From b471b912d68a05711a95a3c0e033c0577262f18e Mon Sep 17 00:00:00 2001 From: Omar Zeidan Date: Sat, 2 Dec 2017 20:19:12 +0100 Subject: Implemented simple corner tiling by mouse drag --- src/core/constraints.c | 8 ++-- src/core/display-private.h | 6 ++- src/core/keybindings.c | 4 +- src/core/screen.c | 26 +++++------ src/core/window-private.h | 16 ++++--- src/core/window.c | 110 ++++++++++++++++++++++++++++++++++----------- 6 files changed, 121 insertions(+), 49 deletions(-) diff --git a/src/core/constraints.c b/src/core/constraints.c index 99b0aefa..512e6404 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -795,7 +795,7 @@ constrain_maximization (MetaWindow *window, /* Determine whether constraint applies; exit if it doesn't */ if ((!window->maximized_horizontally && !window->maximized_vertically) || - META_WINDOW_TILED (window)) + META_WINDOW_SIDE_TILED (window)) return TRUE; /* Calculate target_size = maximized size of (window + frame) */ @@ -882,7 +882,7 @@ constrain_tiling (MetaWindow *window, return TRUE; /* Determine whether constraint applies; exit if it doesn't */ - if (!META_WINDOW_TILED (window)) + if (!META_WINDOW_SIDE_TILED (window)) return TRUE; /* Calculate target_size - as the tile previews need this as well, we @@ -1003,7 +1003,7 @@ constrain_size_increments (MetaWindow *window, /* Determine whether constraint applies; exit if it doesn't */ if (META_WINDOW_MAXIMIZED (window) || window->fullscreen || - META_WINDOW_TILED (window) || info->action_type == ACTION_MOVE) + META_WINDOW_SIDE_TILED (window) || info->action_type == ACTION_MOVE) return TRUE; /* Determine whether constraint is already satisfied; exit if it is */ @@ -1134,7 +1134,7 @@ constrain_aspect_ratio (MetaWindow *window, constraints_are_inconsistent = minr > maxr; if (constraints_are_inconsistent || META_WINDOW_MAXIMIZED (window) || window->fullscreen || - META_WINDOW_TILED (window) || info->action_type == ACTION_MOVE) + META_WINDOW_SIDE_TILED (window) || info->action_type == ACTION_MOVE) return TRUE; /* Determine whether constraint is already satisfied; exit if it is. We diff --git a/src/core/display-private.h b/src/core/display-private.h index 069e0ccf..fe8b948e 100644 --- a/src/core/display-private.h +++ b/src/core/display-private.h @@ -71,7 +71,11 @@ typedef enum { META_TILE_NONE, META_TILE_LEFT, META_TILE_RIGHT, - META_TILE_MAXIMIZED /* only used for previews */ + META_TILE_MAXIMIZED, /* only used for previews */ + META_TILE_TOP_LEFT, + META_TILE_TOP_RIGHT, + META_TILE_BOTTOM_LEFT, + META_TILE_BOTTOM_RIGHT } MetaTileMode; struct _MetaDisplay { diff --git a/src/core/keybindings.c b/src/core/keybindings.c index fd17b49d..8006c9e1 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1457,7 +1457,9 @@ process_mouse_move_resize_grab (MetaDisplay *display, meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL | META_MAXIMIZE_VERTICAL); - else if (window->tile_mode == META_TILE_LEFT || window->tile_mode == META_TILE_RIGHT) + else if (window->tile_mode == META_TILE_LEFT || + window->tile_mode == META_TILE_RIGHT|| + META_WINDOW_QUARTER_TILED(window)) meta_window_tile (window); else if (!display->grab_wireframe_active) meta_window_move_resize (display->grab_window, diff --git a/src/core/screen.c b/src/core/screen.c index 28d2febf..f0ce5dff 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -1495,21 +1495,21 @@ meta_screen_tile_preview_update_timeout (gpointer data) if (window) { switch (window->tile_mode) - { - case META_TILE_LEFT: - case META_TILE_RIGHT: - if (!META_WINDOW_TILED (window)) - needs_preview = TRUE; - break; + { + case META_TILE_MAXIMIZED: + if (!META_WINDOW_MAXIMIZED (window)) + needs_preview = TRUE; + break; + + case META_TILE_NONE: + needs_preview = FALSE; + break; - case META_TILE_MAXIMIZED: - if (!META_WINDOW_MAXIMIZED (window)) - needs_preview = TRUE; - break; + default: + if (!META_WINDOW_SIDE_TILED (window)) + needs_preview = TRUE; + break; - default: - needs_preview = FALSE; - break; } } diff --git a/src/core/window-private.h b/src/core/window-private.h index e775a59e..8ab35718 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -145,7 +145,7 @@ struct _MetaWindow /* The current or requested tile mode. If maximized_vertically is true, * this is the current mode. If not, it is the mode which will be * requested after the window grab is released */ - guint tile_mode : 2; + guint tile_mode : 3; guint tile_resized : 1; /* The last "full" maximized/unmaximized state. We need to keep track of @@ -401,20 +401,26 @@ struct _MetaWindow (w)->maximized_vertically) #define META_WINDOW_MAXIMIZED_VERTICALLY(w) ((w)->maximized_vertically) #define META_WINDOW_MAXIMIZED_HORIZONTALLY(w) ((w)->maximized_horizontally) -#define META_WINDOW_TILED(w) ((w)->maximized_vertically && \ +#define META_WINDOW_SIDE_TILED(w) ((w)->maximized_vertically && \ !(w)->maximized_horizontally && \ (w)->tile_mode != META_TILE_NONE) -#define META_WINDOW_TILED_LEFT(w) (META_WINDOW_TILED(w) && \ +#define META_WINDOW_TILED_LEFT(w) (META_WINDOW_SIDE_TILED(w) && \ (w)->tile_mode == META_TILE_LEFT) -#define META_WINDOW_TILED_RIGHT(w) (META_WINDOW_TILED(w) && \ +#define META_WINDOW_TILED_RIGHT(w) (META_WINDOW_SIDE_TILED(w) && \ (w)->tile_mode == META_TILE_RIGHT) +#define META_WINDOW_QUARTER_TILED(w) (!(w)->maximized_vertically && \ + !(w)->maximized_horizontally && \ + ((w)->tile_mode == META_TILE_BOTTOM_RIGHT || \ + (w)->tile_mode == META_TILE_BOTTOM_LEFT || \ + (w)->tile_mode == META_TILE_TOP_RIGHT || \ + (w)->tile_mode == META_TILE_TOP_LEFT)) #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) && !(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))) #define META_WINDOW_ALLOWS_HORIZONTAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && (w)->size_hints.min_width < (w)->size_hints.max_width) -#define META_WINDOW_ALLOWS_VERTICAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && !META_WINDOW_TILED(w) && (w)->size_hints.min_height < (w)->size_hints.max_height) +#define META_WINDOW_ALLOWS_VERTICAL_RESIZE(w) (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) && !META_WINDOW_SIDE_TILED(w) && (w)->size_hints.min_height < (w)->size_hints.max_height) MetaWindow* meta_window_new (MetaDisplay *display, Window xwindow, diff --git a/src/core/window.c b/src/core/window.c index 546600dd..8a613dea 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -106,6 +106,16 @@ static void update_resize (MetaWindow *window, int x, int y, gboolean force); + +static MetaTileMode calculate_tiling_mode(int x, + int y, + MetaWindow *window, + const MetaXineramaScreenInfo *monitor, + MetaRectangle work_area, + int shake_threshold); + + + static gboolean update_resize_timeout (gpointer data); @@ -2509,7 +2519,8 @@ ensure_size_hints_satisfied (MetaRectangle *rect, static void meta_window_save_rect (MetaWindow *window) { - if (!(META_WINDOW_MAXIMIZED (window) || META_WINDOW_TILED (window) || window->fullscreen)) + if (!(META_WINDOW_MAXIMIZED (window) || META_WINDOW_SIDE_TILED (window) || + META_WINDOW_QUARTER_TILED(window) || window->fullscreen)) { /* save size/pos as appropriate args for move_resize */ if (!window->maximized_horizontally) @@ -2551,7 +2562,7 @@ force_save_user_window_placement (MetaWindow *window) static void save_user_window_placement (MetaWindow *window) { - if (!(META_WINDOW_MAXIMIZED (window) || META_WINDOW_TILED (window) || window->fullscreen)) + if (!(META_WINDOW_MAXIMIZED (window) || META_WINDOW_SIDE_TILED (window) || window->fullscreen)) { MetaRectangle user_rect; @@ -2709,6 +2720,7 @@ meta_window_tile (MetaWindow *window) return; meta_window_maximize_internal (window, META_MAXIMIZE_VERTICAL, NULL); + /* move_resize with new tiling constraints */ @@ -6997,7 +7009,7 @@ update_move (MetaWindow *window, shake_threshold = meta_ui_get_drag_threshold (window->screen->ui) * DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR; - + if (snap) { /* We don't want to tile while snapping. Also, clear any previous tile @@ -7007,7 +7019,7 @@ update_move (MetaWindow *window, } else if (meta_prefs_get_side_by_side_tiling () && !META_WINDOW_MAXIMIZED (window) && - !META_WINDOW_TILED (window)) + !META_WINDOW_SIDE_TILED (window)) { const MetaXineramaScreenInfo *monitor; MetaRectangle work_area; @@ -7034,18 +7046,9 @@ update_move (MetaWindow *window, * and set tile_mode accordingly. */ MetaTileMode tile_mode = window->tile_mode; - if (meta_window_can_tile (window) && - x >= monitor->rect.x && x < (work_area.x + shake_threshold)) - window->tile_mode = META_TILE_LEFT; - else if (meta_window_can_tile (window) && - x >= work_area.x + work_area.width - shake_threshold && - x < (monitor->rect.x + monitor->rect.width)) - window->tile_mode = META_TILE_RIGHT; - else if (meta_window_can_tile_maximized (window) && - y >= monitor->rect.y && y <= work_area.y) - window->tile_mode = META_TILE_MAXIMIZED; - else - window->tile_mode = META_TILE_NONE; + window->tile_mode = calculate_tiling_mode(x, y, window, monitor, + work_area, shake_threshold); + if (window->tile_mode != META_TILE_NONE) window->tile_monitor_number = monitor->number; @@ -7053,7 +7056,7 @@ update_move (MetaWindow *window, /* Reset resized flag when changing tile mode */ if (tile_mode != window->tile_mode) window->tile_resized = FALSE; - } + } /* shake loose (unmaximize) maximized or tiled window if dragged beyond * the threshold in the Y direction. Tiled windows can also be pulled @@ -7061,7 +7064,7 @@ update_move (MetaWindow *window, */ if ((META_WINDOW_MAXIMIZED (window) && ABS (dy) >= shake_threshold) || - (META_WINDOW_TILED (window) && (MAX (ABS (dx), ABS (dy)) >= shake_threshold))) + (META_WINDOW_SIDE_TILED (window) && (MAX (ABS (dx), ABS (dy)) >= shake_threshold))) { double prop; @@ -7113,8 +7116,8 @@ update_move (MetaWindow *window, meta_window_get_work_area_for_xinerama (window, monitor, &work_area); /* check if cursor is near the top of a xinerama work area */ - if (x >= work_area.x && - x < (work_area.x + work_area.width) && + if (x >= work_area.x + shake_threshold && + x < (work_area.x + work_area.width - shake_threshold) && y >= work_area.y && y < (work_area.y + shake_threshold)) { @@ -7156,10 +7159,13 @@ update_move (MetaWindow *window, } } + + /* Delay showing the tile preview slightly to make it more unlikely to * trigger it unwittingly, e.g. when shaking loose the window or moving * it to another monitor. */ + meta_screen_tile_preview_update (window->screen, window->tile_mode != META_TILE_NONE); @@ -7169,7 +7175,7 @@ update_move (MetaWindow *window, meta_window_get_client_root_coords (window, &old); /* Don't allow movement in the maximized directions or while tiled */ - if (window->maximized_horizontally || META_WINDOW_TILED (window)) + if (window->maximized_horizontally || META_WINDOW_SIDE_TILED (window)) new_x = old.x; if (window->maximized_vertically) new_y = old.y; @@ -7201,6 +7207,48 @@ update_move (MetaWindow *window, meta_window_move (window, TRUE, new_x, new_y); } + +static MetaTileMode calculate_tiling_mode(int x, + int y, + MetaWindow *window, + const MetaXineramaScreenInfo *monitor, + MetaRectangle work_area, + int shake_threshold) +{ + if (meta_window_can_tile (window) && + x >= monitor->rect.x + && x < (work_area.x + shake_threshold)) + { + if(y >= monitor->rect.y && y < work_area.y + shake_threshold) + return META_TILE_TOP_LEFT; + else if(y < monitor->rect.y + monitor->rect.height + && y > work_area.y + work_area.height - shake_threshold) + return META_TILE_BOTTOM_LEFT; + else + return META_TILE_LEFT; + } + + else if (meta_window_can_tile (window) && + x >= work_area.x + work_area.width - shake_threshold && + x < (monitor->rect.x + monitor->rect.width)) + { + if(y >= monitor->rect.y && y < work_area.y + shake_threshold) + return META_TILE_TOP_RIGHT; + else if(y < monitor->rect.y + monitor->rect.height + && y > work_area.y + work_area.height - shake_threshold) + return META_TILE_BOTTOM_RIGHT; + else + return META_TILE_RIGHT; + } + else if (meta_window_can_tile_maximized (window) && + y >= monitor->rect.y && y <= work_area.y) + return META_TILE_MAXIMIZED; + else + return META_TILE_NONE; + +} + + static gboolean update_resize_timeout (gpointer data) { @@ -7524,7 +7572,7 @@ update_tile_mode (MetaWindow *window) { case META_TILE_LEFT: case META_TILE_RIGHT: - if (!META_WINDOW_TILED (window)) + if (!META_WINDOW_SIDE_TILED (window)) window->tile_mode = META_TILE_NONE; break; } @@ -7803,12 +7851,24 @@ meta_window_get_current_tile_area (MetaWindow *window, meta_window_get_work_area_for_xinerama (window, tile_monitor_number, tile_area); - if (window->tile_mode == META_TILE_LEFT || - window->tile_mode == META_TILE_RIGHT) + if (window->tile_mode != META_TILE_NONE && + window->tile_mode != META_TILE_MAXIMIZED) tile_area->width /= 2; - if (window->tile_mode == META_TILE_RIGHT) + if(window->tile_mode == META_TILE_BOTTOM_LEFT || + window->tile_mode == META_TILE_BOTTOM_RIGHT || + window->tile_mode == META_TILE_TOP_LEFT || + window->tile_mode == META_TILE_TOP_RIGHT) + tile_area->height /= 2; + + if (window->tile_mode == META_TILE_RIGHT || + window->tile_mode == META_TILE_TOP_RIGHT || + window->tile_mode == META_TILE_BOTTOM_RIGHT) tile_area->x += tile_area->width; + + if(window->tile_mode == META_TILE_BOTTOM_LEFT || + window->tile_mode == META_TILE_BOTTOM_RIGHT) + tile_area->y += tile_area->height; } gboolean -- cgit v1.2.1