summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@fedoraproject.org>2010-06-24 01:46:47 +0000
committerOwen Taylor <otaylor@fedoraproject.org>2010-06-24 01:46:47 +0000
commit4c6a10fb4330e7e6d6ce0e81931cacc359fdb4f1 (patch)
tree51550e29e5d4fb0927c043c75e0f31af371b3b11
parent7a651cc048552ca0afd6e246e3fea629c41d453a (diff)
downloadmetacity-4c6a10fb4330e7e6d6ce0e81931cacc359fdb4f1.tar.gz
metacity-4c6a10fb4330e7e6d6ce0e81931cacc359fdb4f1.tar.xz
metacity-4c6a10fb4330e7e6d6ce0e81931cacc359fdb4f1.zip
- Add patch to allow breaking out from maximization during mouse resize
(gnome bz 622517)
-rw-r--r--Allow-breaking-out-from-maximization-during-mouse.patch413
-rw-r--r--metacity.spec8
2 files changed, 420 insertions, 1 deletions
diff --git a/Allow-breaking-out-from-maximization-during-mouse.patch b/Allow-breaking-out-from-maximization-during-mouse.patch
new file mode 100644
index 0000000..15005b6
--- /dev/null
+++ b/Allow-breaking-out-from-maximization-during-mouse.patch
@@ -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
+
diff --git a/metacity.spec b/metacity.spec
index 9fb940b..3119e2a 100644
--- a/metacity.spec
+++ b/metacity.spec
@@ -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