[gnome-shell] ScreenShield: only emit ActiveChanged at the end of the idle fading



commit 3f6f5970936885071e1f721df523ac87ffa60e05
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Thu Jan 17 23:55:17 2013 +0100

    ScreenShield: only emit ActiveChanged at the end of the idle fading
    
    gnome-settings-daemon wants to use ActiveChanged to drive screen
    blanking policies.
    I also added two big comments that should cover all cases, to clear
    up what's happening when the idle timers fire.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=691964

 js/ui/lightbox.js     |    5 +++
 js/ui/screenShield.js |   87 +++++++++++++++++++++++++++++++++++++------------
 2 files changed, 71 insertions(+), 21 deletions(-)
---
diff --git a/js/ui/lightbox.js b/js/ui/lightbox.js
index d6b0f5d..b876d97 100644
--- a/js/ui/lightbox.js
+++ b/js/ui/lightbox.js
@@ -101,6 +101,7 @@ const Lightbox = new Lang.Class({
     },
 
     show: function() {
+        Tweener.removeTweens(this.actor);
         if (this._fadeInTime) {
             this.shown = false;
             this.actor.opacity = 0;
@@ -110,17 +111,20 @@ const Lightbox = new Lang.Class({
                                transition: 'easeOutQuad',
                                onComplete: Lang.bind(this, function() {
                                    this.shown = true;
+                                   this.emit('shown');
                                })
                              });
         } else {
             this.actor.opacity = 255 * this._fadeFactor;
             this.shown = true;
+            this.emit('shown');
         }
         this.actor.show();
     },
 
     hide: function() {
         this.shown = false;
+        Tweener.removeTweens(this.actor);
         if (this._fadeOutTime) {
             Tweener.addTween(this.actor,
                              { opacity: 0,
@@ -197,3 +201,4 @@ const Lightbox = new Lang.Class({
         this.highlight(null);
     }
 });
+Signals.addSignalMethods(Lightbox.prototype);
diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js
index 73bf137..7d86b96 100644
--- a/js/ui/screenShield.js
+++ b/js/ui/screenShield.js
@@ -537,11 +537,13 @@ const ScreenShield = new Lang.Class({
         this._isActive = false;
         this._inUnlockAnimation = false;
         this._activationTime = 0;
+        this._becameActiveId = 0;
 
         this._lightbox = new Lightbox.Lightbox(Main.uiGroup,
                                                { inhibitEvents: true,
                                                  fadeInTime: STANDARD_FADE_TIME,
                                                  fadeFactor: 1 });
+        this._lightbox.connect('shown', Lang.bind(this, this._onLightboxShown));
 
         this.idleMonitor = new GnomeDesktop.IdleMonitor();
     },
@@ -682,37 +684,75 @@ const ScreenShield = new Lang.Class({
         if (!this._isModal) {
             Main.pushModal(this.actor, { keybindingMode: Main.KeybindingMode.LOCK_SCREEN });
             this._isModal = true;
+            }
+
+        if (this._lightbox.actor.visible ||
+            this._isActive) {
+            // We're either shown and active, or in the process of
+            // showing.
+            // The latter is a very unlikely condition (it requires
+            // idle-delay < 20), but in any case we have nothing
+            // to do at this point: either isActive is true, or
+            // it will soon be.
+            // isActive can also be true if the lightbox is hidden,
+            // in case the shield is down and the user hasn't unlocked yet
+            return;
         }
 
-        if (!this._isActive) {
-            this._lightbox.show();
+        this._lightbox.show();
 
-            if (this._activationTime == 0)
-                this._activationTime = GLib.get_monotonic_time();
+        if (this._activationTime == 0)
+            this._activationTime = GLib.get_monotonic_time();
 
-            this._becameActiveId = this.idleMonitor.connect('became-active', Lang.bind(this, function() {
-                this.idleMonitor.disconnect(this._becameActiveId);
+        if (this._becameActiveId == 0)
+            this._becameActiveId = this.idleMonitor.connect('became-active',
+                                                            Lang.bind(this, this._onUserBecameActive));
+    },
 
-                let lightboxWasShown = this._lightbox.shown;
-                this._lightbox.hide();
+    _onUserBecameActive: function() {
+        // This function gets called here when the user becomes active
+        // after gnome-session changed the status to IDLE
+        // There are four possibilities here:
+        // - we're called when already locked; isActive and isLocked are true,
+        //   we just go back to the lock screen curtain
+        // - we're called before the lightbox is fully shown; at this point
+        //   isActive is false, so we just hide the ligthbox, reset the activationTime
+        //   and go back to the unlocked desktop
+        // - we're called after showing the lightbox, but before the lock
+        //   delay; this is mostly like the case above, but isActive is true now
+        //   so we need to notify gnome-settings-daemon to go back to the normal
+        //   policies for blanking
+        //   (they're handled by the same code, and we emit one extra ActiveChanged
+        //   signal in the case above)
+        // - we're called after showing the lightbox and after lock-delay; the
+        //   session is effectivelly locked now, it's time to build and show
+        //   the lock screen
+
+        this.idleMonitor.disconnect(this._becameActiveId);
+        this._becameActiveId = 0;
+
+        let lightboxWasShown = this._lightbox.shown;
+        this._lightbox.hide();
 
-                // GLib.get_monotonic_time() returns microseconds, convert to seconds
-                let elapsedTime = (GLib.get_monotonic_time() - this._activationTime) / 1000000;
-                let shouldLock = lightboxWasShown &&
-                    this._settings.get_boolean(LOCK_ENABLED_KEY) &&
-                    (elapsedTime >= this._settings.get_uint(LOCK_DELAY_KEY));
-                if (shouldLock || this._isLocked) {
-                    this.lock(false);
-                } else if (this._isActive) {
-                    this.unlock();
-                }
-            }));
+        // GLib.get_monotonic_time() returns microseconds, convert to seconds
+        let elapsedTime = (GLib.get_monotonic_time() - this._activationTime) / 1000000;
+        let shouldLock = lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY) &&
+            (elapsedTime >= this._settings.get_uint(LOCK_DELAY_KEY));
 
-            this._isActive = true;
-            this.emit('lock-status-changed');
+        if (this._isLocked || shouldLock) {
+            this.lock(false);
+        } else {
+            // We're not really locked here, but unlock() will do what we need
+            // and ensure we reset all state
+            this.unlock();
         }
     },
 
+    _onLightboxShown: function() {
+        this._isActive = true;
+        this.emit('lock-status-changed');
+    },
+
     showDialog: function() {
         // Ensure that the stage window is mapped, before taking a grab
         // otherwise X errors out
@@ -989,6 +1029,11 @@ const ScreenShield = new Lang.Class({
         if (Main.sessionMode.currentMode == 'unlock-dialog')
             Main.sessionMode.popMode('unlock-dialog');
 
+        if (this._becameActiveId != 0) {
+            this.idleMonitor.disconnect(this._becameActiveId);
+            this._becameActiveId = 0;
+        }
+
         this._activationTime = 0;
         this._isActive = false;
         this._isLocked = false;



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