From 37e55df29865dac13656116efdd7abec8056dea9 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Mon, 2 Dec 2019 11:01:20 -0300 Subject: [PATCH] unlockDialog: Create auth prompt on demand AuthPrompt is the set of actors that contain the user avatar, the username, and the password entry. With the removal of the screen shield, the unlock dialog (be it UnlockDialog or the LoginDialog) is always created, and in the case of UnlockDialog, so is the auth prompt. This is problematic, though, since for passwordless accounts, the simple act of creating AuthPrompt authenticates the user, and lifts the lock screen. Create the AuthPrompt on demand in UnlockDialog. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872 --- js/ui/unlockDialog.js | 90 +++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 28 deletions(-) diff --git a/js/ui/unlockDialog.js b/js/ui/unlockDialog.js index ec08acd1c..9b8cfd935 100644 --- a/js/ui/unlockDialog.js +++ b/js/ui/unlockDialog.js @@ -453,34 +453,9 @@ var UnlockDialog = GObject.registerClass({ stack.add_child(this._clock); this._showClock(); - this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY); - this._authPrompt.connect('failed', this._fail.bind(this)); - this._authPrompt.connect('cancelled', this._fail.bind(this)); - this._authPrompt.connect('reset', this._onReset.bind(this)); - this._authPrompt.nextButton.label = _("Unlock"); - - this._promptBox.add_child(this._authPrompt); - this.allowCancel = false; - let screenSaverSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.screensaver' }); - if (screenSaverSettings.get_boolean('user-switch-enabled')) { - let otherUserLabel = new St.Label({ text: _("Log in as another user"), - style_class: 'login-dialog-not-listed-label' }); - this._otherUserButton = new St.Button({ style_class: 'login-dialog-not-listed-button', - can_focus: true, - child: otherUserLabel, - reactive: true }); - this._otherUserButton.connect('clicked', this._otherUserClicked.bind(this)); - this._promptBox.add_child(this._otherUserButton); - } else { - this._otherUserButton = null; - } - - this._authPrompt.reset(); - this._updateSensitivity(true); - - Main.ctrlAltTabManager.addGroup(this, _("Unlock Window"), 'dialog-password-symbolic'); + Main.ctrlAltTabManager.addGroup(this, _('Unlock Window'), 'dialog-password-symbolic'); // Notifications this._notificationsBox = new NotificationsBox(); @@ -555,6 +530,58 @@ var UnlockDialog = GObject.registerClass({ this._createBackground(i); } + _ensureAuthPrompt() { + if (this._authPrompt) + return; + + this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY); + this._authPrompt.connect('failed', this._fail.bind(this)); + this._authPrompt.connect('cancelled', this._fail.bind(this)); + this._authPrompt.connect('reset', this._onReset.bind(this)); + this._authPrompt.nextButton.label = _("Unlock"); + + this._promptBox.add_child(this._authPrompt); + + let screenSaverSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.screensaver' }); + if (screenSaverSettings.get_boolean('user-switch-enabled')) { + let otherUserLabel = new St.Label({ + text: _('Log in as another user'), + style_class: 'login-dialog-not-listed-label', + }); + this._otherUserButton = new St.Button({ + style_class: 'login-dialog-not-listed-button', + can_focus: true, + child: otherUserLabel, + reactive: true, + }); + this._otherUserButton.connect('clicked', this._otherUserClicked.bind(this)); + this._promptBox.add_child(this._otherUserButton); + } else { + this._otherUserButton = null; + } + + this._authPrompt.reset(); + this._updateSensitivity(true); + } + + _maybeDestroyAuthPrompt() { + let focus = global.stage.key_focus; + if (focus === null || + (this._authPrompt && this._authPrompt.contains(focus)) || + (this._otherUserButton && focus === this._otherUserButton)) + this.grab_key_focus(); + + if (this._authPrompt) { + this._authPrompt.destroy(); + this._authPrompt = null; + } + + if (this._otherUserButton) { + this._otherUserButton.destroy(); + this._otherUserButton = null; + } + } + _updateSensitivity(sensitive) { this._authPrompt.updateSensitivity(sensitive); @@ -575,7 +602,10 @@ var UnlockDialog = GObject.registerClass({ opacity: 0, duration: CROSSFADE_TIME, mode: Clutter.AnimationMode.EASE_OUT_QUAD, - onComplete: () => this._promptBox.hide(), + onComplete: () => { + this._promptBox.hide(); + this._maybeDestroyAuthPrompt(); + }, }); this._clock.ease({ @@ -586,6 +616,8 @@ var UnlockDialog = GObject.registerClass({ } _showPrompt() { + this._ensureAuthPrompt(); + if (this._activePage === this._promptBox) return; @@ -649,7 +681,8 @@ var UnlockDialog = GObject.registerClass({ } cancel() { - this._authPrompt.cancel(); + if (this._authPrompt) + this._authPrompt.cancel(); } addCharacter(unichar) { @@ -658,6 +691,7 @@ var UnlockDialog = GObject.registerClass({ } finish(onComplete) { + this._ensureAuthPrompt(); this._authPrompt.finish(onComplete); }