ScreenShield: lower the shield when the user is idle but before locking

In time span between idle and lock the shield should behave like autologin,
but should prevent accidental reactivation (for example when using a touch
screen) by showing the curtain.

https://bugzilla.gnome.org/show_bug.cgi?id=692560
This commit is contained in:
Giovanni Campagna 2013-01-27 15:45:04 +01:00
parent 3f6f597093
commit 9a25224890
3 changed files with 79 additions and 52 deletions

View File

@ -315,7 +315,7 @@ const AppMenuButton = new Lang.Class({
},
show: function() {
if (this._visible || Main.screenShield.locked)
if (this._visible)
return;
this._visible = true;

View File

@ -527,7 +527,7 @@ const ScreenShield = new Lang.Class({
this._loginManager = LoginManager.getLoginManager();
this._loginSession = this._loginManager.getCurrentSessionProxy();
this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); }));
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.unlock(); }));
this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.deactivate(false); }));
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
@ -538,6 +538,7 @@ const ScreenShield = new Lang.Class({
this._inUnlockAnimation = false;
this._activationTime = 0;
this._becameActiveId = 0;
this._lockTimeoutId = 0;
this._lightbox = new Lightbox.Lightbox(Main.uiGroup,
{ inhibitEvents: true,
@ -548,6 +549,15 @@ const ScreenShield = new Lang.Class({
this.idleMonitor = new GnomeDesktop.IdleMonitor();
},
_liftShield: function(onPrimary, velocity) {
if (this._isLocked) {
this._ensureUnlockDialog(onPrimary, true /* allowCancel */);
this._hideLockScreen(true /* animate */, velocity);
} else {
this.deactivate(true /* animate */);
}
},
_onLockScreenKeyRelease: function(actor, event) {
let symbol = event.get_key_symbol();
@ -565,8 +575,7 @@ const ScreenShield = new Lang.Class({
if (symbol == Clutter.KEY_Escape ||
symbol == Clutter.KEY_Return ||
symbol == Clutter.KEY_KP_Enter) {
this._ensureUnlockDialog(true, true);
this._hideLockScreen(true, 0);
this._liftShield(false, 0);
return true;
}
@ -588,8 +597,7 @@ const ScreenShield = new Lang.Class({
// 7 standard scrolls to lift up
if (this._lockScreenScrollCounter > 35) {
this._ensureUnlockDialog(false, true);
this._hideLockScreen(true, 0);
this._liftShield(true, 0);
}
return true;
@ -620,7 +628,9 @@ const ScreenShield = new Lang.Class({
_onDragBegin: function() {
Tweener.removeTweens(this._lockScreenGroup);
this._lockScreenState = MessageTray.State.HIDING;
this._ensureUnlockDialog(false, false);
if (this._isLocked)
this._ensureUnlockDialog(false, false);
return true;
},
@ -641,8 +651,7 @@ const ScreenShield = new Lang.Class({
if (this._lockScreenGroup.y < -(ARROW_DRAG_THRESHOLD * global.stage.height)) {
// Complete motion automatically
let [velocity, velocityX, velocityY] = this._dragAction.get_velocity(0);
this._hideLockScreen(true, -velocityY);
this._ensureUnlockDialog(false, true);
this._liftShield(true, -velocityY);
} else {
// restore the lock screen to its original place
// try to use the same speed as the normal animation
@ -707,6 +716,18 @@ const ScreenShield = new Lang.Class({
if (this._becameActiveId == 0)
this._becameActiveId = this.idleMonitor.connect('became-active',
Lang.bind(this, this._onUserBecameActive));
let shouldLock = this._settings.get_boolean(LOCK_ENABLED_KEY) && !this._isLocked;
if (shouldLock) {
let lockTimeout = Math.max(STANDARD_FADE_TIME, this._settings.get_uint(LOCK_DELAY_KEY));
this._lockTimeoutId = Mainloop.timeout_add(lockTimeout * 1000,
Lang.bind(this, function() {
this._lockTimeoutId = 0;
this.lock(true);
return false;
}));
}
},
_onUserBecameActive: function() {
@ -734,23 +755,15 @@ const ScreenShield = new Lang.Class({
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 (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();
// Shortcircuit in case the mouse was moved before the fade completed
if (!lightboxWasShown) {
this.deactivate(false);
return;
}
},
_onLightboxShown: function() {
this._isActive = true;
this.emit('lock-status-changed');
this.activate(false);
},
showDialog: function() {
@ -767,6 +780,7 @@ const ScreenShield = new Lang.Class({
this.actor.show();
this._isGreeter = Main.sessionMode.isGreeter;
this._isLocked = true;
this._ensureUnlockDialog(true, true);
this._hideLockScreen(false, 0);
},
@ -787,6 +801,9 @@ const ScreenShield = new Lang.Class({
},
_hideLockScreen: function(animate, velocity) {
if (this._lockScreenState == MessageTray.State.HIDDEN)
return;
this._lockScreenState = MessageTray.State.HIDING;
if (animate) {
@ -828,7 +845,7 @@ const ScreenShield = new Lang.Class({
let constructor = Main.sessionMode.unlockDialog;
if (!constructor) {
// This session mode has no locking capabilities
this.unlock();
this.deactivate(true);
return;
}
@ -838,8 +855,10 @@ const ScreenShield = new Lang.Class({
let time = global.get_current_time();
this._dialog.connect('loaded', Lang.bind(this, function() {
if (!this._dialog.open(time, onPrimary)) {
// This is kind of an impossible error: we're already modal
// by the time we reach this...
log('Could not open login dialog: failed to acquire grab');
this.unlock();
this.deactivate(true);
}
}));
@ -855,12 +874,15 @@ const ScreenShield = new Lang.Class({
},
_onUnlockSucceded: function() {
this._tweenUnlocked();
this.deactivate(true);
},
_resetLockScreen: function(animateLockScreen, animateLockDialog) {
if (this._lockScreenState == MessageTray.State.SHOWING ||
this._lockScreenState == MessageTray.State.SHOWN)
// Don't reset the lock screen unless it is completely hidden
// This prevents the shield going down if the lock-delay timeout
// fires while the user is dragging (which has the potential
// to confuse our state)
if (this._lockScreenState != MessageTray.State.HIDDEN)
return;
this._ensureLockScreen();
@ -978,6 +1000,10 @@ const ScreenShield = new Lang.Class({
},
get locked() {
return this._isLocked;
},
get active() {
return this._isActive;
},
@ -985,27 +1011,20 @@ const ScreenShield = new Lang.Class({
return this._activationTime;
},
_tweenUnlocked: function() {
this._inUnlockAnimation = true;
this.unlock();
deactivate: function(animate) {
this._hideLockScreen(animate, 0);
Tweener.addTween(this._lockDialogGroup, {
scale_x: 0,
scale_y: 0,
time: Overview.ANIMATION_TIME,
time: animate ? Overview.ANIMATION_TIME : 0,
transition: 'easeOutQuad',
onComplete: function() {
if (this._dialog) {
this._dialog.destroy();
this._dialog = null;
}
this.actor.hide();
this._inUnlockAnimation = false;
},
onComplete: Lang.bind(this, this._completeDeactivate),
onCompleteScope: this
});
},
unlock: function() {
_completeDeactivate: function() {
if (this._hasLockScreen)
this._clearLockScreen();
@ -1021,8 +1040,7 @@ const ScreenShield = new Lang.Class({
this._isModal = false;
}
if (!this._inUnlockAnimation)
this.actor.hide();
this.actor.hide();
if (Main.sessionMode.currentMode == 'lock-screen')
Main.sessionMode.popMode('lock-screen');
@ -1034,18 +1052,18 @@ const ScreenShield = new Lang.Class({
this._becameActiveId = 0;
}
if (this._lockTimeoutId != 0) {
Mainloop.source_remove(this._lockTimeoutId);
this._lockTimeoutId = 0;
}
this._activationTime = 0;
this._isActive = false;
this._isLocked = false;
this.emit('lock-status-changed');
},
lock: function(animate) {
if (!this._isModal) {
Main.pushModal(this.actor, { keybindingMode: Main.KeybindingMode.LOCK_SCREEN });
this._isModal = true;
}
activate: function(animate) {
if (this._activationTime == 0)
this._activationTime = GLib.get_monotonic_time();
@ -1061,9 +1079,18 @@ const ScreenShield = new Lang.Class({
this._resetLockScreen(animate, animate);
this._isActive = true;
this._isLocked = true;
this.emit('lock-status-changed');
},
lock: function(animate) {
if (!this._isModal) {
Main.pushModal(this.actor, { keybindingMode: Main.KeybindingMode.LOCK_SCREEN });
this._isModal = true;
}
this._isLocked = true;
this.activate(animate);
},
});
Signals.addSignalMethods(ScreenShield.prototype);

View File

@ -269,13 +269,13 @@ const ScreenSaverDBus = new Lang.Class({
SetActive: function(active) {
if (active)
this._screenShield.lock(true);
this._screenShield.activate(true);
else
this._screenShield.unlock();
this._screenShield.unlock(false);
},
GetActive: function() {
return this._screenShield.locked;
return this._screenShield.active;
},
GetActiveTime: function() {