summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 ());
}