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

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