summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorOmar Zeidan <[email protected]>2017-12-11 14:54:17 +0100
committerraveit65 <[email protected]>2017-12-20 20:42:12 +0100
commit6219f8e8bcaeefb9185a3c3f5f20de4e2fa8f18f (patch)
treee3652b4e35ca31478ef9f62f89765ff6d97e7b3a /src/core
parent01f68e8f9f1541393e6e069db08f834d4ef18691 (diff)
downloadmarco-6219f8e8bcaeefb9185a3c3f5f20de4e2fa8f18f.tar.bz2
marco-6219f8e8bcaeefb9185a3c3f5f20de4e2fa8f18f.tar.xz
Allow horizontal and vertical resizing when corner tiled
Diffstat (limited to 'src/core')
-rw-r--r--src/core/constraints.c128
-rw-r--r--src/core/keybindings.c27
-rw-r--r--src/core/window-private.h16
-rw-r--r--src/core/window.c159
4 files changed, 207 insertions, 123 deletions
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,