Blame SOURCES/0001-monitor-manager-xrandr-Force-an-update-when-resuming.patch

657d8e
From 849902beff553de41dd3940b17672ef98f687be5 Mon Sep 17 00:00:00 2001
657d8e
From: Rui Matos <tiagomatos@gmail.com>
657d8e
Date: Mon, 4 Jun 2018 16:35:04 -0400
657d8e
Subject: [PATCH] monitor-manager-xrandr: Force an update when resuming from
657d8e
 suspend
657d8e
657d8e
The stack below us isn't as reliable as we'd like and in some cases
657d8e
doesn't generate RRScreenChangeNotify events when e.g. resuming a
657d8e
laptop on a dock, meaning that we'd miss newly attached outputs.
657d8e
---
657d8e
 src/backends/meta-gpu.c                       |  7 ++
657d8e
 src/backends/meta-gpu.h                       |  4 +
657d8e
 src/backends/x11/meta-gpu-xrandr.c            | 26 ++++-
657d8e
 .../x11/meta-monitor-manager-xrandr.c         | 96 +++++++++++++++++--
657d8e
 4 files changed, 123 insertions(+), 10 deletions(-)
657d8e
657d8e
diff --git a/src/backends/meta-gpu.c b/src/backends/meta-gpu.c
657d8e
index 3577391e5..946f72387 100644
657d8e
--- a/src/backends/meta-gpu.c
657d8e
+++ b/src/backends/meta-gpu.c
657d8e
@@ -64,6 +64,13 @@ meta_gpu_has_hotplug_mode_update (MetaGpu *gpu)
657d8e
   return FALSE;
657d8e
 }
657d8e
 
657d8e
+void
657d8e
+meta_gpu_poll_hardware (MetaGpu *gpu)
657d8e
+{
657d8e
+  if (META_GPU_GET_CLASS (gpu)->poll_hardware)
657d8e
+    META_GPU_GET_CLASS (gpu)->poll_hardware (gpu);
657d8e
+}
657d8e
+
657d8e
 gboolean
657d8e
 meta_gpu_read_current (MetaGpu  *gpu,
657d8e
                        GError  **error)
657d8e
diff --git a/src/backends/meta-gpu.h b/src/backends/meta-gpu.h
657d8e
index 701acdc97..a2fd061f7 100644
657d8e
--- a/src/backends/meta-gpu.h
657d8e
+++ b/src/backends/meta-gpu.h
657d8e
@@ -36,8 +36,12 @@ struct _MetaGpuClass
657d8e
 
657d8e
   gboolean (* read_current) (MetaGpu  *gpu,
657d8e
                              GError  **error);
657d8e
+  void     (* poll_hardware) (MetaGpu *gpu);
657d8e
 };
657d8e
 
657d8e
+META_EXPORT_TEST
657d8e
+void meta_gpu_poll_hardware (MetaGpu *gpu);
657d8e
+
657d8e
 META_EXPORT_TEST
657d8e
 gboolean meta_gpu_read_current (MetaGpu  *gpu,
657d8e
                                 GError  **error);
657d8e
diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c
657d8e
index 3e8a7318d..90b33d486 100644
657d8e
--- a/src/backends/x11/meta-gpu-xrandr.c
657d8e
+++ b/src/backends/x11/meta-gpu-xrandr.c
657d8e
@@ -44,6 +44,8 @@ struct _MetaGpuXrandr
657d8e
 
657d8e
   int max_screen_width;
657d8e
   int max_screen_height;
657d8e
+
657d8e
+  gboolean need_hardware_poll;
657d8e
 };
657d8e
 
657d8e
 G_DEFINE_TYPE (MetaGpuXrandr, meta_gpu_xrandr, META_TYPE_GPU)
657d8e
@@ -81,6 +83,14 @@ get_xmode_name (XRRModeInfo *xmode)
657d8e
   return g_strdup_printf ("%dx%d", width, height);
657d8e
 }
657d8e
 
657d8e
+static void
657d8e
+meta_gpu_xrandr_poll_hardware (MetaGpu *gpu)
657d8e
+{
657d8e
+  MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (gpu);
657d8e
+
657d8e
+  gpu_xrandr->need_hardware_poll = TRUE;
657d8e
+}
657d8e
+
657d8e
 static gboolean
657d8e
 meta_gpu_xrandr_read_current (MetaGpu  *gpu,
657d8e
                               GError  **error)
657d8e
@@ -116,8 +126,18 @@ meta_gpu_xrandr_read_current (MetaGpu  *gpu,
657d8e
   monitor_manager->screen_width = WidthOfScreen (screen);
657d8e
   monitor_manager->screen_height = HeightOfScreen (screen);
657d8e
 
657d8e
-  resources = XRRGetScreenResourcesCurrent (xdisplay,
657d8e
-                                            DefaultRootWindow (xdisplay));
657d8e
+  if (gpu_xrandr->need_hardware_poll)
657d8e
+    {
657d8e
+      resources = XRRGetScreenResources (xdisplay,
657d8e
+                                         DefaultRootWindow (xdisplay));
657d8e
+      gpu_xrandr->need_hardware_poll = FALSE;
657d8e
+    }
657d8e
+  else
657d8e
+    {
657d8e
+      resources = XRRGetScreenResourcesCurrent (xdisplay,
657d8e
+                                                DefaultRootWindow (xdisplay));
657d8e
+    }
657d8e
+
657d8e
   if (!resources)
657d8e
     {
657d8e
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
657d8e
@@ -250,6 +270,7 @@ meta_gpu_xrandr_finalize (GObject *object)
657d8e
 static void
657d8e
 meta_gpu_xrandr_init (MetaGpuXrandr *gpu_xrandr)
657d8e
 {
657d8e
+  gpu_xrandr->need_hardware_poll = TRUE;
657d8e
 }
657d8e
 
657d8e
 static void
657d8e
@@ -261,4 +282,5 @@ meta_gpu_xrandr_class_init (MetaGpuXrandrClass *klass)
657d8e
   object_class->finalize = meta_gpu_xrandr_finalize;
657d8e
 
657d8e
   gpu_class->read_current = meta_gpu_xrandr_read_current;
657d8e
+  gpu_class->poll_hardware = meta_gpu_xrandr_poll_hardware;
657d8e
 }
657d8e
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
657d8e
index 448e51fae..d60f00325 100644
657d8e
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
657d8e
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
657d8e
@@ -71,6 +71,10 @@ struct _MetaMonitorManagerXrandr
657d8e
   Display *xdisplay;
657d8e
   int rr_event_base;
657d8e
   int rr_error_base;
657d8e
+
657d8e
+  guint logind_watch_id;
657d8e
+  guint logind_signal_sub_id;
657d8e
+
657d8e
   gboolean has_randr15;
657d8e
 
657d8e
   /*
657d8e
@@ -102,6 +106,8 @@ typedef struct _MetaMonitorXrandrData
657d8e
 
657d8e
 GQuark quark_meta_monitor_xrandr_data;
657d8e
 
657d8e
+static void meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr);
657d8e
+
657d8e
 Display *
657d8e
 meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr)
657d8e
 {
657d8e
@@ -1016,6 +1022,62 @@ meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager
657d8e
   return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
657d8e
 }
657d8e
 
657d8e
+static void
657d8e
+logind_signal_handler (GDBusConnection *connection,
657d8e
+                       const gchar     *sender_name,
657d8e
+                       const gchar     *object_path,
657d8e
+                       const gchar     *interface_name,
657d8e
+                       const gchar     *signal_name,
657d8e
+                       GVariant        *parameters,
657d8e
+                       gpointer         user_data)
657d8e
+{
657d8e
+  MetaMonitorManagerXrandr *manager_xrandr = user_data;
657d8e
+  gboolean suspending;
657d8e
+
657d8e
+  if (!g_str_equal (signal_name, "PrepareForSleep"))
657d8e
+    return;
657d8e
+
657d8e
+  g_variant_get (parameters, "(b)", &suspending);
657d8e
+  if (!suspending)
657d8e
+    {
657d8e
+      meta_gpu_poll_hardware (manager_xrandr->gpu);
657d8e
+      meta_monitor_manager_xrandr_update (manager_xrandr);
657d8e
+    }
657d8e
+}
657d8e
+
657d8e
+static void
657d8e
+logind_appeared (GDBusConnection *connection,
657d8e
+                 const gchar     *name,
657d8e
+                 const gchar     *name_owner,
657d8e
+                 gpointer         user_data)
657d8e
+{
657d8e
+  MetaMonitorManagerXrandr *manager_xrandr = user_data;
657d8e
+
657d8e
+  manager_xrandr->logind_signal_sub_id = g_dbus_connection_signal_subscribe (connection,
657d8e
+                                                                             "org.freedesktop.login1",
657d8e
+                                                                             "org.freedesktop.login1.Manager",
657d8e
+                                                                             "PrepareForSleep",
657d8e
+                                                                             "/org/freedesktop/login1",
657d8e
+                                                                             NULL,
657d8e
+                                                                             G_DBUS_SIGNAL_FLAGS_NONE,
657d8e
+                                                                             logind_signal_handler,
657d8e
+                                                                             manager_xrandr,
657d8e
+                                                                             NULL);
657d8e
+}
657d8e
+
657d8e
+static void
657d8e
+logind_vanished (GDBusConnection *connection,
657d8e
+                 const gchar     *name,
657d8e
+                 gpointer         user_data)
657d8e
+{
657d8e
+  MetaMonitorManagerXrandr *manager_xrandr = user_data;
657d8e
+
657d8e
+  if (connection && manager_xrandr->logind_signal_sub_id > 0)
657d8e
+    g_dbus_connection_signal_unsubscribe (connection, manager_xrandr->logind_signal_sub_id);
657d8e
+
657d8e
+  manager_xrandr->logind_signal_sub_id = 0;
657d8e
+}
657d8e
+
657d8e
 static void
657d8e
 meta_monitor_manager_xrandr_constructed (GObject *object)
657d8e
 {
657d8e
@@ -1072,12 +1134,23 @@ meta_monitor_manager_xrandr_finalize (GObject *object)
657d8e
   g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms);
657d8e
   g_free (manager_xrandr->supported_scales);
657d8e
 
657d8e
+  if (manager_xrandr->logind_watch_id > 0)
657d8e
+    g_bus_unwatch_name (manager_xrandr->logind_watch_id);
657d8e
+  manager_xrandr->logind_watch_id = 0;
657d8e
+
657d8e
   G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object);
657d8e
 }
657d8e
 
657d8e
 static void
657d8e
 meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
657d8e
 {
657d8e
+  manager_xrandr->logind_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
657d8e
+                                                      "org.freedesktop.login1",
657d8e
+                                                      G_BUS_NAME_WATCHER_FLAGS_NONE,
657d8e
+                                                      logind_appeared,
657d8e
+                                                      logind_vanished,
657d8e
+                                                      manager_xrandr,
657d8e
+                                                      NULL);
657d8e
 }
657d8e
 
657d8e
 static void
657d8e
@@ -1123,9 +1196,8 @@ is_xvnc (MetaMonitorManager *manager)
657d8e
   return FALSE;
657d8e
 }
657d8e
 
657d8e
-gboolean
657d8e
-meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
657d8e
-					   XEvent                   *event)
657d8e
+static void
657d8e
+meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr)
657d8e
 {
657d8e
   MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
657d8e
   MetaGpuXrandr *gpu_xrandr;
657d8e
@@ -1134,11 +1206,6 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
657d8e
   gboolean is_our_configuration;
657d8e
   unsigned int timestamp;
657d8e
 
657d8e
-  if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
657d8e
-    return FALSE;
657d8e
-
657d8e
-  XRRUpdateConfiguration (event);
657d8e
-
657d8e
   meta_monitor_manager_read_current_state (manager);
657d8e
 
657d8e
   gpu_xrandr = META_GPU_XRANDR (manager_xrandr->gpu);
657d8e
@@ -1173,6 +1240,19 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
657d8e
 
657d8e
       meta_monitor_manager_xrandr_rebuild_derived (manager, config);
657d8e
     }
657d8e
+}
657d8e
+
657d8e
+gboolean
657d8e
+meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
657d8e
+					   XEvent                   *event)
657d8e
+{
657d8e
+
657d8e
+  if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
657d8e
+    return FALSE;
657d8e
+
657d8e
+  XRRUpdateConfiguration (event);
657d8e
+
657d8e
+  meta_monitor_manager_xrandr_update (manager_xrandr);
657d8e
 
657d8e
   return TRUE;
657d8e
 }
657d8e
-- 
657d8e
2.21.0
657d8e