Blame SOURCES/preserve-monitor.patch

68333f
From abedce08727b9993e0365c9b925bbcab9110feb1 Mon Sep 17 00:00:00 2001
68333f
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
68333f
Date: Fri, 13 Jun 2014 22:28:26 +0200
68333f
Subject: [PATCH 1/2] window: Keep track of preferred output
68333f
68333f
Remember the last monitor a window was moved to by user action and
68333f
try to move it back on monitor changes; this should match user
68333f
expectations much better when a monitor is unplugged temporarily.
68333f
68333f
https://bugzilla.gnome.org/show_bug.cgi?id=731760
68333f
---
68333f
 src/core/window-private.h |  1 +
68333f
 src/core/window.c         | 47 ++++++++++++++++++++++++++++++++++-------------
68333f
 2 files changed, 35 insertions(+), 13 deletions(-)
68333f
68333f
diff --git a/src/core/window-private.h b/src/core/window-private.h
68333f
index e9f935f..9a0c760 100644
68333f
--- a/src/core/window-private.h
68333f
+++ b/src/core/window-private.h
68333f
@@ -148,6 +148,7 @@ struct _MetaWindow
68333f
    * that to toggle between normal/tiled or maximized/tiled states. */
68333f
   guint saved_maximize : 1;
68333f
   int tile_monitor_number;
68333f
+  XID preferred_output;
68333f
 
68333f
   /* Whether we're shaded */
68333f
   guint shaded : 1;
68333f
diff --git a/src/core/window.c b/src/core/window.c
68333f
index 60347ef..8b8fbe7 100644
68333f
--- a/src/core/window.c
68333f
+++ b/src/core/window.c
68333f
@@ -1198,6 +1198,7 @@ meta_window_new_with_attrs (MetaDisplay       *display,
68333f
   window->compositor_private = NULL;
68333f
 
68333f
   window->monitor = meta_screen_get_monitor_for_window (window->screen, window);
68333f
+  window->preferred_output = window->monitor->output;
68333f
 
68333f
   window->tile_match = NULL;
68333f
 
68333f
@@ -4779,13 +4780,29 @@ meta_window_get_monitor (MetaWindow *window)
68333f
   return window->monitor->number;
68333f
 }
68333f
 
68333f
+static MetaMonitorInfo *
68333f
+find_monitor_by_id (MetaWindow *window,
68333f
+                    guint       id)
68333f
+{
68333f
+  int i;
68333f
+
68333f
+  for (i = 0; i < window->screen->n_monitor_infos; i++)
68333f
+    {
68333f
+      MetaMonitorInfo *info = &window->screen->monitor_infos[i];
68333f
+
68333f
+      if (info->output != 0 && info->output == id)
68333f
+        return info;
68333f
+    }
68333f
+
68333f
+  return NULL;
68333f
+}
68333f
+
68333f
 /* This is called when the monitor setup has changed. The window->monitor
68333f
  * reference is still "valid", but refer to the previous monitor setup */
68333f
 void
68333f
 meta_window_update_for_monitors_changed (MetaWindow *window)
68333f
 {
68333f
   const MetaMonitorInfo *old, *new;
68333f
-  int i;
68333f
 
68333f
   if (window->type == META_WINDOW_DESKTOP)
68333f
     return;
68333f
@@ -4798,20 +4815,16 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
68333f
 
68333f
   old = window->monitor;
68333f
 
68333f
-  /* Start on primary */
68333f
-  new = &window->screen->monitor_infos[window->screen->primary_monitor_index];
68333f
+  /* Try the preferred output first */
68333f
+  new = find_monitor_by_id (window, window->preferred_output);
68333f
 
68333f
-  /* But, if we can find the old output on a new monitor, use that */
68333f
-  for (i = 0; i < window->screen->n_monitor_infos; i++)
68333f
-    {
68333f
-      MetaMonitorInfo *info = &window->screen->monitor_infos[i];
68333f
+  /* Otherwise, try to find the old output on a new monitor */
68333f
+  if (!new)
68333f
+    new = find_monitor_by_id (window, old->output);
68333f
 
68333f
-      if (info->output == old->output)
68333f
-        {
68333f
-          new = info;
68333f
-          break;
68333f
-        }
68333f
-    }
68333f
+  /* Fall back to primary if everything else failed */
68333f
+  if (!new)
68333f
+    new = &window->screen->monitor_infos[window->screen->primary_monitor_index];
68333f
 
68333f
   if (window->tile_mode != META_TILE_NONE)
68333f
     window->tile_monitor_number = new->number;
68333f
@@ -4934,6 +4947,7 @@ meta_window_move_resize_internal (MetaWindow          *window,
68333f
   int client_move_y;
68333f
   MetaRectangle new_rect;
68333f
   MetaRectangle old_rect;
68333f
+  guint old_output_id;
68333f
 
68333f
   g_return_if_fail (!window->override_redirect);
68333f
 
68333f
@@ -5332,8 +5346,14 @@ meta_window_move_resize_internal (MetaWindow          *window,
68333f
 
68333f
   meta_window_refresh_resize_popup (window);
68333f
 
68333f
+  old_output_id = window->monitor->output;
68333f
+
68333f
   meta_window_update_monitor (window);
68333f
 
68333f
+  if (old_output_id != window->monitor->output &&
68333f
+      flags & META_IS_MOVE_ACTION && flags & META_IS_USER_ACTION)
68333f
+    window->preferred_output = window->monitor->output;
68333f
+
68333f
   /* Invariants leaving this function are:
68333f
    *   a) window->rect and frame->rect reflect the actual
68333f
    *      server-side size/pos of window->xwindow and frame->xwindow
68333f
@@ -5536,6 +5556,7 @@ meta_window_move_to_monitor (MetaWindow  *window,
68333f
     window->tile_monitor_number = monitor;
68333f
 
68333f
   meta_window_move_between_rects (window, &old_area, &new_area);
68333f
+  window->preferred_output = window->monitor->output;
68333f
 }
68333f
 
68333f
 void
68333f
-- 
68333f
2.1.0
68333f
68333f
68333f
From 6d39e1a72f8914d6a021d801940ab8a6c13d16f7 Mon Sep 17 00:00:00 2001
68333f
From: =?UTF-8?q?Florian=20M=C3=BCllner?= <fmuellner@gnome.org>
68333f
Date: Fri, 20 Jun 2014 18:06:40 +0200
68333f
Subject: [PATCH 2/2] window: Add user_op parameter to update_monitor()
68333f
68333f
When workspaces-only-on-primary is set and a window is moved back to the
68333f
primary, we also move it to the active workspace to avoid the confusion
68333f
of a visible window suddenly disappearing when crossing the monitor border.
68333f
However when the window is not actually moved by the user, preserving the
68333f
workspace makes more sense - we already do this in some cases (e.g. when
68333f
moving between primary monitors), but miss others (unplugging the previous
68333f
monitor); just add an explicit user_op parameter as used elsewhere to cover
68333f
all exceptions.
68333f
68333f
https://bugzilla.gnome.org/show_bug.cgi?id=731760
68333f
---
68333f
 src/core/window-private.h |  1 -
68333f
 src/core/window.c         | 30 ++++++++++++++----------------
68333f
 2 files changed, 14 insertions(+), 17 deletions(-)
68333f
68333f
diff --git a/src/core/window-private.h b/src/core/window-private.h
68333f
index 9a0c760..1a39a4b 100644
68333f
--- a/src/core/window-private.h
68333f
+++ b/src/core/window-private.h
68333f
@@ -677,5 +677,4 @@ gboolean meta_window_can_tile_side_by_side   (MetaWindow *window);
68333f
 void meta_window_compute_tile_match (MetaWindow *window);
68333f
 
68333f
 gboolean meta_window_updates_are_frozen (MetaWindow *window);
68333f
-
68333f
 #endif
68333f
diff --git a/src/core/window.c b/src/core/window.c
68333f
index 8b8fbe7..f376ea0 100644
68333f
--- a/src/core/window.c
68333f
+++ b/src/core/window.c
68333f
@@ -145,7 +145,8 @@ static void meta_window_move_between_rects (MetaWindow          *window,
68333f
 static void unmaximize_window_before_freeing (MetaWindow        *window);
68333f
 static void unminimize_window_and_all_transient_parents (MetaWindow *window);
68333f
 
68333f
-static void meta_window_update_monitor (MetaWindow *window);
68333f
+static void meta_window_update_monitor (MetaWindow *window,
68333f
+                                        gboolean    user_op);
68333f
 
68333f
 /* Idle handlers for the three queues (run with meta_later_add()). The
68333f
  * "data" parameter in each case will be a GINT_TO_POINTER of the
68333f
@@ -4809,7 +4810,7 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
68333f
 
68333f
   if (window->override_redirect)
68333f
     {
68333f
-      meta_window_update_monitor (window);
68333f
+      meta_window_update_monitor (window, FALSE);
68333f
       return;
68333f
     }
68333f
 
68333f
@@ -4842,7 +4843,8 @@ meta_window_update_for_monitors_changed (MetaWindow *window)
68333f
 }
68333f
 
68333f
 static void
68333f
-meta_window_update_monitor (MetaWindow *window)
68333f
+meta_window_update_monitor (MetaWindow *window,
68333f
+                            gboolean    user_op)
68333f
 {
68333f
   const MetaMonitorInfo *old;
68333f
 
68333f
@@ -4852,22 +4854,17 @@ meta_window_update_monitor (MetaWindow *window)
68333f
     {
68333f
       meta_window_update_on_all_workspaces (window);
68333f
 
68333f
-      /* If workspaces only on primary and we moved back to primary, ensure that the
68333f
-       * window is now in that workspace. We do this because while the window is on a
68333f
-       * non-primary monitor it is always visible, so it would be very jarring if it
68333f
-       * disappeared when it crossed the monitor border.
68333f
+      /* If workspaces only on primary and we moved back to primary due to a user action,
68333f
+       * ensure that the window is now in that workspace. We do this because while
68333f
+       * the window is on a non-primary monitor it is always visible, so it would be
68333f
+       * very jarring if it disappeared when it crossed the monitor border.
68333f
        * The one time we want it to both change to the primary monitor and a non-active
68333f
        * workspace is when dropping the window on some other workspace thumbnail directly.
68333f
        * That should be handled by explicitly moving the window before changing the
68333f
-       * workspace
68333f
-       * Don't do this if old == NULL, because thats what happens when starting up, and
68333f
-       * we don't want to move all windows around from a previous WM instance. Nor do
68333f
-       * we want it when moving from one primary monitor to another (can happen during
68333f
-       * screen reconfiguration.
68333f
+       * workspace.
68333f
        */
68333f
-      if (meta_prefs_get_workspaces_only_on_primary () &&
68333f
+      if (meta_prefs_get_workspaces_only_on_primary () && user_op &&
68333f
           meta_window_is_on_primary_monitor (window)  &&
68333f
-          old != NULL && !old->is_primary &&
68333f
           window->screen->active_workspace != window->workspace)
68333f
         meta_window_change_workspace (window, window->screen->active_workspace);
68333f
 
68333f
@@ -4878,6 +4875,7 @@ meta_window_update_monitor (MetaWindow *window)
68333f
       /* If we're changing monitors, we need to update the has_maximize_func flag,
68333f
        * as the working area has changed. */
68333f
       recalc_window_features (window);
68333f
+      meta_window_queue (window, META_QUEUE_CALC_SHOWING);
68333f
     }
68333f
 }
68333f
 
68333f
@@ -5348,7 +5346,7 @@ meta_window_move_resize_internal (MetaWindow          *window,
68333f
 
68333f
   old_output_id = window->monitor->output;
68333f
 
68333f
-  meta_window_update_monitor (window);
68333f
+  meta_window_update_monitor (window, flags & META_IS_USER_ACTION);
68333f
 
68333f
   if (old_output_id != window->monitor->output &&
68333f
       flags & META_IS_MOVE_ACTION && flags & META_IS_USER_ACTION)
68333f
@@ -5672,7 +5670,7 @@ meta_window_configure_notify (MetaWindow      *window,
68333f
   window->rect.y = event->y;
68333f
   window->rect.width = event->width;
68333f
   window->rect.height = event->height;
68333f
-  meta_window_update_monitor (window);
68333f
+  meta_window_update_monitor (window, FALSE);
68333f
 
68333f
   /* Whether an override-redirect window is considered fullscreen depends
68333f
    * on its geometry.
68333f
-- 
68333f
2.1.0
68333f