Added feature for rotation for wlroots-18 again

This commit is contained in:
Jörg Bernau 2025-09-08 15:41:47 +02:00
parent 2e593fe5a8
commit ddc51ce1e5
14 changed files with 131 additions and 101 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;
} }

View file

@ -1,5 +1,5 @@
project('cage', 'c', project('cage', 'c',
version: '0.2.0', version: '0.2.1',
license: 'MIT', license: 'MIT',
meson_version: '>=0.58.1', meson_version: '>=0.58.1',
default_options: [ default_options: [
@ -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);

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