diff options
author | Stefano Karapetsas <[email protected]> | 2013-05-31 16:22:39 +0200 |
---|---|---|
committer | Stefano Karapetsas <[email protected]> | 2013-05-31 16:22:39 +0200 |
commit | a87157176ca6e01c8c4047999ee584f00b63c11e (patch) | |
tree | 80e928a800b4b54f6831a6b38a952014c7f5ae5c /src/core/constraints.c | |
parent | cc760e2586cd0f98f8c60382ab8ff1f7373d9c1d (diff) | |
download | marco-a87157176ca6e01c8c4047999ee584f00b63c11e.tar.bz2 marco-a87157176ca6e01c8c4047999ee584f00b63c11e.tar.xz |
Implement side-by-side tiling
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.
Diffstat (limited to 'src/core/constraints.c')
-rw-r--r-- | src/core/constraints.c | 65 |
1 files changed, 62 insertions, 3 deletions
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) */ @@ -800,6 +807,58 @@ constrain_maximization (MetaWindow *window, } 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, ConstraintPriority priority, @@ -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 |