diff options
Diffstat (limited to 'sway/desktop/layer_shell.c')
-rw-r--r-- | sway/desktop/layer_shell.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index e09282b2..269864d4 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c | |||
@@ -216,12 +216,48 @@ void arrange_layers(struct sway_output *output) { | |||
216 | } | 216 | } |
217 | } | 217 | } |
218 | 218 | ||
219 | static struct sway_layer_surface *find_any_layer_by_client( | ||
220 | struct wl_client *client, struct wlr_output *ignore_output) { | ||
221 | for (int i = 0; i < root->outputs->length; ++i) { | ||
222 | struct sway_output *output = root->outputs->items[i]; | ||
223 | if (output->wlr_output == ignore_output) { | ||
224 | continue; | ||
225 | } | ||
226 | // For now we'll only check the overlay layer | ||
227 | struct sway_layer_surface *lsurface; | ||
228 | wl_list_for_each(lsurface, | ||
229 | &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], link) { | ||
230 | struct wl_resource *resource = lsurface->layer_surface->resource; | ||
231 | if (wl_resource_get_client(resource) == client) { | ||
232 | return lsurface; | ||
233 | } | ||
234 | } | ||
235 | } | ||
236 | return NULL; | ||
237 | } | ||
238 | |||
219 | static void handle_output_destroy(struct wl_listener *listener, void *data) { | 239 | static void handle_output_destroy(struct wl_listener *listener, void *data) { |
220 | struct sway_layer_surface *sway_layer = | 240 | struct sway_layer_surface *sway_layer = |
221 | wl_container_of(listener, sway_layer, output_destroy); | 241 | wl_container_of(listener, sway_layer, output_destroy); |
242 | // Determine if this layer is being used by an exclusive client. If it is, | ||
243 | // try and find another layer owned by this client to pass focus to. | ||
244 | struct sway_seat *seat = input_manager_get_default_seat(input_manager); | ||
245 | struct wl_client *client = | ||
246 | wl_resource_get_client(sway_layer->layer_surface->resource); | ||
247 | bool set_focus = seat->exclusive_client == client; | ||
248 | |||
222 | wl_list_remove(&sway_layer->output_destroy.link); | 249 | wl_list_remove(&sway_layer->output_destroy.link); |
223 | wl_list_remove(&sway_layer->link); | 250 | wl_list_remove(&sway_layer->link); |
224 | wl_list_init(&sway_layer->link); | 251 | wl_list_init(&sway_layer->link); |
252 | |||
253 | if (set_focus) { | ||
254 | struct sway_layer_surface *layer = | ||
255 | find_any_layer_by_client(client, sway_layer->layer_surface->output); | ||
256 | if (layer) { | ||
257 | seat_set_focus_layer(seat, layer->layer_surface); | ||
258 | } | ||
259 | } | ||
260 | |||
225 | sway_layer->layer_surface->output = NULL; | 261 | sway_layer->layer_surface->output = NULL; |
226 | wlr_layer_surface_v1_close(sway_layer->layer_surface); | 262 | wlr_layer_surface_v1_close(sway_layer->layer_surface); |
227 | } | 263 | } |