From 7ca9ef12f8b6a00b8020a500433fabc6b645d85c Mon Sep 17 00:00:00 2001
From: BrassyPanache <brassy.panache@gmail.com>
Date: Wed, 26 Aug 2020 17:33:40 +1000
Subject: Re-focus on parent surface if it is available

My primary issue was IntelliJ IDEA's code suggestion pop-up not returning focus
to the active editing window.

I have spent some time looking at the changes of @Xyene (#5398) and
@RyanDwyer (#2103). I think my proposed change maintains the status
quo for the most part whilst fixing my focus issue.

I have verified that @Xyene's fix for IntelliJ sub-menus still works.

I have done basic testing which consists of:

- Chrome
- IntelliJ IDEA 2020.2.1
- VSCode
- Alacritty

It seems to hold up. I at least didn't see any obvious errors.

Relates to #3007
---
 sway/desktop/xwayland.c | 23 +++++++++--------------
 1 file changed, 9 insertions(+), 14 deletions(-)

(limited to 'sway/desktop')

diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index db21dc78..89b1a481 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -92,20 +92,15 @@ static void unmanaged_handle_unmap(struct wl_listener *listener, void *data) {
 	wl_list_remove(&surface->commit.link);
 
 	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);
+	if (seat->wlr_seat->keyboard_state.focused_surface == xsurface->surface) {
+		// This simply returns focus to the parent surface if there's one available.
+		// This seems to handle JetBrains issues.
+		if (xsurface->parent &&
+				wlr_surface_is_xwayland_surface(xsurface->parent->surface)) {
+			struct wlr_xwayland_surface *next_surface =
+				wlr_xwayland_surface_from_wlr_surface(xsurface->parent->surface);
+			if (wlr_xwayland_or_surface_wants_focus(next_surface)) {
+				seat_set_focus_surface(seat, xsurface->parent->surface, false);
 				return;
 			}
 		}
-- 
cgit v1.2.3