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
This commit is contained in:
parent
57e58eaf2a
commit
6fe71ecc01
@ -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);
|
||||
@ -7567,22 +7618,27 @@ 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
|
||||
|
Loading…
Reference in New Issue
Block a user