diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2019-12-10 19:54:16 -0500 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-12-10 21:09:48 -0500 |
commit | b7f0656fab355f6dc83792794d9f1be780915d0b (patch) | |
tree | 6f3c7d8935afb26e70a99bd75c403a03d1375af7 /sway/desktop | |
parent | input/cursor: remove gesture listeners in destroy (diff) | |
download | sway-b7f0656fab355f6dc83792794d9f1be780915d0b.tar.gz sway-b7f0656fab355f6dc83792794d9f1be780915d0b.tar.zst sway-b7f0656fab355f6dc83792794d9f1be780915d0b.zip |
layer-shell: unfocus output-less layer on unmap
If a layer is focused by any seat, it needs to be unfocused on unmap. If
the unmap was due to an output being disabled, there would not be a
sway_output and unmap would do an early return. This results in a
use-after-free if the layer was focused by any seat prior to being
unmapped. This change just moves the refocusing code above the early
returns.
Diffstat (limited to 'sway/desktop')
-rw-r--r-- | sway/desktop/layer_shell.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index 9289bb4a..b754b1fa 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c | |||
@@ -301,6 +301,15 @@ static void handle_surface_commit(struct wl_listener *listener, void *data) { | |||
301 | } | 301 | } |
302 | 302 | ||
303 | static void unmap(struct sway_layer_surface *sway_layer) { | 303 | static void unmap(struct sway_layer_surface *sway_layer) { |
304 | struct sway_seat *seat; | ||
305 | wl_list_for_each(seat, &server.input->seats, link) { | ||
306 | if (seat->focused_layer == sway_layer->layer_surface) { | ||
307 | seat_set_focus_layer(seat, NULL); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | cursor_rebase_all(); | ||
312 | |||
304 | struct wlr_output *wlr_output = sway_layer->layer_surface->output; | 313 | struct wlr_output *wlr_output = sway_layer->layer_surface->output; |
305 | if (wlr_output == NULL) { | 314 | if (wlr_output == NULL) { |
306 | return; | 315 | return; |
@@ -311,15 +320,6 @@ static void unmap(struct sway_layer_surface *sway_layer) { | |||
311 | } | 320 | } |
312 | output_damage_surface(output, sway_layer->geo.x, sway_layer->geo.y, | 321 | output_damage_surface(output, sway_layer->geo.x, sway_layer->geo.y, |
313 | sway_layer->layer_surface->surface, true); | 322 | sway_layer->layer_surface->surface, true); |
314 | |||
315 | struct sway_seat *seat; | ||
316 | wl_list_for_each(seat, &server.input->seats, link) { | ||
317 | if (seat->focused_layer == sway_layer->layer_surface) { | ||
318 | seat_set_focus_layer(seat, NULL); | ||
319 | } | ||
320 | } | ||
321 | |||
322 | cursor_rebase_all(); | ||
323 | } | 323 | } |
324 | 324 | ||
325 | static void handle_destroy(struct wl_listener *listener, void *data) { | 325 | static void handle_destroy(struct wl_listener *listener, void *data) { |