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

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