]> git.mdlowis.com Git - proto/labwc.git/commitdiff
xwayland: use wlr_xwayland_surface_has_window_type()
authorJohn Lindgren <john@jlindgren.net>
Wed, 21 May 2025 15:43:50 +0000 (11:43 -0400)
committerJohan Malm <johanmalm@users.noreply.github.com>
Thu, 22 May 2025 22:09:41 +0000 (23:09 +0100)
This eliminates a bit of logic, including an extra XWayland connection.

See also:
https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4553

include/view.h
include/xwayland.h
src/xdg.c
src/xwayland.c

index f551f854562cefc5a6ed1dbe22699925aed964b3..e26cff322694160854506f92957033fb949e86ab 100644 (file)
@@ -84,8 +84,15 @@ enum view_wants_focus {
        VIEW_WANTS_FOCUS_OFFER,
 };
 
+/*
+ * Window types are based on the NET_WM constants from X11. See:
+ *   https://specifications.freedesktop.org/wm-spec/1.4/ar01s05.html#id-1.6.7
+ *
+ * The enum constants are intended to match wlr_xwayland_net_wm_window_type.
+ * Redefining the same constants here may seem redundant, but is necessary
+ * to make them available even in builds with xwayland support disabled.
+ */
 enum window_type {
-       /* https://specifications.freedesktop.org/wm-spec/wm-spec-1.4.html#idm45649101374512 */
        NET_WM_WINDOW_TYPE_DESKTOP = 0,
        NET_WM_WINDOW_TYPE_DOCK,
        NET_WM_WINDOW_TYPE_TOOLBAR,
@@ -151,7 +158,8 @@ struct view_impl {
        /* returns true if view reserves space at screen edge */
        bool (*has_strut_partial)(struct view *self);
        /* returns true if view declared itself a window type */
-       bool (*contains_window_type)(struct view *view, int32_t window_type);
+       bool (*contains_window_type)(struct view *view,
+               enum window_type window_type);
        /* returns the client pid that this view belongs to */
        pid_t (*get_pid)(struct view *view);
 };
index 3afea406ce963e7f7e58728781be0c995e06778f..c202d37d4a6d610ccf94fb8366865a2f2609f01f 100644 (file)
@@ -4,39 +4,12 @@
 #include "config.h"
 
 #if HAVE_XWAYLAND
-#include <assert.h>
-#include <stdbool.h>
-#include <xcb/xcb.h>
-#include "common/macros.h"
 #include "view.h"
 
 struct wlr_compositor;
 struct wlr_output;
 struct wlr_output_layout;
 
-static const char * const atom_names[] = {
-       "_NET_WM_WINDOW_TYPE_DESKTOP",
-       "_NET_WM_WINDOW_TYPE_DOCK",
-       "_NET_WM_WINDOW_TYPE_TOOLBAR",
-       "_NET_WM_WINDOW_TYPE_MENU",
-       "_NET_WM_WINDOW_TYPE_UTILITY",
-       "_NET_WM_WINDOW_TYPE_SPLASH",
-       "_NET_WM_WINDOW_TYPE_DIALOG",
-       "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU",
-       "_NET_WM_WINDOW_TYPE_POPUP_MENU",
-       "_NET_WM_WINDOW_TYPE_TOOLTIP",
-       "_NET_WM_WINDOW_TYPE_NOTIFICATION",
-       "_NET_WM_WINDOW_TYPE_COMBO",
-       "_NET_WM_WINDOW_TYPE_DND",
-       "_NET_WM_WINDOW_TYPE_NORMAL",
-};
-
-static_assert(
-       ARRAY_SIZE(atom_names) == WINDOW_TYPE_LEN,
-       "Xwayland atoms out of sync");
-
-extern xcb_atom_t atoms[WINDOW_TYPE_LEN];
-
 struct xwayland_unmanaged {
        struct server *server;
        struct wlr_xwayland_surface *xwayland_surface;
index cebc5e393c8d23edc206ebb9280e17d546927192..656ee1391d76d184b22de955f4971a74fad59b40 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -60,7 +60,8 @@ xdg_toplevel_view_get_size_hints(struct view *view)
 }
 
 static bool
-xdg_toplevel_view_contains_window_type(struct view *view, int32_t window_type)
+xdg_toplevel_view_contains_window_type(struct view *view,
+               enum window_type window_type)
 {
        assert(view);
 
index c64dd3e87c0c3fba5e3c3776c801bc991e034cfa..ba3868090eeee362d375f6aafa34cdca836ea7d8 100644 (file)
@@ -3,7 +3,6 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <wlr/xwayland.h>
-#include "common/array.h"
 #include "common/macros.h"
 #include "common/mem.h"
 #include "config/rcxml.h"
 #include "workspaces.h"
 #include "xwayland.h"
 
-xcb_atom_t atoms[WINDOW_TYPE_LEN] = {0};
-
 static void xwayland_view_unmap(struct view *view, bool client_request);
 
 static bool
-xwayland_surface_contains_window_type(
-               struct wlr_xwayland_surface *surface, enum window_type window_type)
+xwayland_view_contains_window_type(struct view *view,
+               enum window_type window_type)
 {
-       assert(surface);
-       for (size_t i = 0; i < surface->window_type_len; i++) {
-               if (surface->window_type[i] == atoms[window_type]) {
-                       return true;
-               }
-       }
-       return false;
-}
+       /* Compile-time check that the enum types match */
+       static_assert(NET_WM_WINDOW_TYPE_DESKTOP ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DESKTOP
+               && NET_WM_WINDOW_TYPE_DOCK ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DOCK
+               && NET_WM_WINDOW_TYPE_TOOLBAR ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_TOOLBAR
+               && NET_WM_WINDOW_TYPE_MENU ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_MENU
+               && NET_WM_WINDOW_TYPE_UTILITY ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_UTILITY
+               && NET_WM_WINDOW_TYPE_SPLASH ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_SPLASH
+               && NET_WM_WINDOW_TYPE_DIALOG ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DIALOG
+               && NET_WM_WINDOW_TYPE_DROPDOWN_MENU ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DROPDOWN_MENU
+               && NET_WM_WINDOW_TYPE_POPUP_MENU ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_POPUP_MENU
+               && NET_WM_WINDOW_TYPE_TOOLTIP ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_TOOLTIP
+               && NET_WM_WINDOW_TYPE_NOTIFICATION ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_NOTIFICATION
+               && NET_WM_WINDOW_TYPE_COMBO ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_COMBO
+               && NET_WM_WINDOW_TYPE_DND ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DND
+               && NET_WM_WINDOW_TYPE_NORMAL ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_NORMAL
+               && WINDOW_TYPE_LEN ==
+                       (int)WLR_XWAYLAND_NET_WM_WINDOW_TYPE_NORMAL + 1,
+               "enum window_type does not match wlr_xwayland_net_wm_window_type");
 
-static bool
-xwayland_view_contains_window_type(struct view *view, int32_t window_type)
-{
        assert(view);
        struct wlr_xwayland_surface *surface = xwayland_surface_from_view(view);
-       return xwayland_surface_contains_window_type(surface, window_type);
+       return wlr_xwayland_surface_has_window_type(surface,
+               (enum wlr_xwayland_net_wm_window_type)window_type);
 }
 
 static struct view_size_hints
@@ -102,10 +121,10 @@ xwayland_view_wants_focus(struct view *view)
                 * Alt-Tab switcher and be automatically focused when
                 * they become topmost.
                 */
-               return (xwayland_surface_contains_window_type(xsurface,
-                               NET_WM_WINDOW_TYPE_NORMAL)
-                       || xwayland_surface_contains_window_type(xsurface,
-                               NET_WM_WINDOW_TYPE_DIALOG)) ?
+               return (wlr_xwayland_surface_has_window_type(xsurface,
+                               WLR_XWAYLAND_NET_WM_WINDOW_TYPE_NORMAL)
+                       || wlr_xwayland_surface_has_window_type(xsurface,
+                               WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DIALOG)) ?
                        VIEW_WANTS_FOCUS_ALWAYS : VIEW_WANTS_FOCUS_OFFER;
 
        /*
@@ -1012,59 +1031,11 @@ handle_new_surface(struct wl_listener *listener, void *data)
        }
 }
 
-static void
-sync_atoms(xcb_connection_t *xcb_conn)
-{
-       assert(xcb_conn);
-
-       wlr_log(WLR_DEBUG, "Syncing X11 atoms");
-       xcb_intern_atom_cookie_t cookies[WINDOW_TYPE_LEN];
-
-       /* First request everything and then loop over the results to reduce latency */
-       for (size_t i = 0; i < WINDOW_TYPE_LEN; i++) {
-               cookies[i] = xcb_intern_atom(xcb_conn, 0,
-                       strlen(atom_names[i]), atom_names[i]);
-       }
-
-       for (size_t i = 0; i < WINDOW_TYPE_LEN; i++) {
-               xcb_generic_error_t *err = NULL;
-               xcb_intern_atom_reply_t *reply =
-                       xcb_intern_atom_reply(xcb_conn, cookies[i], &err);
-               if (reply) {
-                       atoms[i] = reply->atom;
-                       wlr_log(WLR_DEBUG, "Got X11 atom for %s: %u",
-                               atom_names[i], reply->atom);
-               }
-               if (err) {
-                       wlr_log(WLR_INFO, "Failed to get X11 atom for %s",
-                               atom_names[i]);
-               }
-               free(reply);
-               free(err);
-       }
-}
-
 static void
 handle_server_ready(struct wl_listener *listener, void *data)
 {
        /* Fire an Xwayland startup script if one (or many) can be found */
        session_run_script("xinitrc");
-
-       xcb_connection_t *xcb_conn = xcb_connect(NULL, NULL);
-       if (xcb_connection_has_error(xcb_conn)) {
-               wlr_log(WLR_ERROR, "Failed to create xcb connection");
-
-               /* Just clear all existing atoms */
-               for (size_t i = 0; i < WINDOW_TYPE_LEN; i++) {
-                       atoms[i] = XCB_ATOM_NONE;
-               }
-               return;
-       }
-
-       wlr_log(WLR_DEBUG, "Connected to xwayland");
-       sync_atoms(xcb_conn);
-       wlr_log(WLR_DEBUG, "Disconnecting from xwayland");
-       xcb_disconnect(xcb_conn);
 }
 
 static void