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

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