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
This commit is contained in:
Isaac Freund 2020-05-02 15:51:16 +02:00
parent 490e79eed4
commit 48f51bbeb6
No known key found for this signature in database
GPG key ID: 86DED400DDFD7A11
2 changed files with 19 additions and 8 deletions

View file

@ -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;

View file

@ -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;
}