From a87157176ca6e01c8c4047999ee584f00b63c11e Mon Sep 17 00:00:00 2001 From: Stefano Karapetsas Date: Fri, 31 May 2013 16:22:39 +0200 Subject: Implement side-by-side tiling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch by Florian Müllner for Metacity https://bugzilla.gnome.org/show_bug.cgi?id=607694 When dragging a window over a screen edge and dropping it there, maximize it vertically and scale it horizontally to cover the corresponding half of the current monitor. Whenever a "hot area" which triggers this behavior is entered, an indication of window's target size is displayed after a short delay to avoid distraction when moving a window between monitors. --- src/core/constraints.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 3 deletions(-) (limited to 'src/core/constraints.c') diff --git a/src/core/constraints.c b/src/core/constraints.c index 16d9b107..a79f858a 100644 --- a/src/core/constraints.c +++ b/src/core/constraints.c @@ -98,6 +98,7 @@ typedef enum PRIORITY_ENTIRELY_VISIBLE_ON_WORKAREA = 1, PRIORITY_SIZE_HINTS_INCREMENTS = 1, PRIORITY_MAXIMIZATION = 2, + PRIORITY_TILING = 2, PRIORITY_FULLSCREEN = 2, PRIORITY_SIZE_HINTS_LIMITS = 3, PRIORITY_TITLEBAR_VISIBLE = 4, @@ -145,6 +146,10 @@ static gboolean constrain_maximization (MetaWindow *window, ConstraintInfo *info, ConstraintPriority priority, gboolean check_only); +static gboolean constrain_tiling (MetaWindow *window, + ConstraintInfo *info, + ConstraintPriority priority, + gboolean check_only); static gboolean constrain_fullscreen (MetaWindow *window, ConstraintInfo *info, ConstraintPriority priority, @@ -211,6 +216,7 @@ typedef struct { static const Constraint all_constraints[] = { {constrain_maximization, "constrain_maximization"}, + {constrain_tiling, "constrain_tiling"}, {constrain_fullscreen, "constrain_fullscreen"}, {constrain_size_increments, "constrain_size_increments"}, {constrain_size_limits, "constrain_size_limits"}, @@ -731,7 +737,8 @@ constrain_maximization (MetaWindow *window, return TRUE; /* Determine whether constraint applies; exit if it doesn't */ - if (!window->maximized_horizontally && !window->maximized_vertically) + if ((!window->maximized_horizontally && !window->maximized_vertically) || + META_WINDOW_TILED (window)) return TRUE; /* Calculate target_size = maximized size of (window + frame) */ @@ -799,6 +806,58 @@ constrain_maximization (MetaWindow *window, return TRUE; } +static gboolean +constrain_tiling (MetaWindow *window, + ConstraintInfo *info, + ConstraintPriority priority, + gboolean check_only) +{ + MetaRectangle target_size; + MetaRectangle min_size, max_size; + gboolean hminbad, vminbad; + gboolean horiz_equal, vert_equal; + gboolean constraint_already_satisfied; + + if (priority > PRIORITY_TILING) + return TRUE; + + /* Determine whether constraint applies; exit if it doesn't */ + if (!META_WINDOW_TILED (window)) + return TRUE; + + /* Calculate target_size - as the tile previews need this as well, we + * use an external function for the actual calculation + */ + meta_window_get_current_tile_area (window, &target_size); + unextend_by_frame (&target_size, info->fgeom); + + /* Check min size constraints; max size constraints are ignored as for + * maximized windows. + */ + get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size); + hminbad = target_size.width < min_size.width; + vminbad = target_size.height < min_size.height; + if (hminbad || vminbad) + return TRUE; + + /* Determine whether constraint is already satisfied; exit if it is */ + horiz_equal = target_size.x == info->current.x && + target_size.width == info->current.width; + vert_equal = target_size.y == info->current.y && + target_size.height == info->current.height; + constraint_already_satisfied = horiz_equal && vert_equal; + if (check_only || constraint_already_satisfied) + return constraint_already_satisfied; + + /*** Enforce constraint ***/ + 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 gboolean constrain_fullscreen (MetaWindow *window, ConstraintInfo *info, @@ -850,7 +909,7 @@ constrain_size_increments (MetaWindow *window, /* Determine whether constraint applies; exit if it doesn't */ if (META_WINDOW_MAXIMIZED (window) || window->fullscreen || - 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 */ @@ -981,7 +1040,7 @@ constrain_aspect_ratio (MetaWindow *window, constraints_are_inconsistent = minr > maxr; if (constraints_are_inconsistent || META_WINDOW_MAXIMIZED (window) || window->fullscreen || - 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. We -- cgit v1.2.1