580c05
From 68c280c3bcf8a67a90eb25c30b2e6c2493d7d4d9 Mon Sep 17 00:00:00 2001
580c05
From: Ray Strode <rstrode@redhat.com>
580c05
Date: Wed, 30 Sep 2015 12:47:01 -0400
580c05
Subject: [PATCH 1/4] authPrompt: use correct service name when answering
580c05
 preemptively
580c05
580c05
If the user hits enter before a question is asked, we try to answer
580c05
that question as soon as it comes in.
580c05
580c05
This doesn't work right now because we only answer the question if
580c05
there's a query service, but there won't ever be one until the
580c05
question is asked.
580c05
580c05
This commit corrects the code to it's intention, which is to answer
580c05
the first service that asks a question, as as soon as possible.
580c05
---
580c05
 js/gdm/authPrompt.js | 3 +--
580c05
 1 file changed, 1 insertion(+), 2 deletions(-)
580c05
580c05
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
580c05
index 34ad7fb..816c69c 100644
580c05
--- a/js/gdm/authPrompt.js
580c05
+++ b/js/gdm/authPrompt.js
580c05
@@ -167,62 +167,61 @@ const AuthPrompt = new Lang.Class({
580c05
                                           can_focus: true,
580c05
                                           label: _("Next") });
580c05
         this.nextButton.connect('clicked',
580c05
                                  Lang.bind(this, function() {
580c05
                                      this.emit('next');
580c05
                                  }));
580c05
         this.nextButton.add_style_pseudo_class('default');
580c05
         this._buttonBox.add(this.nextButton,
580c05
                             { expand: false,
580c05
                               x_fill: false,
580c05
                               y_fill: false,
580c05
                               x_align: St.Align.END,
580c05
                               y_align: St.Align.END });
580c05
 
580c05
         this._updateNextButtonSensitivity(this._entry.text.length > 0);
580c05
 
580c05
         this._entry.clutter_text.connect('text-changed',
580c05
                                          Lang.bind(this, function() {
580c05
                                              if (!this._userVerifier.hasPendingMessages)
580c05
                                                  this._fadeOutMessage();
580c05
 
580c05
                                              this._updateNextButtonSensitivity(this._entry.text.length > 0);
580c05
                                          }));
580c05
         this._entry.clutter_text.connect('activate', Lang.bind(this, function() {
580c05
             this.emit('next');
580c05
         }));
580c05
     },
580c05
 
580c05
     _onAskQuestion: function(verifier, serviceName, question, passwordChar) {
580c05
         if (this._preemptiveAnswer) {
580c05
-            if (this._queryingService)
580c05
-                this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer);
580c05
+            this._userVerifier.answerQuery(serviceName, this._preemptiveAnswer);
580c05
             this._preemptiveAnswer = null;
580c05
             return;
580c05
         }
580c05
 
580c05
         if (this._queryingService)
580c05
             this.clear();
580c05
 
580c05
         this._queryingService = serviceName;
580c05
         this.setPasswordChar(passwordChar);
580c05
         this.setQuestion(question);
580c05
 
580c05
         if (passwordChar) {
580c05
             if (this._userVerifier.reauthenticating)
580c05
                 this.nextButton.label = _("Unlock");
580c05
             else
580c05
                 this.nextButton.label = C_("button", "Sign In");
580c05
         } else {
580c05
             this.nextButton.label = _("Next");
580c05
         }
580c05
 
580c05
         this.updateSensitivity(true);
580c05
         this.emit('prompted');
580c05
     },
580c05
 
580c05
     _onOVirtUserAuthenticated: function() {
580c05
         if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED)
580c05
             this.reset();
580c05
     },
580c05
 
580c05
     _onSmartcardStatusChanged: function() {
580c05
-- 
580c05
2.5.0
580c05
580c05
580c05
From 1b7fa7ad6874208873eb8ce1e8b03dc07cb01217 Mon Sep 17 00:00:00 2001
580c05
From: Ray Strode <rstrode@redhat.com>
580c05
Date: Wed, 30 Sep 2015 12:51:24 -0400
580c05
Subject: [PATCH 2/4] authPrompt: don't fade out auth messages if user types
580c05
 password up front
580c05
580c05
Right now we fade out any stale auth messages as soon as the user starts
580c05
typing. This behavior doesn't really make sense if the user is typing up
580c05
front, before a password is asked.
580c05
---
580c05
 js/gdm/authPrompt.js | 2 +-
580c05
 1 file changed, 1 insertion(+), 1 deletion(-)
580c05
580c05
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
580c05
index 816c69c..11b6a23 100644
580c05
--- a/js/gdm/authPrompt.js
580c05
+++ b/js/gdm/authPrompt.js
580c05
@@ -155,61 +155,61 @@ const AuthPrompt = new Lang.Class({
580c05
                               x_align: St.Align.START,
580c05
                               y_align: St.Align.END });
580c05
 
580c05
         this._buttonBox.add(this._defaultButtonWell,
580c05
                             { expand: true,
580c05
                               x_fill: false,
580c05
                               y_fill: false,
580c05
                               x_align: St.Align.END,
580c05
                               y_align: St.Align.MIDDLE });
580c05
         this.nextButton = new St.Button({ style_class: 'modal-dialog-button',
580c05
                                           button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
580c05
                                           reactive: true,
580c05
                                           can_focus: true,
580c05
                                           label: _("Next") });
580c05
         this.nextButton.connect('clicked',
580c05
                                  Lang.bind(this, function() {
580c05
                                      this.emit('next');
580c05
                                  }));
580c05
         this.nextButton.add_style_pseudo_class('default');
580c05
         this._buttonBox.add(this.nextButton,
580c05
                             { expand: false,
580c05
                               x_fill: false,
580c05
                               y_fill: false,
580c05
                               x_align: St.Align.END,
580c05
                               y_align: St.Align.END });
580c05
 
580c05
         this._updateNextButtonSensitivity(this._entry.text.length > 0);
580c05
 
580c05
         this._entry.clutter_text.connect('text-changed',
580c05
                                          Lang.bind(this, function() {
580c05
-                                             if (!this._userVerifier.hasPendingMessages)
580c05
+                                             if (!this._userVerifier.hasPendingMessages && this._queryingService && !this._preemptiveAnswer)
580c05
                                                  this._fadeOutMessage();
580c05
 
580c05
                                              this._updateNextButtonSensitivity(this._entry.text.length > 0);
580c05
                                          }));
580c05
         this._entry.clutter_text.connect('activate', Lang.bind(this, function() {
580c05
             this.emit('next');
580c05
         }));
580c05
     },
580c05
 
580c05
     _onAskQuestion: function(verifier, serviceName, question, passwordChar) {
580c05
         if (this._preemptiveAnswer) {
580c05
             this._userVerifier.answerQuery(serviceName, this._preemptiveAnswer);
580c05
             this._preemptiveAnswer = null;
580c05
             return;
580c05
         }
580c05
 
580c05
         if (this._queryingService)
580c05
             this.clear();
580c05
 
580c05
         this._queryingService = serviceName;
580c05
         this.setPasswordChar(passwordChar);
580c05
         this.setQuestion(question);
580c05
 
580c05
         if (passwordChar) {
580c05
             if (this._userVerifier.reauthenticating)
580c05
                 this.nextButton.label = _("Unlock");
580c05
             else
580c05
                 this.nextButton.label = C_("button", "Sign In");
580c05
         } else {
580c05
             this.nextButton.label = _("Next");
580c05
-- 
580c05
2.5.0
580c05
580c05
580c05
From 3b767c0a55b136b53b7c85aff2095969fb230ce4 Mon Sep 17 00:00:00 2001
580c05
From: Ray Strode <rstrode@redhat.com>
580c05
Date: Wed, 30 Sep 2015 14:36:33 -0400
580c05
Subject: [PATCH 3/4] authPrompt: don't spin unless answering question
580c05
580c05
---
580c05
 js/gdm/authPrompt.js | 2 +-
580c05
 1 file changed, 1 insertion(+), 1 deletion(-)
580c05
580c05
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
580c05
index 11b6a23..875f9c5 100644
580c05
--- a/js/gdm/authPrompt.js
580c05
+++ b/js/gdm/authPrompt.js
580c05
@@ -37,62 +37,62 @@ const BeginRequestType = {
580c05
 };
580c05
 
580c05
 const AuthPrompt = new Lang.Class({
580c05
     Name: 'AuthPrompt',
580c05
 
580c05
     _init: function(gdmClient, mode) {
580c05
         this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
580c05
 
580c05
         this._gdmClient = gdmClient;
580c05
         this._mode = mode;
580c05
 
580c05
         let reauthenticationOnly;
580c05
         if (this._mode == AuthPromptMode.UNLOCK_ONLY)
580c05
             reauthenticationOnly = true;
580c05
         else if (this._mode == AuthPromptMode.UNLOCK_OR_LOG_IN)
580c05
             reauthenticationOnly = false;
580c05
 
580c05
         this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly });
580c05
 
580c05
         this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
580c05
         this._userVerifier.connect('show-message', Lang.bind(this, this._onShowMessage));
580c05
         this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed));
580c05
         this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
580c05
         this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
580c05
         this._userVerifier.connect('smartcard-status-changed', Lang.bind(this, this._onSmartcardStatusChanged));
580c05
         this._userVerifier.connect('ovirt-user-authenticated', Lang.bind(this, this._onOVirtUserAuthenticated));
580c05
         this.smartcardDetected = this._userVerifier.smartcardDetected;
580c05
 
580c05
         this.connect('next', Lang.bind(this, function() {
580c05
                          this.updateSensitivity(false);
580c05
-                         this.startSpinning();
580c05
                          if (this._queryingService) {
580c05
+                             this.startSpinning();
580c05
                              this._userVerifier.answerQuery(this._queryingService, this._entry.text);
580c05
                          } else {
580c05
                              this._preemptiveAnswer = this._entry.text;
580c05
                          }
580c05
                      }));
580c05
 
580c05
         this.actor = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
580c05
                                         vertical: true });
580c05
         this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
580c05
         this.actor.connect('key-press-event',
580c05
                            Lang.bind(this, function(actor, event) {
580c05
                                if (event.get_key_symbol() == Clutter.KEY_Escape) {
580c05
                                    this.cancel();
580c05
                                }
580c05
                                return Clutter.EVENT_PROPAGATE;
580c05
                            }));
580c05
 
580c05
         this._userWell = new St.Bin({ x_fill: true,
580c05
                                       x_align: St.Align.START });
580c05
         this.actor.add(this._userWell,
580c05
                        { x_align: St.Align.START,
580c05
                          x_fill: true,
580c05
                          y_fill: true,
580c05
                          expand: true });
580c05
         this._label = new St.Label({ style_class: 'login-dialog-prompt-label' });
580c05
 
580c05
         this.actor.add(this._label,
580c05
                        { expand: true,
580c05
                          x_fill: false,
580c05
                          y_fill: true,
580c05
-- 
580c05
2.5.0
580c05
580c05
580c05
From 22d618c293906defbac877925491af13f8def9a3 Mon Sep 17 00:00:00 2001
580c05
From: Ray Strode <rstrode@redhat.com>
580c05
Date: Mon, 5 Oct 2015 15:26:18 -0400
580c05
Subject: [PATCH 4/4] authPrompt: stop accepting preemptive answer if user stops
580c05
 typing
580c05
580c05
We only want to allow the user to type the preemptive password in
580c05
one smooth motion.  If they start to type, and then stop typing,
580c05
we should discard their preemptive password as expired.
580c05
580c05
Typing ahead the password is just a convenience for users who don't
580c05
want to manually lift the shift before typing their passwords, after
580c05
all.
580c05
---
580c05
 js/gdm/authPrompt.js | 38 ++++++++++++++++++++++++++++++++++++++
580c05
 1 file changed, 38 insertions(+)
580c05
580c05
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
580c05
index 875f9c5..fe80519 100644
580c05
--- a/js/gdm/authPrompt.js
580c05
+++ b/js/gdm/authPrompt.js
580c05
@@ -1,101 +1,109 @@
580c05
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
580c05
 
580c05
 const Clutter = imports.gi.Clutter;
580c05
 const Lang = imports.lang;
580c05
 const Signals = imports.signals;
580c05
 const St = imports.gi.St;
580c05
 
580c05
 const Animation = imports.ui.animation;
580c05
 const Batch = imports.gdm.batch;
580c05
 const GdmUtil = imports.gdm.util;
580c05
+const Meta = imports.gi.Meta;
580c05
 const Params = imports.misc.params;
580c05
 const ShellEntry = imports.ui.shellEntry;
580c05
 const Tweener = imports.ui.tweener;
580c05
 const UserWidget = imports.ui.userWidget;
580c05
 
580c05
 const DEFAULT_BUTTON_WELL_ICON_SIZE = 24;
580c05
 const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0;
580c05
 const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3;
580c05
 
580c05
 const MESSAGE_FADE_OUT_ANIMATION_TIME = 0.5;
580c05
 
580c05
 const AuthPromptMode = {
580c05
     UNLOCK_ONLY: 0,
580c05
     UNLOCK_OR_LOG_IN: 1
580c05
 };
580c05
 
580c05
 const AuthPromptStatus = {
580c05
     NOT_VERIFYING: 0,
580c05
     VERIFYING: 1,
580c05
     VERIFICATION_FAILED: 2,
580c05
     VERIFICATION_SUCCEEDED: 3
580c05
 };
580c05
 
580c05
 const BeginRequestType = {
580c05
     PROVIDE_USERNAME: 0,
580c05
     DONT_PROVIDE_USERNAME: 1
580c05
 };
580c05
 
580c05
 const AuthPrompt = new Lang.Class({
580c05
     Name: 'AuthPrompt',
580c05
 
580c05
     _init: function(gdmClient, mode) {
580c05
         this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
580c05
 
580c05
         this._gdmClient = gdmClient;
580c05
         this._mode = mode;
580c05
 
580c05
+        this._idleMonitor = Meta.IdleMonitor.get_core();
580c05
+
580c05
         let reauthenticationOnly;
580c05
         if (this._mode == AuthPromptMode.UNLOCK_ONLY)
580c05
             reauthenticationOnly = true;
580c05
         else if (this._mode == AuthPromptMode.UNLOCK_OR_LOG_IN)
580c05
             reauthenticationOnly = false;
580c05
 
580c05
         this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly });
580c05
 
580c05
         this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
580c05
         this._userVerifier.connect('show-message', Lang.bind(this, this._onShowMessage));
580c05
         this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed));
580c05
         this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
580c05
         this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
580c05
         this._userVerifier.connect('smartcard-status-changed', Lang.bind(this, this._onSmartcardStatusChanged));
580c05
         this._userVerifier.connect('ovirt-user-authenticated', Lang.bind(this, this._onOVirtUserAuthenticated));
580c05
         this.smartcardDetected = this._userVerifier.smartcardDetected;
580c05
 
580c05
         this.connect('next', Lang.bind(this, function() {
580c05
                          this.updateSensitivity(false);
580c05
                          if (this._queryingService) {
580c05
                              this.startSpinning();
580c05
                              this._userVerifier.answerQuery(this._queryingService, this._entry.text);
580c05
                          } else {
580c05
                              this._preemptiveAnswer = this._entry.text;
580c05
+
580c05
+                             if (this._preemptiveAnswerWatchId) {
580c05
+                                 this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
580c05
+                                 this._preemptiveAnswerWatchId = 0;
580c05
+                             }
580c05
                          }
580c05
                      }));
580c05
 
580c05
         this.actor = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
580c05
                                         vertical: true });
580c05
         this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
580c05
         this.actor.connect('key-press-event',
580c05
                            Lang.bind(this, function(actor, event) {
580c05
                                if (event.get_key_symbol() == Clutter.KEY_Escape) {
580c05
                                    this.cancel();
580c05
                                }
580c05
                                return Clutter.EVENT_PROPAGATE;
580c05
                            }));
580c05
 
580c05
         this._userWell = new St.Bin({ x_fill: true,
580c05
                                       x_align: St.Align.START });
580c05
         this.actor.add(this._userWell,
580c05
                        { x_align: St.Align.START,
580c05
                          x_fill: true,
580c05
                          y_fill: true,
580c05
                          expand: true });
580c05
         this._label = new St.Label({ style_class: 'login-dialog-prompt-label' });
580c05
 
580c05
         this.actor.add(this._label,
580c05
                        { expand: true,
580c05
                          x_fill: false,
580c05
                          y_fill: true,
580c05
                          x_align: St.Align.START });
580c05
         this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
580c05
                                      can_focus: true });
580c05
@@ -107,60 +115,65 @@ const AuthPrompt = new Lang.Class({
580c05
                          y_fill: false,
580c05
                          x_align: St.Align.START });
580c05
 
580c05
         this._entry.grab_key_focus();
580c05
 
580c05
         this._message = new St.Label({ opacity: 0,
580c05
                                        styleClass: 'login-dialog-message' });
580c05
         this._message.clutter_text.line_wrap = true;
580c05
         this.actor.add(this._message, { x_fill: false, x_align: St.Align.START, y_align: St.Align.START });
580c05
 
580c05
         this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box',
580c05
                                              vertical: false });
580c05
         this.actor.add(this._buttonBox,
580c05
                        { expand:  true,
580c05
                          x_align: St.Align.MIDDLE,
580c05
                          y_align: St.Align.END });
580c05
 
580c05
         this._defaultButtonWell = new St.Widget({ layout_manager: new Clutter.BinLayout() });
580c05
         this._defaultButtonWellActor = null;
580c05
 
580c05
         this._initButtons();
580c05
 
580c05
         let spinnerIcon = global.datadir + '/theme/process-working.svg';
580c05
         this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE);
580c05
         this._spinner.actor.opacity = 0;
580c05
         this._spinner.actor.show();
580c05
         this._defaultButtonWell.add_child(this._spinner.actor);
580c05
     },
580c05
 
580c05
     _onDestroy: function() {
580c05
+        if (this._preemptiveAnswerWatchId) {
580c05
+            this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
580c05
+            this._preemptiveAnswerWatchId = 0;
580c05
+        }
580c05
+
580c05
         this._userVerifier.destroy();
580c05
         this._userVerifier = null;
580c05
     },
580c05
 
580c05
     _initButtons: function() {
580c05
         this.cancelButton = new St.Button({ style_class: 'modal-dialog-button',
580c05
                                             button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
580c05
                                             reactive: true,
580c05
                                             can_focus: true,
580c05
                                             label: _("Cancel") });
580c05
         this.cancelButton.connect('clicked',
580c05
                                    Lang.bind(this, function() {
580c05
                                        this.cancel();
580c05
                                    }));
580c05
         this._buttonBox.add(this.cancelButton,
580c05
                             { expand: false,
580c05
                               x_fill: false,
580c05
                               y_fill: false,
580c05
                               x_align: St.Align.START,
580c05
                               y_align: St.Align.END });
580c05
 
580c05
         this._buttonBox.add(this._defaultButtonWell,
580c05
                             { expand: true,
580c05
                               x_fill: false,
580c05
                               y_fill: false,
580c05
                               x_align: St.Align.END,
580c05
                               y_align: St.Align.MIDDLE });
580c05
         this.nextButton = new St.Button({ style_class: 'modal-dialog-button',
580c05
                                           button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
580c05
                                           reactive: true,
580c05
@@ -316,60 +329,65 @@ const AuthPrompt = new Lang.Class({
580c05
             else
580c05
                 Tweener.addTween(actor,
580c05
                                  { opacity: 255,
580c05
                                    time: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
580c05
                                    delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
580c05
                                    transition: 'linear' });
580c05
         }
580c05
 
580c05
         this._defaultButtonWellActor = actor;
580c05
     },
580c05
 
580c05
     startSpinning: function() {
580c05
         this.setActorInDefaultButtonWell(this._spinner.actor, true);
580c05
     },
580c05
 
580c05
     stopSpinning: function() {
580c05
         this.setActorInDefaultButtonWell(null, false);
580c05
     },
580c05
 
580c05
     clear: function() {
580c05
         this._entry.text = '';
580c05
         this.stopSpinning();
580c05
     },
580c05
 
580c05
     setPasswordChar: function(passwordChar) {
580c05
         this._entry.clutter_text.set_password_char(passwordChar);
580c05
         this._entry.menu.isPassword = passwordChar != '';
580c05
     },
580c05
 
580c05
     setQuestion: function(question) {
580c05
+        if (this._preemptiveAnswerWatchId) {
580c05
+            this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
580c05
+            this._preemptiveAnswerWatchId = 0;
580c05
+        }
580c05
+
580c05
         this._label.set_text(question);
580c05
 
580c05
         this._label.show();
580c05
         this._entry.show();
580c05
 
580c05
         this._entry.grab_key_focus();
580c05
     },
580c05
 
580c05
     getAnswer: function() {
580c05
         let text;
580c05
 
580c05
         if (this._preemptiveAnswer) {
580c05
             text = this._preemptiveAnswer;
580c05
             this._preemptiveAnswer = null;
580c05
         } else {
580c05
             text = this._entry.get_text();
580c05
         }
580c05
 
580c05
         return text;
580c05
     },
580c05
 
580c05
     _fadeOutMessage: function() {
580c05
         if (this._message.opacity == 0)
580c05
             return;
580c05
         Tweener.removeTweens(this._message);
580c05
         Tweener.addTween(this._message,
580c05
                          { opacity: 0,
580c05
                            time: MESSAGE_FADE_OUT_ANIMATION_TIME,
580c05
                            transition: 'easeOutQuad'
580c05
                          });
580c05
@@ -401,66 +419,86 @@ const AuthPrompt = new Lang.Class({
580c05
     },
580c05
 
580c05
     updateSensitivity: function(sensitive) {
580c05
         this._updateNextButtonSensitivity(sensitive && this._entry.text.length > 0);
580c05
         this._entry.reactive = sensitive;
580c05
         this._entry.clutter_text.editable = sensitive;
580c05
     },
580c05
 
580c05
     hide: function() {
580c05
         this.setActorInDefaultButtonWell(null, true);
580c05
         this.actor.hide();
580c05
         this._message.opacity = 0;
580c05
 
580c05
         this.setUser(null);
580c05
 
580c05
         this.updateSensitivity(true);
580c05
         this._entry.set_text('');
580c05
     },
580c05
 
580c05
     setUser: function(user) {
580c05
         let oldChild = this._userWell.get_child();
580c05
         if (oldChild)
580c05
             oldChild.destroy();
580c05
 
580c05
         if (user) {
580c05
             let userWidget = new UserWidget.UserWidget(user);
580c05
             this._userWell.set_child(userWidget.actor);
580c05
         }
580c05
     },
580c05
 
580c05
+    _onUserStoppedTypePreemptiveAnswer: function() {
580c05
+        if (!this._preemptiveAnswerWatchId ||
580c05
+            this._preemptiveAnswer ||
580c05
+            this._queryingService)
580c05
+            return;
580c05
+
580c05
+        this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
580c05
+        this._preemptiveAnswerWatchId = 0;
580c05
+
580c05
+        this._entry.text = '';
580c05
+        this.updateSensitivity(false);
580c05
+    },
580c05
+
580c05
     reset: function() {
580c05
         let oldStatus = this.verificationStatus;
580c05
         this.verificationStatus = AuthPromptStatus.NOT_VERIFYING;
580c05
         this.cancelButton.reactive = true;
580c05
         this.nextButton.label = _("Next");
580c05
 
580c05
+        if (this._preemptiveAnswerWatchId) {
580c05
+            this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
580c05
+        }
580c05
+        this._preemptiveAnswerWatchId = this._idleMonitor.add_idle_watch (500,
580c05
+                                                                          Lang.bind(this,
580c05
+                                                                                    this._onUserStoppedTypePreemptiveAnswer));
580c05
+
580c05
         if (this._userVerifier)
580c05
             this._userVerifier.cancel();
580c05
 
580c05
         this._queryingService = null;
580c05
         this.clear();
580c05
         this._message.opacity = 0;
580c05
         this.setUser(null);
580c05
         this.stopSpinning();
580c05
 
580c05
         if (oldStatus == AuthPromptStatus.VERIFICATION_FAILED)
580c05
             this.emit('failed');
580c05
 
580c05
         let beginRequestType;
580c05
 
580c05
         if (this._mode == AuthPromptMode.UNLOCK_ONLY) {
580c05
             // The user is constant at the unlock screen, so it will immediately
580c05
             // respond to the request with the username
580c05
             beginRequestType = BeginRequestType.PROVIDE_USERNAME;
580c05
         } else if (this._userVerifier.serviceIsForeground(GdmUtil.OVIRT_SERVICE_NAME) ||
580c05
                    this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME)) {
580c05
             // We don't need to know the username if the user preempted the login screen
580c05
             // with a smartcard or with preauthenticated oVirt credentials
580c05
             beginRequestType = BeginRequestType.DONT_PROVIDE_USERNAME;
580c05
         } else {
580c05
             // In all other cases, we should get the username up front.
580c05
             beginRequestType = BeginRequestType.PROVIDE_USERNAME;
580c05
         }
580c05
 
580c05
         this.emit('reset', beginRequestType);
580c05
     },
580c05
-- 
580c05
2.5.0
580c05