diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js index a436431be..17de79c7e 100644 --- a/js/gdm/authPrompt.js +++ b/js/gdm/authPrompt.js @@ -8,6 +8,7 @@ const Signals = imports.signals; const St = imports.gi.St; const Animation = imports.ui.animation; +const AuthList = imports.gdm.authList; const Batch = imports.gdm.batch; const GdmUtil = imports.gdm.util; const Params = imports.misc.params; @@ -57,6 +58,7 @@ var AuthPrompt = new Lang.Class({ this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._onShowMessage)); + this._userVerifier.connect('show-choice-list', Lang.bind(this, this._onShowChoiceList)); this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed)); this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete)); this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); @@ -117,6 +119,17 @@ var AuthPrompt = new Lang.Class({ this._message.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; this.actor.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START }); + this._authList = new AuthList.AuthList(); + this._authList.connect('activate', (list, key) => { + this._userVerifier.selectChoice(this._queryingService, key); + }); + this._authList.actor.hide(); + this.actor.add(this._authList.actor, + { expand: true, + x_fill: true, + y_fill: false, + x_align: St.Align.START }); + this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box', vertical: false }); this.actor.add(this._buttonBox, @@ -222,6 +235,21 @@ var AuthPrompt = new Lang.Class({ this.emit('prompted'); }, + _onShowChoiceList: function(userVerifier, serviceName, choiceList) { + if (this._queryingService) + this.clear(); + + this._queryingService = serviceName; + + if (this._preemptiveAnswer) + this._preemptiveAnswer = null; + + this.nextButton.label = _("Next"); + this.setChoiceList(choiceList); + this.updateSensitivity(true); + this.emit('prompted'); + }, + _onOVirtUserAuthenticated: function() { if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) this.reset(); @@ -350,6 +378,8 @@ var AuthPrompt = new Lang.Class({ clear: function() { this._entry.text = ''; this.stopSpinning(); + this._authList.clear(); + this._authList.actor.hide(); }, setPasswordChar: function(passwordChar) { @@ -360,12 +390,25 @@ var AuthPrompt = new Lang.Class({ setQuestion: function(question) { this._label.set_text(question); + this._authList.actor.hide(); this._label.show(); this._entry.show(); this._entry.grab_key_focus(); }, + setChoiceList: function(choiceList) { + this._label.hide(); + this._entry.hide(); + + this._authList.clear(); + for (let key in choiceList) { + let text = choiceList[key]; + this._authList.addItem(key, text); + } + this._authList.actor.show(); + }, + getAnswer: function() { let text; @@ -416,7 +459,7 @@ var AuthPrompt = new Lang.Class({ }, updateSensitivity: function(sensitive) { - this._updateNextButtonSensitivity(sensitive && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING)); + this._updateNextButtonSensitivity(sensitive && !this._authList.actor.visible && (this._entry.text.length > 0 || this.verificationStatus == AuthPromptStatus.VERIFYING)); this._entry.reactive = sensitive; this._entry.clutter_text.editable = sensitive; }, diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js index 1cae3db85..afad6ac3c 100644 --- a/js/gdm/loginDialog.js +++ b/js/gdm/loginDialog.js @@ -418,6 +418,11 @@ var LoginDialog = new Lang.Class({ this._userManager = AccountsService.UserManager.get_default() this._gdmClient = new Gdm.Client(); + try { + this._gdmClient.set_enabled_extensions([Gdm.UserVerifierChoiceList.interface_info().name]); + } catch(e) { + } + this._settings = new Gio.Settings({ schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA }); this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY, diff --git a/js/gdm/util.js b/js/gdm/util.js index b65a7b0f0..cdc629049 100644 --- a/js/gdm/util.js +++ b/js/gdm/util.js @@ -199,6 +199,8 @@ var ShellUserVerifier = new Lang.Class({ if (this._userVerifier) { this._userVerifier.run_dispose(); this._userVerifier = null; + this._userVerifierChoiceList.run_dispose(); + this._userVerifierChoiceList = null; } }, @@ -226,6 +228,10 @@ var ShellUserVerifier = new Lang.Class({ this._oVirtCredentialsManager = null; }, + selectChoice: function(serviceName, key) { + this._userVerifierChoiceList.call_select_choice(serviceName, key, this._cancellable, null); + }, + answerQuery: function(serviceName, answer) { if (!this.hasPendingMessages) { this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null); @@ -365,6 +371,8 @@ var ShellUserVerifier = new Lang.Class({ return; } + this._userVerifierChoiceList = client.get_user_verifier_choice_list(); + this.reauthenticating = true; this._connectSignals(); this._beginVerification(); @@ -382,6 +390,8 @@ var ShellUserVerifier = new Lang.Class({ return; } + this._userVerifierChoiceList = client.get_user_verifier_choice_list(); + this._connectSignals(); this._beginVerification(); this._hold.release(); @@ -395,6 +405,9 @@ var ShellUserVerifier = new Lang.Class({ this._userVerifier.connect('conversation-stopped', Lang.bind(this, this._onConversationStopped)); this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete)); + + if (this._userVerifierChoiceList) + this._userVerifierChoiceList.connect('choice-query', Lang.bind(this, this._onChoiceListQuery)); }, _getForegroundService: function() { @@ -464,6 +477,13 @@ var ShellUserVerifier = new Lang.Class({ this._startService(FINGERPRINT_SERVICE_NAME); }, + _onChoiceListQuery: function(client, serviceName, list) { + if (!this.serviceIsForeground(serviceName)) + return; + + this.emit('show-choice-list', serviceName, list.deep_unpack()); + }, + _onInfo: function(client, serviceName, info) { if (this.serviceIsForeground(serviceName)) { this._queueMessage(info, MessageType.INFO);