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,
/* 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);
};
#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;
#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
* 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;
/*
}
}
-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