From 48f51bbeb69f9a1cc05d5aee182acaa826e34f49 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Sat, 2 May 2020 15:51:16 +0200 Subject: [PATCH] Handle unmap on never-mapped layer surface I don't think wlroots should be sending this, but we shouldn't crash either. Fixes https://github.com/ifreund/river/issues/19 --- src/layer_surface.zig | 25 ++++++++++++++++++------- src/output.zig | 2 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/layer_surface.zig b/src/layer_surface.zig index e4d4344..1acd321 100644 --- a/src/layer_surface.zig +++ b/src/layer_surface.zig @@ -36,11 +36,16 @@ pub const LayerSurface = struct { self.wlr_layer_surface = wlr_layer_surface; wlr_layer_surface.data = self; - self.mapped = false; - - self.box = undefined; self.layer = layer; + // Temporarily set mapped to true and apply the pending state to allow + // for inital arrangement which sends the first configure. + self.mapped = true; + const stashed_state = wlr_layer_surface.current; + wlr_layer_surface.current = wlr_layer_surface.client_pending; + output.arrangeLayers(); + wlr_layer_surface.current = stashed_state; + // Set up listeners that are active for the entire lifetime of the layer surface self.listen_destroy.notify = handleDestroy; c.wl_signal_add(&self.wlr_layer_surface.events.destroy, &self.listen_destroy); @@ -96,11 +101,17 @@ pub const LayerSurface = struct { Log.Debug.log("Layer surface '{}' unmapped.", .{self.wlr_layer_surface.namespace}); - self.mapped = false; + // 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. + if (self.wlr_layer_surface.mapped) { + // remove listeners only active while the layer surface is mapped + c.wl_list_remove(&self.listen_commit.link); + c.wl_list_remove(&self.listen_new_popup.link); + } - // remove listeners only active while the layer surface is mapped - c.wl_list_remove(&self.listen_commit.link); - c.wl_list_remove(&self.listen_new_popup.link); + self.mapped = false; // 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 5530b77..e3db173 100644 --- a/src/output.zig +++ b/src/output.zig @@ -347,7 +347,7 @@ pub const Output = struct { // If the value of exclusive_zone is greater than zero, then it exclusivly // occupies some area of the screen. - if (exclusive != (current_state.exclusive_zone > 0)) { + if (!layer_surface.mapped or exclusive != (current_state.exclusive_zone > 0)) { continue; }