mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
xwayland: support querying window types
This commit is contained in:
parent
9ecd8c2b43
commit
a04b394e59
3 changed files with 137 additions and 6 deletions
|
|
@ -220,7 +220,8 @@ struct server {
|
|||
struct wl_listener xdg_toplevel_decoration;
|
||||
#if HAVE_XWAYLAND
|
||||
struct wlr_xwayland *xwayland;
|
||||
struct wl_listener xwayland_ready;
|
||||
struct wl_listener xwayland_server_ready;
|
||||
struct wl_listener xwayland_xwm_ready;
|
||||
struct wl_listener xwayland_new_surface;
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -2,13 +2,61 @@
|
|||
#ifndef LABWC_XWAYLAND_H
|
||||
#define LABWC_XWAYLAND_H
|
||||
#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;
|
||||
|
||||
enum atom {
|
||||
/* 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,
|
||||
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,
|
||||
|
||||
ATOM_LEN
|
||||
};
|
||||
|
||||
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) == ATOM_LEN,
|
||||
"Xwayland atoms out of sync");
|
||||
|
||||
extern xcb_atom_t atoms[ATOM_LEN];
|
||||
|
||||
struct xwayland_unmanaged {
|
||||
struct server *server;
|
||||
struct wlr_xwayland_surface *xwayland_surface;
|
||||
|
|
@ -40,10 +88,10 @@ struct xwayland_view {
|
|||
struct wl_listener set_decorations;
|
||||
struct wl_listener set_override_redirect;
|
||||
struct wl_listener set_strut_partial;
|
||||
struct wl_listener set_window_type;
|
||||
|
||||
/* Not (yet) implemented */
|
||||
/* struct wl_listener set_role; */
|
||||
/* struct wl_listener set_window_type; */
|
||||
/* struct wl_listener set_hints; */
|
||||
};
|
||||
|
||||
|
|
@ -57,6 +105,9 @@ void xwayland_adjust_stacking_order(struct server *server);
|
|||
|
||||
struct wlr_xwayland_surface *xwayland_surface_from_view(struct view *view);
|
||||
|
||||
bool xwayland_surface_contains_window_type(
|
||||
struct wlr_xwayland_surface *surface, enum atom window_type);
|
||||
|
||||
void xwayland_server_init(struct server *server,
|
||||
struct wlr_compositor *compositor);
|
||||
void xwayland_server_finish(struct server *server);
|
||||
|
|
|
|||
|
|
@ -15,8 +15,23 @@
|
|||
#include "workspaces.h"
|
||||
#include "xwayland.h"
|
||||
|
||||
xcb_atom_t atoms[ATOM_LEN] = {0};
|
||||
|
||||
static void xwayland_view_unmap(struct view *view, bool client_request);
|
||||
|
||||
bool
|
||||
xwayland_surface_contains_window_type(
|
||||
struct wlr_xwayland_surface *surface, enum atom 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;
|
||||
}
|
||||
|
||||
static struct view_size_hints
|
||||
xwayland_view_get_size_hints(struct view *view)
|
||||
{
|
||||
|
|
@ -313,6 +328,7 @@ handle_destroy(struct wl_listener *listener, void *data)
|
|||
wl_list_remove(&xwayland_view->set_decorations.link);
|
||||
wl_list_remove(&xwayland_view->set_override_redirect.link);
|
||||
wl_list_remove(&xwayland_view->set_strut_partial.link);
|
||||
wl_list_remove(&xwayland_view->set_window_type.link);
|
||||
|
||||
view_destroy(view);
|
||||
}
|
||||
|
|
@ -478,6 +494,12 @@ handle_set_decorations(struct wl_listener *listener, void *data)
|
|||
view_set_decorations(view, want_deco(xwayland_view->xwayland_surface));
|
||||
}
|
||||
|
||||
static void
|
||||
handle_set_window_type(struct wl_listener *listener, void *data)
|
||||
{
|
||||
/* Intentionally left blank */
|
||||
}
|
||||
|
||||
static void
|
||||
handle_set_override_redirect(struct wl_listener *listener, void *data)
|
||||
{
|
||||
|
|
@ -865,6 +887,7 @@ xwayland_view_create(struct server *server,
|
|||
CONNECT_SIGNAL(xsurface, xwayland_view, set_decorations);
|
||||
CONNECT_SIGNAL(xsurface, xwayland_view, set_override_redirect);
|
||||
CONNECT_SIGNAL(xsurface, xwayland_view, set_strut_partial);
|
||||
CONNECT_SIGNAL(xsurface, xwayland_view, set_window_type);
|
||||
|
||||
wl_list_insert(&view->server->views, &view->link);
|
||||
|
||||
|
|
@ -896,10 +919,62 @@ handle_new_surface(struct wl_listener *listener, void *data)
|
|||
}
|
||||
|
||||
static void
|
||||
handle_ready(struct wl_listener *listener, void *data)
|
||||
sync_atoms(xcb_connection_t *xcb_conn)
|
||||
{
|
||||
assert(xcb_conn);
|
||||
|
||||
wlr_log(WLR_DEBUG, "Syncing X11 atoms");
|
||||
xcb_intern_atom_cookie_t cookies[ATOM_LEN];
|
||||
|
||||
/* First request everything and then loop over the results to reduce latency */
|
||||
for (size_t i = 0; i < ATOM_LEN; i++) {
|
||||
cookies[i] = xcb_intern_atom(xcb_conn, 0,
|
||||
strlen(atom_names[i]), atom_names[i]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ATOM_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)
|
||||
{
|
||||
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 < ATOM_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
|
||||
handle_xwm_ready(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct server *server =
|
||||
wl_container_of(listener, server, xwayland_ready);
|
||||
wl_container_of(listener, server, xwayland_xwm_ready);
|
||||
wlr_xwayland_set_seat(server->xwayland, server->seat.seat);
|
||||
xwayland_update_workarea(server);
|
||||
}
|
||||
|
|
@ -917,9 +992,13 @@ xwayland_server_init(struct server *server, struct wlr_compositor *compositor)
|
|||
wl_signal_add(&server->xwayland->events.new_surface,
|
||||
&server->xwayland_new_surface);
|
||||
|
||||
server->xwayland_ready.notify = handle_ready;
|
||||
server->xwayland_server_ready.notify = handle_server_ready;
|
||||
wl_signal_add(&server->xwayland->server->events.ready,
|
||||
&server->xwayland_server_ready);
|
||||
|
||||
server->xwayland_xwm_ready.notify = handle_xwm_ready;
|
||||
wl_signal_add(&server->xwayland->events.ready,
|
||||
&server->xwayland_ready);
|
||||
&server->xwayland_xwm_ready);
|
||||
|
||||
if (setenv("DISPLAY", server->xwayland->display_name, true) < 0) {
|
||||
wlr_log_errno(WLR_ERROR, "unable to set DISPLAY for xwayland");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue