ScreenShield: improve locking/modal policy

Ensure that the lightbox is above everything (including the screenlock
itself) when fading in - this allows for fading while showing the
unlock dialog. Also, don't pushModal again when already locked, or
we won't get out of it.

https://bugzilla.gnome.org/show_bug.cgi?id=619955
This commit is contained in:
Giovanni Campagna 2012-05-21 18:42:45 +02:00
parent 2c3ec7846f
commit c22a00afee

View File

@ -4,6 +4,7 @@ const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const Lang = imports.lang; const Lang = imports.lang;
const Meta = imports.gi.Meta; const Meta = imports.gi.Meta;
const Signals = imports.signals;
const St = imports.gi.St; const St = imports.gi.St;
const GnomeSession = imports.misc.gnomeSession; const GnomeSession = imports.misc.gnomeSession;
@ -42,6 +43,8 @@ const ScreenShield = new Lang.Class({
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA }); this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
this._isModal = false;
this._isLocked = false;
this._group = new St.Widget({ x: 0, this._group = new St.Widget({ x: 0,
y: 0 }); y: 0 });
Main.uiGroup.add_actor(this._group); Main.uiGroup.add_actor(this._group);
@ -57,22 +60,28 @@ const ScreenShield = new Lang.Class({
}, },
_onStatusChanged: function(status) { _onStatusChanged: function(status) {
log ("in _onStatusChanged");
if (status == GnomeSession.PresenceStatus.IDLE) { if (status == GnomeSession.PresenceStatus.IDLE) {
log("session gone idle"); if (this._dialog) {
this._dialog.cancel();
this._dialog = null;
}
this._group.reactive = true; this._group.reactive = true;
if (!this._isModal) {
Main.pushModal(this._group); Main.pushModal(this._group);
this._isModal = true;
}
if (!this._isLocked)
this._lightbox.show(); this._lightbox.show();
} else { } else {
let lightboxWasShown = this._lightbox.shown; let lightboxWasShown = this._lightbox.shown;
log("this._lightbox.shown " + this._lightbox.shown);
this._lightbox.hide(); this._lightbox.hide();
if (lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY)) {
this._background.show();
this._background.raise_top();
this._showUnlockDialog(); let shouldLock = lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY);
} else { if (shouldLock || this._isLocked) {
this.lock();
} else if (this._isModal) {
this._popModal(); this._popModal();
} }
} }
@ -80,9 +89,14 @@ const ScreenShield = new Lang.Class({
_popModal: function() { _popModal: function() {
this._group.reactive = false; this._group.reactive = false;
if (Main.isInModalStack(this._group))
Main.popModal(this._group); Main.popModal(this._group);
this._background.hide(); this._background.hide();
this._isModal = false;
this._isLocked = false;
this.emit('lock-status-changed', false);
}, },
_showUnlockDialog: function() { _showUnlockDialog: function() {
@ -93,7 +107,15 @@ const ScreenShield = new Lang.Class({
this._dialog.connect('failed', Lang.bind(this, this._onUnlockFailed)); this._dialog.connect('failed', Lang.bind(this, this._onUnlockFailed));
this._dialog.connect('unlocked', Lang.bind(this, this._onUnlockSucceded)); this._dialog.connect('unlocked', Lang.bind(this, this._onUnlockSucceded));
this._dialog.open(global.get_current_time()); if (!this._dialog.open(global.get_current_time())) {
log('Could not open unlock dialog: failed to acquire grab');
// and then? best we can do is to autounlock, although that's potentially
// a security issue
this._onUnlockSucceded();
}
this._dialog._group.raise_top();
}, },
_onUnlockFailed: function() { _onUnlockFailed: function() {
@ -113,4 +135,25 @@ const ScreenShield = new Lang.Class({
this._popModal(); this._popModal();
}, },
get locked() {
return this._isLocked;
},
lock: function() {
if (!this._isModal) {
Main.pushModal(this.actor);
this._isModal = true;
}
let wasLocked = this._isLocked;
this._isLocked = true;
this.actor.show();
this._showUnlockDialog();
if (!wasLocked)
this.emit('lock-status-changed', true);
}
}); });
Signals.addSignalMethods(ScreenShield.prototype);