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

474558
From 100795c2729305f919ff9611c877ea3e74d528b7 Mon Sep 17 00:00:00 2001
db633a
From: Rui Matos <tiagomatos@gmail.com>
474558
Date: Mon, 4 Jun 2018 16:35:04 -0400
474558
Subject: [PATCH] monitor-manager-xrandr: Force an update when resuming from
474558
 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
---
474558
 src/backends/meta-gpu.c                       |  7 ++
474558
 src/backends/meta-gpu.h                       |  2 +
474558
 src/backends/x11/meta-gpu-xrandr.c            | 26 ++++-
474558
 .../x11/meta-monitor-manager-xrandr.c         | 96 +++++++++++++++++--
474558
 4 files changed, 121 insertions(+), 10 deletions(-)
db633a
474558
diff --git a/src/backends/meta-gpu.c b/src/backends/meta-gpu.c
474558
index 3577391e5..946f72387 100644
474558
--- a/src/backends/meta-gpu.c
474558
+++ b/src/backends/meta-gpu.c
474558
@@ -37,60 +37,67 @@ enum
474558
 static GParamSpec *obj_props[PROP_LAST];
db633a
 
474558
 typedef struct _MetaGpuPrivate
474558
 {
474558
   MetaMonitorManager *monitor_manager;
db633a
 
474558
   GList *outputs;
474558
   GList *crtcs;
474558
   GList *modes;
474558
 } MetaGpuPrivate;
db633a
 
474558
 G_DEFINE_TYPE_WITH_PRIVATE (MetaGpu, meta_gpu, G_TYPE_OBJECT)
474558
 
474558
 gboolean
474558
 meta_gpu_has_hotplug_mode_update (MetaGpu *gpu)
474558
 {
474558
   MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
474558
   GList *l;
474558
 
474558
   for (l = priv->outputs; l; l = l->next)
474558
     {
474558
       MetaOutput *output = l->data;
474558
 
474558
       if (output->hotplug_mode_update)
474558
         return TRUE;
474558
     }
474558
 
474558
   return FALSE;
db633a
 }
db633a
 
474558
+void
474558
+meta_gpu_poll_hardware (MetaGpu *gpu)
db633a
+{
474558
+  if (META_GPU_GET_CLASS (gpu)->poll_hardware)
474558
+    META_GPU_GET_CLASS (gpu)->poll_hardware (gpu);
db633a
+}
db633a
+
474558
 gboolean
474558
 meta_gpu_read_current (MetaGpu  *gpu,
474558
                        GError  **error)
474558
 {
474558
   MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
474558
   gboolean ret;
474558
   GList *old_outputs;
474558
   GList *old_crtcs;
474558
   GList *old_modes;
474558
 
474558
   /* TODO: Get rid of this when objects incref:s what they need instead */
474558
   old_outputs = priv->outputs;
474558
   old_crtcs = priv->crtcs;
474558
   old_modes = priv->modes;
474558
 
474558
   ret = META_GPU_GET_CLASS (gpu)->read_current (gpu, error);
474558
 
474558
   g_list_free_full (old_outputs, g_object_unref);
474558
   g_list_free_full (old_modes, g_object_unref);
474558
   g_list_free_full (old_crtcs, g_object_unref);
474558
 
474558
   return ret;
474558
 }
474558
 
474558
 MetaMonitorManager *
474558
 meta_gpu_get_monitor_manager (MetaGpu *gpu)
474558
 {
474558
   MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
474558
 
474558
   return priv->monitor_manager;
474558
diff --git a/src/backends/meta-gpu.h b/src/backends/meta-gpu.h
474558
index 4badcbd26..3cec8e5b0 100644
474558
--- a/src/backends/meta-gpu.h
474558
+++ b/src/backends/meta-gpu.h
474558
@@ -8,59 +8,61 @@
474558
  * published by the Free Software Foundation; either version 2 of the
474558
  * License, or (at your option) any later version.
474558
  *
474558
  * This program is distributed in the hope that it will be useful, but
474558
  * WITHOUT ANY WARRANTY; without even the implied warranty of
474558
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
474558
  * General Public License for more details.
474558
  *
474558
  * You should have received a copy of the GNU General Public License
474558
  * along with this program; if not, write to the Free Software
474558
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
474558
  * 02111-1307, USA.
474558
  */
474558
 
474558
 #ifndef META_GPU_H
474558
 #define META_GPU_H
474558
 
474558
 #include <glib-object.h>
474558
 
474558
 #include "backends/meta-monitor-manager-private.h"
474558
 
474558
 #define META_TYPE_GPU (meta_gpu_get_type ())
474558
 G_DECLARE_DERIVABLE_TYPE (MetaGpu, meta_gpu, META, GPU, GObject)
474558
 
474558
 struct _MetaGpuClass
474558
 {
474558
   GObjectClass parent_class;
474558
 
474558
   gboolean (* read_current) (MetaGpu  *gpu,
474558
                              GError  **error);
474558
+  void     (* poll_hardware) (MetaGpu *gpu);
474558
 };
474558
 
474558
 int meta_gpu_get_kms_fd (MetaGpu *gpu);
474558
 
474558
 const char * meta_gpu_get_kms_file_path (MetaGpu *gpu);
474558
 
474558
+void meta_gpu_poll_hardware (MetaGpu *gpu);
474558
 gboolean meta_gpu_read_current (MetaGpu  *gpu,
474558
                                 GError  **error);
474558
 
474558
 gboolean meta_gpu_has_hotplug_mode_update (MetaGpu *gpu);
474558
 
474558
 MetaMonitorManager * meta_gpu_get_monitor_manager (MetaGpu *gpu);
474558
 
474558
 GList * meta_gpu_get_outputs (MetaGpu *gpu);
474558
 
474558
 GList * meta_gpu_get_crtcs (MetaGpu *gpu);
474558
 
474558
 GList * meta_gpu_get_modes (MetaGpu *gpu);
474558
 
474558
 void meta_gpu_take_outputs (MetaGpu *gpu,
474558
                             GList   *outputs);
474558
 
474558
 void meta_gpu_take_crtcs (MetaGpu *gpu,
474558
                           GList   *crtcs);
474558
 
474558
 void meta_gpu_take_modes (MetaGpu *gpu,
474558
                           GList   *modes);
474558
 
474558
 #endif /* META_GPU_H */
474558
diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c
474558
index 14b46d530..add80c0d2 100644
474558
--- a/src/backends/x11/meta-gpu-xrandr.c
474558
+++ b/src/backends/x11/meta-gpu-xrandr.c
474558
@@ -17,97 +17,107 @@
474558
  * This program is distributed in the hope that it will be useful, but
474558
  * WITHOUT ANY WARRANTY; without even the implied warranty of
474558
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
474558
  * General Public License for more details.
474558
  *
474558
  * You should have received a copy of the GNU General Public License
474558
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
474558
  */
474558
 
474558
 #include "config.h"
474558
 
474558
 #include "backends/x11/meta-gpu-xrandr.h"
474558
 
474558
 #include <string.h>
474558
 #include <X11/extensions/dpms.h>
474558
 #include <X11/Xlibint.h>
474558
 
474558
 #include "backends/meta-output.h"
474558
 #include "backends/x11/meta-crtc-xrandr.h"
474558
 #include "backends/x11/meta-monitor-manager-xrandr.h"
474558
 #include "backends/x11/meta-output-xrandr.h"
474558
 
474558
 struct _MetaGpuXrandr
474558
 {
474558
   MetaGpu parent;
474558
 
474558
   XRRScreenResources *resources;
474558
 
474558
   int max_screen_width;
474558
   int max_screen_height;
474558
+
474558
+  gboolean need_hardware_poll;
474558
 };
474558
 
474558
 G_DEFINE_TYPE (MetaGpuXrandr, meta_gpu_xrandr, META_TYPE_GPU)
474558
 
474558
 XRRScreenResources *
474558
 meta_gpu_xrandr_get_resources (MetaGpuXrandr *gpu_xrandr)
474558
 {
474558
   return gpu_xrandr->resources;
474558
 }
474558
 
474558
 void
474558
 meta_gpu_xrandr_get_max_screen_size (MetaGpuXrandr *gpu_xrandr,
474558
                                      int           *max_width,
474558
                                      int           *max_height)
474558
 {
474558
   *max_width = gpu_xrandr->max_screen_width;
474558
   *max_height = gpu_xrandr->max_screen_height;
474558
 }
474558
 
474558
 static int
474558
 compare_outputs (const void *one,
474558
                  const void *two)
474558
 {
474558
   const MetaOutput *o_one = one, *o_two = two;
474558
 
474558
   return strcmp (o_one->name, o_two->name);
474558
 }
474558
 
474558
 static char *
474558
 get_xmode_name (XRRModeInfo *xmode)
474558
 {
474558
   int width = xmode->width;
474558
   int height = xmode->height;
474558
 
474558
   return g_strdup_printf ("%dx%d", width, height);
474558
 }
474558
 
db633a
+static void
474558
+meta_gpu_xrandr_poll_hardware (MetaGpu *gpu)
db633a
+{
474558
+  MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (gpu);
db633a
+
474558
+  gpu_xrandr->need_hardware_poll = TRUE;
474558
+}
db633a
+
474558
 static gboolean
474558
 meta_gpu_xrandr_read_current (MetaGpu  *gpu,
474558
                               GError  **error)
474558
 {
474558
   MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (gpu);
474558
   MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu);
474558
   MetaMonitorManagerXrandr *monitor_manager_xrandr =
474558
     META_MONITOR_MANAGER_XRANDR (monitor_manager);
474558
   Display *xdisplay =
474558
     meta_monitor_manager_xrandr_get_xdisplay (monitor_manager_xrandr);
474558
   XRRScreenResources *resources;
474558
   RROutput primary_output;
474558
   unsigned int i, j;
474558
   GList *l;
474558
   int min_width, min_height;
474558
   Screen *screen;
474558
   BOOL dpms_capable, dpms_enabled;
474558
   CARD16 dpms_state;
474558
   GList *outputs = NULL;
474558
   GList *modes = NULL;
474558
   GList *crtcs = NULL;
474558
 
474558
   if (gpu_xrandr->resources)
474558
     XRRFreeScreenResources (gpu_xrandr->resources);
474558
   gpu_xrandr->resources = NULL;
474558
 
474558
   dpms_capable = DPMSCapable (xdisplay);
474558
 
474558
   if (dpms_capable &&
474558
       DPMSInfo (xdisplay, &dpms_state, &dpms_enabled) &&
474558
@@ -121,62 +131,72 @@ meta_gpu_xrandr_read_current (MetaGpu  *gpu,
474558
         case DPMSModeStandby:
474558
           monitor_manager->power_save_mode = META_POWER_SAVE_STANDBY;
474558
           break;
474558
         case DPMSModeSuspend:
474558
           monitor_manager->power_save_mode = META_POWER_SAVE_SUSPEND;
474558
           break;
474558
         case DPMSModeOff:
474558
           monitor_manager->power_save_mode = META_POWER_SAVE_OFF;
474558
           break;
474558
         default:
474558
           monitor_manager->power_save_mode = META_POWER_SAVE_UNSUPPORTED;
474558
           break;
474558
         }
474558
     }
474558
   else
474558
     {
474558
       monitor_manager->power_save_mode = META_POWER_SAVE_UNSUPPORTED;
474558
     }
474558
 
474558
   XRRGetScreenSizeRange (xdisplay, DefaultRootWindow (xdisplay),
474558
                          &min_width,
474558
                          &min_height,
474558
                          &gpu_xrandr->max_screen_width,
474558
                          &gpu_xrandr->max_screen_height);
474558
 
474558
   screen = ScreenOfDisplay (xdisplay, DefaultScreen (xdisplay));
474558
   /* This is updated because we called XRRUpdateConfiguration. */
474558
   monitor_manager->screen_width = WidthOfScreen (screen);
474558
   monitor_manager->screen_height = HeightOfScreen (screen);
474558
 
474558
-  resources = XRRGetScreenResourcesCurrent (xdisplay,
474558
-                                            DefaultRootWindow (xdisplay));
474558
+  if (gpu_xrandr->need_hardware_poll)
db633a
+    {
474558
+      resources = XRRGetScreenResources (xdisplay,
474558
+                                         DefaultRootWindow (xdisplay));
474558
+      gpu_xrandr->need_hardware_poll = FALSE;
db633a
+    }
db633a
+  else
db633a
+    {
474558
+      resources = XRRGetScreenResourcesCurrent (xdisplay,
474558
+                                                DefaultRootWindow (xdisplay));
474558
+    }
e3f29c
+
474558
   if (!resources)
474558
     {
474558
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
474558
                    "Failed to retrieve Xrandr screen resources");
474558
       return FALSE;
474558
     }
474558
 
474558
   gpu_xrandr->resources = resources;
474558
 
474558
   outputs = NULL;
474558
   modes = NULL;
474558
   crtcs = NULL;
474558
 
474558
   for (i = 0; i < (unsigned)resources->nmode; i++)
474558
     {
474558
       XRRModeInfo *xmode = &resources->modes[i];
474558
       MetaCrtcMode *mode;
474558
 
474558
       mode = g_object_new (META_TYPE_CRTC_MODE, NULL);
474558
 
474558
       mode->mode_id = xmode->id;
474558
       mode->width = xmode->width;
474558
       mode->height = xmode->height;
474558
       mode->refresh_rate = (xmode->dotClock /
474558
                             ((float)xmode->hTotal * xmode->vTotal));
474558
       mode->flags = xmode->modeFlags;
474558
       mode->name = get_xmode_name (xmode);
474558
 
474558
       modes = g_list_append (modes, mode);
474558
     }
474558
@@ -255,42 +275,44 @@ meta_gpu_xrandr_read_current (MetaGpu  *gpu,
474558
                 }
474558
             }
474558
         }
474558
     }
474558
 
474558
   return TRUE;
474558
 }
474558
 
474558
 MetaGpuXrandr *
474558
 meta_gpu_xrandr_new (MetaMonitorManagerXrandr *monitor_manager_xrandr)
474558
 {
474558
   return g_object_new (META_TYPE_GPU_XRANDR,
474558
                        "monitor-manager", monitor_manager_xrandr,
474558
                        NULL);
474558
 }
474558
 
474558
 static void
474558
 meta_gpu_xrandr_finalize (GObject *object)
474558
 {
474558
   MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (object);
474558
 
474558
   g_clear_pointer (&gpu_xrandr->resources,
474558
                    XRRFreeScreenResources);
474558
 
474558
   G_OBJECT_CLASS (meta_gpu_xrandr_parent_class)->finalize (object);
474558
 }
474558
 
474558
 static void
474558
 meta_gpu_xrandr_init (MetaGpuXrandr *gpu_xrandr)
474558
 {
474558
+  gpu_xrandr->need_hardware_poll = TRUE;
474558
 }
474558
 
474558
 static void
474558
 meta_gpu_xrandr_class_init (MetaGpuXrandrClass *klass)
474558
 {
474558
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
474558
   MetaGpuClass *gpu_class = META_GPU_CLASS (klass);
474558
 
474558
   object_class->finalize = meta_gpu_xrandr_finalize;
474558
 
474558
   gpu_class->read_current = meta_gpu_xrandr_read_current;
474558
+  gpu_class->poll_hardware = meta_gpu_xrandr_poll_hardware;
474558
 }
474558
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
474558
index 90a3952db..2d9a32339 100644
474558
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
474558
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
474558
@@ -33,95 +33,101 @@
474558
 #include <clutter/clutter.h>
474558
 
474558
 #include <X11/Xlibint.h>
474558
 #include <X11/extensions/dpms.h>
474558
 #include <X11/Xlib-xcb.h>
474558
 #include <xcb/randr.h>
474558
 
474558
 #include "meta-backend-x11.h"
474558
 #include <meta/main.h>
474558
 #include <meta/errors.h>
474558
 #include "backends/meta-crtc.h"
474558
 #include "backends/meta-monitor-config-manager.h"
474558
 #include "backends/meta-logical-monitor.h"
474558
 #include "backends/meta-output.h"
474558
 #include "backends/x11/meta-crtc-xrandr.h"
474558
 #include "backends/x11/meta-gpu-xrandr.h"
474558
 #include "backends/x11/meta-output-xrandr.h"
474558
 
474558
 /* Look for DPI_FALLBACK in:
474558
  * http://git.gnome.org/browse/gnome-settings-daemon/tree/plugins/xsettings/gsd-xsettings-manager.c
474558
  * for the reasoning */
474558
 #define DPI_FALLBACK 96.0
474558
 
474558
 struct _MetaMonitorManagerXrandr
474558
 {
474558
   MetaMonitorManager parent_instance;
474558
 
474558
   Display *xdisplay;
474558
   int rr_event_base;
474558
   int rr_error_base;
e3f29c
+
474558
+  guint logind_watch_id;
474558
+  guint logind_signal_sub_id;
e3f29c
+
474558
   gboolean has_randr15;
474558
 
474558
   /*
474558
    * The X server deals with multiple GPUs for us, soe just see what the X
474558
    * server gives us as one single GPU, even though it may actually be backed
474558
    * by multiple.
474558
    */
474558
   MetaGpu *gpu;
474558
 
474558
   xcb_timestamp_t last_xrandr_set_timestamp;
474558
 
474558
 #ifdef HAVE_XRANDR15
474558
   GHashTable *tiled_monitor_atoms;
474558
 #endif /* HAVE_XRANDR15 */
474558
 
474558
   float *supported_scales;
474558
   int n_supported_scales;
474558
 };
474558
 
474558
 struct _MetaMonitorManagerXrandrClass
474558
 {
474558
   MetaMonitorManagerClass parent_class;
474558
 };
474558
 
474558
 G_DEFINE_TYPE (MetaMonitorManagerXrandr, meta_monitor_manager_xrandr, META_TYPE_MONITOR_MANAGER);
474558
 
474558
 #ifdef HAVE_XRANDR15
474558
 typedef struct _MetaMonitorXrandrData
474558
 {
474558
   Atom xrandr_name;
474558
 } MetaMonitorXrandrData;
474558
 
474558
 GQuark quark_meta_monitor_xrandr_data;
474558
 #endif /* HAVE_RANDR15 */
474558
 
474558
+static void meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr);
db633a
+
474558
 Display *
474558
 meta_monitor_manager_xrandr_get_xdisplay (MetaMonitorManagerXrandr *manager_xrandr)
474558
 {
474558
   return manager_xrandr->xdisplay;
474558
 }
474558
 
474558
 gboolean
474558
 meta_monitor_manager_xrandr_has_randr15 (MetaMonitorManagerXrandr *manager_xrandr)
474558
 {
474558
   return manager_xrandr->has_randr15;
474558
 }
474558
 
474558
 static GBytes *
474558
 meta_monitor_manager_xrandr_read_edid (MetaMonitorManager *manager,
474558
                                        MetaOutput         *output)
474558
 {
474558
   return meta_output_xrandr_read_edid (output);
474558
 }
474558
 
474558
 static void
474558
 meta_monitor_manager_xrandr_set_power_save_mode (MetaMonitorManager *manager,
474558
 						 MetaPowerSave       mode)
474558
 {
474558
   MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
474558
   CARD16 state;
474558
 
474558
   switch (mode) {
474558
   case META_POWER_SAVE_ON:
474558
     state = DPMSModeOn;
474558
     break;
474558
@@ -934,198 +940,272 @@ meta_monitor_manager_xrandr_calculate_supported_scales (MetaMonitorManager
474558
                    manager_xrandr->n_supported_scales * sizeof (float));
474558
 }
474558
 
474558
 static MetaMonitorManagerCapability
474558
 meta_monitor_manager_xrandr_get_capabilities (MetaMonitorManager *manager)
474558
 {
474558
   return (META_MONITOR_MANAGER_CAPABILITY_MIRRORING |
474558
           META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED);
474558
 }
474558
 
474558
 static gboolean
474558
 meta_monitor_manager_xrandr_get_max_screen_size (MetaMonitorManager *manager,
474558
                                                  int                *max_width,
474558
                                                  int                *max_height)
474558
 {
474558
   MetaMonitorManagerXrandr *manager_xrandr =
474558
     META_MONITOR_MANAGER_XRANDR (manager);
474558
 
474558
   meta_gpu_xrandr_get_max_screen_size (META_GPU_XRANDR (manager_xrandr->gpu),
474558
                                        max_width, max_height);
474558
 
474558
   return TRUE;
474558
 }
474558
 
474558
 static MetaLogicalMonitorLayoutMode
474558
 meta_monitor_manager_xrandr_get_default_layout_mode (MetaMonitorManager *manager)
474558
 {
474558
   return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
474558
 }
474558
 
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
+    {
474558
+      meta_gpu_poll_hardware (manager_xrandr->gpu);
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
474558
 meta_monitor_manager_xrandr_constructed (GObject *object)
db633a
 {
474558
   MetaMonitorManagerXrandr *manager_xrandr =
474558
     META_MONITOR_MANAGER_XRANDR (object);
474558
   MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
474558
   MetaBackendX11 *backend =
474558
     META_BACKEND_X11 (meta_monitor_manager_get_backend (manager));
474558
 
474558
   manager_xrandr->xdisplay = meta_backend_x11_get_xdisplay (backend);
474558
 
474558
   manager_xrandr->gpu = META_GPU (meta_gpu_xrandr_new (manager_xrandr));
474558
   meta_monitor_manager_add_gpu (manager, manager_xrandr->gpu);
474558
 
474558
   if (!XRRQueryExtension (manager_xrandr->xdisplay,
474558
 			  &manager_xrandr->rr_event_base,
474558
 			  &manager_xrandr->rr_error_base))
474558
     {
474558
       return;
474558
     }
474558
   else
474558
     {
474558
       int major_version, minor_version;
474558
       /* We only use ScreenChangeNotify, but GDK uses the others,
474558
 	 and we don't want to step on its toes */
474558
       XRRSelectInput (manager_xrandr->xdisplay,
474558
 		      DefaultRootWindow (manager_xrandr->xdisplay),
474558
 		      RRScreenChangeNotifyMask
474558
 		      | RRCrtcChangeNotifyMask
474558
 		      | RROutputPropertyNotifyMask);
474558
 
474558
       manager_xrandr->has_randr15 = FALSE;
474558
       XRRQueryVersion (manager_xrandr->xdisplay, &major_version,
474558
                        &minor_version);
474558
 #ifdef HAVE_XRANDR15
474558
       if (major_version > 1 ||
474558
           (major_version == 1 &&
474558
            minor_version >= 5))
474558
         {
474558
           manager_xrandr->has_randr15 = TRUE;
474558
           manager_xrandr->tiled_monitor_atoms = g_hash_table_new (NULL, NULL);
474558
         }
db633a
       meta_monitor_manager_xrandr_init_monitors (manager_xrandr);
db633a
 #endif
db633a
     }
474558
 
474558
   G_OBJECT_CLASS (meta_monitor_manager_xrandr_parent_class)->constructed (object);
db633a
 }
db633a
 
db633a
 static void
474558
 meta_monitor_manager_xrandr_finalize (GObject *object)
474558
 {
474558
   MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (object);
474558
 
474558
   g_clear_object (&manager_xrandr->gpu);
e3f29c
   g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms);
e3f29c
   g_free (manager_xrandr->supported_scales);
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
 
474558
 static void
474558
 meta_monitor_manager_xrandr_init (MetaMonitorManagerXrandr *manager_xrandr)
474558
 {
474558
+  manager_xrandr->logind_watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
474558
+                                                      "org.freedesktop.login1",
474558
+                                                      G_BUS_NAME_WATCHER_FLAGS_NONE,
474558
+                                                      logind_appeared,
474558
+                                                      logind_vanished,
474558
+                                                      manager_xrandr,
474558
+                                                      NULL);
474558
 }
474558
 
474558
 static void
474558
 meta_monitor_manager_xrandr_class_init (MetaMonitorManagerXrandrClass *klass)
474558
 {
474558
   MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass);
474558
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
474558
 
474558
   object_class->finalize = meta_monitor_manager_xrandr_finalize;
474558
   object_class->constructed = meta_monitor_manager_xrandr_constructed;
474558
 
474558
   manager_class->read_edid = meta_monitor_manager_xrandr_read_edid;
474558
   manager_class->ensure_initial_config = meta_monitor_manager_xrandr_ensure_initial_config;
474558
   manager_class->apply_monitors_config = meta_monitor_manager_xrandr_apply_monitors_config;
474558
   manager_class->set_power_save_mode = meta_monitor_manager_xrandr_set_power_save_mode;
474558
   manager_class->change_backlight = meta_monitor_manager_xrandr_change_backlight;
474558
   manager_class->get_crtc_gamma = meta_monitor_manager_xrandr_get_crtc_gamma;
474558
   manager_class->set_crtc_gamma = meta_monitor_manager_xrandr_set_crtc_gamma;
474558
 #ifdef HAVE_XRANDR15
474558
   manager_class->tiled_monitor_added = meta_monitor_manager_xrandr_tiled_monitor_added;
474558
   manager_class->tiled_monitor_removed = meta_monitor_manager_xrandr_tiled_monitor_removed;
474558
 #endif
474558
   manager_class->is_transform_handled = meta_monitor_manager_xrandr_is_transform_handled;
474558
   manager_class->calculate_monitor_mode_scale = meta_monitor_manager_xrandr_calculate_monitor_mode_scale;
474558
   manager_class->calculate_supported_scales = meta_monitor_manager_xrandr_calculate_supported_scales;
474558
   manager_class->get_capabilities = meta_monitor_manager_xrandr_get_capabilities;
474558
   manager_class->get_max_screen_size = meta_monitor_manager_xrandr_get_max_screen_size;
474558
   manager_class->get_default_layout_mode = meta_monitor_manager_xrandr_get_default_layout_mode;
474558
 
474558
   quark_meta_monitor_xrandr_data =
e3f29c
     g_quark_from_static_string ("-meta-monitor-xrandr-data");
db633a
 }
db633a
 
474558
 static gboolean
474558
 is_xvnc (MetaMonitorManager *manager)
db633a
 {
474558
   MetaMonitorManagerXrandr *manager_xrandr =
474558
     META_MONITOR_MANAGER_XRANDR (manager);
474558
   GList *l;
db633a
 
474558
   for (l = meta_gpu_get_outputs (manager_xrandr->gpu); l; l = l->next)
474558
     {
474558
       MetaOutput *output = l->data;
db633a
 
474558
       if (g_str_has_prefix (output->name, "VNC-"))
474558
         return TRUE;
474558
     }
474558
 
474558
   return FALSE;
474558
 }
474558
 
474558
-gboolean
474558
-meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
474558
-					   XEvent                   *event)
474558
+static void
474558
+meta_monitor_manager_xrandr_update (MetaMonitorManagerXrandr *manager_xrandr)
474558
 {
474558
   MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
474558
   MetaGpuXrandr *gpu_xrandr;
474558
   XRRScreenResources *resources;
474558
   gboolean is_hotplug;
474558
   gboolean is_our_configuration;
474558
   unsigned int timestamp;
474558
 
474558
-  if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
474558
-    return FALSE;
e3f29c
-
474558
-  XRRUpdateConfiguration (event);
e3f29c
-
474558
   meta_monitor_manager_read_current_state (manager);
474558
 
474558
   gpu_xrandr = META_GPU_XRANDR (manager_xrandr->gpu);
474558
   resources = meta_gpu_xrandr_get_resources (gpu_xrandr);
474558
 
474558
   timestamp = resources->timestamp;
474558
   if (is_xvnc (manager))
474558
     timestamp += 100;
474558
 
474558
   is_hotplug = timestamp < resources->configTimestamp;
474558
   is_our_configuration = (resources->timestamp ==
474558
                           manager_xrandr->last_xrandr_set_timestamp);
474558
   if (is_hotplug)
474558
     {
474558
       meta_monitor_manager_on_hotplug (manager);
474558
     }
474558
   else
474558
     {
474558
       MetaMonitorsConfig *config;
474558
 
474558
       if (is_our_configuration)
474558
         {
474558
           MetaMonitorConfigManager *config_manager =
474558
             meta_monitor_manager_get_config_manager (manager);
474558
 
474558
           config = meta_monitor_config_manager_get_current (config_manager);
474558
         }
474558
       else
474558
         {
474558
           config = NULL;
474558
         }
474558
 
474558
       meta_monitor_manager_xrandr_rebuild_derived (manager, config);
474558
     }
474558
+}
474558
+
474558
+gboolean
474558
+meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xrandr,
474558
+					   XEvent                   *event)
474558
+{
474558
+
474558
+  if ((event->type - manager_xrandr->rr_event_base) != RRScreenChangeNotify)
474558
+    return FALSE;
474558
+
474558
+  XRRUpdateConfiguration (event);
474558
+
db633a
+  meta_monitor_manager_xrandr_update (manager_xrandr);
db633a
 
db633a
   return TRUE;
db633a
 }
db633a
-- 
474558
2.17.1
db633a