[mutter] constraints: Pass constrained relative coordinates to window impl



commit ff381d1d52f0869486f97c923ac4cada35910217
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Feb 14 08:52:48 2020 +0100

    constraints: Pass constrained relative coordinates to window impl
    
    A placement rule placed window positions itself relative to its parent,
    thus converting between relative coordinates to absolute coordinates,
    then back to relative coordinates implies unwanted restrictions for
    example when the absolute coordinate should not be calculated againts
    the current parent window position.
    
    Deal with this by keeping track of the relative position all the way
    from the constraining engine to the move-resize window implementation.
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/705

 src/core/constraints.c            | 75 +++++++++++++++++++++++++++++++--------
 src/core/constraints.h            |  4 ++-
 src/core/window-private.h         |  2 ++
 src/core/window.c                 | 19 ++++++++--
 src/wayland/meta-window-wayland.c |  7 ++--
 src/x11/window-x11.c              |  2 ++
 6 files changed, 86 insertions(+), 23 deletions(-)
---
diff --git a/src/core/constraints.c b/src/core/constraints.c
index fa70ec1bf..8e5009097 100644
--- a/src/core/constraints.c
+++ b/src/core/constraints.c
@@ -123,6 +123,8 @@ typedef struct
 {
   MetaRectangle        orig;
   MetaRectangle        current;
+  int                  rel_x;
+  int                  rel_y;
   ActionType           action_type;
   gboolean             is_user_action;
 
@@ -281,7 +283,9 @@ meta_window_constrain (MetaWindow          *window,
                        MetaMoveResizeFlags  flags,
                        int                  resize_gravity,
                        const MetaRectangle *orig,
-                       MetaRectangle       *new)
+                       MetaRectangle       *new,
+                       int                 *rel_x,
+                       int                 *rel_y)
 {
   ConstraintInfo info;
   ConstraintPriority priority = PRIORITY_MINIMUM;
@@ -318,6 +322,8 @@ meta_window_constrain (MetaWindow          *window,
 
   /* Make sure we use the constrained position */
   *new = info.current;
+  *rel_x = info.rel_x;
+  *rel_y = info.rel_y;
 
   /* We may need to update window->require_fully_onscreen,
    * window->require_on_single_monitor, and perhaps other quantities
@@ -342,6 +348,8 @@ setup_constraint_info (ConstraintInfo      *info,
 
   info->orig    = *orig;
   info->current = *new;
+  info->rel_x = 0;
+  info->rel_y = 0;
 
   if (info->current.width < 1)
     info->current.width = 1;
@@ -494,15 +502,14 @@ place_window_if_needed(MetaWindow     *window,
         {
           MetaWindow *parent = meta_window_get_transient_for (window);
           MetaRectangle parent_rect;
-          int rel_x, rel_y;
 
           meta_window_process_placement (window,
                                          window->placement.rule,
-                                         &rel_x, &rel_y);
+                                         &info->rel_x, &info->rel_y);
           meta_window_get_frame_rect (parent, &parent_rect);
 
-          placed_rect.x = parent_rect.x + rel_x;
-          placed_rect.y = parent_rect.y + rel_y;
+          placed_rect.x = parent_rect.x + info->rel_x;
+          placed_rect.y = parent_rect.y + info->rel_y;
         }
       else
         {
@@ -745,6 +752,8 @@ try_flip_window_position (MetaWindow                       *window,
                           int                               parent_x,
                           int                               parent_y,
                           MetaRectangle                    *rect,
+                          int                              *rel_x,
+                          int                              *rel_y,
                           MetaRectangle                    *intersection)
 {
   MetaPlacementRule flipped_rule = *placement_rule;;
@@ -781,6 +790,8 @@ try_flip_window_position (MetaWindow                       *window,
     {
       *placement_rule = flipped_rule;
       *rect = flipped_rect;
+      *rel_x = flipped_rel_x;
+      *rel_y = flipped_rel_y;
       *intersection = flipped_intersection;
     }
 }
@@ -815,6 +826,8 @@ constrain_custom_rule (MetaWindow         *window,
   MetaRectangle intersection;
   gboolean constraint_satisfied;
   MetaRectangle adjusted_unconstrained;
+  int adjusted_rel_x;
+  int adjusted_rel_y;
   MetaPlacementRule current_rule;
   MetaWindow *parent;
   MetaRectangle parent_rect;
@@ -834,12 +847,16 @@ constrain_custom_rule (MetaWindow         *window,
   switch (window->placement.state)
     {
     case META_PLACEMENT_STATE_UNCONSTRAINED:
+      adjusted_rel_x = window->rect.x - parent->rect.x;
+      adjusted_rel_y = window->rect.y - parent->rect.y;
       break;
     case META_PLACEMENT_STATE_CONSTRAINED:
       adjusted_unconstrained.x =
         parent->rect.x + window->placement.current.rel_x;
       adjusted_unconstrained.y =
         parent->rect.y + window->placement.current.rel_y;
+      adjusted_rel_x = window->placement.current.rel_x;
+      adjusted_rel_y = window->placement.current.rel_y;
       break;
     }
 
@@ -861,6 +878,8 @@ constrain_custom_rule (MetaWindow         *window,
     {
     case META_PLACEMENT_STATE_CONSTRAINED:
       info->current = adjusted_unconstrained;
+      info->rel_x = adjusted_rel_x;
+      info->rel_y = adjusted_rel_y;
       goto done;
     case META_PLACEMENT_STATE_UNCONSTRAINED:
       break;
@@ -878,6 +897,8 @@ constrain_custom_rule (MetaWindow         *window,
                                 parent_rect.x,
                                 parent_rect.y,
                                 &info->current,
+                                &info->rel_x,
+                                &info->rel_y,
                                 &intersection);
     }
   if (info->current.height != intersection.height &&
@@ -889,6 +910,8 @@ constrain_custom_rule (MetaWindow         *window,
                                 parent_rect.x,
                                 parent_rect.y,
                                 &info->current,
+                                &info->rel_x,
+                                &info->rel_y,
                                 &intersection);
     }
 
@@ -906,6 +929,7 @@ constrain_custom_rule (MetaWindow         *window,
     {
       int current_x2;
       int work_area_monitor_x2;
+      int new_x;
 
       current_x2 = info->current.x + info->current.width;
       work_area_monitor_x2 = (info->work_area_monitor.x +
@@ -913,19 +937,27 @@ constrain_custom_rule (MetaWindow         *window,
 
       if (current_x2 > work_area_monitor_x2)
         {
-          info->current.x = MAX (info->work_area_monitor.x,
-                                 work_area_monitor_x2 - info->current.width);
+          new_x = MAX (info->work_area_monitor.x,
+                       work_area_monitor_x2 - info->current.width);
         }
       else if (info->current.x < info->work_area_monitor.x)
         {
-          info->current.x = info->work_area_monitor.x;
+          new_x = info->work_area_monitor.x;
         }
+      else
+        {
+          new_x = info->current.x;
+        }
+
+      info->rel_x += new_x - info->current.x;
+      info->current.x = new_x;
     }
   if (current_rule.constraint_adjustment &
       META_PLACEMENT_CONSTRAINT_ADJUSTMENT_SLIDE_Y)
     {
       int current_y2;
       int work_area_monitor_y2;
+      int new_y;
 
       current_y2 = info->current.y + info->current.height;
       work_area_monitor_y2 = (info->work_area_monitor.y +
@@ -933,13 +965,20 @@ constrain_custom_rule (MetaWindow         *window,
 
       if (current_y2 > work_area_monitor_y2)
         {
-          info->current.y = MAX (info->work_area_monitor.y,
-                                 work_area_monitor_y2 - info->current.height);
+          new_y = MAX (info->work_area_monitor.y,
+                       work_area_monitor_y2 - info->current.height);
         }
       else if (info->current.y < info->work_area_monitor.y)
         {
-          info->current.y = info->work_area_monitor.y;
+          new_y = info->work_area_monitor.y;
         }
+      else
+        {
+          new_y = info->current.y;
+        }
+
+      info->rel_y += new_y - info->current.y;
+      info->current.y = new_y;
     }
 
   meta_rectangle_intersect (&info->current, &info->work_area_monitor,
@@ -954,21 +993,27 @@ constrain_custom_rule (MetaWindow         *window,
   if (current_rule.constraint_adjustment &
       META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_X)
     {
-      info->current.x = intersection.x;
+      int new_x;
+      new_x = intersection.x;
       info->current.width = intersection.width;
+      info->rel_x += new_x - info->current.x;
+      info->current.x = new_x;
     }
   if (current_rule.constraint_adjustment &
       META_PLACEMENT_CONSTRAINT_ADJUSTMENT_RESIZE_Y)
     {
-      info->current.y = intersection.y;
+      int new_y;
+      new_y = intersection.y;
       info->current.height = intersection.height;
+      info->rel_y += new_y - info->current.y;
+      info->current.y = new_y;
     }
 
 done:
   window->placement.state = META_PLACEMENT_STATE_CONSTRAINED;
 
-  window->placement.current.rel_x = info->current.x - parent_rect.x;
-  window->placement.current.rel_y = info->current.y - parent_rect.y;
+  window->placement.current.rel_x = info->rel_x;
+  window->placement.current.rel_y = info->rel_y;
 
   return TRUE;
 }
diff --git a/src/core/constraints.h b/src/core/constraints.h
index 2ebefbecd..775e95dff 100644
--- a/src/core/constraints.h
+++ b/src/core/constraints.h
@@ -31,6 +31,8 @@ void meta_window_constrain (MetaWindow          *window,
                             MetaMoveResizeFlags  flags,
                             int                  resize_gravity,
                             const MetaRectangle *orig,
-                            MetaRectangle       *new);
+                            MetaRectangle       *new,
+                            int                 *rel_x,
+                            int                 *rel_y);
 
 #endif /* META_CONSTRAINTS_H */
diff --git a/src/core/window-private.h b/src/core/window-private.h
index f1daa9da6..d88f0eb2d 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -569,6 +569,8 @@ struct _MetaWindowClass
                                   int                        gravity,
                                   MetaRectangle              unconstrained_rect,
                                   MetaRectangle              constrained_rect,
+                                  int                        rel_x,
+                                  int                        rel_y,
                                   MetaMoveResizeFlags        flags,
                                   MetaMoveResizeResultFlags *result);
   gboolean (*update_struts)      (MetaWindow *window);
diff --git a/src/core/window.c b/src/core/window.c
index 4a7e2b756..612f75974 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -4001,6 +4001,8 @@ meta_window_move_resize_internal (MetaWindow          *window,
   gboolean did_placement;
   MetaRectangle unconstrained_rect;
   MetaRectangle constrained_rect;
+  int rel_x = 0;
+  int rel_y = 0;
   MetaMoveResizeResultFlags result = 0;
   gboolean moved_or_resized = FALSE;
   MetaWindowUpdateMonitorFlags update_monitor_flags;
@@ -4066,7 +4068,14 @@ meta_window_move_resize_internal (MetaWindow          *window,
                              flags,
                              gravity,
                              &old_rect,
-                             &constrained_rect);
+                             &constrained_rect,
+                             &rel_x,
+                             &rel_y);
+    }
+  else if (window->placement.rule)
+    {
+      rel_x = window->placement.current.rel_x;
+      rel_y = window->placement.current.rel_y;
     }
 
   /* If we did placement, then we need to save the position that the window
@@ -4080,7 +4089,13 @@ meta_window_move_resize_internal (MetaWindow          *window,
     }
 
   /* Do the protocol-specific move/resize logic */
-  META_WINDOW_GET_CLASS (window)->move_resize_internal (window, gravity, unconstrained_rect, 
constrained_rect, flags, &result);
+  META_WINDOW_GET_CLASS (window)->move_resize_internal (window,
+                                                        gravity,
+                                                        unconstrained_rect,
+                                                        constrained_rect,
+                                                        rel_x,
+                                                        rel_y,
+                                                        flags, &result);
 
   if (result & META_MOVE_RESIZE_RESULT_MOVED)
     {
diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c
index 9b113a6c9..cc7f66a92 100644
--- a/src/wayland/meta-window-wayland.c
+++ b/src/wayland/meta-window-wayland.c
@@ -220,6 +220,8 @@ meta_window_wayland_move_resize_internal (MetaWindow                *window,
                                           int                        gravity,
                                           MetaRectangle              unconstrained_rect,
                                           MetaRectangle              constrained_rect,
+                                          int                        rel_x,
+                                          int                        rel_y,
                                           MetaMoveResizeFlags        flags,
                                           MetaMoveResizeResultFlags *result)
 {
@@ -326,11 +328,6 @@ meta_window_wayland_move_resize_internal (MetaWindow                *window,
 
           if (window->placement.rule)
             {
-              MetaWindow *parent = meta_window_get_transient_for (window);
-              int rel_x, rel_y;
-
-              rel_x = configured_x - parent->rect.x;
-              rel_y = configured_y - parent->rect.y;
               configuration =
                 meta_wayland_window_configuration_new_relative (rel_x,
                                                                 rel_y,
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index aeaebb7c7..a546ed089 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -1308,6 +1308,8 @@ meta_window_x11_move_resize_internal (MetaWindow                *window,
                                       int                        gravity,
                                       MetaRectangle              unconstrained_rect,
                                       MetaRectangle              constrained_rect,
+                                      int                        rel_x,
+                                      int                        rel_y,
                                       MetaMoveResizeFlags        flags,
                                       MetaMoveResizeResultFlags *result)
 {


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