aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sway/desktop/xwayland.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 8936c8bc..4bf5b6b8 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -94,6 +94,22 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) {
struct sway_seat *seat = input_manager_current_seat();
if (seat->wlr_seat->keyboard_state.focused_surface ==
xsurface->surface) {
+
+ // Try to find another unmanaged surface from the same process to pass
+ // focus to. This is necessary because some applications (e.g. Jetbrains
+ // IDEs) represent their multi-level menus as unmanaged surfaces, and
+ // when closing a submenu, the main menu should get input focus.
+ struct sway_xwayland_unmanaged *current;
+ wl_list_for_each(current, &root->xwayland_unmanaged, link) {
+ struct wlr_xwayland_surface *prev_xsurface =
+ current->wlr_xwayland_surface;
+ if (prev_xsurface->pid == xsurface->pid &&
+ wlr_xwayland_or_surface_wants_focus(prev_xsurface)) {
+ seat_set_focus_surface(seat, prev_xsurface->surface, false);
+ return;
+ }
+ }
+
// Restore focus
struct sway_node *previous = seat_get_focus_inactive(seat, &root->node);
if (previous) {