From 10a47a23aab29d805a4e87ef181d4141d5500707 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Tue, 19 Apr 2016 13:12:46 -0400
Subject: [PATCH] loginDialog: allow timed login with disabled user list

At the moment the timed login feature is implemented in the user list.
If there's no user list, we don't show the indicator anywhere and
don't proceed with timed login.

This commit allows timed login to work when the user list is disabled.
It accomplishes this by putting the timed login indicator on the
auth prompt, in that scenario.
---
 data/theme/gnome-shell-sass/_common.scss |  4 +++
 js/gdm/authPrompt.js                     | 40 ++++++++++++++++++++++++
 js/gdm/loginDialog.js                    | 28 +++++++++++++++--
 3 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/data/theme/gnome-shell-sass/_common.scss b/data/theme/gnome-shell-sass/_common.scss
index 2f05098df..4e82ef58b 100644
--- a/data/theme/gnome-shell-sass/_common.scss
+++ b/data/theme/gnome-shell-sass/_common.scss
@@ -1825,6 +1825,10 @@ StScrollBar {
       padding-bottom: 12px;
       spacing: 8px;
       width: 23em;
+      .login-dialog-timed-login-indicator {
+          height: 2px;
+          background-color: darken($fg_color,40%);
+      }
   }
 
   .login-dialog-prompt-label {
diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js
index 89cef4d5d..e44281117 100644
--- a/js/gdm/authPrompt.js
+++ b/js/gdm/authPrompt.js
@@ -2,6 +2,7 @@
 
 const Clutter = imports.gi.Clutter;
 const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
 const Lang = imports.lang;
 const Pango = imports.gi.Pango;
 const Signals = imports.signals;
@@ -117,6 +118,11 @@ var AuthPrompt = new Lang.Class({
 
         this._entry.grab_key_focus();
 
+        this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
+                                                 scale_x: 0 });
+
+        this.actor.add(this._timedLoginIndicator);
+
         this._message = new St.Label({ opacity: 0,
                                        styleClass: 'login-dialog-message' });
         this._message.clutter_text.line_wrap = true;
@@ -142,6 +148,40 @@ var AuthPrompt = new Lang.Class({
         this._defaultButtonWell.add_child(this._spinner.actor);
     },
 
+    showTimedLoginIndicator(time) {
+        let hold = new Batch.Hold();
+
+        this.hideTimedLoginIndicator();
+
+        let startTime = GLib.get_monotonic_time();
+
+        this._timedLoginTimeoutId = GLib.timeout_add (GLib.PRIORITY_DEFAULT, 33,
+            () => {
+                let currentTime = GLib.get_monotonic_time();
+                let elapsedTime = (currentTime - startTime) / GLib.USEC_PER_SEC;
+                this._timedLoginIndicator.scale_x = elapsedTime / time;
+                if (elapsedTime >= time) {
+                    this._timedLoginTimeoutId = 0;
+                    hold.release();
+                    return GLib.SOURCE_REMOVE;
+                }
+
+                return GLib.SOURCE_CONTINUE;
+            });
+
+        GLib.Source.set_name_by_id(this._timedLoginTimeoutId, '[gnome-shell] this._timedLoginTimeoutId');
+
+        return hold;
+    },
+
+    hideTimedLoginIndicator() {
+        if (this._timedLoginTimeoutId) {
+            GLib.source_remove(this._timedLoginTimeoutId);
+            this._timedLoginTimeoutId = 0;
+        }
+        this._timedLoginIndicator.scale_x = 0.;
+    },
+
     _onDestroy() {
         if (this._preemptiveAnswerWatchId) {
             this._idleMonitor.remove_watch(this._preemptiveAnswerWatchId);
diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js
index 4a93545af..65d9edf1a 100644
--- a/js/gdm/loginDialog.js
+++ b/js/gdm/loginDialog.js
@@ -738,6 +738,9 @@ var LoginDialog = new Lang.Class({
 
             if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
                 this._authPrompt.reset();
+
+            if (this._disableUserList && this._timedLoginUserListHold)
+                this._timedLoginUserListHold.release();
         }
     },
 
@@ -1019,17 +1022,33 @@ var LoginDialog = new Lang.Class({
     },
 
     _startTimedLogin(userName, delay) {
+        this._timedLoginUserName = userName;
         this._timedLoginItem = null;
         this._timedLoginDelay = delay;
         this._timedLoginAnimationTime = delay;
 
-        let tasks = [() => this._waitForItemForUser(userName),
+        let tasks = [() => {
+                         if (this._disableUserList)
+                             return;
+
+                         this._timedLoginUserListHold = this._waitForItemForUser(userName);
+
+                         return this._timedLoginUserListHold;
+                     },
 
                      () => {
+                         this._timedLoginUserListHold = null;
+
+                         if (this._disableUserList)
+                             return;
+
                          this._timedLoginItem = this._userList.getItemFromUserName(userName);
                      },
 
                      () => {
+                         if (this._disableUserList)
+                             return;
+
                          // If we're just starting out, start on the right
                          // item.
                          if (!this._userManager.is_loaded) {
@@ -1040,6 +1059,9 @@ var LoginDialog = new Lang.Class({
                      this._blockTimedLoginUntilIdle,
 
                      () => {
+                         if (this._disableUserList)
+                             return;
+
                          this._userList.scrollToItem(this._timedLoginItem);
                      },
 
@@ -1064,7 +1086,9 @@ var LoginDialog = new Lang.Class({
         if (this._timedLoginItem)
             this._timedLoginItem.hideTimedLoginIndicator();
 
-        let userName = this._timedLoginItem.user.get_user_name();
+        this._authPrompt.hideTimedLoginIndicator();
+
+        let userName = this._timedLoginUserName;
 
         if (userName)
             this._startTimedLogin(userName, this._timedLoginDelay);
-- 
2.17.1

