tiling: Add new "maximized" tile
In addition to the existing side-by-side tiling modes, this commit adds a new "maximize" tiling mode. It allows the user to maximize their windows (in other words, tile with the edge panels) by dragging their window to the top edge of the monitor. https://bugzilla.gnome.org/show_bug.cgi?id=630548
This commit is contained in:
parent
5f4ee1b6e7
commit
07c0471902
3 changed files with 98 additions and 22 deletions
|
@ -1758,6 +1758,7 @@ meta_screen_tile_preview_update_timeout (gpointer data)
|
|||
MetaScreen *screen = data;
|
||||
MetaWindow *window = screen->display->grab_window;
|
||||
gboolean composited = screen->display->compositor != NULL;
|
||||
gboolean needs_preview = FALSE;
|
||||
|
||||
screen->tile_preview_timeout_id = 0;
|
||||
|
||||
|
@ -1775,9 +1776,28 @@ meta_screen_tile_preview_update_timeout (gpointer data)
|
|||
create_serial);
|
||||
}
|
||||
|
||||
if (window
|
||||
&& !META_WINDOW_TILED_SIDE_BY_SIDE (window)
|
||||
&& window->tile_mode != META_TILE_NONE)
|
||||
if (window)
|
||||
{
|
||||
switch (window->tile_mode)
|
||||
{
|
||||
case META_TILE_LEFT:
|
||||
case META_TILE_RIGHT:
|
||||
if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
|
||||
needs_preview = TRUE;
|
||||
break;
|
||||
|
||||
case META_TILE_MAXIMIZED:
|
||||
if (!META_WINDOW_MAXIMIZED (window))
|
||||
needs_preview = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
needs_preview = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (needs_preview)
|
||||
{
|
||||
MetaRectangle tile_rect;
|
||||
|
||||
|
|
|
@ -64,7 +64,8 @@ typedef enum {
|
|||
typedef enum {
|
||||
META_TILE_NONE,
|
||||
META_TILE_LEFT,
|
||||
META_TILE_RIGHT
|
||||
META_TILE_RIGHT,
|
||||
META_TILE_MAXIMIZED
|
||||
} MetaTileMode;
|
||||
|
||||
struct _MetaWindow
|
||||
|
|
|
@ -3187,11 +3187,18 @@ meta_window_is_fullscreen (MetaWindow *window)
|
|||
static void
|
||||
meta_window_tile (MetaWindow *window)
|
||||
{
|
||||
MetaMaximizeFlags directions;
|
||||
|
||||
/* Don't do anything if no tiling is requested */
|
||||
if (window->tile_mode == META_TILE_NONE)
|
||||
return;
|
||||
|
||||
meta_window_maximize_internal (window, META_MAXIMIZE_VERTICAL, NULL);
|
||||
if (window->tile_mode == META_TILE_MAXIMIZED)
|
||||
directions = META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL;
|
||||
else
|
||||
directions = META_MAXIMIZE_VERTICAL;
|
||||
|
||||
meta_window_maximize_internal (window, directions, NULL);
|
||||
meta_screen_tile_preview_update (window->screen, FALSE);
|
||||
|
||||
if (window->display->compositor)
|
||||
|
@ -3249,6 +3256,18 @@ meta_window_can_tile_side_by_side (MetaWindow *window)
|
|||
tile_area.height >= window->size_hints.min_height;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_window_can_tile_maximized (MetaWindow *window)
|
||||
{
|
||||
if (!META_WINDOW_ALLOWS_RESIZE (window))
|
||||
return FALSE;
|
||||
|
||||
if (!window->has_maximize_func)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
unmaximize_window_before_freeing (MetaWindow *window)
|
||||
{
|
||||
|
@ -7799,14 +7818,13 @@ update_move (MetaWindow *window,
|
|||
shake_threshold = meta_ui_get_drag_threshold (window->screen->ui) *
|
||||
DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR;
|
||||
|
||||
if (meta_prefs_get_edge_tiling () &&
|
||||
meta_window_can_tile_side_by_side (window))
|
||||
if (meta_prefs_get_edge_tiling ())
|
||||
{
|
||||
const MetaMonitorInfo *monitor;
|
||||
MetaRectangle work_area;
|
||||
|
||||
/* For tiling we are interested in the work area of the monitor where
|
||||
* the pointer is located.
|
||||
/* For side-by-side tiling we are interested in the inside vertical
|
||||
* edges of the work area of the monitor where the pointer is located.
|
||||
* Also see comment in meta_window_get_current_tile_area()
|
||||
*/
|
||||
monitor = meta_screen_get_current_monitor (window->screen);
|
||||
|
@ -7814,17 +7832,38 @@ update_move (MetaWindow *window,
|
|||
monitor->number,
|
||||
&work_area);
|
||||
|
||||
if (y >= monitor->rect.y &&
|
||||
y < (monitor->rect.y + monitor->rect.height))
|
||||
if (meta_window_can_tile_side_by_side (window))
|
||||
{
|
||||
/* check if cursor is near an edge of the work area */
|
||||
if (x >= monitor->rect.x && x < (work_area.x + shake_threshold))
|
||||
window->tile_mode = META_TILE_LEFT;
|
||||
else if (x >= work_area.x + work_area.width - shake_threshold &&
|
||||
x < (monitor->rect.x + monitor->rect.width))
|
||||
window->tile_mode = META_TILE_RIGHT;
|
||||
else
|
||||
window->tile_mode = META_TILE_NONE;
|
||||
if (y >= monitor->rect.y &&
|
||||
y < (monitor->rect.y + monitor->rect.height))
|
||||
{
|
||||
/* check if cursor is near an edge of the work area */
|
||||
if (x >= monitor->rect.x && x < (work_area.x + shake_threshold))
|
||||
window->tile_mode = META_TILE_LEFT;
|
||||
else if (x >= work_area.x + work_area.width - shake_threshold &&
|
||||
x < (monitor->rect.x + monitor->rect.width))
|
||||
window->tile_mode = META_TILE_RIGHT;
|
||||
else
|
||||
window->tile_mode = META_TILE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/* For maximized tiling we are interested in the outside top edge
|
||||
* of the work area of the monitor where the pointer is located.
|
||||
*
|
||||
* We use the outside edge instead of the inside edge, because we
|
||||
* don't want to force users to maximize windows they are placing
|
||||
* near the top of their screens.
|
||||
*/
|
||||
if (meta_window_can_tile_maximized (window))
|
||||
{
|
||||
if (x >= monitor->rect.x &&
|
||||
x < (monitor->rect.x + monitor->rect.width))
|
||||
{
|
||||
/* check if cursor is on the top edge of the monitor*/
|
||||
if (y >= monitor->rect.y && y < work_area.y)
|
||||
window->tile_mode = META_TILE_MAXIMIZED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7872,12 +7911,13 @@ update_move (MetaWindow *window,
|
|||
* loose or it is still maximized (then move straight)
|
||||
*/
|
||||
else if ((window->shaken_loose || META_WINDOW_MAXIMIZED (window)) &&
|
||||
window->tile_mode == META_TILE_NONE)
|
||||
window->tile_mode != META_TILE_LEFT && window->tile_mode != META_TILE_RIGHT)
|
||||
{
|
||||
const MetaMonitorInfo *wmonitor;
|
||||
MetaRectangle work_area;
|
||||
int monitor;
|
||||
|
||||
window->tile_mode = META_TILE_NONE;
|
||||
wmonitor = meta_screen_get_monitor_for_window (window->screen, window);
|
||||
|
||||
for (monitor = 0; monitor < window->screen->n_monitor_infos; monitor++)
|
||||
|
@ -8372,6 +8412,22 @@ check_use_this_motion_notify (MetaWindow *window,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_tile_mode (MetaWindow *window)
|
||||
{
|
||||
switch (window->tile_mode)
|
||||
{
|
||||
case META_TILE_LEFT:
|
||||
case META_TILE_RIGHT:
|
||||
if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
|
||||
window->tile_mode = META_TILE_NONE;
|
||||
case META_TILE_MAXIMIZED:
|
||||
if (!META_WINDOW_MAXIMIZED (window))
|
||||
window->tile_mode = META_TILE_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
||||
XEvent *event)
|
||||
|
@ -8464,8 +8520,7 @@ meta_window_handle_mouse_grab_op_event (MetaWindow *window,
|
|||
* would break the ability to snap back to the tiled
|
||||
* state, so we wait until mouse release.
|
||||
*/
|
||||
if (!META_WINDOW_TILED_SIDE_BY_SIDE (window))
|
||||
window->tile_mode = META_TILE_NONE;
|
||||
update_tile_mode (window);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue