From 443608282901a16565ef01e70d3fb1f66beb14f5 Mon Sep 17 00:00:00 2001
From: "Owen W. Taylor" <otaylor@fishsoup.net>
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 <meta/main.h>
#include "session.h"
#include <meta/prefs.h>
#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