mirror of
https://github.com/MezzalunaWM/Mezzaluna.git
synced 2026-03-07 19:49:53 -05:00
removed all windows decorations properly, added window closing and compositor exiting as well as view focusing
This commit is contained in:
parent
f636efdfe9
commit
976900ffa6
11 changed files with 289 additions and 117 deletions
|
|
@ -81,5 +81,5 @@ pub fn build(b: *std.Build) void {
|
||||||
const run_cmd = b.addRunArtifact(mez);
|
const run_cmd = b.addRunArtifact(mez);
|
||||||
run_step.dependOn(&run_cmd.step);
|
run_step.dependOn(&run_cmd.step);
|
||||||
run_cmd.step.dependOn(b.getInstallStep());
|
run_cmd.step.dependOn(b.getInstallStep());
|
||||||
run_cmd.addArg("weston-terminal");
|
run_cmd.addArg("alacritty");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
local env_conf = os.getenv("XDG_CONFIG_HOME")
|
local env_conf = os.getenv("XDG_CONFIG_HOME")
|
||||||
if not env_conf then
|
if not env_conf then
|
||||||
env_conf = os.getenv("HOME")
|
env_conf = os.getenv("HOME")
|
||||||
if not env_conf then
|
if not env_conf then
|
||||||
error("Couldn't determine potential config directory is $HOME set?")
|
error("Couldn't determine potential config directory is $HOME set?")
|
||||||
end
|
end
|
||||||
env_conf = mez.fs.joinpath(env_conf, ".config")
|
env_conf = mez.fs.joinpath(env_conf, ".config")
|
||||||
end
|
end
|
||||||
|
|
||||||
mez.path.config = mez.fs.joinpath(env_conf, "mez", "init.lua")
|
mez.path.config = mez.fs.joinpath(env_conf, "mez", "init.lua")
|
||||||
|
|
@ -12,23 +12,27 @@ package.path = package.path..";"..mez.fs.joinpath(env_conf, "mez", "lua", "?.lua
|
||||||
|
|
||||||
-- this is an example
|
-- this is an example
|
||||||
mez.input.add_keymap("alt", "a", {
|
mez.input.add_keymap("alt", "a", {
|
||||||
press = function()
|
press = function()
|
||||||
print("hello from my keymap")
|
print("hello from my keymap")
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
mez.input.add_keymap("alt", "Return", {
|
mez.input.add_keymap("alt", "Return", {
|
||||||
press = function()
|
press = function()
|
||||||
print("spawning foot")
|
mez.api.spawn("foot")
|
||||||
mez.api.spawn("foot")
|
end,
|
||||||
end
|
|
||||||
})
|
})
|
||||||
|
|
||||||
mez.api.add_keymap("alt", "p", {
|
mez.input.add_keymap("alt", "c", {
|
||||||
press = function()
|
press = function ()
|
||||||
print("spawning foot")
|
mez.api.close()
|
||||||
mez.api.spawn("wmenu-run")
|
end
|
||||||
end
|
})
|
||||||
|
|
||||||
|
mez.input.add_keymap("alt", "q", {
|
||||||
|
press = function ()
|
||||||
|
mez.api.exit();
|
||||||
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
-- mez.input.add_keymap("alt", "a", {
|
-- mez.input.add_keymap("alt", "a", {
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ hold_end: wl.Listener(*wlr.Pointer.event.HoldEnd) = .init(handleHoldEnd),
|
||||||
mode: enum { passthrough, move, resize } = .passthrough,
|
mode: enum { passthrough, move, resize } = .passthrough,
|
||||||
|
|
||||||
// Drag information
|
// Drag information
|
||||||
selected_view: ?*View = null,
|
|
||||||
drag_start_x: c_int = 0,
|
drag_start_x: c_int = 0,
|
||||||
drag_start_y: c_int = 0,
|
drag_start_y: c_int = 0,
|
||||||
drag_view_offset_x: c_int = 0,
|
drag_view_offset_x: c_int = 0,
|
||||||
|
|
@ -74,6 +73,8 @@ pub fn processCursorMotion(self: *Cursor, time_msec: u32) void {
|
||||||
switch (self.mode) {
|
switch (self.mode) {
|
||||||
.passthrough => {
|
.passthrough => {
|
||||||
if (server.root.viewAt(self.wlr_cursor.x, self.wlr_cursor.y)) |res| {
|
if (server.root.viewAt(self.wlr_cursor.x, self.wlr_cursor.y)) |res| {
|
||||||
|
server.seat.focusView(res.view);
|
||||||
|
|
||||||
server.seat.wlr_seat.pointerNotifyEnter(res.surface, res.sx, res.sy);
|
server.seat.wlr_seat.pointerNotifyEnter(res.surface, res.sx, res.sy);
|
||||||
server.seat.wlr_seat.pointerNotifyMotion(time_msec, res.sx, res.sy);
|
server.seat.wlr_seat.pointerNotifyMotion(time_msec, res.sx, res.sy);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -82,23 +83,25 @@ pub fn processCursorMotion(self: *Cursor, time_msec: u32) void {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.move => {
|
.move => {
|
||||||
const view = self.selected_view.?;
|
const focused_view = server.seat.focused_view;
|
||||||
|
|
||||||
view.scene_tree.node.setPosition(
|
if(focused_view) |view| {
|
||||||
std.math.clamp(@as(c_int, @intFromFloat(self.wlr_cursor.x)) - self.drag_view_offset_x, 0, std.math.maxInt(u32)),
|
view.scene_tree.node.setPosition(
|
||||||
std.math.clamp(@as(c_int, @intFromFloat(self.wlr_cursor.y)) - self.drag_view_offset_y, 0, std.math.maxInt(u32))
|
std.math.clamp(@as(c_int, @intFromFloat(self.wlr_cursor.x)) - self.drag_view_offset_x, 0, std.math.maxInt(u32)),
|
||||||
);
|
std.math.clamp(@as(c_int, @intFromFloat(self.wlr_cursor.y)) - self.drag_view_offset_y, 0, std.math.maxInt(u32))
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
.resize => {
|
.resize => {
|
||||||
// Fix this resize
|
// Fix this resize
|
||||||
const view = self.selected_view.?;
|
const focused_view = server.seat.focused_view;
|
||||||
|
|
||||||
|
if(focused_view) |view| {
|
||||||
|
_ = view.xdg_toplevel.setSize(
|
||||||
_ = view.xdg_toplevel.setSize(
|
@intCast(@as(c_int, @intFromFloat(self.wlr_cursor.x)) - view.scene_tree.node.x),
|
||||||
@intCast(@as(c_int, @intFromFloat(self.wlr_cursor.x)) - view.scene_tree.node.x),
|
@intCast(@as(c_int, @intFromFloat(self.wlr_cursor.y)) - view.scene_tree.node.y)
|
||||||
@intCast(@as(c_int, @intFromFloat(self.wlr_cursor.y)) - view.scene_tree.node.y)
|
);
|
||||||
);
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -128,33 +131,30 @@ fn handleButton(
|
||||||
|
|
||||||
_ = server.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state);
|
_ = server.seat.wlr_seat.pointerNotifyButton(event.time_msec, event.button, event.state);
|
||||||
|
|
||||||
const view_at_result = server.root.viewAt(cursor.wlr_cursor.x, cursor.wlr_cursor.y);
|
if (server.seat.focused_view) |view| {
|
||||||
if (view_at_result) |res| {
|
server.seat.focusView(view);
|
||||||
server.root.focusView(res.view);
|
server.root.focusView(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
std.log.debug("Button pressed {}", .{event.button});
|
|
||||||
|
|
||||||
switch (event.state) {
|
switch (event.state) {
|
||||||
.pressed => {
|
.pressed => {
|
||||||
if(server.keyboard.wlr_keyboard.getModifiers().alt) {
|
if(server.keyboard.wlr_keyboard.getModifiers().alt) {
|
||||||
// Can be BTN_RIGHT, BTN_LEFT, or BTN_MIDDLE
|
// Can be BTN_RIGHT, BTN_LEFT, or BTN_MIDDLE
|
||||||
if(view_at_result) |res| {
|
if(server.seat.focused_view) |view| {
|
||||||
// Keep track of where the drag started
|
// Keep track of where the drag started
|
||||||
cursor.selected_view = res.view;
|
|
||||||
cursor.drag_start_x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x));
|
cursor.drag_start_x = @as(c_int, @intFromFloat(cursor.wlr_cursor.x));
|
||||||
cursor.drag_start_y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y));
|
cursor.drag_start_y = @as(c_int, @intFromFloat(cursor.wlr_cursor.y));
|
||||||
cursor.drag_view_offset_x = cursor.drag_start_x - res.view.scene_tree.node.x;
|
cursor.drag_view_offset_x = cursor.drag_start_x - view.scene_tree.node.x;
|
||||||
cursor.drag_view_offset_y = cursor.drag_start_y - res.view.scene_tree.node.y;
|
cursor.drag_view_offset_y = cursor.drag_start_y - view.scene_tree.node.y;
|
||||||
cursor.drag_view_width = res.view.xdg_surface.geometry.width;
|
cursor.drag_view_width = view.xdg_toplevel.base.geometry.width;
|
||||||
cursor.drag_view_height = res.view.xdg_surface.geometry.height;
|
cursor.drag_view_height = view.xdg_toplevel.base.geometry.height;
|
||||||
|
|
||||||
// Maybe comptime this for later reference
|
// Maybe comptime this for later reference
|
||||||
if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_LEFT")) {
|
if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_LEFT")) {
|
||||||
cursor.mode = .move;
|
cursor.mode = .move;
|
||||||
} else if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_RIGHT")) {
|
} else if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_RIGHT")) {
|
||||||
cursor.mode = .resize;
|
cursor.mode = .resize;
|
||||||
_ = res.view.xdg_toplevel.setResizing(true);
|
_ = view.xdg_toplevel.setResizing(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -162,10 +162,9 @@ fn handleButton(
|
||||||
.released => {
|
.released => {
|
||||||
cursor.mode = .passthrough;
|
cursor.mode = .passthrough;
|
||||||
|
|
||||||
if(cursor.selected_view) |view| {
|
if(server.seat.focused_view) |view| {
|
||||||
_ = view.xdg_toplevel.setResizing(false);
|
_ = view.xdg_toplevel.setResizing(false);
|
||||||
}
|
}
|
||||||
cursor.selected_view = null;
|
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
std.log.err("Invalid/Unimplemented pointer button event type", .{});
|
std.log.err("Invalid/Unimplemented pointer button event type", .{});
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,8 @@ options: struct {
|
||||||
},
|
},
|
||||||
|
|
||||||
pub fn callback(self: *const Keymap, release: bool) void {
|
pub fn callback(self: *const Keymap, release: bool) void {
|
||||||
var lua_ref_idx = self.lua_press_ref_idx;
|
const lua_ref_idx = if(release) self.lua_release_ref_idx else self.lua_press_ref_idx;
|
||||||
if (release) {
|
|
||||||
lua_ref_idx = self.lua_release_ref_idx;
|
|
||||||
}
|
|
||||||
const t = Lua.state.rawGetIndex(zlua.registry_index, lua_ref_idx);
|
const t = Lua.state.rawGetIndex(zlua.registry_index, lua_ref_idx);
|
||||||
if (t != zlua.LuaType.function) {
|
if (t != zlua.LuaType.function) {
|
||||||
std.log.err("Failed to call keybind, it doesn't have a callback.", .{});
|
std.log.err("Failed to call keybind, it doesn't have a callback.", .{});
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ const zlua = @import("zlua");
|
||||||
const gpa = std.heap.c_allocator;
|
const gpa = std.heap.c_allocator;
|
||||||
|
|
||||||
const env_map = &@import("../main.zig").env_map;
|
const env_map = &@import("../main.zig").env_map;
|
||||||
|
const server = &@import("../main.zig").server;
|
||||||
|
|
||||||
pub fn spawn(L: *zlua.Lua) i32 {
|
pub fn spawn(L: *zlua.Lua) i32 {
|
||||||
const nargs: i32 = L.getTop();
|
const nargs: i32 = L.getTop();
|
||||||
|
|
@ -28,3 +29,31 @@ pub fn spawn(L: *zlua.Lua) i32 {
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn close(L: *zlua.Lua) i32 {
|
||||||
|
const nargs: i32 = L.getTop();
|
||||||
|
|
||||||
|
if (nargs != 0) {
|
||||||
|
L.raiseErrorStr("Expected no arguments", .{});
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(server.seat.focused_view) |view| {
|
||||||
|
view.xdg_toplevel.sendClose();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exit(L: *zlua.Lua) i32 {
|
||||||
|
const nargs: i32 = L.getTop();
|
||||||
|
|
||||||
|
if (nargs != 0) {
|
||||||
|
L.raiseErrorStr("Expected no arguments", .{});
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
server.deinit();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ const posix = std.posix;
|
||||||
const gpa = std.heap.c_allocator;
|
const gpa = std.heap.c_allocator;
|
||||||
const server = &@import("main.zig").server;
|
const server = &@import("main.zig").server;
|
||||||
|
|
||||||
|
focused: bool,
|
||||||
|
|
||||||
wlr_output: *wlr.Output,
|
wlr_output: *wlr.Output,
|
||||||
scene_output: *wlr.SceneOutput,
|
scene_output: *wlr.SceneOutput,
|
||||||
|
|
||||||
|
|
@ -24,6 +26,7 @@ pub fn create(wlr_output: *wlr.Output) *Output {
|
||||||
const output = try gpa.create(Output);
|
const output = try gpa.create(Output);
|
||||||
|
|
||||||
output.* = .{
|
output.* = .{
|
||||||
|
.focused = false,
|
||||||
.wlr_output = wlr_output,
|
.wlr_output = wlr_output,
|
||||||
.scene_output = try server.root.scene.createSceneOutput(wlr_output)
|
.scene_output = try server.root.scene.createSceneOutput(wlr_output)
|
||||||
};
|
};
|
||||||
|
|
|
||||||
23
src/root.zig
23
src/root.zig
|
|
@ -17,10 +17,8 @@ scene: *wlr.Scene,
|
||||||
scene_output_layout: *wlr.SceneOutputLayout,
|
scene_output_layout: *wlr.SceneOutputLayout,
|
||||||
|
|
||||||
output_layout: *wlr.OutputLayout,
|
output_layout: *wlr.OutputLayout,
|
||||||
focused_output: ?*Output,
|
|
||||||
|
|
||||||
views: std.ArrayList(*View) = undefined,
|
views: std.HashMap(u64, *View, std.hash_map.AutoContext(u64), 80),
|
||||||
workspaces: std.ArrayList(*wlr.SceneTree) = undefined,
|
|
||||||
|
|
||||||
pub fn init(self: *Root) void {
|
pub fn init(self: *Root) void {
|
||||||
std.log.info("Creating root of mezzaluna\n", .{});
|
std.log.info("Creating root of mezzaluna\n", .{});
|
||||||
|
|
@ -36,28 +34,21 @@ pub fn init(self: *Root) void {
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.scene = scene,
|
.scene = scene,
|
||||||
.output_layout = output_layout,
|
.output_layout = output_layout,
|
||||||
.focused_output = null,
|
|
||||||
.xdg_toplevel_decoration_manager = try wlr.XdgDecorationManagerV1.create(server.wl_server),
|
.xdg_toplevel_decoration_manager = try wlr.XdgDecorationManagerV1.create(server.wl_server),
|
||||||
.scene_output_layout = try scene.attachOutputLayout(output_layout),
|
.scene_output_layout = try scene.attachOutputLayout(output_layout),
|
||||||
|
.views = .init(gpa)
|
||||||
};
|
};
|
||||||
|
|
||||||
self.views = try std.ArrayList(*View).initCapacity(gpa, 10); // Should consider number better, prolly won't matter that much though
|
|
||||||
// Even though I would never use a changing amount of workspaces, opens more extensibility
|
|
||||||
self.workspaces = try std.ArrayList(*wlr.SceneTree).initCapacity(gpa, 10); // TODO: change to a configured number of workspaces
|
|
||||||
|
|
||||||
// TODO: Make configurable
|
|
||||||
for(0..9) |_| {
|
|
||||||
try self.workspaces.append(gpa, try self.scene.tree.createSceneTree());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Root) void {
|
pub fn deinit(self: *Root) void {
|
||||||
for(self.views.items) |view| {
|
var views_it = self.views.iterator();
|
||||||
view.deinit();
|
while(views_it.next()) |entry| {
|
||||||
|
entry.value_ptr.*.deinit();
|
||||||
}
|
}
|
||||||
self.views.deinit(gpa);
|
|
||||||
|
|
||||||
self.workspaces.deinit(gpa);
|
self.views.deinit();
|
||||||
|
|
||||||
self.output_layout.destroy();
|
self.output_layout.destroy();
|
||||||
self.scene.tree.node.destroy();
|
self.scene.tree.node.destroy();
|
||||||
|
|
@ -66,7 +57,7 @@ pub fn deinit(self: *Root) void {
|
||||||
pub fn addOutput(self: *Root, new_output: *Output) void {
|
pub fn addOutput(self: *Root, new_output: *Output) void {
|
||||||
errdefer Utils.oomPanic();
|
errdefer Utils.oomPanic();
|
||||||
_ = try self.output_layout.addAuto(new_output.wlr_output);
|
_ = try self.output_layout.addAuto(new_output.wlr_output);
|
||||||
self.focused_output = new_output;
|
server.seat.focusOutput(new_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ViewAtResult = struct {
|
const ViewAtResult = struct {
|
||||||
|
|
|
||||||
23
src/seat.zig
23
src/seat.zig
|
|
@ -5,10 +5,14 @@ const wlr = @import("wlroots");
|
||||||
const wl = @import("wayland").server.wl;
|
const wl = @import("wayland").server.wl;
|
||||||
|
|
||||||
const Utils = @import("utils.zig");
|
const Utils = @import("utils.zig");
|
||||||
|
const View = @import("view.zig");
|
||||||
|
const Output = @import("output.zig");
|
||||||
|
|
||||||
const server = &@import("main.zig").server;
|
const server = &@import("main.zig").server;
|
||||||
|
|
||||||
wlr_seat: *wlr.Seat,
|
wlr_seat: *wlr.Seat,
|
||||||
|
focused_view: ?*View,
|
||||||
|
focused_output: ?*Output,
|
||||||
|
|
||||||
request_set_cursor: wl.Listener(*wlr.Seat.event.RequestSetCursor) = .init(handleRequestSetCursor),
|
request_set_cursor: wl.Listener(*wlr.Seat.event.RequestSetCursor) = .init(handleRequestSetCursor),
|
||||||
request_set_selection: wl.Listener(*wlr.Seat.event.RequestSetSelection) = .init(handleRequestSetSelection),
|
request_set_selection: wl.Listener(*wlr.Seat.event.RequestSetSelection) = .init(handleRequestSetSelection),
|
||||||
|
|
@ -20,6 +24,8 @@ pub fn init(self: *Seat) void {
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.wlr_seat = try wlr.Seat.create(server.wl_server, "default"),
|
.wlr_seat = try wlr.Seat.create(server.wl_server, "default"),
|
||||||
|
.focused_view = null,
|
||||||
|
.focused_output = null,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.wlr_seat.events.request_set_cursor.add(&self.request_set_cursor);
|
self.wlr_seat.events.request_set_cursor.add(&self.request_set_cursor);
|
||||||
|
|
@ -33,6 +39,23 @@ pub fn deinit(self: *Seat) void {
|
||||||
self.wlr_seat.destroy();
|
self.wlr_seat.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn focusOutput(self: *Seat, output: *Output) void {
|
||||||
|
if(self.focused_output) |prev_output| {
|
||||||
|
prev_output.focused = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.focused_output = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Should focusing a view, automaticall focus the output containing it
|
||||||
|
pub fn focusView(self: *Seat, view: *View) void {
|
||||||
|
if(self.focused_view) |prev_view| {
|
||||||
|
prev_view.setFocus(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.focused_view = view;
|
||||||
|
}
|
||||||
|
|
||||||
fn handleRequestSetCursor(
|
fn handleRequestSetCursor(
|
||||||
_: *wl.Listener(*wlr.Seat.event.RequestSetCursor),
|
_: *wl.Listener(*wlr.Seat.event.RequestSetCursor),
|
||||||
event: *wlr.Seat.event.RequestSetCursor,
|
event: *wlr.Seat.event.RequestSetCursor,
|
||||||
|
|
|
||||||
|
|
@ -116,15 +116,15 @@ pub fn init(self: *Server) void {
|
||||||
self.xdg_shell.events.new_popup.add(&self.new_xdg_popup);
|
self.xdg_shell.events.new_popup.add(&self.new_xdg_popup);
|
||||||
|
|
||||||
// XdgDecorationManagerV1 events
|
// XdgDecorationManagerV1 events
|
||||||
// self.xdg_toplevel_decoration_manager.events.new_toplevel_decoration.add(&self.new_toplevel_decoration);
|
self.xdg_toplevel_decoration_manager.events.new_toplevel_decoration.add(&self.new_xdg_toplevel_decoration);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Server) void {
|
pub fn deinit(self: *Server) noreturn {
|
||||||
self.new_input.link.remove();
|
self.new_input.link.remove();
|
||||||
self.new_output.link.remove();
|
self.new_output.link.remove();
|
||||||
self.new_xdg_toplevel.link.remove();
|
self.new_xdg_toplevel.link.remove();
|
||||||
self.new_xdg_popup.link.remove();
|
self.new_xdg_popup.link.remove();
|
||||||
self.new_xdg_toplevel.link.remove();
|
self.new_xdg_toplevel_decoration.link.remove();
|
||||||
|
|
||||||
self.seat.deinit();
|
self.seat.deinit();
|
||||||
self.root.deinit();
|
self.root.deinit();
|
||||||
|
|
@ -134,6 +134,9 @@ pub fn deinit(self: *Server) void {
|
||||||
|
|
||||||
self.wl_server.destroyClients();
|
self.wl_server.destroyClients();
|
||||||
self.wl_server.destroy();
|
self.wl_server.destroy();
|
||||||
|
|
||||||
|
std.log.debug("Exiting mez succesfully", .{});
|
||||||
|
std.process.exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------- Backend event handlers ---------
|
// --------- Backend event handlers ---------
|
||||||
|
|
@ -185,20 +188,23 @@ fn handleNewXdgToplevel(
|
||||||
_: *wl.Listener(*wlr.XdgToplevel),
|
_: *wl.Listener(*wlr.XdgToplevel),
|
||||||
xdg_toplevel: *wlr.XdgToplevel
|
xdg_toplevel: *wlr.XdgToplevel
|
||||||
) void {
|
) void {
|
||||||
|
std.log.debug("Request for new toplevel", .{});
|
||||||
_ = View.initFromTopLevel(xdg_toplevel);
|
_ = View.initFromTopLevel(xdg_toplevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handleNewXdgToplevelDecoration(
|
||||||
|
_: *wl.Listener(*wlr.XdgToplevelDecorationV1),
|
||||||
|
decoration: *wlr.XdgToplevelDecorationV1
|
||||||
|
) void {
|
||||||
|
std.log.debug("Request for decorations", .{});
|
||||||
|
if(server.root.views.get(@intFromPtr(decoration.toplevel))) |view| {
|
||||||
|
view.xdg_toplevel_decoration = decoration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handleNewXdgPopup(
|
fn handleNewXdgPopup(
|
||||||
_: *wl.Listener(*wlr.XdgPopup),
|
_: *wl.Listener(*wlr.XdgPopup),
|
||||||
_: *wlr.XdgPopup
|
_: *wlr.XdgPopup
|
||||||
) void {
|
) void {
|
||||||
std.log.err("Unimplemented handle new xdg popup", .{});
|
std.log.err("Unimplemented handle new xdg popup", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleNewXdgToplevelDecoration(
|
|
||||||
_: *wl.Listener(*wlr.XdgToplevelDecorationV1),
|
|
||||||
decoration: *wlr.XdgToplevelDecorationV1
|
|
||||||
) void {
|
|
||||||
// TODO: Configured with lua perhaps
|
|
||||||
decoration.current.mode = .server_side;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
32
src/tag.zig
Normal file
32
src/tag.zig
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
const Tag = @This();
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const wl = @import("wayland").server.wl;
|
||||||
|
const wlr = @import("wlroots");
|
||||||
|
|
||||||
|
const Output = @import("output.zig");
|
||||||
|
const View = @import("view.zig");
|
||||||
|
const Utils = @import("utils.zig");
|
||||||
|
|
||||||
|
const server = @import("main.zig").server;
|
||||||
|
const gpa = std.heap.c_allocator;
|
||||||
|
|
||||||
|
output: *Output,
|
||||||
|
scene_tree: *wlr.SceneTree,
|
||||||
|
|
||||||
|
views: std.ArrayList(*View),
|
||||||
|
|
||||||
|
pub fn init(output: *Output) Tag {
|
||||||
|
errdefer Utils.oomPanic();
|
||||||
|
return .{
|
||||||
|
.output = output,
|
||||||
|
.scene_tree = try server.root.scene.tree.createSceneTree(),
|
||||||
|
.views = .initCapacity(gpa, 2), // Probably shouldn't be a magic number
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *Tag) void {
|
||||||
|
for(self.views.items) |view| {
|
||||||
|
view
|
||||||
|
}
|
||||||
|
}
|
||||||
169
src/view.zig
169
src/view.zig
|
|
@ -9,25 +9,40 @@ const Utils = @import("utils.zig");
|
||||||
const gpa = std.heap.c_allocator;
|
const gpa = std.heap.c_allocator;
|
||||||
const server = &@import("main.zig").server;
|
const server = &@import("main.zig").server;
|
||||||
|
|
||||||
link: wl.list.Link = undefined,
|
mapped: bool,
|
||||||
geometry: *wlr.Box = undefined,
|
focused: bool,
|
||||||
|
id: u64,
|
||||||
|
|
||||||
|
// workspace: Workspace,
|
||||||
xdg_toplevel: *wlr.XdgToplevel,
|
xdg_toplevel: *wlr.XdgToplevel,
|
||||||
xdg_surface: *wlr.XdgSurface,
|
xdg_toplevel_decoration: ?*wlr.XdgToplevelDecorationV1,
|
||||||
scene_tree: *wlr.SceneTree,
|
scene_tree: *wlr.SceneTree,
|
||||||
|
|
||||||
// Surface Listeners
|
// Surface Listeners
|
||||||
map: wl.Listener(void) = .init(handleMap),
|
map: wl.Listener(void) = .init(handleMap),
|
||||||
unmap: wl.Listener(void) = .init(handleUnmap),
|
unmap: wl.Listener(void) = .init(handleUnmap),
|
||||||
commit: wl.Listener(*wlr.Surface) = .init(handleCommit),
|
commit: wl.Listener(*wlr.Surface) = .init(handleCommit),
|
||||||
|
new_popup: wl.Listener(*wlr.XdgPopup) = .init(handleNewPopup),
|
||||||
|
|
||||||
|
ack_configure: wl.Listener(*wlr.XdgSurface.Configure) = .init(handleAckConfigure),
|
||||||
|
|
||||||
// XdgTopLevel Listeners
|
// XdgTopLevel Listeners
|
||||||
destroy: wl.Listener(void) = .init(handleDestroy),
|
destroy: wl.Listener(void) = .init(handleDestroy),
|
||||||
|
|
||||||
request_resize: wl.Listener(*wlr.XdgToplevel.event.Resize) = .init(handleRequestResize),
|
request_resize: wl.Listener(*wlr.XdgToplevel.event.Resize) = .init(handleRequestResize),
|
||||||
request_move: wl.Listener(*wlr.XdgToplevel.event.Move) = .init(handleRequestMove),
|
request_move: wl.Listener(*wlr.XdgToplevel.event.Move) = .init(handleRequestMove),
|
||||||
|
request_fullscreen: wl.Listener(void) = .init(handleRequestFullscreen),
|
||||||
|
|
||||||
// Not yet silly
|
// Do we need to add these
|
||||||
// new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup),
|
// request_show_window_menu: wl.Listener(comptime T: type) = .init(handleRequestShowWindowMenu),
|
||||||
|
// request_minimize: wl.Listener(comptime T: type) = .init(handleRequestMinimize),
|
||||||
|
// request_maximize: wl.Listener(comptime T: type) = .init(handleRequestMaximize),
|
||||||
|
|
||||||
|
set_app_id: wl.Listener(void) = .init(handleSetAppId),
|
||||||
|
set_title: wl.Listener(void) = .init(handleSetTitle),
|
||||||
|
|
||||||
|
// Do we need to add this
|
||||||
|
// set_parent: wl.Listener(void) = .init(handleSetParent),
|
||||||
|
|
||||||
pub fn initFromTopLevel(xdg_toplevel: *wlr.XdgToplevel) *View {
|
pub fn initFromTopLevel(xdg_toplevel: *wlr.XdgToplevel) *View {
|
||||||
errdefer Utils.oomPanic();
|
errdefer Utils.oomPanic();
|
||||||
|
|
@ -37,40 +52,30 @@ pub fn initFromTopLevel(xdg_toplevel: *wlr.XdgToplevel) *View {
|
||||||
|
|
||||||
self.* = .{
|
self.* = .{
|
||||||
.xdg_toplevel = xdg_toplevel,
|
.xdg_toplevel = xdg_toplevel,
|
||||||
.xdg_surface = xdg_toplevel.base,
|
.focused = false,
|
||||||
.geometry = &xdg_toplevel.base.geometry,
|
|
||||||
.scene_tree = undefined,
|
.scene_tree = undefined,
|
||||||
|
.xdg_toplevel_decoration = null,
|
||||||
|
.mapped = false,
|
||||||
|
.id = @intFromPtr(xdg_toplevel),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.xdg_toplevel.base.surface.events.unmap.add(&self.unmap);
|
||||||
|
|
||||||
// Add new Toplevel to focused output instead of some random shit
|
// Add new Toplevel to focused output instead of some random shit
|
||||||
// This is where we find out where to tile the widow, but not NOW
|
// This is where we find out where to tile the widow, but not NOW
|
||||||
// We need lua for that
|
// We need lua for that
|
||||||
self.scene_tree = try server.root.workspaces.items[0].createSceneXdgSurface(xdg_toplevel.base);
|
// self.scene_tree = try server.root.workspaces.items[0].createSceneXdgSurface(xdg_toplevel.base);
|
||||||
|
self.scene_tree = try server.root.scene.tree.createSceneXdgSurface(xdg_toplevel.base);
|
||||||
|
|
||||||
self.scene_tree.node.data = self;
|
self.scene_tree.node.data = self;
|
||||||
self.xdg_surface.data = self.scene_tree;
|
self.xdg_toplevel.base.data = self.scene_tree;
|
||||||
|
|
||||||
// Attach listeners
|
|
||||||
self.xdg_surface.surface.events.map.add(&self.map);
|
|
||||||
self.xdg_surface.surface.events.unmap.add(&self.unmap);
|
|
||||||
self.xdg_surface.surface.events.commit.add(&self.commit);
|
|
||||||
|
|
||||||
self.xdg_toplevel.events.destroy.add(&self.destroy);
|
self.xdg_toplevel.events.destroy.add(&self.destroy);
|
||||||
self.xdg_toplevel.events.request_move.add(&self.request_move);
|
self.xdg_toplevel.base.surface.events.map.add(&self.map);
|
||||||
self.xdg_toplevel.events.request_resize.add(&self.request_resize);
|
self.xdg_toplevel.base.surface.events.commit.add(&self.commit);
|
||||||
|
self.xdg_toplevel.base.events.new_popup.add(&self.new_popup);
|
||||||
|
|
||||||
// xdg_toplevel.events.request_fullscreen.add(&self.request_fullscreen);
|
try server.root.views.put(self.id, self);
|
||||||
// xdg_toplevel.events.request_minimize.add(&self.request_minimize);
|
|
||||||
// xdg_toplevel.events.request_maxminize.add(&self.request_maximize);
|
|
||||||
|
|
||||||
// xdg_toplevel.events.set_title.add(&self.set_title);
|
|
||||||
// xdg_toplevel.events.set_app_id.add(&self.set_app_id);
|
|
||||||
// xdg_toplevel.events.set_parent.add(&self.set_parent);
|
|
||||||
|
|
||||||
// xdg_toplevel.events.request_show_window_menu.add(&self.request_show_window_menu);
|
|
||||||
|
|
||||||
try server.root.views.append(gpa, self);
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
@ -85,10 +90,22 @@ pub fn deinit(self: *View) void {
|
||||||
self.request_resize.link.remove();
|
self.request_resize.link.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle borders to appropriate colros make necessary notifications
|
||||||
|
pub fn setFocus(self: *View, focus: bool) void {
|
||||||
|
self.focused = focus;
|
||||||
|
}
|
||||||
|
|
||||||
// --------- XdgTopLevel event handlers ---------
|
// --------- XdgTopLevel event handlers ---------
|
||||||
fn handleMap(listener: *wl.Listener(void)) void {
|
fn handleMap(listener: *wl.Listener(void)) void {
|
||||||
const view: *View = @fieldParentPtr("map", listener);
|
const view: *View = @fieldParentPtr("map", listener);
|
||||||
std.log.info("View mapped {s}", .{view.xdg_toplevel.title orelse "(unnamed)"});
|
std.log.debug("Mapping view '{s}'", .{view.xdg_toplevel.title orelse "(unnamed)"});
|
||||||
|
|
||||||
|
view.xdg_toplevel.events.request_fullscreen.add(&view.request_fullscreen);
|
||||||
|
view.xdg_toplevel.events.request_move.add(&view.request_move);
|
||||||
|
view.xdg_toplevel.events.request_resize.add(&view.request_resize);
|
||||||
|
view.xdg_toplevel.events.set_app_id.add(&view.set_app_id);
|
||||||
|
view.xdg_toplevel.events.set_title.add(&view.set_title);
|
||||||
|
// view.xdg_toplevel.events.set_parent.add(&view.set_parent);
|
||||||
|
|
||||||
const xdg_surface = view.xdg_toplevel.base;
|
const xdg_surface = view.xdg_toplevel.base;
|
||||||
server.seat.wlr_seat.keyboardNotifyEnter(
|
server.seat.wlr_seat.keyboardNotifyEnter(
|
||||||
|
|
@ -96,29 +113,49 @@ fn handleMap(listener: *wl.Listener(void)) void {
|
||||||
server.keyboard.wlr_keyboard.keycodes[0..server.keyboard.wlr_keyboard.num_keycodes],
|
server.keyboard.wlr_keyboard.keycodes[0..server.keyboard.wlr_keyboard.num_keycodes],
|
||||||
&server.keyboard.wlr_keyboard.modifiers
|
&server.keyboard.wlr_keyboard.modifiers
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if(view.xdg_toplevel_decoration) |decoration| {
|
||||||
|
_ = decoration.setMode(wlr.XdgToplevelDecorationV1.Mode.server_side);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here is where we should tile and set size
|
||||||
|
|
||||||
|
view.mapped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleUnmap(listener: *wl.Listener(void)) void {
|
fn handleUnmap(listener: *wl.Listener(void)) void {
|
||||||
_ = listener;
|
const view: *View = @fieldParentPtr("unmap", listener);
|
||||||
std.log.err("Unimplemented view handle unamp", .{});
|
std.log.debug("Unmapping view '{s}'", .{view.xdg_toplevel.title orelse "(unnamed)"});
|
||||||
|
|
||||||
|
view.request_fullscreen.link.remove();
|
||||||
|
view.request_move.link.remove();
|
||||||
|
view.request_resize.link.remove();
|
||||||
|
view.set_title.link.remove();
|
||||||
|
view.set_app_id.link.remove();
|
||||||
|
|
||||||
|
// Why does this crash mez???
|
||||||
|
// view.ack_configure.link.remove();
|
||||||
|
|
||||||
|
view.mapped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handleDestroy(listener: *wl.Listener(void)) void {
|
fn handleDestroy(listener: *wl.Listener(void)) void {
|
||||||
const view: *View = @fieldParentPtr("destroy", listener);
|
const view: *View = @fieldParentPtr("destroy", listener);
|
||||||
std.log.debug("Destroying view {s}", .{view.xdg_toplevel.title orelse "(unnamed)"});
|
|
||||||
|
// Remove decorations
|
||||||
|
|
||||||
view.map.link.remove();
|
view.map.link.remove();
|
||||||
view.unmap.link.remove();
|
view.unmap.link.remove();
|
||||||
view.commit.link.remove();
|
view.commit.link.remove();
|
||||||
view.destroy.link.remove();
|
view.destroy.link.remove();
|
||||||
|
view.new_popup.link.remove();
|
||||||
|
|
||||||
// Remove this view from the list of views
|
view.xdg_toplevel.base.surface.data = null;
|
||||||
// for(server.root.all_views.items, 0..) |v, i| {
|
|
||||||
// if(v == view) {
|
view.scene_tree.node.destroy();
|
||||||
// _ = server.root.all_views.orderedRemove(i);
|
// Destroy popups
|
||||||
// break;
|
|
||||||
// }
|
_ = server.root.views.remove(view.id);
|
||||||
// }
|
|
||||||
|
|
||||||
gpa.destroy(view);
|
gpa.destroy(view);
|
||||||
}
|
}
|
||||||
|
|
@ -132,6 +169,7 @@ fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --------- XdgToplevel Event Handlers ---------
|
||||||
fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), popup: *wlr.XdgPopup) void {
|
fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), popup: *wlr.XdgPopup) void {
|
||||||
_ = listener;
|
_ = listener;
|
||||||
_ = popup;
|
_ = popup;
|
||||||
|
|
@ -144,7 +182,7 @@ fn handleRequestMove(
|
||||||
) void {
|
) void {
|
||||||
// const view: *View = @fieldParentPtr("request_move", listener);
|
// const view: *View = @fieldParentPtr("request_move", listener);
|
||||||
|
|
||||||
std.log.err("The clients should not be request moves", .{});
|
std.log.debug("The clients should not be request moves", .{});
|
||||||
|
|
||||||
// server.cursor.moveView(view);
|
// server.cursor.moveView(view);
|
||||||
// server.cursor.grabbed_view = view;
|
// server.cursor.grabbed_view = view;
|
||||||
|
|
@ -159,7 +197,7 @@ fn handleRequestResize(
|
||||||
) void {
|
) void {
|
||||||
// const view: *View = @fieldParentPtr("request_resize", listener);
|
// const view: *View = @fieldParentPtr("request_resize", listener);
|
||||||
|
|
||||||
std.log.err("The clients should not be request moves", .{});
|
std.log.debug("The clients should not be request moves", .{});
|
||||||
|
|
||||||
// server.cursor.grabbed_view = view;
|
// server.cursor.grabbed_view = view;
|
||||||
// server.cursor.mode = .resize;
|
// server.cursor.mode = .resize;
|
||||||
|
|
@ -176,3 +214,52 @@ fn handleRequestResize(
|
||||||
// server.cursor.grab_box.x += view.geometry.x;
|
// server.cursor.grab_box.x += view.geometry.x;
|
||||||
// server.cursor.grab_box.y += view.geometry.y;
|
// server.cursor.grab_box.y += view.geometry.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handleAckConfigure(
|
||||||
|
listener: *wl.Listener(*wlr.XdgSurface.Configure),
|
||||||
|
_: *wlr.XdgSurface.Configure,
|
||||||
|
) void {
|
||||||
|
const view: *View = @fieldParentPtr("ack_configure", listener);
|
||||||
|
_ = view;
|
||||||
|
std.log.err("Unimplemented act configure", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handleRequestFullscreen(
|
||||||
|
listener: *wl.Listener(void)
|
||||||
|
) void {
|
||||||
|
const view: *View = @fieldParentPtr("request_fullscreen", listener);
|
||||||
|
_ = view;
|
||||||
|
std.log.err("Unimplemented request fullscreen", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handleRequestMinimize(
|
||||||
|
listener: *wl.Listener(void)
|
||||||
|
) void {
|
||||||
|
const view: *View = @fieldParentPtr("request_fullscreen", listener);
|
||||||
|
_ = view;
|
||||||
|
std.log.err("Unimplemented request minimize", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handleRequestMaximize(
|
||||||
|
listener: *wl.Listener(void)
|
||||||
|
) void {
|
||||||
|
const view: *View = @fieldParentPtr("request_fullscreen", listener);
|
||||||
|
_ = view;
|
||||||
|
std.log.err("Unimplemented request maximize", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handleSetAppId(
|
||||||
|
listener: *wl.Listener(void)
|
||||||
|
) void {
|
||||||
|
const view: *View = @fieldParentPtr("set_app_id", listener);
|
||||||
|
_ = view;
|
||||||
|
std.log.err("Unimplemented request maximize", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handleSetTitle(
|
||||||
|
listener: *wl.Listener(void)
|
||||||
|
) void {
|
||||||
|
const view: *View = @fieldParentPtr("set_title", listener);
|
||||||
|
_ = view;
|
||||||
|
std.log.err("Unimplemented set title", .{});
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue