From cdb2cb6cbc53e396eb722e215c198e90347abbf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 5 Nov 2025 16:31:21 +0100 Subject: [PATCH] xwayland: Adjust RandR emulation for rotation Need to use the extents of the output in screen cordinates, instead of the canonical mode size. Part-of: (cherry picked from commit 44dea3a8bda392e673c3db47000e23af5549ffc4) --- hw/xwayland/xwayland-output.c | 13 +++++++++--- hw/xwayland/xwayland-output.h | 2 ++ hw/xwayland/xwayland-window.c | 39 ++++++++++++++++++++++++----------- 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c index 3df7177ab..d377a0018 100644 --- a/hw/xwayland/xwayland-output.c +++ b/hw/xwayland/xwayland-output.c @@ -139,7 +139,7 @@ output_get_logical_mode(struct xwl_output *xwl_output, int *width, int *height) } } -static void +void output_get_logical_extents(struct xwl_output *xwl_output, int *width, int *height) { /* When we have xdg-output support the stored size is already rotated. */ @@ -518,8 +518,15 @@ xwl_output_randr_emu_prop(struct xwl_screen *xwl_screen, ClientPtr client, prop->rects[index][0] = xwl_output->logical_x; prop->rects[index][1] = xwl_output->logical_y; - prop->rects[index][2] = emulated_mode->width; - prop->rects[index][3] = emulated_mode->height; + + if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) { + prop->rects[index][2] = emulated_mode->width; + prop->rects[index][3] = emulated_mode->height; + } else { + prop->rects[index][2] = emulated_mode->height; + prop->rects[index][3] = emulated_mode->width; + } + index++; } diff --git a/hw/xwayland/xwayland-output.h b/hw/xwayland/xwayland-output.h index 17bdf94d9..8bce0ba63 100644 --- a/hw/xwayland/xwayland-output.h +++ b/hw/xwayland/xwayland-output.h @@ -111,6 +111,8 @@ void xwl_output_remove(struct xwl_output *xwl_output); struct xwl_emulated_mode *xwl_output_get_emulated_mode_for_client( struct xwl_output *xwl_output, ClientPtr client); +void output_get_logical_extents(struct xwl_output *xwl_output, int *width, int *height); + RRModePtr xwl_output_find_mode(struct xwl_output *xwl_output, int32_t width, int32_t height); void xwl_output_set_emulated_mode(struct xwl_output *xwl_output, diff --git a/hw/xwayland/xwayland-window.c b/hw/xwayland/xwayland-window.c index e9765c7b9..7a7a54da4 100644 --- a/hw/xwayland/xwayland-window.c +++ b/hw/xwayland/xwayland-window.c @@ -443,30 +443,35 @@ xwl_window_enable_viewport_for_output(struct xwl_window *xwl_window, struct xwl_emulated_mode *emulated_mode) { struct xwl_screen *xwl_screen = xwl_window->xwl_screen; - int width, height; + int width, height, logical_width, logical_height; + + if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) { + width = emulated_mode->width / xwl_screen->global_surface_scale; + height = emulated_mode->height / xwl_screen->global_surface_scale; + } else { + width = emulated_mode->height / xwl_screen->global_surface_scale; + height = emulated_mode->width / xwl_screen->global_surface_scale; + } + + output_get_logical_extents(xwl_output, &logical_width, &logical_height); if (!xwl_window_has_viewport_enabled(xwl_window)) { DebugF("XWAYLAND: enabling viewport %dx%d -> %dx%d\n", - emulated_mode->width, emulated_mode->height, - xwl_output->logical_w, xwl_output->logical_h); + width, height, logical_width, logical_height); xwl_window->viewport = wp_viewporter_get_viewport(xwl_window->xwl_screen->viewporter, xwl_window->surface); } - width = emulated_mode->width / xwl_screen->global_surface_scale; - height = emulated_mode->height / xwl_screen->global_surface_scale; - wp_viewport_set_source(xwl_window->viewport, wl_fixed_from_int(0), wl_fixed_from_int(0), wl_fixed_from_int(width), wl_fixed_from_int(height)); wp_viewport_set_destination(xwl_window->viewport, - xwl_output->logical_w, - xwl_output->logical_h); + logical_width, logical_height); - xwl_window->viewport_scale_x = (float) width / xwl_output->logical_w; - xwl_window->viewport_scale_y = (float) height / xwl_output->logical_h; + xwl_window->viewport_scale_x = (float) width / logical_width; + xwl_window->viewport_scale_y = (float) height / logical_height; xwl_window_set_input_region(xwl_window, wInputShape(xwl_window->toplevel)); } @@ -602,14 +607,24 @@ xwl_window_should_enable_viewport(struct xwl_window *xwl_window, * This path gets hit by most games / libs (e.g. SDL, SFML, OGRE) */ xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) { + int emulated_width, emulated_height; + emulated_mode = xwl_output_get_emulated_mode_for_client(xwl_output, owner); if (!emulated_mode) continue; + if (xwl_output->rotation & (RR_Rotate_0 | RR_Rotate_180)) { + emulated_width = emulated_mode->width; + emulated_height = emulated_mode->height; + } else { + emulated_width = emulated_mode->height; + emulated_height = emulated_mode->width; + } + if (drawable->x == xwl_output->logical_x && drawable->y == xwl_output->logical_y && - drawable->width == emulated_mode->width && - drawable->height == emulated_mode->height) { + drawable->width == emulated_width && + drawable->height == emulated_height) { memcpy(emulated_mode_ret, emulated_mode, sizeof(struct xwl_emulated_mode)); *xwl_output_ret = xwl_output;