aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoremersion <contact@emersion.fr>2018-10-04 14:18:13 +0200
committerGitHub <noreply@github.com>2018-10-04 14:18:13 +0200
commit0d5c2f75b58aecbfa539dcb345c64be4bfe184bf (patch)
treee9bb6e6d7ee7ca5abf696af42ab27bc7735c8556
parent192ec7d6c8843b18aafce70eefe322e6db11e5b9 (diff)
parent32cb631143fe9087d9d14e96f42a38f602369212 (diff)
Merge pull request #2760 from RyanDwyer/swaylock-handle-output-disconnect
Give focus to another swaylock surface when output is disconnected
-rw-r--r--sway/desktop/layer_shell.c36
-rw-r--r--sway/input/seat.c3
2 files changed, 36 insertions, 3 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) {
}
}
+static struct sway_layer_surface *find_any_layer_by_client(
+ struct wl_client *client, struct wlr_output *ignore_output) {
+ for (int i = 0; i < root->outputs->length; ++i) {
+ struct sway_output *output = root->outputs->items[i];
+ if (output->wlr_output == ignore_output) {
+ continue;
+ }
+ // For now we'll only check the overlay layer
+ struct sway_layer_surface *lsurface;
+ wl_list_for_each(lsurface,
+ &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], link) {
+ struct wl_resource *resource = lsurface->layer_surface->resource;
+ if (wl_resource_get_client(resource) == client) {
+ return lsurface;
+ }
+ }
+ }
+ return NULL;
+}
+
static void handle_output_destroy(struct wl_listener *listener, void *data) {
struct sway_layer_surface *sway_layer =
wl_container_of(listener, sway_layer, output_destroy);
+ // Determine if this layer is being used by an exclusive client. If it is,
+ // try and find another layer owned by this client to pass focus to.
+ struct sway_seat *seat = input_manager_get_default_seat(input_manager);
+ struct wl_client *client =
+ wl_resource_get_client(sway_layer->layer_surface->resource);
+ bool set_focus = seat->exclusive_client == client;
+
wl_list_remove(&sway_layer->output_destroy.link);
wl_list_remove(&sway_layer->link);
wl_list_init(&sway_layer->link);
+
+ if (set_focus) {
+ struct sway_layer_surface *layer =
+ find_any_layer_by_client(client, sway_layer->layer_surface->output);
+ if (layer) {
+ seat_set_focus_layer(seat, layer->layer_surface);
+ }
+ }
+
sway_layer->layer_surface->output = NULL;
wlr_layer_surface_v1_close(sway_layer->layer_surface);
}
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 15c56a43..415f85ac 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -800,9 +800,6 @@ void seat_set_focus_workspace(struct sway_seat *seat,
void seat_set_focus_surface(struct sway_seat *seat,
struct wlr_surface *surface, bool unfocus) {
- if (seat->focused_layer != NULL) {
- return;
- }
if (seat->has_focus && unfocus) {
struct sway_node *focus = seat_get_focus(seat);
seat_send_unfocus(focus, seat);