[mutter/wip/fmuellner/contraint-tiling: 5/14] window: Allow resizing of tiled windows



commit ff34e518263024f57dbd64bd9f9780f183f7df2d
Author: Florian Müllner <fmuellner gnome org>
Date:   Wed Sep 27 14:37:57 2017 +0200

    window: Allow resizing of tiled windows
    
    Currently tiled windows are not resizable and their size is fixed
    to half the screen width. Adjust the code to work with fractions
    other than half, and allow users to adjust the split by dragging
    the window edge that is not constrained by a monitor edge.
    
    Follow-up patches will improve on that by resizing neighboring
    tiled windows by a shared edge, and making the functionality
    available to client-side decorated windows implementing the
    new edge constraints protocol.

 src/core/keybindings.c    |    5 +++-
 src/core/window-private.h |    8 +++++-
 src/core/window.c         |   62 ++++++++++++++++++++++++++++++++++++++++++---
 src/ui/frames.c           |    7 +++-
 4 files changed, 74 insertions(+), 8 deletions(-)
---
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index ef36cff..f2ef076 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -2239,7 +2239,10 @@ process_mouse_move_resize_grab (MetaDisplay     *display,
       if (window->shaken_loose || tile_mode == META_TILE_MAXIMIZED)
         meta_window_maximize (window, META_MAXIMIZE_BOTH);
       else if (tile_mode != META_TILE_NONE)
-        meta_window_tile (window, tile_mode);
+        meta_window_restore_tile (window,
+                                  tile_mode,
+                                  display->grab_initial_window_pos.width,
+                                  display->grab_initial_window_pos.height);
       else
         meta_window_move_resize_frame (display->grab_window,
                                        TRUE,
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 443bcf4..a4b03ea 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -207,6 +207,8 @@ struct _MetaWindow
   int tile_monitor_number;
   int preferred_output_winsys_id;
 
+  double tile_hfraction;
+
   /* Whether we're shaded */
   guint shaded : 1;
 
@@ -557,7 +559,7 @@ struct _MetaWindowClass
 #define META_WINDOW_TILED_MAXIMIZED(w)(META_WINDOW_MAXIMIZED(w) && \
                                        (w)->tile_mode == META_TILE_MAXIMIZED)
 #define META_WINDOW_ALLOWS_MOVE(w)     ((w)->has_move_func && !(w)->fullscreen)
-#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w)   ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && 
!META_WINDOW_TILED_SIDE_BY_SIDE(w) && !(w)->fullscreen && !(w)->shaded)
+#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w)   ((w)->has_resize_func && !META_WINDOW_MAXIMIZED (w) && 
!(w)->fullscreen && !(w)->shaded)
 #define META_WINDOW_ALLOWS_RESIZE(w)   (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) &&                \
                                         (((w)->size_hints.min_width < (w)->size_hints.max_width) ||  \
                                          ((w)->size_hints.min_height < (w)->size_hints.max_height)))
@@ -579,6 +581,10 @@ void        meta_window_queue              (MetaWindow  *window,
                                             guint queuebits);
 void        meta_window_tile               (MetaWindow        *window,
                                             MetaTileMode       mode);
+void        meta_window_restore_tile       (MetaWindow        *window,
+                                            MetaTileMode       mode,
+                                            int                width,
+                                            int                height);
 void        meta_window_maximize_internal  (MetaWindow        *window,
                                             MetaMaximizeFlags  directions,
                                             MetaRectangle     *saved_rect);
diff --git a/src/core/window.c b/src/core/window.c
index d4fb404..09f6fd3 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -1017,6 +1017,7 @@ _meta_window_shared_new (MetaDisplay         *display,
   window->on_all_workspaces_requested = FALSE;
   window->tile_mode = META_TILE_NONE;
   window->tile_monitor_number = -1;
+  window->tile_hfraction = -1.;
   window->shaded = FALSE;
   window->initially_iconic = FALSE;
   window->minimized = FALSE;
@@ -2968,6 +2969,42 @@ meta_window_requested_dont_bypass_compositor (MetaWindow *window)
   return window->bypass_compositor == _NET_WM_BYPASS_COMPOSITOR_HINT_OFF;
 }
 
+static void
+meta_window_get_tile_fraction (MetaWindow   *window,
+                               MetaTileMode  tile_mode,
+                               double       *fraction)
+{
+  if (tile_mode == META_TILE_NONE)
+    *fraction = -1.;
+  else if (tile_mode == META_TILE_MAXIMIZED)
+    *fraction = 1.;
+  else if (META_WINDOW_TILED_SIDE_BY_SIDE (window))
+    {
+      if (window->tile_mode != tile_mode)
+        *fraction = 1. - window->tile_hfraction;
+      else
+        *fraction = window->tile_hfraction;
+    }
+  else
+    *fraction = .5;
+}
+
+static void
+meta_window_update_tile_fraction (MetaWindow *window,
+                                  int         new_w,
+                                  int         new_h)
+{
+  MetaRectangle work_area;
+
+  if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
+    return;
+
+  meta_window_get_work_area_for_monitor (window,
+                                         window->tile_monitor_number,
+                                         &work_area);
+  window->tile_hfraction = (double)new_w / work_area.width;
+}
+
 void
 meta_window_tile (MetaWindow   *window,
                   MetaTileMode  tile_mode)
@@ -2975,6 +3012,7 @@ meta_window_tile (MetaWindow   *window,
   MetaMaximizeFlags directions;
   MetaRectangle old_frame_rect, old_buffer_rect;
 
+  meta_window_get_tile_fraction (window, tile_mode, &window->tile_hfraction);
   window->tile_mode = tile_mode;
 
   /* Don't do anything if no tiling is requested */
@@ -3007,6 +3045,16 @@ meta_window_tile (MetaWindow   *window,
     meta_frame_queue_draw (window->frame);
 }
 
+void
+meta_window_restore_tile (MetaWindow   *window,
+                          MetaTileMode  mode,
+                          int           width,
+                          int           height)
+{
+  meta_window_update_tile_fraction (window, width, height);
+  meta_window_tile (window, mode);
+}
+
 static gboolean
 meta_window_can_tile_maximized (MetaWindow *window)
 {
@@ -4026,6 +4074,9 @@ meta_window_resize_frame_with_gravity (MetaWindow *window,
   rect.width = w;
   rect.height = h;
 
+  if (user_op)
+    meta_window_update_tile_fraction (window, w, h);
+
   flags = (user_op ? META_MOVE_RESIZE_USER_ACTION : 0) | META_MOVE_RESIZE_RESIZE_ACTION;
   meta_window_move_resize_internal (window, flags, gravity, rect);
 }
@@ -6349,19 +6400,22 @@ meta_window_get_tile_area (MetaWindow    *window,
                            MetaTileMode   tile_mode,
                            MetaRectangle *tile_area)
 {
+  MetaRectangle work_area;
   int tile_monitor_number;
+  double fraction;
 
   g_return_if_fail (tile_mode != META_TILE_NONE);
 
   tile_monitor_number = meta_window_get_current_tile_monitor_number (window);
 
-  meta_window_get_work_area_for_monitor (window, tile_monitor_number, tile_area);
+  meta_window_get_work_area_for_monitor (window, tile_monitor_number, &work_area);
+  meta_window_get_tile_fraction (window, tile_mode, &fraction);
 
-  if (tile_mode == META_TILE_LEFT  || tile_mode == META_TILE_RIGHT)
-    tile_area->width /= 2;
+  *tile_area = work_area;
+  tile_area->width = round (tile_area->width * fraction);
 
   if (tile_mode == META_TILE_RIGHT)
-    tile_area->x += tile_area->width;
+    tile_area->x += work_area.width - tile_area->width;
 }
 
 gboolean
diff --git a/src/ui/frames.c b/src/ui/frames.c
index 2d86254..129a9e5 100644
--- a/src/ui/frames.c
+++ b/src/ui/frames.c
@@ -1621,6 +1621,9 @@ get_control (MetaUIFrame *frame, int root_x, int root_y)
   has_vert = (flags & META_FRAME_ALLOWS_VERTICAL_RESIZE) != 0;
   has_horiz = (flags & META_FRAME_ALLOWS_HORIZONTAL_RESIZE) != 0;
 
+  if (flags & META_FRAME_TILED_LEFT || flags & META_FRAME_TILED_RIGHT)
+    has_vert = has_horiz = FALSE;
+
   if (POINT_IN_RECT (x, y, fgeom.title_rect))
     {
       if (has_vert && y <= TOP_RESIZE_HEIGHT && has_north_resize)
@@ -1693,12 +1696,12 @@ get_control (MetaUIFrame *frame, int root_x, int root_y)
     }
   else if (x <= fgeom.borders.total.left)
     {
-      if (has_horiz)
+      if (has_horiz || flags & META_FRAME_TILED_RIGHT)
         return META_FRAME_CONTROL_RESIZE_W;
     }
   else if (x >= (fgeom.width - fgeom.borders.total.right))
     {
-      if (has_horiz)
+      if (has_horiz || flags & META_FRAME_TILED_LEFT)
         return META_FRAME_CONTROL_RESIZE_E;
     }
 


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