ScreenShield: move lock status handling to use session mode

Have distinct session modes for the lock screen and the unlock dialog,
and rework the logic in ScreenShield to have the lock-screen mode stack
onto the unlock-dialog mode (where applicable)

https://bugzilla.gnome.org/show_bug.cgi?id=682542
This commit is contained in:
Giovanni Campagna 2012-08-26 16:53:08 +02:00
parent 09e3aed770
commit 8cf9baa132
4 changed files with 76 additions and 58 deletions

View File

@ -1513,8 +1513,7 @@ const MessageTray = new Lang.Class({
this._updateState(); this._updateState();
})); }));
this._isScreenLocked = false; Main.sessionMode.connect('updated', Lang.bind(this, this._updateState));
Main.screenShield.connect('lock-status-changed', Lang.bind(this, this._onScreenLockStatusChanged));
global.display.add_keybinding('toggle-message-tray', global.display.add_keybinding('toggle-message-tray',
new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }), new Gio.Settings({ schema: SHELL_KEYBINDINGS_SCHEMA }),
@ -1688,11 +1687,6 @@ const MessageTray = new Lang.Class({
this._notificationQueue.splice(index, 1); this._notificationQueue.splice(index, 1);
}, },
_onScreenLockStatusChanged: function(screenShield, locked) {
this._isScreenLocked = locked;
this._updateState();
},
_lock: function() { _lock: function() {
this._locked = true; this._locked = true;
}, },
@ -1919,15 +1913,12 @@ const MessageTray = new Lang.Class({
_updateState: function() { _updateState: function() {
// Notifications // Notifications
let notificationQueue = this._notificationQueue.filter(Lang.bind(this, function(notification) { let notificationQueue = this._notificationQueue.filter(Lang.bind(this, function(notification) {
if (this._isScreenLocked) return notification.showWhenLocked || Main.sessionMode.hasNotifications;
return notification.showWhenLocked;
else
return true;
})); }));
let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL; let notificationUrgent = notificationQueue.length > 0 && notificationQueue[0].urgency == Urgency.CRITICAL;
// notificationsLimited is false when the screen is locked, because they go through // notificationsLimited is false when the screen is locked, because they go through
// different filtering, and we want to show non urgent messages at times // different filtering, and we want to show non urgent messages at times
let notificationsLimited = (this._busy || this._inFullscreen) && !this._isScreenLocked; let notificationsLimited = (this._busy || this._inFullscreen) && Main.sessionMode.hasNotifications;
let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent); let notificationsPending = notificationQueue.length > 0 && (!notificationsLimited || notificationUrgent);
let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null; let nextNotification = notificationQueue.length > 0 ? notificationQueue[0] : null;
let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved; let notificationPinned = this._pointerInTray && !this._pointerInSummary && !this._notificationRemoved;
@ -1938,7 +1929,7 @@ const MessageTray = new Lang.Class({
!this._pointerInTray && !this._pointerInTray &&
!this._locked && !this._locked &&
!(this._pointerInKeyboard && notificationExpanded); !(this._pointerInKeyboard && notificationExpanded);
let notificationLockedOut = this._isScreenLocked && (this._notification && !this._notification.showWhenLocked); let notificationLockedOut = !Main.sessionMode.hasNotifications && (this._notification && !this._notification.showWhenLocked);
// TODO: how to deal with locked out notiifcations if want to keep showing notifications?! // TODO: how to deal with locked out notiifcations if want to keep showing notifications?!
let notificationMustClose = this._notificationRemoved || notificationLockedOut || (notificationExpired && this._userActiveWhileNotificationShown) || this._notificationClosed; let notificationMustClose = this._notificationRemoved || notificationLockedOut || (notificationExpired && this._userActiveWhileNotificationShown) || this._notificationClosed;
let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN; let canShowNotification = notificationsPending && this._summaryState == State.HIDDEN;
@ -1968,7 +1959,7 @@ const MessageTray = new Lang.Class({
let summaryOptionalInOverview = this._overviewVisible && !this._locked && !summaryHovered; let summaryOptionalInOverview = this._overviewVisible && !this._locked && !summaryHovered;
let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview)) let mustHideSummary = (notificationsPending && (notificationUrgent || summaryOptionalInOverview))
|| notificationsVisible || this._isScreenLocked; || notificationsVisible || !Main.sessionMode.hasNotifications;
if (this._summaryState == State.HIDDEN && !mustHideSummary && summarySummoned) if (this._summaryState == State.HIDDEN && !mustHideSummary && summarySummoned)
this._showSummary(); this._showSummary();

View File

@ -422,8 +422,9 @@ 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._isModal = false;
this._isLocked = false;
this._hasLockScreen = false; this._hasLockScreen = false;
this._isGreeter = false;
this._isActive = false;
this._lightbox = new Lightbox.Lightbox(Main.uiGroup, this._lightbox = new Lightbox.Lightbox(Main.uiGroup,
{ inhibitEvents: true, { inhibitEvents: true,
@ -519,7 +520,7 @@ const ScreenShield = new Lang.Class({
// If we have a unlock dialog, cancel it // If we have a unlock dialog, cancel it
if (this._dialog) { if (this._dialog) {
this._dialog.cancel(); this._dialog.cancel();
if (!this._keepDialog) { if (!this._isGreeter) {
this._dialog = null; this._dialog = null;
} }
} }
@ -530,7 +531,7 @@ const ScreenShield = new Lang.Class({
if (status == GnomeSession.PresenceStatus.IDLE) { if (status == GnomeSession.PresenceStatus.IDLE) {
if (this._dialog) { if (this._dialog) {
this._dialog.cancel(); this._dialog.cancel();
if (!this._keepDialog) { if (!this._isGreeter) {
this._dialog = null; this._dialog = null;
} }
} }
@ -540,14 +541,14 @@ const ScreenShield = new Lang.Class({
this._isModal = true; this._isModal = true;
} }
if (!this._isLocked) if (!this._isActive)
this._lightbox.show(); this._lightbox.show();
} else { } else {
let lightboxWasShown = this._lightbox.shown; let lightboxWasShown = this._lightbox.shown;
this._lightbox.hide(); this._lightbox.hide();
let shouldLock = lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY); let shouldLock = lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY);
if (shouldLock || this._isLocked) { if (shouldLock || this._isActive) {
this.lock(false); this.lock(false);
} else if (this._isModal) { } else if (this._isModal) {
this.unlock(); this.unlock();
@ -556,7 +557,13 @@ const ScreenShield = new Lang.Class({
}, },
showDialog: function() { showDialog: function() {
this.lock(true); if (!this._isModal) {
Main.pushModal(this.actor);
this._isModal = true;
}
this.actor.show();
this._isGreeter = Main.sessionMode.isGreeter;
this._ensureUnlockDialog(); this._ensureUnlockDialog();
this._hideLockScreen(false); this._hideLockScreen(false);
}, },
@ -590,25 +597,24 @@ const ScreenShield = new Lang.Class({
time: time, time: time,
transition: 'linear', transition: 'linear',
onComplete: function() { onComplete: function() {
this._lockScreenHidden(); this._lockScreenState = MessageTray.State.HIDDEN;
this._lockScreenGroup.hide();
}, },
onCompleteScope: this, onCompleteScope: this,
}); });
} else { } else {
this._lockScreenHidden(); this._lockScreenState = MessageTray.State.HIDDEN;
this._lockScreenGroup.hide();
} }
},
_lockScreenHidden: function() { if (Main.sessionMode.currentMode == 'lock-screen')
this._lockScreenState = MessageTray.State.HIDDEN; Main.sessionMode.popMode('lock-screen');
this._lockScreenGroup.hide();
}, },
_ensureUnlockDialog: function() { _ensureUnlockDialog: function() {
if (!this._dialog) { if (!this._dialog) {
let constructor = Main.sessionMode.unlockDialog; let constructor = Main.sessionMode.unlockDialog;
this._dialog = new constructor(this._lockDialogGroup); this._dialog = new constructor(this._lockDialogGroup);
this._keepDialog = Main.sessionMode.isGreeter;
if (!this._dialog) { if (!this._dialog) {
// This session mode has no locking capabilities // This session mode has no locking capabilities
this.unlock(); this.unlock();
@ -625,15 +631,6 @@ 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));
} }
if (Main.sessionMode.isGreeter) {
// Notify the other components that even though we are showing the
// screenshield, we're not in a locked state
// (this happens for the gdm greeter)
this._isLocked = false;
this.emit('lock-status-changed', false);
}
}, },
_onUnlockFailed: function() { _onUnlockFailed: function() {
@ -648,6 +645,7 @@ const ScreenShield = new Lang.Class({
}, },
_resetLockScreen: function(animate) { _resetLockScreen: function(animate) {
this._ensureLockScreen();
this._lockDialogGroup.scale_x = 1; this._lockDialogGroup.scale_x = 1;
this._lockDialogGroup.scale_y = 1; this._lockDialogGroup.scale_y = 1;
@ -679,6 +677,9 @@ const ScreenShield = new Lang.Class({
} }
this._lockScreenGroup.grab_key_focus(); this._lockScreenGroup.grab_key_focus();
if (Main.sessionMode.currentMode != 'lock-screen')
Main.sessionMode.pushMode('lock-screen');
}, },
_lockScreenShown: function() { _lockScreenShown: function() {
@ -696,7 +697,10 @@ const ScreenShield = new Lang.Class({
// Some of the actors in the lock screen are heavy in // Some of the actors in the lock screen are heavy in
// resources, so we only create them when needed // resources, so we only create them when needed
_prepareLockScreen: function() { _ensureLockScreen: function() {
if (this._hasLockScreen)
return;
this._lockScreenContentsBox = new St.BoxLayout({ x_align: Clutter.ActorAlign.CENTER, this._lockScreenContentsBox = new St.BoxLayout({ x_align: Clutter.ActorAlign.CENTER,
y_align: Clutter.ActorAlign.CENTER, y_align: Clutter.ActorAlign.CENTER,
x_expand: true, x_expand: true,
@ -738,7 +742,7 @@ const ScreenShield = new Lang.Class({
}, },
get locked() { get locked() {
return this._isLocked; return this._isActive;
}, },
_tweenUnlocked: function() { _tweenUnlocked: function() {
@ -760,13 +764,10 @@ const ScreenShield = new Lang.Class({
}, },
unlock: function() { unlock: function() {
if (!this._isLocked)
return;
if (this._hasLockScreen) if (this._hasLockScreen)
this._clearLockScreen(); this._clearLockScreen();
if (this._dialog && !this._keepDialog) { if (this._dialog && !this._isGreeter) {
this._dialog.destroy(); this._dialog.destroy();
this._dialog = null; this._dialog = null;
} }
@ -778,30 +779,36 @@ const ScreenShield = new Lang.Class({
this._isModal = false; this._isModal = false;
} }
this._isLocked = false; this.actor.hide();
this.emit('lock-status-changed', false); if (Main.sessionMode.currentMode == 'lock-screen')
Main.sessionMode.popMode('lock-screen'); Main.sessionMode.popMode('lock-screen');
if (Main.sessionMode.currentMode == 'unlock-dialog')
Main.sessionMode.popMode('unlock-dialog');
this._isActive = false;
this.emit('lock-status-changed');
}, },
lock: function(animate) { lock: function(animate) {
if (this._isLocked)
return;
if (!this._hasLockScreen)
this._prepareLockScreen();
if (!this._isModal) { if (!this._isModal) {
Main.pushModal(this.actor); Main.pushModal(this.actor);
this._isModal = true; this._isModal = true;
} }
this._isLocked = true;
this.actor.show(); this.actor.show();
if (Main.sessionMode.currentMode != 'unlock-dialog' &&
Main.sessionMode.currentMode != 'lock-screen') {
this._isGreeter = Main.sessionMode.isGreeter;
if (!this._isGreeter)
Main.sessionMode.pushMode('unlock-dialog');
}
this._resetLockScreen(animate); this._resetLockScreen(animate);
this.emit('lock-status-changed', true); this._isActive = true;
Main.sessionMode.pushMode('lock-screen'); this.emit('lock-status-changed');
}, },
}); });
Signals.addSignalMethods(ScreenShield.prototype); Signals.addSignalMethods(ScreenShield.prototype);

View File

@ -18,6 +18,7 @@ const _modes = {
hasRunDialog: false, hasRunDialog: false,
hasWorkspaces: false, hasWorkspaces: false,
hasWindows: false, hasWindows: false,
hasNotifications: false,
isLocked: false, isLocked: false,
isGreeter: false, isGreeter: false,
isPrimary: false, isPrimary: false,
@ -32,6 +33,7 @@ const _modes = {
'gdm': { 'gdm': {
allowKeybindingsWhenModal: true, allowKeybindingsWhenModal: true,
hasNotifications: true,
isGreeter: true, isGreeter: true,
isPrimary: true, isPrimary: true,
unlockDialog: imports.gdm.loginDialog.LoginDialog, unlockDialog: imports.gdm.loginDialog.LoginDialog,
@ -46,7 +48,6 @@ const _modes = {
'lock-screen': { 'lock-screen': {
isLocked: true, isLocked: true,
isGreeter: undefined,
unlockDialog: undefined, unlockDialog: undefined,
components: ['networkAgent', 'polkitAgent', 'telepathyClient'], components: ['networkAgent', 'polkitAgent', 'telepathyClient'],
panel: { panel: {
@ -56,6 +57,17 @@ const _modes = {
}, },
}, },
'unlock-dialog': {
isLocked: true,
unlockDialog: undefined,
components: ['networkAgent', 'polkitAgent', 'telepathyClient'],
panel: {
left: ['userMenu'],
center: [],
right: ['a11y', 'keyboard', 'lockScreen']
},
},
'initial-setup': { 'initial-setup': {
isPrimary: true, isPrimary: true,
components: ['keyring'], components: ['keyring'],
@ -74,9 +86,10 @@ const _modes = {
hasRunDialog: true, hasRunDialog: true,
hasWorkspaces: true, hasWorkspaces: true,
hasWindows: true, hasWindows: true,
unlockDialog: imports.ui.unlockDialog.UnlockDialog, hasNotifications: true,
isLocked: false, isLocked: false,
isPrimary: true, isPrimary: true,
unlockDialog: imports.ui.unlockDialog.UnlockDialog,
components: ['networkAgent', 'polkitAgent', 'telepathyClient', components: ['networkAgent', 'polkitAgent', 'telepathyClient',
'keyring', 'recorder', 'autorunManager', 'automountManager'], 'keyring', 'recorder', 'autorunManager', 'automountManager'],
panel: { panel: {
@ -118,6 +131,13 @@ const SessionMode = new Lang.Class({
this._sync(); this._sync();
}, },
switchMode: function(to) {
if (this.currentMode == to)
return;
this._modeStack[this._modeStack.length - 1] = to;
this._sync();
},
get currentMode() { get currentMode() {
return this._modeStack[this._modeStack.length - 1]; return this._modeStack[this._modeStack.length - 1];
}, },

View File

@ -343,8 +343,8 @@ const ScreenSaverDBus = new Lang.Class({
_init: function() { _init: function() {
this.parent(); this.parent();
Main.screenShield.connect('lock-status-changed', Lang.bind(this, function(shield, locked) { Main.screenShield.connect('lock-status-changed', Lang.bind(this, function(shield) {
this._dbusImpl.emit_signal('ActiveChanged', GLib.Variant.new('(b)', [locked])); this._dbusImpl.emit_signal('ActiveChanged', GLib.Variant.new('(b)', [shield.locked]));
})); }));
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreenSaverIface, this); this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ScreenSaverIface, this);