mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
xwayland: use wlr_xwayland_surface_has_window_type()
This eliminates a bit of logic, including an extra XWayland connection. See also: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4553
This commit is contained in:
parent
a3d6226728
commit
fd5031731e
4 changed files with 52 additions and 99 deletions
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
109
src/xwayland.c
109
src/xwayland.c
|
|
@ -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"
|
||||
|
|
@ -18,29 +17,49 @@
|
|||
#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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue