From a277c35c3d6f1f48efaab3a35bca8a6774c40a2d Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Mon, 16 Feb 2026 19:47:12 +0000 Subject: [PATCH] layer: on popup destory, return focus ...to whoever had it before the popop Co-authored-by: @tokyo4j --- include/layers.h | 1 + src/layers.c | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/include/layers.h b/include/layers.h index 6cb505c1..5e39868c 100644 --- a/include/layers.h +++ b/include/layers.h @@ -31,6 +31,7 @@ struct lab_layer_popup { struct wlr_scene_tree *scene_tree; struct server *server; struct lab_layer_surface *lab_layer_surface; + bool parent_was_focused; /* To simplify moving popup nodes from the bottom to the top layer */ struct wlr_box output_toplevel_sx_box; diff --git a/src/layers.c b/src/layers.c index 8326ed75..eef196f4 100644 --- a/src/layers.c +++ b/src/layers.c @@ -448,7 +448,13 @@ handle_popup_destroy(struct wl_listener *listener, void *data) wl_list_remove(&popup->commit.link); } - cursor_update_focus(popup->server); + /* Give focus back to whoever had it before the popup */ + if (popup->parent_was_focused && popup->wlr_popup->parent) { + struct seat *seat = &popup->server->seat; + seat_force_focus_surface(seat, popup->wlr_popup->parent); + } else { + desktop_focus_topmost_view(popup->server); + } free(popup); } @@ -512,12 +518,18 @@ handle_popup_commit(struct wl_listener *listener, void *data) wl_list_remove(&popup->commit.link); popup->commit.notify = NULL; - if (!seat->server->session_lock_manager->locked - && popup->wlr_popup->seat) { + /* Force focus when popup was triggered by IPC */ + struct server *server = popup->server; + struct seat *seat = &server->seat; + bool locked = server->session_lock_manager->locked; + if (seat->seat->keyboard_state.focused_surface + == popup->wlr_popup->parent) { + popup->parent_was_focused = true; + } + if (!locked && popup->wlr_popup->seat) { struct wlr_layer_surface_v1 *layer_surface = popup->lab_layer_surface->layer_surface; - seat_force_focus_surface(&popup->server->seat, - layer_surface->surface); + seat_force_focus_surface(seat, layer_surface->surface); } } }