summaryrefslogtreecommitdiff
path: root/src/core/constraints.c
diff options
context:
space:
mode:
authorStefano Karapetsas <[email protected]>2013-05-31 16:22:39 +0200
committerStefano Karapetsas <[email protected]>2013-05-31 16:22:39 +0200
commita87157176ca6e01c8c4047999ee584f00b63c11e (patch)
tree80e928a800b4b54f6831a6b38a952014c7f5ae5c /src/core/constraints.c
parentcc760e2586cd0f98f8c60382ab8ff1f7373d9c1d (diff)
downloadmarco-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.c65
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