[mutter/wip/gbsneto/tiling-improvements] window: Properly handle different monitors when tiling



commit bba8ca20841d909f96ac27959a7c3921bb94bc32
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Mon Jun 19 23:45:21 2017 -0300

    window: Properly handle different monitors when tiling
    
    When changing the tile mode, or resizing a tiled window, it's
    important to consider the legit case of multiple monitors, and
    so the tiling code cannot just assume that the correct monitor
    is the current one.
    
    This patch, then, adapts the code - namely the tile matching
    computing function, and the tiled sizes calculation function -
    to properly handle the multi monitor case.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=645153

 src/core/screen.c         |   14 +++++++++--
 src/core/stack.c          |    2 +-
 src/core/window-private.h |   16 +++++++-----
 src/core/window.c         |   56 +++++++++++++++++++++++++++++++++-----------
 4 files changed, 63 insertions(+), 25 deletions(-)
---
diff --git a/src/core/screen.c b/src/core/screen.c
index 0213f8c..361b6ac 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -1428,16 +1428,24 @@ meta_screen_update_tile_preview_timeout (gpointer data)
 
   if (needs_preview)
     {
+      MetaLogicalMonitor *monitor;
+      MetaMonitorManager *manager;
       MetaRectangle tile_rect;
-      int monitor;
+      MetaBackend *backend;
+      int monitor_number;
+
+      backend = meta_get_backend ();
+      manager = meta_backend_get_monitor_manager (backend);
+      monitor_number = meta_window_get_current_tile_monitor_number (window);
+      monitor = meta_monitor_manager_get_logical_monitor_from_number (manager, monitor_number);
 
-      monitor = meta_window_get_current_tile_monitor_number (window);
       meta_window_get_tile_area_for_mode (window,
                                           &tile_rect,
+                                          monitor,
                                           window->preview_tile_mode,
                                           window->tile_mode);
       meta_compositor_show_tile_preview (screen->display->compositor,
-                                         window, &tile_rect, monitor);
+                                         window, &tile_rect, monitor_number);
     }
   else
     meta_compositor_hide_tile_preview (screen->display->compositor);
diff --git a/src/core/stack.c b/src/core/stack.c
index 66c59a3..370f72e 100644
--- a/src/core/stack.c
+++ b/src/core/stack.c
@@ -269,7 +269,7 @@ meta_stack_update_window_tile_matches (MetaStack     *stack,
     {
       MetaWindow *window = tmp->data;
 
-      window->tile_match = meta_window_compute_tile_match (window, window->tile_mode, FALSE);
+      window->tile_match = meta_window_compute_tile_match (window, window->tile_mode, NULL, FALSE);
       tmp = tmp->next;
     }
 
diff --git a/src/core/window-private.h b/src/core/window-private.h
index a831e07..f001765 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -660,10 +660,11 @@ void meta_window_get_work_area_for_logical_monitor (MetaWindow         *window,
                                                     MetaRectangle      *area);
 
 int meta_window_get_current_tile_monitor_number (MetaWindow    *window);
-void meta_window_get_tile_area_for_mode         (MetaWindow    *window,
-                                                 MetaRectangle *tile_area,
-                                                 MetaTileMode   tile_mode,
-                                                 MetaTileMode   previous_mode);
+void meta_window_get_tile_area_for_mode         (MetaWindow         *window,
+                                                 MetaRectangle      *tile_area,
+                                                 MetaLogicalMonitor *target_monitor,
+                                                 MetaTileMode        tile_mode,
+                                                 MetaTileMode        previous_mode);
 void meta_window_get_current_tile_area          (MetaWindow    *window,
                                                  MetaRectangle *tile_area);
 
@@ -707,9 +708,10 @@ void meta_window_on_all_workspaces_changed (MetaWindow *window);
 gboolean meta_window_should_attach_to_parent (MetaWindow *window);
 gboolean meta_window_can_tile_side_by_side   (MetaWindow *window);
 
-MetaWindow* meta_window_compute_tile_match (MetaWindow   *window,
-                                            MetaTileMode  current_mode,
-                                            gboolean      ignore_edges);
+MetaWindow* meta_window_compute_tile_match (MetaWindow         *window,
+                                            MetaTileMode        current_mode,
+                                            MetaLogicalMonitor *target_monitor,
+                                            gboolean            ignore_edges);
 
 gboolean meta_window_updates_are_frozen (MetaWindow *window);
 
diff --git a/src/core/window.c b/src/core/window.c
index f52ab45..8871eca 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -2892,18 +2892,36 @@ meta_window_requested_dont_bypass_compositor (MetaWindow *window)
 static void
 meta_window_update_tile_state_internal (MetaWindow *window)
 {
+  MetaLogicalMonitor *target_monitor;
   MetaRectangle monitor_area;
   MetaWindow *tile_match_window;
   gboolean was_tiled;
   gint borders_width = 0;
 
+  /* Tiling to a different monitor yields the need to be careful to not pick the
+   * wrong monitor.
+   */
+  if (window->tile_monitor_number != -1)
+    {
+      MetaBackend *backend = meta_get_backend ();
+      MetaMonitorManager *monitor_manager =
+        meta_backend_get_monitor_manager (backend);
+
+      target_monitor = meta_monitor_manager_get_logical_monitor_from_number (monitor_manager,
+                                                                             window->tile_monitor_number);
+    }
+  else
+    {
+      target_monitor = window->monitor;
+    }
+
   /* When tiling a window, the new matching tile window is not yet synchronized,
    * so we must do that now manually. It is not necessary to recompute all windows'
    * tile matches, just the current one */
-  tile_match_window = meta_window_compute_tile_match (window, window->tile_mode, TRUE);
+  tile_match_window = meta_window_compute_tile_match (window, window->tile_mode, target_monitor, TRUE);
   window->tile_match = tile_match_window;
 
-  meta_window_get_work_area_current_monitor (window, &monitor_area);
+  meta_window_get_work_area_for_monitor (window, target_monitor->number, &monitor_area);
 
   /* window->tile_rect must consider the visible borders */
   if (window->frame)
@@ -5929,7 +5947,11 @@ update_tile_rects (MetaWindow *window,
   /* Make sure the resize does not break minimum sizes */
   new_w = MAX (new_w, window->size_hints.min_width);
 
-  meta_window_get_work_area_for_monitor (window, window->tile_monitor_number, &work_area);
+  /* It's safe to assume that the tile match is in the same monitor that
+   * the current window. meta_window_compute_tile_match() checks that
+   * already.
+   */
+  meta_window_get_work_area_current_monitor (window, &work_area);
 
   if (tile_match)
     {
@@ -6409,10 +6431,11 @@ meta_window_get_current_tile_monitor_number (MetaWindow *window)
 }
 
 void
-meta_window_get_tile_area_for_mode (MetaWindow    *window,
-                                    MetaRectangle *tile_area,
-                                    MetaTileMode   tile_mode,
-                                    MetaTileMode   previous_mode)
+meta_window_get_tile_area_for_mode (MetaWindow         *window,
+                                    MetaRectangle      *tile_area,
+                                    MetaLogicalMonitor *target_monitor,
+                                    MetaTileMode        tile_mode,
+                                    MetaTileMode        previous_mode)
 {
   MetaRectangle monitor_area;
   MetaWindow *tile_match_window;
@@ -6422,9 +6445,9 @@ meta_window_get_tile_area_for_mode (MetaWindow    *window,
   g_return_if_fail (tile_mode != META_TILE_NONE);
 
   /* If we are previewing, don't change the actual tile mode */
-  tile_match_window = meta_window_compute_tile_match (window, tile_mode, TRUE);
+  tile_match_window = meta_window_compute_tile_match (window, tile_mode, target_monitor, TRUE);
 
-  meta_window_get_work_area_current_monitor (window, &monitor_area);
+  meta_window_get_work_area_for_monitor (window, target_monitor->number, &monitor_area);
 
   /* Initially assume the tile area */
   *tile_area = window->tile_rect;
@@ -7580,9 +7603,10 @@ meta_window_get_tile_match (MetaWindow *window)
 }
 
 MetaWindow *
-meta_window_compute_tile_match (MetaWindow   *window,
-                                MetaTileMode  current_mode,
-                                gboolean      ignore_edges)
+meta_window_compute_tile_match (MetaWindow         *window,
+                                MetaTileMode        current_mode,
+                                MetaLogicalMonitor *target_monitor,
+                                gboolean            ignore_edges)
 {
   MetaWindow *match;
   MetaStack *stack;
@@ -7598,6 +7622,10 @@ meta_window_compute_tile_match (MetaWindow   *window,
   else
     return NULL;
 
+  /* Assume the current monitor if none is passed */
+  if (!target_monitor)
+    target_monitor = window->monitor;
+
   stack = window->screen->stack;
 
   for (match = meta_stack_get_top (stack);
@@ -7607,7 +7635,7 @@ meta_window_compute_tile_match (MetaWindow   *window,
       if (!match->shaded &&
           !match->minimized &&
           match->tile_mode == match_tile_mode &&
-          match->monitor == window->monitor &&
+          match->monitor == target_monitor &&
           meta_window_get_workspace (match) == meta_window_get_workspace (window))
         break;
     }
@@ -7642,7 +7670,7 @@ meta_window_compute_tile_match (MetaWindow   *window,
            above = meta_stack_get_above (stack, above, FALSE))
         {
           if (above->minimized ||
-              above->monitor != window->monitor ||
+              above->monitor != target_monitor ||
               meta_window_get_workspace (above) != meta_window_get_workspace (window))
             continue;
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]