[mutter/wip/gbsneto/edge-constraints: 41/45] constraints: Add percentage constraint



commit d139a6798c821a6e5d18d7b4256b9dc10f218686
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Fri Aug 18 21:27:35 2017 -0300

    constraints: Add percentage constraint
    
    In the past, the tiling constraint was used to enforce
    that windows would have 50% of the workarea, even when
    the monitor changes.
    
    Now that windows can be resized when tiled, this aspect
    of the tiling constraint was lost. Its purpose, now, is
    to keep the tiled windows in the position we expect them
    to be, but now, tiled windows have a slightly mistuned
    behavior when changing monitors: they keep their widths,
    not the percentage of window covered.
    
    Fix that by adding a new percentage constraint. This new
    constraint enforces that, when windows are tiled, they
    keep the same percentage of the screen.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=645153

 src/core/constraints.c    |   77 +++++++++++++++++++++++++++++++++------------
 src/core/window-private.h |    3 ++
 src/core/window.c         |   16 +++++++++
 3 files changed, 76 insertions(+), 20 deletions(-)
---
diff --git a/src/core/constraints.c b/src/core/constraints.c
index 558e43d..a2dd085 100644
--- a/src/core/constraints.c
+++ b/src/core/constraints.c
@@ -100,6 +100,7 @@ typedef enum
   PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA = 1,
   PRIORITY_SIZE_HINTS_INCREMENTS = 1,
   PRIORITY_MAXIMIZATION = 2,
+  PRIORITY_PERCENTAGE = 2,
   PRIORITY_TILING = 2,
   PRIORITY_FULLSCREEN = 2,
   PRIORITY_SIZE_HINTS_LIMITS = 3,
@@ -160,6 +161,10 @@ static gboolean constrain_maximization       (MetaWindow         *window,
                                               ConstraintInfo     *info,
                                               ConstraintPriority  priority,
                                               gboolean            check_only);
+static gboolean constrain_percentage         (MetaWindow         *window,
+                                              ConstraintInfo     *info,
+                                              ConstraintPriority  priority,
+                                              gboolean            check_only);
 static gboolean constrain_tiling             (MetaWindow         *window,
                                               ConstraintInfo     *info,
                                               ConstraintPriority  priority,
@@ -222,6 +227,7 @@ static const Constraint all_constraints[] = {
   {constrain_custom_rule,        "constrain_custom_rule"},
   {constrain_modal_dialog,       "constrain_modal_dialog"},
   {constrain_maximization,       "constrain_maximization"},
+  {constrain_percentage,         "constrain_percentage"},
   {constrain_tiling,             "constrain_tiling"},
   {constrain_fullscreen,         "constrain_fullscreen"},
   {constrain_size_increments,    "constrain_size_increments"},
@@ -1014,10 +1020,10 @@ constrain_maximization (MetaWindow         *window,
 }
 
 static gboolean
-constrain_tiling (MetaWindow         *window,
-                  ConstraintInfo     *info,
-                  ConstraintPriority  priority,
-                  gboolean            check_only)
+constrain_percentage (MetaWindow         *window,
+                      ConstraintInfo     *info,
+                      ConstraintPriority  priority,
+                      gboolean            check_only)
 {
   MetaRectangle target_size;
   MetaRectangle min_size, max_size;
@@ -1025,22 +1031,17 @@ constrain_tiling (MetaWindow         *window,
   gboolean horiz_equal, vert_equal;
   gboolean constraint_already_satisfied;
 
-  if (priority > PRIORITY_TILING)
+  if (priority > PRIORITY_PERCENTAGE)
     return TRUE;
 
   /* Determine whether constraint applies; exit if it doesn't */
   if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
     return TRUE;
 
-  /* Calculate target_size - as the tile previews need this as well, we
-   * use an external function for the actual calculation
-   */
-  meta_window_get_tile_area_for_mode (window,
-                                      window->tile_mode,
-                                      window->tile_mode,
-                                      window->tile_monitor_number,
-                                      TRUE,
-                                      &target_size);
+  /* The percentage constraint only enforces the sizes of the window. The tiling
+   * constraint is the one that enforces the positioning. */
+  target_size.width = info->work_area_monitor.width * window->hpercentage;
+  target_size.height = info->work_area_monitor.height * window->vpercentage;
 
   /* Check min size constraints; max size constraints are ignored as for
    * maximized windows.
@@ -1052,22 +1053,19 @@ constrain_tiling (MetaWindow         *window,
     return TRUE;
 
   /* Determine whether constraint is already satisfied; exit if it is */
-  horiz_equal = target_size.x      == info->current.x &&
-                target_size.width  == info->current.width;
-  vert_equal  = target_size.y      == info->current.y &&
-                target_size.height == info->current.height;
+  horiz_equal = target_size.width  == info->current.width;
+  vert_equal  = target_size.height == info->current.height;
   constraint_already_satisfied = horiz_equal && vert_equal;
   if (check_only || constraint_already_satisfied)
     return constraint_already_satisfied;
 
   /*** Enforce constraint ***/
-  info->current.y      = target_size.y;
+  info->current.width  = target_size.width;
   info->current.height = target_size.height;
 
   return TRUE;
 }
 
-
 static gboolean
 constrain_fullscreen (MetaWindow         *window,
                       ConstraintInfo     *info,
@@ -1104,6 +1102,45 @@ constrain_fullscreen (MetaWindow         *window,
 }
 
 static gboolean
+constrain_tiling (MetaWindow         *window,
+                  ConstraintInfo     *info,
+                  ConstraintPriority  priority,
+                  gboolean            check_only)
+{
+  MetaRectangle target_size;
+  gboolean horiz_equal, vert_equal;
+  gboolean constraint_already_satisfied;
+
+  if (priority > PRIORITY_TILING)
+    return TRUE;
+
+  /* Determine whether constraint applies; exit if it doesn't */
+  if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
+    return TRUE;
+
+  /* The tiling constraint only enforces the position of the window. The percentage
+   * constraint is the one that enforces the sizing. */
+  target_size.x = info->work_area_monitor.x;
+  target_size.y = info->work_area_monitor.y;
+
+  if (window->tile_mode == META_TILE_RIGHT)
+    target_size.x += info->work_area_monitor.width - info->current.width;
+
+  /* Determine whether constraint is already satisfied; exit if it is */
+  horiz_equal = target_size.x == info->current.x;
+  vert_equal  = target_size.y == info->current.y;
+  constraint_already_satisfied = horiz_equal && vert_equal;
+  if (check_only || constraint_already_satisfied)
+    return constraint_already_satisfied;
+
+  /*** Enforce constraint ***/
+  info->current.x = target_size.x;
+  info->current.y = target_size.y;
+
+  return TRUE;
+}
+
+static gboolean
 constrain_size_increments (MetaWindow         *window,
                            ConstraintInfo     *info,
                            ConstraintPriority  priority,
diff --git a/src/core/window-private.h b/src/core/window-private.h
index ce11574..0c58675 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -213,6 +213,9 @@ struct _MetaWindow
   guint previous_tile_mode : 2;
   guint preview_tile_mode : 2;
 
+  gdouble hpercentage;
+  gdouble vpercentage;
+
   int preferred_output_winsys_id;
 
   /* Whether we're shaded */
diff --git a/src/core/window.c b/src/core/window.c
index 7ebf0ee..ba0c1b3 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -3723,6 +3723,18 @@ meta_window_update_monitor (MetaWindow *window,
     }
 }
 
+static void
+meta_window_update_percentage (MetaWindow    *window,
+                               MetaRectangle  rect)
+{
+  MetaRectangle workarea;
+
+  meta_window_get_work_area_current_monitor (window, &workarea);
+
+  window->hpercentage = rect.width / (gdouble) workarea.width;
+  window->vpercentage = rect.height / (gdouble) workarea.height;
+}
+
 void
 meta_window_move_resize_internal (MetaWindow          *window,
                                   MetaMoveResizeFlags  flags,
@@ -3771,6 +3783,8 @@ meta_window_move_resize_internal (MetaWindow          *window,
     {
       /* We're both moving and resizing. Just use the passed in rect. */
       unconstrained_rect = frame_rect;
+
+      meta_window_update_percentage (window, unconstrained_rect);
     }
   else if ((flags & META_MOVE_RESIZE_RESIZE_ACTION))
     {
@@ -3782,6 +3796,8 @@ meta_window_move_resize_internal (MetaWindow          *window,
                                           gravity,
                                           frame_rect.width,
                                           frame_rect.height);
+
+      meta_window_update_percentage (window, unconstrained_rect);
     }
   else if ((flags & META_MOVE_RESIZE_MOVE_ACTION))
     {


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