[gnome-shell] ScreenShield: fade the screen to black when locking manually



commit 2a2bcc89842beb1d50f61fb758943d28c5e63277
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sat Aug 17 19:40:09 2013 +0200

    ScreenShield: fade the screen to black when locking manually
    
    When locking manually (or locking with an animation), fade the
    screen to black after a small timeout. This provides a smoother
    experience, instead of abruptly turning off the screen.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=699112

 js/ui/screenShield.js |  115 ++++++++++++++++++++++++++++++++-----------------
 1 files changed, 75 insertions(+), 40 deletions(-)
---
diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js
index 8a13c56..eaeafe0 100644
--- a/js/ui/screenShield.js
+++ b/js/ui/screenShield.js
@@ -580,11 +580,17 @@ const ScreenShield = new Lang.Class({
         this._becameActiveId = 0;
         this._lockTimeoutId = 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));
+        // The "long" lightbox is used for the longer (20 seconds) fade from session
+        // to idle status, the "short" is used for quickly fading to black when locking
+        // manually
+        this._longLightbox = new Lightbox.Lightbox(Main.uiGroup,
+                                                   { inhibitEvents: true,
+                                                     fadeFactor: 1 });
+        this._longLightbox.connect('shown', Lang.bind(this, this._onLongLightboxShown));
+        this._shortLightbox = new Lightbox.Lightbox(Main.uiGroup,
+                                                    { inhibitEvents: true,
+                                                      fadeFactor: 1 });
+        this._shortLightbox.connect('shown', Lang.bind(this, this._onShortLightboxShown));
 
         this.idleMonitor = new GnomeDesktop.IdleMonitor();
     },
@@ -807,7 +813,7 @@ const ScreenShield = new Lang.Class({
 
         this._maybeCancelDialog();
 
-        if (this._lightbox.actor.visible ||
+        if (this._longLightbox.actor.visible ||
             this._isActive) {
             // We're either shown and active, or in the process of
             // showing.
@@ -825,7 +831,7 @@ const ScreenShield = new Lang.Class({
             // screenshield. The user is probably very upset at this
             // point, but any application using global grabs is broken
             // Just tell him to stop using this app
-            // 
+            //
             // XXX: another option is to kick the user into the gdm login
             // screen, where we're not affected by grabs
             Main.notifyError(_("Unable to lock"),
@@ -833,13 +839,9 @@ const ScreenShield = new Lang.Class({
             return;
         }
 
-        this._lightbox.show();
-
         if (this._activationTime == 0)
             this._activationTime = GLib.get_monotonic_time();
 
-        this._becameActiveId = this.idleMonitor.add_user_active_watch(Lang.bind(this, 
this._onUserBecameActive));
-
         let shouldLock = this._settings.get_boolean(LOCK_ENABLED_KEY) && !this._isLocked;
 
         if (shouldLock) {
@@ -847,48 +849,59 @@ const ScreenShield = new Lang.Class({
             this._lockTimeoutId = Mainloop.timeout_add(lockTimeout * 1000,
                                                        Lang.bind(this, function() {
                                                            this._lockTimeoutId = 0;
-                                                           this.lock(true);
+                                                           this.lock(false);
                                                            return false;
                                                        }));
         }
+
+        this._activateFade(this._longLightbox, STANDARD_FADE_TIME);
+    },
+
+    _activateFade: function(lightbox, time) {
+        lightbox.show(time);
+
+        if (this._becameActiveId == 0)
+            this._becameActiveId = this.idleMonitor.add_user_active_watch(Lang.bind(this, 
this._onUserBecameActive));
     },
 
     _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,
+        // after we activated a lightbox
+        // There are two possibilities here:
+        // - we're called when already locked/active; isLocked or isActive is 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
+        //   (isActive == isLocked == true: normal case
+        //    isActive == false, isLocked == true: during the fade for manual locking
+        //    isActive == true, isLocked == false: after session idle, before lock-delay)
+        // - we're called because the session is IDLE but before the lightbox
+        //   is fully shown; at this point isActive is false, so we just hide
+        //   the lightbox, reset the activationTime and go back to the unlocked
+        //   desktop
+        //   using deactivate() is a little of overkill, but it ensures we
+        //   don't forget of some bit like modal, DBus properties or idle watches
+        //
+        // Note: if the (long) lightbox is shown then we're necessarily
+        // active, because we call activate() without animation.
 
         this.idleMonitor.remove_watch(this._becameActiveId);
         this._becameActiveId = 0;
 
-        let lightboxWasShown = this._lightbox.shown;
-        this._lightbox.hide();
-
-        // Shortcircuit in case the mouse was moved before the fade completed
-        if (!lightboxWasShown) {
+        if (this._isActive || this._isLocked) {
+            this._longLightbox.hide();
+            this._shortLightbox.hide();
+        } else {
             this.deactivate(false);
-            return;
         }
     },
 
-    _onLightboxShown: function() {
+    _onLongLightboxShown: function() {
         this.activate(false);
     },
 
+    _onShortLightboxShown: function() {
+        this._completeLockScreenShown();
+    },
+
     showDialog: function() {
         // Ensure that the stage window is mapped, before taking a grab
         // otherwise X errors out
@@ -980,7 +993,8 @@ const ScreenShield = new Lang.Class({
 
     _onUnlockFailed: function() {
         this._resetLockScreen({ animateLockScreen: true,
-                                animateLockDialog: false });
+                                animateLockDialog: false,
+                                fadeToBlack: false });
     },
 
     _resetLockScreen: function(params) {
@@ -998,6 +1012,8 @@ const ScreenShield = new Lang.Class({
         this._lockScreenGroup.show();
         this._lockScreenState = MessageTray.State.SHOWING;
 
+        let fadeToBlack = params.fadeToBlack;
+
         if (params.animateLockScreen) {
             this._lockScreenGroup.y = -global.screen_height;
             Tweener.removeTweens(this._lockScreenGroup);
@@ -1006,13 +1022,15 @@ const ScreenShield = new Lang.Class({
                                time: MANUAL_FADE_TIME,
                                transition: 'easeOutQuad',
                                onComplete: function() {
-                                   this._lockScreenShown();
+                                   this._lockScreenShown({ fadeToBlack: fadeToBlack,
+                                                           animateFade: true });
                                },
                                onCompleteScope: this
                              });
         } else {
             this._lockScreenGroup.fixed_position_set = false;
-            this._lockScreenShown();
+            this._lockScreenShown({ fadeToBlack: fadeToBlack,
+                                    animateFade: false });
         }
 
         if (params.animateLockDialog) {
@@ -1079,7 +1097,7 @@ const ScreenShield = new Lang.Class({
             this._pauseArrowAnimation();
     },
 
-    _lockScreenShown: function() {
+    _lockScreenShown: function(params) {
         if (this._dialog && !this._isGreeter) {
             this._dialog.destroy();
             this._dialog = null;
@@ -1101,6 +1119,21 @@ const ScreenShield = new Lang.Class({
         this._lockScreenGroup.fixed_position_set = false;
         this._lockScreenScrollCounter = 0;
 
+        if (params.fadeToBlack && params.animateFade) {
+            // Take a beat
+
+            Mainloop.timeout_add(1000 * MANUAL_FADE_TIME, Lang.bind(this, function() {
+                this._activateFade(this._shortLightbox, MANUAL_FADE_TIME);
+            }));
+        } else {
+            if (params.fadeToBlack)
+                this._activateFade(this._shortLightbox, 0);
+
+            this._completeLockScreenShown();
+        }
+    },
+
+    _completeLockScreenShown: function() {
         let prevIsActive = this._isActive;
         this._isActive = true;
 
@@ -1225,7 +1258,8 @@ const ScreenShield = new Lang.Class({
             this._dialog = null;
         }
 
-        this._lightbox.hide();
+        this._longLightbox.hide();
+        this._shortLightbox.hide();
         this.actor.hide();
 
         if (this._becameActiveId != 0) {
@@ -1260,7 +1294,8 @@ const ScreenShield = new Lang.Class({
         }
 
         this._resetLockScreen({ animateLockScreen: animate,
-                                animateLockDialog: animate });
+                                animateLockDialog: animate,
+                                fadeToBlack: true });
         global.set_runtime_state(LOCKED_STATE_STR, GLib.Variant.new('b', true));
 
         // We used to set isActive and emit active-changed here,


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