Make xwayland support optional

This commit is contained in:
Johan Malm 2020-12-30 10:29:21 +00:00
parent cd9fe2900e
commit cfc6e18cdc
10 changed files with 75 additions and 10 deletions

View file

@ -38,13 +38,15 @@ Dependencies include:
- wlroots (>=0.11.0) - wlroots (>=0.11.0)
- wayland (>=1.16) - wayland (>=1.16)
- wayland-protocols - wayland-protocols
- xwayland - xwayland, xcb (optional)
- libinput (>=1.14) - libinput (>=1.14)
- libxml2 - libxml2
- cairo, pango, glib-2.0 - cairo, pango, glib-2.0
- xcb - xcb
- xkbcommon - xkbcommon
Disable xwayland with `meson -Dxwayland=disabled build`
For further details see [wiki/Build](https://github.com/johanmalm/labwc/wiki/Build). For further details see [wiki/Build](https://github.com/johanmalm/labwc/wiki/Build).
## 3. Configure ## 3. Configure
@ -87,21 +89,21 @@ Suggested apps to use with labwc:
No acceptance criteria exists, but the following list indicates the inteded high level roadmap: No acceptance criteria exists, but the following list indicates the inteded high level roadmap:
- [x] Support xwayland - [x] Optionally support xwayland
- [x] Parse openbox config files (rc.xml, autostart, environment) - [x] Parse openbox config files (rc.xml, autostart, environment)
- [x] Parse openbox themes files and associated xbm icons - [x] Parse openbox themes files and associated xbm icons
- [x] Show maximize, iconify, close buttons - [x] Show maximize, iconify, close buttons
- [x] Catch SIGHUP to re-load config file and theme - [x] Catch SIGHUP to re-load config file and theme
- [x] Support layer-shell protocol ('exclusive' not yet implemented) - [x] Support layer-shell protocol ('exclusive' not yet implemented)
- [ ] Support root-menu and parse menu.xml (very simple implementation, not submenus yet) - [ ] Support root-menu and parse menu.xml (very simple implementation, not submenus yet)
- [ ] Support damage tracking to reduce CPU usage
- [ ] Support 'maximize' - [ ] Support 'maximize'
- [ ] Support wlr-output-management protocol and [kanshi](https://github.com/emersion/kanshi.git) - [ ] Support wlr-output-management protocol and [kanshi](https://github.com/emersion/kanshi.git)
- [ ] Show window title
- [ ] Support foreign-toplevel protocol (e.g. to integrate with wlroots panels/bars) - [ ] Support foreign-toplevel protocol (e.g. to integrate with wlroots panels/bars)
- [ ] Support damage tracking to reduce CPU usage
- [ ] Implement client-menu - [ ] Implement client-menu
- [ ] Support on-screen display (osd), for example to support alt-tab window list - [ ] Support on-screen display (osd), for example to support alt-tab window list
- [ ] Support HiDPI - [ ] Support HiDPI
- [ ] Support libinput configuration (tap is enabled for the time being)
## 7. Scope ## 7. Scope

View file

@ -1,6 +1,6 @@
#ifndef __LABWC_H #ifndef __LABWC_H
#define __LABWC_H #define __LABWC_H
#include "config.h"
#include <getopt.h> #include <getopt.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
@ -27,7 +27,9 @@
#include <wlr/types/wlr_xdg_decoration_v1.h> #include <wlr/types/wlr_xdg_decoration_v1.h>
#include <wlr/types/wlr_xdg_shell.h> #include <wlr/types/wlr_xdg_shell.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#if HAVE_XWAYLAND
#include <wlr/xwayland.h> #include <wlr/xwayland.h>
#endif
#include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon.h>
#include "common/log.h" #include "common/log.h"
@ -90,8 +92,10 @@ struct server {
struct wl_listener new_layer_surface; struct wl_listener new_layer_surface;
struct wl_listener xdg_toplevel_decoration; struct wl_listener xdg_toplevel_decoration;
#if HAVE_XWAYLAND
struct wlr_xwayland *xwayland; struct wlr_xwayland *xwayland;
struct wl_listener new_xwayland_surface; struct wl_listener new_xwayland_surface;
#endif
struct wl_list views; struct wl_list views;
struct wl_list unmanaged_surfaces; struct wl_list unmanaged_surfaces;
@ -124,7 +128,12 @@ struct output {
struct wl_listener destroy; struct wl_listener destroy;
}; };
enum view_type { LAB_XDG_SHELL_VIEW, LAB_XWAYLAND_VIEW }; enum view_type {
LAB_XDG_SHELL_VIEW,
#if HAVE_XWAYLAND
LAB_XWAYLAND_VIEW,
#endif
};
enum deco_part { enum deco_part {
LAB_DECO_NONE = 0, LAB_DECO_NONE = 0,
@ -164,7 +173,9 @@ struct view {
union { union {
struct wlr_xdg_surface *xdg_surface; struct wlr_xdg_surface *xdg_surface;
#if HAVE_XWAYLAND
struct wlr_xwayland_surface *xwayland_surface; struct wlr_xwayland_surface *xwayland_surface;
#endif
}; };
struct wlr_surface *surface; struct wlr_surface *surface;
@ -202,6 +213,7 @@ struct view {
struct wl_listener request_configure; struct wl_listener request_configure;
}; };
#if HAVE_XWAYLAND
struct xwayland_unmanaged { struct xwayland_unmanaged {
struct server *server; struct server *server;
struct wlr_xwayland_surface *xwayland_surface; struct wlr_xwayland_surface *xwayland_surface;
@ -214,13 +226,16 @@ struct xwayland_unmanaged {
struct wl_listener unmap; struct wl_listener unmap;
struct wl_listener destroy; struct wl_listener destroy;
}; };
#endif
void xdg_toplevel_decoration(struct wl_listener *listener, void *data); void xdg_toplevel_decoration(struct wl_listener *listener, void *data);
void xdg_surface_new(struct wl_listener *listener, void *data); void xdg_surface_new(struct wl_listener *listener, void *data);
#if HAVE_XWAYLAND
void xwayland_surface_new(struct wl_listener *listener, void *data); void xwayland_surface_new(struct wl_listener *listener, void *data);
void xwayland_unmanaged_create(struct server *server, void xwayland_unmanaged_create(struct server *server,
struct wlr_xwayland_surface *xsurface); struct wlr_xwayland_surface *xsurface);
#endif
void view_move_resize(struct view *view, struct wlr_box geo); void view_move_resize(struct view *view, struct wlr_box geo);
void view_move(struct view *view, double x, double y); void view_move(struct view *view, double x, double y);

1
include/meson.build Normal file
View file

@ -0,0 +1 @@
configure_file(output: 'config.h', configuration: conf_data)

View file

@ -34,17 +34,28 @@ wlroots_proj = subproject(
if wlroots_proj.found() if wlroots_proj.found()
wlroots = wlroots_proj.get_variable('wlroots') wlroots = wlroots_proj.get_variable('wlroots')
wlroots_conf = wlroots_proj.get_variable('conf_data')
wlroots_has_xwayland = wlroots_conf.get('WLR_HAS_XWAYLAND') == 1
else else
wlroots = dependency('wlroots', version: '>= 0.10.0') wlroots = dependency('wlroots', version: '>= 0.11.0')
wlroots_has_xwayland = cc.get_define('WLR_HAS_XWAYLAND', prefix: '#include <wlr/config.h>', dependencies: wlroots) == '1'
endif endif
wayland_server = dependency('wayland-server') wayland_server = dependency('wayland-server')
wayland_protos = dependency('wayland-protocols') wayland_protos = dependency('wayland-protocols')
xkbcommon = dependency('xkbcommon') xkbcommon = dependency('xkbcommon')
xcb = dependency('xcb', required: get_option('xwayland'))
xml2 = dependency('libxml-2.0') xml2 = dependency('libxml-2.0')
glib = dependency('glib-2.0') glib = dependency('glib-2.0')
cairo = dependency('cairo') cairo = dependency('cairo')
pangocairo = dependency('pangocairo') pangocairo = dependency('pangocairo')
if get_option('xwayland').enabled() and not wlroots_has_xwayland
error('no wlroots Xwayland support')
endif
have_xwayland = xcb.found() and wlroots_has_xwayland
conf_data = configuration_data()
conf_data.set10('HAVE_XWAYLAND', have_xwayland)
labwc_inc = include_directories('include') labwc_inc = include_directories('include')
subdir('protocols') subdir('protocols')
@ -54,6 +65,7 @@ labwc_deps = [
cairo, pangocairo cairo, pangocairo
] ]
subdir('include')
subdir('src') subdir('src')
subdir('docs') subdir('docs')

1
meson_options.txt Normal file
View file

@ -0,0 +1 @@
option('xwayland', type: 'feature', value: 'auto', description: 'Enable support for X11 applications')

View file

@ -1,3 +1,4 @@
#include "config.h"
#include <assert.h> #include <assert.h>
#include "labwc.h" #include "labwc.h"
@ -8,6 +9,7 @@ move_to_front(struct view *view)
wl_list_insert(&view->server->views, &view->link); wl_list_insert(&view->server->views, &view->link);
} }
#if HAVE_XWAYLAND
static struct wlr_xwayland_surface * static struct wlr_xwayland_surface *
top_parent_of(struct view *view) top_parent_of(struct view *view)
{ {
@ -44,6 +46,7 @@ move_xwayland_sub_views_to_front(struct view *parent)
/* TODO: we should probably focus on these too here */ /* TODO: we should probably focus on these too here */
} }
} }
#endif
/* Activate/deactivate toplevel surface */ /* Activate/deactivate toplevel surface */
static void static void
@ -56,10 +59,12 @@ set_activated(struct wlr_surface *surface, bool activated)
struct wlr_xdg_surface *s; struct wlr_xdg_surface *s;
s = wlr_xdg_surface_from_wlr_surface(surface); s = wlr_xdg_surface_from_wlr_surface(surface);
wlr_xdg_toplevel_set_activated(s, activated); wlr_xdg_toplevel_set_activated(s, activated);
#if HAVE_XWAYLAND
} else if (wlr_surface_is_xwayland_surface(surface)) { } else if (wlr_surface_is_xwayland_surface(surface)) {
struct wlr_xwayland_surface *s; struct wlr_xwayland_surface *s;
s = wlr_xwayland_surface_from_wlr_surface(surface); s = wlr_xwayland_surface_from_wlr_surface(surface);
wlr_xwayland_surface_activate(s, activated); wlr_xwayland_surface_activate(s, activated);
#endif
} }
} }
@ -87,7 +92,9 @@ desktop_focus_view(struct seat *seat, struct view *view)
move_to_front(view); move_to_front(view);
set_activated(view->surface, true); set_activated(view->surface, true);
seat_focus_surface(seat, view->surface); seat_focus_surface(seat, view->surface);
#if HAVE_XWAYLAND
move_xwayland_sub_views_to_front(view); move_xwayland_sub_views_to_front(view);
#endif
} }
} }
@ -200,10 +207,12 @@ _view_at(struct view *view, double lx, double ly, struct wlr_surface **surface,
_surface = wlr_xdg_surface_surface_at( _surface = wlr_xdg_surface_surface_at(
view->xdg_surface, view_sx, view_sy, &_sx, &_sy); view->xdg_surface, view_sx, view_sy, &_sx, &_sy);
break; break;
#if HAVE_XWAYLAND
case LAB_XWAYLAND_VIEW: case LAB_XWAYLAND_VIEW:
_surface = wlr_surface_surface_at(view->surface, view_sx, _surface = wlr_surface_surface_at(view->surface, view_sx,
view_sy, &_sx, &_sy); view_sy, &_sx, &_sy);
break; break;
#endif
} }
if (_surface) { if (_surface) {

View file

@ -13,10 +13,16 @@ labwc_sources = files(
'server.c', 'server.c',
'view.c', 'view.c',
'xdg.c', 'xdg.c',
'xwayland.c',
'xwayland-unmanaged.c',
) )
if have_xwayland
labwc_sources += files(
'xwayland.c',
'xwayland-unmanaged.c',
)
endif
subdir('common') subdir('common')
subdir('config') subdir('config')
subdir('theme') subdir('theme')

View file

@ -1,8 +1,10 @@
#include "config.h"
#include "common/log.h" #include "common/log.h"
#include "config/keybind.h" #include "config/keybind.h"
#include "config/rcxml.h" #include "config/rcxml.h"
#include "labwc.h" #include "labwc.h"
#if HAVE_XWAYLAND
static int static int
xwl_nr_parents(struct view *view) xwl_nr_parents(struct view *view)
{ {
@ -19,6 +21,7 @@ xwl_nr_parents(struct view *view)
} }
return i; return i;
} }
#endif
static void static void
show_one_xdg_view(struct view *view) show_one_xdg_view(struct view *view)
@ -41,6 +44,7 @@ show_one_xdg_view(struct view *view)
view->h); view->h);
} }
#if HAVE_XWAYLAND
static void static void
show_one_xwl_view(struct view *view) show_one_xwl_view(struct view *view)
{ {
@ -69,6 +73,7 @@ show_one_xwl_view(struct view *view)
* view->xwayland_surface->surface->sy); * view->xwayland_surface->surface->sy);
*/ */
} }
#endif
void void
dbg_show_one_view(struct view *view) dbg_show_one_view(struct view *view)
@ -81,8 +86,10 @@ dbg_show_one_view(struct view *view)
} }
if (view->type == LAB_XDG_SHELL_VIEW) { if (view->type == LAB_XDG_SHELL_VIEW) {
show_one_xdg_view(view); show_one_xdg_view(view);
#if HAVE_XWAYLAND
} else if (view->type == LAB_XWAYLAND_VIEW) { } else if (view->type == LAB_XWAYLAND_VIEW) {
show_one_xwl_view(view); show_one_xwl_view(view);
#endif
} }
} }

View file

@ -1,4 +1,5 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include "config.h"
#include <wlr/types/wlr_xdg_output_v1.h> #include <wlr/types/wlr_xdg_output_v1.h>
#include "labwc.h" #include "labwc.h"
#include "menu/menu.h" #include "menu/menu.h"
@ -367,6 +368,7 @@ output_frame_notify(struct wl_listener *listener, void *data)
/* If in cycle (alt-tab) mode, highlight selected view */ /* If in cycle (alt-tab) mode, highlight selected view */
render_cycle_box(output); render_cycle_box(output);
#if HAVE_XWAYLAND
/* Render xwayland override_redirect surfaces */ /* Render xwayland override_redirect surfaces */
struct xwayland_unmanaged *unmanaged; struct xwayland_unmanaged *unmanaged;
wl_list_for_each_reverse (unmanaged, wl_list_for_each_reverse (unmanaged,
@ -383,6 +385,7 @@ output_frame_notify(struct wl_listener *listener, void *data)
struct wlr_surface *s = unmanaged->xwayland_surface->surface; struct wlr_surface *s = unmanaged->xwayland_surface->surface;
render_surface(s, 0, 0, &rdata); render_surface(s, 0, 0, &rdata);
} }
#endif
render_layer(&now, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]); render_layer(&now, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]);
render_layer(&now, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]); render_layer(&now, &output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]);

View file

@ -1,4 +1,5 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include "config.h"
#include <signal.h> #include <signal.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <wlr/types/wlr_data_control_v1.h> #include <wlr/types/wlr_data_control_v1.h>
@ -175,6 +176,7 @@ server_init(struct server *server)
layers_init(server); layers_init(server);
#if HAVE_XWAYLAND
/* Init xwayland */ /* Init xwayland */
server->xwayland = server->xwayland =
wlr_xwayland_create(server->wl_display, compositor, true); wlr_xwayland_create(server->wl_display, compositor, true);
@ -192,11 +194,13 @@ server_init(struct server *server)
wlr_log(WLR_DEBUG, "xwayland is running on display %s", wlr_log(WLR_DEBUG, "xwayland is running on display %s",
server->xwayland->display_name); server->xwayland->display_name);
} }
#endif
if (!wlr_xcursor_manager_load(server->seat.xcursor_manager, 1)) { if (!wlr_xcursor_manager_load(server->seat.xcursor_manager, 1)) {
wlr_log(WLR_ERROR, "cannot load xwayland xcursor theme"); wlr_log(WLR_ERROR, "cannot load xcursor theme");
} }
#if HAVE_XWAYLAND
struct wlr_xcursor *xcursor; struct wlr_xcursor *xcursor;
xcursor = wlr_xcursor_manager_get_xcursor(server->seat.xcursor_manager, xcursor = wlr_xcursor_manager_get_xcursor(server->seat.xcursor_manager,
XCURSOR_DEFAULT, 1); XCURSOR_DEFAULT, 1);
@ -207,6 +211,7 @@ server_init(struct server *server)
image->height, image->hotspot_x, image->height, image->hotspot_x,
image->hotspot_y); image->hotspot_y);
} }
#endif
} }
void void
@ -237,13 +242,17 @@ server_start(struct server *server)
wl_display_init_shm(server->wl_display); wl_display_init_shm(server->wl_display);
#if HAVE_XWAYLAND
wlr_xwayland_set_seat(server->xwayland, server->seat.seat); wlr_xwayland_set_seat(server->xwayland, server->seat.seat);
#endif
} }
void void
server_finish(struct server *server) server_finish(struct server *server)
{ {
#if HAVE_XWAYLAND
wlr_xwayland_destroy(server->xwayland); wlr_xwayland_destroy(server->xwayland);
#endif
if (sighup_source) { if (sighup_source) {
wl_event_source_remove(sighup_source); wl_event_source_remove(sighup_source);
} }