diff --git a/src/c.zig b/src/c.zig index 473a139..2967207 100644 --- a/src/c.zig +++ b/src/c.zig @@ -17,6 +17,7 @@ pub const c = @cImport({ @cInclude("wlr/types/wlr_pointer.h"); @cInclude("wlr/types/wlr_seat.h"); @cInclude("wlr/types/wlr_xcursor_manager.h"); + @cInclude("wlr/types/wlr_xdg_decoration_v1.h"); @cInclude("wlr/types/wlr_xdg_shell.h"); @cInclude("wlr/util/log.h"); @cInclude("xkbcommon/xkbcommon.h"); diff --git a/src/decoration.zig b/src/decoration.zig new file mode 100644 index 0000000..7ae8401 --- /dev/null +++ b/src/decoration.zig @@ -0,0 +1,37 @@ +const std = @import("std"); +const c = @import("c.zig").c; + +const DecorationManager = @import("decoration_manager.zig").DecorationManager; + +// TODO: this needs to listen for destroy and free nodes from the deco list +pub const Decoration = struct { + const Self = @This(); + + decoration_manager: *DecorationManager, + wlr_xdg_toplevel_decoration: *c.wlr_xdg_toplevel_decoration_v1, + + listen_request_mode: c.wl_listener, + + pub fn init( + self: *Self, + decoration_manager: *DecorationManager, + wlr_xdg_toplevel_decoration: *c.wlr_xdg_toplevel_decoration_v1, + ) void { + self.decoration_manager = decoration_manager; + self.wlr_xdg_toplevel_decoration = wlr_xdg_toplevel_decoration; + + self.listen_request_mode.notify = handleRequestMode; + c.wl_signal_add(&self.wlr_xdg_toplevel_decoration.events.request_mode, &self.listen_request_mode); + + handleRequestMode(&self.listen_request_mode, self.wlr_xdg_toplevel_decoration); + } + + fn handleRequestMode(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { + const decoration = @fieldParentPtr(Decoration, "listen_request_mode", listener.?); + // TODO: we might need to take this configure serial and do a transaction + _ = c.wlr_xdg_toplevel_decoration_v1_set_mode( + decoration.wlr_xdg_toplevel_decoration, + c.wlr_xdg_toplevel_decoration_v1_mode.WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE, + ); + } +}; diff --git a/src/decoration_manager.zig b/src/decoration_manager.zig new file mode 100644 index 0000000..d6beb1e --- /dev/null +++ b/src/decoration_manager.zig @@ -0,0 +1,45 @@ +const std = @import("std"); +const c = @import("c.zig").c; + +const Decoration = @import("decoration.zig").Decoration; +const Server = @import("server.zig").Server; + +pub const DecorationManager = struct { + const Self = @This(); + + server: *Server, + + wlr_xdg_decoration_manager: *c.wlr_xdg_decoration_manager_v1, + + decorations: std.SinglyLinkedList(Decoration), + + listen_new_toplevel_decoration: c.wl_listener, + + pub fn init(self: *Self, server: *Server) !void { + self.server = server; + self.wlr_xdg_decoration_manager = c.wlr_xdg_decoration_manager_v1_create(server.wl_display) orelse + return error.CantCreateWlrXdgDecorationManager; + + self.listen_new_toplevel_decoration.notify = handleNewToplevelDecoration; + c.wl_signal_add( + &self.wlr_xdg_decoration_manager.events.new_toplevel_decoration, + &self.listen_new_toplevel_decoration, + ); + } + + fn handleNewToplevelDecoration(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { + const decoration_manager = @fieldParentPtr( + DecorationManager, + "listen_new_toplevel_decoration", + listener.?, + ); + const wlr_xdg_toplevel_decoration = @ptrCast( + *c.wlr_xdg_toplevel_decoration_v1, + @alignCast(@alignOf(*c.wlr_xdg_toplevel_decoration_v1), data), + ); + + const node = decoration_manager.decorations.allocateNode(decoration_manager.server.allocator) catch unreachable; + node.data.init(decoration_manager, wlr_xdg_toplevel_decoration); + decoration_manager.decorations.prepend(node); + } +}; diff --git a/src/server.zig b/src/server.zig index c6aef76..79ec54a 100644 --- a/src/server.zig +++ b/src/server.zig @@ -1,6 +1,7 @@ const std = @import("std"); const c = @import("c.zig").c; +const DecorationManager = @import("decoration_manager.zig").DecorationManager; const Output = @import("output.zig").Output; const Root = @import("root.zig").Root; const Seat = @import("seat.zig").Seat; @@ -11,16 +12,17 @@ pub const Server = struct { allocator: *std.mem.Allocator, - root: Root, - seat: Seat, - wl_display: *c.wl_display, wlr_backend: *c.wlr_backend, wlr_renderer: *c.wlr_renderer, - listen_new_output: c.wl_listener, - wlr_xdg_shell: *c.wlr_xdg_shell, + + decoration_manager: DecorationManager, + root: Root, + seat: Seat, + + listen_new_output: c.wl_listener, listen_new_xdg_surface: c.wl_listener, pub fn init(self: *Self, allocator: *std.mem.Allocator) !void { @@ -58,6 +60,8 @@ pub const Server = struct { self.wlr_xdg_shell = c.wlr_xdg_shell_create(self.wl_display) orelse return error.CantCreateWlrXdgShell; + try self.decoration_manager.init(self); + try self.root.init(self); try self.seat.init(self);