diff options
-rw-r--r-- | src/core/monitor-xrandr.c | 90 |
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 ()); } |