From 74562e3c5ceb67e911899a6ed809f02482dbb850 Mon Sep 17 00:00:00 2001 From: Jeffrey Knockel Date: Sun, 12 May 2024 09:55:07 -0400 Subject: [PATCH 1/3] meta-monitor-manager-xrandr.c: fix crtc disabling CRTCs must also be disabled if the requested screen size is, in any dimension, smaller than what the screen size would be without any xrandr scaling applied. See, e.g., [1, 2]. [1] https://lists.x.org/archives/xorg-devel/2018-March/056203.html [2] https://github.com/linuxmint/muffin/blob/b15de53d7bc43dbcd0136cd7f845eb7ec9d89e6a/src/backends/x11/meta-monitor-manager-xrandr.c#L851 --- src/backends/x11/meta-monitor-manager-xrandr.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c index 0290475a7..40bae342e 100644 --- a/src/backends/x11/meta-monitor-manager-xrandr.c +++ b/src/backends/x11/meta-monitor-manager-xrandr.c @@ -550,7 +550,7 @@ apply_crtc_assignments (MetaMonitorManager *manager, MetaX11ScaleMode scale_mode = meta_settings_get_x11_scale_mode (settings); unsigned i, valid_crtcs; GList *l; - int width, height; + int width, height, scaled_width, scaled_height; float max_scale; float avg_screen_scale; gboolean have_scaling; @@ -563,6 +563,7 @@ apply_crtc_assignments (MetaMonitorManager *manager, /* Compute the new size of the screen (framebuffer) */ max_scale = get_maximum_crtc_info_scale (crtcs, n_crtcs); width = 0; height = 0; + scaled_width = 0; scaled_height = 0; avg_screen_scale = 0; valid_crtcs = 0; for (i = 0; i < n_crtcs; i++) @@ -578,6 +579,13 @@ apply_crtc_assignments (MetaMonitorManager *manager, if (have_scaling && scale_mode == META_X11_SCALE_MODE_UI_DOWN) scale = (ceilf (max_scale) / crtc_info->scale) * crtc_info->scale; + else + { + scaled_width = MAX (scaled_width, crtc_info->layout.origin.x + + crtc_info->layout.size.width * crtc_info->scale); + scaled_height = MAX (scaled_height, crtc_info->layout.origin.y + + crtc_info->layout.size.height * crtc_info->scale); + } width = MAX (width, (int) roundf (crtc_info->layout.origin.x + crtc_info->layout.size.width * scale)); @@ -609,7 +617,7 @@ apply_crtc_assignments (MetaMonitorManager *manager, y2 = (int) roundf (crtc_config->layout.origin.y + crtc_config->layout.size.height); - if (!crtc_info->mode || x2 > width || y2 > height) + if (!crtc_info->mode || width < scaled_width || height < scaled_height || x2 > width || y2 > height) { xrandr_set_crtc_config (manager_xrandr, crtc, From 652ff9b62b2d1ef2706a1c349692a3bd62339143 Mon Sep 17 00:00:00 2001 From: Jeffrey Knockel Date: Sun, 12 May 2024 10:15:39 -0400 Subject: [PATCH 2/3] meta-monitor-manager-xrandr.c: fix screen size Only call meta_monitor_manager_xrandr_update_screen_size() when the CRTCs have been, if necessary, disabled. It is always safe and sometimes required to call it in this state. Previously, for instance, we would not call it in this state when shrinking the screen size (e.g., when in fractional "scale-up" mode), but it is in fact required to call it in this state when using fractional "scale-up" mode. --- src/backends/x11/meta-monitor-manager-xrandr.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c index 40bae342e..77f60e2ab 100644 --- a/src/backends/x11/meta-monitor-manager-xrandr.c +++ b/src/backends/x11/meta-monitor-manager-xrandr.c @@ -669,7 +669,7 @@ apply_crtc_assignments (MetaMonitorManager *manager, if (!n_crtcs) goto out; - if (width > manager->screen_width || height > manager->screen_height) + if (width > 0 && height > 0) { meta_monitor_manager_xrandr_update_screen_size (manager_xrandr, width, height, @@ -791,13 +791,6 @@ apply_crtc_assignments (MetaMonitorManager *manager, output->is_primary = FALSE; } - if (width > 0 && height > 0) - { - meta_monitor_manager_xrandr_update_screen_size (manager_xrandr, - width, height, - avg_screen_scale); - } - out: XUngrabServer (manager_xrandr->xdisplay); XFlush (manager_xrandr->xdisplay); From c3dd5a41268dcb37e2b8faaeb0c26773250bd6b1 Mon Sep 17 00:00:00 2001 From: Jeffrey Knockel Date: Sun, 12 May 2024 10:38:06 -0400 Subject: [PATCH 3/3] meta-monitor-manager-xrandr.c: screen size fixes In previous commits, we have fixed "scale-up" fractional mode scaling when done via the display settings UI. However, there is still the matter of meta_monitor_manager_xrandr_update_screen_size_derived() which can be called on anyone's change to the xrandr configuration. Prior to this commit, to work around an issue where CRTCs must be disabled, this function *never* set the correct screen size when scaling up. This has some horrible consequences like breaking edges on the sides of monitors, windows appearing completely offscreen, incorrect workspace previews, etc., so we should *never* do this. Let's instead try to set the correct screen size. If it fails, that's fine because we are doing it via XCB and will merely log the error. It's better than always setting the wrong screen size. Plus, there is reason to think that the screen size will already be correct anyways. In previous commits we already fixed *our* handling of xrandr scaling to correctly update the screen size when the necessary CRTCs are disabled. Hopefully all other tools are doing it correctly as well and we never have to update the screen size here. :) If this prediction proves inaccurate, we can later update this function to (1) check if the screen size actually needs changing and, if it does, then (2) disable any CRTCs that need disabling before changing the screen size and (3) re-enable them after the change of screen size. Unfortunately I don't know if there is a simpler way. In general, we have to be careful to not disable CRTCs too eagerly either because disabling a CRTC is typically quite easily noticed by a user and results in the screen turning black for a moment. --- src/backends/x11/meta-monitor-manager-xrandr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c index 77f60e2ab..98eff49a3 100644 --- a/src/backends/x11/meta-monitor-manager-xrandr.c +++ b/src/backends/x11/meta-monitor-manager-xrandr.c @@ -847,7 +847,7 @@ meta_monitor_manager_xrandr_update_screen_size_derived (MetaMonitorManager *mana if (!crtc || !crtc->config) continue; - if (!have_scaling || scale_mode != META_X11_SCALE_MODE_UI_DOWN) + if (!have_scaling) { /* When scaling up we should not reduce the screen size, or X will * fail miserably, while we must do it when scaling down, in order to