From 0eb6c7c11339b8742048219d7bc1538d1e29bc45 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Tue, 12 May 2020 00:11:11 +0200 Subject: [PATCH] Only store mapped layer surfaces in Output.layers --- src/LayerSurface.zig | 32 ++++++++++++++++---------------- src/Output.zig | 16 ++-------------- src/Server.zig | 5 ++++- src/render.zig | 3 --- 4 files changed, 22 insertions(+), 34 deletions(-) diff --git a/src/LayerSurface.zig b/src/LayerSurface.zig index 5da7025..a90917c 100644 --- a/src/LayerSurface.zig +++ b/src/LayerSurface.zig @@ -28,9 +28,6 @@ const Output = @import("Output.zig"); output: *Output, wlr_layer_surface: *c.wlr_layer_surface_v1, -/// True if the layer surface is currently mapped -mapped: bool, - box: Box, layer: c.zwlr_layer_shell_v1_layer, @@ -47,20 +44,22 @@ pub fn init( self: *Self, output: *Output, wlr_layer_surface: *c.wlr_layer_surface_v1, - layer: c.zwlr_layer_shell_v1_layer, ) void { self.output = output; self.wlr_layer_surface = wlr_layer_surface; wlr_layer_surface.data = self; - self.layer = layer; + self.layer = wlr_layer_surface.client_pending.layer; - // Temporarily set mapped to true and apply the pending state to allow + // Temporarily add to the output's list and apply the pending state to allow // for inital arrangement which sends the first configure. - self.mapped = true; + const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self); + const list = &output.layers[@intCast(usize, @enumToInt(self.layer))]; const stashed_state = wlr_layer_surface.current; wlr_layer_surface.current = wlr_layer_surface.client_pending; + list.append(node); output.arrangeLayers(); + list.remove(node); wlr_layer_surface.current = stashed_state; // Set up listeners that are active for the entire lifetime of the layer surface @@ -86,10 +85,7 @@ fn handleDestroy(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { c.wl_list_remove(&self.listen_unmap.link); const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self); - output.layers[@intCast(usize, @enumToInt(self.layer))].remove(node); output.root.server.allocator.destroy(node); - - self.output.arrangeLayers(); } fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { @@ -98,8 +94,6 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { Log.Debug.log("Layer surface '{}' mapped.", .{wlr_layer_surface.namespace}); - self.mapped = true; - // Add listeners that are only active while mapped self.listen_commit.notify = handleCommit; c.wl_signal_add(&wlr_layer_surface.surface.*.events.commit, &self.listen_commit); @@ -111,6 +105,9 @@ fn handleMap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { wlr_layer_surface.surface, wlr_layer_surface.output, ); + + const node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self); + self.output.layers[@intCast(usize, @enumToInt(self.layer))].append(node); } fn handleUnmap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { @@ -119,9 +116,10 @@ fn handleUnmap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { Log.Debug.log("Layer surface '{}' unmapped.", .{self.wlr_layer_surface.namespace}); // This is a bit ugly: we need to use the wlr bool here since surfaces - // may be closed during the inital configure since we set our mapped - // bool to true so that we can avoid making the arrange function even - // more complex. + // may be closed during the inital configure which we preform + // while unmapped. wlroots currently calls unmap unconditionally on close + // even if the surface is not mapped. I sent a patch which was merged, but + // we need to wait for a release to use it. // // TODO(wlroots): Remove this check on updating // https://github.com/swaywm/wlroots/commit/11e94c406bb75c9a8990ce99489798411deb110c @@ -131,7 +129,9 @@ fn handleUnmap(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { c.wl_list_remove(&self.listen_new_popup.link); } - self.mapped = false; + // Remove from the output's list of layer surfaces + const self_node = @fieldParentPtr(std.TailQueue(Self).Node, "data", self); + self.output.layers[@intCast(usize, @enumToInt(self.layer))].remove(self_node); // If the unmapped surface is focused, clear focus var it = self.output.root.server.input_manager.seats.first; diff --git a/src/Output.zig b/src/Output.zig index c2315bc..7668928 100644 --- a/src/Output.zig +++ b/src/Output.zig @@ -147,15 +147,6 @@ pub fn getRenderer(self: Self) *c.wlr_renderer { return c.river_wlr_backend_get_renderer(self.wlr_output.backend); } -/// Add a newly created layer surface to the output. -pub fn addLayerSurface(self: *Self, wlr_layer_surface: *c.wlr_layer_surface_v1) !void { - const layer = wlr_layer_surface.client_pending.layer; - const node = try self.layers[@intCast(usize, @enumToInt(layer))].allocateNode(self.root.server.allocator); - node.data.init(self, wlr_layer_surface, layer); - self.layers[@intCast(usize, @enumToInt(layer))].append(node); - self.arrangeLayers(); -} - /// Arrange all views on the output for the current layout. Modifies only /// pending state, the changes are not appplied until a transaction is started /// and completed. @@ -312,10 +303,7 @@ pub fn arrangeLayers(self: *Self) void { var it = self.layers[layer].last; while (it) |node| : (it = node.prev) { const layer_surface = &node.data; - // Only mapped surfaces may gain focus - if (layer_surface.mapped and - layer_surface.wlr_layer_surface.current.keyboard_interactive) - { + if (layer_surface.wlr_layer_surface.current.keyboard_interactive) { break :outer layer_surface; } } @@ -360,7 +348,7 @@ fn arrangeLayer( // If the value of exclusive_zone is greater than zero, then it exclusivly // occupies some area of the screen. - if (!layer_surface.mapped or exclusive != (current_state.exclusive_zone > 0)) { + if (exclusive != (current_state.exclusive_zone > 0)) { continue; } diff --git a/src/Server.zig b/src/Server.zig index 8639233..b8d1877 100644 --- a/src/Server.zig +++ b/src/Server.zig @@ -25,6 +25,7 @@ const c = @import("c.zig"); const Config = @import("Config.zig"); const DecorationManager = @import("DecorationManager.zig"); const InputManager = @import("InputManager.zig"); +const LayerSurface = @import("LayerSurface.zig"); const Log = @import("log.zig").Log; const Output = @import("Output.zig"); const Root = @import("Root.zig"); @@ -240,8 +241,10 @@ fn handleNewLayerSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) } } + // The layer surface will add itself to the proper list of the output on map const output = @ptrCast(*Output, @alignCast(@alignOf(*Output), wlr_layer_surface.output.*.data)); - output.addLayerSurface(wlr_layer_surface) catch unreachable; + const node = self.allocator.create(std.TailQueue(LayerSurface).Node) catch unreachable; + node.data.init(output, wlr_layer_surface); } fn handleNewXwaylandSurface(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { diff --git a/src/render.zig b/src/render.zig index 7341e18..a7055ef 100644 --- a/src/render.zig +++ b/src/render.zig @@ -121,9 +121,6 @@ fn renderLayer(output: Output, layer: std.TailQueue(LayerSurface), now: *c.times var it = layer.first; while (it) |node| : (it = node.next) { const layer_surface = &node.data; - if (!layer_surface.mapped) { - continue; - } var rdata = SurfaceRenderData{ .output = &output, .output_x = layer_surface.box.x,