diff options
-rw-r--r-- | sway/desktop/xwayland.c | 16 |
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) { | |||
94 | struct sway_seat *seat = input_manager_current_seat(); | 94 | struct sway_seat *seat = input_manager_current_seat(); |
95 | if (seat->wlr_seat->keyboard_state.focused_surface == | 95 | if (seat->wlr_seat->keyboard_state.focused_surface == |
96 | xsurface->surface) { | 96 | xsurface->surface) { |
97 | |||
98 | // Try to find another unmanaged surface from the same process to pass | ||
99 | // focus to. This is necessary because some applications (e.g. Jetbrains | ||
100 | // IDEs) represent their multi-level menus as unmanaged surfaces, and | ||
101 | // when closing a submenu, the main menu should get input focus. | ||
102 | struct sway_xwayland_unmanaged *current; | ||
103 | wl_list_for_each(current, &root->xwayland_unmanaged, link) { | ||
104 | struct wlr_xwayland_surface *prev_xsurface = | ||
105 | current->wlr_xwayland_surface; | ||
106 | if (prev_xsurface->pid == xsurface->pid && | ||
107 | wlr_xwayland_or_surface_wants_focus(prev_xsurface)) { | ||
108 | seat_set_focus_surface(seat, prev_xsurface->surface, false); | ||
109 | return; | ||
110 | } | ||
111 | } | ||
112 | |||
97 | // Restore focus | 113 | // Restore focus |
98 | struct sway_node *previous = seat_get_focus_inactive(seat, &root->node); | 114 | struct sway_node *previous = seat_get_focus_inactive(seat, &root->node); |
99 | if (previous) { | 115 | if (previous) { |