[mutter/wip/quadbuffer-stereo: 3/4] Leave windows in place on a crash respawn



commit cf67327f0edc6cdef07b1346e565507220991c4f
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Tue Jul 8 21:35:47 2014 -0400

    Leave windows in place on a crash respawn
    
    When Mutter is restarted and cleans up the window positions
    cleanly, we need to add gravity adjustments. We can detect
    this easily.
    
     - Windows started before the window manager (should add
       add gravity adjustments)
     - Replacing a different window manager (should add gravity
       adjustments)
     - A crash (no adjustments needed)
    
    In GNOME the first two cases shouldn't happen in normal
    usage, so assume the third case (though that *shouldn't*
    happen in normal usage either.)

 src/core/display.c        |    4 ++--
 src/core/screen.c         |    3 +--
 src/core/window-private.h |    4 ++--
 src/core/window.c         |   32 +++++++++++++++++++++++++-------
 4 files changed, 30 insertions(+), 13 deletions(-)
---
diff --git a/src/core/display.c b/src/core/display.c
index dac97f4..f9eb71c 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -2836,14 +2836,14 @@ event_callback (XEvent   *event,
               && meta_display_screen_for_root (display, event->xmap.event))
             {
               window = meta_window_new (display, event->xmap.window,
-                                        FALSE, META_COMP_EFFECT_CREATE);
+                                        FALSE, FALSE);
             }
           break;
         case MapRequest:
           if (window == NULL)
             {
               window = meta_window_new (display, event->xmaprequest.window,
-                                        FALSE, META_COMP_EFFECT_CREATE);
+                                        FALSE, FALSE);
             }
           /* if frame was receiver it's some malicious send event or something */
           else if (!frame_was_receiver && window)        
diff --git a/src/core/screen.c b/src/core/screen.c
index ec368b8..f486c03 100644
--- a/src/core/screen.c
+++ b/src/core/screen.c
@@ -891,8 +891,7 @@ meta_screen_manage_all_windows (MetaScreen *screen)
 
   for (i = 0; i < n_children; ++i)
     {
-      meta_window_new (screen->display, children[i], TRUE,
-                       META_COMP_EFFECT_NONE);
+      meta_window_new (screen->display, children[i], TRUE, TRUE);
     }
 
   g_free (children);
diff --git a/src/core/window-private.h b/src/core/window-private.h
index fbeacab..e3fa92b 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -488,8 +488,8 @@ struct _MetaWindowClass
 
 MetaWindow* meta_window_new                (MetaDisplay *display,
                                             Window       xwindow,
-                                            gboolean     must_be_viewable,
-                                            MetaCompEffect     effect);
+                                            gboolean     managing_screen,
+                                            gboolean     must_be_viewable);
 void        meta_window_unmanage           (MetaWindow  *window,
                                             guint32      timestamp);
 void        meta_window_calc_showing       (MetaWindow  *window);
diff --git a/src/core/window.c b/src/core/window.c
index af52a3a..a7f0e33 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -38,6 +38,7 @@
 #include "keybindings-private.h"
 #include "ui.h"
 #include "place.h"
+#include <meta/main.h>
 #include "session.h"
 #include <meta/prefs.h>
 #include "resizepopup.h"
@@ -844,8 +845,8 @@ sync_client_window_mapped (MetaWindow *window)
 MetaWindow*
 meta_window_new (MetaDisplay   *display,
                  Window         xwindow,
-                 gboolean       must_be_viewable,
-                 MetaCompEffect effect)
+                 gboolean       managing_screen,
+                 gboolean       must_be_viewable)
 {
   XWindowAttributes    attrs;
   MetaWindow *window;
@@ -855,6 +856,8 @@ meta_window_new (MetaDisplay   *display,
   gulong event_mask;
   MetaMoveResizeFlags flags;
   MetaScreen *screen;
+  MetaCompEffect effect =
+    managing_screen ? META_COMP_EFFECT_NONE : META_COMP_EFFECT_CREATE;
 
   meta_verbose ("Attempting to manage 0x%lx\n", xwindow);
 
@@ -1434,12 +1437,27 @@ meta_window_new (MetaDisplay   *display,
   else
     window->layer = META_LAYER_OVERRIDE_REDIRECT; /* otherwise set by MetaStack */
 
-  /* Put our state back where it should be,
-   * passing TRUE for is_configure_request, ICCCM says
-   * initial map is handled same as configure request
-   */
   flags =
-    META_IS_CONFIGURE_REQUEST | META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION | META_IS_INITIAL_RESIZE;
+    META_IS_MOVE_ACTION | META_IS_RESIZE_ACTION | META_IS_INITIAL_RESIZE;
+
+  /* ICCCM says initial map is handled same as configure request. When
+   * we are initially managing the screen, we distinguish two cases:
+   *
+   *  Restart: in this case, we put the windows back to the unframed
+   *   position before exiting, so we need to give them gravity
+   *   adjustments.
+   *  Something else: (perhaps a crash) if we didn't exit cleanly, then
+   *   windows will be reparented by the X server so that the client
+   *   origin stays the same, and no frame adjustment is needed.
+   *
+   * We don't have any way to distinguish replacing a different window
+   * manager from respawning on crash, so when we replace a different
+   * window manager, windows will shift onscreen, but this is expected
+   * to only happen in development.
+   */
+  if (!managing_screen || meta_is_restart())
+    flags |= META_IS_CONFIGURE_REQUEST;
+
   if (!window->override_redirect)
     meta_window_move_resize_internal (window,
                                       flags,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]