From ff641acc654e4e02b8b962844b4789e14ea4f96f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Mon, 28 Feb 2022 18:08:23 +0100 Subject: [PATCH] xwayland: Add RandR mode for the native resolution if it fits in logical Always add it as the first mode, which makes it considered the preferred mode per the RandR protocol. Mark the logical mode as currently set. v2: * Drop change in xwl_window_should_enable_viewport which seems unnecessary and coult result in a crash. (Olivier Fourdan) * Use 'native' instead of 'actual'. Part-of: (cherry picked from commit 288dcb3128611806425e55b934303fe40d89bcf1) --- hw/xwayland/xwayland-output.c | 41 +++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/hw/xwayland/xwayland-output.c b/hw/xwayland/xwayland-output.c index 066e305cc..dad5689ce 100644 --- a/hw/xwayland/xwayland-output.c +++ b/hw/xwayland/xwayland-output.c @@ -375,27 +375,46 @@ output_get_rr_modes(struct xwl_output *xwl_output, RRModePtr *rr_modes; int i; - rr_modes = xallocarray(ARRAY_SIZE(xwl_output_fake_modes) + 1, sizeof(RRModePtr)); + rr_modes = xallocarray(ARRAY_SIZE(xwl_output_fake_modes) + 2, sizeof(RRModePtr)); if (!rr_modes) goto err; - /* Add actual output mode */ - rr_modes[0] = xwayland_cvt(width, height, xwl_output->refresh / 1000.0, 0, 0); - if (!rr_modes[0]) + *count = 0; + + if (xwl_screen_has_resolution_change_emulation(xwl_screen) && + (width > xwl_output->mode_width || + (width == xwl_output->mode_width && height > xwl_output->mode_height))) { + /* Add native output mode as preferred */ + rr_modes[0] = xwayland_cvt(xwl_output->mode_width, xwl_output->mode_height, + xwl_output->refresh / 1000.0, 0, 0); + if (!rr_modes[0]) + goto err; + + *count = 1; + } + + /* Add logical output mode */ + rr_modes[*count] = xwayland_cvt(width, height, xwl_output->refresh / 1000.0, 0, 0); + if (!rr_modes[*count]) goto err; - *count = 1; + (*count)++; if (!xwl_screen_has_resolution_change_emulation(xwl_screen) && !xwl_screen->force_xrandr_emulation) return rr_modes; /* Add fake modes */ for (i = 0; i < ARRAY_SIZE(xwl_output_fake_modes); i++) { - /* Skip actual output mode, already added */ + /* Skip logical output mode, already added */ if (xwl_output_fake_modes[i][0] == width && xwl_output_fake_modes[i][1] == height) continue; + /* Skip native output mode, already added */ + if (xwl_output_fake_modes[i][0] == xwl_output->mode_width && + xwl_output_fake_modes[i][1] == xwl_output->mode_height) + continue; + /* Skip modes which are too big, avoid downscaling */ if (xwl_output_fake_modes[i][0] > width || xwl_output_fake_modes[i][1] > height) @@ -657,6 +676,7 @@ apply_output_change(struct xwl_output *xwl_output) struct xwl_output *it; int logical_width, logical_height, count, has_this_output = 0; RRModePtr *randr_modes; + RRModePtr default_mode; /* Clear out the "done" received flags */ xwl_output->wl_output_done = FALSE; @@ -667,8 +687,15 @@ apply_output_change(struct xwl_output *xwl_output) if (xwl_output->randr_output) { /* Build a fresh modes array using the current refresh rate */ randr_modes = output_get_rr_modes(xwl_output, logical_width, logical_height, &count); + + if (randr_modes[0]->mode.width == logical_width && + randr_modes[0]->mode.height == logical_height) + default_mode = randr_modes[0]; + else + default_mode = randr_modes[1]; + RROutputSetModes(xwl_output->randr_output, randr_modes, count, 1); - RRCrtcNotify(xwl_output->randr_crtc, randr_modes[0], + RRCrtcNotify(xwl_output->randr_crtc, default_mode, xwl_output->logical_x, xwl_output->logical_y, xwl_output->rotation, NULL, 1, &xwl_output->randr_output); /* RROutputSetModes takes ownership of the passed in modes, so we only