From ddc9a05f39bc4eca90b81308bc2a99096a166550 Mon Sep 17 00:00:00 2001 From: Harrison DiAmbrosio Date: Sun, 19 Oct 2025 19:09:38 -0400 Subject: [PATCH] hi --- build.zig | 4 +-- src/keyboard.zig | 2 +- src/output.zig | 20 +++++++----- src/root.zig | 18 ++++++---- src/server.zig | 35 +++++++++++--------- src/view.zig | 85 +++++++++++++++++++++++++++++++++++++----------- 6 files changed, 111 insertions(+), 53 deletions(-) diff --git a/build.zig b/build.zig index 784872f..2aa4bbe 100644 --- a/build.zig +++ b/build.zig @@ -64,7 +64,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()); - if (b.args) |args| { - run_cmd.addArgs(args); - } + run_cmd.addArg("weston-terminal"); } diff --git a/src/keyboard.zig b/src/keyboard.zig index 734f09d..081fefe 100644 --- a/src/keyboard.zig +++ b/src/keyboard.zig @@ -91,7 +91,7 @@ fn handleKeyMap(_: *wl.Listener(*wlr.Keyboard), _: *wlr.Keyboard) void { pub fn handleDestroy(listener: *wl.Listener(*wlr.InputDevice), _: *wlr.InputDevice) void { const keyboard: *Keyboard = @fieldParentPtr("destroy", listener); - std.log.debug("removing keyboard: {s}", .{keyboard.*.device.*.name orelse "(null)"}); + std.log.debug("removing keyboard: {s}", .{keyboard.device.name orelse "(null)"}); keyboard.link.remove(); diff --git a/src/output.zig b/src/output.zig index d2e0f35..628a51e 100644 --- a/src/output.zig +++ b/src/output.zig @@ -30,7 +30,7 @@ pub fn create(wlr_output: *wlr.Output) !*Output { wlr_output.events.request_state.add(&output.request_state); wlr_output.events.destroy.add(&output.destroy); - std.log.debug("adding output: {s}", .{output.*.wlr_output.*.name}); + std.log.debug("adding output: {s}", .{output.wlr_output.name}); // I don't think we need the result of this _ = try server.root.output_layout.addAuto(wlr_output); @@ -63,18 +63,20 @@ fn handleFrame( _: *wl.Listener(*wlr.Output), wlr_output: *wlr.Output ) void { - std.log.debug("Handling frame for {s}", .{wlr_output.name}); + // std.log.debug("Handling frame for {s}", .{wlr_output.name}); const scene_output = server.root.scene.getSceneOutput(wlr_output); - if(scene_output) |so| { - std.log.info("Rendering commited scene output\n", .{}); - _ = so.commit(null); - - var now = posix.clock_gettime(posix.CLOCK.MONOTONIC) catch @panic("CLOCK_MONOTONIC not supported"); - so.sendFrameDone(&now); + if(scene_output == null) { + std.log.err("Unable to get scene output to render", .{}); + return; } + // std.log.info("Rendering commited scene output\n", .{}); + _ = scene_output.?.commit(null); + + var now = posix.clock_gettime(posix.CLOCK.MONOTONIC) catch @panic("CLOCK_MONOTONIC not supported"); + scene_output.?.sendFrameDone(&now); } fn handleDestroy( @@ -84,7 +86,7 @@ fn handleDestroy( std.log.debug("Handling destroy", .{}); const output: *Output = @fieldParentPtr("destroy", listener); - std.log.debug("removing output: {s}", .{output.*.wlr_output.*.name}); + std.log.debug("removing output: {s}", .{output.wlr_output.name}); output.frame.link.remove(); output.request_state.link.remove(); diff --git a/src/root.zig b/src/root.zig index 18a5fb8..4319844 100644 --- a/src/root.zig +++ b/src/root.zig @@ -11,6 +11,7 @@ const server = &@import("main.zig").server; const gpa = std.heap.c_allocator; scene: *wlr.Scene, +scene_tree: ?*wlr.Scene, scene_output_layout: *wlr.SceneOutputLayout, output_layout: *wlr.OutputLayout, @@ -28,10 +29,11 @@ pub fn init(self: *Root) !void { self.* = .{ .scene = scene, + .scene_tree = null, .output_layout = output_layout, - .scene_output_layout = try scene.attachOutputLayout(output_layout), + .all_views = try .initCapacity(gpa, 10), }; } @@ -49,13 +51,17 @@ pub fn addOutput(self: *Root, new_output: *Output) void { } pub fn addView(self: *Root, view: *View) void { - self.all_views.append(gpa, view) catch { - std.log.err("Out of memory to append view", .{}); - }; - - _ = self.scene.tree.createSceneXdgSurface(view.xdg_toplevel.base) catch { + self.scene_tree = self.scene.tree.createSceneXdgSurface(view.xdg_toplevel.base) catch { std.log.err("Unable to create scene node for new view", .{}); }; + + self.all_views.append(gpa, view) catch { + std.log.err("Out of memory to append view", .{}); + self.scene_tree = null; + return; + }; + + std.log.debug("View added succesfully", .{}); } const ViewAtResult = struct { diff --git a/src/server.zig b/src/server.zig index 8c35a72..2941629 100644 --- a/src/server.zig +++ b/src/server.zig @@ -39,7 +39,8 @@ new_output: wl.Listener(*wlr.Output) = .init(handleNewOutput), // backend.events.destroy // XdgShell listeners -new_xdg_surface: wl.Listener(*wlr.XdgSurface) = .init(handleNewXdgSurface), +new_xdg_toplevel: wl.Listener(*wlr.XdgToplevel) = .init(handleNewXdgToplevel), +new_xdg_popup: wl.Listener(*wlr.XdgPopup) = .init(handleNewXdgPopup), // new_xdg_popup // new_xdg_toplevel @@ -85,8 +86,8 @@ pub fn init(self: *Server) !void { self.backend.events.new_output.add(&self.new_output); // XdgShell events - self.xdg_shell.events.new_surface.add(&self.new_xdg_surface); - + self.xdg_shell.events.new_toplevel.add(&self.new_xdg_toplevel); + self.xdg_shell.events.new_popup.add(&self.new_xdg_popup); } pub fn deinit(self: *Server) void { @@ -154,7 +155,6 @@ fn handleNewOutput( server.root.addOutput(new_output); } - fn handleRequestSetSelection( _: *wl.Listener(*wlr.Seat.event.RequestSetSelection), event: *wlr.Seat.event.RequestSetSelection, @@ -162,16 +162,21 @@ fn handleRequestSetSelection( server.seat.setSelection(event.source, event.serial); } -fn handleNewXdgSurface( - _: *wl.Listener(*wlr.XdgSurface), - xdg_surface: *wlr.XdgSurface +fn handleNewXdgToplevel( + _: *wl.Listener(*wlr.XdgToplevel), + xdg_toplevel: *wlr.XdgToplevel ) void { - std.log.info("New xdg_toplevel added", .{}); - - const view = View.init(xdg_surface) catch { - std.log.err("Unable to allocate a top level", .{}); - return; - }; - - server.root.addView(view); + if(View.initFromTopLevel(xdg_toplevel)) |view| { + std.log.debug("Adding new view {s}", .{view.xdg_toplevel.title orelse "(null)"}); + server.root.addView(view); + } else { + std.log.err("Unable to allocate new view", .{}); + } +} + +fn handleNewXdgPopup( + _: *wl.Listener(*wlr.XdgPopup), + _: *wlr.XdgPopup +) void { + std.log.err("Unimplemented handle new xdg popup", .{}); } diff --git a/src/view.zig b/src/view.zig index 6f30df6..ef72a50 100644 --- a/src/view.zig +++ b/src/view.zig @@ -8,38 +8,70 @@ const gpa = std.heap.c_allocator; const server = &@import("main.zig").server; xdg_toplevel: *wlr.XdgToplevel, -box: *wlr.Box, -// Listeners -destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy), +// XdgTopLevel Listeners map: wl.Listener(void) = wl.Listener(void).init(handleMap), unmap: wl.Listener(void) = wl.Listener(void).init(handleUnmap), commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit), -new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup), +destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy), -pub fn init(xdg_surface: *wlr.XdgSurface) !*View { - const view = gpa.create(View) catch |err| { +// Not yet silly +// new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup), + +pub fn initFromTopLevel(xdg_toplevel: *wlr.XdgToplevel) ?*View { + const self = gpa.create(View) catch { std.log.err("Unable to allocate memory for new XdgTopLevel", .{}); - return err; + return null; }; - if(xdg_surface.role_data.toplevel) |xgd_toplevel| { - view.* = .{ - .xdg_toplevel = xgd_toplevel, - .box = undefined, - }; + self.xdg_toplevel = xdg_toplevel; - view.box.x = 0; - view.box.y = 0; + self.xdg_toplevel.base.surface.events.map.add(&self.map); + self.xdg_toplevel.base.surface.events.unmap.add(&self.unmap); + self.xdg_toplevel.base.surface.events.commit.add(&self.commit); + + 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); + + return self; +} + +pub fn init(xdg_surface: *wlr.XdgSurface) ?*View { + const self = gpa.create(View) catch { + std.log.err("Unable to allocate memory for new XdgTopLevel", .{}); + return null; + }; + + if(xdg_surface.role_data.toplevel) |xdg_toplevel| { + self.xdg_toplevel = xdg_toplevel; + } else { + std.log.err("Unable to get top_level from new surface", .{}); + return null; } - return view; + self.xdg_toplevel.base.surface.events.map.add(&self.map); + self.xdg_toplevel.base.surface.events.unmap.add(&self.unmap); + self.xdg_toplevel.base.surface.events.commit.add(&self.commit); + + 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); + + return self; +} + +pub fn deinit(self: *View) void { + gpa.free(self); } // --------- XdgTopLevel event handlers --------- fn handleMap(listener: *wl.Listener(void)) void { - _ = listener; - std.log.err("Unimplemented view handle map", .{}); + const view: *View = @fieldParentPtr("map", listener); + std.log.info("View mapped {s}", .{view.xdg_toplevel.title orelse "(unnamed)"}); + + const xdg_surface = view.xdg_toplevel.base; + server.seat.wlr_seat.keyboardNotifyEnter(xdg_surface.surface, &.{}, null); } fn handleUnmap(listener: *wl.Listener(void)) void { @@ -48,8 +80,23 @@ fn handleUnmap(listener: *wl.Listener(void)) void { } fn handleDestroy(listener: *wl.Listener(void)) void { - _ = listener; - std.log.err("Unimplemented view handle destroy", .{}); + const view: *View = @fieldParentPtr("destroy", listener); + std.log.debug("Destroying view {s}", .{view.xdg_toplevel.title orelse "(unnamed)"}); + + view.map.link.remove(); + view.unmap.link.remove(); + view.commit.link.remove(); + view.destroy.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; + // } + // } + + gpa.destroy(view); } fn handleCommit(listener: *wl.Listener(*wlr.Surface), surface: *wlr.Surface) void {