git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit17e229d3b3144e93e5f3142b707f49f621928b45
parentf793d0f9fc
authorIsaac Freund <[email protected]>
date2020-09-29 17:27
layer-shell: default to focused output

Layer shell clients may leave the output on which to display a layer
surface up to the compositor. Instead of always putting such surfaces
on the first output use the focused output of the default seat.

 river/Cursor.zig       |  2 +-
 river/InputManager.zig | 12 +++++++-----
 river/Server.zig       | 28 ++++++++++++----------------
 3 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/river/Cursor.zig b/river/Cursor.zig
index d102f53..7920751 100644
--- a/river/Cursor.zig
+++ b/river/Cursor.zig
@@ -316,7 +316,7 @@ pub fn setTheme(self: *Self, theme: ?[*:0]const u8, _size: ?u32) !void {
 
     // If this cursor belongs to the default seat, set the xcursor environment
     // variables and the xwayland cursor theme.
-    if (self.seat == self.seat.input_manager.default_seat) {
+    if (self.seat == self.seat.input_manager.defaultSeat()) {
         const size_str = try std.fmt.allocPrint0(util.gpa, "{}", .{size});
         defer util.gpa.free(size_str);
         if (c.setenv("XCURSOR_SIZE", size_str, 1) < 0) return error.OutOfMemory;
diff --git a/river/InputManager.zig b/river/InputManager.zig
index b6f5866..9482cfe 100644
--- a/river/InputManager.zig
+++ b/river/InputManager.zig
@@ -36,7 +36,6 @@ wlr_idle: *c.wlr_idle,
 wlr_input_inhibit_manager: *c.wlr_input_inhibit_manager,
 
 seats: std.TailQueue(Seat) = std.TailQueue(Seat).init(),
-default_seat: *Seat,
 
 exclusive_client: ?*c.wl_client = null,
 
@@ -53,13 +52,12 @@ pub fn init(self: *Self, server: *Server) !void {
         .wlr_idle = c.wlr_idle_create(server.wl_display) orelse return error.OutOfMemory,
         .wlr_input_inhibit_manager = c.wlr_input_inhibit_manager_create(server.wl_display) orelse
             return error.OutOfMemory,
-        .default_seat = &seat_node.data,
     };
 
-    try seat_node.data.init(self, default_seat_name);
     self.seats.prepend(seat_node);
+    try seat_node.data.init(self, default_seat_name);
 
-    if (build_options.xwayland) c.wlr_xwayland_set_seat(server.wlr_xwayland, self.default_seat.wlr_seat);
+    if (build_options.xwayland) c.wlr_xwayland_set_seat(server.wlr_xwayland, self.defaultSeat().wlr_seat);
 
     // Set up all listeners
     self.listen_inhibit_activate.notify = handleInhibitActivate;
@@ -79,6 +77,10 @@ pub fn deinit(self: *Self) void {
     }
 }
 
+pub fn defaultSeat(self: Self) *Seat {
+    return &self.seats.first.?.data;
+}
+
 /// Must be called whenever a view is unmapped.
 pub fn handleViewUnmap(self: Self, view: *View) void {
     var it = self.seats.first;
@@ -147,5 +149,5 @@ fn handleNewInput(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void {
     const device = util.voidCast(c.wlr_input_device, data.?);
 
     // TODO: suport multiple seats
-    self.default_seat.addDevice(device);
+    self.defaultSeat().addDevice(device);
 }
diff --git a/river/Server.zig b/river/Server.zig
index 639c2fd..fd28ce7 100644
--- a/river/Server.zig
+++ b/river/Server.zig
@@ -196,7 +196,7 @@ fn handleNewXdgSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) v
     log.debug(.server, "new xdg_toplevel", .{});
 
     // The View will add itself to the output's view stack on map
-    const output = self.input_manager.default_seat.focused_output;
+    const output = self.input_manager.defaultSeat().focused_output;
     const node = util.gpa.create(ViewStack(View).Node) catch {
         c.wl_resource_post_no_memory(wlr_xdg_surface.resource);
         return;
@@ -229,23 +229,19 @@ fn handleNewLayerSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C)
     // If the new layer surface does not have an output assigned to it, use the
     // first output or close the surface if none are available.
     if (wlr_layer_surface.output == null) {
-        if (self.root.outputs.first) |node| {
-            const output = &node.data;
-            log.debug(
-                .server,
-                "new layer surface had null output, assigning it to output '{}'",
-                .{output.wlr_output.name},
-            );
-            wlr_layer_surface.output = output.wlr_output;
-        } else {
-            log.err(
-                .server,
-                "no output available for layer surface '{}'",
-                .{wlr_layer_surface.namespace},
-            );
+        const output = self.input_manager.defaultSeat().focused_output;
+        if (output == &self.root.noop_output) {
+            log.err(.server, "no output available for layer surface '{s}'", .{wlr_layer_surface.namespace});
             c.wlr_layer_surface_v1_close(wlr_layer_surface);
             return;
         }
+
+        log.debug(
+            .server,
+            "new layer surface had null output, assigning it to output '{s}'",
+            .{output.wlr_output.name},
+        );
+        wlr_layer_surface.output = output.wlr_output;
     }
 
     // The layer surface will add itself to the proper list of the output on map
@@ -277,7 +273,7 @@ fn handleNewXwaylandSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(
     );
 
     // The View will add itself to the output's view stack on map
-    const output = self.input_manager.default_seat.focused_output;
+    const output = self.input_manager.defaultSeat().focused_output;
     const node = util.gpa.create(ViewStack(View).Node) catch return;
     node.view.init(output, output.current.tags, wlr_xwayland_surface);
 }