Blame SOURCES/0001-Add-support-for-meta_restart-and-MetaDisplay-restart.patch

13bb5b
From 3e707f08e1b8687abb093d020b78dc571c68df06 Mon Sep 17 00:00:00 2001
13bb5b
From: "Owen W. Taylor" <otaylor@fishsoup.net>
13bb5b
Date: Thu, 8 May 2014 18:56:23 -0400
13bb5b
Subject: [PATCH] Add support for meta_restart() and MetaDisplay::restart
13bb5b
13bb5b
Support was added to Mutter to allow it to trigger a restart
13bb5b
to allow for restarts when switching in or out of stereo mode.
13bb5b
13bb5b
Hook up to the new signals on MetaDisplay to show the restart
13bb5b
message and reexec. Meta.is_restart() is used to suppress
13bb5b
the startup animation.
13bb5b
13bb5b
This also allows us to do 'Alt-F2 r' restarts more cleanly
13bb5b
without a visual flash and animation.
13bb5b
---
13bb5b
 data/theme/gnome-shell.css |   5 ++
13bb5b
 js/ui/layout.js            | 115 +++++++++++++++++++++++++++------------------
13bb5b
 js/ui/main.js              |  36 ++++++++++++++
13bb5b
 js/ui/modalDialog.js       |  35 ++++++++------
13bb5b
 js/ui/runDialog.js         |  14 +++---
13bb5b
 5 files changed, 138 insertions(+), 67 deletions(-)
13bb5b
13bb5b
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
13bb5b
index f4ea781..66346a1 100644
13bb5b
--- a/data/theme/gnome-shell.css
13bb5b
+++ b/data/theme/gnome-shell.css
13bb5b
@@ -1920,6 +1920,11 @@ StScrollBar StButton#vhandle:active {
13bb5b
     color: #444444;
13bb5b
 }
13bb5b
 
13bb5b
+/* Restart message */
13bb5b
+.restart-message {
13bb5b
+    font-size: 14pt;
13bb5b
+}
13bb5b
+
13bb5b
 /* ShellMountOperation Dialogs */
13bb5b
 .shell-mount-operation-icon {
13bb5b
     icon-size: 48px;
13bb5b
diff --git a/js/ui/layout.js b/js/ui/layout.js
13bb5b
index 141eecc..223a0e2 100644
13bb5b
--- a/js/ui/layout.js
13bb5b
+++ b/js/ui/layout.js
13bb5b
@@ -560,56 +560,75 @@ const LayoutManager = new Lang.Class({
13bb5b
         // so events don't get delivered to X11 windows (which are distorted by the animation)
13bb5b
         global.stage_input_mode = Shell.StageInputMode.FULLSCREEN;
13bb5b
 
13bb5b
-        if (Main.sessionMode.isGreeter) {
13bb5b
-            this.panelBox.translation_y = -this.panelBox.height;
13bb5b
+        let background;
13bb5b
+        if (Meta.is_restart()) {
13bb5b
+            // On restart, we don't do an animation, so start loading the primary
13bb5b
+            // background now.
13bb5b
+            this._createPrimaryBackground();
13bb5b
+            background = this._bgManagers[this.primaryIndex].background;
13bb5b
         } else {
13bb5b
-            // We need to force an update of the regions now before we scale
13bb5b
-            // the UI group to get the coorect allocation for the struts.
13bb5b
-            this._updateRegions();
13bb5b
-
13bb5b
-            this.trayBox.hide();
13bb5b
-            this.keyboardBox.hide();
13bb5b
-
13bb5b
-            let monitor = this.primaryMonitor;
13bb5b
-            let x = monitor.x + monitor.width / 2.0;
13bb5b
-            let y = monitor.y + monitor.height / 2.0;
13bb5b
-
13bb5b
-            this.uiGroup.set_pivot_point(x / global.screen_width,
13bb5b
-                                         y / global.screen_height);
13bb5b
-            this.uiGroup.scale_x = this.uiGroup.scale_y = 0.5;
13bb5b
-            this.uiGroup.opacity = 0;
13bb5b
-            global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
13bb5b
-        }
13bb5b
-
13bb5b
-        this._systemBackground = new Background.SystemBackground();
13bb5b
-        this._systemBackground.actor.hide();
13bb5b
-
13bb5b
-        global.stage.insert_child_below(this._systemBackground.actor, null);
13bb5b
+            if (Main.sessionMode.isGreeter) {
13bb5b
+                this.panelBox.translation_y = -this.panelBox.height;
13bb5b
+            } else {
13bb5b
+                // We need to force an update of the regions now before we scale
13bb5b
+                // the UI group to get the coorect allocation for the struts.
13bb5b
+                this._updateRegions();
13bb5b
+
13bb5b
+                this.trayBox.hide();
13bb5b
+                this.keyboardBox.hide();
13bb5b
+
13bb5b
+                let monitor = this.primaryMonitor;
13bb5b
+                let x = monitor.x + monitor.width / 2.0;
13bb5b
+                let y = monitor.y + monitor.height / 2.0;
13bb5b
+
13bb5b
+                this.uiGroup.set_pivot_point(x / global.screen_width,
13bb5b
+                                             y / global.screen_height);
13bb5b
+                this.uiGroup.scale_x = this.uiGroup.scale_y = 0.5;
13bb5b
+                this.uiGroup.opacity = 0;
13bb5b
+                global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
13bb5b
+            }
13bb5b
 
13bb5b
-        let constraint = new Clutter.BindConstraint({ source: global.stage,
13bb5b
-                                                      coordinate: Clutter.BindCoordinate.ALL });
13bb5b
-        this._systemBackground.actor.add_constraint(constraint);
13bb5b
+            this._systemBackground = new Background.SystemBackground();
13bb5b
+            this._systemBackground.actor.hide();
13bb5b
 
13bb5b
-        let signalId = this._systemBackground.connect('loaded',
13bb5b
-                                                      Lang.bind(this, function() {
13bb5b
-                                                          this._systemBackground.disconnect(signalId);
13bb5b
-                                                          this._systemBackground.actor.show();
13bb5b
-                                                          global.stage.show();
13bb5b
+            global.stage.insert_child_below(this._systemBackground.actor, null);
13bb5b
 
13bb5b
-                                                          this.emit('startup-prepared');
13bb5b
+            let constraint = new Clutter.BindConstraint({ source: global.stage,
13bb5b
+                                                          coordinate: Clutter.BindCoordinate.ALL });
13bb5b
+            this._systemBackground.actor.add_constraint(constraint);
13bb5b
+            background = this._systemBackground;
13bb5b
+        }
13bb5b
 
13bb5b
-                                                          // We're mostly prepared for the startup animation
13bb5b
-                                                          // now, but since a lot is going on asynchronously
13bb5b
-                                                          // during startup, let's defer the startup animation
13bb5b
-                                                          // until the event loop is uncontended and idle.
13bb5b
-                                                          // This helps to prevent us from running the animation
13bb5b
-                                                          // when the system is bogged down
13bb5b
-                                                          GLib.idle_add(GLib.PRIORITY_LOW,
13bb5b
-                                                                        Lang.bind(this, function() {
13bb5b
-                                                                            this._startupAnimation();
13bb5b
-                                                                            return false;
13bb5b
-                                                                        }));
13bb5b
-                                                      }));
13bb5b
+        let signalId = background.connect('loaded',
13bb5b
+                                          Lang.bind(this, function() {
13bb5b
+                                              background.disconnect(signalId);
13bb5b
+                                              if (this._systemBackground)
13bb5b
+                                                  this._systemBackground.actor.show();
13bb5b
+                                              global.stage.show();
13bb5b
+
13bb5b
+                                              this.emit('startup-prepared');
13bb5b
+
13bb5b
+                                              // We're mostly prepared for the startup animation
13bb5b
+                                              // now, but since a lot is going on asynchronously
13bb5b
+                                              // during startup, let's defer the startup animation
13bb5b
+                                              // until the event loop is uncontended and idle.
13bb5b
+                                              // This helps to prevent us from running the animation
13bb5b
+                                              // when the system is bogged down. Don't wait on
13bb5b
+                                              // restart, since it might take a long time for us
13bb5b
+                                              // to go idle, and we don't show an animation. Just
13bb5b
+                                              // finish immediately.
13bb5b
+                                              if (Meta.is_restart()) {
13bb5b
+                                                  // Nothing else will do this reliably
13bb5b
+                                                  this._queueUpdateRegions();
13bb5b
+                                                  this._startupAnimationComplete();
13bb5b
+                                              } else {
13bb5b
+                                                  GLib.idle_add(GLib.PRIORITY_LOW,
13bb5b
+                                                                Lang.bind(this, function() {
13bb5b
+                                                                    this._startupAnimation();
13bb5b
+                                                                    return false;
13bb5b
+                                                                }));
13bb5b
+                                              }
13bb5b
+                                          }));
13bb5b
     },
13bb5b
 
13bb5b
     _startupAnimation: function() {
13bb5b
@@ -647,8 +666,10 @@ const LayoutManager = new Lang.Class({
13bb5b
 
13bb5b
         global.stage_input_mode = Shell.StageInputMode.NORMAL;
13bb5b
 
13bb5b
-        this._systemBackground.actor.destroy();
13bb5b
-        this._systemBackground = null;
13bb5b
+        if (this._systemBackground) {
13bb5b
+            this._systemBackground.actor.destroy();
13bb5b
+            this._systemBackground = null;
13bb5b
+        }
13bb5b
 
13bb5b
         this._startingUp = false;
13bb5b
 
13bb5b
diff --git a/js/ui/main.js b/js/ui/main.js
13bb5b
index bd5dc47..a3b73f0 100644
13bb5b
--- a/js/ui/main.js
13bb5b
+++ b/js/ui/main.js
13bb5b
@@ -18,6 +18,7 @@ const ExtensionSystem = imports.ui.extensionSystem;
13bb5b
 const ExtensionDownloader = imports.ui.extensionDownloader;
13bb5b
 const Keyboard = imports.ui.keyboard;
13bb5b
 const MessageTray = imports.ui.messageTray;
13bb5b
+const ModalDialog = imports.ui.modalDialog;
13bb5b
 const OsdWindow = imports.ui.osdWindow;
13bb5b
 const Overview = imports.ui.overview;
13bb5b
 const Panel = imports.ui.panel;
13bb5b
@@ -176,6 +177,16 @@ function _initializeUI() {
13bb5b
                                             false, -1, 1);
13bb5b
     global.display.connect('overlay-key', Lang.bind(overview, overview.toggle));
13bb5b
 
13bb5b
+    global.display.connect('show-restart-message', function(display, message) {
13bb5b
+        showRestartMessage(message);
13bb5b
+        return true;
13bb5b
+    });
13bb5b
+
13bb5b
+    global.display.connect('restart', function() {
13bb5b
+        global.reexec_self();
13bb5b
+        return true;
13bb5b
+    });
13bb5b
+
13bb5b
     // Provide the bus object for gnome-session to
13bb5b
     // initiate logouts.
13bb5b
     EndSessionDialog.init();
13bb5b
@@ -800,3 +811,28 @@ function queueDeferredWork(workId) {
13bb5b
         });
13bb5b
     }
13bb5b
 }
13bb5b
+
13bb5b
+const RestartMessage = new Lang.Class({
13bb5b
+    Name: 'RestartMessage',
13bb5b
+    Extends: ModalDialog.ModalDialog,
13bb5b
+
13bb5b
+    _init : function(message) {
13bb5b
+        this.parent({ shellReactive: true,
13bb5b
+                      styleClass: 'restart-message',
13bb5b
+                      shouldFadeIn: false,
13bb5b
+                      destroyOnClose: true });
13bb5b
+
13bb5b
+        let label = new St.Label({ text: message });
13bb5b
+
13bb5b
+        this.contentLayout.add(label, { x_fill: false,
13bb5b
+                                        y_fill: false,
13bb5b
+                                        x_align: St.Align.MIDDLE,
13bb5b
+                                        y_align: St.Align.MIDDLE });
13bb5b
+        this.buttonLayout.hide();
13bb5b
+    }
13bb5b
+});
13bb5b
+
13bb5b
+function showRestartMessage(message) {
13bb5b
+    let restartMessage = new RestartMessage(message);
13bb5b
+    restartMessage.open();
13bb5b
+}
13bb5b
diff --git a/js/ui/modalDialog.js b/js/ui/modalDialog.js
13bb5b
index f770faf..aba7758 100644
13bb5b
--- a/js/ui/modalDialog.js
13bb5b
+++ b/js/ui/modalDialog.js
13bb5b
@@ -43,6 +43,7 @@ const ModalDialog = new Lang.Class({
13bb5b
                                         parentActor: Main.uiGroup,
13bb5b
                                         keybindingMode: Shell.KeyBindingMode.SYSTEM_MODAL,
13bb5b
                                         shouldFadeIn: true,
13bb5b
+                                        shouldFadeOut: true,
13bb5b
                                         destroyOnClose: true });
13bb5b
 
13bb5b
         this.state = State.CLOSED;
13bb5b
@@ -50,6 +51,7 @@ const ModalDialog = new Lang.Class({
13bb5b
         this._keybindingMode = params.keybindingMode;
13bb5b
         this._shellReactive = params.shellReactive;
13bb5b
         this._shouldFadeIn = params.shouldFadeIn;
13bb5b
+        this._shouldFadeOut = params.shouldFadeOut;
13bb5b
         this._destroyOnClose = params.destroyOnClose;
13bb5b
 
13bb5b
         this._group = new St.Widget({ visible: false,
13bb5b
@@ -303,6 +305,15 @@ const ModalDialog = new Lang.Class({
13bb5b
         return true;
13bb5b
     },
13bb5b
 
13bb5b
+    _closeComplete: function() {
13bb5b
+        this.state = State.CLOSED;
13bb5b
+        this._group.hide();
13bb5b
+        this.emit('closed');
13bb5b
+
13bb5b
+        if (this._destroyOnClose)
13bb5b
+            this.destroy();
13bb5b
+    },
13bb5b
+
13bb5b
     close: function(timestamp) {
13bb5b
         if (this.state == State.CLOSED || this.state == State.CLOSING)
13bb5b
             return;
13bb5b
@@ -311,20 +322,16 @@ const ModalDialog = new Lang.Class({
13bb5b
         this.popModal(timestamp);
13bb5b
         this._savedKeyFocus = null;
13bb5b
 
13bb5b
-        Tweener.addTween(this._group,
13bb5b
-                         { opacity: 0,
13bb5b
-                           time: OPEN_AND_CLOSE_TIME,
13bb5b
-                           transition: 'easeOutQuad',
13bb5b
-                           onComplete: Lang.bind(this,
13bb5b
-                               function() {
13bb5b
-                                   this.state = State.CLOSED;
13bb5b
-                                   this._group.hide();
13bb5b
-                                   this.emit('closed');
13bb5b
-
13bb5b
-                                   if (this._destroyOnClose)
13bb5b
-                                       this.destroy();
13bb5b
-                               })
13bb5b
-                         });
13bb5b
+        if (this._shouldFadeOut)
13bb5b
+            Tweener.addTween(this._group,
13bb5b
+                             { opacity: 0,
13bb5b
+                               time: OPEN_AND_CLOSE_TIME,
13bb5b
+                               transition: 'easeOutQuad',
13bb5b
+                               onComplete: Lang.bind(this,
13bb5b
+                                                     this._closeComplete)
13bb5b
+                             })
13bb5b
+        else
13bb5b
+            this._closeComplete();
13bb5b
     },
13bb5b
 
13bb5b
     // Drop modal status without closing the dialog; this makes the
13bb5b
diff --git a/js/ui/runDialog.js b/js/ui/runDialog.js
13bb5b
index 7b753a7..1901296 100644
13bb5b
--- a/js/ui/runDialog.js
13bb5b
+++ b/js/ui/runDialog.js
13bb5b
@@ -50,14 +50,10 @@ const RunDialog = new Lang.Class({
13bb5b
                                        Main.createLookingGlass().open();
13bb5b
                                    }),
13bb5b
 
13bb5b
-                                   'r': Lang.bind(this, function() {
13bb5b
-                                       global.reexec_self();
13bb5b
-                                   }),
13bb5b
+                                   'r': Lang.bind(this, this._restart),
13bb5b
 
13bb5b
                                    // Developer brain backwards compatibility
13bb5b
-                                   'restart': Lang.bind(this, function() {
13bb5b
-                                       global.reexec_self();
13bb5b
-                                   }),
13bb5b
+                                   'restart': Lang.bind(this, this._restart),
13bb5b
 
13bb5b
                                    'debugexit': Lang.bind(this, function() {
13bb5b
                                        Meta.quit(Meta.ExitCode.ERROR);
13bb5b
@@ -267,6 +263,12 @@ const RunDialog = new Lang.Class({
13bb5b
         }
13bb5b
     },
13bb5b
 
13bb5b
+    _restart: function() {
13bb5b
+        this._shouldFadeOut = false;
13bb5b
+        this.close();
13bb5b
+        Meta.restart('Restarting...');
13bb5b
+    },
13bb5b
+
13bb5b
     open: function() {
13bb5b
         this._history.lastItem();
13bb5b
         this._errorBox.hide();
13bb5b
-- 
13bb5b
1.8.3.1
13bb5b