adding xwayland support

This commit is contained in:
2026-04-06 23:38:06 +07:00
parent 7601b86450
commit e995f748b2
10 changed files with 133 additions and 11 deletions
+10 -1
View File
@@ -6,7 +6,16 @@
bool absinthe_toplevel_is_x11(struct absinthe_toplevel *toplevel)
{
#ifdef XWAYLAND
return toplevel->type == ABSINTHE_TOPLEVEL_TYPE_X11;
return toplevel->type == ABSINTHE_TOPLEVEL_X11;
#endif
return false;
}
bool absinthe_toplevel_is_unmanaged(struct absinthe_toplevel *toplevel)
{
#ifdef XWAYLAND
if (absinthe_toplevel_is_x11(toplevel))
return toplevel->toplevel.x11->override_redirect;
#endif
return false;
}
+15
View File
@@ -131,6 +131,8 @@ int main(int argc, char **argv)
server.request_set_selection.notify = seat_request_set_selection;
wl_signal_add(&server.seat->events.request_set_selection, &server.request_set_selection);
unsetenv("DISPLAY");
const char *socket = wl_display_add_socket_auto(server.display);
if (!socket) {
wlr_log(WLR_ERROR, "Failed to add socket");
@@ -145,6 +147,19 @@ int main(int argc, char **argv)
return 1;
}
#ifdef XWAYLAND
if ((server.xwayland = wlr_xwayland_create(server.display, server.compositor, 1))) {
server.xwayland_ready.notify = server_xwayland_ready;
wl_signal_add(&server.xwayland->events.ready, &server.xwayland_ready);
server.xwayland_new_surface.notify = server_xwayland_new_surface;
wl_signal_add(&server.xwayland->events.new_surface, &server.xwayland_new_surface);
setenv("DISPLAY", server.xwayland->display_name, 1);
} else {
wlr_log(WLR_ERROR, "Failed to setup XWayland, continuing without it");
}
#endif
setenv("WAYLAND_DISPLAY", socket, true);
wlr_log(WLR_INFO, "Running absinthe on WAYLAND_DISPLAY=%s", socket);
+55
View File
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <wlr/util/log.h>
#include <wlr/types/wlr_xcursor_manager.h>
#include "types.h"
#include "output.h"
@@ -13,6 +14,11 @@
#include "keyboard.h"
#include "cursor.h"
#ifdef XWAYLAND
#include <wlr/xwayland.h>
#include "xwayland.h"
#endif
void server_new_output(struct wl_listener *listener, void *data)
{
struct absinthe_server *server = wl_container_of(listener, server, new_output);
@@ -118,8 +124,57 @@ void server_new_xdg_decoration(struct wl_listener *listener, void *data)
wl_signal_add(&xdg_decoration->events.destroy, &toplevel->decoration_destroy);
xdg_decoration_request_mode(&toplevel->decoration_request_mode, xdg_decoration);
toplevel->destroy.notify = xdg_toplevel_destroy;
wl_signal_add(&toplevel->toplevel.xdg->events.destroy, &toplevel->destroy);
}
#ifdef XWAYLAND
void server_xwayland_ready(struct wl_listener *listener, void *data)
{
struct absinthe_server *server = wl_container_of(listener, server, xwayland_ready);
struct wlr_xcursor *xcursor;
wlr_xwayland_set_seat(server->xwayland, server->seat);
if ((xcursor = wlr_xcursor_manager_get_xcursor(server->cursor_mgr, "default", 1)))
wlr_xwayland_set_cursor(server->xwayland,
xcursor->images[0]->buffer, xcursor->images[0]->width * 4,
xcursor->images[0]->width, xcursor->images[0]->height,
xcursor->images[0]->hotspot_x, xcursor->images[0]->hotspot_y);
}
void server_xwayland_new_surface(struct wl_listener *listener, void *data)
{
struct wlr_xwayland_surface *surface = data;
struct absinthe_toplevel *toplevel = malloc(sizeof(*toplevel));
toplevel->type = ABSINTHE_TOPLEVEL_X11;
toplevel->toplevel.x11 = surface;
toplevel->border_width = absinthe_toplevel_is_unmanaged(toplevel)
? 0
: ABSINTHE_TOPLEVEL_BORDER_WIDTH;
toplevel->destroy.notify = xdg_toplevel_destroy;
wl_signal_add(&surface->events.destroy, &toplevel->destroy);
toplevel->request_maximize.notify = xdg_toplevel_request_maximize;
wl_signal_add(&surface->events.request_maximize, &toplevel->request_maximize);
toplevel->request_fullscreen.notify = xdg_toplevel_request_fullscreen;
wl_signal_add(&surface->events.request_fullscreen, &toplevel->request_fullscreen);
toplevel->xwayland_activate.notify = xwayland_activate;
wl_signal_add(&surface->events.request_activate, &toplevel->xwayland_activate);
toplevel->xwayland_associate.notify = xwayland_associate;
wl_signal_add(&surface->events.associate, &toplevel->xwayland_associate);
toplevel->xwayland_dissociate.notify = xwayland_dissociate;
wl_signal_add(&surface->events.dissociate, &toplevel->xwayland_dissociate);
toplevel->xwayland_configure.notify = xwayland_configure;
wl_signal_add(&surface->events.request_configure, &toplevel->xwayland_configure);
toplevel->xwayland_set_hints.notify = xwayland_set_hints;
wl_signal_add(&surface->events.set_hints, &toplevel->xwayland_set_hints);
}
#endif
void server_cursor_motion(struct wl_listener *listener, void *data)
{
struct absinthe_server *server = wl_container_of(listener, server, cursor_motion);
+14 -5
View File
@@ -70,15 +70,24 @@ void xdg_toplevel_destroy(struct wl_listener *listener, void *data)
{
struct absinthe_toplevel *toplevel = wl_container_of(listener, toplevel, destroy);
wl_list_remove(&toplevel->map.link);
wl_list_remove(&toplevel->unmap.link);
wl_list_remove(&toplevel->commit.link);
wl_list_remove(&toplevel->destroy.link);
wl_list_remove(&toplevel->request_move.link);
wl_list_remove(&toplevel->request_resize.link);
wl_list_remove(&toplevel->request_maximize.link);
wl_list_remove(&toplevel->request_fullscreen.link);
if (absinthe_toplevel_is_x11(toplevel)) {
wl_list_remove(&toplevel->xwayland_activate.link);
wl_list_remove(&toplevel->xwayland_associate.link);
wl_list_remove(&toplevel->xwayland_dissociate.link);
wl_list_remove(&toplevel->xwayland_configure.link);
wl_list_remove(&toplevel->xwayland_set_hints.link);
} else {
wl_list_remove(&toplevel->map.link);
wl_list_remove(&toplevel->unmap.link);
wl_list_remove(&toplevel->commit.link);
wl_list_remove(&toplevel->request_move.link);
wl_list_remove(&toplevel->request_resize.link);
}
free(toplevel);
}
+12
View File
@@ -0,0 +1,12 @@
#ifdef XWAYLAND
#include "types.h"
#include "absinthe-toplevel.h"
#include "xwayland.h"
void xwayland_activate(struct wl_listener *listener, void *data) {}
void xwayland_associate(struct wl_listener *listener, void *data) {}
void xwayland_dissociate(struct wl_listener *listener, void *data) {}
void xwayland_configure(struct wl_listener *listener, void *data) {}
void xwayland_set_hints(struct wl_listener *listener, void *data) {}
#endif