diff options
Diffstat (limited to 'src/server.zig')
| -rw-r--r-- | src/server.zig | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/src/server.zig b/src/server.zig index 54d3efe..7206341 100644 --- a/src/server.zig +++ b/src/server.zig @@ -11,8 +11,10 @@ pub const Server = struct { listen_new_output: c.wl_listener, - xdg_shell: *c.wlr_xdg_shell, - new_xdg_surface: c.wl_listener, + wlr_xdg_shell: *c.wlr_xdg_shell, + listen_new_xdg_surface: c.wl_listener, + + // Must stay ordered bottom to top views: std.ArrayList(View), pub fn init(allocator: *std.mem.Allocator) !@This() { @@ -57,6 +59,17 @@ pub const Server = struct { // Setup a listener for new outputs server.listen_new_output = handle_new_output; c.wl_signal_add(&server.wlr_backend.*.events.new_output, &server.listen_new_output); + + // Set up our list of views and the xdg-shell. The xdg-shell is a Wayland + // protocol which is used for application windows. + // https://drewdevault.com/2018/07/29/Wayland-shells.html + server.views = std.ArrayList(View).init(std.heap.c_allocator); + server.wlr_xdg_shell = c.wlr_xdg_shell_create(server.wl_display) orelse + return error.CantCreateWlrXdgShell; + server.listen_new_xdg_surface.notify = handle_new_xdg_surface; + c.wl_signal_add(&server.xdg_shell.*.events.new_surface, &server.listen_new_xdg_surface); + + return server; } /// Free allocated memory and clean up @@ -120,6 +133,31 @@ pub const Server = struct { var wlr_output = @ptrCast(*c.wlr_output, @alignCast(@alignOf(*c.wlr_output), data)); // TODO: Handle failure - server.outputs.append(Output.init(server, wlr_output) orelse return); + server.outputs.append(Output.init(server, wlr_output) catch unreachable); + } + + fn handle_new_xdg_surface(listener: [*c]c.wl_listener, data: ?*c_void) callconv(.C) void { + // This event is raised when wlr_xdg_shell receives a new xdg surface from a + // client, either a toplevel (application window) or popup. + var server = @fieldParentPtr(Server, "listen_new_xdg_surface", listener); + var wlr_xdg_surface = @ptrCast(*c.wlr_xdg_surface, @alignCast(@alignOf(*c.wlr_xdg_surface), data)); + + if (wlr_xdg_surface.role != c.enum_wlr_xdg_surface_role.WLR_XDG_SURFACE_ROLE_TOPLEVEL) { + return; + } + + // Init a View to handle this surface + server.*.views.append(View.init(server, wlr_xdg_surface)) catch unreachable; + } + + /// Finds the top most view under the output layout coordinates lx, ly + /// returns the view if found, and a pointer to the wlr_surface as well as the surface coordinates + pub fn desktop_view_at(self: *@This(), lx: f64, ly: f64, surface: *?*c.wlr_surface, sx: *f64, sy: *f64) ?*View { + for (server.*.views.span()) |*view| { + if (view.is_at(lx, ly, surface, sx, sy)) { + return view; + } + } + return null; } }; |
