server: Hide a window before destroying it if it was still visible.
diff --git a/server/window.c b/server/window.c
index a24b2d6..a0e0788 100644
--- a/server/window.c
+++ b/server/window.c
@@ -378,39 +378,6 @@
     win->thread = NULL;
 }
 
-/* destroy a window */
-void destroy_window( struct window *win )
-{
-    /* destroy all children */
-    while (!list_empty(&win->children))
-        destroy_window( LIST_ENTRY( list_head(&win->children), struct window, entry ));
-    while (!list_empty(&win->unlinked))
-        destroy_window( LIST_ENTRY( list_head(&win->unlinked), struct window, entry ));
-
-    /* reset global window pointers, if the corresponding window is destroyed */
-    if (win == shell_window) shell_window = NULL;
-    if (win == shell_listview) shell_listview = NULL;
-    if (win == progman_window) progman_window = NULL;
-    if (win == taskman_window) taskman_window = NULL;
-    free_user_handle( win->handle );
-    destroy_properties( win );
-    list_remove( &win->entry );
-    if (is_desktop_window(win))
-    {
-        struct desktop *desktop = win->desktop;
-        assert( desktop->top_window == win || desktop->msg_window == win );
-        if (desktop->top_window == win) desktop->top_window = NULL;
-        else desktop->msg_window = NULL;
-    }
-    detach_window_thread( win );
-    if (win->win_region) free_region( win->win_region );
-    if (win->update_region) free_region( win->update_region );
-    if (win->class) release_class( win->class );
-    free( win->text );
-    memset( win, 0x55, sizeof(*win) + win->nb_extra_bytes - 1 );
-    free( win );
-}
-
 /* get the process owning the top window of a given desktop */
 struct process *get_top_window_owner( struct desktop *desktop )
 {
@@ -1696,6 +1663,55 @@
 }
 
 
+/* destroy a window */
+void destroy_window( struct window *win )
+{
+    /* hide the window */
+    if (is_visible(win))
+    {
+        struct region *vis_rgn = get_visible_region( win, DCX_WINDOW );
+        win->style &= ~WS_VISIBLE;
+        if (vis_rgn)
+        {
+            struct region *exposed_rgn = expose_window( win, &win->window_rect, vis_rgn );
+            if (exposed_rgn) free_region( exposed_rgn );
+            free_region( vis_rgn );
+        }
+        validate_whole_window( win );
+        validate_children( win );
+    }
+
+    /* destroy all children */
+    while (!list_empty(&win->children))
+        destroy_window( LIST_ENTRY( list_head(&win->children), struct window, entry ));
+    while (!list_empty(&win->unlinked))
+        destroy_window( LIST_ENTRY( list_head(&win->unlinked), struct window, entry ));
+
+    /* reset global window pointers, if the corresponding window is destroyed */
+    if (win == shell_window) shell_window = NULL;
+    if (win == shell_listview) shell_listview = NULL;
+    if (win == progman_window) progman_window = NULL;
+    if (win == taskman_window) taskman_window = NULL;
+    free_user_handle( win->handle );
+    destroy_properties( win );
+    list_remove( &win->entry );
+    if (is_desktop_window(win))
+    {
+        struct desktop *desktop = win->desktop;
+        assert( desktop->top_window == win || desktop->msg_window == win );
+        if (desktop->top_window == win) desktop->top_window = NULL;
+        else desktop->msg_window = NULL;
+    }
+    detach_window_thread( win );
+    if (win->win_region) free_region( win->win_region );
+    if (win->update_region) free_region( win->update_region );
+    if (win->class) release_class( win->class );
+    free( win->text );
+    memset( win, 0x55, sizeof(*win) + win->nb_extra_bytes - 1 );
+    free( win );
+}
+
+
 /* create a window */
 DECL_HANDLER(create_window)
 {