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

67f8b7
From 677c216fbf52e5cbc1d5f0890ebc1ee9216cfd27 Mon Sep 17 00:00:00 2001
67f8b7
From: Rui Matos <tiagomatos@gmail.com>
67f8b7
Date: Sun, 25 Oct 2015 16:14:58 +0100
67f8b7
Subject: [PATCH] monitor-manager-xrandr: Force an update when resuming from
67f8b7
 suspend
67f8b7
67f8b7
The stack below us isn't as reliable as we'd like and in some cases
67f8b7
doesn't generate RRScreenChangeNotify events when e.g. resuming a
67f8b7
laptop on a dock, meaning that we'd miss newly attached outputs.
67f8b7
---
67f8b7
 src/backends/x11/meta-monitor-manager-xrandr.c | 157 +++++++++++++++++++------
67f8b7
 1 file changed, 122 insertions(+), 35 deletions(-)
67f8b7
67f8b7
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
67f8b7
index 4a27b3a14..aa3ff76f5 100644
67f8b7
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
67f8b7
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
67f8b7
@@ -58,6 +58,11 @@ struct _MetaMonitorManagerXrandr
67f8b7
   XRRScreenResources *resources;
67f8b7
   int rr_event_base;
67f8b7
   int rr_error_base;
67f8b7
+
67f8b7
+  guint logind_watch_id;
67f8b7
+  guint logind_signal_sub_id;
67f8b7
+
67f8b7
+  gboolean need_hardware_poll;
67f8b7
   gboolean has_randr15;
67f8b7
 };
67f8b7
 
67f8b7
@@ -763,8 +768,15 @@ meta_monitor_manager_xrandr_read_current (MetaMonitorManager *manager)
67f8b7
   manager->screen_width = WidthOfScreen (screen);
67f8b7
   manager->screen_height = HeightOfScreen (screen);
67f8b7
 
67f8b7
-  resources = XRRGetScreenResourcesCurrent (manager_xrandr->xdisplay,
67f8b7
-					    DefaultRootWindow (manager_xrandr->xdisplay));
67f8b7
+  if (manager_xrandr->need_hardware_poll)
67f8b7
+    {
67f8b7
+      resources = XRRGetScreenResources (manager_xrandr->xdisplay,
67f8b7
+                                         DefaultRootWindow (manager_xrandr->xdisplay));
67f8b7
+      manager_xrandr->need_hardware_poll = FALSE;
67f8b7
+    }
67f8b7
+  else
67f8b7
+    resources = XRRGetScreenResourcesCurrent (manager_xrandr->xdisplay,
67f8b7
+                                              DefaultRootWindow (manager_xrandr->xdisplay));
67f8b7
   if (!resources)
67f8b7
     return;
67f8b7
 
67f8b7
@@ -1414,6 +1426,100 @@ meta_monitor_manager_xrandr_init_monitors(MetaMonitorManagerXrandr *manager_xran
67f8b7
 }
67f8b7
 #endif
67f8b7
 
67f8b7
+static gboolean
67f8b7
+is_xvnc (MetaMonitorManager *manager)
67f8b7
+{
67f8b7
+  unsigned int i;
67f8b7
+
67f8b7
+  for (i = 0; i < manager->n_outputs; ++i)
67f8b7
+    if (g_str_has_prefix (manager->outputs[i].name, "VNC-"))
67f8b7
+      return TRUE;
67f8b7
+
67f8b7
+  return FALSE;
67f8b7
+}
67f8b7
+
67f8b7
+static void
67f8b7
+meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr)
67f8b7
+{
67f8b7
+  MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
67f8b7
+  gboolean hotplug;
67f8b7
+  unsigned int timestamp;
67f8b7
+
67f8b7
+  meta_monitor_manager_read_current_config (manager);
67f8b7
+
67f8b7
+  timestamp = manager_xrandr->resources->timestamp;
67f8b7
+  if (is_xvnc (manager))
67f8b7
+    timestamp += 100;
67f8b7
+
67f8b7
+  hotplug = timestamp < manager_xrandr->resources->configTimestamp;
67f8b7
+  if (hotplug)
67f8b7
+    {
67f8b7
+      /* This is a hotplug event, so go ahead and build a new configuration. */
67f8b7
+      meta_monitor_manager_on_hotplug (manager);
67f8b7
+    }
67f8b7
+  else
67f8b7
+    {
67f8b7
+      /* Something else changed -- tell the world about it. */
67f8b7
+      meta_monitor_manager_rebuild_derived (manager);
67f8b7
+    }
67f8b7
+}
67f8b7
+
67f8b7
+static void
67f8b7
+logind_signal_handler (GDBusConnection *connection,
67f8b7
+                       const gchar     *sender_name,
67f8b7
+                       const gchar     *object_path,
67f8b7
+                       const gchar     *interface_name,
67f8b7
+                       const gchar     *signal_name,
67f8b7
+                       GVariant        *parameters,
67f8b7
+                       gpointer         user_data)
67f8b7
+{
67f8b7
+  MetaMonitorManagerXrandr *manager_xrandr = user_data;
67f8b7
+  gboolean suspending;
67f8b7
+
67f8b7
+  if (!g_str_equal (signal_name, "PrepareForSleep"))
67f8b7
+    return;
67f8b7
+
67f8b7
+  g_variant_get (parameters, "(b)", &suspending);
67f8b7
+  if (!suspending)
67f8b7
+    {
67f8b7
+      manager_xrandr->need_hardware_poll = TRUE;
67f8b7
+      meta_monitor_manager_xrandr_update (manager_xrandr);
67f8b7
+    }
67f8b7
+}
67f8b7
+
67f8b7
+static void
67f8b7
+logind_appeared (GDBusConnection *connection,
67f8b7
+                 const gchar     *name,
67f8b7
+                 const gchar     *name_owner,
67f8b7
+                 gpointer         user_data)
67f8b7
+{
67f8b7
+  MetaMonitorManagerXrandr *manager_xrandr = user_data;
67f8b7
+
67f8b7
+  manager_xrandr->logind_signal_sub_id = g_dbus_connection_signal_subscribe (connection,
67f8b7
+                                                                             "org.freedesktop.login1",
67f8b7
+                                                                             "org.freedesktop.login1.Manager",
67f8b7
+                                                                             "PrepareForSleep",
67f8b7
+                                                                             "/org/freedesktop/login1",
67f8b7
+                                                                             NULL,
67f8b7
+                                                                             G_DBUS_SIGNAL_FLAGS_NONE,
67f8b7
+                                                                             logind_signal_handler,
67f8b7
+                                                                             manager_xrandr,
67f8b7
+                                                                             NULL);
67f8b7
+}
67f8b7
+
67f8b7
+static void
67f8b7
+logind_vanished (GDBusConnection *connection,
67f8b7
+                 const gchar     *name,
67f8b7
+                 gpointer         user_data)
67f8b7
+{
67f8b7
+  MetaMonitorManagerXrandr *manager_xrandr = user_data;
67f8b7
+
67f8b7
+  if (connection && manager_xrandr->logind_signal_sub_id > 0)
67f8b7
+    g_dbus_connection_signal_unsubscribe (connection, manager_xrandr->logind_signal_sub_id);
67f8b7
+
67f8b7
+  manager_xrandr->logind_signal_sub_id = 0;
67f8b7
+}
67f8b7
+
67f8b7
 static void
67f8b7
 meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
67f8b7
 {
67f8b7
@@ -1449,6 +1555,15 @@ meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
67f8b7
       meta_monitor_manager_xrandr_init_monitors (manager_xrandr);
67f8b7
 #endif
67f8b7
     }
67f8b7
+
67f8b7
+  manager_xrandr->logind_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
67f8b7
+                                                      "org.freedesktop.login1",
67f8b7
+                                                      G_BUS_NAME_WATCHER_FLAGS_NONE,
67f8b7
+                                                      logind_appeared,
67f8b7
+                                                      logind_vanished,
67f8b7
+                                                      manager_xrandr,
67f8b7
+                                                      NULL);
67f8b7
+  manager_xrandr->need_hardware_poll = TRUE;
67f8b7
 }
67f8b7
 
67f8b7
 static void
67f8b7
@@ -1460,6 +1575,10 @@ meta_monitor_manager_xrandr_finalize (GObject *object)
67f8b7
     XRRFreeScreenResources (manager_xrandr->resources);
67f8b7
   manager_xrandr->resources = NULL;
67f8b7
 
67f8b7
+  if (manager_xrandr->logind_watch_id > 0)
67f8b7
+    g_bus_unwatch_name (manager_xrandr->logind_watch_id);
67f8b7
+  manager_xrandr->logind_watch_id = 0;
67f8b7
+
67f8b7
   G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->finalize (object);
67f8b7
 }
67f8b7
 
67f8b7
@@ -1484,48 +1603,16 @@ meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
67f8b7
 #endif
67f8b7
 }
67f8b7
 
67f8b7
-static gboolean
67f8b7
-is_xvnc (MetaMonitorManager *manager)
67f8b7
-{
67f8b7
-  unsigned int i;
67f8b7
-
67f8b7
-  for (i = 0; i < manager->n_outputs; ++i)
67f8b7
-    if (g_str_has_prefix (manager->outputs[i].name, "VNC-"))
67f8b7
-      return TRUE;
67f8b7
-
67f8b7
-  return FALSE;
67f8b7
-}
67f8b7
-
67f8b7
 gboolean
67f8b7
 meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
67f8b7
 					   XEvent                   *event)
67f8b7
 {
67f8b7
-  MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
67f8b7
-  gboolean hotplug;
67f8b7
-  unsigned int timestamp;
67f8b7
-
67f8b7
   if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
67f8b7
     return FALSE;
67f8b7
 
67f8b7
   XRRUpdateConfiguration (event);
67f8b7
 
67f8b7
-  meta_monitor_manager_read_current_config (manager);
67f8b7
-
67f8b7
-  timestamp = manager_xrandr->resources->timestamp;
67f8b7
-  if (is_xvnc (manager))
67f8b7
-    timestamp += 100;
67f8b7
-
67f8b7
-  hotplug = timestamp < manager_xrandr->resources->configTimestamp;
67f8b7
-  if (hotplug)
67f8b7
-    {
67f8b7
-      /* This is a hotplug event, so go ahead and build a new configuration. */
67f8b7
-      meta_monitor_manager_on_hotplug (manager);
67f8b7
-    }
67f8b7
-  else
67f8b7
-    {
67f8b7
-      /* Something else changed -- tell the world about it. */
67f8b7
-      meta_monitor_manager_rebuild_derived (manager);
67f8b7
-    }
67f8b7
+  meta_monitor_manager_xrandr_update (manager_xrandr);
67f8b7
 
67f8b7
   return TRUE;
67f8b7
 }
67f8b7
-- 
67f8b7
2.12.0
67f8b7