summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElijah Newren <newren@gmail.com>2005-10-23 05:36:34 +0000
committerElijah Newren <newren@src.gnome.org>2005-10-23 05:36:34 +0000
commit2c9463569448d4556f3bfb0ef88bdf1af2dd0a00 (patch)
tree0c10d071c0268b3c39a163700ac466a974a6efc2
parent65437e8f7510df7636db0bc6c293d3f896cb17fc (diff)
downloadmetacity-2c9463569448d4556f3bfb0ef88bdf1af2dd0a00.tar.gz
Make maximize_vertically and maximize_horizontally toggle and be
2005-10-22 Elijah Newren <newren@gmail.com> Make maximize_vertically and maximize_horizontally toggle and be constrained. Partially based on patches from John Russell and Bert Vermeulen in bug 113601. * constraints-ideas.txt: I need to remove the compiling warnings from constraints.c sometime even if it's just the compiler being stupid * src/constraints.c (constrain_maximization): constrain different maximization directions individually * src/keybindings.c (handle_maximize_vert, handle_maximize_horiz): have these functions toggle the maximization in the relevant direction * src/window.c (meta_window_save_rect): only save the coordinate for directions that aren't maximized * src/constraints.c (place_window_if_needed, constrain_size_increments, constrain_aspect_ratio): * src/core.c (meta_core_maximize, meta_core_toggle_maximize, meta_core_unmaximize): * src/frame.c (meta_frame_get_flags): * src/keybindings.c (handle_toggle_maximize, handle_maximize, handle_unmaximize): * src/place.c (meta_window_place): * src/session.c (save_state): * src/window.[ch] (struct MetaWindow, meta_window_new_with_attrs, meta_window_apply_session_info, meta_window_free, set_net_wm_state, meta_window_maximize_internal, meta_window_maximize, meta_window_unmaximize, meta_window_client_message, update_net_wm_state, menu_callback, meta_window_show_menu, update_move): need to deal with maximization in separate directions now, use the META_WINDOW_MAXIMIZED() macro for determining when both directions are maximized, and specify the relevant directions to meta_window_(un)maximize(_internal) * src/window.c (check_maximize_to_work_area, meta_window_fill_horizontal, meta_window_fill_vertical): remove these functions as they are no longer needed
-rw-r--r--ChangeLog44
-rw-r--r--constraints-ideas.txt24
-rw-r--r--src/constraints.c70
-rw-r--r--src/core.c10
-rw-r--r--src/frame.c5
-rw-r--r--src/keybindings.c28
-rw-r--r--src/place.c10
-rw-r--r--src/session.c2
-rw-r--r--src/window.c241
-rw-r--r--src/window.h23
10 files changed, 264 insertions, 193 deletions
diff --git a/ChangeLog b/ChangeLog
index 0f523f74..e1d7bdd0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,47 @@
+2005-10-22 Elijah Newren <newren@gmail.com>
+
+ Make maximize_vertically and maximize_horizontally toggle and be
+ constrained. Partially based on patches from John Russell and
+ Bert Vermeulen in bug 113601.
+
+ * constraints-ideas.txt: I need to remove the compiling warnings
+ from constraints.c sometime even if it's just the compiler being
+ stupid
+
+ * src/constraints.c (constrain_maximization): constrain different
+ maximization directions individually
+
+ * src/keybindings.c (handle_maximize_vert, handle_maximize_horiz):
+ have these functions toggle the maximization in the relevant
+ direction
+
+ * src/window.c (meta_window_save_rect): only save the coordinate
+ for directions that aren't maximized
+
+ * src/constraints.c (place_window_if_needed,
+ constrain_size_increments, constrain_aspect_ratio):
+ * src/core.c (meta_core_maximize, meta_core_toggle_maximize,
+ meta_core_unmaximize):
+ * src/frame.c (meta_frame_get_flags):
+ * src/keybindings.c (handle_toggle_maximize, handle_maximize,
+ handle_unmaximize):
+ * src/place.c (meta_window_place):
+ * src/session.c (save_state):
+ * src/window.[ch] (struct MetaWindow, meta_window_new_with_attrs,
+ meta_window_apply_session_info, meta_window_free,
+ set_net_wm_state, meta_window_maximize_internal,
+ meta_window_maximize, meta_window_unmaximize,
+ meta_window_client_message, update_net_wm_state, menu_callback,
+ meta_window_show_menu, update_move):
+ need to deal with maximization in separate directions now, use the
+ META_WINDOW_MAXIMIZED() macro for determining when both directions
+ are maximized, and specify the relevant directions to
+ meta_window_(un)maximize(_internal)
+
+ * src/window.c (check_maximize_to_work_area,
+ meta_window_fill_horizontal, meta_window_fill_vertical): remove
+ these functions as they are no longer needed
+
2005-10-21 Elijah Newren <newren@gmail.com>
* constraints-ideas.txt: Nailed the "gnome-terminal drifts upward
diff --git a/constraints-ideas.txt b/constraints-ideas.txt
index 475763aa..2a0ab5f2 100644
--- a/constraints-ideas.txt
+++ b/constraints-ideas.txt
@@ -1,18 +1,18 @@
Short-term (I hope...) TODO list/reminders:
- - Quicklist I thought of:
- - Titlebar onscreen func should use CLAMP(percent*width, 10, 75)
- for width and 2-3 pixels for height for checking if the titlbar
- is partially onscreen or not
- - on-single-xinerama constraint should not apply if only 1
- xinerama exists
+ - Quicklist that I thought of:
+ - Titlebar onscreen func should use CLAMP(percent*width, 10, 75) for
+ width and 2-3 pixels for height for checking if the titlebar is
+ partially onscreen or not
+ - on-single-xinerama constraint should not apply if only 1 xinerama
+ exists
- use CLAMP() macro in more places of constraints.c
- - Two of meta_window_move_resize_internal() calling methods in
- huge comment are actually the same; search for "bogus" and
- "BEFORE"
- X There may be a bug with gravity an onscreen constraints--it
- seems that creating a tab then removing it and repeating this a
- lot made the window drift northwest. Very weird.
+ - Two of meta_window_move_resize_internal() calling methods in huge
+ comment are actually the same; search for "bogus" and "BEFORE"
+ X There may be a bug with gravity an onscreen constraints--it seems
+ that creating a tab then removing it and repeating this a lot made
+ the window drift northwest. Very weird.
+ - Get rid of compiling warnings for constraints.c even if they're dumb
- Should we turn off fully-onscreen & on-single-xinerama constraints
for decorationless windows? Otherwise, most users (those that
diff --git a/src/constraints.c b/src/constraints.c
index 500ce8d8..abb6ed75 100644
--- a/src/constraints.c
+++ b/src/constraints.c
@@ -644,7 +644,7 @@ place_window_if_needed(MetaWindow *window,
did_placement = FALSE;
if (!window->placed &&
window->calc_placement &&
- !window->maximized &&
+ !META_WINDOW_MAXIMIZED (window) &&
!window->fullscreen)
{
MetaRectangle placed_rect = info->orig;
@@ -675,30 +675,37 @@ place_window_if_needed(MetaWindow *window,
info->fixed_directions = 0;
}
- if (window->maximize_after_placement &&
+ if ((window->maximize_horizontally_after_placement ||
+ window->maximize_vertically_after_placement) &&
(window->placed || did_placement))
{
- window->maximize_after_placement = FALSE;
-
- if (meta_rectangle_could_fit_rect (&info->current,
- &info->work_area_xinerama))
+ /* define a sane saved_rect so that the user can unmaximize to
+ * something reasonable.
+ */
+ if (info->current.width >= info->work_area_xinerama.width)
{
- /* define a sane saved_rect so that the user can unmaximize
- * to something reasonable.
- */
info->current.width = .75 * info->work_area_xinerama.width;
- info->current.height = .75 * info->work_area_xinerama.height;
info->current.x = info->work_area_xinerama.x +
.125 * info->work_area_xinerama.width;
+ }
+ if (info->current.height >= info->work_area_xinerama.height)
+ {
+ info->current.height = .75 * info->work_area_xinerama.height;
info->current.y = info->work_area_xinerama.y +
.083 * info->work_area_xinerama.height;
}
- meta_window_maximize_internal (window, &info->current);
+ if (window->maximize_horizontally_after_placement)
+ meta_window_maximize_internal (window, TRUE, FALSE, &info->current);
+ if (window->maximize_vertically_after_placement);
+ meta_window_maximize_internal (window, FALSE, TRUE, &info->current);
/* maximization may have changed frame geometry */
if (window->frame && !window->fullscreen)
meta_frame_calc_geometry (window->frame, info->fgeom);
+
+ window->maximize_horizontally_after_placement = FALSE;
+ window->maximize_vertically_after_placement = FALSE;
}
}
@@ -831,25 +838,45 @@ constrain_maximization (MetaWindow *window,
return TRUE;
/* Determine whether constraint applies; exit if it doesn't */
- if (!window->maximized)
+ if (!window->maximized_horizontally && !window->maximized_vertically)
return TRUE;
+
MetaRectangle min_size, max_size;
MetaRectangle work_area = info->work_area_xinerama;
unextend_by_frame (&work_area, info->fgeom);
get_size_limits (window, info->fgeom, FALSE, &min_size, &max_size);
- gboolean too_big = !meta_rectangle_could_fit_rect (&work_area, &min_size);
- gboolean too_small = !meta_rectangle_could_fit_rect (&max_size, &work_area);
- if (too_big || too_small)
+
+ gboolean hminbad, vminbad, hmaxbad, vmaxbad;
+ hminbad = work_area.width < min_size.width && window->maximized_horizontally;
+ vminbad = work_area.height < min_size.height && window->maximized_vertically;
+ hmaxbad = work_area.width > max_size.width && window->maximized_horizontally;
+ vmaxbad = work_area.height > max_size.height && window->maximized_vertically;
+ if (hminbad || vminbad || hmaxbad || vmaxbad)
return TRUE;
/* Determine whether constraint is already satisfied; exit if it is */
+ gboolean horiz_equal, vert_equal;
+ horiz_equal = work_area.x == info->current.x &&
+ work_area.width == info->current.width;
+ vert_equal = work_area.y == info->current.y &&
+ work_area.height == info->current.height;
gboolean constraint_already_satisfied =
- meta_rectangle_equal (&info->current, &work_area);
+ (horiz_equal || !window->maximized_horizontally) &&
+ (vert_equal || !window->maximized_vertically);
if (check_only || constraint_already_satisfied)
return constraint_already_satisfied;
/*** Enforce constraint ***/
- info->current = work_area;
+ if (window->maximized_horizontally)
+ {
+ info->current.x = work_area.x;
+ info->current.width = work_area.width;
+ }
+ if (window->maximized_vertically)
+ {
+ info->current.y = work_area.y;
+ info->current.height = work_area.height;
+ }
return TRUE;
}
@@ -894,7 +921,7 @@ constrain_size_increments (MetaWindow *window,
return TRUE;
/* Determine whether constraint applies; exit if it doesn't */
- if (window->maximized || window->fullscreen ||
+ if (META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
info->action_type == ACTION_MOVE)
return TRUE;
@@ -906,6 +933,10 @@ constrain_size_increments (MetaWindow *window,
wi = window->size_hints.width_inc;
extra_height = (info->current.height - bh) % hi;
extra_width = (info->current.width - bw) % wi;
+ if (window->maximized_horizontally)
+ extra_width *= 0;
+ if (window->maximized_vertically)
+ extra_height *= 0;
gboolean constraint_already_satisfied =
(extra_height == 0 && extra_width == 0);
@@ -979,7 +1010,8 @@ constrain_aspect_ratio (MetaWindow *window,
maxr = window->size_hints.max_aspect.x /
(double)window->size_hints.max_aspect.y;
gboolean constraints_are_inconsistent = minr > maxr;
- if (constraints_are_inconsistent || window->maximized || window->fullscreen ||
+ if (constraints_are_inconsistent ||
+ META_WINDOW_MAXIMIZED (window) || window->fullscreen ||
info->action_type == ACTION_MOVE)
return TRUE;
diff --git a/src/core.c b/src/core.c
index c2d0fcbc..88c58db4 100644
--- a/src/core.c
+++ b/src/core.c
@@ -370,7 +370,7 @@ meta_core_maximize (Display *xdisplay,
if (window == NULL || window->frame == NULL)
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
- meta_window_maximize (window);
+ meta_window_maximize (window, TRUE, TRUE);
}
void
@@ -386,10 +386,10 @@ meta_core_toggle_maximize (Display *xdisplay,
if (window == NULL || window->frame == NULL)
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
- if (window->maximized)
- meta_window_unmaximize (window);
+ if (META_WINDOW_MAXIMIZED (window))
+ meta_window_unmaximize (window, TRUE, TRUE);
else
- meta_window_maximize (window);
+ meta_window_maximize (window, TRUE, TRUE);
}
void
@@ -405,7 +405,7 @@ meta_core_unmaximize (Display *xdisplay,
if (window == NULL || window->frame == NULL)
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
- meta_window_unmaximize (window);
+ meta_window_unmaximize (window, TRUE, TRUE);
}
void
diff --git a/src/frame.c b/src/frame.c
index 76e62966..3b8badfc 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -264,7 +264,10 @@ meta_frame_get_flags (MetaFrame *frame)
if (frame->window->on_all_workspaces)
flags |= META_FRAME_STUCK;
- if (frame->window->maximized)
+ /* FIXME: Should we have some kind of UI for windows that are just vertically
+ * maximized or just horizontally maximized?
+ */
+ if (META_WINDOW_MAXIMIZED (frame->window))
flags |= META_FRAME_MAXIMIZED;
if (frame->window->fullscreen)
diff --git a/src/keybindings.c b/src/keybindings.c
index 0f9f31f2..d2990efa 100644
--- a/src/keybindings.c
+++ b/src/keybindings.c
@@ -2747,10 +2747,12 @@ handle_maximize_vert (MetaDisplay *display,
XEvent *event,
MetaKeyBinding *binding)
{
- if (window)
+ if (window && window->has_resize_func)
{
- if (window->has_resize_func)
- meta_window_fill_vertical (window);
+ if (window->maximized_vertically)
+ meta_window_unmaximize (window, FALSE, TRUE);
+ else
+ meta_window_maximize (window, FALSE, TRUE);
}
}
@@ -2761,10 +2763,12 @@ handle_maximize_horiz (MetaDisplay *display,
XEvent *event,
MetaKeyBinding *binding)
{
- if (window)
+ if (window && window->has_resize_func)
{
- if (window->has_resize_func)
- meta_window_fill_horizontal (window);
+ if (window->maximized_horizontally)
+ meta_window_unmaximize (window, TRUE, FALSE);
+ else
+ meta_window_maximize (window, TRUE, FALSE);
}
}
@@ -3190,10 +3194,10 @@ handle_toggle_maximize (MetaDisplay *display,
{
if (window)
{
- if (window->maximized)
- meta_window_unmaximize (window);
+ if (META_WINDOW_MAXIMIZED (window))
+ meta_window_unmaximize (window, TRUE, TRUE);
else if (window->has_maximize_func)
- meta_window_maximize (window);
+ meta_window_maximize (window, TRUE, TRUE);
}
}
@@ -3207,7 +3211,7 @@ handle_maximize (MetaDisplay *display,
if (window)
{
if (window->has_maximize_func)
- meta_window_maximize (window);
+ meta_window_maximize (window, TRUE, TRUE);
}
}
@@ -3220,8 +3224,8 @@ handle_unmaximize (MetaDisplay *display,
{
if (window)
{
- if (window->maximized)
- meta_window_unmaximize (window);
+ if (window->maximized_vertically || window->maximized_horizontally)
+ meta_window_unmaximize (window, TRUE, TRUE);
}
}
diff --git a/src/place.c b/src/place.c
index 5620be2a..9173547d 100644
--- a/src/place.c
+++ b/src/place.c
@@ -985,11 +985,11 @@ meta_window_place (MetaWindow *window,
&workarea);
meta_window_get_outer_rect (window, &outer);
- if (outer.width >= workarea.width &&
- outer.height >= workarea.height)
- {
- window->maximize_after_placement = TRUE;
- }
+ if (outer.width >= workarea.width)
+ window->maximize_horizontally_after_placement = TRUE;
+
+ if (outer.height >= workarea.height)
+ window->maximize_vertically_after_placement = TRUE;
}
done_check_denied_focus:
diff --git a/src/session.c b/src/session.c
index ac9e2142..f561f69e 100644
--- a/src/session.c
+++ b/src/session.c
@@ -953,7 +953,7 @@ save_state (void)
fputs (" <minimized/>\n", outfile);
/* Maximized */
- if (window->maximized)
+ if (META_WINDOW_MAXIMIZED (window))
{
fprintf (outfile,
" <maximized saved_x=\"%d\" saved_y=\"%d\" saved_width=\"%d\" saved_height=\"%d\"/>\n",
diff --git a/src/window.c b/src/window.c
index a4ef71c6..56b185ed 100644
--- a/src/window.c
+++ b/src/window.c
@@ -427,8 +427,10 @@ meta_window_new_with_attrs (MetaDisplay *display,
window->user_has_move_resized = FALSE;
- window->maximized = FALSE;
- window->maximize_after_placement = FALSE;
+ window->maximized_horizontally = FALSE;
+ window->maximized_vertically = FALSE;
+ window->maximize_horizontally_after_placement = FALSE;
+ window->maximize_vertically_after_placement = FALSE;
window->fullscreen = FALSE;
window->require_fully_onscreen = TRUE;
window->require_on_single_xinerama = TRUE;
@@ -769,7 +771,7 @@ meta_window_apply_session_info (MetaWindow *window,
if (window->has_maximize_func && info->maximized)
{
- meta_window_maximize (window);
+ meta_window_maximize (window, TRUE, TRUE);
if (info->saved_rect_set)
{
@@ -962,8 +964,8 @@ meta_window_free (MetaWindow *window)
if (window->display->focus_window == window)
window->display->focus_window = NULL;
- if (window->maximized)
- meta_window_unmaximize (window);
+ if (window->maximized_horizontally || window->maximized_vertically)
+ meta_window_unmaximize (window, TRUE, TRUE);
meta_window_unqueue_calc_showing (window);
meta_window_unqueue_move_resize (window);
@@ -1131,10 +1133,13 @@ set_net_wm_state (MetaWindow *window)
data[i] = window->display->atom_net_wm_state_skip_taskbar;
++i;
}
- if (window->maximized)
+ if (window->maximized_horizontally)
{
data[i] = window->display->atom_net_wm_state_maximized_horz;
++i;
+ }
+ if (window->maximized_vertically)
+ {
data[i] = window->display->atom_net_wm_state_maximized_vert;
++i;
}
@@ -1985,53 +1990,88 @@ meta_window_unminimize (MetaWindow *window)
static void
meta_window_save_rect (MetaWindow *window)
{
- if (!(window->maximized || window->fullscreen))
+ if (!(META_WINDOW_MAXIMIZED (window) || window->fullscreen))
{
/* save size/pos as appropriate args for move_resize */
- window->saved_rect = window->rect;
- if (window->frame)
+ if (!window->maximized_horizontally)
{
- window->saved_rect.x += window->frame->rect.x;
- window->saved_rect.y += window->frame->rect.y;
+ window->saved_rect.x = window->rect.x;
+ window->saved_rect.width = window->rect.width;
+ if (window->frame)
+ window->saved_rect.x += window->frame->rect.x;
+ }
+ if (!window->maximized_vertically)
+ {
+ window->saved_rect.y = window->rect.y;
+ window->saved_rect.height = window->rect.height;
+ if (window->frame)
+ window->saved_rect.y += window->frame->rect.y;
}
}
}
void
meta_window_maximize_internal (MetaWindow *window,
+ gboolean maximize_horizontally,
+ gboolean maximize_vertically,
MetaRectangle *saved_rect)
{
+ g_assert (maximize_horizontally || maximize_vertically);
+
meta_topic (META_DEBUG_WINDOW_OPS,
- "Maximizing %s\n", window->desc);
+ "Maximizing %s%s\n",
+ window->desc,
+ maximize_horizontally && maximize_vertically ? "" :
+ maximize_horizontally ? " horizontally" :
+ maximize_vertically ? " vertically" : "BUGGGGG");
if (saved_rect != NULL)
window->saved_rect = *saved_rect;
else
meta_window_save_rect (window);
- window->maximized = TRUE;
+ window->maximized_horizontally =
+ window->maximized_horizontally || maximize_horizontally;
+ window->maximized_vertically =
+ window->maximized_vertically || maximize_vertically;
recalc_window_features (window);
set_net_wm_state (window);
}
void
-meta_window_maximize (MetaWindow *window)
+meta_window_maximize (MetaWindow *window,
+ gboolean maximize_horizontally,
+ gboolean maximize_vertically)
{
- if (!window->maximized)
+ g_assert (maximize_horizontally || maximize_vertically);
+
+ /* Only do something if the window isn't already maximized in the
+ * given direction(s).
+ */
+ if ((maximize_horizontally && !window->maximized_horizontally) ||
+ (maximize_vertically && !window->maximized_vertically))
{
- if (window->shaded)
+ if (window->shaded && maximize_vertically)
meta_window_unshade (window);
/* if the window hasn't been placed yet, we'll maximize it then
*/
if (!window->placed)
{
- window->maximize_after_placement = TRUE;
+ window->maximize_horizontally_after_placement =
+ window->maximize_horizontally_after_placement ||
+ maximize_horizontally;
+ window->maximize_vertically_after_placement =
+ window->maximize_vertically_after_placement ||
+ maximize_vertically;
return;
}
- meta_window_maximize_internal (window, NULL);
+ meta_window_maximize_internal (window,
+ maximize_horizontally,
+ maximize_vertically,
+ NULL);
/* move_resize with new maximization constraints
*/
@@ -2040,14 +2080,27 @@ meta_window_maximize (MetaWindow *window)
}
void
-meta_window_unmaximize (MetaWindow *window)
+meta_window_unmaximize (MetaWindow *window,
+ gboolean unmaximize_horizontally,
+ gboolean unmaximize_vertically)
{
- if (window->maximized)
+ /* 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))
{
meta_topic (META_DEBUG_WINDOW_OPS,
- "Unmaximizing %s\n", window->desc);
+ "Unmaximizing %s%s\n",
+ window->desc,
+ unmaximize_horizontally && unmaximize_vertically ? "" :
+ unmaximize_horizontally ? " horizontally" :
+ unmaximize_vertically ? " vertically" : "BUGGGGG");
- window->maximized = FALSE;
+ window->maximized_horizontally =
+ window->maximized_horizontally && !unmaximize_horizontally;
+ window->maximized_vertically =
+ window->maximized_vertically && !unmaximize_vertically;
/* When we unmaximize, if we're doing a mouse move also we could
* get the window suddenly jumping to the upper left corner of
@@ -3013,94 +3066,6 @@ meta_window_move_resize_now (MetaWindow *window)
window->rect.height);
}
-static void
-check_maximize_to_work_area (MetaWindow *window,
- const MetaRectangle *work_area)
-{
- /* If we now fill the screen, maximize.
- * the point here is that fill horz + fill vert = maximized
- */
- MetaRectangle rect;
-
- if (!window->has_maximize_func)
- return;
-
- meta_window_get_outer_rect (window, &rect);
-
- /* The logic in this if is basically:
- * if window's left side is at far left or offscreen AND
- * window's bottom side is far top or offscreen AND
- * window's right side is at far right or offscreen AND
- * window's bottom side is at far bottom or offscreen
- * except that we maximize windows with a size increment hint (e.g.
- * terminals) should be maximized if they are "sufficiently close"
- * to the above criteria...
- */
- if ( rect.x <= work_area->x &&
- rect.y <= work_area->y &&
- (((work_area->width + work_area->x) - (rect.width + rect.x)) <
- window->size_hints.width_inc) &&
- (((work_area->height + work_area->y) - (rect.height + rect.y)) <
- window->size_hints.height_inc) )
- meta_window_maximize (window);
-}
-
-void
-meta_window_fill_horizontal (MetaWindow *window)
-{
- MetaRectangle work_area;
- int x, y, w, h;
-
- meta_window_get_user_position (window, &x, &y);
-
- w = window->rect.width;
- h = window->rect.height;
-
- meta_window_get_work_area_current_xinerama (window, &work_area);
-
- x = work_area.x;
- w = work_area.width;
-
- if (window->frame != NULL)
- {
- x += window->frame->child_x;
- w -= (window->frame->child_x + window->frame->right_width);
- }
-
- meta_window_move_resize (window, TRUE,
- x, y, w, h);
-
- check_maximize_to_work_area (window, &work_area);
-}
-
-void
-meta_window_fill_vertical (MetaWindow *window)
-{
- MetaRectangle work_area;
- int x, y, w, h;
-
- meta_window_get_user_position (window, &x, &y);
-
- w = window->rect.width;
- h = window->rect.height;
-
- meta_window_get_work_area_current_xinerama (window, &work_area);
-
- y = work_area.y;
- h = work_area.height;
-
- if (window->frame != NULL)
- {
- y += window->frame->child_y;
- h -= (window->frame->child_y + window->frame->bottom_height);
- }
-
- meta_window_move_resize (window, TRUE,
- x, y, w, h);
-
- check_maximize_to_work_area (window, &work_area);
-}
-
static guint move_resize_idle = 0;
static GSList *move_resize_pending = NULL;
@@ -4305,18 +4270,31 @@ meta_window_client_message (MetaWindow *window,
}
if (first == display->atom_net_wm_state_maximized_horz ||
- second == display->atom_net_wm_state_maximized_horz ||
- first == display->atom_net_wm_state_maximized_vert ||
+ second == display->atom_net_wm_state_maximized_horz)
+ {
+ gboolean max;
+
+ max = (action == _NET_WM_STATE_ADD ||
+ (action == _NET_WM_STATE_TOGGLE &&
+ !window->maximized_horizontally));
+ if (max && window->has_maximize_func)
+ meta_window_maximize (window, TRUE, FALSE);
+ else
+ meta_window_unmaximize (window, TRUE, FALSE);
+ }
+
+ if (first == display->atom_net_wm_state_maximized_vert ||
second == display->atom_net_wm_state_maximized_vert)
{
gboolean max;
max = (action == _NET_WM_STATE_ADD ||
- (action == _NET_WM_STATE_TOGGLE && !window->maximized));
+ (action == _NET_WM_STATE_TOGGLE &&
+ !window->maximized_vertically));
if (max && window->has_maximize_func)
- meta_window_maximize (window);
+ meta_window_maximize (window, FALSE, TRUE);
else
- meta_window_unmaximize (window);
+ meta_window_unmaximize (window, FALSE, TRUE);
}
if (first == display->atom_net_wm_state_modal ||
@@ -4932,7 +4910,8 @@ update_net_wm_state (MetaWindow *window)
Atom *atoms;
window->shaded = FALSE;
- window->maximized = FALSE;
+ window->maximized_horizontally = FALSE;
+ window->maximized_vertically = FALSE;
window->wm_state_modal = FALSE;
window->wm_state_skip_taskbar = FALSE;
window->wm_state_skip_pager = FALSE;
@@ -4952,9 +4931,9 @@ update_net_wm_state (MetaWindow *window)
if (atoms[i] == window->display->atom_net_wm_state_shaded)
window->shaded = TRUE;
else if (atoms[i] == window->display->atom_net_wm_state_maximized_horz)
- window->maximize_after_placement = TRUE;
+ window->maximize_horizontally_after_placement = TRUE;
else if (atoms[i] == window->display->atom_net_wm_state_maximized_vert)
- window->maximize_after_placement = TRUE;
+ window->maximize_vertically_after_placement = TRUE;
else if (atoms[i] == window->display->atom_net_wm_state_modal)
window->wm_state_modal = TRUE;
else if (atoms[i] == window->display->atom_net_wm_state_skip_taskbar)
@@ -6116,11 +6095,11 @@ menu_callback (MetaWindowMenu *menu,
break;
case META_MENU_OP_UNMAXIMIZE:
- meta_window_unmaximize (window);
+ meta_window_unmaximize (window, TRUE, TRUE);
break;
case META_MENU_OP_MAXIMIZE:
- meta_window_maximize (window);
+ meta_window_maximize (window, TRUE, TRUE);
break;
case META_MENU_OP_UNSHADE:
@@ -6267,7 +6246,7 @@ meta_window_show_menu (MetaWindow *window,
ops |= META_MENU_OP_MOVE_DOWN;
}
- if (window->maximized)
+ if (META_WINDOW_MAXIMIZED (window))
ops |= META_MENU_OP_UNMAXIMIZE;
else
ops |= META_MENU_OP_MAXIMIZE;
@@ -6464,7 +6443,7 @@ update_move (MetaWindow *window,
shake_threshold = meta_ui_get_drag_threshold (window->screen->ui) *
DRAG_THRESHOLD_TO_SHAKE_THRESHOLD_FACTOR;
- if (window->maximized && ABS (dy) >= shake_threshold)
+ if (META_WINDOW_MAXIMIZED (window) && ABS (dy) >= shake_threshold)
{
double prop;
@@ -6490,14 +6469,14 @@ update_move (MetaWindow *window,
window->display->grab_anchor_root_x = x;
window->display->grab_anchor_root_y = y;
- meta_window_unmaximize (window);
+ meta_window_unmaximize (window, TRUE, TRUE);
return;
}
/* remaximize window on an other xinerama monitor if window has
* been shaken loose or it is still maximized (then move straight)
*/
- else if (window->shaken_loose || window->maximized)
+ else if (window->shaken_loose || META_WINDOW_MAXIMIZED (window))
{
const MetaXineramaScreenInfo *wxinerama;
MetaRectangle work_area;
@@ -6529,7 +6508,7 @@ update_move (MetaWindow *window,
window->saved_rect.y += window->frame->child_y;
}
- meta_window_unmaximize (window);
+ meta_window_unmaximize (window, TRUE, TRUE);
}
window->display->grab_initial_window_pos = work_area;
@@ -6537,17 +6516,13 @@ update_move (MetaWindow *window,
window->display->grab_anchor_root_y = y;
window->shaken_loose = FALSE;
- meta_window_maximize (window);
+ meta_window_maximize (window, TRUE, TRUE);
return;
}
}
}
- /* don't allow a maximized window to move */
- if (window->maximized)
- return;
-
if (mask & ShiftMask)
{
/* snap to edges */
@@ -6558,6 +6533,12 @@ update_move (MetaWindow *window,
new_y = meta_window_find_nearest_horizontal_edge (window, new_y);
}
+ /* Don't allow movement in the maximized directions */
+ if (window->maximized_horizontally)
+ new_x = window->rect.x;
+ if (window->maximized_vertically)
+ new_y = window->rect.y;
+
if (window->display->grab_wireframe_active)
meta_window_update_wireframe (window, new_x, new_y,
window->display->grab_wireframe_rect.width,
diff --git a/src/window.h b/src/window.h
index 4f01b9e7..a39c96b6 100644
--- a/src/window.h
+++ b/src/window.h
@@ -107,8 +107,10 @@ struct _MetaWindow
Time initial_timestamp;
/* Whether we're maximized */
- guint maximized : 1;
- guint maximize_after_placement : 1;
+ guint maximized_horizontally : 1;
+ guint maximized_vertically : 1;
+ guint maximize_horizontally_after_placement : 1;
+ guint maximize_vertically_after_placement : 1;
/* Whether we're shaded */
guint shaded : 1;
@@ -342,8 +344,10 @@ struct _MetaWindow
* the dynamic window state such as "maximized", not just the
* window's type
*/
+#define META_WINDOW_MAXIMIZED(w) ((w)->maximized_horizontally && \
+ (w)->maximized_vertically)
#define META_WINDOW_ALLOWS_MOVE(w) ((w)->has_move_func && !(w)->fullscreen)
-#define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w) ((w)->has_resize_func && !(w)->maximized && !(w)->fullscreen && !(w)->shaded)
+#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) && \
(((w)->size_hints.min_width < (w)->size_hints.max_width) || \
((w)->size_hints.min_height < (w)->size_hints.max_height)))
@@ -362,10 +366,16 @@ void meta_window_calc_showing (MetaWindow *window);
void meta_window_queue_calc_showing (MetaWindow *window);
void meta_window_minimize (MetaWindow *window);
void meta_window_unminimize (MetaWindow *window);
-void meta_window_maximize (MetaWindow *window);
+void meta_window_maximize (MetaWindow *window,
+ gboolean maximize_horizontally,
+ gboolean maximize_vertically);
void meta_window_maximize_internal (MetaWindow *window,
+ gboolean maximize_horizontally,
+ gboolean maximize_vertically,
MetaRectangle *saved_rect);
-void meta_window_unmaximize (MetaWindow *window);
+void meta_window_unmaximize (MetaWindow *window,
+ gboolean unmaximize_horizontally,
+ gboolean unmaximize_vertically);
void meta_window_make_above (MetaWindow *window);
void meta_window_unmake_above (MetaWindow *window);
void meta_window_shade (MetaWindow *window);
@@ -402,9 +412,6 @@ void meta_window_resize_with_gravity (MetaWindow *window,
int gravity);
-void meta_window_fill_horizontal (MetaWindow *window);
-void meta_window_fill_vertical (MetaWindow *window);
-
/* Return whether the window would be showing if we were on its workspace */
gboolean meta_window_showing_on_its_workspace (MetaWindow *window);