summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiovanni Campagna <gcampagn@redhat.com>2013-08-16 19:02:57 +0200
committerGiovanni Campagna <gcampagna@src.gnome.org>2013-08-17 16:57:33 +0200
commit78b41e542ba484da0df5c886eddfc25d087034ae (patch)
treea90b0f713fece155ac02fe011d32414d55e700ec
parent13557b39d0b27d4ec5cdb208aa06be8d0444401c (diff)
downloadmutter-wip/display-no-wayland.tar.gz
MonitorXrandr: follow the right order in applying the new configurationwip/display-no-wayland
First disable CRTCs that should be off in the new configuration, then resize the framebuffer, then enable the new CRTCs. If we don't do that, and we're making the screen smaller, X complains with a BadMatch. https://bugzilla.gnome.org/show_bug.cgi?id=705670
-rw-r--r--src/core/monitor-xrandr.c90
1 files changed, 54 insertions, 36 deletions
diff --git a/src/core/monitor-xrandr.c b/src/core/monitor-xrandr.c
index 2a04993e4..af51e8621 100644
--- a/src/core/monitor-xrandr.c
+++ b/src/core/monitor-xrandr.c
@@ -660,10 +660,13 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
meta_display_grab (meta_get_display ());
+ /* First compute the new size of the screen (framebuffer) */
width = 0; height = 0;
for (i = 0; i < n_crtcs; i++)
{
MetaCRTCInfo *crtc_info = crtcs[i];
+ MetaCRTC *crtc = crtc_info->crtc;
+ crtc->dirty = TRUE;
if (crtc_info->mode == NULL)
continue;
@@ -680,6 +683,54 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
}
}
+ /* Second disable all newly disabled CRTCs, or CRTCs that in the previous
+ configuration would be outside the new framebuffer (otherwise X complains
+ loudly when resizing)
+ CRTC will be enabled again after resizing the FB
+ */
+ for (i = 0; i < n_crtcs; i++)
+ {
+ MetaCRTCInfo *crtc_info = crtcs[i];
+ MetaCRTC *crtc = crtc_info->crtc;
+
+ if (crtc_info->mode == NULL ||
+ crtc->rect.x + crtc->rect.width > width ||
+ crtc->rect.y + crtc->rect.height > height)
+ {
+ XRRSetCrtcConfig (manager_xrandr->xdisplay,
+ manager_xrandr->resources,
+ (XID)crtc->crtc_id,
+ manager_xrandr->time,
+ 0, 0,
+ None,
+ RR_Rotate_0,
+ NULL, 0);
+ }
+ }
+
+ /* Disable CRTCs not mentioned in the list */
+ for (i = 0; i < manager->n_crtcs; i++)
+ {
+ MetaCRTC *crtc = &manager->crtcs[i];
+
+ if (crtc->dirty)
+ {
+ crtc->dirty = FALSE;
+ continue;
+ }
+ if (crtc->current_mode == NULL)
+ continue;
+
+ XRRSetCrtcConfig (manager_xrandr->xdisplay,
+ manager_xrandr->resources,
+ (XID)crtc->crtc_id,
+ manager_xrandr->time,
+ 0, 0,
+ None,
+ RR_Rotate_0,
+ NULL, 0);
+ }
+
g_assert (width > 0 && height > 0);
/* The 'physical size' of an X screen is meaningless if that screen
* can consist of many monitors. So just pick a size that make the
@@ -689,27 +740,17 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
*/
width_mm = (width / DPI_FALLBACK) * 25.4 + 0.5;
height_mm = (height / DPI_FALLBACK) * 25.4 + 0.5;
+ meta_error_trap_push (meta_get_display ());
XRRSetScreenSize (manager_xrandr->xdisplay, DefaultRootWindow (manager_xrandr->xdisplay),
width, height, width_mm, height_mm);
+ meta_error_trap_pop (meta_get_display ());
for (i = 0; i < n_crtcs; i++)
{
MetaCRTCInfo *crtc_info = crtcs[i];
MetaCRTC *crtc = crtc_info->crtc;
- crtc->dirty = TRUE;
- if (crtc_info->mode == NULL)
- {
- XRRSetCrtcConfig (manager_xrandr->xdisplay,
- manager_xrandr->resources,
- (XID)crtc->crtc_id,
- manager_xrandr->time,
- 0, 0,
- None,
- RR_Rotate_0,
- NULL, 0);
- }
- else
+ if (crtc_info->mode != NULL)
{
MetaMonitorMode *mode;
XID *outputs;
@@ -761,29 +802,6 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
output_info->is_presentation);
}
- /* Disable CRTCs not mentioned in the list */
- for (i = 0; i < manager->n_crtcs; i++)
- {
- MetaCRTC *crtc = &manager->crtcs[i];
-
- if (crtc->dirty)
- {
- crtc->dirty = FALSE;
- continue;
- }
- if (crtc->current_mode == NULL)
- continue;
-
- XRRSetCrtcConfig (manager_xrandr->xdisplay,
- manager_xrandr->resources,
- (XID)crtc->crtc_id,
- manager_xrandr->time,
- 0, 0,
- None,
- RR_Rotate_0,
- NULL, 0);
- }
-
meta_display_ungrab (meta_get_display ());
}