From 2c9463569448d4556f3bfb0ef88bdf1af2dd0a00 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Sun, 23 Oct 2005 05:36:34 +0000 Subject: Make maximize_vertically and maximize_horizontally toggle and be 2005-10-22 Elijah Newren 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 --- ChangeLog | 44 +++++++++ constraints-ideas.txt | 24 ++--- src/constraints.c | 70 +++++++++++---- src/core.c | 10 +-- src/frame.c | 5 +- src/keybindings.c | 28 +++--- src/place.c | 10 +-- src/session.c | 2 +- src/window.c | 241 +++++++++++++++++++++++--------------------------- src/window.h | 23 +++-- 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 + + 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 * 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 (" \n", outfile); /* Maximized */ - if (window->maximized) + if (META_WINDOW_MAXIMIZED (window)) { fprintf (outfile, " \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); -- cgit v1.2.1