Refactor xdg_shell handling
This commit is contained in:
@ -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;
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user