aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xglgen.sh35
-rw-r--r--include/rootston/config.h1
-rw-r--r--include/rootston/desktop.h7
-rw-r--r--include/rootston/server.h2
-rw-r--r--include/rootston/view.h4
-rw-r--r--include/wlr/types/wlr_keyboard.h1
-rw-r--r--include/wlr/types/wlr_surface.h7
-rw-r--r--include/wlr/types/wlr_xdg_shell_v6.h8
-rw-r--r--meson.build36
-rw-r--r--meson_options.txt1
-rw-r--r--rootston/config.c16
-rw-r--r--rootston/desktop.c90
-rw-r--r--rootston/meson.build33
-rw-r--r--rootston/rootston.ini.example4
-rw-r--r--types/wlr_surface.c49
-rw-r--r--types/wlr_xdg_shell_v6.c41
16 files changed, 214 insertions, 121 deletions
diff --git a/glgen.sh b/glgen.sh
index d9de6f9f..75d93c3b 100755
--- a/glgen.sh
+++ b/glgen.sh
@@ -30,28 +30,36 @@ CHECK_FMT='if (!%s) {
}'
while read -r COMMAND; do
- [ ${COMMAND::1} = "-" ]
- OPTIONAL=$?
+ OPTIONAL=0
+ FUNC_PTR_FMT='PFN%sPROC'
- COMMAND=${COMMAND#-}
- if [ ${COMMAND: -2} = "WL" ]; then
+ case $COMMAND in
+ -*)
+ OPTIONAL=1
+ ;;
+ esac
+
+ case $COMMAND in
+ *WL)
FUNC_PTR_FMT='PFN%s'
- else
- FUNC_PTR_FMT='PFN%sPROC'
- fi
+ ;;
+ esac
+ COMMAND=${COMMAND#-}
FUNC_PTR=$(printf "$FUNC_PTR_FMT" "$COMMAND" | tr [:lower:] [:upper:])
DECL="$DECL$(printf "\n$DECL_FMT" "$FUNC_PTR" "$COMMAND")"
DEFN="$DEFN$(printf "\n$DEFN_FMT" "$FUNC_PTR" "$COMMAND")"
LOADER="$LOADER$(printf "\n$LOADER_FMT" "$COMMAND" "$FUNC_PTR" "$COMMAND")"
- if [ $OPTIONAL -ne 0 ]; then
+ if [ $OPTIONAL -eq 0 ]; then
LOADER="$LOADER$(printf "\n$CHECK_FMT" "$COMMAND" "$COMMAND")"
fi
done < $SPEC
-if [ ${OUT: -2} = '.h' ]; then
+
+case $OUT in
+*.h)
cat > $OUT << EOF
#ifndef $INCLUDE_GUARD
#define $INCLUDE_GUARD
@@ -69,7 +77,8 @@ if [ ${OUT: -2} = '.h' ]; then
#endif
EOF
-elif [ ${OUT: -2} = '.c' ]; then
+ ;;
+*.c)
cat > $OUT << EOF
#include <wlr/util/log.h>
#include "$BASE.h"
@@ -86,6 +95,8 @@ elif [ ${OUT: -2} = '.c' ]; then
return true;
}
EOF
-else
+ ;;
+*)
exit 1
-fi
+ ;;
+esac
diff --git a/include/rootston/config.h b/include/rootston/config.h
index 545b6742..66347c3c 100644
--- a/include/rootston/config.h
+++ b/include/rootston/config.h
@@ -27,6 +27,7 @@ struct binding_config {
};
struct roots_config {
+ bool xwayland;
// TODO: Multiple cursors, multiseat
struct {
char *mapped_output;
diff --git a/include/rootston/desktop.h b/include/rootston/desktop.h
index 68fc5b94..1225bdcd 100644
--- a/include/rootston/desktop.h
+++ b/include/rootston/desktop.h
@@ -35,15 +35,18 @@ struct roots_desktop {
struct wlr_compositor *compositor;
struct wlr_wl_shell *wl_shell;
struct wlr_xdg_shell_v6 *xdg_shell_v6;
- struct wlr_xwayland *xwayland;
struct wlr_gamma_control_manager *gamma_control_manager;
struct wlr_screenshooter *screenshooter;
struct wl_listener output_add;
struct wl_listener output_remove;
struct wl_listener xdg_shell_v6_surface;
- struct wl_listener xwayland_surface;
struct wl_listener wl_shell_surface;
+
+#ifdef HAS_XWAYLAND
+ struct wlr_xwayland *xwayland;
+ struct wl_listener xwayland_surface;
+#endif
};
struct roots_server;
diff --git a/include/rootston/server.h b/include/rootston/server.h
index 15e3a4ee..a4eacb7f 100644
--- a/include/rootston/server.h
+++ b/include/rootston/server.h
@@ -5,7 +5,9 @@
#include <wlr/backend/session.h>
#include <wlr/types/wlr_data_device_manager.h>
#include <wlr/render.h>
+#ifdef HAS_XWAYLAND
#include <wlr/xwayland.h>
+#endif
#include "rootston/config.h"
#include "rootston/desktop.h"
#include "rootston/input.h"
diff --git a/include/rootston/view.h b/include/rootston/view.h
index 0b68f93f..af087182 100644
--- a/include/rootston/view.h
+++ b/include/rootston/view.h
@@ -58,12 +58,16 @@ struct roots_view {
union {
struct wlr_wl_shell_surface *wl_shell_surface;
struct wlr_xdg_surface_v6 *xdg_surface_v6;
+#ifdef HAS_XWAYLAND
struct wlr_xwayland_surface *xwayland_surface;
+#endif
};
union {
struct roots_wl_shell_surface *roots_wl_shell_surface;
struct roots_xdg_surface_v6 *roots_xdg_surface_v6;
+#ifdef HAS_XWAYLAND
struct roots_xwayland_surface *roots_xwayland_surface;
+#endif
};
struct wlr_surface *wlr_surface;
// TODO: This would probably be better as a field that's updated on a
diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h
index 99a624c2..a6726a7c 100644
--- a/include/wlr/types/wlr_keyboard.h
+++ b/include/wlr/types/wlr_keyboard.h
@@ -3,6 +3,7 @@
#include <wayland-server.h>
#include <stdint.h>
+#include <stdbool.h>
#include <wayland-server.h>
#include <xkbcommon/xkbcommon.h>
diff --git a/include/wlr/types/wlr_surface.h b/include/wlr/types/wlr_surface.h
index 9f898b38..03376788 100644
--- a/include/wlr/types/wlr_surface.h
+++ b/include/wlr/types/wlr_surface.h
@@ -122,4 +122,11 @@ void wlr_surface_make_subsurface(struct wlr_surface *surface,
*/
struct wlr_surface *wlr_surface_get_main_surface(struct wlr_surface *surface);
+/**
+ * Find a subsurface within this surface at the surface-local coordinates.
+ * Returns the surface and coordinates in the topmost surface coordinate system
+ * or NULL if no subsurface is found at that location.
+ */
+struct wlr_subsurface *wlr_surface_subsurface_at(struct wlr_surface *surface,
+ double sx, double sy, double *sub_x, double *sub_y);
#endif
diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h
index 00295ec1..48da6604 100644
--- a/include/wlr/types/wlr_xdg_shell_v6.h
+++ b/include/wlr/types/wlr_xdg_shell_v6.h
@@ -206,4 +206,12 @@ void wlr_xdg_toplevel_v6_set_resizing(struct wlr_xdg_surface_v6 *surface,
*/
void wlr_xdg_toplevel_v6_send_close(struct wlr_xdg_surface_v6 *surface);
+/**
+ * Find a popup within this surface at the surface-local coordinates. Returns
+ * the popup and coordinates in the topmost surface coordinate system or NULL if
+ * no popup is found at that location.
+ */
+struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_popup_at(
+ struct wlr_xdg_surface_v6 *surface, double sx, double sy,
+ double *popup_sx, double *popup_sy);
#endif
diff --git a/meson.build b/meson.build
index 179550d6..d885484b 100644
--- a/meson.build
+++ b/meson.build
@@ -24,7 +24,6 @@ add_project_link_arguments(
)
wlr_inc = include_directories('include')
-install_subdir('include/wlr', install_dir: 'include')
cc = meson.get_compiler('c')
@@ -72,13 +71,36 @@ if elogind.found() and get_option('enable_elogind')
add_project_arguments('-DHAS_ELOGIND', language: 'c')
endif
+exclude_files = []
+wlr_parts = []
+conf_data = configuration_data()
+if get_option('enable_xwayland')
+ add_project_arguments('-DHAS_XWAYLAND', language: 'c')
+ subdir('xwayland')
+ wlr_parts += [lib_wlr_xwayland]
+ conf_data.set('WLR_HAS_XWAYLAND', true)
+else
+ exclude_files += ['xwayland.h']
+endif
+configure_file(output: 'config.h', install_dir: 'include/wlr', configuration: conf_data)
+install_subdir('include/wlr', install_dir: 'include', exclude_files: exclude_files)
+
+
subdir('protocol')
subdir('render')
subdir('backend')
subdir('types')
subdir('util')
subdir('xcursor')
-subdir('xwayland')
+
+wlr_parts += [
+ lib_wl_protos,
+ lib_wlr_backend,
+ lib_wlr_render,
+ lib_wlr_types,
+ lib_wlr_util,
+ lib_wlr_xcursor,
+]
wlr_deps = [
wayland_server,
@@ -104,15 +126,7 @@ wlr_deps = [
lib_wlr = library(
'wlroots',
files('dummy.c'),
- link_whole: [
- lib_wl_protos,
- lib_wlr_backend,
- lib_wlr_render,
- lib_wlr_types,
- lib_wlr_util,
- lib_wlr_xcursor,
- lib_wlr_xwayland,
- ],
+ link_whole: wlr_parts,
dependencies: wlr_deps,
include_directories: wlr_inc,
install: true,
diff --git a/meson_options.txt b/meson_options.txt
index a3f9ca45..b1e64bd9 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,3 +1,4 @@
option('enable_libcap', type: 'boolean', value: true, description: 'Enable support for capabilities')
option('enable_systemd', type: 'boolean', value: true, description: 'Enable support for logind')
option('enable_elogind', type: 'boolean', value: true, description: 'Enable support for logind')
+option('enable_xwayland', type: 'boolean', value: true, description: 'Enable support X11 applications')
diff --git a/rootston/config.c b/rootston/config.c
index d454c2d9..4918c8dd 100644
--- a/rootston/config.c
+++ b/rootston/config.c
@@ -5,6 +5,7 @@
#include <limits.h>
#include <getopt.h>
#include <string.h>
+#include <strings.h>
#include <unistd.h>
#include <sys/param.h>
#include <wlr/util/log.h>
@@ -114,7 +115,19 @@ static const char *device_prefix = "device:";
static int config_ini_handler(void *user, const char *section, const char *name,
const char *value) {
struct roots_config *config = user;
- if (strncmp(output_prefix, section, strlen(output_prefix)) == 0) {
+ if (strcmp(section, "core") == 0) {
+ if (strcmp(name, "xwayland") == 0) {
+ if (strcasecmp(value, "true") == 0) {
+ config->xwayland = true;
+ } else if (strcasecmp(value, "false") == 0) {
+ config->xwayland = false;
+ } else {
+ wlr_log(L_ERROR, "got unknown xwayland value: %s", value);
+ }
+ } else {
+ wlr_log(L_ERROR, "got unknown core config: %s", name);
+ }
+ } else if (strncmp(output_prefix, section, strlen(output_prefix)) == 0) {
const char *output_name = section + strlen(output_prefix);
struct output_config *oc;
bool found = false;
@@ -251,6 +264,7 @@ static int config_ini_handler(void *user, const char *section, const char *name,
struct roots_config *parse_args(int argc, char *argv[]) {
struct roots_config *config = calloc(1, sizeof(struct roots_config));
+ config->xwayland = true;
wl_list_init(&config->outputs);
wl_list_init(&config->devices);
wl_list_init(&config->bindings);
diff --git a/rootston/desktop.c b/rootston/desktop.c
index b34fb19e..bef0fad4 100644
--- a/rootston/desktop.c
+++ b/rootston/desktop.c
@@ -98,75 +98,6 @@ bool view_initialize(struct roots_view *view) {
return centered;
}
-static struct wlr_subsurface *subsurface_at(struct wlr_surface *surface,
- double sx, double sy, double *sub_x, double *sub_y) {
- struct wlr_subsurface *subsurface;
- wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) {
- double _sub_x = subsurface->surface->current->subsurface_position.x;
- double _sub_y = subsurface->surface->current->subsurface_position.y;
- struct wlr_subsurface *sub =
- subsurface_at(subsurface->surface, _sub_x + sx, _sub_y + sy,
- sub_x, sub_y);
- if (sub) {
- // TODO: This won't work for nested subsurfaces. Convert sub_x and
- // sub_y to the parent coordinate system
- return sub;
- }
-
- int sub_width = subsurface->surface->current->buffer_width;
- int sub_height = subsurface->surface->current->buffer_height;
- if ((sx > _sub_x && sx < _sub_x + sub_width) &&
- (sy > _sub_y && sy < _sub_y + sub_height)) {
- if (pixman_region32_contains_point(
- &subsurface->surface->current->input,
- sx - _sub_x, sy - _sub_y, NULL)) {
- *sub_x = _sub_x;
- *sub_y = _sub_y;
- return subsurface;
- }
- }
- }
-
- return NULL;
-}
-
-static struct wlr_xdg_surface_v6 *xdg_v6_popup_at(
- struct wlr_xdg_surface_v6 *surface, double sx, double sy,
- double *popup_sx, double *popup_sy) {
- // XXX: I think this is so complicated because we're mixing geometry
- // coordinates with surface coordinates. Input handling should only deal
- // with surface coordinates.
- struct wlr_xdg_surface_v6 *popup;
- wl_list_for_each(popup, &surface->popups, popup_link) {
- double _popup_sx = surface->geometry->x + popup->popup_state->geometry.x;
- double _popup_sy = surface->geometry->y + popup->popup_state->geometry.y;
- int popup_width = popup->popup_state->geometry.width;
- int popup_height = popup->popup_state->geometry.height;
-
- struct wlr_xdg_surface_v6 *_popup =
- xdg_v6_popup_at(popup, sx - _popup_sx + popup->geometry->x,
- sy - _popup_sy + popup->geometry->y, popup_sx, popup_sy);
- if (_popup) {
- *popup_sx = *popup_sx + _popup_sx - popup->geometry->x;
- *popup_sy = *popup_sy + _popup_sy - popup->geometry->y;
- return _popup;
- }
-
- if ((sx > _popup_sx && sx < _popup_sx + popup_width) &&
- (sy > _popup_sy && sy < _popup_sy + popup_height)) {
- if (pixman_region32_contains_point(&popup->surface->current->input,
- sx - _popup_sx + popup->geometry->x,
- sy - _popup_sy + popup->geometry->y, NULL)) {
- *popup_sx = _popup_sx - popup->geometry->x;
- *popup_sy = _popup_sy - popup->geometry->y;
- return popup;
- }
- }
- }
-
- return NULL;
-}
-
struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy) {
for (int i = desktop->views->length - 1; i >= 0; --i) {
@@ -196,8 +127,8 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly,
// TODO: test if this works with rotated views
double popup_sx, popup_sy;
struct wlr_xdg_surface_v6 *popup =
- xdg_v6_popup_at(view->xdg_surface_v6, view_sx, view_sy,
- &popup_sx, &popup_sy);
+ wlr_xdg_surface_v6_popup_at(view->xdg_surface_v6,
+ view_sx, view_sy, &popup_sx, &popup_sy);
if (popup) {
*sx = view_sx - popup_sx;
@@ -209,7 +140,8 @@ struct roots_view *view_at(struct roots_desktop *desktop, double lx, double ly,
double sub_x, sub_y;
struct wlr_subsurface *subsurface =
- subsurface_at(view->wlr_surface, view_sx, view_sy, &sub_x, &sub_y);
+ wlr_surface_subsurface_at(view->wlr_surface,
+ view_sx, view_sy, &sub_x, &sub_y);
if (subsurface) {
*sx = view_sx - sub_x;
*sy = view_sy - sub_y;
@@ -262,11 +194,15 @@ struct roots_desktop *desktop_create(struct roots_server *server,
&desktop->wl_shell_surface);
desktop->wl_shell_surface.notify = handle_wl_shell_surface;
- desktop->xwayland = wlr_xwayland_create(server->wl_display,
- desktop->compositor);
- wl_signal_add(&desktop->xwayland->events.new_surface,
- &desktop->xwayland_surface);
- desktop->xwayland_surface.notify = handle_xwayland_surface;
+#ifdef HAS_XWAYLAND
+ if (config->xwayland) {
+ desktop->xwayland = wlr_xwayland_create(server->wl_display,
+ desktop->compositor);
+ wl_signal_add(&desktop->xwayland->events.new_surface,
+ &desktop->xwayland_surface);
+ desktop->xwayland_surface.notify = handle_xwayland_surface;
+ }
+#endif
desktop->gamma_control_manager = wlr_gamma_control_manager_create(
server->wl_display);
diff --git a/rootston/meson.build b/rootston/meson.build
index 1eb0704d..7ff79f8e 100644
--- a/rootston/meson.build
+++ b/rootston/meson.build
@@ -1,17 +1,20 @@
+sources = [
+ 'config.c',
+ 'cursor.c',
+ 'desktop.c',
+ 'ini.c',
+ 'input.c',
+ 'keyboard.c',
+ 'main.c',
+ 'output.c',
+ 'pointer.c',
+ 'tablet_tool.c',
+ 'xdg_shell_v6.c',
+ 'wl_shell.c',
+]
+if get_option('enable_xwayland')
+ sources += ['xwayland.c']
+endif
executable(
- 'rootston', [
- 'config.c',
- 'cursor.c',
- 'desktop.c',
- 'ini.c',
- 'input.c',
- 'keyboard.c',
- 'main.c',
- 'output.c',
- 'pointer.c',
- 'tablet_tool.c',
- 'xdg_shell_v6.c',
- 'xwayland.c',
- 'wl_shell.c',
- ], dependencies: wlroots
+ 'rootston', sources, dependencies: wlroots
)
diff --git a/rootston/rootston.ini.example b/rootston/rootston.ini.example
index 8ac474d4..460efa13 100644
--- a/rootston/rootston.ini.example
+++ b/rootston/rootston.ini.example
@@ -1,3 +1,7 @@
+[core]
+# Disable X11 support. Enabled by default.
+xwayland=false
+
# Single output configuration. String after semicolon must match output's name.
[output:VGA-1]
# Set logical (layout) coordinates for this screen
diff --git a/types/wlr_surface.c b/types/wlr_surface.c
index 7b620c6b..ca7a9af5 100644
--- a/types/wlr_surface.c
+++ b/types/wlr_surface.c
@@ -134,6 +134,12 @@ static void surface_set_input_region(struct wl_client *client,
}
static void wlr_surface_update_size(struct wlr_surface *surface, struct wlr_surface_state *state) {
+ if (!state->buffer) {
+ state->height = 0;
+ state->width = 0;
+ return;
+ }
+
int scale = state->scale;
enum wl_output_transform transform = state->transform;
@@ -343,8 +349,16 @@ static void wlr_surface_commit_pending(struct wlr_surface *surface) {
int32_t oldw = surface->current->buffer_width;
int32_t oldh = surface->current->buffer_height;
+ bool null_buffer_commit =
+ (surface->pending->invalid & WLR_SURFACE_INVALID_BUFFER &&
+ surface->pending->buffer == NULL);
+
wlr_surface_move_state(surface, surface->pending, surface->current);
+ if (null_buffer_commit) {
+ surface->texture->valid = false;
+ }
+
// commit subsurface order
struct wlr_subsurface *subsurface;
wl_list_for_each_reverse(subsurface, &surface->subsurface_pending_list,
@@ -447,9 +461,6 @@ static void surface_commit(struct wl_client *client,
void wlr_surface_flush_damage(struct wlr_surface *surface) {
if (!surface->current->buffer) {
- if (surface->texture->valid) {
- // TODO: Detach buffers
- }
return;
}
struct wl_shm_buffer *buffer = wl_shm_buffer_get(surface->current->buffer);
@@ -835,3 +846,35 @@ struct wlr_surface *wlr_surface_get_main_surface(struct wlr_surface *surface) {
return surface;
}
+
+struct wlr_subsurface *wlr_surface_subsurface_at(struct wlr_surface *surface,
+ double sx, double sy, double *sub_x, double *sub_y) {
+ struct wlr_subsurface *subsurface;
+ wl_list_for_each(subsurface, &surface->subsurface_list, parent_link) {
+ double _sub_x = subsurface->surface->current->subsurface_position.x;
+ double _sub_y = subsurface->surface->current->subsurface_position.y;
+ struct wlr_subsurface *sub =
+ wlr_surface_subsurface_at(subsurface->surface, _sub_x + sx,
+ _sub_y + sy, sub_x, sub_y);
+ if (sub) {
+ // TODO: This won't work for nested subsurfaces. Convert sub_x and
+ // sub_y to the parent coordinate system
+ return sub;
+ }
+
+ int sub_width = subsurface->surface->current->buffer_width;
+ int sub_height = subsurface->surface->current->buffer_height;
+ if ((sx > _sub_x && sx < _sub_x + sub_width) &&
+ (sy > _sub_y && sy < _sub_y + sub_height)) {
+ if (pixman_region32_contains_point(
+ &subsurface->surface->current->input,
+ sx - _sub_x, sy - _sub_y, NULL)) {
+ *sub_x = _sub_x;
+ *sub_y = _sub_y;
+ return subsurface;
+ }
+ }
+ }
+
+ return NULL;
+}
diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c
index 5f2554f8..a16d3319 100644
--- a/types/wlr_xdg_shell_v6.c
+++ b/types/wlr_xdg_shell_v6.c
@@ -1301,3 +1301,44 @@ void wlr_xdg_toplevel_v6_send_close(struct wlr_xdg_surface_v6 *surface) {
assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL);
zxdg_toplevel_v6_send_close(surface->toplevel_state->resource);
}
+
+struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6_popup_at(
+ struct wlr_xdg_surface_v6 *surface, double sx, double sy,
+ double *popup_sx, double *popup_sy) {
+ // XXX: I think this is so complicated because we're mixing geometry
+ // coordinates with surface coordinates. Input handling should only deal
+ // with surface coordinates.
+ struct wlr_xdg_surface_v6 *popup;
+ wl_list_for_each(popup, &surface->popups, popup_link) {
+ double _popup_sx =
+ surface->geometry->x + popup->popup_state->geometry.x;
+ double _popup_sy =
+ surface->geometry->y + popup->popup_state->geometry.y;
+ int popup_width = popup->popup_state->geometry.width;
+ int popup_height = popup->popup_state->geometry.height;
+
+ struct wlr_xdg_surface_v6 *_popup =
+ wlr_xdg_surface_v6_popup_at(popup,
+ sx - _popup_sx + popup->geometry->x,
+ sy - _popup_sy + popup->geometry->y,
+ popup_sx, popup_sy);
+ if (_popup) {
+ *popup_sx = *popup_sx + _popup_sx - popup->geometry->x;
+ *popup_sy = *popup_sy + _popup_sy - popup->geometry->y;
+ return _popup;
+ }
+
+ if ((sx > _popup_sx && sx < _popup_sx + popup_width) &&
+ (sy > _popup_sy && sy < _popup_sy + popup_height)) {
+ if (pixman_region32_contains_point(&popup->surface->current->input,
+ sx - _popup_sx + popup->geometry->x,
+ sy - _popup_sy + popup->geometry->y, NULL)) {
+ *popup_sx = _popup_sx - popup->geometry->x;
+ *popup_sy = _popup_sy - popup->geometry->y;
+ return popup;
+ }
+ }
+ }
+
+ return NULL;
+}