From 6219f8e8bcaeefb9185a3c3f5f20de4e2fa8f18f Mon Sep 17 00:00:00 2001 From: Omar Zeidan Date: Mon, 11 Dec 2017 14:54:17 +0100 Subject: Allow horizontal and vertical resizing when corner tiled --- src/core/constraints.c | 128 +++++++++++++++++++++++++++++-------- src/core/keybindings.c | 27 ++------ src/core/window-private.h | 16 +++-- src/core/window.c | 159 +++++++++++++++++++++++++--------------------- 4 files changed, 207 insertions(+), 123 deletions(-) (limited to 'src') diff --git a/src/core/constraints.c b/src/core/constraints.c index 512e6404..b4f9b551 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -206,6 +206,11 @@ static inline void get_size_limits (const MetaWindow *window, MetaRectangle *min_size, MetaRectangle *max_size); +static void can_resize_tiled (guint tile_mode, + int resize_gravity, + gboolean *resize_horizontally, + gboolean *resize_vertically); + typedef gboolean (* ConstraintFunc) (MetaWindow *window, ConstraintInfo *info, ConstraintPriority priority, @@ -876,13 +881,14 @@ constrain_tiling (MetaWindow *window, gboolean hminbad, vminbad; gboolean horiz_equal, vert_equal; gboolean constraint_already_satisfied; - gboolean allow_resize = FALSE; + gboolean allow_resize_horizontally = FALSE; + gboolean allow_resize_vertically = FALSE; if (priority > PRIORITY_TILING) return TRUE; /* Determine whether constraint applies; exit if it doesn't */ - if (!META_WINDOW_SIDE_TILED (window)) + if (!META_WINDOW_TILED(window)) return TRUE; /* Calculate target_size - as the tile previews need this as well, we @@ -912,46 +918,118 @@ constrain_tiling (MetaWindow *window, /* Allow the user to resize horizontally when tiled */ if (info->is_user_action) { - /* Only allow resizing from the window side farther from the screen edge */ - switch (info->resize_gravity) - { - case NorthEastGravity: - case EastGravity: - case SouthEastGravity: - if (window->tile_mode == META_TILE_RIGHT) - allow_resize = TRUE; - break; - case NorthWestGravity: - case WestGravity: - case SouthWestGravity: - if (window->tile_mode == META_TILE_LEFT) - allow_resize = TRUE; - break; - } - - /* Mark window as being resized from a tiled state */ + can_resize_tiled(window->tile_mode, + info->resize_gravity, + &allow_resize_horizontally, + &allow_resize_vertically); + window->tile_resized = TRUE; } if (window->tile_resized) { /* Maintain current tile size for user-resized windows */ + target_size.y = info->orig.y; + target_size.height = info->orig.height; target_size.x = info->orig.x; target_size.width = info->orig.width; } /*** Enforce constraint ***/ - if (!allow_resize) + if (!allow_resize_vertically) { + info->current.y = target_size.y; + info->current.height = target_size.height; + } + + if(!allow_resize_horizontally) + { info->current.x = target_size.x; info->current.width = target_size.width; } - info->current.y = target_size.y; - info->current.height = target_size.height; - + return TRUE; } +static void +can_resize_tiled (guint tile_mode, + int resize_gravity, + gboolean *resize_horizontally, + gboolean *resize_vertically) +{ + switch(tile_mode) + { + case META_TILE_RIGHT: + if (resize_gravity == EastGravity) + *resize_horizontally = TRUE; + break; + case META_TILE_LEFT: + if(resize_gravity == WestGravity) + *resize_horizontally = TRUE; + break; + case META_TILE_TOP_RIGHT: + switch(resize_gravity) + { + case EastGravity: + *resize_horizontally = TRUE; + break; + case NorthGravity: + *resize_vertically = TRUE; + break; + case NorthEastGravity: + *resize_horizontally = TRUE; + *resize_vertically = TRUE; + break; + } + break; + case META_TILE_TOP_LEFT: + switch(resize_gravity) + { + case WestGravity: + *resize_horizontally = TRUE; + break; + case NorthGravity: + *resize_vertically = TRUE; + break; + case NorthWestGravity: + *resize_horizontally = TRUE; + *resize_vertically = TRUE; + break; + } + break; + case META_TILE_BOTTOM_RIGHT: + switch(resize_gravity) + { + case EastGravity: + *resize_horizontally = TRUE; + break; + case SouthGravity: + *resize_vertically = TRUE; + break; + case SouthEastGravity: + *resize_horizontally = TRUE; + *resize_vertically = TRUE; + break; + } + break; + case META_TILE_BOTTOM_LEFT: + switch(resize_gravity) + { + case WestGravity: + *resize_horizontally = TRUE; + break; + case SouthGravity: + *resize_vertically = TRUE; + break; + case SouthWestGravity: + *resize_horizontally = TRUE; + *resize_vertically = TRUE; + break; + } + break; + } +} + static gboolean constrain_fullscreen (MetaWindow *window, ConstraintInfo *info, @@ -1003,7 +1081,7 @@ constrain_size_increments (MetaWindow *window, /* Determine whether constraint applies; exit if it doesn't */ if (META_WINDOW_MAXIMIZED (window) || window->fullscreen || - META_WINDOW_SIDE_TILED (window) || info->action_type == ACTION_MOVE) + META_WINDOW_TILED (window) || info->action_type == ACTION_MOVE) return TRUE; /* Determine whether constraint is already satisfied; exit if it is */ diff --git a/src/core/keybindings.c b/src/core/keybindings.c index 3a54ca0d..0c9a5e27 100644 --- a/src/core/keybindings.c +++ b/src/core/keybindings.c @@ -1457,9 +1457,8 @@ 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|| - META_WINDOW_QUARTER_TILED(window)) + else if (window->tile_mode != META_TILE_MAXIMIZED && + window->tile_mode != META_TILE_NONE) meta_window_tile (window); else if (!display->grab_wireframe_active) meta_window_move_resize (display->grab_window, @@ -3090,24 +3089,11 @@ handle_toggle_tiled (MetaDisplay *display, { MetaTileMode mode = binding->handler->data; - if (mode == window->tile_mode && - window->maximized_vertically && - !window->maximized_horizontally) + if (mode == window->tile_mode && META_WINDOW_TILED(window)) { - if (window->saved_maximize) - { - window->tile_mode = META_TILE_MAXIMIZED; - window->tile_monitor_number = meta_screen_get_xinerama_for_window (window->screen, window)->number; - meta_window_maximize (window, META_MAXIMIZE_VERTICAL | - META_MAXIMIZE_HORIZONTAL); - } - else - { - window->tile_mode = META_TILE_NONE; - window->tile_monitor_number = -1; - meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL | - META_MAXIMIZE_HORIZONTAL); - } + window->tile_mode = META_TILE_NONE; + window->tile_monitor_number = -1; + meta_window_untile(window); } else if (meta_window_can_tile (window)) { @@ -3128,6 +3114,7 @@ handle_toggle_tiled (MetaDisplay *display, window->saved_maximize = FALSE; window->maximized_horizontally = FALSE; + window->maximized_vertically = FALSE; meta_window_tile (window); } } diff --git a/src/core/window-private.h b/src/core/window-private.h index 0d744faf..f0832abf 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -147,6 +147,7 @@ struct _MetaWindow * requested after the window grab is released */ guint tile_mode : 3; guint tile_resized : 1; + guint tiled : 1; /* The last "full" maximized/unmaximized state. We need to keep track of * that to toggle between normal/tiled or maximized/tiled states. */ @@ -401,19 +402,19 @@ 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_SIDE_TILED(w) ((w)->maximized_vertically && \ - !(w)->maximized_horizontally && \ - (w)->tile_mode != META_TILE_NONE) -#define META_WINDOW_TILED_LEFT(w) (META_WINDOW_SIDE_TILED(w) && \ +#define META_WINDOW_SIDE_TILED(w) ((w)->tiled && \ + ((w)->tile_mode == META_TILE_LEFT || \ + (w)->tile_mode == META_TILE_RIGHT)) +#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_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 || \ +#define META_WINDOW_CORNER_TILED(w) ((w)->tiled && \ + ((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_TILED(w) (META_WINDOW_SIDE_TILED(w) || META_WINDOW_CORNER_TILED(w)) #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) && \ @@ -435,6 +436,7 @@ void meta_window_calc_showing (MetaWindow *window); void meta_window_queue (MetaWindow *window, guint queuebits); void meta_window_tile (MetaWindow *window); +void meta_window_untile (MetaWindow *window); void meta_window_minimize (MetaWindow *window); void meta_window_unminimize (MetaWindow *window); void meta_window_maximize (MetaWindow *window, diff --git a/src/core/window.c b/src/core/window.c index 8a613dea..86bca3ec 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -2520,7 +2520,7 @@ static void meta_window_save_rect (MetaWindow *window) { if (!(META_WINDOW_MAXIMIZED (window) || META_WINDOW_SIDE_TILED (window) || - META_WINDOW_QUARTER_TILED(window) || window->fullscreen)) + META_WINDOW_CORNER_TILED(window) || window->fullscreen)) { /* save size/pos as appropriate args for move_resize */ if (!window->maximized_horizontally) @@ -2719,14 +2719,27 @@ meta_window_tile (MetaWindow *window) if (window->tile_mode == META_TILE_NONE) return; - meta_window_maximize_internal (window, META_MAXIMIZE_VERTICAL, NULL); - + if(window->tile_mode == META_TILE_LEFT || window->tile_mode == META_TILE_RIGHT) + meta_window_maximize_internal (window, META_MAXIMIZE_VERTICAL, NULL); + else + meta_window_save_rect(window); + + window->tiled = TRUE; /* move_resize with new tiling constraints */ meta_window_queue (window, META_QUEUE_MOVE_RESIZE); } +void +meta_window_untile (MetaWindow *window) +{ + window->tiled = FALSE; + + meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL | META_MAXIMIZE_HORIZONTAL); + +} + static gboolean meta_window_can_tile_maximized (MetaWindow *window) { @@ -2779,77 +2792,73 @@ meta_window_unmaximize (MetaWindow *window, /* Only do something if the window isn't already maximized in the * given direction(s). */ - if ((unmaximize_horizontally && window->maximized_horizontally) || - (unmaximize_vertically && window->maximized_vertically)) - { - MetaRectangle target_rect; - - meta_topic (META_DEBUG_WINDOW_OPS, - "Unmaximizing %s%s\n", - window->desc, - unmaximize_horizontally && unmaximize_vertically ? "" : - unmaximize_horizontally ? " horizontally" : - unmaximize_vertically ? " vertically" : "BUGGGGG"); + MetaRectangle target_rect; - window->maximized_horizontally = - window->maximized_horizontally && !unmaximize_horizontally; - window->maximized_vertically = - window->maximized_vertically && !unmaximize_vertically; + meta_topic (META_DEBUG_WINDOW_OPS, + "Unmaximizing %s%s\n", + window->desc, + unmaximize_horizontally && unmaximize_vertically ? "" : + unmaximize_horizontally ? " horizontally" : + unmaximize_vertically ? " vertically" : "BUGGGGG"); - /* Unmaximize to the saved_rect position in the direction(s) - * being unmaximized. - */ - meta_window_get_client_root_coords (window, &target_rect); - if (unmaximize_horizontally) - { - target_rect.x = window->saved_rect.x; - target_rect.width = window->saved_rect.width; - } - if (unmaximize_vertically) - { - target_rect.y = window->saved_rect.y; - target_rect.height = window->saved_rect.height; - } + window->maximized_horizontally = + window->maximized_horizontally && !unmaximize_horizontally; + window->maximized_vertically = + window->maximized_vertically && !unmaximize_vertically; - /* Window's size hints may have changed while maximized, making - * saved_rect invalid. #329152 - */ - ensure_size_hints_satisfied (&target_rect, &window->size_hints); + /* Unmaximize to the saved_rect position in the direction(s) + * being unmaximized. + */ + meta_window_get_client_root_coords (window, &target_rect); + if (unmaximize_horizontally) + { + target_rect.x = window->saved_rect.x; + target_rect.width = window->saved_rect.width; + } + if (unmaximize_vertically) + { + target_rect.y = window->saved_rect.y; + target_rect.height = window->saved_rect.height; + } - meta_window_move_resize (window, - FALSE, - target_rect.x, - target_rect.y, - target_rect.width, - target_rect.height); + /* Window's size hints may have changed while maximized, making + * saved_rect invalid. #329152 + */ + ensure_size_hints_satisfied (&target_rect, &window->size_hints); - /* Make sure user_rect is current. - */ - force_save_user_window_placement (window); + meta_window_move_resize (window, + FALSE, + target_rect.x, + target_rect.y, + target_rect.width, + target_rect.height); - /* When we unmaximize, if we're doing a mouse move also we could - * get the window suddenly jumping to the upper left corner of - * the workspace, since that's where it was when the grab op - * started. So we need to update the grab state. We have to do - * it after the actual operation, as the window may have been moved - * by constraints. - */ - if (meta_grab_op_is_moving (window->display->grab_op) && - window->display->grab_window == window) - { - window->display->grab_anchor_window_pos = window->user_rect; - } + /* Make sure user_rect is current. + */ + force_save_user_window_placement (window); + + /* When we unmaximize, if we're doing a mouse move also we could + * get the window suddenly jumping to the upper left corner of + * the workspace, since that's where it was when the grab op + * started. So we need to update the grab state. We have to do + * it after the actual operation, as the window may have been moved + * by constraints. + */ + if (meta_grab_op_is_moving (window->display->grab_op) && + window->display->grab_window == window) + { + window->display->grab_anchor_window_pos = window->user_rect; + } - if (window->display->grab_wireframe_active) - { - window->display->grab_wireframe_rect = target_rect; - } + if (window->display->grab_wireframe_active) + { + window->display->grab_wireframe_rect = target_rect; + } - recalc_window_features (window); - set_net_wm_state (window); + recalc_window_features (window); + set_net_wm_state (window); - meta_compositor_unmaximize_window (window->display->compositor, window); - } + meta_compositor_unmaximize_window (window->display->compositor, window); } void @@ -7019,7 +7028,7 @@ update_move (MetaWindow *window, } else if (meta_prefs_get_side_by_side_tiling () && !META_WINDOW_MAXIMIZED (window) && - !META_WINDOW_SIDE_TILED (window)) + !META_WINDOW_TILED (window)) { const MetaXineramaScreenInfo *monitor; MetaRectangle work_area; @@ -7064,7 +7073,7 @@ update_move (MetaWindow *window, */ if ((META_WINDOW_MAXIMIZED (window) && ABS (dy) >= shake_threshold) || - (META_WINDOW_SIDE_TILED (window) && (MAX (ABS (dx), ABS (dy)) >= shake_threshold))) + (META_WINDOW_TILED (window) && (MAX (ABS (dx), ABS (dy)) >= shake_threshold))) { double prop; @@ -7074,6 +7083,7 @@ update_move (MetaWindow *window, */ window->shaken_loose = META_WINDOW_MAXIMIZED (window); window->tile_mode = META_TILE_NONE; + window->tiled = FALSE; /* move the unmaximized window to the cursor */ prop = @@ -7175,10 +7185,17 @@ 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_SIDE_TILED (window)) - new_x = old.x; - if (window->maximized_vertically) - new_y = old.y; + + if (window->maximized_horizontally || META_WINDOW_TILED (window)) + { + new_x = old.x; + } + + if (window->maximized_vertically || META_WINDOW_CORNER_TILED(window)) + { + new_y = old.y; + } + /* Do any edge resistance/snapping */ meta_window_edge_resistance_for_move (window, -- cgit v1.2.1