|
|
68333f |
From 6710b03d1ebafc15ee4e826a5281204c6441c083 Mon Sep 17 00:00:00 2001
|
|
|
68333f |
From: "Owen W. Taylor" <otaylor@fishsoup.net>
|
|
|
68333f |
Date: Thu, 8 May 2014 18:35:49 -0400
|
|
|
68333f |
Subject: [PATCH 1/4] Add a framework for restarting the compositor with nice
|
|
|
68333f |
visuals
|
|
|
68333f |
|
|
|
68333f |
The current GNOME Shell Alt-F2 restart looks very messy and also
|
|
|
68333f |
provides no indication to the user what is going on. We need to
|
|
|
68333f |
restart the compositor to switch in and out of stereo mode, so
|
|
|
68333f |
add a framework for doing this more cleanly:
|
|
|
68333f |
|
|
|
68333f |
Additions:
|
|
|
68333f |
|
|
|
68333f |
meta_restart(): restarts the compositor with a message
|
|
|
68333f |
MetaDisplay::show-restart-message: signal the embedding
|
|
|
68333f |
shell to show a message
|
|
|
68333f |
MetaDisplay::restart: signal the embedding shell to restart
|
|
|
68333f |
itself.
|
|
|
68333f |
meta_is_restart(): indicates whether the current instance is a
|
|
|
68333f |
restart so we can suppress login animations.
|
|
|
68333f |
|
|
|
68333f |
A helper program meta-restart-helper holds the composite overlay
|
|
|
68333f |
window up during the restart to avoid visual artifacts.
|
|
|
68333f |
|
|
|
68333f |
https://bugzilla.gnome.org/show_bug.cgi?id=733026
|
|
|
68333f |
---
|
|
|
68333f |
configure.ac | 1 +
|
|
|
68333f |
src/Makefile.am | 5 ++
|
|
|
68333f |
src/compositor/compositor.c | 5 ++
|
|
|
68333f |
src/core/display-private.h | 7 ++
|
|
|
68333f |
src/core/display.c | 80 +++++++++++++++++
|
|
|
68333f |
src/core/main.c | 3 +
|
|
|
68333f |
src/core/restart-helper.c | 82 +++++++++++++++++
|
|
|
68333f |
src/core/restart.c | 212 ++++++++++++++++++++++++++++++++++++++++++++
|
|
|
68333f |
src/meta/main.h | 3 +
|
|
|
68333f |
9 files changed, 398 insertions(+)
|
|
|
68333f |
create mode 100644 src/core/restart-helper.c
|
|
|
68333f |
create mode 100644 src/core/restart.c
|
|
|
68333f |
|
|
|
68333f |
diff --git a/configure.ac b/configure.ac
|
|
|
68333f |
index 6e9ca8c..dcd8a54 100644
|
|
|
68333f |
--- a/configure.ac
|
|
|
68333f |
+++ b/configure.ac
|
|
|
68333f |
@@ -69,6 +69,7 @@ CLUTTER_PACKAGE=clutter-1.0
|
|
|
68333f |
MUTTER_PC_MODULES="
|
|
|
68333f |
gtk+-3.0 >= 3.3.7
|
|
|
68333f |
gio-2.0 >= 2.25.10
|
|
|
68333f |
+ gio-unix-2.0 >= 2.25.10
|
|
|
68333f |
pango >= 1.2.0
|
|
|
68333f |
cairo >= 1.10.0
|
|
|
68333f |
gsettings-desktop-schemas >= 3.7.3
|
|
|
68333f |
diff --git a/src/Makefile.am b/src/Makefile.am
|
|
|
68333f |
index e2cec91..d664b54 100644
|
|
|
68333f |
--- a/src/Makefile.am
|
|
|
68333f |
+++ b/src/Makefile.am
|
|
|
68333f |
@@ -119,6 +119,7 @@ libmutter_la_SOURCES = \
|
|
|
68333f |
core/screen-private.h \
|
|
|
68333f |
meta/screen.h \
|
|
|
68333f |
meta/types.h \
|
|
|
68333f |
+ core/restart.c \
|
|
|
68333f |
core/session.c \
|
|
|
68333f |
core/session.h \
|
|
|
68333f |
core/stack.c \
|
|
|
68333f |
@@ -213,6 +214,10 @@ bin_PROGRAMS=mutter mutter-theme-viewer
|
|
|
68333f |
mutter_SOURCES = core/mutter.c
|
|
|
68333f |
mutter_LDADD = $(MUTTER_LIBS) libmutter.la
|
|
|
68333f |
|
|
|
68333f |
+libexec_PROGRAMS = mutter-restart-helper
|
|
|
68333f |
+mutter_restart_helper_SOURCES = core/restart-helper.c
|
|
|
68333f |
+mutter_restart_helper_LDADD = $(MUTTER_LIBS)
|
|
|
68333f |
+
|
|
|
68333f |
if HAVE_INTROSPECTION
|
|
|
68333f |
include $(INTROSPECTION_MAKEFILE)
|
|
|
68333f |
|
|
|
68333f |
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
|
|
|
68333f |
index 91b477f..539a7a6 100644
|
|
|
68333f |
--- a/src/compositor/compositor.c
|
|
|
68333f |
+++ b/src/compositor/compositor.c
|
|
|
68333f |
@@ -86,6 +86,7 @@
|
|
|
68333f |
#include "meta-window-group.h"
|
|
|
68333f |
#include "window-private.h" /* to check window->hidden */
|
|
|
68333f |
#include "display-private.h" /* for meta_display_lookup_x_window() */
|
|
|
68333f |
+#include "util-private.h"
|
|
|
68333f |
#include <X11/extensions/shape.h>
|
|
|
68333f |
#include <X11/extensions/Xcomposite.h>
|
|
|
68333f |
|
|
|
68333f |
@@ -216,6 +217,10 @@ get_output_window (MetaScreen *screen)
|
|
|
68333f |
xroot = meta_screen_get_xroot (screen);
|
|
|
68333f |
output = XCompositeGetOverlayWindow (xdisplay, xroot);
|
|
|
68333f |
|
|
|
68333f |
+ /* Now that we've gotten taken a reference count on the COW, we
|
|
|
68333f |
+ * can close the helper that is holding on to it */
|
|
|
68333f |
+ meta_restart_finish ();
|
|
|
68333f |
+
|
|
|
68333f |
meta_core_add_old_event_mask (xdisplay, output, &mask);
|
|
|
68333f |
|
|
|
68333f |
XISetMask (mask.mask, XI_KeyPress);
|
|
|
68333f |
diff --git a/src/core/display-private.h b/src/core/display-private.h
|
|
|
68333f |
index 3423fb1..d227492 100644
|
|
|
68333f |
--- a/src/core/display-private.h
|
|
|
68333f |
+++ b/src/core/display-private.h
|
|
|
68333f |
@@ -470,4 +470,11 @@ gboolean meta_display_process_barrier_event (MetaDisplay *display,
|
|
|
68333f |
XIBarrierEvent *event);
|
|
|
68333f |
#endif /* HAVE_XI23 */
|
|
|
68333f |
|
|
|
68333f |
+gboolean meta_display_show_restart_message (MetaDisplay *display,
|
|
|
68333f |
+ const char *message);
|
|
|
68333f |
+gboolean meta_display_request_restart (MetaDisplay *display);
|
|
|
68333f |
+
|
|
|
68333f |
+void meta_restart_init (void);
|
|
|
68333f |
+void meta_restart_finish (void);
|
|
|
68333f |
+
|
|
|
68333f |
#endif
|
|
|
68333f |
diff --git a/src/core/display.c b/src/core/display.c
|
|
|
68333f |
index d611314..9ed0f6e 100644
|
|
|
68333f |
--- a/src/core/display.c
|
|
|
68333f |
+++ b/src/core/display.c
|
|
|
68333f |
@@ -146,6 +146,8 @@ enum
|
|
|
68333f |
WINDOW_MARKED_URGENT,
|
|
|
68333f |
GRAB_OP_BEGIN,
|
|
|
68333f |
GRAB_OP_END,
|
|
|
68333f |
+ SHOW_RESTART_MESSAGE,
|
|
|
68333f |
+ RESTART,
|
|
|
68333f |
LAST_SIGNAL
|
|
|
68333f |
};
|
|
|
68333f |
|
|
|
68333f |
@@ -322,6 +324,59 @@ meta_display_class_init (MetaDisplayClass *klass)
|
|
|
68333f |
META_TYPE_WINDOW,
|
|
|
68333f |
META_TYPE_GRAB_OP);
|
|
|
68333f |
|
|
|
68333f |
+ /**
|
|
|
68333f |
+ * MetaDisplay::show-restart-message:
|
|
|
68333f |
+ * @display: the #MetaDisplay instance
|
|
|
68333f |
+ * @message: (allow-none): The message to display, or %NULL
|
|
|
68333f |
+ * to clear a previous restart message.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * The ::show-restart-message signal will be emitted to indicate
|
|
|
68333f |
+ * that the compositor should show a message during restart. This is
|
|
|
68333f |
+ * emitted when meta_restart() is called, either by Mutter
|
|
|
68333f |
+ * internally or by the embedding compositor. The message should be
|
|
|
68333f |
+ * immediately added to the Clutter stage in its final form -
|
|
|
68333f |
+ * ::restart will be emitted to exit the application and leave the
|
|
|
68333f |
+ * stage contents frozen as soon as the the stage is painted again.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * On case of failure to restart, this signal will be emitted again
|
|
|
68333f |
+ * with %NULL for @message.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * Returns: %TRUE means the message was added to the stage; %FALSE
|
|
|
68333f |
+ * indicates that the compositor did not show the message.
|
|
|
68333f |
+ */
|
|
|
68333f |
+ display_signals[SHOW_RESTART_MESSAGE] =
|
|
|
68333f |
+ g_signal_new ("show-restart-message",
|
|
|
68333f |
+ G_TYPE_FROM_CLASS (klass),
|
|
|
68333f |
+ G_SIGNAL_RUN_LAST,
|
|
|
68333f |
+ 0,
|
|
|
68333f |
+ g_signal_accumulator_true_handled,
|
|
|
68333f |
+ NULL, NULL,
|
|
|
68333f |
+ G_TYPE_BOOLEAN, 1,
|
|
|
68333f |
+ G_TYPE_STRING);
|
|
|
68333f |
+
|
|
|
68333f |
+ /**
|
|
|
68333f |
+ * MetaDisplay::restart:
|
|
|
68333f |
+ * @display: the #MetaDisplay instance
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * The ::restart signal is emitted to indicate that compositor
|
|
|
68333f |
+ * should reexec the process. This is
|
|
|
68333f |
+ * emitted when meta_restart() is called, either by Mutter
|
|
|
68333f |
+ * internally or by the embedding compositor. See also
|
|
|
68333f |
+ * ::show-restart-message.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * Returns: %FALSE to indicate that the compositor could not
|
|
|
68333f |
+ * be restarted. When the compositor is restarted, the signal
|
|
|
68333f |
+ * should not return.
|
|
|
68333f |
+ */
|
|
|
68333f |
+ display_signals[RESTART] =
|
|
|
68333f |
+ g_signal_new ("restart",
|
|
|
68333f |
+ G_TYPE_FROM_CLASS (klass),
|
|
|
68333f |
+ G_SIGNAL_RUN_LAST,
|
|
|
68333f |
+ 0,
|
|
|
68333f |
+ g_signal_accumulator_true_handled,
|
|
|
68333f |
+ NULL, NULL,
|
|
|
68333f |
+ G_TYPE_BOOLEAN, 0);
|
|
|
68333f |
+
|
|
|
68333f |
g_object_class_install_property (object_class,
|
|
|
68333f |
PROP_FOCUS_WINDOW,
|
|
|
68333f |
g_param_spec_object ("focus-window",
|
|
|
68333f |
@@ -5856,3 +5911,28 @@ meta_display_clear_mouse_mode (MetaDisplay *display)
|
|
|
68333f |
{
|
|
|
68333f |
display->mouse_mode = FALSE;
|
|
|
68333f |
}
|
|
|
68333f |
+
|
|
|
68333f |
+gboolean
|
|
|
68333f |
+meta_display_show_restart_message (MetaDisplay *display,
|
|
|
68333f |
+ const char *message)
|
|
|
68333f |
+{
|
|
|
68333f |
+ gboolean result = FALSE;
|
|
|
68333f |
+
|
|
|
68333f |
+ g_signal_emit (display,
|
|
|
68333f |
+ display_signals[SHOW_RESTART_MESSAGE], 0,
|
|
|
68333f |
+ message, &result);
|
|
|
68333f |
+
|
|
|
68333f |
+ return result;
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+gboolean
|
|
|
68333f |
+meta_display_request_restart (MetaDisplay *display)
|
|
|
68333f |
+{
|
|
|
68333f |
+ gboolean result = FALSE;
|
|
|
68333f |
+
|
|
|
68333f |
+ g_signal_emit (display,
|
|
|
68333f |
+ display_signals[RESTART], 0,
|
|
|
68333f |
+ &result);
|
|
|
68333f |
+
|
|
|
68333f |
+ return result;
|
|
|
68333f |
+}
|
|
|
68333f |
diff --git a/src/core/main.c b/src/core/main.c
|
|
|
68333f |
index 4bec3d2..d5bde44 100644
|
|
|
68333f |
--- a/src/core/main.c
|
|
|
68333f |
+++ b/src/core/main.c
|
|
|
68333f |
@@ -53,6 +53,7 @@
|
|
|
68333f |
#include <meta/errors.h>
|
|
|
68333f |
#include "ui.h"
|
|
|
68333f |
#include "session.h"
|
|
|
68333f |
+#include "stereo.h"
|
|
|
68333f |
#include <meta/prefs.h>
|
|
|
68333f |
#include <meta/compositor.h>
|
|
|
68333f |
|
|
|
68333f |
@@ -441,6 +442,8 @@ meta_init (void)
|
|
|
68333f |
|
|
|
68333f |
meta_ui_init ();
|
|
|
68333f |
|
|
|
68333f |
+ meta_restart_init ();
|
|
|
68333f |
+
|
|
|
68333f |
/*
|
|
|
68333f |
* Clutter can only be initialized after the UI.
|
|
|
68333f |
*/
|
|
|
68333f |
diff --git a/src/core/restart-helper.c b/src/core/restart-helper.c
|
|
|
68333f |
new file mode 100644
|
|
|
68333f |
index 0000000..57a19fb
|
|
|
68333f |
--- /dev/null
|
|
|
68333f |
+++ b/src/core/restart-helper.c
|
|
|
68333f |
@@ -0,0 +1,82 @@
|
|
|
68333f |
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
68333f |
+
|
|
|
68333f |
+/*
|
|
|
68333f |
+ * SECTION:restart-helper
|
|
|
68333f |
+ * @short_description: helper program during a restart
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * To smoothly restart Mutter, we want to keep the composite
|
|
|
68333f |
+ * overlay window enabled during the restart. This is done by
|
|
|
68333f |
+ * spawning this program, which keeps a reference to the the composite
|
|
|
68333f |
+ * overlay window until Mutter picks it back up.
|
|
|
68333f |
+ */
|
|
|
68333f |
+
|
|
|
68333f |
+/*
|
|
|
68333f |
+ * Copyright (C) 2014 Red Hat, Inc.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * This program is free software; you can redistribute it and/or
|
|
|
68333f |
+ * modify it under the terms of the GNU General Public License as
|
|
|
68333f |
+ * published by the Free Software Foundation; either version 2 of the
|
|
|
68333f |
+ * License, or (at your option) any later version.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * This program is distributed in the hope that it will be useful, but
|
|
|
68333f |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
68333f |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
68333f |
+ * General Public License for more details.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * You should have received a copy of the GNU General Public License
|
|
|
68333f |
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
68333f |
+ */
|
|
|
68333f |
+
|
|
|
68333f |
+#include <stdlib.h>
|
|
|
68333f |
+#include <stdio.h>
|
|
|
68333f |
+#include <X11/Xlib.h>
|
|
|
68333f |
+#include <X11/extensions/Xcomposite.h>
|
|
|
68333f |
+
|
|
|
68333f |
+int
|
|
|
68333f |
+main (int argc,
|
|
|
68333f |
+ char **argv)
|
|
|
68333f |
+{
|
|
|
68333f |
+ Display *display = XOpenDisplay (NULL);
|
|
|
68333f |
+ Window selection_window;
|
|
|
68333f |
+ XSetWindowAttributes xwa;
|
|
|
68333f |
+ unsigned long mask = 0;
|
|
|
68333f |
+
|
|
|
68333f |
+ xwa.override_redirect = True;
|
|
|
68333f |
+ mask |= CWOverrideRedirect;
|
|
|
68333f |
+
|
|
|
68333f |
+
|
|
|
68333f |
+ XCompositeGetOverlayWindow (display, DefaultRootWindow (display));
|
|
|
68333f |
+
|
|
|
68333f |
+ selection_window = XCreateWindow (display,
|
|
|
68333f |
+ DefaultRootWindow (display),
|
|
|
68333f |
+ -100, -100, 1, 1, 0,
|
|
|
68333f |
+ 0,
|
|
|
68333f |
+ InputOnly,
|
|
|
68333f |
+ DefaultVisual (display, DefaultScreen (display)),
|
|
|
68333f |
+ mask, &xwa;;
|
|
|
68333f |
+
|
|
|
68333f |
+ XSetSelectionOwner (display,
|
|
|
68333f |
+ XInternAtom (display, "_MUTTER_RESTART_HELPER", False),
|
|
|
68333f |
+ selection_window,
|
|
|
68333f |
+ CurrentTime);
|
|
|
68333f |
+
|
|
|
68333f |
+ /* Mutter looks for an (arbitrary) line printed to stdout to know that
|
|
|
68333f |
+ * we have started and have a reference to the COW. XSync() so that
|
|
|
68333f |
+ * everything is set on the X server before Mutter starts restarting.
|
|
|
68333f |
+ */
|
|
|
68333f |
+ XSync (display, False);
|
|
|
68333f |
+
|
|
|
68333f |
+ printf ("STARTED\n");
|
|
|
68333f |
+ fflush (stdout);
|
|
|
68333f |
+
|
|
|
68333f |
+ while (True)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ XEvent xev;
|
|
|
68333f |
+
|
|
|
68333f |
+ XNextEvent (display, &xev);
|
|
|
68333f |
+ /* Mutter restarted and unset the selection to indicate that
|
|
|
68333f |
+ * it has a reference on the COW again */
|
|
|
68333f |
+ if (xev.xany.type == SelectionClear)
|
|
|
68333f |
+ return 0;
|
|
|
68333f |
+ }
|
|
|
68333f |
+}
|
|
|
68333f |
diff --git a/src/core/restart.c b/src/core/restart.c
|
|
|
68333f |
new file mode 100644
|
|
|
68333f |
index 0000000..04ef7d5
|
|
|
68333f |
--- /dev/null
|
|
|
68333f |
+++ b/src/core/restart.c
|
|
|
68333f |
@@ -0,0 +1,212 @@
|
|
|
68333f |
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
|
|
|
68333f |
+
|
|
|
68333f |
+/*
|
|
|
68333f |
+ * Copyright (C) 2014 Red Hat, Inc.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * This program is free software; you can redistribute it and/or
|
|
|
68333f |
+ * modify it under the terms of the GNU General Public License as
|
|
|
68333f |
+ * published by the Free Software Foundation; either version 2 of the
|
|
|
68333f |
+ * License, or (at your option) any later version.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * This program is distributed in the hope that it will be useful, but
|
|
|
68333f |
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
68333f |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
68333f |
+ * General Public License for more details.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * You should have received a copy of the GNU General Public License
|
|
|
68333f |
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
68333f |
+ */
|
|
|
68333f |
+
|
|
|
68333f |
+/*
|
|
|
68333f |
+ * SECTION:restart
|
|
|
68333f |
+ * @short_description: Smoothly restart the compositor
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * There are some cases where we need to restart Mutter in order
|
|
|
68333f |
+ * to deal with changes in state - the particular case inspiring
|
|
|
68333f |
+ * this is enabling or disabling stereo output. To make this
|
|
|
68333f |
+ * fairly smooth for the user, we need to do two things:
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * - Display a message to the user and make sure that it is
|
|
|
68333f |
+ * actually painted before we exit.
|
|
|
68333f |
+ * - Use a helper program so that the Composite Overlay Window
|
|
|
68333f |
+ * isn't unmapped and mapped.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * This handles both of these.
|
|
|
68333f |
+ */
|
|
|
68333f |
+
|
|
|
68333f |
+#include <config.h>
|
|
|
68333f |
+
|
|
|
68333f |
+#include <clutter/clutter.h>
|
|
|
68333f |
+#include <gio/gunixinputstream.h>
|
|
|
68333f |
+
|
|
|
68333f |
+#include <meta/main.h>
|
|
|
68333f |
+#include <meta/util.h>
|
|
|
68333f |
+#include "ui.h"
|
|
|
68333f |
+#include "display-private.h"
|
|
|
68333f |
+
|
|
|
68333f |
+static gboolean restart_helper_started = FALSE;
|
|
|
68333f |
+static gboolean restart_message_shown = FALSE;
|
|
|
68333f |
+static gboolean is_restart = FALSE;
|
|
|
68333f |
+
|
|
|
68333f |
+void
|
|
|
68333f |
+meta_restart_init (void)
|
|
|
68333f |
+{
|
|
|
68333f |
+ Display *xdisplay = meta_ui_get_display ();
|
|
|
68333f |
+ Atom atom_restart_helper = XInternAtom (xdisplay, "_MUTTER_RESTART_HELPER", False);
|
|
|
68333f |
+ Window restart_helper_window = NULL;
|
|
|
68333f |
+
|
|
|
68333f |
+ restart_helper_window = XGetSelectionOwner (xdisplay, atom_restart_helper);
|
|
|
68333f |
+ if (restart_helper_window)
|
|
|
68333f |
+ is_restart = TRUE;
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+static void
|
|
|
68333f |
+restart_check_ready (void)
|
|
|
68333f |
+{
|
|
|
68333f |
+ if (restart_helper_started && restart_message_shown)
|
|
|
68333f |
+ meta_display_request_restart (meta_get_display ());
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+static void
|
|
|
68333f |
+restart_helper_read_line_callback (GObject *source_object,
|
|
|
68333f |
+ GAsyncResult *res,
|
|
|
68333f |
+ gpointer user_data)
|
|
|
68333f |
+{
|
|
|
68333f |
+ GError *error = NULL;
|
|
|
68333f |
+ gsize length;
|
|
|
68333f |
+ char *line = g_data_input_stream_read_line_finish_utf8 (G_DATA_INPUT_STREAM (source_object),
|
|
|
68333f |
+ res,
|
|
|
68333f |
+ &length, &error);
|
|
|
68333f |
+ if (line == NULL)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ meta_warning ("Failed to read output from restart helper%s%s\n",
|
|
|
68333f |
+ error ? ": " : NULL,
|
|
|
68333f |
+ error ? error->message : NULL);
|
|
|
68333f |
+ }
|
|
|
68333f |
+ else
|
|
|
68333f |
+ g_free (line); /* We don't actually care what the restart helper outputs */
|
|
|
68333f |
+
|
|
|
68333f |
+ g_object_unref (source_object);
|
|
|
68333f |
+
|
|
|
68333f |
+ restart_helper_started = TRUE;
|
|
|
68333f |
+ restart_check_ready ();
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+static gboolean
|
|
|
68333f |
+restart_message_painted (gpointer data)
|
|
|
68333f |
+{
|
|
|
68333f |
+ restart_message_shown = TRUE;
|
|
|
68333f |
+ restart_check_ready ();
|
|
|
68333f |
+
|
|
|
68333f |
+ return FALSE;
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+/**
|
|
|
68333f |
+ * meta_restart:
|
|
|
68333f |
+ * @message: message to display to the user.
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * Starts the process of restarting the compositor. Note that Mutter's
|
|
|
68333f |
+ * involvement here is to make the restart visually smooth for the
|
|
|
68333f |
+ * user - it cannot itself safely reexec a program that embeds libmuttter.
|
|
|
68333f |
+ * So in order for this to work, the compositor must handle two
|
|
|
68333f |
+ * signals - MetaDisplay::show-restart-message, to display the
|
|
|
68333f |
+ * message passed here on the Clutter stage, and ::restart to actually
|
|
|
68333f |
+ * reexec the compositor.
|
|
|
68333f |
+ */
|
|
|
68333f |
+void
|
|
|
68333f |
+meta_restart (const char *message)
|
|
|
68333f |
+{
|
|
|
68333f |
+ MetaDisplay *display = meta_get_display();
|
|
|
68333f |
+ GInputStream *unix_stream;
|
|
|
68333f |
+ GDataInputStream *data_stream;
|
|
|
68333f |
+ GError *error = NULL;
|
|
|
68333f |
+ int helper_out_fd;
|
|
|
68333f |
+
|
|
|
68333f |
+ static const char * const helper_argv[] = {
|
|
|
68333f |
+ MUTTER_LIBEXECDIR "/mutter-restart-helper", NULL
|
|
|
68333f |
+ };
|
|
|
68333f |
+
|
|
|
68333f |
+ if (meta_display_show_restart_message (display, message))
|
|
|
68333f |
+ {
|
|
|
68333f |
+ /* Wait until the stage was painted */
|
|
|
68333f |
+ clutter_threads_add_repaint_func_full (CLUTTER_REPAINT_FLAGS_POST_PAINT,
|
|
|
68333f |
+ restart_message_painted,
|
|
|
68333f |
+ NULL, NULL);
|
|
|
68333f |
+ }
|
|
|
68333f |
+ else
|
|
|
68333f |
+ {
|
|
|
68333f |
+ /* Can't show the message, show the message as soon as the
|
|
|
68333f |
+ * restart helper starts
|
|
|
68333f |
+ */
|
|
|
68333f |
+ restart_message_painted (NULL);
|
|
|
68333f |
+ }
|
|
|
68333f |
+
|
|
|
68333f |
+ /* We also need to wait for the restart helper to get its
|
|
|
68333f |
+ * reference to the Composite Overlay Window.
|
|
|
68333f |
+ */
|
|
|
68333f |
+ if (!g_spawn_async_with_pipes (NULL, /* working directory */
|
|
|
68333f |
+ (char **)helper_argv,
|
|
|
68333f |
+ NULL, /* envp */
|
|
|
68333f |
+ 0, /* G_SPAWN_DEFAULT */
|
|
|
68333f |
+ NULL, NULL, /* child_setup */
|
|
|
68333f |
+ NULL, /* child_pid */
|
|
|
68333f |
+ NULL, /* standard_input */
|
|
|
68333f |
+ &helper_out_fd,
|
|
|
68333f |
+ NULL, /* standard_error */
|
|
|
68333f |
+ &error))
|
|
|
68333f |
+ {
|
|
|
68333f |
+ meta_warning ("Failed to start restart helper: %s\n", error->message);
|
|
|
68333f |
+ goto error;
|
|
|
68333f |
+ }
|
|
|
68333f |
+
|
|
|
68333f |
+ unix_stream = g_unix_input_stream_new (helper_out_fd, TRUE);
|
|
|
68333f |
+ data_stream = g_data_input_stream_new (unix_stream);
|
|
|
68333f |
+ g_object_unref (unix_stream);
|
|
|
68333f |
+
|
|
|
68333f |
+ g_data_input_stream_read_line_async (data_stream, G_PRIORITY_DEFAULT,
|
|
|
68333f |
+ NULL, restart_helper_read_line_callback,
|
|
|
68333f |
+ &error);
|
|
|
68333f |
+ if (error != NULL)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ meta_warning ("Failed to read from restart helper: %s\n", error->message);
|
|
|
68333f |
+ g_object_unref (data_stream);
|
|
|
68333f |
+ goto error;
|
|
|
68333f |
+ }
|
|
|
68333f |
+
|
|
|
68333f |
+ return;
|
|
|
68333f |
+
|
|
|
68333f |
+ error:
|
|
|
68333f |
+ /* If starting the restart helper fails, then we just go ahead and restart
|
|
|
68333f |
+ * immediately. We won't get a smooth transition, since the overlay window
|
|
|
68333f |
+ * will be destroyed and recreated, but otherwise it will work fine.
|
|
|
68333f |
+ */
|
|
|
68333f |
+ restart_helper_started = TRUE;
|
|
|
68333f |
+ restart_check_ready ();
|
|
|
68333f |
+
|
|
|
68333f |
+ return;
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+void
|
|
|
68333f |
+meta_restart_finish (void)
|
|
|
68333f |
+{
|
|
|
68333f |
+ if (is_restart)
|
|
|
68333f |
+ {
|
|
|
68333f |
+ Display *xdisplay = meta_display_get_xdisplay (meta_get_display ());
|
|
|
68333f |
+ Atom atom_restart_helper = XInternAtom (xdisplay, "_MUTTER_RESTART_HELPER", False);
|
|
|
68333f |
+ XSetSelectionOwner (xdisplay, atom_restart_helper, None, CurrentTime);
|
|
|
68333f |
+ }
|
|
|
68333f |
+}
|
|
|
68333f |
+
|
|
|
68333f |
+/**
|
|
|
68333f |
+ * meta_is_restart:
|
|
|
68333f |
+ *
|
|
|
68333f |
+ * Returns %TRUE if this instance of Mutter comes from Mutter
|
|
|
68333f |
+ * restarting itself (for example to enable/disable stereo.)
|
|
|
68333f |
+ * See meta_restart(). If this is the case, any startup visuals
|
|
|
68333f |
+ * or animations should be suppressed.
|
|
|
68333f |
+ */
|
|
|
68333f |
+gboolean
|
|
|
68333f |
+meta_is_restart (void)
|
|
|
68333f |
+{
|
|
|
68333f |
+ return is_restart;
|
|
|
68333f |
+}
|
|
|
68333f |
diff --git a/src/meta/main.h b/src/meta/main.h
|
|
|
68333f |
index dd4e7f1..af7a2c9 100644
|
|
|
68333f |
--- a/src/meta/main.h
|
|
|
68333f |
+++ b/src/meta/main.h
|
|
|
68333f |
@@ -35,6 +35,9 @@ gboolean meta_get_replace_current_wm (void); /* Actually defined in util
|
|
|
68333f |
void meta_set_wm_name (const char *wm_name);
|
|
|
68333f |
void meta_set_gnome_wm_keybindings (const char *wm_keybindings);
|
|
|
68333f |
|
|
|
68333f |
+void meta_restart (const char *message);
|
|
|
68333f |
+gboolean meta_is_restart (void);
|
|
|
68333f |
+
|
|
|
68333f |
/**
|
|
|
68333f |
* MetaExitCode:
|
|
|
68333f |
* @META_EXIT_SUCCESS: Success
|
|
|
68333f |
--
|
|
|
68333f |
1.9.3
|
|
|
68333f |
|