From 5c4038493f982deef2f667eb77eddd30b56023ad Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Sun, 15 Oct 2023 00:15:16 -0400 Subject: [PATCH] view: add view_is_related() Allows removing xwayland-specific stuff from seat.c. Based on a suggestion from @Consolatis. v2: add comments --- include/view.h | 10 ++++++++++ src/seat.c | 25 ++++--------------------- src/view.c | 11 +++++++++++ src/xwayland.c | 13 +++++++++++++ 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/include/view.h b/include/view.h index 09d516e5..9379d1e6 100644 --- a/include/view.h +++ b/include/view.h @@ -37,6 +37,7 @@ enum view_edge { }; struct view; +struct wlr_surface; /* Basic size hints (subset of XSizeHints from X11) */ struct view_size_hints { @@ -68,6 +69,8 @@ struct view_impl { void (*move_to_back)(struct view *view); struct view *(*get_root)(struct view *self); void (*append_children)(struct view *self, struct wl_array *children); + /* determines if view and surface are owned by the same process */ + bool (*is_related)(struct view *self, struct wlr_surface *surface); struct view_size_hints (*get_size_hints)(struct view *self); /* if not implemented, view is assumed to want focus */ bool (*wants_focus)(struct view *self); @@ -342,6 +345,13 @@ void view_move_to_back(struct view *view); struct view *view_get_root(struct view *view); void view_append_children(struct view *view, struct wl_array *children); +/** + * view_is_related() - determine if view and surface are owned by the + * same application/process. Currently only implemented for xwayland + * views/surfaces. + */ +bool view_is_related(struct view *view, struct wlr_surface *surface); + const char *view_get_string_prop(struct view *view, const char *prop); void view_update_title(struct view *view); void view_update_app_id(struct view *view); diff --git a/src/seat.c b/src/seat.c index 9dc47d27..7852180d 100644 --- a/src/seat.c +++ b/src/seat.c @@ -13,10 +13,6 @@ #include "labwc.h" #include "view.h" -#if HAVE_XWAYLAND -#include -#endif - static void input_device_destroy(struct wl_listener *listener, void *data) { @@ -357,30 +353,17 @@ 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; - } + if (!view && server->focused_view && event->new_surface + && view_is_related(server->focused_view, + event->new_surface)) { + return; } -#endif if (view != server->focused_view) { if (server->focused_view) { diff --git a/src/view.c b/src/view.c index 1f88327f..94f2d82a 100644 --- a/src/view.c +++ b/src/view.c @@ -1285,6 +1285,17 @@ view_append_children(struct view *view, struct wl_array *children) } } +bool +view_is_related(struct view *view, struct wlr_surface *surface) +{ + assert(view); + assert(surface); + if (view->impl->is_related) { + return view->impl->is_related(view, surface); + } + return false; +} + const char * view_get_string_prop(struct view *view, const char *prop) { diff --git a/src/xwayland.c b/src/xwayland.c index 265e63d9..97337c45 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -614,6 +614,18 @@ xwayland_view_append_children(struct view *self, struct wl_array *children) } } +static bool +xwayland_view_is_related(struct view *view, struct wlr_surface *surface) +{ + struct wlr_xwayland_surface *xsurface = + xwayland_surface_from_view(view); + struct wlr_xwayland_surface *xsurface2 = + wlr_surface_is_xwayland_surface(surface) ? + wlr_xwayland_surface_from_wlr_surface(surface) : NULL; + + return (xsurface2 && xsurface2->pid == xsurface->pid); +} + static void xwayland_view_set_activated(struct view *view, bool activated) { @@ -659,6 +671,7 @@ static const struct view_impl xwayland_view_impl = { .move_to_back = xwayland_view_move_to_back, .get_root = xwayland_view_get_root, .append_children = xwayland_view_append_children, + .is_related = xwayland_view_is_related, .get_size_hints = xwayland_view_get_size_hints, .wants_focus = xwayland_view_wants_focus, };