Blob Blame History Raw
From bac090f571e6f413ba2a362ed2d70146b7701d16 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
Date: Mon, 24 Feb 2020 17:37:34 +0100
Subject: [PATCH] crtc-xrandr: Respect configured RANDR panning

A user may have configured an output to be panning, e.g. using xrandr
--output <output> --mode <mode> --panning <size>. Respect this by making
the logical monitor use the panning size, instead of the mode. This
makes e.g. makes the background cover the whole panning size, and panels
etc will cover the whole top of the panned area, instead of just the top
left part covering the monitor if having panned to (0, 0).

No support is added to configuring panning, i.e. a panned monitor
configuration cannot be stored in monitors.xml.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/1085
---
 src/backends/x11/meta-crtc-xrandr.c | 31 +++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/src/backends/x11/meta-crtc-xrandr.c b/src/backends/x11/meta-crtc-xrandr.c
index d201b8581..dc3f931e3 100644
--- a/src/backends/x11/meta-crtc-xrandr.c
+++ b/src/backends/x11/meta-crtc-xrandr.c
@@ -177,7 +177,14 @@ meta_create_xrandr_crtc (MetaGpuXrandr      *gpu_xrandr,
                          RRCrtc              crtc_id,
                          XRRScreenResources *resources)
 {
+  MetaGpu *gpu = META_GPU (gpu_xrandr);
+  MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu);
+  MetaMonitorManagerXrandr *monitor_manager_xrandr =
+    META_MONITOR_MANAGER_XRANDR (monitor_manager);
+  Display *xdisplay =
+    meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr);
   MetaCrtc *crtc;
+  XRRPanning *panning;
   unsigned int i;
   GList *modes;
 
@@ -185,10 +192,26 @@ meta_create_xrandr_crtc (MetaGpuXrandr      *gpu_xrandr,
 
   crtc->gpu = META_GPU (gpu_xrandr);
   crtc->crtc_id = crtc_id;
-  crtc->rect.x = xrandr_crtc->x;
-  crtc->rect.y = xrandr_crtc->y;
-  crtc->rect.width = xrandr_crtc->width;
-  crtc->rect.height = xrandr_crtc->height;
+
+  panning = XRRGetPanning (xdisplay, resources, crtc_id);
+  if (panning && panning->width > 0 && panning->height > 0)
+    {
+      crtc->rect = (MetaRectangle) {
+        .x = panning->left,
+        .y = panning->top,
+        .width = panning->width,
+        .height = panning->height,
+      };
+    }
+  else
+    {
+      crtc->rect = (MetaRectangle) {
+        .x = xrandr_crtc->x,
+        .y = xrandr_crtc->y,
+        .width = xrandr_crtc->width,
+        .height = xrandr_crtc->height,
+      };
+    }
   crtc->is_dirty = FALSE;
   crtc->transform =
     meta_monitor_transform_from_xrandr (xrandr_crtc->rotation);
-- 
2.24.1