From ae80350494d7e0756ab51191092db4347defa030 Mon Sep 17 00:00:00 2001 From: Victor Kareh Date: Mon, 28 Oct 2019 12:12:43 -0400 Subject: window: Add optional tile size cycling Adding a new option to allow tile size cycling. When enabled, using the keyboard shortcut for tiling multiple times in a row cycles the window through different sizes (1/2 -> 1/3 -> 1/4 -> 3/4 -> 2/3 -> Untiled). --- src/core/keybindings.c | 50 ++++++++++++++++++++++++++++++++++++++- src/core/prefs.c | 16 +++++++++++++ src/core/window-private.h | 10 ++++++++ src/core/window.c | 53 ++++++++++++++++++++++++++++++++---------- src/include/prefs.h | 2 ++ src/org.mate.marco.gschema.xml | 5 ++++ 6 files changed, 123 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/core/keybindings.c b/src/core/keybindings.c index e94d1824..e9597340 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -3161,15 +3161,63 @@ handle_toggle_tiled (MetaDisplay *display, MetaKeyBinding *binding) { MetaTileMode mode = binding->handler->data; + MetaTileCycle next_cycle; - if (mode == window->tile_mode && META_WINDOW_TILED(window)) + /* Check if we're cycling through tile ratios */ + if (meta_prefs_get_allow_tile_cycling ()) + { + if (window->tile_mode != mode) + { + /* If changing tile mode, reset to first tile size */ + next_cycle = META_TILE_CYCLE_50; + } + else + { + /* Cycle through the different tile sizes: 1/2 -> 1/3 -> 1/4 -> 3/4 -> 2/3 -> Untiled */ + switch (window->tile_cycle) + { + case META_TILE_CYCLE_NONE: + next_cycle = META_TILE_CYCLE_50; + break; + case META_TILE_CYCLE_50: + next_cycle = META_TILE_CYCLE_33; + break; + case META_TILE_CYCLE_33: + next_cycle = META_TILE_CYCLE_25; + break; + case META_TILE_CYCLE_25: + next_cycle = META_TILE_CYCLE_75; + break; + case META_TILE_CYCLE_75: + next_cycle = META_TILE_CYCLE_66; + break; + case META_TILE_CYCLE_66: + next_cycle = META_TILE_CYCLE_NONE; + break; + default: + g_assert_not_reached (); + break; + } + } + } + else + { + if (META_WINDOW_TILED(window)) + next_cycle = META_TILE_CYCLE_NONE; + else + next_cycle = META_TILE_CYCLE_50; + } + + if (mode == window->tile_mode && next_cycle == META_TILE_CYCLE_NONE) { window->tile_mode = META_TILE_NONE; window->tile_monitor_number = -1; + window->tile_cycle = META_TILE_CYCLE_NONE; meta_window_untile(window); } else if (meta_window_can_tile (window)) { + window->tile_cycle = next_cycle; window->tile_mode = mode; window->tile_resized = FALSE; window->tile_monitor_number = meta_screen_get_xinerama_for_window (window->screen, window)->number; diff --git a/src/core/prefs.c b/src/core/prefs.c index df6bed14..f7df9f39 100644 --- a/src/core/prefs.c +++ b/src/core/prefs.c @@ -130,6 +130,7 @@ static gboolean center_new_windows = FALSE; static gboolean force_fullscreen = TRUE; static gboolean allow_tiling = FALSE; static gboolean allow_top_tiling = TRUE; +static gboolean allow_tile_cycling = TRUE; static GList *show_desktop_skip_list = NULL; static MetaVisualBellType visual_bell_type = META_VISUAL_BELL_FULLSCREEN_FLASH; @@ -443,6 +444,12 @@ static MetaBoolPreference preferences_bool[] = &allow_top_tiling, FALSE, }, + { "allow-tile-cycling", + KEY_GENERAL_SCHEMA, + META_PREF_ALLOW_TILE_CYCLING, + &allow_tile_cycling, + FALSE, + }, { "alt-tab-expand-to-fit-title", KEY_GENERAL_SCHEMA, META_PREF_ALT_TAB_EXPAND_TO_FIT_TITLE, @@ -1700,6 +1707,9 @@ meta_preference_to_string (MetaPreference pref) case META_PREF_ALLOW_TOP_TILING: return "ALLOW_TOP_TILING"; + case META_PREF_ALLOW_TILE_CYCLING: + return "ALLOW_TILE_CYCLING"; + case META_PREF_PLACEMENT_MODE: return "PLACEMENT_MODE"; @@ -2390,6 +2400,12 @@ meta_prefs_get_allow_top_tiling () return allow_top_tiling; } +gboolean +meta_prefs_get_allow_tile_cycling () +{ + return allow_tile_cycling; +} + guint meta_prefs_get_mouse_button_resize (void) { diff --git a/src/core/window-private.h b/src/core/window-private.h index ada9f8bb..008979e5 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -83,6 +83,15 @@ typedef enum { META_QUEUE_UPDATE_ICON = 1 << 2, } MetaQueueType; +typedef enum { + META_TILE_CYCLE_NONE, + META_TILE_CYCLE_50, + META_TILE_CYCLE_33, + META_TILE_CYCLE_25, + META_TILE_CYCLE_75, + META_TILE_CYCLE_66 +} MetaTileCycle; + #define NUMBER_OF_QUEUES 3 struct _MetaWindow @@ -150,6 +159,7 @@ struct _MetaWindow guint tile_mode : 3; guint tile_resized : 1; guint tiled : 1; + guint tile_cycle : 3; /* The last "full" maximized/unmaximized state. We need to keep track of * that to toggle between normal/tiled or maximized/tiled states. */ diff --git a/src/core/window.c b/src/core/window.c index 1536c62d..4a1bb71f 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -7259,13 +7259,13 @@ 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 request. */ window->tile_mode = META_TILE_NONE; window->tile_monitor_number = -1; + window->tile_cycle = META_TILE_CYCLE_NONE; } else if (meta_prefs_get_allow_tiling () && !META_WINDOW_MAXIMIZED (window) && @@ -7298,15 +7298,17 @@ update_move (MetaWindow *window, MetaTileMode old_tile_mode = window->tile_mode; 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; - /* Reset resized flag when changing tile mode */ + /* Reset resized and cycle flags when changing tile mode */ if (old_tile_mode != window->tile_mode) - window->tile_resized = FALSE; - } + { + window->tile_resized = FALSE; + window->tile_cycle = META_TILE_CYCLE_NONE; + } + } /* shake loose (unmaximize) maximized or tiled window if dragged beyond * the threshold in the Y direction. Tiled windows can also be pulled @@ -7324,6 +7326,7 @@ update_move (MetaWindow *window, */ window->shaken_loose = META_WINDOW_MAXIMIZED (window); window->tile_mode = META_TILE_NONE; + window->tile_cycle = META_TILE_CYCLE_NONE; window->tiled = FALSE; /* move the unmaximized window to the cursor */ @@ -7399,7 +7402,8 @@ update_move (MetaWindow *window, display->grab_anchor_root_y = y; window->shaken_loose = FALSE; - window->tile_mode = META_TILE_NONE; + window->tile_mode = META_TILE_NONE; + window->tile_cycle = META_TILE_CYCLE_NONE; meta_window_maximize (window, META_MAXIMIZE_HORIZONTAL | @@ -7410,13 +7414,11 @@ 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); @@ -8087,6 +8089,8 @@ meta_window_get_current_tile_area (MetaWindow *window, MetaRectangle *tile_area) { int tile_monitor_number; + int width; + double tile_ratio; g_return_if_fail (window->tile_mode != META_TILE_NONE); @@ -8110,9 +8114,32 @@ meta_window_get_current_tile_area (MetaWindow *window, meta_window_get_work_area_for_xinerama (window, tile_monitor_number, tile_area); + width = tile_area->width; + + switch (window->tile_cycle) + { + case META_TILE_CYCLE_33: + tile_ratio = 1 / 3.0; + break; + case META_TILE_CYCLE_25: + tile_ratio = 1 / 4.0; + break; + case META_TILE_CYCLE_75: + tile_ratio = 3 / 4.0; + break; + case META_TILE_CYCLE_66: + tile_ratio = 2 / 3.0; + break; + case META_TILE_CYCLE_50: + case META_TILE_CYCLE_NONE: + default: + tile_ratio = 1 / 2.0; + break; + } + if (window->tile_mode != META_TILE_NONE && window->tile_mode != META_TILE_MAXIMIZED) - tile_area->width /= 2; + width = (int)(tile_area->width * tile_ratio); if(window->tile_mode == META_TILE_BOTTOM_LEFT || window->tile_mode == META_TILE_BOTTOM_RIGHT || @@ -8123,11 +8150,13 @@ meta_window_get_current_tile_area (MetaWindow *window, 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; + tile_area->x += tile_area->width - width; if(window->tile_mode == META_TILE_BOTTOM_LEFT || window->tile_mode == META_TILE_BOTTOM_RIGHT) tile_area->y += tile_area->height; + + tile_area->width = width; } gboolean diff --git a/src/include/prefs.h b/src/include/prefs.h index 515e9173..a7dc2508 100644 --- a/src/include/prefs.h +++ b/src/include/prefs.h @@ -70,6 +70,7 @@ typedef enum META_PREF_CENTER_NEW_WINDOWS, META_PREF_ALLOW_TILING, META_PREF_ALLOW_TOP_TILING, + META_PREF_ALLOW_TILE_CYCLING, META_PREF_FORCE_FULLSCREEN, META_PREF_PLACEMENT_MODE, META_PREF_SHOW_DESKTOP_SKIP_LIST @@ -107,6 +108,7 @@ gboolean meta_prefs_get_mate_accessibility (void); gboolean meta_prefs_get_mate_animations (void); gboolean meta_prefs_get_allow_tiling (void); gboolean meta_prefs_get_allow_top_tiling (void); +gboolean meta_prefs_get_allow_tile_cycling (void); const char* meta_prefs_get_command (int i); diff --git a/src/org.mate.marco.gschema.xml b/src/org.mate.marco.gschema.xml index bfa07994..46785844 100644 --- a/src/org.mate.marco.gschema.xml +++ b/src/org.mate.marco.gschema.xml @@ -186,6 +186,11 @@ Whether to maximize the window when dragged to the top of the screen If enabled, drag-dropping a window to the top of the screen will maximize it. Only works when allow-tiling is enabled. + + true + Whether to enable cycling through different tile sizes + If enabled, tiling a window will cycle through multiple different sizes by using the same keyboard shortcut multiple times in a row. + 'automatic' Window placement mode -- cgit v1.2.1