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
This commit is contained in:
parent
6b8339e9b4
commit
2a2bcc8984
@ -580,11 +580,17 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._becameActiveId = 0;
|
this._becameActiveId = 0;
|
||||||
this._lockTimeoutId = 0;
|
this._lockTimeoutId = 0;
|
||||||
|
|
||||||
this._lightbox = new Lightbox.Lightbox(Main.uiGroup,
|
// 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,
|
{ inhibitEvents: true,
|
||||||
fadeInTime: STANDARD_FADE_TIME,
|
|
||||||
fadeFactor: 1 });
|
fadeFactor: 1 });
|
||||||
this._lightbox.connect('shown', Lang.bind(this, this._onLightboxShown));
|
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();
|
this.idleMonitor = new GnomeDesktop.IdleMonitor();
|
||||||
},
|
},
|
||||||
@ -807,7 +813,7 @@ const ScreenShield = new Lang.Class({
|
|||||||
|
|
||||||
this._maybeCancelDialog();
|
this._maybeCancelDialog();
|
||||||
|
|
||||||
if (this._lightbox.actor.visible ||
|
if (this._longLightbox.actor.visible ||
|
||||||
this._isActive) {
|
this._isActive) {
|
||||||
// We're either shown and active, or in the process of
|
// We're either shown and active, or in the process of
|
||||||
// showing.
|
// showing.
|
||||||
@ -833,13 +839,9 @@ const ScreenShield = new Lang.Class({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._lightbox.show();
|
|
||||||
|
|
||||||
if (this._activationTime == 0)
|
if (this._activationTime == 0)
|
||||||
this._activationTime = GLib.get_monotonic_time();
|
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;
|
let shouldLock = this._settings.get_boolean(LOCK_ENABLED_KEY) && !this._isLocked;
|
||||||
|
|
||||||
if (shouldLock) {
|
if (shouldLock) {
|
||||||
@ -847,48 +849,59 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._lockTimeoutId = Mainloop.timeout_add(lockTimeout * 1000,
|
this._lockTimeoutId = Mainloop.timeout_add(lockTimeout * 1000,
|
||||||
Lang.bind(this, function() {
|
Lang.bind(this, function() {
|
||||||
this._lockTimeoutId = 0;
|
this._lockTimeoutId = 0;
|
||||||
this.lock(true);
|
this.lock(false);
|
||||||
return 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() {
|
_onUserBecameActive: function() {
|
||||||
// This function gets called here when the user becomes active
|
// This function gets called here when the user becomes active
|
||||||
// after gnome-session changed the status to IDLE
|
// after we activated a lightbox
|
||||||
// There are four possibilities here:
|
// There are two possibilities here:
|
||||||
// - we're called when already locked; isActive and isLocked are true,
|
// - we're called when already locked/active; isLocked or isActive is true,
|
||||||
// we just go back to the lock screen curtain
|
// we just go back to the lock screen curtain
|
||||||
// - we're called before the lightbox is fully shown; at this point
|
// (isActive == isLocked == true: normal case
|
||||||
// isActive is false, so we just hide the ligthbox, reset the activationTime
|
// isActive == false, isLocked == true: during the fade for manual locking
|
||||||
// and go back to the unlocked desktop
|
// isActive == true, isLocked == false: after session idle, before lock-delay)
|
||||||
// - we're called after showing the lightbox, but before the lock
|
// - we're called because the session is IDLE but before the lightbox
|
||||||
// delay; this is mostly like the case above, but isActive is true now
|
// is fully shown; at this point isActive is false, so we just hide
|
||||||
// so we need to notify gnome-settings-daemon to go back to the normal
|
// the lightbox, reset the activationTime and go back to the unlocked
|
||||||
// policies for blanking
|
// desktop
|
||||||
// (they're handled by the same code, and we emit one extra ActiveChanged
|
// using deactivate() is a little of overkill, but it ensures we
|
||||||
// signal in the case above)
|
// don't forget of some bit like modal, DBus properties or idle watches
|
||||||
// - we're called after showing the lightbox and after lock-delay; the
|
//
|
||||||
// session is effectivelly locked now, it's time to build and show
|
// Note: if the (long) lightbox is shown then we're necessarily
|
||||||
// the lock screen
|
// active, because we call activate() without animation.
|
||||||
|
|
||||||
this.idleMonitor.remove_watch(this._becameActiveId);
|
this.idleMonitor.remove_watch(this._becameActiveId);
|
||||||
this._becameActiveId = 0;
|
this._becameActiveId = 0;
|
||||||
|
|
||||||
let lightboxWasShown = this._lightbox.shown;
|
if (this._isActive || this._isLocked) {
|
||||||
this._lightbox.hide();
|
this._longLightbox.hide();
|
||||||
|
this._shortLightbox.hide();
|
||||||
// Shortcircuit in case the mouse was moved before the fade completed
|
} else {
|
||||||
if (!lightboxWasShown) {
|
|
||||||
this.deactivate(false);
|
this.deactivate(false);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_onLightboxShown: function() {
|
_onLongLightboxShown: function() {
|
||||||
this.activate(false);
|
this.activate(false);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_onShortLightboxShown: function() {
|
||||||
|
this._completeLockScreenShown();
|
||||||
|
},
|
||||||
|
|
||||||
showDialog: function() {
|
showDialog: function() {
|
||||||
// Ensure that the stage window is mapped, before taking a grab
|
// Ensure that the stage window is mapped, before taking a grab
|
||||||
// otherwise X errors out
|
// otherwise X errors out
|
||||||
@ -980,7 +993,8 @@ const ScreenShield = new Lang.Class({
|
|||||||
|
|
||||||
_onUnlockFailed: function() {
|
_onUnlockFailed: function() {
|
||||||
this._resetLockScreen({ animateLockScreen: true,
|
this._resetLockScreen({ animateLockScreen: true,
|
||||||
animateLockDialog: false });
|
animateLockDialog: false,
|
||||||
|
fadeToBlack: false });
|
||||||
},
|
},
|
||||||
|
|
||||||
_resetLockScreen: function(params) {
|
_resetLockScreen: function(params) {
|
||||||
@ -998,6 +1012,8 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._lockScreenGroup.show();
|
this._lockScreenGroup.show();
|
||||||
this._lockScreenState = MessageTray.State.SHOWING;
|
this._lockScreenState = MessageTray.State.SHOWING;
|
||||||
|
|
||||||
|
let fadeToBlack = params.fadeToBlack;
|
||||||
|
|
||||||
if (params.animateLockScreen) {
|
if (params.animateLockScreen) {
|
||||||
this._lockScreenGroup.y = -global.screen_height;
|
this._lockScreenGroup.y = -global.screen_height;
|
||||||
Tweener.removeTweens(this._lockScreenGroup);
|
Tweener.removeTweens(this._lockScreenGroup);
|
||||||
@ -1006,13 +1022,15 @@ const ScreenShield = new Lang.Class({
|
|||||||
time: MANUAL_FADE_TIME,
|
time: MANUAL_FADE_TIME,
|
||||||
transition: 'easeOutQuad',
|
transition: 'easeOutQuad',
|
||||||
onComplete: function() {
|
onComplete: function() {
|
||||||
this._lockScreenShown();
|
this._lockScreenShown({ fadeToBlack: fadeToBlack,
|
||||||
|
animateFade: true });
|
||||||
},
|
},
|
||||||
onCompleteScope: this
|
onCompleteScope: this
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this._lockScreenGroup.fixed_position_set = false;
|
this._lockScreenGroup.fixed_position_set = false;
|
||||||
this._lockScreenShown();
|
this._lockScreenShown({ fadeToBlack: fadeToBlack,
|
||||||
|
animateFade: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.animateLockDialog) {
|
if (params.animateLockDialog) {
|
||||||
@ -1079,7 +1097,7 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._pauseArrowAnimation();
|
this._pauseArrowAnimation();
|
||||||
},
|
},
|
||||||
|
|
||||||
_lockScreenShown: function() {
|
_lockScreenShown: function(params) {
|
||||||
if (this._dialog && !this._isGreeter) {
|
if (this._dialog && !this._isGreeter) {
|
||||||
this._dialog.destroy();
|
this._dialog.destroy();
|
||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
@ -1101,6 +1119,21 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._lockScreenGroup.fixed_position_set = false;
|
this._lockScreenGroup.fixed_position_set = false;
|
||||||
this._lockScreenScrollCounter = 0;
|
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;
|
let prevIsActive = this._isActive;
|
||||||
this._isActive = true;
|
this._isActive = true;
|
||||||
|
|
||||||
@ -1225,7 +1258,8 @@ const ScreenShield = new Lang.Class({
|
|||||||
this._dialog = null;
|
this._dialog = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._lightbox.hide();
|
this._longLightbox.hide();
|
||||||
|
this._shortLightbox.hide();
|
||||||
this.actor.hide();
|
this.actor.hide();
|
||||||
|
|
||||||
if (this._becameActiveId != 0) {
|
if (this._becameActiveId != 0) {
|
||||||
@ -1260,7 +1294,8 @@ const ScreenShield = new Lang.Class({
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._resetLockScreen({ animateLockScreen: animate,
|
this._resetLockScreen({ animateLockScreen: animate,
|
||||||
animateLockDialog: animate });
|
animateLockDialog: animate,
|
||||||
|
fadeToBlack: true });
|
||||||
global.set_runtime_state(LOCKED_STATE_STR, GLib.Variant.new('b', true));
|
global.set_runtime_state(LOCKED_STATE_STR, GLib.Variant.new('b', true));
|
||||||
|
|
||||||
// We used to set isActive and emit active-changed here,
|
// We used to set isActive and emit active-changed here,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user