This commit is contained in:
SALZ Automation GmbH 2025-10-02 17:09:07 +02:00 committed by GitHub
commit 21dc099150
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 343 additions and 100 deletions

5
CHANGELOG Normal file
View file

@ -0,0 +1,5 @@
cage-kiosk (0.2.1-1) unstable; urgency=low
* Enabled rotation again with wlroots >= 0.18.0
-- Joerg Bernau <Joerg.Bernau@salz-automation.com> Mon, 26 May 2025 12:00:00 +0000

View file

@ -19,6 +19,13 @@ All releases are published on [GitHub](https://github.com/cage-kiosk/cage/releas
## Building and running Cage ## Building and running Cage
### Installing dependencies
``` bash
sudo apt install -y libexpat-dev libdisplay-info-dev libliftoff-dev libxcb-errors-dev mesa-common-dev libegl1-mesa-dev libgl1-mesa-dev libgbm-dev libglvnd-core-dev libglw1-mesa-dev libwxgtk3.2-dev libxcb-dri3-dev libxcb-composite0-dev libxcb-present-dev libxcb-render-util0-dev libxcb-ewmh-dev libxcb-xinput-dev libxcb-res0-dev libxcb-icccm4-dev libinput-dev libcairo2-dev libvulkan-dev glslang-dev libseat-dev libsystemd-dev libmng-dev libicu-dev scdoc xwayland hwdata valgrind librust-xkb-dev
```
You can build Cage with the [meson](https://mesonbuild.com/) build system. It You can build Cage with the [meson](https://mesonbuild.com/) build system. It
requires wayland, wlroots, and xkbcommon to be installed. Optionally, install requires wayland, wlroots, and xkbcommon to be installed. Optionally, install
scdoc for manual pages. Cage is currently based on branch 0.18 of wlroots. scdoc for manual pages. Cage is currently based on branch 0.18 of wlroots.

View file

@ -22,6 +22,10 @@ activities outside the scope of the running application are prevented.
*-D* *-D*
Enable debug logging. Enable debug logging.
*-r*
Transform display orienation
90 | 180 | 270 | flipped | flipped-90 | flipped-180 | flipped-170
*-h* *-h*
Show the help message. Show the help message.

46
cage.c
View file

@ -226,13 +226,15 @@ usage(FILE *file, const char *cage)
fprintf(file, fprintf(file,
"Usage: %s [OPTIONS] [--] [APPLICATION...]\n" "Usage: %s [OPTIONS] [--] [APPLICATION...]\n"
"\n" "\n"
" -d\t Don't draw client side decorations, when possible\n" " -d Don't draw client side decorations, when possible\n"
" -D\t Enable debug logging\n" " -D Enable debug logging\n"
" -h\t Display this help message\n" " -h Display this help message\n"
" -r Transform display\n"
" [90, 180, 270, flipped, flipped-90, flipped-180, flipped-170]\n"
" -m extend Extend the display across all connected outputs (default)\n" " -m extend Extend the display across all connected outputs (default)\n"
" -m last Use only the last connected output\n" " -m last Use only the last connected output\n"
" -s\t Allow VT switching\n" " -s Allow VT switching\n"
" -v\t Show the version number and exit\n" " -v Show the version number and exit\n"
"\n" "\n"
" Use -- when you want to pass arguments to APPLICATION\n", " Use -- when you want to pass arguments to APPLICATION\n",
cage); cage);
@ -242,7 +244,7 @@ static bool
parse_args(struct cg_server *server, int argc, char *argv[]) parse_args(struct cg_server *server, int argc, char *argv[])
{ {
int c; int c;
while ((c = getopt(argc, argv, "dDhm:sv")) != -1) { while ((c = getopt(argc, argv, "dDhm:r:sv")) != -1) {
switch (c) { switch (c) {
case 'd': case 'd':
server->xdg_decoration = true; server->xdg_decoration = true;
@ -260,6 +262,25 @@ parse_args(struct cg_server *server, int argc, char *argv[])
server->output_mode = CAGE_MULTI_OUTPUT_MODE_EXTEND; server->output_mode = CAGE_MULTI_OUTPUT_MODE_EXTEND;
} }
break; break;
case 'r':
if (strcmp(optarg, "90") == 0) {
server->transform = WL_OUTPUT_TRANSFORM_90;
} else if (strcmp(optarg, "180") == 0) {
server->transform = WL_OUTPUT_TRANSFORM_180;
} else if (strcmp(optarg, "270") == 0) {
server->transform = WL_OUTPUT_TRANSFORM_270;
} else if (strcmp(optarg, "flipped") == 0) {
server->transform = WL_OUTPUT_TRANSFORM_FLIPPED;
} else if (strcmp(optarg, "flipped-90") == 0) {
server->transform = WL_OUTPUT_TRANSFORM_FLIPPED_90;
} else if (strcmp(optarg, "flipped-180") == 0) {
server->transform = WL_OUTPUT_TRANSFORM_FLIPPED_180;
} else if (strcmp(optarg, "flipped-270") == 0) {
server->transform = WL_OUTPUT_TRANSFORM_FLIPPED_270;
} else {
wlr_log(WLR_ERROR, "got unknown transform value: %s", optarg);
}
break;
case 's': case 's':
server->allow_vt_switch = true; server->allow_vt_switch = true;
break; break;
@ -280,6 +301,8 @@ main(int argc, char *argv[])
{ {
struct cg_server server = {.log_level = WLR_INFO}; struct cg_server server = {.log_level = WLR_INFO};
struct wl_event_source *sigchld_source = NULL; struct wl_event_source *sigchld_source = NULL;
server.transform = WL_OUTPUT_TRANSFORM_NORMAL;
pid_t pid = 0; pid_t pid = 0;
int ret = 0, app_ret = 0; int ret = 0, app_ret = 0;
@ -304,7 +327,7 @@ main(int argc, char *argv[])
wlr_log(WLR_ERROR, "Cannot allocate a Wayland display"); wlr_log(WLR_ERROR, "Cannot allocate a Wayland display");
return 1; return 1;
} }
server.display_destroy.notify = handle_display_destroy; server.display_destroy.notify = handle_display_destroy;
wl_display_add_destroy_listener(server.wl_display, &server.display_destroy); wl_display_add_destroy_listener(server.wl_display, &server.display_destroy);
@ -416,7 +439,7 @@ main(int argc, char *argv[])
wl_signal_add(&server.idle_inhibit_v1->events.new_inhibitor, &server.new_idle_inhibitor_v1); wl_signal_add(&server.idle_inhibit_v1->events.new_inhibitor, &server.new_idle_inhibitor_v1);
wl_list_init(&server.inhibitors); wl_list_init(&server.inhibitors);
struct wlr_xdg_shell *xdg_shell = wlr_xdg_shell_create(server.wl_display, 5); struct wlr_xdg_shell *xdg_shell = wlr_xdg_shell_create(server.wl_display, 4);
if (!xdg_shell) { if (!xdg_shell) {
wlr_log(WLR_ERROR, "Unable to create the XDG shell interface"); wlr_log(WLR_ERROR, "Unable to create the XDG shell interface");
ret = 1; ret = 1;
@ -454,7 +477,7 @@ main(int argc, char *argv[])
goto end; goto end;
} }
struct wlr_presentation *presentation = wlr_presentation_create(server.wl_display, server.backend, 2); struct wlr_presentation *presentation = wlr_presentation_create(server.wl_display, server.backend);
if (!presentation) { if (!presentation) {
wlr_log(WLR_ERROR, "Unable to create the presentation interface"); wlr_log(WLR_ERROR, "Unable to create the presentation interface");
ret = 1; ret = 1;
@ -630,8 +653,5 @@ end:
/* This function is not null-safe, but we only ever get here /* This function is not null-safe, but we only ever get here
with a proper wl_display. */ with a proper wl_display. */
wl_display_destroy(server.wl_display); wl_display_destroy(server.wl_display);
wlr_scene_node_destroy(&server.scene->tree.node);
wlr_allocator_destroy(server.allocator);
wlr_renderer_destroy(server.renderer);
return ret; return ret;
} }

87
debian/changelog vendored Normal file
View file

@ -0,0 +1,87 @@
cage (0.2.1-1) experimental; urgency=low
* Added rotation again under wlroots-18
-- Joerg.Bernau <Joerg.Bernau@salz-automation.com> Mon, 26 May 2025 12:00:00 +0000
cage (0.2.0-2) unstable; urgency=medium
* Reupload to unstable
-- Birger Schacht <birger@debian.org> Thu, 26 Dec 2024 15:07:29 +0100
cage (0.2.0-1) experimental; urgency=medium
* New upstream release (Closes: #1081391)
* d/control: bump wlroots build dependency
* d/rules: drop dh_auto_configure override (it was only used for the
xwayland compile time option, which does not exist anymore)
-- Birger Schacht <birger@debian.org> Mon, 07 Oct 2024 16:06:52 +0200
cage (0.1.5+20240127-2) unstable; urgency=medium
* Add xwayland to Dependencies (Closes: #1063495)
-- Birger Schacht <birger@debian.org> Fri, 09 Feb 2024 08:32:52 +0100
cage (0.1.5+20240127-1) unstable; urgency=medium
* Upload updated unrelease upstream sources for wlroots 0.17
compatibility (Closes: #1058495)
* d/rules: change meson option from `true` to `enabled`
* d/copyright: bump years
* d/control: set and update build-dep version constraints
-- Birger Schacht <birger@debian.org> Sat, 27 Jan 2024 10:44:53 +0100
cage (0.1.5-1) unstable; urgency=medium
* New upstream release
-- Birger Schacht <birger@debian.org> Fri, 28 Jul 2023 18:56:42 +0200
cage (0.1.4+20230724-1) unstable; urgency=medium
* Package latest upstream sources (Closes: #1041851)
* Drop backported patches
* Update all references to new git repository
* d/control:
+ Bump standards-version to 4.6.2 (no changes required)
* d/changelog:
+ Bump years
-- Birger Schacht <birger@debian.org> Mon, 24 Jul 2023 14:26:42 +0200
cage (0.1.4-4) unstable; urgency=medium
[ Debian Janitor ]
* Remove constraints unnecessary since buster:
+ Build-Depends: Drop versioned constraint on wayland-protocols.
[ Birger Schacht ]
* Adapt d/watch to use gitmode
* Bump Standards-Version to 4.6.1.0 (no changes required)
-- Birger Schacht <birger@debian.org> Wed, 12 Oct 2022 15:54:08 +0200
cage (0.1.4-3) unstable; urgency=medium
* Add patches to build with wlroots 0.15 (thanks to jbicha, Closes: #1008350)
* Drop filenamemangle option from d/watch
* Update year range in d/copyright stanza for debian/*
-- Birger Schacht <birger@debian.org> Sun, 03 Apr 2022 19:27:37 +0200
cage (0.1.4-2) unstable; urgency=medium
* Fix d/watch
* Add upstream signing key
-- Birger Schacht <birger@debian.org> Tue, 28 Dec 2021 10:05:58 +0100
cage (0.1.4-1) unstable; urgency=medium
* Initial packaging (Closes: #927899)
-- Birger Schacht <birger@debian.org> Thu, 16 Dec 2021 12:19:06 +0100

35
debian/control vendored Normal file
View file

@ -0,0 +1,35 @@
Source: cage
Section: x11
Priority: optional
Maintainer: Sway and related packages team <team+swaywm@tracker.debian.org>
Uploaders: Birger Schacht <birger@debian.org>
Build-Depends:
debhelper-compat (= 13),
libwlroots-0.18-dev (>= 0.18.0),
wayland-protocols (>= 1.14.0),
libwayland-server0,
libpixman-1-dev,
libxkbcommon-dev,
scdoc,
meson,
pkgconf,
Standards-Version: 4.6.2
Homepage: https://github.com/cage-kiosk/cage
Vcs-Browser: https://salsa.debian.org/swaywm-team/cage
Vcs-Git: https://salsa.debian.org/swaywm-team/cage.git
Rules-Requires-Root: no
Package: cage
Architecture: any
Depends:
${shlibs:Depends},
${misc:Depends},
xwayland
Description: Kiosk compositor for Wayland
Cage is a kiosk compositor for Wayland. A kiosk is a window manager (in the
X11 world) or compositor (in the Wayland world) that is designed for a user
experience wherein user interaction and activities outside the scope of the
running application are prevented. That is, a kiosk compositor displays a
single maximized application at a time and prevents the user from interacting
with anything but this application.

4
debian/md5sums vendored Normal file
View file

@ -0,0 +1,4 @@
93749c0770fc645faa23fe1295805ed1 usr/bin/cage
32e025aab0ec2a216980bda8845051e2 usr/share/doc/cage/changelog.Debian.gz
a77e584bb3560e2eff09e4493db141da usr/share/doc/cage/copyright
2a320cfa4b6a2cf7eb1839efdebbd2e0 usr/share/man/man1/cage.1.gz

13
debian/rules vendored Normal file
View file

@ -0,0 +1,13 @@
#!/usr/bin/make -f
# -*- makefile -*-
export DH_VERBOSE=1
export DH_OPTIONS=-v
include /usr/share/dpkg/pkg-info.mk
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
%:
dh $@ --buildsystem=meson

View file

@ -35,7 +35,7 @@ if is_freebsd
) )
endif endif
wlroots = dependency('wlroots-0.19', fallback: ['wlroots', 'wlroots']) wlroots = dependency('wlroots-0.18', fallback: ['wlroots', 'wlroots'], version: '>=0.17.0',)
wayland_protos = dependency('wayland-protocols', version: '>=1.14') wayland_protos = dependency('wayland-protocols', version: '>=1.14')
wayland_server = dependency('wayland-server') wayland_server = dependency('wayland-server')
xkbcommon = dependency('xkbcommon') xkbcommon = dependency('xkbcommon')

View file

@ -15,24 +15,24 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <wayland-server-core.h> #include <wayland-server-core.h>
#include <wlr/version.h>
#include <wlr/backend.h> #include <wlr/backend.h>
#include <wlr/backend/wayland.h> #include <wlr/backend/wayland.h>
#include <wlr/config.h> #include <wlr/config.h>
#if WLR_HAS_X11_BACKEND #if WLR_HAS_X11_BACKEND
#include <wlr/backend/x11.h> #include <wlr/backend/x11.h>
#endif #endif
#include <wlr/render/swapchain.h>
#include <wlr/render/wlr_renderer.h> #include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_compositor.h> #include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_data_device.h> #include <wlr/types/wlr_data_device.h>
#include <wlr/types/wlr_output.h> #include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_output_layout.h> #include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_output_management_v1.h> #include <wlr/types/wlr_output_management_v1.h>
#include <wlr/types/wlr_output_swapchain_manager.h>
#include <wlr/types/wlr_scene.h> #include <wlr/types/wlr_scene.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>
#include <wlr/util/region.h> #include <wlr/util/region.h>
#include <wlr/types/wlr_output_management_v1.h>
#include "output.h" #include "output.h"
#include "seat.h" #include "seat.h"
@ -62,6 +62,7 @@ update_output_manager_config(struct cg_server *server)
if (!wlr_box_empty(&output_box)) { if (!wlr_box_empty(&output_box)) {
config_head->state.x = output_box.x; config_head->state.x = output_box.x;
config_head->state.y = output_box.y; config_head->state.y = output_box.y;
config_head->state.transform = server->transform;
} }
} }
@ -132,6 +133,31 @@ output_disable(struct cg_output *output)
output_layout_remove(output); output_layout_remove(output);
} }
static bool
output_apply_config(struct cg_output *output, struct wlr_output_configuration_head_v1 *head, bool test_only)
{
struct wlr_output_state state = {0};
wlr_output_head_v1_state_apply(&head->state, &state);
if (test_only) {
bool ret = wlr_output_test_state(output->wlr_output, &state);
return ret;
}
/* Apply output configuration */
if (!wlr_output_commit_state(output->wlr_output, &state)) {
return false;
}
if (head->state.enabled) {
output_layout_add(output, head->state.x, head->state.y);
} else {
output_layout_remove(output);
}
return true;
}
static void static void
handle_output_frame(struct wl_listener *listener, void *data) handle_output_frame(struct wl_listener *listener, void *data)
{ {
@ -178,7 +204,6 @@ void
handle_output_layout_change(struct wl_listener *listener, void *data) handle_output_layout_change(struct wl_listener *listener, void *data)
{ {
struct cg_server *server = wl_container_of(listener, server, output_layout_change); struct cg_server *server = wl_container_of(listener, server, output_layout_change);
view_position_all(server); view_position_all(server);
update_output_manager_config(server); update_output_manager_config(server);
} }
@ -291,7 +316,8 @@ handle_new_output(struct wl_listener *listener, void *data)
} }
} }
if (server->output_mode == CAGE_MULTI_OUTPUT_MODE_LAST && wl_list_length(&server->outputs) > 1) { if (server->output_mode == CAGE_MULTI_OUTPUT_MODE_LAST
&& wl_list_length(&server->outputs) > 1) {
struct cg_output *next = wl_container_of(output->link.next, next, link); struct cg_output *next = wl_container_of(output->link.next, next, link);
output_disable(next); output_disable(next);
} }
@ -300,8 +326,12 @@ handle_new_output(struct wl_listener *listener, void *data)
wlr_log(WLR_ERROR, "Cannot load XCursor theme for output '%s' with scale %f", wlr_output->name, wlr_log(WLR_ERROR, "Cannot load XCursor theme for output '%s' with scale %f", wlr_output->name,
wlr_output->scale); wlr_output->scale);
} }
if (server->transform != WL_OUTPUT_TRANSFORM_NORMAL) {
wlr_output_state_set_transform(&state, server->transform);
}
wlr_log(WLR_DEBUG, "Enabling new output %s", wlr_output->name); wlr_log(WLR_INFO, "Enabling new output %s", wlr_output->name);
if (wlr_output_commit_state(wlr_output, &state)) { if (wlr_output_commit_state(wlr_output, &state)) {
output_layout_add_auto(output); output_layout_add_auto(output);
} }
@ -332,63 +362,17 @@ output_set_window_title(struct cg_output *output, const char *title)
static bool static bool
output_config_apply(struct cg_server *server, struct wlr_output_configuration_v1 *config, bool test_only) output_config_apply(struct cg_server *server, struct wlr_output_configuration_v1 *config, bool test_only)
{ {
bool ok = false;
size_t states_len;
struct wlr_backend_output_state *states = wlr_output_configuration_v1_build_state(config, &states_len);
if (states == NULL) {
return false;
}
struct wlr_output_swapchain_manager swapchain_manager;
wlr_output_swapchain_manager_init(&swapchain_manager, server->backend);
ok = wlr_output_swapchain_manager_prepare(&swapchain_manager, states, states_len);
if (!ok || test_only) {
goto out;
}
for (size_t i = 0; i < states_len; i++) {
struct wlr_backend_output_state *backend_state = &states[i];
struct cg_output *output = backend_state->output->data;
struct wlr_swapchain *swapchain =
wlr_output_swapchain_manager_get_swapchain(&swapchain_manager, backend_state->output);
struct wlr_scene_output_state_options options = {
.swapchain = swapchain,
};
struct wlr_output_state *state = &backend_state->base;
if (!wlr_scene_output_build_state(output->scene_output, state, &options)) {
ok = false;
goto out;
}
}
ok = wlr_backend_commit(server->backend, states, states_len);
if (!ok) {
goto out;
}
wlr_output_swapchain_manager_apply(&swapchain_manager);
struct wlr_output_configuration_head_v1 *head; struct wlr_output_configuration_head_v1 *head;
wl_list_for_each (head, &config->heads, link) { wl_list_for_each (head, &config->heads, link) {
struct cg_output *output = head->state.output->data; struct cg_output *output = head->state.output->data;
if (head->state.enabled) { if (!output_apply_config(output, head, test_only)) {
output_layout_add(output, head->state.x, head->state.y); return false;
} else {
output_layout_remove(output);
} }
} }
out: return true;
wlr_output_swapchain_manager_finish(&swapchain_manager);
for (size_t i = 0; i < states_len; i++) {
wlr_output_state_finish(&states[i].base);
}
free(states);
return ok;
} }
void void

View file

@ -25,5 +25,4 @@ void handle_output_manager_test(struct wl_listener *listener, void *data);
void handle_output_layout_change(struct wl_listener *listener, void *data); void handle_output_layout_change(struct wl_listener *listener, void *data);
void handle_new_output(struct wl_listener *listener, void *data); void handle_new_output(struct wl_listener *listener, void *data);
void output_set_window_title(struct cg_output *output, const char *title); void output_set_window_title(struct cg_output *output, const char *title);
#endif #endif

2
seat.c
View file

@ -937,7 +937,7 @@ seat_set_focus(struct cg_seat *seat, struct cg_view *view)
#if CAGE_HAS_XWAYLAND #if CAGE_HAS_XWAYLAND
if (view->type == CAGE_XWAYLAND_VIEW) { if (view->type == CAGE_XWAYLAND_VIEW) {
struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view); struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view);
if (!wlr_xwayland_surface_override_redirect_wants_focus(xwayland_view->xwayland_surface)) { if (!wlr_xwayland_or_surface_wants_focus(xwayland_view->xwayland_surface)) {
return; return;
} }
} }

View file

@ -66,6 +66,7 @@ struct cg_server {
bool return_app_code; bool return_app_code;
bool terminated; bool terminated;
enum wlr_log_importance log_level; enum wlr_log_importance log_level;
enum wl_output_transform transform;
}; };
void server_terminate(struct cg_server *server); void server_terminate(struct cg_server *server);

View file

@ -0,0 +1,2 @@
[wrap-redirect]
filename = libdisplay-info/subprojects/edid-decode.wrap

View file

@ -0,0 +1,7 @@
[wrap-git]
directory = libdisplay-info
url = https://gitlab.freedesktop.org/emersion/libdisplay-info.git
revision = 5ea36938334f3af016c273ba88679f018ea0b1c6
depth = 1
[patch]

View file

@ -0,0 +1,4 @@
[wrap-git]
url = https://git.linuxtv.org/edid-decode.git
revision = c6b859d7f0251e2433fb81bd3f67bd2011c2036c

7
subprojects/libdrm.wrap Normal file
View file

@ -0,0 +1,7 @@
[wrap-git]
directory = libdrm
url = https://gitlab.freedesktop.org/mesa/drm.git
revision = 38ec7dbd4df3141441afafe5ac62dfc9df36a77e
depth = 1
[patch]

View file

@ -0,0 +1,7 @@
[wrap-git]
directory = libliftoff
url = https://gitlab.freedesktop.org/emersion/libliftoff.git
revision = 8b08dc1c14fd019cc90ddabe34ad16596b0691f4
depth = 1
[patch]

View file

@ -0,0 +1,8 @@
[wrap-git]
directory = xkbcommon
url = https://github.com/xkbcommon/libxkbcommon.git
revision = master
tag = xkbcommon-1.9.2
depth = 1
[patch]

9
subprojects/pixman.wrap Normal file
View file

@ -0,0 +1,9 @@
[wrap-file]
directory = pixman-0.43.4
source_url = https://www.x.org/releases/individual/lib/pixman-0.43.4.tar.xz
source_filename = pixman-0.43.4.tar.xz
source_hash = 48d8539f35488d694a2fef3ce17394d1153ed4e71c05d1e621904d574be5df19
[provide]
pixman-1 = idep_pixman

8
subprojects/seatd.wrap Normal file
View file

@ -0,0 +1,8 @@
[wrap-git]
directory = seatd
url = https://github.com/kennylevinsen/seatd.git
revision = master
tag = v0.9.1
depth = 1
[patch]

View file

@ -0,0 +1,8 @@
[wrap-git]
directory = wayland-protocols
url = https://gitlab.freedesktop.org/wayland/wayland-protocols.git
revision = 810f1adaf33521cc55fc510566efba2a1418174f
depth = 1
[patch]

7
subprojects/wayland.wrap Normal file
View file

@ -0,0 +1,7 @@
[wrap-git]
directory = wayland
url = https://gitlab.freedesktop.org/wayland/wayland.git
revision = a9fec8dd65977c57f4039ced34327204d9b9d779
depth = 1
[patch]

7
subprojects/wlroots.wrap Normal file
View file

@ -0,0 +1,7 @@
[wrap-git]
directory = wlroots
url = https://gitlab.freedesktop.org/wlroots/wlroots.git
revision = 766a228da4eaea221470c2b939ce3db20a9d1600
depth = 1
[patch]

6
x86_64-amd64-cross.txt Normal file
View file

@ -0,0 +1,6 @@
[binaries]
c = 'clang'
cpp = 'clang'
[properties]
pkg_config_libdir = '/lib/aarch64-linux-gnu/pkgconfig/'

18
x86_64-arm64-cross.txt Normal file
View file

@ -0,0 +1,18 @@
[binaries]
c = 'aarch64-linux-gnu-gcc'
cpp = 'aarch64-linux-gnu-g++'
ar = 'aarch64-linux-gnu-ar'
windres = 'aarch64-linux-gnu-windres'
strip = 'aarch64-linux-gnu-strip'
pkgconfig = 'pkg-config'
[host_machine]
system = 'linux'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'
[properties]
pkg_config_libdir = '/lib/aarch64-linux-gnu/pkgconfig/'

View file

@ -128,10 +128,11 @@ static void
get_geometry(struct cg_view *view, int *width_out, int *height_out) get_geometry(struct cg_view *view, int *width_out, int *height_out)
{ {
struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view); struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view);
struct wlr_xdg_surface *xdg_surface = xdg_shell_view->xdg_toplevel->base; struct wlr_box geom;
*width_out = xdg_surface->geometry.width; wlr_xdg_surface_get_geometry(xdg_shell_view->xdg_toplevel->base, &geom);
*height_out = xdg_surface->geometry.height; *width_out = geom.width;
*height_out = geom.height;
} }
static bool static bool
@ -184,7 +185,7 @@ destroy(struct cg_view *view)
} }
static void static void
handle_xdg_toplevel_request_fullscreen(struct wl_listener *listener, void *data) handle_xdg_shell_surface_request_fullscreen(struct wl_listener *listener, void *data)
{ {
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, request_fullscreen); struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, request_fullscreen);
@ -201,7 +202,7 @@ handle_xdg_toplevel_request_fullscreen(struct wl_listener *listener, void *data)
} }
static void static void
handle_xdg_toplevel_unmap(struct wl_listener *listener, void *data) handle_xdg_shell_surface_unmap(struct wl_listener *listener, void *data)
{ {
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, unmap); struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, unmap);
struct cg_view *view = &xdg_shell_view->view; struct cg_view *view = &xdg_shell_view->view;
@ -210,7 +211,7 @@ handle_xdg_toplevel_unmap(struct wl_listener *listener, void *data)
} }
static void static void
handle_xdg_toplevel_map(struct wl_listener *listener, void *data) handle_xdg_shell_surface_map(struct wl_listener *listener, void *data)
{ {
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, map); struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, map);
struct cg_view *view = &xdg_shell_view->view; struct cg_view *view = &xdg_shell_view->view;
@ -219,7 +220,7 @@ handle_xdg_toplevel_map(struct wl_listener *listener, void *data)
} }
static void static void
handle_xdg_toplevel_commit(struct wl_listener *listener, void *data) handle_xdg_shell_surface_commit(struct wl_listener *listener, void *data)
{ {
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, commit); struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, commit);
@ -227,15 +228,13 @@ handle_xdg_toplevel_commit(struct wl_listener *listener, void *data)
return; return;
} }
wlr_xdg_toplevel_set_wm_capabilities(xdg_shell_view->xdg_toplevel, XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
/* When an xdg_surface performs an initial commit, the compositor must /* When an xdg_surface performs an initial commit, the compositor must
* reply with a configure so the client can map the surface. */ * reply with a configure so the client can map the surface. */
view_position(&xdg_shell_view->view); view_position(&xdg_shell_view->view);
} }
static void static void
handle_xdg_toplevel_destroy(struct wl_listener *listener, void *data) handle_xdg_shell_surface_destroy(struct wl_listener *listener, void *data)
{ {
struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, destroy); struct cg_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, destroy);
struct cg_view *view = &xdg_shell_view->view; struct cg_view *view = &xdg_shell_view->view;
@ -275,15 +274,15 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data)
view_init(&xdg_shell_view->view, server, CAGE_XDG_SHELL_VIEW, &xdg_shell_view_impl); view_init(&xdg_shell_view->view, server, CAGE_XDG_SHELL_VIEW, &xdg_shell_view_impl);
xdg_shell_view->xdg_toplevel = toplevel; xdg_shell_view->xdg_toplevel = toplevel;
xdg_shell_view->commit.notify = handle_xdg_toplevel_commit; xdg_shell_view->commit.notify = handle_xdg_shell_surface_commit;
wl_signal_add(&toplevel->base->surface->events.commit, &xdg_shell_view->commit); wl_signal_add(&toplevel->base->surface->events.commit, &xdg_shell_view->commit);
xdg_shell_view->map.notify = handle_xdg_toplevel_map; xdg_shell_view->map.notify = handle_xdg_shell_surface_map;
wl_signal_add(&toplevel->base->surface->events.map, &xdg_shell_view->map); wl_signal_add(&toplevel->base->surface->events.map, &xdg_shell_view->map);
xdg_shell_view->unmap.notify = handle_xdg_toplevel_unmap; xdg_shell_view->unmap.notify = handle_xdg_shell_surface_unmap;
wl_signal_add(&toplevel->base->surface->events.unmap, &xdg_shell_view->unmap); wl_signal_add(&toplevel->base->surface->events.unmap, &xdg_shell_view->unmap);
xdg_shell_view->destroy.notify = handle_xdg_toplevel_destroy; xdg_shell_view->destroy.notify = handle_xdg_shell_surface_destroy;
wl_signal_add(&toplevel->events.destroy, &xdg_shell_view->destroy); wl_signal_add(&toplevel->events.destroy, &xdg_shell_view->destroy);
xdg_shell_view->request_fullscreen.notify = handle_xdg_toplevel_request_fullscreen; xdg_shell_view->request_fullscreen.notify = handle_xdg_shell_surface_request_fullscreen;
wl_signal_add(&toplevel->events.request_fullscreen, &xdg_shell_view->request_fullscreen); wl_signal_add(&toplevel->events.request_fullscreen, &xdg_shell_view->request_fullscreen);
toplevel->base->data = xdg_shell_view; toplevel->base->data = xdg_shell_view;
@ -295,7 +294,6 @@ popup_handle_destroy(struct wl_listener *listener, void *data)
struct cg_xdg_popup *popup = wl_container_of(listener, popup, destroy); struct cg_xdg_popup *popup = wl_container_of(listener, popup, destroy);
wl_list_remove(&popup->destroy.link); wl_list_remove(&popup->destroy.link);
wl_list_remove(&popup->commit.link); wl_list_remove(&popup->commit.link);
wl_list_remove(&popup->reposition.link);
free(popup); free(popup);
} }
@ -309,14 +307,6 @@ popup_handle_commit(struct wl_listener *listener, void *data)
} }
} }
static void
popup_handle_reposition(struct wl_listener *listener, void *data)
{
struct cg_xdg_popup *popup = wl_container_of(listener, popup, reposition);
popup_unconstrain(popup->xdg_popup);
}
void void
handle_new_xdg_popup(struct wl_listener *listener, void *data) handle_new_xdg_popup(struct wl_listener *listener, void *data)
{ {
@ -361,9 +351,6 @@ handle_new_xdg_popup(struct wl_listener *listener, void *data)
popup->commit.notify = popup_handle_commit; popup->commit.notify = popup_handle_commit;
wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit); wl_signal_add(&wlr_popup->base->surface->events.commit, &popup->commit);
popup->reposition.notify = popup_handle_reposition;
wl_signal_add(&wlr_popup->events.reposition, &popup->reposition);
struct wlr_scene_tree *popup_scene_tree = wlr_scene_xdg_surface_create(parent_scene_tree, wlr_popup->base); struct wlr_scene_tree *popup_scene_tree = wlr_scene_xdg_surface_create(parent_scene_tree, wlr_popup->base);
if (popup_scene_tree == NULL) { if (popup_scene_tree == NULL) {
wlr_log(WLR_ERROR, "Failed to allocate scene-graph node for XDG popup"); wlr_log(WLR_ERROR, "Failed to allocate scene-graph node for XDG popup");

View file

@ -31,7 +31,6 @@ struct cg_xdg_popup {
struct wl_listener destroy; struct wl_listener destroy;
struct wl_listener commit; struct wl_listener commit;
struct wl_listener reposition;
}; };
void handle_new_xdg_toplevel(struct wl_listener *listener, void *data); void handle_new_xdg_toplevel(struct wl_listener *listener, void *data);

View file

@ -92,7 +92,7 @@ maximize(struct cg_view *view, int output_width, int output_height)
struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view); struct cg_xwayland_view *xwayland_view = xwayland_view_from_view(view);
wlr_xwayland_surface_configure(xwayland_view->xwayland_surface, view->lx, view->ly, output_width, wlr_xwayland_surface_configure(xwayland_view->xwayland_surface, view->lx, view->ly, output_width,
output_height); output_height);
wlr_xwayland_surface_set_maximized(xwayland_view->xwayland_surface, true, true); wlr_xwayland_surface_set_maximized(xwayland_view->xwayland_surface, true);
} }
static void static void