- Add patch to allow breaking out from maximization during mouse resize
(gnome bz 622517)
This commit is contained in:
parent
7a651cc048
commit
4c6a10fb43
413
Allow-breaking-out-from-maximization-during-mouse.patch
Normal file
413
Allow-breaking-out-from-maximization-during-mouse.patch
Normal file
@ -0,0 +1,413 @@
|
||||
From 339710e884cfbab810382a63fafb3cdab8ee51e9 Mon Sep 17 00:00:00 2001
|
||||
From: Owen W. Taylor <otaylor@fishsoup.net>
|
||||
Date: Wed, 23 Jun 2010 15:08:38 -0400
|
||||
Subject: [PATCH] Allow breaking out from maximization during a mouse resize
|
||||
|
||||
A maximized window can't be resized from the screen edges (preserves
|
||||
Fitts law goodness for the application), but it's still possible
|
||||
to start a resize drag with alt-middle-button. Currently we just
|
||||
don't let the user resize the window, while showing drag feedback;
|
||||
it's more useful to let the user "break" out from the resize.
|
||||
|
||||
This provides a fast way to get a window partially aligned with
|
||||
the screen edges - maximize, then alt-drag it out from one edge.
|
||||
|
||||
Behavior choices in this patch:
|
||||
|
||||
- You can drag out a window out of maximization in both directions -
|
||||
smaller and larger. This can be potentilaly useful in multihead.
|
||||
|
||||
- Dragging a window in only one direction unmaximizes the window
|
||||
fully, rather than leaving it in a horizontally/vertically
|
||||
maximized state. This is done because the horizontally/vertically
|
||||
maximzed states don't have clear visual representation and can
|
||||
be confusing to the user.
|
||||
|
||||
- If you drag back to the maximized state after breaking out,
|
||||
maximization is restored, but you can't maximize a window by
|
||||
dragging to the full size if it didn't start out that way.
|
||||
|
||||
A new internal function meta_window_unmaximize_with_gravity() is
|
||||
added for implementing this; it's a hybrid of
|
||||
meta_window_unmaximize() and meta_window_resize_with_gravity().
|
||||
|
||||
https://bugzilla.gnome.org/show_bug.cgi?id=622517
|
||||
---
|
||||
src/core/display-private.h | 3 +
|
||||
src/core/display.c | 20 +++-
|
||||
src/core/window-private.h | 5 +
|
||||
src/core/window.c | 224 ++++++++++++++++++++++++++++++++++++++++----
|
||||
4 files changed, 228 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/src/core/display-private.h b/src/core/display-private.h
|
||||
index 19287f3..a19d1d8 100644
|
||||
--- a/src/core/display-private.h
|
||||
+++ b/src/core/display-private.h
|
||||
@@ -170,6 +170,9 @@ struct _MetaDisplay
|
||||
guint grab_wireframe_active : 1;
|
||||
guint grab_was_cancelled : 1; /* Only used in wireframe mode */
|
||||
guint grab_frame_action : 1;
|
||||
+ /* During a resize operation, the directions in which we've broken
|
||||
+ * out of the initial maximization state */
|
||||
+ guint grab_resize_unmaximize : 2; /* MetaMaximizeFlags */
|
||||
MetaRectangle grab_wireframe_rect;
|
||||
MetaRectangle grab_wireframe_last_xor_rect;
|
||||
MetaRectangle grab_initial_window_pos;
|
||||
diff --git a/src/core/display.c b/src/core/display.c
|
||||
index 4c7b4c0..2122851 100644
|
||||
--- a/src/core/display.c
|
||||
+++ b/src/core/display.c
|
||||
@@ -3353,6 +3353,7 @@ meta_display_begin_grab_op (MetaDisplay *display,
|
||||
#endif
|
||||
display->grab_was_cancelled = FALSE;
|
||||
display->grab_frame_action = frame_action;
|
||||
+ display->grab_resize_unmaximize = 0;
|
||||
|
||||
if (display->grab_resize_timeout_id)
|
||||
{
|
||||
@@ -3583,11 +3584,20 @@ meta_display_end_grab_op (MetaDisplay *display,
|
||||
display->grab_wireframe_rect.x,
|
||||
display->grab_wireframe_rect.y);
|
||||
if (meta_grab_op_is_resizing (display->grab_op))
|
||||
- meta_window_resize_with_gravity (display->grab_window,
|
||||
- TRUE,
|
||||
- display->grab_wireframe_rect.width,
|
||||
- display->grab_wireframe_rect.height,
|
||||
- meta_resize_gravity_from_grab_op (display->grab_op));
|
||||
+ {
|
||||
+ if (display->grab_resize_unmaximize != 0)
|
||||
+ meta_window_unmaximize_with_gravity (display->grab_window,
|
||||
+ display->grab_resize_unmaximize,
|
||||
+ display->grab_wireframe_rect.width,
|
||||
+ display->grab_wireframe_rect.height,
|
||||
+ meta_resize_gravity_from_grab_op (display->grab_op));
|
||||
+ else
|
||||
+ meta_window_resize_with_gravity (display->grab_window,
|
||||
+ TRUE,
|
||||
+ display->grab_wireframe_rect.width,
|
||||
+ display->grab_wireframe_rect.height,
|
||||
+ meta_resize_gravity_from_grab_op (display->grab_op));
|
||||
+ }
|
||||
}
|
||||
meta_window_calc_showing (display->grab_window);
|
||||
}
|
||||
diff --git a/src/core/window-private.h b/src/core/window-private.h
|
||||
index da3fc52..65143ce 100644
|
||||
--- a/src/core/window-private.h
|
||||
+++ b/src/core/window-private.h
|
||||
@@ -412,6 +412,11 @@ void meta_window_maximize_internal (MetaWindow *window,
|
||||
MetaRectangle *saved_rect);
|
||||
void meta_window_unmaximize (MetaWindow *window,
|
||||
MetaMaximizeFlags directions);
|
||||
+void meta_window_unmaximize_with_gravity (MetaWindow *window,
|
||||
+ MetaMaximizeFlags directions,
|
||||
+ int new_width,
|
||||
+ int new_height,
|
||||
+ int gravity);
|
||||
void meta_window_make_above (MetaWindow *window);
|
||||
void meta_window_unmake_above (MetaWindow *window);
|
||||
void meta_window_shade (MetaWindow *window,
|
||||
diff --git a/src/core/window.c b/src/core/window.c
|
||||
index 9af5283..6438540 100644
|
||||
--- a/src/core/window.c
|
||||
+++ b/src/core/window.c
|
||||
@@ -2666,9 +2666,11 @@ unmaximize_window_before_freeing (MetaWindow *window)
|
||||
}
|
||||
}
|
||||
|
||||
-void
|
||||
-meta_window_unmaximize (MetaWindow *window,
|
||||
- MetaMaximizeFlags directions)
|
||||
+static void
|
||||
+meta_window_unmaximize_internal (MetaWindow *window,
|
||||
+ MetaMaximizeFlags directions,
|
||||
+ MetaRectangle *desired_rect,
|
||||
+ int gravity)
|
||||
{
|
||||
/* At least one of the two directions ought to be set */
|
||||
gboolean unmaximize_horizontally, unmaximize_vertically;
|
||||
@@ -2702,13 +2704,13 @@ meta_window_unmaximize (MetaWindow *window,
|
||||
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;
|
||||
+ target_rect.x = desired_rect->x;
|
||||
+ target_rect.width = desired_rect->width;
|
||||
}
|
||||
if (unmaximize_vertically)
|
||||
{
|
||||
- target_rect.y = window->saved_rect.y;
|
||||
- target_rect.height = window->saved_rect.height;
|
||||
+ target_rect.y = desired_rect->y;
|
||||
+ target_rect.height = desired_rect->height;
|
||||
}
|
||||
|
||||
/* Window's size hints may have changed while maximized, making
|
||||
@@ -2727,12 +2729,13 @@ meta_window_unmaximize (MetaWindow *window,
|
||||
window->display->grab_anchor_window_pos = target_rect;
|
||||
}
|
||||
|
||||
- meta_window_move_resize (window,
|
||||
- FALSE,
|
||||
- target_rect.x,
|
||||
- target_rect.y,
|
||||
- target_rect.width,
|
||||
- target_rect.height);
|
||||
+ meta_window_move_resize_internal (window,
|
||||
+ META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION,
|
||||
+ gravity,
|
||||
+ target_rect.x,
|
||||
+ target_rect.y,
|
||||
+ target_rect.width,
|
||||
+ target_rect.height);
|
||||
|
||||
/* Make sure user_rect is current.
|
||||
*/
|
||||
@@ -2749,6 +2752,36 @@ meta_window_unmaximize (MetaWindow *window,
|
||||
}
|
||||
|
||||
void
|
||||
+meta_window_unmaximize (MetaWindow *window,
|
||||
+ MetaMaximizeFlags directions)
|
||||
+{
|
||||
+ meta_window_unmaximize_internal (window, directions, &window->saved_rect,
|
||||
+ NorthWestGravity);
|
||||
+}
|
||||
+
|
||||
+/* Like meta_window_unmaximize(), but instead of unmaximizing to the
|
||||
+ * saved position, we give the new desired size, and the gravity that
|
||||
+ * determines the positioning relationship between the area occupied
|
||||
+ * maximized and the new are. The arguments are similar to
|
||||
+ * meta_window_resize_with_gravity().
|
||||
+ */
|
||||
+void
|
||||
+meta_window_unmaximize_with_gravity (MetaWindow *window,
|
||||
+ MetaMaximizeFlags directions,
|
||||
+ int new_width,
|
||||
+ int new_height,
|
||||
+ int gravity)
|
||||
+{
|
||||
+ MetaRectangle desired_rect;
|
||||
+
|
||||
+ meta_window_get_position (window, &desired_rect.x, &desired_rect.y);
|
||||
+ desired_rect.width = new_width;
|
||||
+ desired_rect.height = new_height;
|
||||
+
|
||||
+ meta_window_unmaximize_internal (window, directions, &desired_rect, gravity);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
meta_window_make_above (MetaWindow *window)
|
||||
{
|
||||
window->wm_state_above = TRUE;
|
||||
@@ -7033,6 +7066,112 @@ update_resize_timeout (gpointer data)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
+/* When resizing a maximized window by using alt-middle-drag (resizing
|
||||
+ * with the grips or the menu for a maximized window is not enabled),
|
||||
+ * the user can "break" out of the maximized state. This checks for
|
||||
+ * that possibility. During such a break-out resize the user can also
|
||||
+ * return to the previous maximization state by resizing back to near
|
||||
+ * the original size.
|
||||
+ */
|
||||
+static MetaMaximizeFlags
|
||||
+check_resize_unmaximize(MetaWindow *window,
|
||||
+ int dx,
|
||||
+ int dy)
|
||||
+{
|
||||
+ int threshold;
|
||||
+ MetaMaximizeFlags new_unmaximize;
|
||||
+
|
||||
+#define DRAG_THRESHOLD_TO_RESIZE_THRESHOLD_FACTOR 3
|
||||
+
|
||||
+ threshold = meta_ui_get_drag_threshold (window->screen->ui) *
|
||||
+ DRAG_THRESHOLD_TO_RESIZE_THRESHOLD_FACTOR;
|
||||
+ new_unmaximize = 0;
|
||||
+
|
||||
+ if (window->maximized_horizontally ||
|
||||
+ (window->display->grab_resize_unmaximize & META_MAXIMIZE_HORIZONTAL) != 0)
|
||||
+ {
|
||||
+ int x_amount;
|
||||
+
|
||||
+ /* We allow breaking out of maximization in either direction, to make
|
||||
+ * the window larger than the monitor as well as smaller than the
|
||||
+ * monitor. If we wanted to only allow resizing smaller than the
|
||||
+ * monitor, we'd use - dx for NE/E/SE and dx for SW/W/NW.
|
||||
+ */
|
||||
+ switch (window->display->grab_op)
|
||||
+ {
|
||||
+ case META_GRAB_OP_RESIZING_NE:
|
||||
+ case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
||||
+ case META_GRAB_OP_RESIZING_E:
|
||||
+ case META_GRAB_OP_KEYBOARD_RESIZING_E:
|
||||
+ case META_GRAB_OP_RESIZING_SE:
|
||||
+ case META_GRAB_OP_KEYBOARD_RESIZING_SE:
|
||||
+ case META_GRAB_OP_RESIZING_SW:
|
||||
+ case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
||||
+ case META_GRAB_OP_RESIZING_W:
|
||||
+ case META_GRAB_OP_KEYBOARD_RESIZING_W:
|
||||
+ case META_GRAB_OP_RESIZING_NW:
|
||||
+ case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
||||
+ x_amount = dx < 0 ? - dx : dx;
|
||||
+ break;
|
||||
+ default:
|
||||
+ x_amount = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (x_amount > threshold)
|
||||
+ new_unmaximize |= META_MAXIMIZE_HORIZONTAL;
|
||||
+ }
|
||||
+
|
||||
+ if (window->maximized_vertically ||
|
||||
+ (window->display->grab_resize_unmaximize & META_MAXIMIZE_VERTICAL) != 0)
|
||||
+ {
|
||||
+ int y_amount;
|
||||
+
|
||||
+ switch (window->display->grab_op)
|
||||
+ {
|
||||
+ case META_GRAB_OP_RESIZING_N:
|
||||
+ case META_GRAB_OP_KEYBOARD_RESIZING_N:
|
||||
+ case META_GRAB_OP_RESIZING_NE:
|
||||
+ case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
||||
+ case META_GRAB_OP_RESIZING_NW:
|
||||
+ case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
||||
+ case META_GRAB_OP_RESIZING_SE:
|
||||
+ case META_GRAB_OP_KEYBOARD_RESIZING_SE:
|
||||
+ case META_GRAB_OP_RESIZING_S:
|
||||
+ case META_GRAB_OP_KEYBOARD_RESIZING_S:
|
||||
+ case META_GRAB_OP_RESIZING_SW:
|
||||
+ case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
||||
+ y_amount = dy < 0 ? - dy : dy;
|
||||
+ break;
|
||||
+ default:
|
||||
+ y_amount = 0;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (y_amount > threshold)
|
||||
+ new_unmaximize |= META_MAXIMIZE_VERTICAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Metacity doesn't have a full user interface for only horizontally or
|
||||
+ * vertically maximized, so while only unmaximizing in the direction drags
|
||||
+ * has some advantages, it will also confuse the user. So, we always
|
||||
+ * unmaximize both ways if possible.
|
||||
+ */
|
||||
+ if (new_unmaximize != 0)
|
||||
+ {
|
||||
+ new_unmaximize = 0;
|
||||
+
|
||||
+ if (window->maximized_horizontally ||
|
||||
+ (window->display->grab_resize_unmaximize & META_MAXIMIZE_HORIZONTAL) != 0)
|
||||
+ new_unmaximize |= META_MAXIMIZE_HORIZONTAL;
|
||||
+ if (window->maximized_vertically ||
|
||||
+ (window->display->grab_resize_unmaximize & META_MAXIMIZE_VERTICAL) != 0)
|
||||
+ new_unmaximize |= META_MAXIMIZE_VERTICAL;
|
||||
+ }
|
||||
+
|
||||
+ return new_unmaximize;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
update_resize (MetaWindow *window,
|
||||
gboolean snap,
|
||||
@@ -7045,6 +7184,7 @@ update_resize (MetaWindow *window,
|
||||
MetaRectangle old;
|
||||
int new_x, new_y;
|
||||
double remaining;
|
||||
+ MetaMaximizeFlags new_unmaximize;
|
||||
|
||||
window->display->grab_latest_motion_x = x;
|
||||
window->display->grab_latest_motion_y = y;
|
||||
@@ -7109,7 +7249,9 @@ update_resize (MetaWindow *window,
|
||||
meta_window_update_keyboard_resize (window, TRUE);
|
||||
}
|
||||
}
|
||||
-
|
||||
+
|
||||
+ new_unmaximize = check_resize_unmaximize (window, dx, dy);
|
||||
+
|
||||
/* FIXME: This stupidity only needed because of wireframe mode and
|
||||
* the fact that wireframe isn't making use of
|
||||
* meta_rectangle_resize_with_gravity(). If we were to use that, we
|
||||
@@ -7233,6 +7375,8 @@ update_resize (MetaWindow *window,
|
||||
|
||||
if (window->display->grab_wireframe_active)
|
||||
{
|
||||
+ MetaRectangle root_coords;
|
||||
+
|
||||
if ((new_x + new_w <= new_x) || (new_y + new_h <= new_y))
|
||||
return;
|
||||
|
||||
@@ -7242,18 +7386,60 @@ update_resize (MetaWindow *window,
|
||||
* wireframe, but still resize it; however, that probably
|
||||
* confuses broken clients that have problems with opaque
|
||||
* resize, they probably don't track their visibility.
|
||||
+ *
|
||||
+ * We handle the basic constraints on maximized windows here
|
||||
+ * to give the user feedback.
|
||||
*/
|
||||
+
|
||||
+ if (window->maximized_horizontally && (new_unmaximize & META_MAXIMIZE_HORIZONTAL) == 0)
|
||||
+ {
|
||||
+ meta_window_get_client_root_coords (window, &root_coords);
|
||||
+ new_x = root_coords.x;
|
||||
+ new_w = root_coords.width;
|
||||
+ }
|
||||
+ if (window->maximized_vertically && (new_unmaximize & META_MAXIMIZE_VERTICAL) == 0)
|
||||
+ {
|
||||
+ meta_window_get_client_root_coords (window, &root_coords);
|
||||
+ new_y = root_coords.y;
|
||||
+ new_h = root_coords.height;
|
||||
+ }
|
||||
+
|
||||
meta_window_update_wireframe (window, new_x, new_y, new_w, new_h);
|
||||
}
|
||||
else
|
||||
{
|
||||
- /* We don't need to update unless the specified width and height
|
||||
- * are actually different from what we had before.
|
||||
- */
|
||||
- if (old.width != new_w || old.height != new_h)
|
||||
- meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
|
||||
+ if (new_unmaximize == window->display->grab_resize_unmaximize)
|
||||
+ {
|
||||
+ /* We don't need to update unless the specified width and height
|
||||
+ * are actually different from what we had before.
|
||||
+ */
|
||||
+ if (old.width != new_w || old.height != new_h)
|
||||
+ {
|
||||
+ if ((window->display->grab_resize_unmaximize == new_unmaximize))
|
||||
+ meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if ((new_unmaximize & ~window->display->grab_resize_unmaximize) != 0)
|
||||
+ {
|
||||
+ meta_window_unmaximize_with_gravity (window,
|
||||
+ (new_unmaximize & ~window->display->grab_resize_unmaximize),
|
||||
+ new_w, new_h, gravity);
|
||||
+ }
|
||||
+
|
||||
+ if ((window->display->grab_resize_unmaximize & ~new_unmaximize))
|
||||
+ {
|
||||
+ MetaRectangle saved_rect = window->saved_rect;
|
||||
+ meta_window_maximize (window,
|
||||
+ (window->display->grab_resize_unmaximize & ~new_unmaximize));
|
||||
+ window->saved_rect = saved_rect;
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
+ window->display->grab_resize_unmaximize = new_unmaximize;
|
||||
+
|
||||
/* Store the latest resize time, if we actually resized. */
|
||||
if (window->rect.width != old.width || window->rect.height != old.height)
|
||||
g_get_current_time (&window->display->grab_last_moveresize_time);
|
||||
--
|
||||
1.7.0.1
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
Summary: Unobtrusive window manager
|
||||
Name: metacity
|
||||
Version: 2.30.0
|
||||
Release: 5%{?dist}
|
||||
Release: 6%{?dist}
|
||||
URL: http://download.gnome.org/sources/metacity/
|
||||
Source0: http://download.gnome.org/sources/metacity/2.30/metacity-%{version}.tar.bz2
|
||||
# http://bugzilla.gnome.org/show_bug.cgi?id=558723
|
||||
@ -45,6 +45,8 @@ Patch26: libs.patch
|
||||
Patch27: title-click.patch
|
||||
# https://bugzilla.gnome.org/show_bug.cgi?id=599181
|
||||
Patch28: Stop-confusing-GDK-s-grab-tracking.patch
|
||||
# https://bugzilla.gnome.org/show_bug.cgi?id=622517
|
||||
Patch29: Allow-breaking-out-from-maximization-during-mouse.patch
|
||||
|
||||
# default window icon: https://bugzilla.gnome.org/show_bug.cgi?id=616246
|
||||
Patch30: default-window-icon.patch
|
||||
@ -240,6 +242,10 @@ fi
|
||||
%{_mandir}/man1/metacity-window-demo.1.gz
|
||||
|
||||
%changelog
|
||||
* Wed Jun 23 2010 Owen Taylor <otaylor@redhat.com> - 2.30.0-6
|
||||
- Add patch to allow breaking out from maximization during mouse resize
|
||||
(gnome bz 622517)
|
||||
|
||||
* Wed Jun 9 2010 Owen Taylor <otaylor@redhat.com> - 2.30.0-5
|
||||
- Add a patch to fix confusion between windows (rhbz #533066)
|
||||
- Add additional tweeks no_focus_windows and new_windows_always_on_top
|
||||
|
||||
Loading…
Reference in New Issue
Block a user