diff -rudp metacity-cvs-shakeloose-04/src/constraints.c metacity-cvs-shakeloose-04-preserveprop-03/src/constraints.c
--- metacity-cvs-shakeloose-04/src/constraints.c	2006-10-01 22:10:53.000000000 +0200
+++ metacity-cvs-shakeloose-04-preserveprop-03/src/constraints.c	2006-10-01 22:31:28.000000000 +0200
@@ -458,13 +458,15 @@ place_window_if_needed(MetaWindow     *w
 
   /* 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     *w
       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 -rudp metacity-cvs-shakeloose-04/src/display.c metacity-cvs-shakeloose-04-preserveprop-03/src/display.c
--- metacity-cvs-shakeloose-04/src/display.c	2006-10-01 22:10:53.000000000 +0200
+++ metacity-cvs-shakeloose-04-preserveprop-03/src/display.c	2006-10-01 22:31:28.000000000 +0200
@@ -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 -rudp metacity-cvs-shakeloose-04/src/display.h metacity-cvs-shakeloose-04-preserveprop-03/src/display.h
--- metacity-cvs-shakeloose-04/src/display.h	2006-10-01 21:07:18.000000000 +0200
+++ metacity-cvs-shakeloose-04-preserveprop-03/src/display.h	2006-10-01 22:31:48.000000000 +0200
@@ -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 -rudp metacity-cvs-shakeloose-04/src/window.c metacity-cvs-shakeloose-04-preserveprop-03/src/window.c
--- metacity-cvs-shakeloose-04/src/window.c	2006-10-01 22:10:54.000000000 +0200
+++ metacity-cvs-shakeloose-04-preserveprop-03/src/window.c	2006-10-01 22:31:48.000000000 +0200
@@ -445,6 +445,7 @@ meta_window_new_with_attrs (MetaDisplay 
   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;
@@ -758,10 +759,15 @@ meta_window_new_with_attrs (MetaDisplay 
   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);
@@ -2325,13 +2331,32 @@ unmaximize_window_before_freeing (MetaWi
   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 -rudp metacity-cvs-shakeloose-04/src/window.h metacity-cvs-shakeloose-04-preserveprop-03/src/window.h
--- metacity-cvs-shakeloose-04/src/window.h	2006-10-01 22:10:54.000000000 +0200
+++ metacity-cvs-shakeloose-04-preserveprop-03/src/window.h	2006-10-01 22:31:48.000000000 +0200
@@ -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;
diff -rudp metacity-cvs-shakeloose-04/src/window-props.c metacity-cvs-shakeloose-04-preserveprop-03/src/window-props.c
--- metacity-cvs-shakeloose-04/src/window-props.c	2006-10-01 21:07:18.000000000 +0200
+++ metacity-cvs-shakeloose-04-preserveprop-03/src/window-props.c	2006-10-01 22:31:48.000000000 +0200
@@ -459,6 +459,8 @@ reload_net_wm_state (MetaWindow    *wind
         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)
