diff --git a/ChangeLog b/ChangeLog index d070a9025..676874c4d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2006-10-01 Elijah Newren + + Patch from Carlo Wood to ensure that maximized and minimized + properties are maintained across restarts. #358042. + + * src/constraints.c (place_window_if_needed): fix up partial + maximization handling and add minimize_after_placement handling. + + * src/display.[ch] (struct MetaDisplay, meta_display_open): add a + new display->display_opening flag to allow handling startup + differently where needed. + + * src/window-props.c (reload_net_wm_state): handle + _net_wm_state_hidden as well, setting + window->minimize_after_placement appropriately + + * src/window.[ch] (struct MetaWindow, meta_window_new_with_attrs): + add a window->minimize_after_placement field + + * src/window.c (meta_window_new_with_attrs): only unminimize the + window and its transients if the display isn't being opened, + (unmaximize_window_before_freeing): don't reset the state unless + the window is becoming withdrawn, if the screen is being closed be + sure to save the unmaximized state of the window so the next + window manager can restore it + 2006-10-01 Elijah Newren * src/window-props.c (set_title_text): surround the diff --git a/src/constraints.c b/src/constraints.c index 228d0ad96..4c2fbbc8d 100644 --- a/src/constraints.c +++ b/src/constraints.c @@ -458,13 +458,15 @@ place_window_if_needed(MetaWindow *window, /* Do placement if any, so we go ahead and apply position * constraints in a move-only context. Don't place - * maximized/fullscreen windows until they are unmaximized - * and unfullscreened + * maximized/minimized/fullscreen windows until they are + * unmaximized, unminimized and unfullscreened. */ did_placement = FALSE; if (!window->placed && window->calc_placement && - !META_WINDOW_MAXIMIZED (window) && + !(window->maximized_horizontally || + window->maximized_vertically) && + !window->minimized && !window->fullscreen) { MetaRectangle placed_rect = info->orig; @@ -499,53 +501,47 @@ place_window_if_needed(MetaWindow *window, info->fixed_directions = 0; } - if ((window->maximize_horizontally_after_placement || - window->maximize_vertically_after_placement) && - (window->placed || did_placement)) + if (window->placed || did_placement) { - /* define a sane saved_rect so that the user can unmaximize to - * something reasonable. - */ - if (info->current.width >= info->work_area_xinerama.width) - { - info->current.width = .75 * info->work_area_xinerama.width; - 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; - } - - if (window->maximize_horizontally_after_placement && + if (window->maximize_horizontally_after_placement || window->maximize_vertically_after_placement) - meta_window_maximize_internal (window, - META_MAXIMIZE_HORIZONTAL | - META_MAXIMIZE_VERTICAL, - &info->current); - else if (window->maximize_horizontally_after_placement) { - info->current.x = info->work_area_xinerama.x - + info->fgeom->left_width; - info->current.width = info->work_area_xinerama.width - - info->fgeom->left_width - info->fgeom->right_width; + /* define a sane saved_rect so that the user can unmaximize to + * something reasonable. + */ + if (info->current.width >= info->work_area_xinerama.width) + { + info->current.width = .75 * info->work_area_xinerama.width; + 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; + } + + if (window->maximize_horizontally_after_placement || + window->maximize_vertically_after_placement) + meta_window_maximize_internal (window, + (window->maximize_horizontally_after_placement ? + META_MAXIMIZE_HORIZONTAL : 0 ) | + (window->maximize_vertically_after_placement ? + META_MAXIMIZE_VERTICAL : 0), &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; } - else if (window->maximize_vertically_after_placement); + if (window->minimize_after_placement) { - info->current.y = info->work_area_xinerama.y - + info->fgeom->top_height; - info->current.height = info->work_area_xinerama.height - - info->fgeom->top_height - info->fgeom->bottom_height; + meta_window_minimize (window); + window->minimize_after_placement = FALSE; } - - /* 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; } } diff --git a/src/display.c b/src/display.c index 0f1d82eef..fd6ebcb31 100644 --- a/src/display.c +++ b/src/display.c @@ -363,6 +363,7 @@ meta_display_open (void) display->error_traps = 0; display->error_trap_handler = NULL; display->server_grab_count = 0; + display->display_opening = TRUE; display->pending_pings = NULL; display->autoraise_timeout_id = 0; @@ -767,6 +768,9 @@ meta_display_open (void) if (meta_prefs_get_compositing_manager ()) enable_compositor (display); + /* Done opening new display */ + display->display_opening = FALSE; + return TRUE; } diff --git a/src/display.h b/src/display.h index 689af220b..528e23271 100644 --- a/src/display.h +++ b/src/display.h @@ -311,6 +311,9 @@ struct _MetaDisplay /* Xinerama cache */ unsigned int xinerama_cache_invalidated : 1; + /* Opening the display */ + unsigned int display_opening : 1; + /* Closing down the display */ int closing; diff --git a/src/window-props.c b/src/window-props.c index 92026e08e..49df9aeeb 100644 --- a/src/window-props.c +++ b/src/window-props.c @@ -464,6 +464,8 @@ reload_net_wm_state (MetaWindow *window, window->maximize_horizontally_after_placement = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom_net_wm_state_maximized_vert) window->maximize_vertically_after_placement = TRUE; + else if (value->v.atom_list.atoms[i] == window->display->atom_net_wm_state_hidden) + window->minimize_after_placement = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom_net_wm_state_modal) window->wm_state_modal = TRUE; else if (value->v.atom_list.atoms[i] == window->display->atom_net_wm_state_skip_taskbar) diff --git a/src/window.c b/src/window.c index 31f1ce73e..acccfe66d 100644 --- a/src/window.c +++ b/src/window.c @@ -445,6 +445,7 @@ meta_window_new_with_attrs (MetaDisplay *display, window->maximized_vertically = FALSE; window->maximize_horizontally_after_placement = FALSE; window->maximize_vertically_after_placement = FALSE; + window->minimize_after_placement = FALSE; window->fullscreen = FALSE; window->require_fully_onscreen = TRUE; window->require_on_single_xinerama = TRUE; @@ -757,10 +758,15 @@ meta_window_new_with_attrs (MetaDisplay *display, meta_window_foreach_transient (window, queue_calc_showing_func, NULL); - /* See bug 334899; the window may have minimized ancestors which need to be - * shown. + /* See bug 334899; the window may have minimized ancestors + * which need to be shown. + * + * However, we shouldn't unminimize windows here when opening + * a new display because that breaks passing _NET_WM_STATE_HIDDEN + * between window managers when replacing them; see bug 358042. */ - unminimize_window_and_all_transient_parents (window); + if (!display->display_opening) + unminimize_window_and_all_transient_parents (window); meta_error_trap_pop (display, FALSE); /* pop the XSync()-reducing trap */ meta_display_ungrab (display); @@ -2318,13 +2324,32 @@ unmaximize_window_before_freeing (MetaWindow *window) meta_topic (META_DEBUG_WINDOW_OPS, "Unmaximizing %s just before freeing\n", window->desc); - - window->rect = window->saved_rect; - send_configure_notify (window); window->maximized_horizontally = FALSE; window->maximized_vertically = FALSE; - set_net_wm_state (window); + + if (window->withdrawn) /* See bug #137185 */ + { + window->rect = window->saved_rect; + send_configure_notify (window); + + set_net_wm_state (window); + } + else if (window->screen->closing) /* See bug #358042 */ + { + /* Do NOT update net_wm_state: this screen is closing, + * it likely will be managed by another window manager + * that will need the current _NET_WM_STATE atoms. + * Moreover, it will need to know the unmaximized geometry, + * therefore move_resize the window to saved_rect here + * before closing it. */ + meta_window_move_resize (window, + FALSE, + window->saved_rect.x, + window->saved_rect.y, + window->saved_rect.width, + window->saved_rect.height); + } } void diff --git a/src/window.h b/src/window.h index f31c33da7..2b9dd201a 100644 --- a/src/window.h +++ b/src/window.h @@ -123,8 +123,11 @@ struct _MetaWindow /* Whether we're maximized */ guint maximized_horizontally : 1; guint maximized_vertically : 1; + + /* Whether we have to maximize/minimize after placement */ guint maximize_horizontally_after_placement : 1; guint maximize_vertically_after_placement : 1; + guint minimize_after_placement : 1; /* Whether we're shaded */ guint shaded : 1;