]> git.mdlowis.com Git - proto/labwc.git/commitdiff
seat: ignore focus change to unmanaged surface belonging to same PID
authorJohn Lindgren <john@jlindgren.net>
Sat, 14 Oct 2023 16:41:31 +0000 (12:41 -0400)
committerJohn Lindgren <john@jlindgren.net>
Sat, 14 Oct 2023 17:38:19 +0000 (13:38 -0400)
If an xwayland-unmanaged surface was focused belonging to the same
application as the focused view, allow the view to remain active. This
fixes an issue with menus immediately closing in some X11 apps (try
LibreOffice with SAL_USE_VCLPLUGIN=gen).

Fixes: 4028a9482f9399e3c3587f5c6eca6c0b128c9afc
("seat: use focus_change event to update focused/active view")

src/seat.c

index f36c532c41096634c0053e071560d949df54ee63..9dc47d27e419d86aa6f222a0c8249ef9322c8197 100644 (file)
 #include "labwc.h"
 #include "view.h"
 
+#if HAVE_XWAYLAND
+#include <wlr/xwayland.h>
+#endif
+
 static void
 input_device_destroy(struct wl_listener *listener, void *data)
 {
@@ -353,6 +357,31 @@ focus_change_notify(struct wl_listener *listener, void *data)
        struct view *view = event->new_surface ?
                view_from_wlr_surface(event->new_surface) : NULL;
 
+#if HAVE_XWAYLAND
+       /*
+        * If an xwayland-unmanaged surface was focused belonging to the
+        * same application as the focused view, allow the view to remain
+        * active. This fixes an issue with menus immediately closing in
+        * some X11 apps (try LibreOffice with SAL_USE_VCLPLUGIN=gen).
+        */
+       struct wlr_surface *old_surface =
+               server->focused_view ? server->focused_view->surface : NULL;
+
+       if (old_surface && event->new_surface && !view
+                       && wlr_surface_is_xwayland_surface(old_surface)
+                       && wlr_surface_is_xwayland_surface(event->new_surface)) {
+               struct wlr_xwayland_surface *old_xsurface =
+                       wlr_xwayland_surface_from_wlr_surface(old_surface);
+               struct wlr_xwayland_surface *new_xsurface =
+                       wlr_xwayland_surface_from_wlr_surface(event->new_surface);
+
+               if (old_xsurface && new_xsurface
+                               && old_xsurface->pid == new_xsurface->pid) {
+                       return;
+               }
+       }
+#endif
+
        if (view != server->focused_view) {
                if (server->focused_view) {
                        view_set_activated(server->focused_view, false);