[mutter/wip/gbsneto/tiling-improvements: 5/9] window: Tile and resize considering the tile match
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/wip/gbsneto/tiling-improvements: 5/9] window: Tile and resize considering the tile match
- Date: Fri, 16 Jun 2017 00:46:25 +0000 (UTC)
commit c6c3c373688fd0dd70289811192d3aee2ffe6e8d
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.
!!!WARNING!!! This is work-in-progress, and is flawed. There's one
big issue with this patch, that I'm yet to fix:
Windows tiled in a complementary way in different workspaces,
if moved to the same workspace, are considered matches and enters in
an inconsistent state. Steps to reproduce:
- Open window A and B. Move B to another workspace.
- Tile A right, and B left. Resize them.
- Move B to A's workspace.
- Resize them again
https://bugzilla.gnome.org/show_bug.cgi?id=645153
src/core/window.c | 84 +++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 69 insertions(+), 15 deletions(-)
---
diff --git a/src/core/window.c b/src/core/window.c
index 99ad4db..59fe3e1 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -2893,9 +2893,16 @@ static void
meta_window_update_tile_state_internal (MetaWindow *window)
{
MetaRectangle monitor_area;
+ MetaWindow *tile_match_window;
gboolean was_tiled;
gint borders_width = 0;
+ /* When tiling a window, the new matching tile window is not yet synchronized,
+ * so we must do that now manually. It is not necessary to recompute all windows'
+ * tile matches, just the current one */
+ tile_match_window = meta_window_compute_tile_match (window, FALSE);
+ window->tile_match = tile_match_window;
+
meta_window_get_work_area_current_monitor (window, &monitor_area);
/* window->tile_rect must consider the visible borders */
@@ -2915,14 +2922,21 @@ meta_window_update_tile_state_internal (MetaWindow *window)
was_tiled = window->previous_tile_mode == META_TILE_LEFT ||
window->previous_tile_mode == META_TILE_RIGHT;
- if (window->tile_mode == META_TILE_MAXIMIZED)
- /* When maximized, cover the entire width*/
- window->tile_rect.width = monitor_area.width;
- else if (was_tiled && META_WINDOW_TILED_SIDE_BY_SIDE (window))
- window->tile_rect.width = monitor_area.width - window->tile_rect.width;
+ if (tile_match_window)
+ {
+ window->tile_rect.width = monitor_area.width - tile_match_window->tile_rect.width - borders_width;
+ }
else
- /* Assume half of the work area of the current monitor */
- window->tile_rect.width = monitor_area.width / 2 + borders_width;
+ {
+ if (window->tile_mode == META_TILE_MAXIMIZED)
+ /* When maximized, cover the entire width*/
+ window->tile_rect.width = monitor_area.width;
+ else if (was_tiled && META_WINDOW_TILED_SIDE_BY_SIDE (window))
+ window->tile_rect.width = monitor_area.width - window->tile_rect.width;
+ else
+ /* Assume half of the work area of the current monitor */
+ window->tile_rect.width = monitor_area.width / 2 + borders_width;
+ }
/* Update the horizontal position */
if (window->tile_mode == META_TILE_RIGHT)
@@ -5889,21 +5903,39 @@ update_resize_timeout (gpointer data)
}
static void
-update_tile_rect (MetaWindow *window,
- int *out_new_w)
+update_tile_rects (MetaWindow *window,
+ int *out_new_w)
{
+ MetaRectangle work_area;
+ MetaWindow *tile_match;
int new_w;
if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
return;
new_w = *out_new_w;
+ tile_match = window->tile_match;
/* Make sure the resize does not break minimum sizes */
new_w = MAX (new_w, window->size_hints.min_width);
+ meta_window_get_work_area_for_monitor (window, window->tile_monitor_number, &work_area);
+
+ if (tile_match)
+ {
+ /* If there's a tile match window, we have to make sure we're not resizing
+ * the tile match below its min width */
+ if (work_area.width - new_w < tile_match->size_hints.min_width)
+ new_w = work_area.width - tile_match->size_hints.min_width;
+
+ tile_match->tile_rect.width = work_area.width - new_w;
+ }
+
if (META_WINDOW_TILED_LEFT_RESIZING (window))
{
+ if (tile_match)
+ tile_match->tile_rect.x += new_w - window->tile_rect.width;
+
window->tile_rect.width = new_w;
}
else if (META_WINDOW_TILED_RIGHT_RESIZING (window))
@@ -5917,6 +5949,12 @@ update_tile_rect (MetaWindow *window,
*out_new_w = new_w;
}
+static gint
+opposite_gravity (guint gravity)
+{
+ return StaticGravity - gravity;
+}
+
static void
update_resize (MetaWindow *window,
gboolean snap,
@@ -6042,9 +6080,19 @@ update_resize (MetaWindow *window,
snap,
FALSE);
- update_tile_rect (window, &new_w);
+ update_tile_rects (window, &new_w);
meta_window_resize_frame_with_gravity (window, TRUE, new_w, new_h, gravity);
+ if (window->tile_match)
+ {
+ /* The tile match window's new width is stored in tile_rect.width directly */
+ meta_window_resize_frame_with_gravity (window->tile_match,
+ TRUE,
+ window->tile_match->tile_rect.width,
+ window->tile_match->tile_rect.height,
+ opposite_gravity (gravity));
+ }
+
/* Store the latest resize time, if we actually resized. */
if (window->rect.width != old.width || window->rect.height != old.height)
g_get_current_time (&window->display->grab_last_moveresize_time);
@@ -6356,16 +6404,18 @@ meta_window_get_current_tile_area (MetaWindow *window,
{
MetaRectangle monitor_area;
MetaTileMode tile_mode;
+ MetaWindow *tile_match_window;
+ gboolean preview;
gint borders_height = 0;
gint borders_width = 0;
g_return_if_fail (window->tile_mode != META_TILE_NONE || window->preview_tile_mode != META_TILE_NONE);
+ preview = window->preview_tile_mode != META_TILE_NONE;
+
/* If we are previewing, don't change the actual tile mode */
- if (window->preview_tile_mode != META_TILE_NONE)
- tile_mode = window->preview_tile_mode;
- else
- tile_mode = window->tile_mode;
+ tile_mode = preview ? window->preview_tile_mode : window->tile_mode;
+ tile_match_window = meta_window_compute_tile_match (window, preview);
meta_window_get_work_area_current_monitor (window, &monitor_area);
@@ -6387,7 +6437,11 @@ meta_window_get_current_tile_area (MetaWindow *window,
tile_area->y = monitor_area.y;
tile_area->height = monitor_area.height + borders_height;
- if (tile_mode == META_TILE_MAXIMIZED)
+ if (tile_match_window)
+ {
+ window->tile_rect.width = monitor_area.width - tile_match_window->tile_rect.width - borders_width;
+ }
+ else if (tile_mode == META_TILE_MAXIMIZED)
{
/* When maximized, cover the entire width*/
tile_area->width = monitor_area.width;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]