From 976900ffa6101c4352de45b3e98e832ac4261c4f Mon Sep 17 00:00:00 2001 From: Harrison DiAmbrosio Date: Sat, 25 Oct 2025 18:50:06 -0400 Subject: [PATCH] removed all windows decorations properly, added window closing and compositor exiting as well as view focusing --- build.zig | 2 +- runtime/share/mezzaluna/init.lua | 38 +++---- src/cursor.zig | 53 +++++----- src/keymap.zig | 6 +- src/lua/api.zig | 29 ++++++ src/output.zig | 3 + src/root.zig | 23 ++--- src/seat.zig | 23 +++++ src/server.zig | 28 +++-- src/tag.zig | 32 ++++++ src/view.zig | 169 +++++++++++++++++++++++-------- 11 files changed, 289 insertions(+), 117 deletions(-) create mode 100644 src/tag.zig diff --git a/build.zig b/build.zig index 0b9d396..11dbdf3 100644 --- a/build.zig +++ b/build.zig @@ -81,5 +81,5 @@ pub fn build(b: *std.Build) void { const run_cmd = b.addRunArtifact(mez); run_step.dependOn(&run_cmd.step); run_cmd.step.dependOn(b.getInstallStep()); - run_cmd.addArg("weston-terminal"); + run_cmd.addArg("alacritty"); } diff --git a/runtime/share/mezzaluna/init.lua b/runtime/share/mezzaluna/init.lua index 4c58888..069e955 100644 --- a/runtime/share/mezzaluna/init.lua +++ b/runtime/share/mezzaluna/init.lua @@ -1,10 +1,10 @@ local env_conf = os.getenv("XDG_CONFIG_HOME") if not env_conf then - env_conf = os.getenv("HOME") - if not env_conf then - error("Couldn't determine potential config directory is $HOME set?") - end - env_conf = mez.fs.joinpath(env_conf, ".config") + env_conf = os.getenv("HOME") + if not env_conf then + error("Couldn't determine potential config directory is $HOME set?") + end + env_conf = mez.fs.joinpath(env_conf, ".config") end 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 mez.input.add_keymap("alt", "a", { - press = function() - print("hello from my keymap") - end + press = function() + print("hello from my keymap") + end }) mez.input.add_keymap("alt", "Return", { - press = function() - print("spawning foot") - mez.api.spawn("foot") - end + press = function() + mez.api.spawn("foot") + end, }) -mez.api.add_keymap("alt", "p", { - press = function() - print("spawning foot") - mez.api.spawn("wmenu-run") - end +mez.input.add_keymap("alt", "c", { + press = function () + mez.api.close() + end +}) + +mez.input.add_keymap("alt", "q", { + press = function () + mez.api.exit(); + end }) -- mez.input.add_keymap("alt", "a", { diff --git a/src/cursor.zig b/src/cursor.zig index d26ad4a..5cf3f62 100644 --- a/src/cursor.zig +++ b/src/cursor.zig @@ -30,7 +30,6 @@ hold_end: wl.Listener(*wlr.Pointer.event.HoldEnd) = .init(handleHoldEnd), mode: enum { passthrough, move, resize } = .passthrough, // Drag information -selected_view: ?*View = null, drag_start_x: c_int = 0, drag_start_y: 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) { .passthrough => { 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.pointerNotifyMotion(time_msec, res.sx, res.sy); } else { @@ -82,23 +83,25 @@ pub fn processCursorMotion(self: *Cursor, time_msec: u32) void { } }, .move => { - const view = self.selected_view.?; + const focused_view = server.seat.focused_view; - view.scene_tree.node.setPosition( - 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)) - ); + if(focused_view) |view| { + view.scene_tree.node.setPosition( + 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 => { // Fix this resize - const view = self.selected_view.?; + const focused_view = server.seat.focused_view; - - - _ = 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.y)) - view.scene_tree.node.y) - ); + if(focused_view) |view| { + _ = 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.y)) - view.scene_tree.node.y) + ); + } }, } } @@ -128,33 +131,30 @@ fn handleButton( _ = 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 (view_at_result) |res| { - server.root.focusView(res.view); + if (server.seat.focused_view) |view| { + server.seat.focusView(view); + server.root.focusView(view); } - std.log.debug("Button pressed {}", .{event.button}); - switch (event.state) { .pressed => { if(server.keyboard.wlr_keyboard.getModifiers().alt) { // 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 - cursor.selected_view = res.view; 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_view_offset_x = cursor.drag_start_x - res.view.scene_tree.node.x; - cursor.drag_view_offset_y = cursor.drag_start_y - res.view.scene_tree.node.y; - cursor.drag_view_width = res.view.xdg_surface.geometry.width; - cursor.drag_view_height = res.view.xdg_surface.geometry.height; + cursor.drag_view_offset_x = cursor.drag_start_x - view.scene_tree.node.x; + cursor.drag_view_offset_y = cursor.drag_start_y - view.scene_tree.node.y; + cursor.drag_view_width = view.xdg_toplevel.base.geometry.width; + cursor.drag_view_height = view.xdg_toplevel.base.geometry.height; // Maybe comptime this for later reference if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_LEFT")) { cursor.mode = .move; } else if(event.button == c.libevdev_event_code_from_name(c.EV_KEY, "BTN_RIGHT")) { cursor.mode = .resize; - _ = res.view.xdg_toplevel.setResizing(true); + _ = view.xdg_toplevel.setResizing(true); } } } @@ -162,10 +162,9 @@ fn handleButton( .released => { cursor.mode = .passthrough; - if(cursor.selected_view) |view| { + if(server.seat.focused_view) |view| { _ = view.xdg_toplevel.setResizing(false); } - cursor.selected_view = null; }, else => { std.log.err("Invalid/Unimplemented pointer button event type", .{}); diff --git a/src/keymap.zig b/src/keymap.zig index d693391..93a74c8 100644 --- a/src/keymap.zig +++ b/src/keymap.zig @@ -21,10 +21,8 @@ options: struct { }, pub fn callback(self: *const Keymap, release: bool) void { - var lua_ref_idx = self.lua_press_ref_idx; - if (release) { - lua_ref_idx = self.lua_release_ref_idx; - } + const lua_ref_idx = if(release) self.lua_release_ref_idx else self.lua_press_ref_idx; + const t = Lua.state.rawGetIndex(zlua.registry_index, lua_ref_idx); if (t != zlua.LuaType.function) { std.log.err("Failed to call keybind, it doesn't have a callback.", .{}); diff --git a/src/lua/api.zig b/src/lua/api.zig index bf64d93..9e0e3f7 100644 --- a/src/lua/api.zig +++ b/src/lua/api.zig @@ -4,6 +4,7 @@ const zlua = @import("zlua"); const gpa = std.heap.c_allocator; const env_map = &@import("../main.zig").env_map; +const server = &@import("../main.zig").server; pub fn spawn(L: *zlua.Lua) i32 { const nargs: i32 = L.getTop(); @@ -28,3 +29,31 @@ pub fn spawn(L: *zlua.Lua) i32 { 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; +} diff --git a/src/output.zig b/src/output.zig index f22aca8..4ec10cf 100644 --- a/src/output.zig +++ b/src/output.zig @@ -10,6 +10,8 @@ const posix = std.posix; const gpa = std.heap.c_allocator; const server = &@import("main.zig").server; +focused: bool, + wlr_output: *wlr.Output, scene_output: *wlr.SceneOutput, @@ -24,6 +26,7 @@ pub fn create(wlr_output: *wlr.Output) *Output { const output = try gpa.create(Output); output.* = .{ + .focused = false, .wlr_output = wlr_output, .scene_output = try server.root.scene.createSceneOutput(wlr_output) }; diff --git a/src/root.zig b/src/root.zig index 88cff11..0668ac1 100644 --- a/src/root.zig +++ b/src/root.zig @@ -17,10 +17,8 @@ scene: *wlr.Scene, scene_output_layout: *wlr.SceneOutputLayout, output_layout: *wlr.OutputLayout, -focused_output: ?*Output, -views: std.ArrayList(*View) = undefined, -workspaces: std.ArrayList(*wlr.SceneTree) = undefined, +views: std.HashMap(u64, *View, std.hash_map.AutoContext(u64), 80), pub fn init(self: *Root) void { std.log.info("Creating root of mezzaluna\n", .{}); @@ -36,28 +34,21 @@ pub fn init(self: *Root) void { self.* = .{ .scene = scene, .output_layout = output_layout, - .focused_output = null, .xdg_toplevel_decoration_manager = try wlr.XdgDecorationManagerV1.create(server.wl_server), .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 { - for(self.views.items) |view| { - view.deinit(); + var views_it = self.views.iterator(); + 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.scene.tree.node.destroy(); @@ -66,7 +57,7 @@ pub fn deinit(self: *Root) void { pub fn addOutput(self: *Root, new_output: *Output) void { errdefer Utils.oomPanic(); _ = try self.output_layout.addAuto(new_output.wlr_output); - self.focused_output = new_output; + server.seat.focusOutput(new_output); } const ViewAtResult = struct { diff --git a/src/seat.zig b/src/seat.zig index eb9fa3c..02950fb 100644 --- a/src/seat.zig +++ b/src/seat.zig @@ -5,10 +5,14 @@ const wlr = @import("wlroots"); const wl = @import("wayland").server.wl; const Utils = @import("utils.zig"); +const View = @import("view.zig"); +const Output = @import("output.zig"); const server = &@import("main.zig").server; wlr_seat: *wlr.Seat, +focused_view: ?*View, +focused_output: ?*Output, request_set_cursor: wl.Listener(*wlr.Seat.event.RequestSetCursor) = .init(handleRequestSetCursor), request_set_selection: wl.Listener(*wlr.Seat.event.RequestSetSelection) = .init(handleRequestSetSelection), @@ -20,6 +24,8 @@ pub fn init(self: *Seat) void { self.* = .{ .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); @@ -33,6 +39,23 @@ pub fn deinit(self: *Seat) void { 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( _: *wl.Listener(*wlr.Seat.event.RequestSetCursor), event: *wlr.Seat.event.RequestSetCursor, diff --git a/src/server.zig b/src/server.zig index 4b7a32c..f2fb4cb 100644 --- a/src/server.zig +++ b/src/server.zig @@ -116,15 +116,15 @@ pub fn init(self: *Server) void { self.xdg_shell.events.new_popup.add(&self.new_xdg_popup); // 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_output.link.remove(); self.new_xdg_toplevel.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.root.deinit(); @@ -134,6 +134,9 @@ pub fn deinit(self: *Server) void { self.wl_server.destroyClients(); self.wl_server.destroy(); + + std.log.debug("Exiting mez succesfully", .{}); + std.process.exit(0); } // --------- Backend event handlers --------- @@ -185,20 +188,23 @@ fn handleNewXdgToplevel( _: *wl.Listener(*wlr.XdgToplevel), xdg_toplevel: *wlr.XdgToplevel ) void { + std.log.debug("Request for new 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( _: *wl.Listener(*wlr.XdgPopup), _: *wlr.XdgPopup ) void { 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; -} diff --git a/src/tag.zig b/src/tag.zig new file mode 100644 index 0000000..63023ac --- /dev/null +++ b/src/tag.zig @@ -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 + } +} diff --git a/src/view.zig b/src/view.zig index 54c44e6..f210922 100644 --- a/src/view.zig +++ b/src/view.zig @@ -9,25 +9,40 @@ const Utils = @import("utils.zig"); const gpa = std.heap.c_allocator; const server = &@import("main.zig").server; -link: wl.list.Link = undefined, -geometry: *wlr.Box = undefined, +mapped: bool, +focused: bool, +id: u64, +// workspace: Workspace, xdg_toplevel: *wlr.XdgToplevel, -xdg_surface: *wlr.XdgSurface, +xdg_toplevel_decoration: ?*wlr.XdgToplevelDecorationV1, scene_tree: *wlr.SceneTree, // Surface Listeners map: wl.Listener(void) = .init(handleMap), unmap: wl.Listener(void) = .init(handleUnmap), 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 destroy: wl.Listener(void) = .init(handleDestroy), + request_resize: wl.Listener(*wlr.XdgToplevel.event.Resize) = .init(handleRequestResize), request_move: wl.Listener(*wlr.XdgToplevel.event.Move) = .init(handleRequestMove), +request_fullscreen: wl.Listener(void) = .init(handleRequestFullscreen), -// Not yet silly -// new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup), +// Do we need to add these +// 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 { errdefer Utils.oomPanic(); @@ -37,40 +52,30 @@ pub fn initFromTopLevel(xdg_toplevel: *wlr.XdgToplevel) *View { self.* = .{ .xdg_toplevel = xdg_toplevel, - .xdg_surface = xdg_toplevel.base, - .geometry = &xdg_toplevel.base.geometry, + .focused = false, .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 // This is where we find out where to tile the widow, but not NOW // 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.xdg_surface.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.base.data = self.scene_tree; self.xdg_toplevel.events.destroy.add(&self.destroy); - self.xdg_toplevel.events.request_move.add(&self.request_move); - self.xdg_toplevel.events.request_resize.add(&self.request_resize); + self.xdg_toplevel.base.surface.events.map.add(&self.map); + 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); - // 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); + try server.root.views.put(self.id, self); return self; } @@ -85,10 +90,22 @@ pub fn deinit(self: *View) void { 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 --------- fn handleMap(listener: *wl.Listener(void)) void { 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; 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.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 { - _ = listener; - std.log.err("Unimplemented view handle unamp", .{}); + const view: *View = @fieldParentPtr("unmap", listener); + 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 { 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.unmap.link.remove(); view.commit.link.remove(); view.destroy.link.remove(); + view.new_popup.link.remove(); - // Remove this view from the list of views - // for(server.root.all_views.items, 0..) |v, i| { - // if(v == view) { - // _ = server.root.all_views.orderedRemove(i); - // break; - // } - // } + view.xdg_toplevel.base.surface.data = null; + + view.scene_tree.node.destroy(); + // Destroy popups + + _ = server.root.views.remove(view.id); 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 { _ = listener; _ = popup; @@ -144,7 +182,7 @@ fn handleRequestMove( ) void { // 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.grabbed_view = view; @@ -159,7 +197,7 @@ fn handleRequestResize( ) void { // 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.mode = .resize; @@ -176,3 +214,52 @@ fn handleRequestResize( // server.cursor.grab_box.x += view.geometry.x; // 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", .{}); +}