From 443608282901a16565ef01e70d3fb1f66beb14f5 Mon Sep 17 00:00:00 2001 From: "Owen W. Taylor" Date: Tue, 8 Jul 2014 21:35:47 -0400 Subject: [PATCH 4/4] 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 | 2 +- src/core/window-private.h | 3 ++- src/core/window.c | 33 ++++++++++++++++++++++++++------- 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/core/display.c b/src/core/display.c index 9ed0f6e..90888c5 100644 --- a/src/core/display.c +++ b/src/core/display.c @@ -2613,14 +2613,14 @@ event_callback (XEvent *event, && meta_display_screen_for_root (display, event->xmap.event)) { window = meta_window_new (display, event->xmap.window, - FALSE); + FALSE, FALSE); } break; case MapRequest: if (window == NULL) { window = meta_window_new (display, event->xmaprequest.window, - FALSE); + 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 6db3ea3..6d8d018 100644 --- a/src/core/screen.c +++ b/src/core/screen.c @@ -1093,7 +1093,7 @@ meta_screen_manage_all_windows (MetaScreen *screen) WindowInfo *info = list->data; meta_window_new_with_attrs (screen->display, info->xwindow, TRUE, - META_COMP_EFFECT_NONE, + TRUE, &info->attrs); } meta_stack_thaw (screen->stack); diff --git a/src/core/window-private.h b/src/core/window-private.h index e9f935f..cc77861 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -481,11 +481,12 @@ struct _MetaWindowClass MetaWindow* meta_window_new (MetaDisplay *display, Window xwindow, + gboolean managing_screen, gboolean must_be_viewable); MetaWindow* meta_window_new_with_attrs (MetaDisplay *display, Window xwindow, + gboolean managing_screen, gboolean must_be_viewable, - MetaCompEffect effect, XWindowAttributes *attrs); void meta_window_unmanage (MetaWindow *window, guint32 timestamp); diff --git a/src/core/window.c b/src/core/window.c index 8d221e3..8a290f3 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -40,6 +40,7 @@ #include "keybindings-private.h" #include "ui.h" #include "place.h" +#include #include "session.h" #include #include "resizepopup.h" @@ -659,6 +660,7 @@ maybe_leave_show_desktop_mode (MetaWindow *window) MetaWindow* meta_window_new (MetaDisplay *display, Window xwindow, + gboolean managing_screen, gboolean must_be_viewable) { XWindowAttributes attrs; @@ -682,8 +684,8 @@ meta_window_new (MetaDisplay *display, return NULL; } window = meta_window_new_with_attrs (display, xwindow, + managing_screen, must_be_viewable, - META_COMP_EFFECT_CREATE, &attrs); } else @@ -815,8 +817,8 @@ meta_window_should_attach_to_parent (MetaWindow *window) MetaWindow* meta_window_new_with_attrs (MetaDisplay *display, Window xwindow, + gboolean managing_screen, gboolean must_be_viewable, - MetaCompEffect effect, XWindowAttributes *attrs) { MetaWindow *window; @@ -827,6 +829,8 @@ meta_window_new_with_attrs (MetaDisplay *display, MetaMoveResizeFlags flags; gboolean has_shape; MetaScreen *screen; + MetaCompEffect effect = + managing_screen ? META_COMP_EFFECT_NONE : META_COMP_EFFECT_CREATE; g_assert (attrs != NULL); @@ -1425,12 +1429,27 @@ meta_window_new_with_attrs (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, -- 1.9.3