mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-17 06:46:39 -04:00
Merge branch 'xwayland-async-prop' into 'master'
xwayland: add support for asynchronous reply handlers See merge request wlroots/wlroots!4304
This commit is contained in:
commit
95459e8250
2 changed files with 81 additions and 13 deletions
|
|
@ -93,6 +93,17 @@ enum atom_name {
|
||||||
ATOM_LAST // keep last
|
ATOM_LAST // keep last
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wlr_xwm_reply_handler;
|
||||||
|
|
||||||
|
typedef void (*xwm_reply_handler_func_t)(struct wlr_xwm *xwm,
|
||||||
|
struct wlr_xwm_reply_handler *reply_handler, xcb_generic_reply_t *reply);
|
||||||
|
|
||||||
|
struct wlr_xwm_reply_handler {
|
||||||
|
unsigned int request;
|
||||||
|
xwm_reply_handler_func_t callback;
|
||||||
|
struct wl_list link;
|
||||||
|
};
|
||||||
|
|
||||||
struct wlr_xwm {
|
struct wlr_xwm {
|
||||||
struct wlr_xwayland *xwayland;
|
struct wlr_xwayland *xwayland;
|
||||||
struct wl_event_source *event_source;
|
struct wl_event_source *event_source;
|
||||||
|
|
@ -108,6 +119,8 @@ struct wlr_xwm {
|
||||||
xcb_render_pictformat_t render_format_id;
|
xcb_render_pictformat_t render_format_id;
|
||||||
xcb_cursor_t cursor;
|
xcb_cursor_t cursor;
|
||||||
|
|
||||||
|
struct wl_list reply_handlers; // wlr_xwm_reply_handler.link
|
||||||
|
|
||||||
struct wlr_xwm_selection clipboard_selection;
|
struct wlr_xwm_selection clipboard_selection;
|
||||||
struct wlr_xwm_selection primary_selection;
|
struct wlr_xwm_selection primary_selection;
|
||||||
struct wlr_xwm_selection dnd_selection;
|
struct wlr_xwm_selection dnd_selection;
|
||||||
|
|
@ -162,4 +175,7 @@ char *xwm_get_atom_name(struct wlr_xwm *xwm, xcb_atom_t atom);
|
||||||
bool xwm_atoms_contains(struct wlr_xwm *xwm, xcb_atom_t *atoms,
|
bool xwm_atoms_contains(struct wlr_xwm *xwm, xcb_atom_t *atoms,
|
||||||
size_t num_atoms, enum atom_name needle);
|
size_t num_atoms, enum atom_name needle);
|
||||||
|
|
||||||
|
void xwm_init_reply_handler(struct wlr_xwm *xwm, struct wlr_xwm_reply_handler *handler,
|
||||||
|
unsigned int request, xwm_reply_handler_func_t callback);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include <xcb/composite.h>
|
#include <xcb/composite.h>
|
||||||
#include <xcb/render.h>
|
#include <xcb/render.h>
|
||||||
#include <xcb/res.h>
|
#include <xcb/res.h>
|
||||||
|
#include <xcb/xcbext.h>
|
||||||
#include <xcb/xfixes.h>
|
#include <xcb/xfixes.h>
|
||||||
#include "xwayland/xwm.h"
|
#include "xwayland/xwm.h"
|
||||||
|
|
||||||
|
|
@ -1157,24 +1158,46 @@ static void xwm_handle_unmap_notify(struct wlr_xwm *xwm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_xwm_property_reply_handler {
|
||||||
|
struct wlr_xwm_reply_handler base;
|
||||||
|
xcb_window_t window;
|
||||||
|
xcb_atom_t property;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void xwm_handle_property_reply(struct wlr_xwm *xwm,
|
||||||
|
struct wlr_xwm_reply_handler *reply_handler_base,
|
||||||
|
xcb_generic_reply_t *generic_reply) {
|
||||||
|
struct wlr_xwm_property_reply_handler *reply_handler =
|
||||||
|
wl_container_of(reply_handler_base, reply_handler, base);
|
||||||
|
xcb_get_property_reply_t *reply = (xcb_get_property_reply_t *)generic_reply;
|
||||||
|
if (reply == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wlr_xwayland_surface *xsurface = lookup_surface(xwm, reply_handler->window);
|
||||||
|
if (xsurface == NULL) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
read_surface_property(xwm, xsurface, reply_handler->property, reply);
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(reply_handler);
|
||||||
|
}
|
||||||
|
|
||||||
static void xwm_handle_property_notify(struct wlr_xwm *xwm,
|
static void xwm_handle_property_notify(struct wlr_xwm *xwm,
|
||||||
xcb_property_notify_event_t *ev) {
|
xcb_property_notify_event_t *ev) {
|
||||||
struct wlr_xwayland_surface *xsurface = lookup_surface(xwm, ev->window);
|
struct wlr_xwm_property_reply_handler *reply_handler = calloc(1, sizeof(*reply_handler));
|
||||||
if (xsurface == NULL) {
|
if (reply_handler == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reply_handler->window = ev->window;
|
||||||
|
reply_handler->property = ev->atom;
|
||||||
|
|
||||||
xcb_get_property_cookie_t cookie =
|
xcb_get_property_cookie_t cookie =
|
||||||
xcb_get_property(xwm->xcb_conn, 0, xsurface->window_id, ev->atom, XCB_ATOM_ANY, 0, 2048);
|
xcb_get_property(xwm->xcb_conn, 0, ev->window, ev->atom, XCB_ATOM_ANY, 0, 2048);
|
||||||
xcb_get_property_reply_t *reply =
|
xwm_init_reply_handler(xwm, &reply_handler->base, cookie.sequence, xwm_handle_property_reply);
|
||||||
xcb_get_property_reply(xwm->xcb_conn, cookie, NULL);
|
|
||||||
if (reply == NULL) {
|
|
||||||
wlr_log(WLR_ERROR, "Failed to get window property");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
read_surface_property(xwm, xsurface, ev->atom, reply);
|
|
||||||
free(reply);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xwm_handle_surface_id_message(struct wlr_xwm *xwm,
|
static void xwm_handle_surface_id_message(struct wlr_xwm *xwm,
|
||||||
|
|
@ -1660,7 +1683,6 @@ static void xwm_handle_unhandled_event(struct wlr_xwm *xwm, xcb_generic_event_t
|
||||||
|
|
||||||
static int x11_event_handler(int fd, uint32_t mask, void *data) {
|
static int x11_event_handler(int fd, uint32_t mask, void *data) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
xcb_generic_event_t *event;
|
|
||||||
struct wlr_xwm *xwm = data;
|
struct wlr_xwm *xwm = data;
|
||||||
|
|
||||||
if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
|
if ((mask & WL_EVENT_HANGUP) || (mask & WL_EVENT_ERROR)) {
|
||||||
|
|
@ -1668,6 +1690,18 @@ static int x11_event_handler(int fd, uint32_t mask, void *data) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wlr_xwm_reply_handler *reply_handler, *reply_handler_tmp;
|
||||||
|
wl_list_for_each_safe(reply_handler, reply_handler_tmp, &xwm->reply_handlers, link) {
|
||||||
|
void *reply = NULL;
|
||||||
|
if (!xcb_poll_for_reply(xwm->xcb_conn, reply_handler->request, &reply, NULL)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wl_list_remove(&reply_handler->link);
|
||||||
|
reply_handler->callback(xwm, reply_handler, reply);
|
||||||
|
free(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
xcb_generic_event_t *event;
|
||||||
while ((event = xcb_poll_for_event(xwm->xcb_conn))) {
|
while ((event = xcb_poll_for_event(xwm->xcb_conn))) {
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
|
|
@ -1733,6 +1767,18 @@ static int x11_event_handler(int fd, uint32_t mask, void *data) {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void xwm_init_reply_handler(struct wlr_xwm *xwm, struct wlr_xwm_reply_handler *handler,
|
||||||
|
uint32_t request, xwm_reply_handler_func_t callback) {
|
||||||
|
if (request == 0) {
|
||||||
|
// Failed to send the request
|
||||||
|
callback(xwm, handler, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handler->request = request;
|
||||||
|
handler->callback = callback;
|
||||||
|
wl_list_insert(xwm->reply_handlers.prev, &handler->link);
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_compositor_new_surface(struct wl_listener *listener,
|
static void handle_compositor_new_surface(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct wlr_xwm *xwm =
|
struct wlr_xwm *xwm =
|
||||||
|
|
@ -1904,6 +1950,11 @@ void xwm_destroy(struct wlr_xwm *xwm) {
|
||||||
wl_list_for_each_safe(xsurface, tmp, &xwm->unpaired_surfaces, unpaired_link) {
|
wl_list_for_each_safe(xsurface, tmp, &xwm->unpaired_surfaces, unpaired_link) {
|
||||||
xwayland_surface_destroy(xsurface);
|
xwayland_surface_destroy(xsurface);
|
||||||
}
|
}
|
||||||
|
struct wlr_xwm_reply_handler *reply_handler, *reply_handler_tmp;
|
||||||
|
wl_list_for_each_safe(reply_handler, reply_handler_tmp, &xwm->reply_handlers, link) {
|
||||||
|
wl_list_remove(&reply_handler->link);
|
||||||
|
reply_handler->callback(xwm, reply_handler, NULL);
|
||||||
|
}
|
||||||
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);
|
wl_list_remove(&xwm->shell_v1_new_surface.link);
|
||||||
|
|
@ -2156,6 +2207,7 @@ struct wlr_xwm *xwm_create(struct wlr_xwayland *xwayland, int wm_fd) {
|
||||||
wl_list_init(&xwm->surfaces_in_stack_order);
|
wl_list_init(&xwm->surfaces_in_stack_order);
|
||||||
wl_list_init(&xwm->unpaired_surfaces);
|
wl_list_init(&xwm->unpaired_surfaces);
|
||||||
wl_list_init(&xwm->pending_startup_ids);
|
wl_list_init(&xwm->pending_startup_ids);
|
||||||
|
wl_list_init(&xwm->reply_handlers);
|
||||||
xwm->ping_timeout = 10000;
|
xwm->ping_timeout = 10000;
|
||||||
|
|
||||||
xwm->xcb_conn = xcb_connect_to_fd(wm_fd, NULL);
|
xwm->xcb_conn = xcb_connect_to_fd(wm_fd, NULL);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue