[mutter/wip/fmuellner/contraint-tiling: 7/14] window: Tile and resize considering the tile match
- From: Florian Müllner <fmuellner src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/fmuellner/contraint-tiling: 7/14] window: Tile and resize considering the tile match
- Date: Tue, 3 Oct 2017 19:29:12 +0000 (UTC)
commit cfb5ee046d9c4b982d29543cae90f4beda431bc0
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Sun Jun 11 22:13:03 2017 -0300
window: Tile and resize considering the tile match
After the introduction of the possibility to resize tiled windows,
it is a sensible decision to make windows aware of their tiling
match. A tiling match is another window that is tiled in such a
way that is the complement of the current window.
The newly introduced behavior attepts to make tiling as smooth as
possible, with the following rules:
* Windows now compute their tile match when tiling and, if there's
a match, they automatically complement the sibling's width.
* Resizing a window with a sibling automatically resizes the sibling
too to be the complement of the window's width.
* It is not possible to resize below windows' minimum widths.
https://bugzilla.gnome.org/show_bug.cgi?id=645153
src/core/window.c | 78 +++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 67 insertions(+), 11 deletions(-)
---
diff --git a/src/core/window.c b/src/core/window.c
index 9aa962c..e34f459 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -133,6 +133,9 @@ static void set_workspace_state (MetaWindow *window,
gboolean on_all_workspaces,
MetaWorkspace *workspace);
+static MetaWindow * meta_window_find_tile_match (MetaWindow *window,
+ MetaTileMode mode);
+
/* Idle handlers for the three queues (run with meta_later_add()). The
* "data" parameter in each case will be a GINT_TO_POINTER of the
* index into the queue arrays to use.
@@ -2974,10 +2977,19 @@ meta_window_get_tile_fraction (MetaWindow *window,
MetaTileMode tile_mode,
double *fraction)
{
+ MetaWindow *tile_match;
+
+ /* Make sure the tile match is up-to-date and matches the
+ * passed in mode rather than the current state
+ */
+ tile_match = meta_window_find_tile_match (window, tile_mode);
+
if (tile_mode == META_TILE_NONE)
*fraction = -1.;
else if (tile_mode == META_TILE_MAXIMIZED)
*fraction = 1.;
+ else if (tile_match)
+ *fraction = 1. - tile_match->tile_hfraction;
else if (META_WINDOW_TILED_SIDE_BY_SIDE (window))
{
if (window->tile_mode != tile_mode)
@@ -2994,6 +3006,7 @@ meta_window_update_tile_fraction (MetaWindow *window,
int new_w,
int new_h)
{
+ MetaWindow *tile_match = window->tile_match;
MetaRectangle work_area;
if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
@@ -3003,6 +3016,9 @@ meta_window_update_tile_fraction (MetaWindow *window,
window->tile_monitor_number,
&work_area);
window->tile_hfraction = (double)new_w / work_area.width;
+
+ if (tile_match && window->display->grab_window == window)
+ meta_window_tile (tile_match, tile_match->tile_mode);
}
void
@@ -4061,6 +4077,34 @@ meta_window_move_to_monitor (MetaWindow *window,
meta_screen_queue_check_fullscreen (window->screen);
}
+static void
+adjust_size_for_tile_match (MetaWindow *window,
+ int *new_w,
+ int *new_h)
+{
+ MetaRectangle work_area, rect;
+ MetaWindow *tile_match = window->tile_match;
+
+ if (!META_WINDOW_TILED_SIDE_BY_SIDE (window) || !tile_match)
+ return;
+
+ meta_window_get_work_area_for_monitor (window, window->tile_monitor_number, &work_area);
+
+ /* Make sure the resize does not break minimum sizes */
+ rect = work_area;
+ rect.width = *new_w;
+
+ meta_window_frame_rect_to_client_rect (window, &rect, &rect);
+ *new_w += MAX(0, window->size_hints.min_width - rect.width);
+
+ /* Make sure we're not resizing the tile match below its min width */
+ rect = work_area;
+ rect.width = work_area.width - *new_w;
+
+ meta_window_frame_rect_to_client_rect (tile_match, &rect, &rect);
+ *new_w -= MAX(0, tile_match->size_hints.min_width - rect.width);
+}
+
void
meta_window_resize_frame_with_gravity (MetaWindow *window,
gboolean user_op,
@@ -4075,7 +4119,14 @@ meta_window_resize_frame_with_gravity (MetaWindow *window,
rect.height = h;
if (user_op)
- meta_window_update_tile_fraction (window, w, h);
+ {
+ /* When resizing in-tandem with a tile match, we need to respect
+ * its minimum width
+ */
+ if (window->display->grab_window == window)
+ adjust_size_for_tile_match (window, &w, &h);
+ 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);
@@ -7568,21 +7619,26 @@ meta_window_get_tile_match (MetaWindow *window)
void
meta_window_compute_tile_match (MetaWindow *window)
{
+ window->tile_match = meta_window_find_tile_match (window, window->tile_mode);
+}
+
+static MetaWindow *
+meta_window_find_tile_match (MetaWindow *window,
+ MetaTileMode current_mode)
+{
MetaWindow *match;
MetaStack *stack;
MetaTileMode match_tile_mode = META_TILE_NONE;
- window->tile_match = NULL;
-
if (window->shaded || window->minimized)
- return;
+ return NULL;
- if (META_WINDOW_TILED_LEFT (window))
+ if (current_mode == META_TILE_LEFT)
match_tile_mode = META_TILE_RIGHT;
- else if (META_WINDOW_TILED_RIGHT (window))
+ else if (current_mode == META_TILE_RIGHT)
match_tile_mode = META_TILE_LEFT;
else
- return;
+ return NULL;
stack = window->screen->stack;
@@ -7593,7 +7649,7 @@ meta_window_compute_tile_match (MetaWindow *window)
if (!match->shaded &&
!match->minimized &&
match->tile_mode == match_tile_mode &&
- match->monitor == window->monitor &&
+ match->tile_monitor_number == window->tile_monitor_number &&
meta_window_get_workspace (match) == meta_window_get_workspace (window))
break;
}
@@ -7633,11 +7689,11 @@ meta_window_compute_tile_match (MetaWindow *window)
if (meta_rectangle_overlap (&above_rect, &bottommost_rect) &&
meta_rectangle_overlap (&above_rect, &topmost_rect))
- return;
+ return NULL;
}
-
- window->tile_match = match;
}
+
+ return match;
}
void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]