[mutter] window: Make move_to_monitor work for zero sized and offscreen windows



commit bb2e8ff09a5461d3a87954d1b81ef94de324577a
Author: Rui Matos <tiagomatos gmail com>
Date:   Tue Nov 15 14:10:05 2016 +0100

    window: Make move_to_monitor work for zero sized and offscreen windows
    
    Wayland windows are initially zero sized until clients commit the
    first buffer. Despite being invisible, clients are allowed to request
    such windows to be fullscreened on a specific output before they
    attach the first buffer which means we need to be able to move them.
    
    meta_window_move_to_monitor() doesn't handle this case because these
    windows' initial monitor is a placeholder since their initial
    coordinates are 0,0+0+0, which results in us using a rectangle as
    old_area for meta_window_move_between_rects() that might be to the "right"
    of the window causing the move to go further out of the visible
    screen's coordinates. This is later "corrected" by the constraints
    system but the window might end up in the wrong monitor.
    
    To fix this, we can make meta_window_move_between_rects() accept a
    NULL old_area, meaning that we move the window to the new_area without
    trying to keep a relative position.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=772525

 src/core/window.c |   33 +++++++++++++++++++++++++--------
 1 files changed, 25 insertions(+), 8 deletions(-)
---
diff --git a/src/core/window.c b/src/core/window.c
index 82a8f85..cd2bb90 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -3790,10 +3790,17 @@ meta_window_move_between_rects (MetaWindow  *window,
   int rel_x, rel_y;
   double scale_x, scale_y;
 
-  rel_x = window->unconstrained_rect.x - old_area->x;
-  rel_y = window->unconstrained_rect.y - old_area->y;
-  scale_x = (double)new_area->width / old_area->width;
-  scale_y = (double)new_area->height / old_area->height;
+  if (old_area)
+    {
+      rel_x = window->unconstrained_rect.x - old_area->x;
+      rel_y = window->unconstrained_rect.y - old_area->y;
+      scale_x = (double)new_area->width / old_area->width;
+      scale_y = (double)new_area->height / old_area->height;
+    }
+  else
+    {
+      rel_x = rel_y = scale_x = scale_y = 0;
+    }
 
   window->unconstrained_rect.x = new_area->x + rel_x * scale_x;
   window->unconstrained_rect.y = new_area->y + rel_y * scale_y;
@@ -3847,9 +3854,6 @@ meta_window_move_to_monitor (MetaWindow  *window,
 {
   MetaRectangle old_area, new_area;
 
-  if (monitor == window->monitor->number)
-    return;
-
   meta_window_get_work_area_for_monitor (window,
                                          window->monitor->number,
                                          &old_area);
@@ -3857,10 +3861,23 @@ meta_window_move_to_monitor (MetaWindow  *window,
                                          monitor,
                                          &new_area);
 
+  if (window->unconstrained_rect.width == 0 ||
+      window->unconstrained_rect.height == 0 ||
+      !meta_rectangle_overlap (&window->unconstrained_rect, &old_area))
+    {
+      meta_window_move_between_rects (window, NULL, &new_area);
+    }
+  else
+    {
+      if (monitor == window->monitor->number)
+        return;
+
+      meta_window_move_between_rects (window, &old_area, &new_area);
+    }
+
   if (window->tile_mode != META_TILE_NONE)
     window->tile_monitor_number = monitor;
 
-  meta_window_move_between_rects (window, &old_area, &new_area);
   window->preferred_output_winsys_id = window->monitor->winsys_id;
 
   if (window->fullscreen || window->override_redirect)


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