Blame SOURCES/0002-window-Force-update-monitor-on-hot-plugs.patch

776610
From 83b7b17b64b3e42a87f524ac3504be81789ec0fc Mon Sep 17 00:00:00 2001
776610
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
776610
Date: Fri, 24 Aug 2018 12:56:31 +0200
776610
Subject: [PATCH 2/2] window: Force update monitor on hot plugs
776610
776610
Commit a3da4b8d5bd217c0262fd9361036877d155a300f changed updating of
776610
window monitors to always use take affect when it was done from a
776610
non-user operation. This could cause feed back loops when a non-user
776610
driven operation would trigger the changing of a monitor, which itself
776610
would trigger changing of the monitor again due to a window scale
776610
change.
776610
776610
The reason for the change, was that when the window monitor changed due
776610
to a hot plug, if it didn't actually change, eventually the window
776610
monitor pointer would be pointing to freed memory.
776610
776610
Instead of force updating the monitor on all non-user operations, just
776610
do it on hot plugs. This allows for the feedback loop preventing logic
776610
to still do what its supposed to do, without risking dangling pointers
776610
on hot plugs.
776610
776610
Related: https://gitlab.gnome.org/GNOME/mutter/issues/189
776610
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/192
776610
776610
(cherry picked from commit 8d3e053059cd202e740076caedfc8e3ac149066a)
776610
---
776610
 src/core/window-private.h | 1 +
776610
 src/core/window.c         | 4 ++--
776610
 2 files changed, 3 insertions(+), 2 deletions(-)
776610
776610
diff --git a/src/core/window-private.h b/src/core/window-private.h
776610
index bed2fc7f6..8552829b2 100644
776610
--- a/src/core/window-private.h
776610
+++ b/src/core/window-private.h
776610
@@ -98,60 +98,61 @@ typedef enum
776610
   META_PLACEMENT_GRAVITY_TOP    = 1 << 0,
776610
   META_PLACEMENT_GRAVITY_BOTTOM = 1 << 1,
776610
   META_PLACEMENT_GRAVITY_LEFT   = 1 << 2,
776610
   META_PLACEMENT_GRAVITY_RIGHT  = 1 << 3,
776610
 } MetaPlacementGravity;
776610
 
776610
 typedef enum
776610
 {
776610
   META_PLACEMENT_ANCHOR_NONE   = 0,
776610
   META_PLACEMENT_ANCHOR_TOP    = 1 << 0,
776610
   META_PLACEMENT_ANCHOR_BOTTOM = 1 << 1,
776610
   META_PLACEMENT_ANCHOR_LEFT   = 1 << 2,
776610
   META_PLACEMENT_ANCHOR_RIGHT  = 1 << 3,
776610
 } MetaPlacementAnchor;
776610
 
776610
 typedef enum
776610
 {
776610
   META_PLACEMENT_CONSTRAINT_ADJUSTMENT_NONE     = 0,
776610
   META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_X  = 1 << 0,
776610
   META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_Y  = 1 << 1,
776610
   META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_X   = 1 << 2,
776610
   META_PLACEMENT_CONSTRAINT_ADJUSTMENT_FLIP_Y   = 1 << 3,
776610
   META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_X = 1 << 4,
776610
   META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 1 << 5,
776610
 } MetaPlacementConstraintAdjustment;
776610
 
776610
 typedef enum _MetaWindowUpdateMonitorFlags
776610
 {
776610
   META_WINDOW_UPDATE_MONITOR_FLAGS_NONE = 0,
776610
   META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP = 1 << 0,
776610
+  META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE = 1 << 1,
776610
 } MetaWindowUpdateMonitorFlags;
776610
 
776610
 typedef struct _MetaPlacementRule
776610
 {
776610
   MetaRectangle anchor_rect;
776610
   MetaPlacementGravity gravity;
776610
   MetaPlacementAnchor anchor;
776610
   MetaPlacementConstraintAdjustment constraint_adjustment;
776610
   int offset_x;
776610
   int offset_y;
776610
   int width;
776610
   int height;
776610
 } MetaPlacementRule;
776610
 
776610
 typedef enum
776610
 {
776610
   META_EDGE_CONSTRAINT_NONE    = 0,
776610
   META_EDGE_CONSTRAINT_WINDOW  = 1,
776610
   META_EDGE_CONSTRAINT_MONITOR = 2,
776610
 } MetaEdgeConstraint;
776610
 
776610
 struct _MetaWindow
776610
 {
776610
   GObject parent_instance;
776610
 
776610
   MetaDisplay *display;
776610
   MetaScreen *screen;
776610
   guint64 stamp;
776610
   MetaLogicalMonitor *monitor;
776610
   MetaWorkspace *workspace;
776610
diff --git a/src/core/window.c b/src/core/window.c
776610
index ad4059704..07f826bb5 100644
776610
--- a/src/core/window.c
776610
+++ b/src/core/window.c
776610
@@ -3776,97 +3776,97 @@ find_monitor_by_winsys_id (MetaWindow *window,
776610
   logical_monitors =
776610
     meta_monitor_manager_get_logical_monitors (monitor_manager);
776610
 
776610
   for (l = logical_monitors; l; l = l->next)
776610
     {
776610
       MetaLogicalMonitor *logical_monitor = l->data;
776610
 
776610
       if (logical_monitor->winsys_id == winsys_id)
776610
         return logical_monitor;
776610
     }
776610
 
776610
   return NULL;
776610
 }
776610
 
776610
 /* This is called when the monitor setup has changed. The window->monitor
776610
  * reference is still "valid", but refer to the previous monitor setup */
776610
 void
776610
 meta_window_update_for_monitors_changed (MetaWindow *window)
776610
 {
776610
   MetaBackend *backend = meta_get_backend ();
776610
   MetaMonitorManager *monitor_manager =
776610
     meta_backend_get_monitor_manager (backend);
776610
   const MetaLogicalMonitor *old, *new;
776610
 
776610
   if (meta_window_has_fullscreen_monitors (window))
776610
     meta_window_clear_fullscreen_monitors (window);
776610
 
776610
   if (window->override_redirect || window->type == META_WINDOW_DESKTOP)
776610
     {
776610
       meta_window_update_monitor (window,
776610
-                                  META_WINDOW_UPDATE_MONITOR_FLAGS_NONE);
776610
+                                  META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE);
776610
       return;
776610
     }
776610
 
776610
   old = window->monitor;
776610
 
776610
   /* Try the preferred output first */
776610
   new = find_monitor_by_winsys_id (window, window->preferred_output_winsys_id);
776610
 
776610
   /* Otherwise, try to find the old output on a new monitor */
776610
   if (old && !new)
776610
     new = find_monitor_by_winsys_id (window, old->winsys_id);
776610
 
776610
   /* Fall back to primary if everything else failed */
776610
   if (!new)
776610
     new = meta_monitor_manager_get_primary_logical_monitor (monitor_manager);
776610
 
776610
   if (new && old)
776610
     {
776610
       if (window->tile_mode != META_TILE_NONE)
776610
         window->tile_monitor_number = new->number;
776610
 
776610
       /* This will eventually reach meta_window_update_monitor that
776610
        * will send leave/enter-monitor events. The old != new monitor
776610
        * check will always fail (due to the new logical_monitors set) so
776610
        * we will always send the events, even if the new and old monitor
776610
        * index is the same. That is right, since the enumeration of the
776610
        * monitors changed and the same index could be refereing
776610
        * to a different monitor. */
776610
       meta_window_move_between_rects (window,
776610
                                       &old->rect,
776610
                                       &new->rect);
776610
     }
776610
   else
776610
     {
776610
       meta_window_update_monitor (window,
776610
-                                  META_WINDOW_UPDATE_MONITOR_FLAGS_NONE);
776610
+                                  META_WINDOW_UPDATE_MONITOR_FLAGS_FORCE);
776610
     }
776610
 }
776610
 
776610
 void
776610
 meta_window_update_monitor (MetaWindow                   *window,
776610
                             MetaWindowUpdateMonitorFlags  flags)
776610
 {
776610
   const MetaLogicalMonitor *old;
776610
 
776610
   old = window->monitor;
776610
   META_WINDOW_GET_CLASS (window)->update_main_monitor (window, flags);
776610
   if (old != window->monitor)
776610
     {
776610
       meta_window_on_all_workspaces_changed (window);
776610
 
776610
       /* If workspaces only on primary and we moved back to primary due to a user action,
776610
        * ensure that the window is now in that workspace. We do this because while
776610
        * the window is on a non-primary monitor it is always visible, so it would be
776610
        * very jarring if it disappeared when it crossed the monitor border.
776610
        * The one time we want it to both change to the primary monitor and a non-active
776610
        * workspace is when dropping the window on some other workspace thumbnail directly.
776610
        * That should be handled by explicitly moving the window before changing the
776610
        * workspace.
776610
        */
776610
       if (meta_prefs_get_workspaces_only_on_primary () &&
776610
           flags & META_WINDOW_UPDATE_MONITOR_FLAGS_USER_OP &&
776610
           meta_window_is_on_primary_monitor (window)  &&
776610
           window->screen->active_workspace != window->workspace)
776610
         meta_window_change_workspace (window, window->screen->active_workspace);
776610
 
776610
-- 
776610
2.18.1
776610