mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2024-11-25 16:42:26 +00:00
xwayland/xwm: add support for xwayland-shell-v1
This commit is contained in:
parent
85b37127a6
commit
4ff46e6cf9
@ -21,6 +21,7 @@ struct wlr_drag;
|
|||||||
struct wlr_xwayland {
|
struct wlr_xwayland {
|
||||||
struct wlr_xwayland_server *server;
|
struct wlr_xwayland_server *server;
|
||||||
struct wlr_xwm *xwm;
|
struct wlr_xwm *xwm;
|
||||||
|
struct wlr_xwayland_shell_v1 *shell_v1;
|
||||||
struct wlr_xwayland_cursor *cursor;
|
struct wlr_xwayland_cursor *cursor;
|
||||||
|
|
||||||
const char *display_name;
|
const char *display_name;
|
||||||
@ -42,6 +43,7 @@ struct wlr_xwayland {
|
|||||||
*/
|
*/
|
||||||
int (*user_event_handler)(struct wlr_xwm *xwm, xcb_generic_event_t *event);
|
int (*user_event_handler)(struct wlr_xwm *xwm, xcb_generic_event_t *event);
|
||||||
|
|
||||||
|
struct wl_listener server_start;
|
||||||
struct wl_listener server_ready;
|
struct wl_listener server_ready;
|
||||||
struct wl_listener server_destroy;
|
struct wl_listener server_destroy;
|
||||||
struct wl_listener seat_destroy;
|
struct wl_listener seat_destroy;
|
||||||
@ -80,6 +82,7 @@ struct wlr_xwayland_surface {
|
|||||||
xcb_window_t window_id;
|
xcb_window_t window_id;
|
||||||
struct wlr_xwm *xwm;
|
struct wlr_xwm *xwm;
|
||||||
uint32_t surface_id;
|
uint32_t surface_id;
|
||||||
|
uint64_t serial;
|
||||||
|
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
struct wl_list stack_link;
|
struct wl_list stack_link;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
enum atom_name {
|
enum atom_name {
|
||||||
WL_SURFACE_ID,
|
WL_SURFACE_ID,
|
||||||
|
WL_SURFACE_SERIAL,
|
||||||
WM_DELETE_WINDOW,
|
WM_DELETE_WINDOW,
|
||||||
WM_PROTOCOLS,
|
WM_PROTOCOLS,
|
||||||
WM_HINTS,
|
WM_HINTS,
|
||||||
@ -130,6 +131,7 @@ struct wlr_xwm {
|
|||||||
|
|
||||||
struct wl_listener compositor_new_surface;
|
struct wl_listener compositor_new_surface;
|
||||||
struct wl_listener compositor_destroy;
|
struct wl_listener compositor_destroy;
|
||||||
|
struct wl_listener shell_v1_new_surface;
|
||||||
struct wl_listener seat_set_selection;
|
struct wl_listener seat_set_selection;
|
||||||
struct wl_listener seat_set_primary_selection;
|
struct wl_listener seat_set_primary_selection;
|
||||||
struct wl_listener seat_start_drag;
|
struct wl_listener seat_start_drag;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wlr/types/wlr_seat.h>
|
#include <wlr/types/wlr_seat.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
|
#include <wlr/xwayland/shell.h>
|
||||||
#include <wlr/xwayland/xwayland.h>
|
#include <wlr/xwayland/xwayland.h>
|
||||||
#include "sockets.h"
|
#include "sockets.h"
|
||||||
#include "xwayland/xwm.h"
|
#include "xwayland/xwm.h"
|
||||||
@ -33,6 +34,12 @@ static void handle_server_destroy(struct wl_listener *listener, void *data) {
|
|||||||
wlr_xwayland_destroy(xwayland);
|
wlr_xwayland_destroy(xwayland);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_server_start(struct wl_listener *listener, void *data) {
|
||||||
|
struct wlr_xwayland *xwayland =
|
||||||
|
wl_container_of(listener, xwayland, server_start);
|
||||||
|
wlr_xwayland_shell_v1_set_client(xwayland->shell_v1, xwayland->server->client);
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_server_ready(struct wl_listener *listener, void *data) {
|
static void handle_server_ready(struct wl_listener *listener, void *data) {
|
||||||
struct wlr_xwayland *xwayland =
|
struct wlr_xwayland *xwayland =
|
||||||
wl_container_of(listener, xwayland, server_ready);
|
wl_container_of(listener, xwayland, server_ready);
|
||||||
@ -62,11 +69,13 @@ void wlr_xwayland_destroy(struct wlr_xwayland *xwayland) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
wl_list_remove(&xwayland->server_destroy.link);
|
wl_list_remove(&xwayland->server_destroy.link);
|
||||||
|
wl_list_remove(&xwayland->server_start.link);
|
||||||
wl_list_remove(&xwayland->server_ready.link);
|
wl_list_remove(&xwayland->server_ready.link);
|
||||||
free(xwayland->cursor);
|
free(xwayland->cursor);
|
||||||
|
|
||||||
wlr_xwayland_set_seat(xwayland, NULL);
|
wlr_xwayland_set_seat(xwayland, NULL);
|
||||||
wlr_xwayland_server_destroy(xwayland->server);
|
wlr_xwayland_server_destroy(xwayland->server);
|
||||||
|
wlr_xwayland_shell_v1_destroy(xwayland->shell_v1);
|
||||||
free(xwayland);
|
free(xwayland);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +93,12 @@ struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display,
|
|||||||
wl_signal_init(&xwayland->events.ready);
|
wl_signal_init(&xwayland->events.ready);
|
||||||
wl_signal_init(&xwayland->events.remove_startup_info);
|
wl_signal_init(&xwayland->events.remove_startup_info);
|
||||||
|
|
||||||
|
xwayland->shell_v1 = wlr_xwayland_shell_v1_create(wl_display, 1);
|
||||||
|
if (xwayland->shell_v1 == NULL) {
|
||||||
|
free(xwayland);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_xwayland_server_options options = {
|
struct wlr_xwayland_server_options options = {
|
||||||
.lazy = lazy,
|
.lazy = lazy,
|
||||||
.enable_wm = true,
|
.enable_wm = true,
|
||||||
@ -93,6 +108,7 @@ struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display,
|
|||||||
};
|
};
|
||||||
xwayland->server = wlr_xwayland_server_create(wl_display, &options);
|
xwayland->server = wlr_xwayland_server_create(wl_display, &options);
|
||||||
if (xwayland->server == NULL) {
|
if (xwayland->server == NULL) {
|
||||||
|
wlr_xwayland_shell_v1_destroy(xwayland->shell_v1);
|
||||||
free(xwayland);
|
free(xwayland);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -102,6 +118,9 @@ struct wlr_xwayland *wlr_xwayland_create(struct wl_display *wl_display,
|
|||||||
xwayland->server_destroy.notify = handle_server_destroy;
|
xwayland->server_destroy.notify = handle_server_destroy;
|
||||||
wl_signal_add(&xwayland->server->events.destroy, &xwayland->server_destroy);
|
wl_signal_add(&xwayland->server->events.destroy, &xwayland->server_destroy);
|
||||||
|
|
||||||
|
xwayland->server_start.notify = handle_server_start;
|
||||||
|
wl_signal_add(&xwayland->server->events.start, &xwayland->server_start);
|
||||||
|
|
||||||
xwayland->server_ready.notify = handle_server_ready;
|
xwayland->server_ready.notify = handle_server_ready;
|
||||||
wl_signal_add(&xwayland->server->events.ready, &xwayland->server_ready);
|
wl_signal_add(&xwayland->server->events.ready, &xwayland->server_ready);
|
||||||
|
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
#include <wlr/util/edges.h>
|
#include <wlr/util/edges.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <wlr/xcursor.h>
|
#include <wlr/xcursor.h>
|
||||||
#include <wlr/xwayland.h>
|
#include <wlr/xwayland/shell.h>
|
||||||
|
#include <wlr/xwayland/xwayland.h>
|
||||||
#include <xcb/composite.h>
|
#include <xcb/composite.h>
|
||||||
#include <xcb/render.h>
|
#include <xcb/render.h>
|
||||||
#include <xcb/res.h>
|
#include <xcb/res.h>
|
||||||
@ -20,6 +21,7 @@
|
|||||||
|
|
||||||
const char *const atom_map[ATOM_LAST] = {
|
const char *const atom_map[ATOM_LAST] = {
|
||||||
[WL_SURFACE_ID] = "WL_SURFACE_ID",
|
[WL_SURFACE_ID] = "WL_SURFACE_ID",
|
||||||
|
[WL_SURFACE_SERIAL] = "WL_SURFACE_SERIAL",
|
||||||
[WM_DELETE_WINDOW] = "WM_DELETE_WINDOW",
|
[WM_DELETE_WINDOW] = "WM_DELETE_WINDOW",
|
||||||
[WM_PROTOCOLS] = "WM_PROTOCOLS",
|
[WM_PROTOCOLS] = "WM_PROTOCOLS",
|
||||||
[WM_HINTS] = "WM_HINTS",
|
[WM_HINTS] = "WM_HINTS",
|
||||||
@ -1118,6 +1120,35 @@ static void xwm_handle_surface_id_message(struct wlr_xwm *xwm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xwm_handle_surface_serial_message(struct wlr_xwm *xwm,
|
||||||
|
xcb_client_message_event_t *ev) {
|
||||||
|
struct wlr_xwayland_surface *xsurface = lookup_surface(xwm, ev->window);
|
||||||
|
if (xsurface == NULL) {
|
||||||
|
wlr_log(WLR_DEBUG,
|
||||||
|
"Received client message WL_SURFACE_SERIAL but no X11 window %u",
|
||||||
|
ev->window);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (xsurface->serial != 0) {
|
||||||
|
wlr_log(WLR_DEBUG, "Received multiple client messages WL_SURFACE_SERIAL "
|
||||||
|
"for the same X11 window %u", ev->window);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t serial_lo = ev->data.data32[0];
|
||||||
|
uint32_t serial_hi = ev->data.data32[1];
|
||||||
|
xsurface->serial = ((uint64_t)serial_hi << 32) | serial_lo;
|
||||||
|
|
||||||
|
struct wlr_surface *surface = wlr_xwayland_shell_v1_surface_from_serial(
|
||||||
|
xwm->xwayland->shell_v1, xsurface->serial);
|
||||||
|
if (surface != NULL) {
|
||||||
|
xwm_map_shell_surface(xwm, xsurface, surface);
|
||||||
|
} else {
|
||||||
|
wl_list_remove(&xsurface->unpaired_link);
|
||||||
|
wl_list_insert(&xwm->unpaired_surfaces, &xsurface->unpaired_link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
|
#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
|
||||||
#define _NET_WM_MOVERESIZE_SIZE_TOP 1
|
#define _NET_WM_MOVERESIZE_SIZE_TOP 1
|
||||||
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
|
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
|
||||||
@ -1430,6 +1461,8 @@ static void xwm_handle_client_message(struct wlr_xwm *xwm,
|
|||||||
xcb_client_message_event_t *ev) {
|
xcb_client_message_event_t *ev) {
|
||||||
if (ev->type == xwm->atoms[WL_SURFACE_ID]) {
|
if (ev->type == xwm->atoms[WL_SURFACE_ID]) {
|
||||||
xwm_handle_surface_id_message(xwm, ev);
|
xwm_handle_surface_id_message(xwm, ev);
|
||||||
|
} else if (ev->type == xwm->atoms[WL_SURFACE_SERIAL]) {
|
||||||
|
xwm_handle_surface_serial_message(xwm, ev);
|
||||||
} else if (ev->type == xwm->atoms[NET_WM_STATE]) {
|
} else if (ev->type == xwm->atoms[NET_WM_STATE]) {
|
||||||
xwm_handle_net_wm_state_message(xwm, ev);
|
xwm_handle_net_wm_state_message(xwm, ev);
|
||||||
} else if (ev->type == xwm->atoms[NET_WM_MOVERESIZE]) {
|
} else if (ev->type == xwm->atoms[NET_WM_MOVERESIZE]) {
|
||||||
@ -1656,6 +1689,20 @@ static void handle_compositor_destroy(struct wl_listener *listener,
|
|||||||
wl_list_init(&xwm->compositor_destroy.link);
|
wl_list_init(&xwm->compositor_destroy.link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_shell_v1_new_surface(struct wl_listener *listener,
|
||||||
|
void *data) {
|
||||||
|
struct wlr_xwm *xwm = wl_container_of(listener, xwm, shell_v1_new_surface);
|
||||||
|
struct wlr_xwayland_surface_v1 *shell_surface = data;
|
||||||
|
|
||||||
|
struct wlr_xwayland_surface *xsurface;
|
||||||
|
wl_list_for_each(xsurface, &xwm->unpaired_surfaces, unpaired_link) {
|
||||||
|
if (xsurface->serial == shell_surface->serial) {
|
||||||
|
xwm_map_shell_surface(xwm, xsurface, shell_surface->surface);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void wlr_xwayland_surface_activate(struct wlr_xwayland_surface *xsurface,
|
void wlr_xwayland_surface_activate(struct wlr_xwayland_surface *xsurface,
|
||||||
bool activated) {
|
bool activated) {
|
||||||
struct wlr_xwayland_surface *focused = xsurface->xwm->focus_surface;
|
struct wlr_xwayland_surface *focused = xsurface->xwm->focus_surface;
|
||||||
@ -1756,6 +1803,7 @@ void xwm_destroy(struct wlr_xwm *xwm) {
|
|||||||
}
|
}
|
||||||
wl_list_remove(&xwm->compositor_new_surface.link);
|
wl_list_remove(&xwm->compositor_new_surface.link);
|
||||||
wl_list_remove(&xwm->compositor_destroy.link);
|
wl_list_remove(&xwm->compositor_destroy.link);
|
||||||
|
wl_list_remove(&xwm->shell_v1_new_surface.link);
|
||||||
xcb_disconnect(xwm->xcb_conn);
|
xcb_disconnect(xwm->xcb_conn);
|
||||||
|
|
||||||
struct pending_startup_id *pending, *next;
|
struct pending_startup_id *pending, *next;
|
||||||
@ -2097,6 +2145,10 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
|
|||||||
wl_signal_add(&xwayland->compositor->events.destroy,
|
wl_signal_add(&xwayland->compositor->events.destroy,
|
||||||
&xwm->compositor_destroy);
|
&xwm->compositor_destroy);
|
||||||
|
|
||||||
|
xwm->shell_v1_new_surface.notify = handle_shell_v1_new_surface;
|
||||||
|
wl_signal_add(&xwayland->shell_v1->events.new_surface,
|
||||||
|
&xwm->shell_v1_new_surface);
|
||||||
|
|
||||||
xwm_create_wm_window(xwm);
|
xwm_create_wm_window(xwm);
|
||||||
|
|
||||||
xcb_flush(xwm->xcb_conn);
|
xcb_flush(xwm->xcb_conn);
|
||||||
|
Loading…
Reference in New Issue
Block a user