1 diff -upr marco-1.4.1-orig/src/core/display.c marco-1.4.1/src/core/display.c
2 --- marco-1.4.1-orig/src/core/display.c 2012-08-21 21:42:39.000000000 +0200
3 +++ marco-1.4.1/src/core/display.c 2012-08-25 14:51:42.021447065 +0200
4 @@ -3512,6 +3512,7 @@ meta_display_begin_grab_op (MetaDisplay
6 display->grab_was_cancelled = FALSE;
7 display->grab_frame_action = frame_action;
8 + display->grab_resize_unmaximize = 0;
10 if (display->grab_resize_timeout_id)
12 @@ -3753,11 +3754,20 @@ meta_display_end_grab_op (MetaDisplay *d
13 display->grab_wireframe_rect.x,
14 display->grab_wireframe_rect.y);
15 if (meta_grab_op_is_resizing (display->grab_op))
16 - meta_window_resize_with_gravity (display->grab_window,
18 - display->grab_wireframe_rect.width,
19 - display->grab_wireframe_rect.height,
20 - meta_resize_gravity_from_grab_op (display->grab_op));
22 + if (display->grab_resize_unmaximize != 0)
23 + meta_window_unmaximize_with_gravity (display->grab_window,
24 + display->grab_resize_unmaximize,
25 + display->grab_wireframe_rect.width,
26 + display->grab_wireframe_rect.height,
27 + meta_resize_gravity_from_grab_op (display->grab_op));
29 + meta_window_resize_with_gravity (display->grab_window,
31 + display->grab_wireframe_rect.width,
32 + display->grab_wireframe_rect.height,
33 + meta_resize_gravity_from_grab_op (display->grab_op));
36 meta_window_calc_showing (display->grab_window);
38 diff -upr marco-1.4.1-orig/src/core/display-private.h marco-1.4.1/src/core/display-private.h
39 --- marco-1.4.1-orig/src/core/display-private.h 2012-08-21 21:42:39.000000000 +0200
40 +++ marco-1.4.1/src/core/display-private.h 2012-08-25 14:48:47.159605550 +0200
41 @@ -163,6 +163,9 @@ struct _MetaDisplay {
42 guint grab_wireframe_active : 1;
43 guint grab_was_cancelled : 1; /* Only used in wireframe mode */
44 guint grab_frame_action : 1;
45 + /* During a resize operation, the directions in which we've broken
46 + * out of the initial maximization state */
47 + guint grab_resize_unmaximize : 2; /* MetaMaximizeFlags */
48 MetaRectangle grab_wireframe_rect;
49 MetaRectangle grab_wireframe_last_xor_rect;
50 MetaRectangle grab_initial_window_pos;
51 diff -upr marco-1.4.1-orig/src/core/window.c marco-1.4.1/src/core/window.c
52 --- marco-1.4.1-orig/src/core/window.c 2012-08-21 21:42:39.000000000 +0200
53 +++ marco-1.4.1/src/core/window.c 2012-08-25 15:11:22.636859026 +0200
54 @@ -2666,9 +2666,11 @@ unmaximize_window_before_freeing (MetaWi
59 -meta_window_unmaximize (MetaWindow *window,
60 - MetaMaximizeFlags directions)
62 +meta_window_unmaximize_internal (MetaWindow *window,
63 + MetaMaximizeFlags directions,
64 + MetaRectangle *desired_rect,
67 /* At least one of the two directions ought to be set */
68 gboolean unmaximize_horizontally, unmaximize_vertically;
69 @@ -2702,13 +2704,13 @@ meta_window_unmaximize (MetaWindow
70 meta_window_get_client_root_coords (window, &target_rect);
71 if (unmaximize_horizontally)
73 - target_rect.x = window->saved_rect.x;
74 - target_rect.width = window->saved_rect.width;
75 + target_rect.x = desired_rect->x;
76 + target_rect.width = desired_rect->width;
78 if (unmaximize_vertically)
80 - target_rect.y = window->saved_rect.y;
81 - target_rect.height = window->saved_rect.height;
82 + target_rect.y = desired_rect->y;
83 + target_rect.height = desired_rect->height;
86 /* Window's size hints may have changed while maximized, making
87 @@ -2727,12 +2729,13 @@ meta_window_unmaximize (MetaWindow
88 window->display->grab_anchor_window_pos = target_rect;
91 - meta_window_move_resize (window,
96 - target_rect.height);
97 + meta_window_move_resize_internal (window,
98 + META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION,
103 + target_rect.height);
105 /* Make sure user_rect is current.
107 @@ -2749,6 +2752,36 @@ meta_window_unmaximize (MetaWindow
111 +meta_window_unmaximize (MetaWindow *window,
112 + MetaMaximizeFlags directions)
114 + meta_window_unmaximize_internal (window, directions, &window->saved_rect,
118 +/* Like meta_window_unmaximize(), but instead of unmaximizing to the
119 + * saved position, we give the new desired size, and the gravity that
120 + * determines the positioning relationship between the area occupied
121 + * maximized and the new are. The arguments are similar to
122 + * meta_window_resize_with_gravity().
125 +meta_window_unmaximize_with_gravity (MetaWindow *window,
126 + MetaMaximizeFlags directions,
131 + MetaRectangle desired_rect;
133 + meta_window_get_position (window, &desired_rect.x, &desired_rect.y);
134 + desired_rect.width = new_width;
135 + desired_rect.height = new_height;
137 + meta_window_unmaximize_internal (window, directions, &desired_rect, gravity);
141 meta_window_make_above (MetaWindow *window)
143 window->wm_state_above = TRUE;
144 @@ -7033,6 +7066,112 @@ update_resize_timeout (gpointer data)
148 +/* When resizing a maximized window by using alt-middle-drag (resizing
149 + * with the grips or the menu for a maximized window is not enabled),
150 + * the user can "break" out of the maximized state. This checks for
151 + * that possibility. During such a break-out resize the user can also
152 + * return to the previous maximization state by resizing back to near
153 + * the original size.
155 +static MetaMaximizeFlags
156 +check_resize_unmaximize(MetaWindow *window,
161 + MetaMaximizeFlags new_unmaximize;
163 +#define DRAG_THRESHOLD_TO_RESIZE_THRESHOLD_FACTOR 3
165 + threshold = meta_ui_get_drag_threshold (window->screen->ui) *
166 + DRAG_THRESHOLD_TO_RESIZE_THRESHOLD_FACTOR;
167 + new_unmaximize = 0;
169 + if (window->maximized_horizontally ||
170 + (window->display->grab_resize_unmaximize & META_MAXIMIZE_HORIZONTAL) != 0)
174 + /* We allow breaking out of maximization in either direction, to make
175 + * the window larger than the monitor as well as smaller than the
176 + * monitor. If we wanted to only allow resizing smaller than the
177 + * monitor, we'd use - dx for NE/E/SE and dx for SW/W/NW.
179 + switch (window->display->grab_op)
181 + case META_GRAB_OP_RESIZING_NE:
182 + case META_GRAB_OP_KEYBOARD_RESIZING_NE:
183 + case META_GRAB_OP_RESIZING_E:
184 + case META_GRAB_OP_KEYBOARD_RESIZING_E:
185 + case META_GRAB_OP_RESIZING_SE:
186 + case META_GRAB_OP_KEYBOARD_RESIZING_SE:
187 + case META_GRAB_OP_RESIZING_SW:
188 + case META_GRAB_OP_KEYBOARD_RESIZING_SW:
189 + case META_GRAB_OP_RESIZING_W:
190 + case META_GRAB_OP_KEYBOARD_RESIZING_W:
191 + case META_GRAB_OP_RESIZING_NW:
192 + case META_GRAB_OP_KEYBOARD_RESIZING_NW:
193 + x_amount = dx < 0 ? - dx : dx;
200 + if (x_amount > threshold)
201 + new_unmaximize |= META_MAXIMIZE_HORIZONTAL;
204 + if (window->maximized_vertically ||
205 + (window->display->grab_resize_unmaximize & META_MAXIMIZE_VERTICAL) != 0)
209 + switch (window->display->grab_op)
211 + case META_GRAB_OP_RESIZING_N:
212 + case META_GRAB_OP_KEYBOARD_RESIZING_N:
213 + case META_GRAB_OP_RESIZING_NE:
214 + case META_GRAB_OP_KEYBOARD_RESIZING_NE:
215 + case META_GRAB_OP_RESIZING_NW:
216 + case META_GRAB_OP_KEYBOARD_RESIZING_NW:
217 + case META_GRAB_OP_RESIZING_SE:
218 + case META_GRAB_OP_KEYBOARD_RESIZING_SE:
219 + case META_GRAB_OP_RESIZING_S:
220 + case META_GRAB_OP_KEYBOARD_RESIZING_S:
221 + case META_GRAB_OP_RESIZING_SW:
222 + case META_GRAB_OP_KEYBOARD_RESIZING_SW:
223 + y_amount = dy < 0 ? - dy : dy;
230 + if (y_amount > threshold)
231 + new_unmaximize |= META_MAXIMIZE_VERTICAL;
234 + /* Marco doesn't have a full user interface for only horizontally or
235 + * vertically maximized, so while only unmaximizing in the direction drags
236 + * has some advantages, it will also confuse the user. So, we always
237 + * unmaximize both ways if possible.
239 + if (new_unmaximize != 0)
241 + new_unmaximize = 0;
243 + if (window->maximized_horizontally ||
244 + (window->display->grab_resize_unmaximize & META_MAXIMIZE_HORIZONTAL) != 0)
245 + new_unmaximize |= META_MAXIMIZE_HORIZONTAL;
246 + if (window->maximized_vertically ||
247 + (window->display->grab_resize_unmaximize & META_MAXIMIZE_VERTICAL) != 0)
248 + new_unmaximize |= META_MAXIMIZE_VERTICAL;
251 + return new_unmaximize;
255 update_resize (MetaWindow *window,
257 @@ -7045,6 +7184,7 @@ update_resize (MetaWindow *window,
261 + MetaMaximizeFlags new_unmaximize;
263 window->display->grab_latest_motion_x = x;
264 window->display->grab_latest_motion_y = y;
265 @@ -7233,6 +7373,8 @@ update_resize (MetaWindow *window,
267 if (window->display->grab_wireframe_active)
269 + MetaRectangle root_coords;
271 if ((new_x + new_w <= new_x) || (new_y + new_h <= new_y))
274 @@ -7242,16 +7384,56 @@ update_resize (MetaWindow *window,
275 * wireframe, but still resize it; however, that probably
276 * confuses broken clients that have problems with opaque
277 * resize, they probably don't track their visibility.
279 + * We handle the basic constraints on maximized windows here
280 + * to give the user feedback.
283 + if (window->maximized_horizontally && (new_unmaximize & META_MAXIMIZE_HORIZONTAL) == 0)
285 + meta_window_get_client_root_coords (window, &root_coords);
286 + new_x = root_coords.x;
287 + new_w = root_coords.width;
289 + if (window->maximized_vertically && (new_unmaximize & META_MAXIMIZE_VERTICAL) == 0)
291 + meta_window_get_client_root_coords (window, &root_coords);
292 + new_y = root_coords.y;
293 + new_h = root_coords.height;
296 meta_window_update_wireframe (window, new_x, new_y, new_w, new_h);
300 - /* We don't need to update unless the specified width and height
301 - * are actually different from what we had before.
303 - if (old.width != new_w || old.height != new_h)
304 - meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
305 + if (new_unmaximize == window->display->grab_resize_unmaximize)
307 + /* We don't need to update unless the specified width and height
308 + * are actually different from what we had before.
310 + if (old.width != new_w || old.height != new_h)
312 + if ((window->display->grab_resize_unmaximize == new_unmaximize))
313 + meta_window_resize_with_gravity (window, TRUE, new_w, new_h, gravity);
318 + if ((new_unmaximize & ~window->display->grab_resize_unmaximize) != 0)
320 + meta_window_unmaximize_with_gravity (window,
321 + (new_unmaximize & ~window->display->grab_resize_unmaximize),
322 + new_w, new_h, gravity);
325 + if ((window->display->grab_resize_unmaximize & ~new_unmaximize))
327 + MetaRectangle saved_rect = window->saved_rect;
328 + meta_window_maximize (window,
329 + (window->display->grab_resize_unmaximize & ~new_unmaximize));
330 + window->saved_rect = saved_rect;
335 /* Store the latest resize time, if we actually resized. */
336 diff -upr marco-1.4.1-orig/src/core/window-private.h marco-1.4.1/src/core/window-private.h
337 --- marco-1.4.1-orig/src/core/window-private.h 2012-08-21 21:42:39.000000000 +0200
338 +++ marco-1.4.1/src/core/window-private.h 2012-08-25 14:53:44.522736630 +0200
339 @@ -412,6 +412,12 @@ void meta_window_maximize_interna
340 MetaRectangle *saved_rect);
341 void meta_window_unmaximize (MetaWindow *window,
342 MetaMaximizeFlags directions);
343 +void meta_window_unmaximize_with_gravity (MetaWindow *window,
344 + MetaMaximizeFlags directions,
348 +void meta_window_make_above (MetaWindow *window);
349 void meta_window_make_above (MetaWindow *window);
350 void meta_window_unmake_above (MetaWindow *window);
351 void meta_window_shade (MetaWindow *window,