diff --git a/SOURCES/0001-keyring-Don-t-unregister-the-prompt-when-disabled.patch b/SOURCES/0001-keyring-Don-t-unregister-the-prompt-when-disabled.patch new file mode 100644 index 0000000..5f8c49f --- /dev/null +++ b/SOURCES/0001-keyring-Don-t-unregister-the-prompt-when-disabled.patch @@ -0,0 +1,83 @@ +From 17c5b2b32b99185beb7565856d0bc247b7ba9ed4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 18 Sep 2013 17:53:26 +0200 +Subject: [PATCH 1/2] keyring: Don't unregister the prompt when disabled + +gnome-keyring provides a fallback in case our builtin prompt fails +to register, so keyring dialogs may still pop up even when they +are supposed to be disabled. +Instead, keep the prompt registered but cancel requests immediately +while disabled. + +https://bugzilla.gnome.org/show_bug.cgi?id=708187 +--- + js/ui/components/keyring.js | 41 ++++++++++++++++++++++++++++++++--------- + 1 file changed, 32 insertions(+), 9 deletions(-) + +diff --git a/js/ui/components/keyring.js b/js/ui/components/keyring.js +index 299ecc6..6de3965 100644 +--- a/js/ui/components/keyring.js ++++ b/js/ui/components/keyring.js +@@ -221,27 +221,50 @@ const KeyringDialog = new Lang.Class({ + }, + }); + ++const KeyringDummyDialog = new Lang.Class({ ++ Name: 'KeyringDummyDialog', ++ ++ _init: function() { ++ this.prompt = new Shell.KeyringPrompt(); ++ this.prompt.connect('show-password', ++ Lang.bind(this, this._cancelPrompt)); ++ this.prompt.connect('show-confirm', Lang.bind(this, ++ this._cancelPrompt)); ++ }, ++ ++ _cancelPrompt: function() { ++ this.prompt.cancel(); ++ } ++}); ++ + const KeyringPrompter = new Lang.Class({ + Name: 'KeyringPrompter', + + _init: function() { + this._prompter = new Gcr.SystemPrompter(); +- this._prompter.connect('new-prompt', function(prompter) { +- let dialog = new KeyringDialog(); +- return dialog.prompt; +- }); ++ this._prompter.connect('new-prompt', Lang.bind(this, ++ function() { ++ let dialog = this._enabled ? new KeyringDialog() ++ : new KeyringDummyDialog(); ++ return dialog.prompt; ++ })); + this._dbusId = null; ++ this._registered = false; ++ this._enabled = false; + }, + + enable: function() { +- this._prompter.register(Gio.DBus.session); +- this._dbusId = Gio.DBus.session.own_name('org.gnome.keyring.SystemPrompter', +- Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT, null, null); ++ if (!this._registered) { ++ this._prompter.register(Gio.DBus.session); ++ this._dbusId = Gio.DBus.session.own_name('org.gnome.keyring.SystemPrompter', ++ Gio.BusNameOwnerFlags.ALLOW_REPLACEMENT, null, null); ++ this._registered = true; ++ } ++ this._enabled = true; + }, + + disable: function() { +- this._prompter.unregister(false); +- Gio.DBus.session.unown_name(this._dbusId); ++ this._enabled = false; + } + }); + +-- +1.8.4.2 + diff --git a/SOURCES/0001-main-Close-runDialog-as-necessary-on-session-mode-ch.patch b/SOURCES/0001-main-Close-runDialog-as-necessary-on-session-mode-ch.patch new file mode 100644 index 0000000..6795de6 --- /dev/null +++ b/SOURCES/0001-main-Close-runDialog-as-necessary-on-session-mode-ch.patch @@ -0,0 +1,36 @@ +From d1eb56f4ad154f8bada35b5b9d13fbdb325be1a6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 18 Sep 2013 19:47:59 +0200 +Subject: [PATCH] main: Close runDialog as necessary on session mode changes + +We already do this for looking glass, but it makes even less sense +for the normal run dialog - if a mode sets runDialog to false, the +intention is to not allow executing aribitrary commands. + +https://bugzilla.gnome.org/show_bug.cgi?id=708218 +--- + js/ui/main.js | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/js/ui/main.js b/js/ui/main.js +index bd5dc47..ff8cd2c 100644 +--- a/js/ui/main.js ++++ b/js/ui/main.js +@@ -84,8 +84,12 @@ function _sessionUpdated() { + Shell.KeyBindingMode.OVERVIEW, + sessionMode.hasRunDialog ? openRunDialog : null); + +- if (!sessionMode.hasRunDialog && lookingGlass) +- lookingGlass.close(); ++ if (!sessionMode.hasRunDialog) { ++ if (runDialog) ++ runDialog.close(); ++ if (lookingGlass) ++ lookingGlass.close(); ++ } + } + + function start() { +-- +1.8.4.2 + diff --git a/SOURCES/0001-main-allow-session-mode-to-be-specified-in-the-envir.patch b/SOURCES/0001-main-allow-session-mode-to-be-specified-in-the-envir.patch new file mode 100644 index 0000000..ca8a982 --- /dev/null +++ b/SOURCES/0001-main-allow-session-mode-to-be-specified-in-the-envir.patch @@ -0,0 +1,88 @@ +From 55fa78bacbb4537cdc2fb090cb2f607476cae780 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Tue, 7 Jan 2014 13:14:31 -0500 +Subject: [PATCH] main: allow session mode to be specified in the environment + +Specifying the session mode on the command-line doesn't play +well with session management (since the saved session desktop +file well either drop the specified session mode, or force it +always, even if the user picked a different mode at the login +screen) + +This commit adds support for specifying the session mode via an +enviroment variable. For now, keep the old command line interface +for backward compatibility +--- + src/main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/main.c b/src/main.c +index 9f7f890..1c42667 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -334,60 +334,62 @@ GOptionEntry gnome_shell_options[] = { + N_("Mode used by GDM for login screen"), + NULL + }, + { + "mode", 0, 0, G_OPTION_ARG_STRING, + &session_mode, + N_("Use a specific mode, e.g. \"gdm\" for login screen"), + "MODE" + }, + { + "list-modes", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, + list_modes, + N_("List possible modes"), + NULL + }, + { NULL } + }; + + int + main (int argc, char **argv) + { + GOptionContext *ctx; + GError *error = NULL; + int ecode; + TpDebugSender *sender; + + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + ++ session_mode = (char *) g_getenv ("GNOME_SHELL_SESSION_MODE"); ++ + ctx = meta_get_option_context (); + g_option_context_add_main_entries (ctx, gnome_shell_options, GETTEXT_PACKAGE); + if (!g_option_context_parse (ctx, &argc, &argv, &error)) + { + g_printerr ("%s: %s\n", argv[0], error->message); + exit (1); + } + + g_option_context_free (ctx); + + meta_plugin_manager_set_plugin_type (gnome_shell_plugin_get_type ()); + + meta_set_wm_name (WM_NAME); + meta_set_gnome_wm_keybindings (GNOME_WM_KEYBINDINGS); + + /* Prevent meta_init() from causing gtk to load gail and at-bridge */ + g_setenv ("NO_AT_BRIDGE", "1", TRUE); + meta_init (); + g_unsetenv ("NO_AT_BRIDGE"); + + /* FIXME: Add gjs API to set this stuff and don't depend on the + * environment. These propagate to child processes. + */ + g_setenv ("GJS_DEBUG_OUTPUT", "stderr", TRUE); + g_setenv ("GJS_DEBUG_TOPICS", "JS ERROR;JS LOG", TRUE); + + shell_dbus_init (meta_get_replace_current_wm ()); + shell_a11y_init (); + shell_perf_log_init (); + shell_introspection_init (); +-- +1.8.3.1 + diff --git a/SOURCES/0001-panel-add-an-icon-to-the-ActivitiesButton.patch b/SOURCES/0001-panel-add-an-icon-to-the-ActivitiesButton.patch new file mode 100644 index 0000000..d741b9a --- /dev/null +++ b/SOURCES/0001-panel-add-an-icon-to-the-ActivitiesButton.patch @@ -0,0 +1,161 @@ +From cfff54659c516eef0813e3940606642a64b698d0 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 15 Jan 2014 16:45:34 -0500 +Subject: [PATCH] panel: add an icon to the ActivitiesButton + +Requested by brand +--- + data/theme/gnome-shell.css | 5 +++++ + js/ui/panel.js | 9 ++++++++- + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css +index 3727197..4191817 100644 +--- a/data/theme/gnome-shell.css ++++ b/data/theme/gnome-shell.css +@@ -567,60 +567,65 @@ StScrollBar StButton#vhandle:active { + #panel.login-screen .panel-button:focus { + color: white; + } + + .panel-button:hover { + color: white; + text-shadow: black 0px 2px 2px; + } + + .panel-button:active, + .panel-button:overview, + .panel-button:focus { + border-image: url("panel-button-border.svg") 6 10 0 2; + background-image: url("panel-button-highlight-wide.svg"); + color: white; + text-shadow: black 0px 2px 2px; + } + + .panel-status-button:active, + .panel-status-button:checked, + .panel-status-button:focus { + background-image: url("panel-button-highlight-narrow.svg"); + } + + .panel-button:active > .system-status-icon, + .panel-button:checked > .system-status-icon, + .panel-button:focus > .system-status-icon { + icon-shadow: black 0px 2px 2px; + } + ++.panel-logo-icon { ++ padding-right: .4em; ++ icon-size: 1em; ++} ++ + .panel-menu { + -boxpointer-gap: 4px; + } + + .panel-status-button-box { + spacing: 4px; + } + + .lock-screen-status-button-box { + spacing: 8px; + } + + /* User Menu */ + + #panelUserMenu { + spacing: 4px; + } + + .status-chooser { + spacing: .4em; + } + + .status-chooser .popup-menu-item, + .status-chooser-combo .popup-menu-item { + padding: .4em; + } + + .status-chooser-user-icon { + border: 2px solid #8b8b8b; + border-radius: 5px; +diff --git a/js/ui/panel.js b/js/ui/panel.js +index a6f73a5..afea8c8 100644 +--- a/js/ui/panel.js ++++ b/js/ui/panel.js +@@ -655,64 +655,71 @@ const AppMenuButton = new Lang.Class({ + } + if (this._overviewHidingId > 0) { + Main.overview.disconnect(this._overviewHidingId); + this._overviewHidingId = 0; + } + if (this._overviewShowingId > 0) { + Main.overview.disconnect(this._overviewShowingId); + this._overviewShowingId = 0; + } + if (this._switchWorkspaceNotifyId > 0) { + global.window_manager.disconnect(this._switchWorkspaceNotifyId); + this._switchWorkspaceNotifyId = 0; + } + + this.parent(); + } + }); + + Signals.addSignalMethods(AppMenuButton.prototype); + + const ActivitiesButton = new Lang.Class({ + Name: 'ActivitiesButton', + Extends: PanelMenu.Button, + + _init: function() { + this.parent(0.0, null, true); + this.actor.accessible_role = Atk.Role.TOGGLE_BUTTON; + + this.actor.name = 'panelActivities'; + ++ let box = new St.BoxLayout(); ++ this.actor.add_actor(box); ++ let iconFile = Gio.File.new_for_path('/usr/share/icons/hicolor/scalable/apps/start-here.svg'); ++ this._icon = new St.Icon({ gicon: new Gio.FileIcon({ file: iconFile }), ++ style_class: 'panel-logo-icon' }); ++ box.add_actor(this._icon); ++ + /* Translators: If there is no suitable word for "Activities" + in your language, you can use the word for "Overview". */ + this._label = new St.Label({ text: _("Activities") }); +- this.actor.add_actor(this._label); ++ box.add_actor(this._label); + + this.actor.label_actor = this._label; + + this.actor.connect('captured-event', Lang.bind(this, this._onCapturedEvent)); + this.actor.connect_after('button-release-event', Lang.bind(this, this._onButtonRelease)); + this.actor.connect_after('key-release-event', Lang.bind(this, this._onKeyRelease)); + + Main.overview.connect('showing', Lang.bind(this, function() { + this.actor.add_style_pseudo_class('overview'); + this.actor.add_accessible_state (Atk.StateType.CHECKED); + })); + Main.overview.connect('hiding', Lang.bind(this, function() { + this.actor.remove_style_pseudo_class('overview'); + this.actor.remove_accessible_state (Atk.StateType.CHECKED); + })); + + this._xdndTimeOut = 0; + }, + + handleDragOver: function(source, actor, x, y, time) { + if (source != Main.xdndHandler) + return DND.DragMotionResult.CONTINUE; + + if (this._xdndTimeOut != 0) + Mainloop.source_remove(this._xdndTimeOut); + this._xdndTimeOut = Mainloop.timeout_add(BUTTON_DND_ACTIVATION_TIMEOUT, + Lang.bind(this, this._xdndToggleOverview, actor)); + + return DND.DragMotionResult.CONTINUE; + }, +-- +1.8.3.1 + diff --git a/SOURCES/0002-keyring-Cancel-active-prompts-on-disable.patch b/SOURCES/0002-keyring-Cancel-active-prompts-on-disable.patch new file mode 100644 index 0000000..a741ad1 --- /dev/null +++ b/SOURCES/0002-keyring-Cancel-active-prompts-on-disable.patch @@ -0,0 +1,50 @@ +From ba64565bf9be6d827fbbf4dd4de1998b770956ed Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Fri, 27 Sep 2013 16:04:25 +0200 +Subject: [PATCH 2/2] keyring: Cancel active prompts on disable() + +Since commit 1242a16265d5bf2, we will use a fake prompt which +cancels alls requests without dialog when the keyring component +is disabled. However this does only apply to new requests, dialogs +that are already active when the session mode changes are kept +open. This is not quite as expected, so cancel the prompt in that +case. + +https://bugzilla.gnome.org/show_bug.cgi?id=708910 +--- + js/ui/components/keyring.js | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/js/ui/components/keyring.js b/js/ui/components/keyring.js +index 6de3965..5f7813b 100644 +--- a/js/ui/components/keyring.js ++++ b/js/ui/components/keyring.js +@@ -246,11 +246,13 @@ const KeyringPrompter = new Lang.Class({ + function() { + let dialog = this._enabled ? new KeyringDialog() + : new KeyringDummyDialog(); +- return dialog.prompt; ++ this._currentPrompt = dialog.prompt; ++ return this._currentPrompt; + })); + this._dbusId = null; + this._registered = false; + this._enabled = false; ++ this._currentPrompt = null; + }, + + enable: function() { +@@ -265,6 +267,10 @@ const KeyringPrompter = new Lang.Class({ + + disable: function() { + this._enabled = false; ++ ++ if (this._prompter.prompting) ++ this._currentPrompt.cancel(); ++ this._currentPrompt = null; + } + }); + +-- +1.8.4.2 + diff --git a/SOURCES/dont-load-user-list-when-disabled.patch b/SOURCES/dont-load-user-list-when-disabled.patch new file mode 100644 index 0000000..260b9ac --- /dev/null +++ b/SOURCES/dont-load-user-list-when-disabled.patch @@ -0,0 +1,130 @@ +From c23b174119abf62fec5c05b461cc3c5a7ec4bc08 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Fri, 7 Mar 2014 16:16:20 +0100 +Subject: [PATCH 1/2] loginDialog: Add missing return value + +_loadUserList() may be used as idle handler, so we should explicitly +return a boolean. + +https://bugzilla.gnome.org/show_bug.cgi?id=725905 +--- + js/gdm/loginDialog.js | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js +index ee0199c..98dd7b2 100644 +--- a/js/gdm/loginDialog.js ++++ b/js/gdm/loginDialog.js +@@ -940,6 +940,8 @@ const LoginDialog = new Lang.Class({ + Lang.bind(this, function(userManager, user) { + this._userList.removeUser(user); + })); ++ ++ return false; + }, + + open: function() { +-- +1.9.0 + + +From 5517e6bdbbc42347e03068d823dd215e9c86eb4d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Sat, 8 Mar 2014 00:05:24 +0100 +Subject: [PATCH 2/2] loginDialog: Defer loading user list until needed + +Loading the user list can be expensive, for instance when there is +a large number of users and/or their avatars have to be fetched over +the network. In case the user list is disabled anyway, there is no +point in doing that work just to hide it, so stop doing that. + +https://bugzilla.gnome.org/show_bug.cgi?id=725905 +--- + js/gdm/loginDialog.js | 44 +++++++++++++++++++++++++++++--------------- + 1 file changed, 29 insertions(+), 15 deletions(-) + +diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js +index 98dd7b2..b4487e6 100644 +--- a/js/gdm/loginDialog.js ++++ b/js/gdm/loginDialog.js +@@ -520,18 +520,6 @@ const LoginDialog = new Lang.Class({ + this.actor.set_child_above_sibling(this._userSelectionBox, null); + this.actor.set_child_above_sibling(this._authPrompt.actor, null); + +- if (!this._userManager.is_loaded) +- this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', +- Lang.bind(this, function() { +- if (this._userManager.is_loaded) { +- this._loadUserList(); +- this._userManager.disconnect(this._userManagerLoadedId); +- this._userManagerLoadedId = 0; +- } +- })); +- else +- GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList)); +- + this._userList.connect('activate', + Lang.bind(this, function(userList, item) { + this._onUserListActivated(item); +@@ -547,7 +535,29 @@ const LoginDialog = new Lang.Class({ + this._sessionMenuButton.actor.show(); + this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor); + +- }, ++ this._disableUserList = undefined; ++ this._userListLoaded = false; ++ ++ // If the user list is enabled, it should take key focus; make sure the ++ // screen shield is initialized first to prevent it from stealing the ++ // focus later ++ Main.layoutManager.connect('startup-complete', ++ Lang.bind(this, this._updateDisableUserList)); ++ }, ++ ++ _ensureUserListLoaded: function() { ++ if (!this._userManager.is_loaded) ++ this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', ++ Lang.bind(this, function() { ++ if (this._userManager.is_loaded) { ++ this._loadUserList(); ++ this._userManager.disconnect(this._userManagerLoadedId); ++ this._userManagerLoadedId = 0; ++ } ++ })); ++ else ++ GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList)); ++ }, + + _updateDisableUserList: function() { + let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); +@@ -880,6 +890,7 @@ const LoginDialog = new Lang.Class({ + }, + + _showUserList: function() { ++ this._ensureUserListLoaded(); + this._authPrompt.hide(); + this._sessionMenuButton.close(); + this._setUserListExpanded(true); +@@ -923,14 +934,17 @@ const LoginDialog = new Lang.Class({ + }, + + _loadUserList: function() { ++ if (this._userListLoaded) ++ return false; ++ ++ this._userListLoaded = true; ++ + let users = this._userManager.list_users(); + + for (let i = 0; i < users.length; i++) { + this._userList.addUser(users[i]); + } + +- this._updateDisableUserList(); +- + this._userManager.connect('user-added', + Lang.bind(this, function(userManager, user) { + this._userList.addUser(user); +-- +1.9.0 + diff --git a/SOURCES/fix-background-leaks.patch b/SOURCES/fix-background-leaks.patch new file mode 100644 index 0000000..640be41 --- /dev/null +++ b/SOURCES/fix-background-leaks.patch @@ -0,0 +1,777 @@ +From cdee11381cfb10a93fb41d014b989a4968068b0c Mon Sep 17 00:00:00 2001 +From: Adel Gadllah +Date: Thu, 15 Aug 2013 21:51:46 +0200 +Subject: [PATCH 01/13] Revert "background: fix asynchronous management of + background loading operations" + +This reverts commit 1020d8a0f8523a04d8336b1348388b8b242e414f. + +https://bugzilla.gnome.org/show_bug.cgi?id=704646 +--- + js/ui/background.js | 69 +++++++++++++++++++---------------------------------- + 1 file changed, 25 insertions(+), 44 deletions(-) + +diff --git a/js/ui/background.js b/js/ui/background.js +index 13343c6..1d9ab7c 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -142,40 +142,33 @@ const BackgroundCache = new Lang.Class({ + cancellable: null, + onFinished: null }); + +- let fileLoad = { filename: params.filename, +- style: params.style, +- shouldCopy: false, +- monitorIndex: params.monitorIndex, +- effects: params.effects, +- onFinished: params.onFinished, +- cancellable: new Gio.Cancellable(), }; +- this._pendingFileLoads.push(fileLoad); +- +- if (params.cancellable) { +- params.cancellable.connect(Lang.bind(this, function(c) { +- fileLoad.cancellable.cancel(); +- })); ++ for (let i = 0; i < this._pendingFileLoads.length; i++) { ++ if (this._pendingFileLoads[i].filename == params.filename && ++ this._pendingFileLoads[i].style == params.style) { ++ this._pendingFileLoads[i].callers.push({ shouldCopy: true, ++ monitorIndex: params.monitorIndex, ++ effects: params.effects, ++ onFinished: params.onFinished }); ++ return; ++ } + } + ++ this._pendingFileLoads.push({ filename: params.filename, ++ style: params.style, ++ callers: [{ shouldCopy: false, ++ monitorIndex: params.monitorIndex, ++ effects: params.effects, ++ onFinished: params.onFinished }] }); ++ + let content = new Meta.Background({ meta_screen: global.screen, + monitor: params.monitorIndex, + effects: params.effects }); + + content.load_file_async(params.filename, + params.style, +- fileLoad.cancellable, ++ params.cancellable, + Lang.bind(this, + function(object, result) { +- if (fileLoad.cancellable.is_cancelled()) { +- if (params.cancellable && params.cancellable.is_cancelled()) { +- if (params.onFinished) +- params.onFinished(null); +- this._removePendingFileLoad(fileLoad); +- return; +- } +- return; +- } +- + try { + content.load_file_finish(result); + +@@ -185,25 +178,22 @@ const BackgroundCache = new Lang.Class({ + content = null; + } + +- let needsCopy = false; + for (let i = 0; i < this._pendingFileLoads.length; i++) { + let pendingLoad = this._pendingFileLoads[i]; + if (pendingLoad.filename != params.filename || + pendingLoad.style != params.style) + continue; + +- if (pendingLoad.cancellable.is_cancelled()) +- continue; ++ for (let j = 0; j < pendingLoad.callers.length; j++) { ++ if (pendingLoad.callers[j].onFinished) { ++ if (content && pendingLoad.callers[j].shouldCopy) { ++ content = object.copy(pendingLoad.callers[j].monitorIndex, ++ pendingLoad.callers[j].effects); + +- pendingLoad.cancellable.cancel(); +- if (pendingLoad.onFinished) { +- if (content && needsCopy) { +- content = object.copy(pendingLoad.monitorIndex, +- pendingLoad.effects); +- } ++ } + +- needsCopy = true; +- pendingLoad.onFinished(content); ++ pendingLoad.callers[j].onFinished(content); ++ } + } + + this._pendingFileLoads.splice(i, 1); +@@ -211,15 +201,6 @@ const BackgroundCache = new Lang.Class({ + })); + }, + +- _removePendingFileLoad: function(fileLoad) { +- for (let i = 0; i < this._pendingFileLoads.length; i++) { +- if (this._pendingFileLoads[i].cancellable == fileLoad.cancellable) { +- this._pendingFileLoads.splice(i, 1); +- break; +- } +- } +- }, +- + getImageContent: function(params) { + params = Params.parse(params, { monitorIndex: 0, + style: null, +-- +1.9.0 + + +From 980a8618e1b89911c93183c461528bc9c3d465de Mon Sep 17 00:00:00 2001 +From: Adel Gadllah +Date: Wed, 2 Oct 2013 15:29:30 +0200 +Subject: [PATCH 02/13] background: Disconnect settings signal handler on + destroy + +We connect to the changed signal in _init() but never actually disconnect from +it. The callback has a reference to "this" which results into the background +object not getting garbage collected. + +Fix that leaks by disconnecting in _destroy() + +https://bugzilla.gnome.org/show_bug.cgi?id=709263 +--- + js/ui/background.js | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/js/ui/background.js b/js/ui/background.js +index 1d9ab7c..b855b4e 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -318,9 +318,9 @@ const Background = new Lang.Class({ + this._cancellable = new Gio.Cancellable(); + this.isLoaded = false; + +- this._settings.connect('changed', Lang.bind(this, function() { +- this.emit('changed'); +- })); ++ this._settingsChangedSignalId = this._settings.connect('changed', Lang.bind(this, function() { ++ this.emit('changed'); ++ })); + + this._load(); + }, +@@ -361,6 +361,10 @@ const Background = new Lang.Class({ + + this.actor.disconnect(this._destroySignalId); + this._destroySignalId = 0; ++ ++ if (this._settingsChangedSignalId != 0) ++ this._settings.disconnect(this._settingsChangedSignalId); ++ this._settingsChangedSignalId = 0; + }, + + _setLoaded: function() { +-- +1.9.0 + + +From cfe72aa21a0aa8ea96dac81bfd6e532af62e9081 Mon Sep 17 00:00:00 2001 +From: Adel Gadllah +Date: Wed, 2 Oct 2013 15:48:39 +0200 +Subject: [PATCH 03/13] layout: Use monitor index when adding bg managers + +Don't assume that this._bgManagers.push() (i.e adding to the end) is always +correct. + +On startup we call _createPrimaryBackground which passes in the primary index +which may not be 0. +--- + js/ui/layout.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/js/ui/layout.js b/js/ui/layout.js +index e25b3bd..141eecc 100644 +--- a/js/ui/layout.js ++++ b/js/ui/layout.js +@@ -347,7 +347,7 @@ const LayoutManager = new Lang.Class({ + BackgroundMenu.addBackgroundMenu(bgManager.background.actor); + })); + +- this._bgManagers.push(bgManager); ++ this._bgManagers[monitorIndex] = bgManager; + + return bgManager.background; + }, +-- +1.9.0 + + +From 304c11552766963f51343d97f8257096e62abb15 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Fri, 14 Mar 2014 18:09:22 +0100 +Subject: [PATCH 04/13] background: Force a GC run after removing a background + +--- + js/ui/background.js | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/js/ui/background.js b/js/ui/background.js +index b855b4e..0e4ff5d 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -6,8 +6,10 @@ const Gio = imports.gi.Gio; + const GLib = imports.gi.GLib; + const GnomeDesktop = imports.gi.GnomeDesktop; + const Lang = imports.lang; ++const Mainloop = imports.mainloop; + const Meta = imports.gi.Meta; + const Signals = imports.signals; ++const System = imports.system; + + const Main = imports.ui.main; + const Params = imports.misc.params; +@@ -119,6 +121,14 @@ const BackgroundCache = new Lang.Class({ + + if (index >= 0) + contentList.splice(index, 1); ++ ++ if (!this._gcId) ++ this._gcId = Mainloop.idle_add(Lang.bind(this, ++ function() { ++ System.gc(); ++ this._gcId = 0; ++ return false; ++ })); + }, + + removePatternContent: function(content) { +-- +1.9.0 + + +From 1cd71c438f3ee5dc6ccbc68ef646d42128e6883b Mon Sep 17 00:00:00 2001 +From: "Jasper St. Pierre" +Date: Tue, 3 Dec 2013 18:08:42 -0500 +Subject: [PATCH 05/13] background: Clarify the intent of the code + +Stomping on local variables and trying to keep loop state isn't +too fun. Just use a new variable here so we aren't too confused +with what we're doing. + +https://bugzilla.gnome.org/show_bug.cgi?id=719803 +--- + js/ui/background.js | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/js/ui/background.js b/js/ui/background.js +index 0e4ff5d..80a3bba 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -196,13 +196,16 @@ const BackgroundCache = new Lang.Class({ + + for (let j = 0; j < pendingLoad.callers.length; j++) { + if (pendingLoad.callers[j].onFinished) { +- if (content && pendingLoad.callers[j].shouldCopy) { +- content = object.copy(pendingLoad.callers[j].monitorIndex, +- pendingLoad.callers[j].effects); ++ let newContent; + ++ if (content && pendingLoad.callers[j].shouldCopy) { ++ newContent = content.copy(pendingLoad.callers[j].monitorIndex, ++ pendingLoad.callers[j].effects); ++ } else { ++ newContent = content; + } + +- pendingLoad.callers[j].onFinished(content); ++ pendingLoad.callers[j].onFinished(newContent); + } + } + +-- +1.9.0 + + +From f86064aaf8753050582ead02d329aa9c36d0447c Mon Sep 17 00:00:00 2001 +From: "Jasper St. Pierre" +Date: Tue, 3 Dec 2013 18:09:23 -0500 +Subject: [PATCH 06/13] background: Add copied content from pending image loads + to the cache + +https://bugzilla.gnome.org/show_bug.cgi?id=719803 +--- + js/ui/background.js | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/js/ui/background.js b/js/ui/background.js +index 80a3bba..6349148 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -201,6 +201,7 @@ const BackgroundCache = new Lang.Class({ + if (content && pendingLoad.callers[j].shouldCopy) { + newContent = content.copy(pendingLoad.callers[j].monitorIndex, + pendingLoad.callers[j].effects); ++ this._images.push(newContent); + } else { + newContent = content; + } +-- +1.9.0 + + +From 8964898af8dde2e425d5fde711d2e572d87249d3 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 26 Feb 2014 14:35:38 -0500 +Subject: [PATCH 07/13] background: always copy background content when loading + into cache + +Copying is actually a lightweight operation, so trying to avoid it just adds +code complexity for little gain. + +Based on work from Jasper St. Pierre + +https://bugzilla.gnome.org/show_bug.cgi?id=722149 +--- + js/ui/background.js | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +diff --git a/js/ui/background.js b/js/ui/background.js +index 6349148..1e4d2ae 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -155,8 +155,7 @@ const BackgroundCache = new Lang.Class({ + for (let i = 0; i < this._pendingFileLoads.length; i++) { + if (this._pendingFileLoads[i].filename == params.filename && + this._pendingFileLoads[i].style == params.style) { +- this._pendingFileLoads[i].callers.push({ shouldCopy: true, +- monitorIndex: params.monitorIndex, ++ this._pendingFileLoads[i].callers.push({ monitorIndex: params.monitorIndex, + effects: params.effects, + onFinished: params.onFinished }); + return; +@@ -165,14 +164,11 @@ const BackgroundCache = new Lang.Class({ + + this._pendingFileLoads.push({ filename: params.filename, + style: params.style, +- callers: [{ shouldCopy: false, +- monitorIndex: params.monitorIndex, ++ callers: [{ monitorIndex: params.monitorIndex, + effects: params.effects, + onFinished: params.onFinished }] }); + +- let content = new Meta.Background({ meta_screen: global.screen, +- monitor: params.monitorIndex, +- effects: params.effects }); ++ let content = new Meta.Background({ meta_screen: global.screen }); + + content.load_file_async(params.filename, + params.style, +@@ -183,7 +179,6 @@ const BackgroundCache = new Lang.Class({ + content.load_file_finish(result); + + this._monitorFile(params.filename); +- this._images.push(content); + } catch(e) { + content = null; + } +@@ -198,12 +193,10 @@ const BackgroundCache = new Lang.Class({ + if (pendingLoad.callers[j].onFinished) { + let newContent; + +- if (content && pendingLoad.callers[j].shouldCopy) { ++ if (content) { + newContent = content.copy(pendingLoad.callers[j].monitorIndex, + pendingLoad.callers[j].effects); + this._images.push(newContent); +- } else { +- newContent = content; + } + + pendingLoad.callers[j].onFinished(newContent); +-- +1.9.0 + + +From 0975134611b07d35cc9dff9c1451c1dc8a2cbafc Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 26 Feb 2014 15:13:21 -0500 +Subject: [PATCH 08/13] background: refactor file loading + +This commit moves the code around a bit such that the +caller gets allocated up front and then a file load is either +found or created to attach the caller to. + +Functionally, the code is the same, it's just now factored in a way +that will make it easier to fix a bug with cancellation later. + +https://bugzilla.gnome.org/show_bug.cgi?id=722149 +--- + js/ui/background.js | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/js/ui/background.js b/js/ui/background.js +index 1e4d2ae..63b62a0 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -144,6 +144,10 @@ const BackgroundCache = new Lang.Class({ + this._removeContent(this._images, content); + }, + ++ _attachCallerToFileLoad: function(caller, fileLoad) { ++ fileLoad.callers.push(caller); ++ }, ++ + _loadImageContent: function(params) { + params = Params.parse(params, { monitorIndex: 0, + style: null, +@@ -152,21 +156,24 @@ const BackgroundCache = new Lang.Class({ + cancellable: null, + onFinished: null }); + ++ let caller = { monitorIndex: params.monitorIndex, ++ effects: params.effects, ++ onFinished: params.onFinished }; ++ + for (let i = 0; i < this._pendingFileLoads.length; i++) { +- if (this._pendingFileLoads[i].filename == params.filename && +- this._pendingFileLoads[i].style == params.style) { +- this._pendingFileLoads[i].callers.push({ monitorIndex: params.monitorIndex, +- effects: params.effects, +- onFinished: params.onFinished }); ++ let fileLoad = this._pendingFileLoads[i]; ++ ++ if (fileLoad.filename == params.filename && ++ fileLoad.style == params.style) { ++ this._attachCallerToFileLoad(caller, fileLoad); + return; + } + } + +- this._pendingFileLoads.push({ filename: params.filename, +- style: params.style, +- callers: [{ monitorIndex: params.monitorIndex, +- effects: params.effects, +- onFinished: params.onFinished }] }); ++ let fileLoad = { filename: params.filename, ++ style: params.style, ++ callers: [] }; ++ this._attachCallerToFileLoad(caller, fileLoad); + + let content = new Meta.Background({ meta_screen: global.screen }); + +-- +1.9.0 + + +From d5fdad361b7224e811921004be0d096cffb18f41 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 26 Feb 2014 16:09:26 -0500 +Subject: [PATCH 09/13] background: get rid of nested loop when finishing file + loading + +At the moment when a file is loaded, we iterate through the list of +pending file loads and ignore any unrelated to the file, then iterate +all the callers of the related file loads and finish them. + +In fact, there can only ever be one pending file load related to the +file, and we already know it, so we can avoid the ugly nested loops. + +https://bugzilla.gnome.org/show_bug.cgi?id=722149 +--- + js/ui/background.js | 32 +++++++++++++------------------- + 1 file changed, 13 insertions(+), 19 deletions(-) + +diff --git a/js/ui/background.js b/js/ui/background.js +index 63b62a0..417f70d 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -190,28 +190,22 @@ const BackgroundCache = new Lang.Class({ + content = null; + } + +- for (let i = 0; i < this._pendingFileLoads.length; i++) { +- let pendingLoad = this._pendingFileLoads[i]; +- if (pendingLoad.filename != params.filename || +- pendingLoad.style != params.style) +- continue; +- +- for (let j = 0; j < pendingLoad.callers.length; j++) { +- if (pendingLoad.callers[j].onFinished) { +- let newContent; +- +- if (content) { +- newContent = content.copy(pendingLoad.callers[j].monitorIndex, +- pendingLoad.callers[j].effects); +- this._images.push(newContent); +- } +- +- pendingLoad.callers[j].onFinished(newContent); ++ for (let i = 0; i < fileLoad.callers.length; i++) { ++ let caller = fileLoad.callers[i]; ++ if (caller.onFinished) { ++ let newContent; ++ ++ if (content) { ++ newContent = content.copy(caller.monitorIndex, caller.effects); ++ this._images.push(newContent); + } +- } + +- this._pendingFileLoads.splice(i, 1); ++ caller.onFinished(newContent); ++ } + } ++ ++ let idx = this._pendingFileLoads.indexOf(fileLoad); ++ this._pendingFileLoads.splice(idx, 1); + })); + }, + +-- +1.9.0 + + +From ef3fe7c12368f05e5187b89eb88a7454b9d43193 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Wed, 26 Feb 2014 15:45:14 -0500 +Subject: [PATCH 10/13] background: fix cancellable issue + +If we have the following sequence: + + cache.getImageContent({ filename: "foo", cancellable: cancellable1 }); + cache.getImageContent({ filename: "foo", cancellable: cancellable2 }); + cancellable1.cancel(); + +Then the second load will complete with "null" as its content, even though +it was never cancelled, and we'll see a blank image. Meanwhile, since the +second load simply appends to the list of callers for the second load, +cancellable2 does absolutely nothing: cancelling it won't stop the load, +and it will still receive onFinished handling. + +To prevent this from happening, give the actual load operation its own +Gio.Cancellable, which is "ref-counted" -- only cancel it when all the other +possible callers cancel. + +Based on work from Jasper St. Pierre + +https://bugzilla.gnome.org/show_bug.cgi?id=722149 +--- + js/ui/background.js | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/js/ui/background.js b/js/ui/background.js +index 417f70d..5d6d615 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -146,6 +146,21 @@ const BackgroundCache = new Lang.Class({ + + _attachCallerToFileLoad: function(caller, fileLoad) { + fileLoad.callers.push(caller); ++ ++ if (!caller.cancellable) ++ return; ++ ++ caller.cancellable.connect(Lang.bind(this, function() { ++ let idx = fileLoad.callers.indexOf(caller); ++ fileLoad.callers.splice(idx, 1); ++ ++ if (fileLoad.callers.length == 0) { ++ fileLoad.cancellable.cancel(); ++ ++ let idx = this._pendingFileLoads.indexOf(fileLoad); ++ this._pendingFileLoads.splice(idx, 1); ++ } ++ })); + }, + + _loadImageContent: function(params) { +@@ -158,6 +173,7 @@ const BackgroundCache = new Lang.Class({ + + let caller = { monitorIndex: params.monitorIndex, + effects: params.effects, ++ cancellable: params.cancellable, + onFinished: params.onFinished }; + + for (let i = 0; i < this._pendingFileLoads.length; i++) { +@@ -172,6 +188,7 @@ const BackgroundCache = new Lang.Class({ + + let fileLoad = { filename: params.filename, + style: params.style, ++ cancellable: new Gio.Cancellable(), + callers: [] }; + this._attachCallerToFileLoad(caller, fileLoad); + +-- +1.9.0 + + +From b9c8c220ea0cdd1f3d1b8ddefb9fc0e43d9e004f Mon Sep 17 00:00:00 2001 +From: "Jasper St. Pierre" +Date: Tue, 3 Dec 2013 15:41:42 -0500 +Subject: [PATCH 11/13] background: Fix the check for spanning backgrounds + +this._monitorIndex does not exist, and neither does +MetaBackground.monitor_index... + +https://bugzilla.gnome.org/show_bug.cgi?id=719803 +--- + js/ui/background.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/js/ui/background.js b/js/ui/background.js +index 5d6d615..0ac4ddc 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -247,7 +247,7 @@ const BackgroundCache = new Lang.Class({ + continue; + + if (params.style == GDesktopEnums.BackgroundStyle.SPANNED && +- this._images[i].monitor_index != this._monitorIndex) ++ this._images[i].monitor != params.monitorIndex) + continue; + + candidateContent = this._images[i]; +-- +1.9.0 + + +From 3466eb95898adb14a28f32740dde559b460a3ca2 Mon Sep 17 00:00:00 2001 +From: "Jasper St. Pierre" +Date: Tue, 3 Dec 2013 15:56:12 -0500 +Subject: [PATCH 12/13] background: Don't wait for gdk-pixbuf to fail before + loading animations + +We don't have any better way of determining whether something is a slideshow +animation, so discriminate on the .xml filename instead of waiting for +gdk-pixbuf to determine whether it can load a file or not. + +https://bugzilla.gnome.org/show_bug.cgi?id=719803 +--- + js/ui/background.js | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/js/ui/background.js b/js/ui/background.js +index 0ac4ddc..0c22a0d 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -568,24 +568,25 @@ const Background = new Lang.Class({ + }); + }, + +- _loadFile: function(filename) { ++ _loadImage: function(filename) { + this._cache.getImageContent({ monitorIndex: this._monitorIndex, + effects: this._effects, + style: this._style, + filename: filename, + cancellable: this._cancellable, + onFinished: Lang.bind(this, function(content) { +- if (!content) { +- if (!this._cancellable.is_cancelled()) +- this._loadAnimation(filename); +- return; +- } +- +- this._addImage(content, 0, filename); ++ if (content) ++ this._addImage(content, 0, filename); + this._setLoaded(); + }) + }); ++ }, + ++ _loadFile: function(filename) { ++ if (filename.indexOf('.xml', filename.length - 4) !== -1) ++ this._loadAnimation(filename); ++ else ++ this._loadImage(filename); + }, + + _load: function () { +-- +1.9.0 + + +From b44299e03981125c2877082226cc2276ad5b47bd Mon Sep 17 00:00:00 2001 +From: "Jasper St. Pierre" +Date: Tue, 3 Dec 2013 17:25:57 -0500 +Subject: [PATCH 13/13] background: Simplify animation code + +https://bugzilla.gnome.org/show_bug.cgi?id=719803 +--- + js/ui/background.js | 31 ++++++++++++++----------------- + 1 file changed, 14 insertions(+), 17 deletions(-) + +diff --git a/js/ui/background.js b/js/ui/background.js +index 0c22a0d..5575815 100644 +--- a/js/ui/background.js ++++ b/js/ui/background.js +@@ -439,29 +439,27 @@ const Background = new Lang.Class({ + this._fileWatches[filename] = signalId; + }, + +- _addImage: function(content, index, filename) { +- content.saturation = this._saturation; +- content.brightness = this._brightness; +- content.vignette_sharpness = this._vignetteSharpness; ++ _ensureImage: function(index) { ++ if (this._images[index]) ++ return; + + let actor = new Meta.BackgroundActor(); +- actor.content = content; + + // The background pattern is the first actor in + // the group, and all images should be above that. + this.actor.insert_child_at_index(actor, index + 1); +- + this._images[index] = actor; +- this._watchCacheFile(filename); + }, + +- _updateImage: function(content, index, filename) { ++ _updateImage: function(index, content, filename) { + content.saturation = this._saturation; + content.brightness = this._brightness; + content.vignette_sharpness = this._vignetteSharpness; + +- this._cache.removeImageContent(this._images[index].content); +- this._images[index].content = content; ++ let image = this._images[index]; ++ if (image.content) ++ this._cache.removeImageContent(content); ++ image.content = content; + this._watchCacheFile(filename); + }, + +@@ -509,11 +507,8 @@ const Background = new Lang.Class({ + return; + } + +- if (!this._images[i]) { +- this._addImage(content, i, files[i]); +- } else { +- this._updateImage(content, i, files[i]); +- } ++ this._ensureImage(i); ++ this._updateImage(i, content, files[i]); + + if (numPendingImages == 0) { + this._setLoaded(); +@@ -575,8 +570,10 @@ const Background = new Lang.Class({ + filename: filename, + cancellable: this._cancellable, + onFinished: Lang.bind(this, function(content) { +- if (content) +- this._addImage(content, 0, filename); ++ if (content) { ++ this._ensureImage(0); ++ this._updateImage(0, content, filename); ++ } + this._setLoaded(); + }) + }); +-- +1.9.0 + diff --git a/SOURCES/fix-remote-search-provider-loading.patch b/SOURCES/fix-remote-search-provider-loading.patch new file mode 100644 index 0000000..d6be5f9 --- /dev/null +++ b/SOURCES/fix-remote-search-provider-loading.patch @@ -0,0 +1,296 @@ +From 8f05bb1332ef7ad25e599b9a7d998733564cc3c8 Mon Sep 17 00:00:00 2001 +From: "Jasper St. Pierre" +Date: Thu, 11 Jul 2013 14:25:08 -0400 +Subject: [PATCH 1/3] search: Ensure that we correctly remove remote search + providers + +When we reload the remote search providers, we currently try to remove +all remote providers, and then re-scan. It turns out that we sometimes +remove the wrong providers from the remote provider list, causing us to +have some providers not correctly unloaded. + +https://bugzilla.gnome.org/show_bug.cgi?id=700283 +--- + js/ui/search.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/js/ui/search.js b/js/ui/search.js +index 3dd59d7..2cc8693 100644 +--- a/js/ui/search.js ++++ b/js/ui/search.js +@@ -31,7 +31,7 @@ const SearchSystem = new Lang.Class({ + + let remoteIndex = this._remoteProviders.indexOf(provider); + if (remoteIndex != -1) +- this._remoteProviders.splice(index, 1); ++ this._remoteProviders.splice(remoteIndex, 1); + }, + + getProviders: function() { +-- +1.9.0 + + +From ab6694662aa79819d5140083b4eee15b312d3807 Mon Sep 17 00:00:00 2001 +From: "Jasper St. Pierre" +Date: Fri, 26 Jul 2013 18:36:31 -0400 +Subject: [PATCH 2/3] remoteSearch: Load remote search providers synchronously + +As we only reload search providers on startup or when the sort order changes, +and given the small number of search providers we'll actually load, I doubt +we'll see any speed decrease. + +The simplicity of synchronous code is also much clearer, and fully avoids +all the possible bugs about in-flight requests or similar. + +This also prevents issues with multiple search providers showing up at once, +which happen when multiple requests to reload search providers get called +immediately, with the existing in-flight async requests never cancelled. + +https://bugzilla.gnome.org/show_bug.cgi?id=700283 +--- + js/ui/remoteSearch.js | 154 +++++++++++++++++++++++++------------------------- + 1 file changed, 76 insertions(+), 78 deletions(-) + +diff --git a/js/ui/remoteSearch.js b/js/ui/remoteSearch.js +index e7cd6fe..323db5e 100644 +--- a/js/ui/remoteSearch.js ++++ b/js/ui/remoteSearch.js +@@ -7,7 +7,6 @@ const Lang = imports.lang; + const St = imports.gi.St; + const Shell = imports.gi.Shell; + +-const FileUtils = imports.misc.fileUtils; + const Search = imports.ui.search; + + const KEY_FILE_GROUP = 'Shell Search Provider'; +@@ -60,108 +59,107 @@ var SearchProviderProxy = Gio.DBusProxy.makeProxyWrapper(SearchProviderIface); + var SearchProvider2Proxy = Gio.DBusProxy.makeProxyWrapper(SearchProvider2Iface); + + function loadRemoteSearchProviders(addProviderCallback) { +- let data = { loadedProviders: [], +- objectPaths: {}, +- addProviderCallback: addProviderCallback }; +- FileUtils.collectFromDatadirsAsync('search-providers', +- { loadedCallback: remoteProvidersLoaded, +- processFile: loadRemoteSearchProvider, +- data: data +- }); +-} +- +-function loadRemoteSearchProvider(file, info, data) { +- let keyfile = new GLib.KeyFile(); +- let path = file.get_path(); +- +- try { +- keyfile.load_from_file(path, 0); +- } catch(e) { +- return; +- } +- +- if (!keyfile.has_group(KEY_FILE_GROUP)) +- return; ++ let objectPaths = {}; ++ let loadedProviders = []; + +- let remoteProvider; +- try { +- let group = KEY_FILE_GROUP; +- let busName = keyfile.get_string(group, 'BusName'); +- let objectPath = keyfile.get_string(group, 'ObjectPath'); ++ function loadRemoteSearchProvider(file) { ++ let keyfile = new GLib.KeyFile(); ++ let path = file.get_path(); + +- if (data.objectPaths[objectPath]) +- return; +- +- let appInfo = null; + try { +- let desktopId = keyfile.get_string(group, 'DesktopId'); +- appInfo = Gio.DesktopAppInfo.new(desktopId); +- } catch (e) { +- log('Ignoring search provider ' + path + ': missing DesktopId'); ++ keyfile.load_from_file(path, 0); ++ } catch(e) { + return; + } + +- let version = '1'; ++ if (!keyfile.has_group(KEY_FILE_GROUP)) ++ return; ++ ++ let remoteProvider; + try { +- version = keyfile.get_string(group, 'Version'); +- } catch (e) { +- // ignore error +- } ++ let group = KEY_FILE_GROUP; ++ let busName = keyfile.get_string(group, 'BusName'); ++ let objectPath = keyfile.get_string(group, 'ObjectPath'); ++ ++ if (objectPaths[objectPath]) ++ return; ++ ++ let appInfo = null; ++ try { ++ let desktopId = keyfile.get_string(group, 'DesktopId'); ++ appInfo = Gio.DesktopAppInfo.new(desktopId); ++ } catch (e) { ++ log('Ignoring search provider ' + path + ': missing DesktopId'); ++ return; ++ } + +- if (version >= 2) +- remoteProvider = new RemoteSearchProvider2(appInfo, busName, objectPath); +- else +- remoteProvider = new RemoteSearchProvider(appInfo, busName, objectPath); ++ let version = '1'; ++ try { ++ version = keyfile.get_string(group, 'Version'); ++ } catch (e) { ++ // ignore error ++ } + +- data.objectPaths[objectPath] = remoteProvider; +- data.loadedProviders.push(remoteProvider); +- } catch(e) { +- log('Failed to add search provider %s: %s'.format(path, e.toString())); ++ if (version >= 2) ++ remoteProvider = new RemoteSearchProvider2(appInfo, busName, objectPath); ++ else ++ remoteProvider = new RemoteSearchProvider(appInfo, busName, objectPath); ++ ++ objectPaths[objectPath] = remoteProvider; ++ loadedProviders.push(remoteProvider); ++ } catch(e) { ++ log('Failed to add search provider %s: %s'.format(path, e.toString())); ++ } + } +-} + +-function remoteProvidersLoaded(loadState) { ++ let dataDirs = GLib.get_system_data_dirs(); ++ dataDirs.forEach(function(dataDir) { ++ let path = GLib.build_filenamev([dataDir, 'gnome-shell', 'search-providers']); ++ let dir = Gio.File.new_for_path(path); ++ let fileEnum = dir.enumerate_children('standard::name,standard::type', ++ Gio.FileQueryInfoFlags.NONE, null); ++ let info; ++ while ((info = fileEnum.next_file(null))) ++ loadRemoteSearchProvider(fileEnum.get_child(info)); ++ }); ++ + let searchSettings = new Gio.Settings({ schema: Search.SEARCH_PROVIDERS_SCHEMA }); + let sortOrder = searchSettings.get_strv('sort-order'); + + // Special case gnome-control-center to be always active and always first + sortOrder.unshift('gnome-control-center.desktop'); + +- loadState.loadedProviders.sort( +- function(providerA, providerB) { +- let idxA, idxB; +- let appIdA, appIdB; ++ loadedProviders.sort(function(providerA, providerB) { ++ let idxA, idxB; ++ let appIdA, appIdB; + +- appIdA = providerA.appInfo.get_id(); +- appIdB = providerB.appInfo.get_id(); ++ appIdA = providerA.appInfo.get_id(); ++ appIdB = providerB.appInfo.get_id(); + +- idxA = sortOrder.indexOf(appIdA); +- idxB = sortOrder.indexOf(appIdB); ++ idxA = sortOrder.indexOf(appIdA); ++ idxB = sortOrder.indexOf(appIdB); + +- // if no provider is found in the order, use alphabetical order +- if ((idxA == -1) && (idxB == -1)) { +- let nameA = providerA.appInfo.get_name(); +- let nameB = providerB.appInfo.get_name(); ++ // if no provider is found in the order, use alphabetical order ++ if ((idxA == -1) && (idxB == -1)) { ++ let nameA = providerA.appInfo.get_name(); ++ let nameB = providerB.appInfo.get_name(); + +- return GLib.utf8_collate(nameA, nameB); +- } ++ return GLib.utf8_collate(nameA, nameB); ++ } + +- // if providerA isn't found, it's sorted after providerB +- if (idxA == -1) +- return 1; ++ // if providerA isn't found, it's sorted after providerB ++ if (idxA == -1) ++ return 1; + +- // if providerB isn't found, it's sorted after providerA +- if (idxB == -1) +- return -1; ++ // if providerB isn't found, it's sorted after providerA ++ if (idxB == -1) ++ return -1; + +- // finally, if both providers are found, return their order in the list +- return (idxA - idxB); +- }); ++ // finally, if both providers are found, return their order in the list ++ return (idxA - idxB); ++ }); + +- loadState.loadedProviders.forEach( +- function(provider) { +- loadState.addProviderCallback(provider); +- }); ++ loadedProviders.forEach(addProviderCallback); + } + + const RemoteSearchProvider = new Lang.Class({ +-- +1.9.0 + + +From d47c0ff65deb9301458c054ffd82ac3d398a79d5 Mon Sep 17 00:00:00 2001 +From: Colin Walters +Date: Sat, 27 Jul 2013 10:55:57 -0400 +Subject: [PATCH 3/3] search: Don't throw if provider directories don't exist + +There's no /usr/local/share/gnome-shell/search-providers, so don't +throw if we don't find it. +--- + js/ui/remoteSearch.js | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/js/ui/remoteSearch.js b/js/ui/remoteSearch.js +index 323db5e..25e379c 100644 +--- a/js/ui/remoteSearch.js ++++ b/js/ui/remoteSearch.js +@@ -116,11 +116,18 @@ function loadRemoteSearchProviders(addProviderCallback) { + dataDirs.forEach(function(dataDir) { + let path = GLib.build_filenamev([dataDir, 'gnome-shell', 'search-providers']); + let dir = Gio.File.new_for_path(path); +- let fileEnum = dir.enumerate_children('standard::name,standard::type', ++ let fileEnum; ++ try { ++ fileEnum = dir.enumerate_children('standard::name,standard::type', + Gio.FileQueryInfoFlags.NONE, null); +- let info; +- while ((info = fileEnum.next_file(null))) +- loadRemoteSearchProvider(fileEnum.get_child(info)); ++ } catch (e) { ++ fileEnum = null; ++ } ++ if (fileEnum != null) { ++ let info; ++ while ((info = fileEnum.next_file(null))) ++ loadRemoteSearchProvider(fileEnum.get_child(info)); ++ } + }); + + let searchSettings = new Gio.Settings({ schema: Search.SEARCH_PROVIDERS_SCHEMA }); +-- +1.9.0 + diff --git a/SOURCES/gdm-support-pre-authenticated-logins-from-oVirt.patch b/SOURCES/gdm-support-pre-authenticated-logins-from-oVirt.patch index d2f91d3..7f7ff46 100644 --- a/SOURCES/gdm-support-pre-authenticated-logins-from-oVirt.patch +++ b/SOURCES/gdm-support-pre-authenticated-logins-from-oVirt.patch @@ -101,15 +101,13 @@ index 2121f2e..ba66c42 100644 _onSmartcardStatusChanged: function() { this.smartcardDetected = this._userVerifier.smartcardDetected; -@@ -443,10 +449,11 @@ const AuthPrompt = new Lang.Class({ +@@ -443,9 +449,10 @@ const AuthPrompt = new Lang.Class({ // The user is constant at the unlock screen, so it will immediately // respond to the request with the username beginRequestType = BeginRequestType.PROVIDE_USERNAME; -- } else if (this.smartcardDetected && -- this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME)) { +- } else if (this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME)) { + } else if (this._userVerifier.serviceIsForeground(GdmUtil.OVIRT_SERVICE_NAME) || -+ (this.smartcardDetected && -+ this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME))) { ++ this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME)) { // We don't need to know the username if the user preempted the login screen - // with a smartcard. + // with a smartcard or with preauthenticated oVirt credentials diff --git a/SOURCES/gnome-shell-favourite-apps-empathy.patch b/SOURCES/gnome-shell-favourite-apps-empathy.patch new file mode 100644 index 0000000..52c19f5 --- /dev/null +++ b/SOURCES/gnome-shell-favourite-apps-empathy.patch @@ -0,0 +1,12 @@ +diff -up gnome-shell-3.8.4/data/org.gnome.shell.gschema.xml.in.in.empathy gnome-shell-3.8.4/data/org.gnome.shell.gschema.xml.in.in +--- gnome-shell-3.8.4/data/org.gnome.shell.gschema.xml.in.in.empathy 2013-12-04 19:59:30.805795688 -0500 ++++ gnome-shell-3.8.4/data/org.gnome.shell.gschema.xml.in.in 2013-12-04 19:59:53.021745970 -0500 +@@ -32,7 +32,7 @@ + + + +- [ 'firefox.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'libreoffice-writer.desktop', 'nautilus.desktop', 'gnome-documents.desktop', 'yelp.desktop', 'gnome-terminal.desktop' ] ++ [ 'firefox.desktop', 'evolution.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'libreoffice-writer.desktop', 'nautilus.desktop', 'gnome-documents.desktop', 'yelp.desktop', 'gnome-terminal.desktop' ] + <_summary>List of desktop file IDs for favorite applications + <_description> + The applications corresponding to these identifiers diff --git a/SOURCES/gnome-shell-favourite-apps-terminal.patch b/SOURCES/gnome-shell-favourite-apps-terminal.patch new file mode 100644 index 0000000..a94c9ea --- /dev/null +++ b/SOURCES/gnome-shell-favourite-apps-terminal.patch @@ -0,0 +1,12 @@ +diff -up gnome-shell-3.8.4/data/org.gnome.shell.gschema.xml.in.in.terminal gnome-shell-3.8.4/data/org.gnome.shell.gschema.xml.in.in +--- gnome-shell-3.8.4/data/org.gnome.shell.gschema.xml.in.in.terminal 2013-12-04 19:55:59.264274478 -0500 ++++ gnome-shell-3.8.4/data/org.gnome.shell.gschema.xml.in.in 2013-12-04 19:56:51.813151886 -0500 +@@ -32,7 +32,7 @@ + + + +- [ 'firefox.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'libreoffice-writer.desktop', 'nautilus.desktop', 'gnome-documents.desktop', 'yelp.desktop' ] ++ [ 'firefox.desktop', 'evolution.desktop', 'empathy.desktop', 'rhythmbox.desktop', 'shotwell.desktop', 'libreoffice-writer.desktop', 'nautilus.desktop', 'gnome-documents.desktop', 'yelp.desktop', 'gnome-terminal.desktop' ] + <_summary>List of desktop file IDs for favorite applications + <_description> + The applications corresponding to these identifiers diff --git a/SOURCES/login-screen-backport.patch b/SOURCES/login-screen-backport.patch index acd94b5..eb79b8e 100644 --- a/SOURCES/login-screen-backport.patch +++ b/SOURCES/login-screen-backport.patch @@ -1,7 +1,7 @@ -From 51b5fb2e3560f64e1887683cd224d14b13cddd07 Mon Sep 17 00:00:00 2001 +From c41bf58d6214f585c29394e6a1a87b6650e20bce Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 14 Jun 2013 08:14:34 -0400 -Subject: [PATCH 01/66] loginDialog: clean up import lines +Subject: [PATCH 01/69] loginDialog: clean up import lines There are a few unused imports, and some import lines out of order. @@ -37,7 +37,7 @@ index 4355c1d..c3e26fa 100644 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ - + const AccountsService = imports.gi.AccountsService; const Clutter = imports.gi.Clutter; -const CtrlAltTab = imports.ui.ctrlAltTab; @@ -56,7 +56,7 @@ index 4355c1d..c3e26fa 100644 +const Signals = imports.signals; const St = imports.gi.St; -const Gdm = imports.gi.Gdm; - + const Batch = imports.gdm.batch; -const Fprint = imports.gdm.fingerprint; +const CtrlAltTab = imports.ui.ctrlAltTab; @@ -69,22 +69,22 @@ index 4355c1d..c3e26fa 100644 const Tweener = imports.ui.tweener; const UserMenu = imports.ui.userMenu; const UserWidget = imports.ui.userWidget; - + const _FADE_ANIMATION_TIME = 0.25; const _SCROLL_ANIMATION_TIME = 0.5; const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0; const _LOGO_ICON_HEIGHT = 48; - + let _loginDialog = null; - + const UserListItem = new Lang.Class({ Name: 'UserListItem', - + _init: function(user) { this.user = user; this._userChangedId = this.user.connect('changed', Lang.bind(this, this._onUserChanged)); - + let layout = new St.BoxLayout({ vertical: false }); this.actor = new St.Button({ style_class: 'login-dialog-user-list-item', button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, @@ -93,17 +93,17 @@ index 4355c1d..c3e26fa 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._userAvatar = new UserMenu.UserAvatarWidget(this.user, { styleClass: 'login-dialog-user-list-item-icon' }); --- +-- 1.8.3.1 -From cc789d8c429aaa5276f8cff339a866cf1e52b3b0 Mon Sep 17 00:00:00 2001 +From 18fe9560aea74461b0c6e77ec7c888f5b5d447f8 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 25 Jun 2013 12:55:21 -0400 -Subject: [PATCH 02/66] loginDialog: drop use of modal dialog +Subject: [PATCH 02/69] loginDialog: drop use of modal dialog The login screen is no longer even remotely dialog-like, so using ModalDialog is pretty weird. It also makes it difficult @@ -118,7 +118,7 @@ https://bugzilla.gnome.org/show_bug.cgi?id=702818 2 files changed, 138 insertions(+), 60 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css -index f4ea781..0fa3265 100644 +index 34a4cb2..7dac907 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -350,128 +350,134 @@ StScrollBar StButton#vhandle:active { @@ -127,9 +127,9 @@ index f4ea781..0fa3265 100644 background-gradient-direction: none; background-color: rgba(102, 102, 102, 0.15); } - + /* Common radii */ - + #searchEntry, .modal-dialog-button, .notification-button, @@ -137,20 +137,20 @@ index f4ea781..0fa3265 100644 .app-view-controls { border-radius: 18px; } - + .app-view-control:first-child:ltr, .app-view-control:last-child:rtl { border-radius: 18px 0px 0px 18px; border-right-width: 0px; } - + .app-view-control:last-child:ltr, .app-view-control:first-child:rtl { border-radius: 0px 18px 18px 0px; } - + /* Entries */ - + #searchEntry, +.login-dialog StEntry, .notification StEntry, @@ -162,7 +162,7 @@ index f4ea781..0fa3265 100644 selected-color: white; padding: 4px 12px; } - + #searchEntry, +.login-dialog StEntry, .run-dialog-entry, @@ -174,7 +174,7 @@ index f4ea781..0fa3265 100644 transition-duration: 300ms; box-shadow: inset 0px 2px 4px rgba(0,0,0,0.6); } - + #searchEntry:focus, #searchEntry:hover, +.login-dialog StEntry:focus, @@ -186,45 +186,45 @@ index f4ea781..0fa3265 100644 background-gradient-direction: vertical; box-shadow: inset 0px 2px 4px rgba(0,0,0,0.6); } - + +.login-dialog StEntry:focus, .notification StEntry:focus, .modal-dialog StEntry:focus { border: 2px solid #3465a4; } - + #searchEntry { border-color: rgba(245,245,245,0.3); color: rgb(192, 192, 192); caret-color: rgb(192, 192, 192); } - + #searchEntry:hover { color: rgb(128, 128, 128); caret-color: rgb(128, 128, 128); } - + #searchEntry:focus { color: rgb(64, 64, 64); caret-color: rgb(64, 64, 64); font-weight: bold; transition-duration: 0ms; } - + +.login-dialog StEntry, .notification StEntry, .modal-dialog StEntry { border-radius: 5px; padding: 4px 4px; } - + .prompt-dialog-password-entry .capslock-warning, .login-dialog-prompt-entry .capslock-warning { icon-size: 16px; warning-color: #999; padding: 0 4px; } - + +.login-dialog StEntry:insensitive, .modal-dialog StEntry:insensitive { border-color: #666666; @@ -234,28 +234,28 @@ index f4ea781..0fa3265 100644 background-color: rgba(102, 102, 102, 0.15); box-shadow: inset 0 0 rgba(0,0,0,1.0); } - + /* Panel */ - + #panel { background-color: black; font-weight: bold; height: 1.86em; } - + #panel.lock-screen { background-color: rgba(0,0,0,0.3); } - + #panel.unlock-screen, #panel.login-screen { background-color: transparent; } - + #panelLeft, #panelCenter { spacing: 4px; } - + diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js index c3e26fa..6b36b45 100644 --- a/js/gdm/loginDialog.js @@ -280,7 +280,7 @@ index c3e26fa..6b36b45 100644 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ - + const AccountsService = imports.gi.AccountsService; +const Atk = imports.gi.Atk; const Clutter = imports.gi.Clutter; @@ -294,7 +294,7 @@ index c3e26fa..6b36b45 100644 const Shell = imports.gi.Shell; const Signals = imports.signals; const St = imports.gi.St; - + +const Panel = imports.ui.panel; const Batch = imports.gdm.batch; const CtrlAltTab = imports.ui.ctrlAltTab; @@ -306,7 +306,7 @@ index c3e26fa..6b36b45 100644 const Tweener = imports.ui.tweener; const UserMenu = imports.ui.userMenu; const UserWidget = imports.ui.userWidget; - + const _FADE_ANIMATION_TIME = 0.25; const _SCROLL_ANIMATION_TIME = 0.5; +const _WORK_SPINNER_ICON_SIZE = 24; @@ -314,17 +314,17 @@ index c3e26fa..6b36b45 100644 +const _WORK_SPINNER_ANIMATION_TIME = 0.3; const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0; const _LOGO_ICON_HEIGHT = 48; - + let _loginDialog = null; - + const UserListItem = new Lang.Class({ Name: 'UserListItem', - + _init: function(user) { this.user = user; this._userChangedId = this.user.connect('changed', Lang.bind(this, this._onUserChanged)); - + let layout = new St.BoxLayout({ vertical: false }); this.actor = new St.Button({ style_class: 'login-dialog-user-list-item', button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, @@ -333,17 +333,17 @@ index c3e26fa..6b36b45 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._userAvatar = new UserMenu.UserAvatarWidget(this.user, { styleClass: 'login-dialog-user-list-item-icon' }); layout.add(this._userAvatar.actor); let textLayout = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-text-box', vertical: true }); layout.add(textLayout, { expand: true }); - + this._nameLabel = new St.Label({ style_class: 'login-dialog-user-list-item-name' }); @@ -442,205 +447,223 @@ const SessionList = new Lang.Class({ - + if (ids.length <= 1) { this._box.hide(); this._button.hide(); @@ -351,17 +351,17 @@ index c3e26fa..6b36b45 100644 this._button.show(); this._box.show(); } - + for (let i = 0; i < ids.length; i++) { let [sessionName, sessionDescription] = Gdm.get_session_name_and_description(ids[i]); - + let item = new SessionListItem(ids[i], sessionName); this._itemList.add_actor(item.actor); this._items[ids[i]] = item; - + if (!this._activeSessionId) this.setActiveSession(ids[i]); - + item.connect('activate', Lang.bind(this, function() { this.setActiveSession(item.id); @@ -370,11 +370,11 @@ index c3e26fa..6b36b45 100644 } }); Signals.addSignalMethods(SessionList.prototype); - + const LoginDialog = new Lang.Class({ Name: 'LoginDialog', - Extends: ModalDialog.ModalDialog, - + _init: function(parentActor) { - this.parent({ shellReactive: true, - styleClass: 'login-dialog', @@ -392,22 +392,22 @@ index c3e26fa..6b36b45 100644 + this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true })); + this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); + parentActor.add_child(this.actor); - + this._userManager = AccountsService.UserManager.get_default() this._greeterClient = new Gdm.Client(); - + if (GLib.getenv('GDM_GREETER_TEST') != '1') { this._greeter = this._greeterClient.get_greeter_sync(null); - + this._greeter.connect('default-session-name-changed', Lang.bind(this, this._onDefaultSessionChanged)); - + this._greeter.connect('session-opened', Lang.bind(this, this._onSessionOpened)); this._greeter.connect('timed-login-requested', Lang.bind(this, this._onTimedLoginRequested)); } - + this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient); this._userVerifier.connect('ask-question', Lang.bind(this, this._askQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage)); @@ -416,9 +416,9 @@ index c3e26fa..6b36b45 100644 this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint)); this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint)); this._verifyingUser = false; - + this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA }); - + this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY, Lang.bind(this, this._updateBanner)); this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY, @@ -427,11 +427,11 @@ index c3e26fa..6b36b45 100644 Lang.bind(this, this._updateDisableUserList)); this._settings.connect('changed::' + GdmUtil.LOGO_KEY, Lang.bind(this, this._updateLogo)); - + this._textureCache = St.TextureCache.get_default(); this._textureCache.connect('texture-file-changed', Lang.bind(this, this._updateLogoTexture)); - + this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', vertical: true }); - this.contentLayout.add(this._userSelectionBox); @@ -439,18 +439,18 @@ index c3e26fa..6b36b45 100644 + align_axis: Clutter.AlignAxis.BOTH, + factor: 0.5 })); + this.actor.add_child(this._userSelectionBox); - + this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', text: '' }); this._userSelectionBox.add(this._bannerLabel); this._updateBanner(); - + this._userList = new UserList(); this._userSelectionBox.add(this._userList.actor, { expand: true, x_fill: true, y_fill: true }); - + - this.setInitialKeyFocus(this._userList.actor); - this._promptBox = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout', @@ -480,7 +480,7 @@ index c3e26fa..6b36b45 100644 y_fill: true, expand: true }); this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this._promptBox.add(this._promptLabel, { expand: true, x_fill: true, @@ -495,14 +495,14 @@ index c3e26fa..6b36b45 100644 x_fill: true, y_fill: false, x_align: St.Align.START }); - + this._promptMessage = new St.Label({ visible: false }); this._promptBox.add(this._promptMessage, { x_fill: true }); - + this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' }); this._promptLoginHint.hide(); this._promptBox.add(this._promptLoginHint); - + - this._signInButton = null; - this._sessionList = new SessionList(); @@ -510,7 +510,7 @@ index c3e26fa..6b36b45 100644 Lang.bind(this, function(list, sessionId) { this._greeter.call_select_session_sync (sessionId, null); })); - + this._promptBox.add(this._sessionList.actor, { expand: true, x_fill: false, @@ -526,7 +526,7 @@ index c3e26fa..6b36b45 100644 + this._signInButton = null; + this._promptBox.hide(); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -539,14 +539,14 @@ index c3e26fa..6b36b45 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn)); - + this._userSelectionBox.add(this._notListedButton, { expand: false, x_align: St.Align.START, x_fill: true }); - + this._logoBin = new St.Bin({ style_class: 'login-dialog-logo-bin', y_expand: true }); this._logoBin.set_y_align(Clutter.ActorAlign.END); - this.backgroundStack.add_actor(this._logoBin); @@ -558,7 +558,7 @@ index c3e26fa..6b36b45 100644 + factor: 1.0 })); + this.actor.add_child(this._logoBin); this._updateLogo(); - + if (!this._userManager.is_loaded) this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', Lang.bind(this, function() { @@ -570,54 +570,54 @@ index c3e26fa..6b36b45 100644 })); else this._loadUserList(); - + this._userList.connect('activate', Lang.bind(this, function(userList, item) { this._onUserListActivated(item); })); - + }, - + _updateDisableUserList: function() { let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); - + // If this is the first time around, set initial focus if (this._disableUserList == undefined && disableUserList) this.setInitialKeyFocus(this._promptEntry); - + if (disableUserList != this._disableUserList) { this._disableUserList = disableUserList; @@ -667,65 +690,92 @@ const LoginDialog = new Lang.Class({ return; - + let icon = null; if (this._logoFileUri) icon = this._textureCache.load_uri_async(this._logoFileUri, -1, _LOGO_ICON_HEIGHT); this._logoBin.set_child(icon); }, - + _updateLogo: function() { let path = this._settings.get_string(GdmUtil.LOGO_KEY); - + this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; this._updateLogoTexture(this._textureCache, this._logoFileUri); }, - + _reset: function() { this._userVerifier.clear(); - + this._updateSensitivity(true); this._promptMessage.hide(); this._user = null; this._verifyingUser = false; - + if (this._disableUserList) this._hideUserListAndLogIn(); else this._showUserList(); }, - + + _setWorking: function(working) { + if (!this._workSpinner) + return; @@ -647,16 +647,16 @@ index c3e26fa..6b36b45 100644 + _verificationFailed: function() { this._promptEntry.text = ''; - + this._updateSensitivity(true); - this.setWorking(false); + this._setWorking(false); }, - + _onDefaultSessionChanged: function(client, sessionId) { this._sessionList.setActiveSession(sessionId); }, - + _showMessage: function(userVerifier, message, styleClass) { if (message) { this._promptMessage.text = message; @@ -666,18 +666,18 @@ index c3e26fa..6b36b45 100644 this._promptMessage.hide(); } }, - + _showLoginHint: function(verifier, message) { this._promptLoginHint.set_text(message) this._promptLoginHint.show(); this._promptLoginHint.opacity = 255; }, - + _hideLoginHint: function() { this._promptLoginHint.hide(); this._promptLoginHint.set_text(''); }, - + cancel: function() { if (this._verifyingUser) this._userVerifier.cancel(); @@ -693,24 +693,24 @@ index c3e26fa..6b36b45 100644 { opacity: 255, time: _FADE_ANIMATION_TIME, transition: 'easeOutQuad' }); - + if ((this._user && !this._user.is_logged_in()) || this._verifyingUser) this._sessionList.actor.show(); - + this._promptEntry.grab_key_focus(); - + let hold = new Batch.Hold(); let tasks = [function() { this._prepareDialog(forSecret, hold); }, - + hold]; - + let batch = new Batch.ConcurrentBatch(this, tasks); - + return batch.run(); }, - + _prepareDialog: function(forSecret, hold) { - this.buttonLayout.visible = true; - this.clearButtons(); @@ -785,79 +785,79 @@ index c3e26fa..6b36b45 100644 + y_fill: false, + x_align: St.Align.END, + y_align: St.Align.END }); - + this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0); - + this._promptEntryTextChangedId = this._promptEntry.clutter_text.connect('text-changed', Lang.bind(this, function() { this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0); })); - + this._promptEntryActivateId = this._promptEntry.clutter_text.connect('activate', function() { hold.release(); }); }, - + _updateSensitivity: function(sensitive) { this._promptEntry.reactive = sensitive; this._promptEntry.clutter_text.editable = sensitive; this._sessionList.updateSensitivity(sensitive); this._updateSignInButtonSensitivity(sensitive); }, - + _updateSignInButtonSensitivity: function(sensitive) { if (this._signInButton) { this._signInButton.reactive = sensitive; this._signInButton.can_focus = sensitive; } }, - + _hidePrompt: function() { - this.setButtons([]); + this._buttonBox.destroy_all_children(); - + if (this._promptEntryTextChangedId > 0) { this._promptEntry.clutter_text.disconnect(this._promptEntryTextChangedId); this._promptEntryTextChangedId = 0; } - + if (this._promptEntryActivateId > 0) { this._promptEntry.clutter_text.disconnect(this._promptEntryActivateId); this._promptEntryActivateId = 0; } - + - this.setWorking(false); + this._setWorking(false); this._promptBox.hide(); this._promptLoginHint.hide(); - + this._promptUser.set_child(null); - + this._updateSensitivity(true); this._promptEntry.set_text(''); - + this._sessionList.close(); this._promptLoginHint.hide(); - + - this.clearButtons(); + this._buttonBox.destroy_all_children(); this._signInButton = null; + this._cancelButton = null; }, - + _askQuestion: function(verifier, serviceName, question, passwordChar) { this._promptLabel.set_text(question); - + this._updateSensitivity(true); this._promptEntry.set_text(''); this._promptEntry.clutter_text.set_password_char(passwordChar); - + let tasks = [function() { return this._showPrompt(!!passwordChar); }, - + function() { let text = this._promptEntry.get_text(); this._updateSensitivity(false); @@ -865,51 +865,51 @@ index c3e26fa..6b36b45 100644 + this._setWorking(true); this._userVerifier.answerQuery(serviceName, text); }]; - + let batch = new Batch.ConsecutiveBatch(this, tasks); return batch.run(); }, - + _showRealmLoginHint: function(realmManager, hint) { if (!hint) return; - + hint = hint.replace(/%U/g, 'user'); hint = hint.replace(/%D/g, 'DOMAIN'); hint = hint.replace(/%[^UD]/g, ''); - + // Translators: this message is shown below the username entry field // to clue the user in on how to login to the local network realm this._showLoginHint(null, _("(e.g., user or %s)").format(hint)); }, - + _askForUsernameAndLogIn: function() { this._promptLabel.set_text(_("Username: ")); this._promptEntry.set_text(''); this._promptEntry.clutter_text.set_password_char(''); - + let realmManager = new Realmd.Manager(); let signalId = realmManager.connect('login-format-changed', - Lang.bind(this, this._showRealmLoginHint)); + Lang.bind(this, this._showRealmLoginHint)); this._showRealmLoginHint(realmManager.loginFormat); - + let tasks = [this._showPrompt, - + function() { let userName = this._promptEntry.get_text(); this._promptEntry.reactive = false; return this._beginVerificationForUser(userName); }, - + function() { realmManager.disconnect(signalId) realmManager.release(); }]; - + let batch = new Batch.ConsecutiveBatch(this, tasks); return batch.run(); }, - + _startSession: function(serviceName) { - Tweener.addTween(this.dialogLayout, + Tweener.addTween(this.actor, @@ -918,7 +918,7 @@ index c3e26fa..6b36b45 100644 transition: 'easeOutQuad', onUpdate: function() { let children = Main.layoutManager.uiGroup.get_children(); - + for (let i = 0; i < children.length; i++) { if (children[i] != Main.layoutManager.screenShieldGroup) - children[i].opacity = this.dialogLayout.opacity; @@ -934,7 +934,7 @@ index c3e26fa..6b36b45 100644 }, onCompleteScope: this }); }, - + _onSessionOpened: function(client, serviceName) { if (!this._userVerifier.hasPendingMessages) { this._startSession(serviceName); @@ -946,44 +946,44 @@ index c3e26fa..6b36b45 100644 })); } }, - + _waitForItemForUser: function(userName) { let item = this._userList.getItemFromUserName(userName); - + if (item) return null; - + @@ -1122,48 +1192,50 @@ const LoginDialog = new Lang.Class({ batch.run(); }, - + _onDestroy: function() { if (this._userManagerLoadedId) { this._userManager.disconnect(this._userManagerLoadedId); this._userManagerLoadedId = 0; } }, - + _loadUserList: function() { let users = this._userManager.list_users(); - + for (let i = 0; i < users.length; i++) { this._userList.addUser(users[i]); } - + this._updateDisableUserList(); - + this._userManager.connect('user-added', Lang.bind(this, function(userManager, user) { this._userList.addUser(user); })); - + this._userManager.connect('user-removed', Lang.bind(this, function(userManager, user) { this._userList.removeUser(user); })); }, - + - _onOpened: function() { - Main.ctrlAltTabManager.addGroup(this.dialogLayout, + open: function() { @@ -993,29 +993,29 @@ index c3e26fa..6b36b45 100644 { sortGroup: CtrlAltTab.SortGroup.MIDDLE }); + this._userList.actor.grab_key_focus(); + this.actor.show(); - + + return true; }, - + close: function() { - this.parent(); - Main.ctrlAltTabManager.removeGroup(this.dialogLayout); }, - + addCharacter: function(unichar) { this._promptEntry.clutter_text.insert_unichar(unichar); }, }); +Signals.addSignalMethods(LoginDialog.prototype); --- +-- 1.8.3.1 -From 11dc03aee173cbbd77d274fc83df64da74d77b2e Mon Sep 17 00:00:00 2001 +From f23e8a56ea95b904d5fc87bbdb9e440a8676e717 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 26 Jun 2013 10:52:02 -0400 -Subject: [PATCH 03/66] loginDialog: don't show Not Listed? button before user +Subject: [PATCH 03/69] loginDialog: don't show Not Listed? button before user list Right now, there's a weird flicker at start up where the @@ -1048,9 +1048,9 @@ index 6b36b45..4cbb0c9 100644 y_align: St.Align.END }); this._cancelButton = null; this._signInButton = null; - + this._promptBox.hide(); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -1063,15 +1063,15 @@ index 6b36b45..4cbb0c9 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn)); + this._notListedButton.hide(); - + this._userSelectionBox.add(this._notListedButton, { expand: false, x_align: St.Align.START, x_fill: true }); - + this._logoBin = new St.Bin({ style_class: 'login-dialog-logo-bin', y_expand: true }); this._logoBin.set_y_align(Clutter.ActorAlign.END); this._logoBin.add_constraint(new Clutter.AlignConstraint({ source: this.actor, @@ -1082,7 +1082,7 @@ index 6b36b45..4cbb0c9 100644 factor: 1.0 })); this.actor.add_child(this._logoBin); this._updateLogo(); - + if (!this._userManager.is_loaded) this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', Lang.bind(this, function() { @@ -1094,10 +1094,10 @@ index 6b36b45..4cbb0c9 100644 })); else this._loadUserList(); - + this._userList.connect('activate', @@ -1127,60 +1128,61 @@ const LoginDialog = new Lang.Class({ - + if (event.type() == Clutter.EventType.KEY_PRESS || event.type() == Clutter.EventType.BUTTON_PRESS) { if (this._timedLoginBatch) { @@ -1108,41 +1108,41 @@ index 6b36b45..4cbb0c9 100644 event.type() == Clutter.EventType.BUTTON_RELEASE) { this._resetTimedLogin(); } - + return false; })); }, - + _setUserListExpanded: function(expanded) { this._userList.updateStyle(expanded); this._userSelectionBox.visible = expanded; }, - + _hideUserListAndLogIn: function() { this._setUserListExpanded(false); GdmUtil.cloneAndFadeOutActor(this._userSelectionBox); this._askForUsernameAndLogIn(); }, - + _showUserList: function() { this._hidePrompt(); this._setUserListExpanded(true); + this._notListedButton.show(); this._userList.actor.grab_key_focus(); }, - + _beginVerificationForUser: function(userName) { let hold = new Batch.Hold(); - + this._userVerifier.begin(userName, hold); this._verifyingUser = true; return hold; }, - + _beginVerificationForItem: function(item) { let userWidget = new UserWidget.UserWidget(item.user); this._promptUser.set_child(userWidget.actor); - + let tasks = [function() { let userName = item.user.get_user_name(); return this._beginVerificationForUser(userName); @@ -1150,7 +1150,7 @@ index 6b36b45..4cbb0c9 100644 let batch = new Batch.ConsecutiveBatch(this, tasks); return batch.run(); }, - + _onUserListActivated: function(activatedItem) { let tasks = [function() { return GdmUtil.cloneAndFadeOutActor(this._userSelectionBox); @@ -1158,14 +1158,14 @@ index 6b36b45..4cbb0c9 100644 function() { this._setUserListExpanded(false); }]; --- +-- 1.8.3.1 -From 38f510c4d6fff0758af652109811a59e14b7c175 Mon Sep 17 00:00:00 2001 +From b05ad741f1489eee41099ec28e79fd3cea295962 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 23 Jun 2013 23:14:10 -0400 -Subject: [PATCH 04/66] loginDialog: Move the session list to a PopupMenu +Subject: [PATCH 04/69] loginDialog: Move the session list to a PopupMenu There are some issues with the existing session menu. First, it looks kinda bad. It seems like it's hanging around there, but it doesn't really know @@ -1189,17 +1189,17 @@ https://bugzilla.gnome.org/show_bug.cgi?id=702818 2 files changed, 78 insertions(+), 189 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css -index 0fa3265..4c0a795 100644 +index 7dac907..9f9830a 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css -@@ -2322,97 +2322,71 @@ StScrollBar StButton#vhandle:active { +@@ -2327,97 +2327,71 @@ StScrollBar StButton#vhandle:active { } - + .login-dialog-not-listed-button:focus .login-dialog-not-listed-label, .login-dialog-not-listed-button:hover .login-dialog-not-listed-label { color: #E8E8E8; } - + .login-dialog-username { font-size: 16pt; font-weight: bold; @@ -1207,22 +1207,22 @@ index 0fa3265..4c0a795 100644 padding-left: 15px; text-shadow: black 0px 4px 3px 0px; } - + .login-dialog-prompt-layout { padding-top: 24px; padding-bottom: 12px; spacing: 8px; } - + .login-dialog-prompt-label { color: #eeeeee; font-size: 14px; } - + .login-dialog-prompt-entry { width: 15em; } - + -.login-dialog-session-list, -.login-dialog-session-list-item { - color: #babdb6; @@ -1237,12 +1237,12 @@ index 0fa3265..4c0a795 100644 +.login-dialog-session-list-button StIcon { + icon-size: 1.25em; } - + .login-dialog-session-list-button { - padding: 4px; + color: #8b8b8b; } - + -.login-dialog-session-list-scroll-view { - padding: 6px; -} @@ -1267,35 +1267,35 @@ index 0fa3265..4c0a795 100644 +.login-dialog-session-list-button:active { + color: white; } - + .login-dialog-logo-bin { padding: 24px 0px; } - + .login-dialog .modal-dialog-button-box { spacing: 3px; } - + .login-dialog .modal-dialog-button { border-radius: 5px; padding: 3px 18px; } - + .login-dialog .modal-dialog-button:focus { padding: 2px 17px; } - + .login-dialog .modal-dialog-button:default { background-gradient-start: #6793c4; background-gradient-end: #335d8f; background-gradient-direction: vertical; border-color: #16335d; } - + .login-dialog .modal-dialog-button:default:focus { border: 2px solid #377fe7; } - + diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js index 4cbb0c9..5557db9 100644 --- a/js/gdm/loginDialog.js @@ -1314,7 +1314,7 @@ index 4cbb0c9..5557db9 100644 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ - + const AccountsService = imports.gi.AccountsService; const Atk = imports.gi.Atk; const Clutter = imports.gi.Clutter; @@ -1328,7 +1328,7 @@ index 4cbb0c9..5557db9 100644 const Shell = imports.gi.Shell; const Signals = imports.signals; const St = imports.gi.St; - + const Panel = imports.ui.panel; const Batch = imports.gdm.batch; +const BoxPointer = imports.ui.boxpointer; @@ -1341,7 +1341,7 @@ index 4cbb0c9..5557db9 100644 const Tweener = imports.ui.tweener; const UserMenu = imports.ui.userMenu; const UserWidget = imports.ui.userWidget; - + const _FADE_ANIMATION_TIME = 0.25; const _SCROLL_ANIMATION_TIME = 0.5; const _WORK_SPINNER_ICON_SIZE = 24; @@ -1349,17 +1349,17 @@ index 4cbb0c9..5557db9 100644 const _WORK_SPINNER_ANIMATION_TIME = 0.3; const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0; const _LOGO_ICON_HEIGHT = 48; - + let _loginDialog = null; - + const UserListItem = new Lang.Class({ Name: 'UserListItem', - + _init: function(user) { this.user = user; this._userChangedId = this.user.connect('changed', Lang.bind(this, this._onUserChanged)); - + let layout = new St.BoxLayout({ vertical: false }); this.actor = new St.Button({ style_class: 'login-dialog-user-list-item', button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, @@ -1372,32 +1372,32 @@ index 4cbb0c9..5557db9 100644 function() { this.scrollToItem(item); })); - + this._moveFocusToItems(); - + this.emit('item-added', item); }, - + removeUser: function(user) { if (!user.is_loaded) return; - + let userName = user.get_user_name(); - + if (!userName) return; - + let item = this._items[userName]; - + if (!item) return; - + item.actor.destroy(); delete this._items[userName]; } }); Signals.addSignalMethods(UserList.prototype); - + -const SessionListItem = new Lang.Class({ - Name: 'SessionListItem', - @@ -1459,7 +1459,7 @@ index 4cbb0c9..5557db9 100644 - Name: 'SessionList', +const SessionMenuButton = new Lang.Class({ + Name: 'SessionMenuButton', - + _init: function() { - this.actor = new St.Bin(); - @@ -1503,19 +1503,19 @@ index 4cbb0c9..5557db9 100644 + accessible_name: _("Choose Session"), + accessible_role: Atk.Role.MENU, + child: gearIcon }); - + - open: function() { - if (this.isOpen) - return; + this.actor = new St.Bin({ child: this._button }); - + - this._button.add_style_pseudo_class('open'); - this._scrollView.show(); - this._triangle.set_text('\u25BE'); + this._menu = new PopupMenu.PopupMenu(this._button, 0, St.Side.TOP); + Main.uiGroup.add_actor(this._menu.actor); + this._menu.actor.hide(); - + - this.isOpen = true; - }, + this._menu.connect('open-state-changed', @@ -1525,26 +1525,26 @@ index 4cbb0c9..5557db9 100644 + else + this._button.remove_style_pseudo_class('active'); + })); - + - close: function() { - if (!this.isOpen) - return; + let subtitle = new PopupMenu.PopupMenuItem(_("Session"), { style_class: 'popup-subtitle-menu-item', + reactive: false }); + this._menu.addMenuItem(subtitle); - + - this._button.remove_style_pseudo_class('open'); - this._scrollView.hide(); - this._triangle.set_text('\u25B8'); + this._manager = new PopupMenu.PopupMenuManager({ actor: this._button }); + this._manager.addMenu(this._menu); - + - this.isOpen = false; - }, + this._button.connect('clicked', Lang.bind(this, function() { + this._menu.toggle(); + })); - + - _onClicked: function() { - if (!this.isOpen) - this.open(); @@ -1554,13 +1554,13 @@ index 4cbb0c9..5557db9 100644 + this._activeSessionId = null; + this._populate(); }, - + updateSensitivity: function(sensitive) { this._button.reactive = sensitive; this._button.can_focus = sensitive; + this._menu.close(BoxPointer.PopupAnimation.NONE); + }, - + - for (let id in this._items) - this._items[id].actor.reactive = sensitive; + _updateOrnament: function() { @@ -1572,21 +1572,21 @@ index 4cbb0c9..5557db9 100644 + this._items[itemIds[i]].setShowDot(false); + } }, - + setActiveSession: function(sessionId) { if (sessionId == this._activeSessionId) return; - + - if (this._activeSessionId) - this._items[this._activeSessionId].setShowDot(false); - - this._items[sessionId].setShowDot(true); this._activeSessionId = sessionId; + this._updateOrnament(); - + this.emit('session-activated', this._activeSessionId); }, - + - _populate: function() { - this._itemList.destroy_all_children(); - this._activeSessionId = null; @@ -1594,11 +1594,11 @@ index 4cbb0c9..5557db9 100644 + close: function() { + this._menu.close(); + }, - + + _populate: function() { let ids = Gdm.get_session_ids(); ids.sort(); - + if (ids.length <= 1) { - this._box.hide(); this._button.hide(); @@ -1607,10 +1607,10 @@ index 4cbb0c9..5557db9 100644 - this._box.show(); + return; } - + for (let i = 0; i < ids.length; i++) { let [sessionName, sessionDescription] = Gdm.get_session_name_and_description(ids[i]); - + - let item = new SessionListItem(ids[i], sessionName); - this._itemList.add_actor(item.actor); - this._items[ids[i]] = item; @@ -1618,11 +1618,11 @@ index 4cbb0c9..5557db9 100644 + let item = new PopupMenu.PopupMenuItem(sessionName); + this._menu.addMenuItem(item); + this._items[id] = item; - + if (!this._activeSessionId) - this.setActiveSession(ids[i]); + this.setActiveSession(id); - + - item.connect('activate', - Lang.bind(this, function() { - this.setActiveSession(item.id); @@ -1635,34 +1635,34 @@ index 4cbb0c9..5557db9 100644 }); -Signals.addSignalMethods(SessionList.prototype); +Signals.addSignalMethods(SessionMenuButton.prototype); - + const LoginDialog = new Lang.Class({ Name: 'LoginDialog', - + _init: function(parentActor) { this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW, style_class: 'login-dialog', visible: false }); - + this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true })); this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); parentActor.add_child(this.actor); - + this._userManager = AccountsService.UserManager.get_default() this._greeterClient = new Gdm.Client(); - + if (GLib.getenv('GDM_GREETER_TEST') != '1') { this._greeter = this._greeterClient.get_greeter_sync(null); - + this._greeter.connect('default-session-name-changed', Lang.bind(this, this._onDefaultSessionChanged)); - + this._greeter.connect('session-opened', Lang.bind(this, this._onSessionOpened)); this._greeter.connect('timed-login-requested', Lang.bind(this, this._onTimedLoginRequested)); } - + this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient); this._userVerifier.connect('ask-question', Lang.bind(this, this._askQuestion)); @@ -559,131 +479,125 @@ const LoginDialog = new Lang.Class({ @@ -1673,7 +1673,7 @@ index 4cbb0c9..5557db9 100644 y_fill: true, expand: true }); this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this._promptBox.add(this._promptLabel, { expand: true, x_fill: true, @@ -1688,14 +1688,14 @@ index 4cbb0c9..5557db9 100644 x_fill: true, y_fill: false, x_align: St.Align.START }); - + this._promptMessage = new St.Label({ visible: false }); this._promptBox.add(this._promptMessage, { x_fill: true }); - + this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' }); this._promptLoginHint.hide(); this._promptBox.add(this._promptLoginHint); - + - this._sessionList = new SessionList(); - this._sessionList.connect('session-activated', - Lang.bind(this, function(list, sessionId) { @@ -1715,9 +1715,9 @@ index 4cbb0c9..5557db9 100644 y_align: St.Align.END }); this._cancelButton = null; this._signInButton = null; - + this._promptBox.hide(); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -1730,15 +1730,15 @@ index 4cbb0c9..5557db9 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn)); this._notListedButton.hide(); - + this._userSelectionBox.add(this._notListedButton, { expand: false, x_align: St.Align.START, x_fill: true }); - + this._logoBin = new St.Bin({ style_class: 'login-dialog-logo-bin', y_expand: true }); this._logoBin.set_y_align(Clutter.ActorAlign.END); this._logoBin.add_constraint(new Clutter.AlignConstraint({ source: this.actor, @@ -1749,7 +1749,7 @@ index 4cbb0c9..5557db9 100644 factor: 1.0 })); this.actor.add_child(this._logoBin); this._updateLogo(); - + if (!this._userManager.is_loaded) this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', Lang.bind(this, function() { @@ -1761,38 +1761,38 @@ index 4cbb0c9..5557db9 100644 })); else this._loadUserList(); - + this._userList.connect('activate', Lang.bind(this, function(userList, item) { this._onUserListActivated(item); })); - + + this._sessionMenuButton = new SessionMenuButton(); + this._sessionMenuButton.connect('session-activated', + Lang.bind(this, function(button, sessionId) { + this._greeter.call_select_session_sync (sessionId, null); + })); }, - + _updateDisableUserList: function() { let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); - + // If this is the first time around, set initial focus if (this._disableUserList == undefined && disableUserList) this.setInitialKeyFocus(this._promptEntry); - + if (disableUserList != this._disableUserList) { this._disableUserList = disableUserList; - + if (!this._verifyingUser) this._reset(); } }, - + _updateBanner: function() { let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); - + if (enabled && text) { this._bannerLabel.set_text(text); this._bannerLabel.show(); @@ -1800,7 +1800,7 @@ index 4cbb0c9..5557db9 100644 this._bannerLabel.hide(); } }, - + _updateLogoTexture: function(cache, uri) { @@ -726,223 +640,224 @@ const LoginDialog = new Lang.Class({ if (working) { @@ -1824,19 +1824,19 @@ index 4cbb0c9..5557db9 100644 }); } }, - + _verificationFailed: function() { this._promptEntry.text = ''; - + this._updateSensitivity(true); this._setWorking(false); }, - + _onDefaultSessionChanged: function(client, sessionId) { - this._sessionList.setActiveSession(sessionId); + this._sessionMenuButton.setActiveSession(sessionId); }, - + _showMessage: function(userVerifier, message, styleClass) { if (message) { this._promptMessage.text = message; @@ -1846,25 +1846,25 @@ index 4cbb0c9..5557db9 100644 this._promptMessage.hide(); } }, - + _showLoginHint: function(verifier, message) { this._promptLoginHint.set_text(message) this._promptLoginHint.show(); this._promptLoginHint.opacity = 255; }, - + _hideLoginHint: function() { this._promptLoginHint.hide(); this._promptLoginHint.set_text(''); }, - + cancel: function() { if (this._verifyingUser) this._userVerifier.cancel(); else this._reset(); }, - + _showPrompt: function(forSecret) { - this._sessionList.actor.hide(); + this._sessionMenuButton.actor.hide(); @@ -1878,30 +1878,30 @@ index 4cbb0c9..5557db9 100644 { opacity: 255, time: _FADE_ANIMATION_TIME, transition: 'easeOutQuad' }); - + if ((this._user && !this._user.is_logged_in()) || this._verifyingUser) - this._sessionList.actor.show(); + this._sessionMenuButton.actor.show(); - + this._promptEntry.grab_key_focus(); - + let hold = new Batch.Hold(); let tasks = [function() { this._prepareDialog(forSecret, hold); }, - + hold]; - + let batch = new Batch.ConcurrentBatch(this, tasks); - + return batch.run(); }, - + _prepareDialog: function(forSecret, hold) { this._buttonBox.visible = true; - this._buttonBox.destroy_all_children(); + this._buttonBox.remove_all_children(); - + if (!this._disableUserList || this._verifyingUser) { this._cancelButton = new St.Button({ style_class: 'modal-dialog-button', button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, @@ -1919,16 +1919,16 @@ index 4cbb0c9..5557db9 100644 x_align: St.Align.START, y_align: St.Align.END }); } - + let spinnerIcon = global.datadir + '/theme/process-working.svg'; this._workSpinner = new Panel.AnimatedIcon(spinnerIcon, _WORK_SPINNER_ICON_SIZE); this._workSpinner.actor.opacity = 0; this._workSpinner.actor.show(); - + this._buttonBox.add(this._workSpinner.actor, { expand: false, x_align: St.Align.END }); - + + this._buttonBox.add(this._sessionMenuButton.actor, + { expand: false, + x_align: St.Align.END }); @@ -1948,21 +1948,21 @@ index 4cbb0c9..5557db9 100644 y_fill: false, x_align: St.Align.END, y_align: St.Align.END }); - + this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0); - + this._promptEntryTextChangedId = this._promptEntry.clutter_text.connect('text-changed', Lang.bind(this, function() { this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0); })); - + this._promptEntryActivateId = this._promptEntry.clutter_text.connect('activate', function() { hold.release(); }); }, - + _updateSensitivity: function(sensitive) { this._promptEntry.reactive = sensitive; this._promptEntry.clutter_text.editable = sensitive; @@ -1970,14 +1970,14 @@ index 4cbb0c9..5557db9 100644 + this._sessionMenuButton.updateSensitivity(sensitive); this._updateSignInButtonSensitivity(sensitive); }, - + _updateSignInButtonSensitivity: function(sensitive) { if (this._signInButton) { this._signInButton.reactive = sensitive; this._signInButton.can_focus = sensitive; } }, - + _hidePrompt: function() { - this._buttonBox.destroy_all_children(); - @@ -1985,65 +1985,65 @@ index 4cbb0c9..5557db9 100644 this._promptEntry.clutter_text.disconnect(this._promptEntryTextChangedId); this._promptEntryTextChangedId = 0; } - + if (this._promptEntryActivateId > 0) { this._promptEntry.clutter_text.disconnect(this._promptEntryActivateId); this._promptEntryActivateId = 0; } - + this._setWorking(false); this._promptBox.hide(); this._promptLoginHint.hide(); - + this._promptUser.set_child(null); - + this._updateSensitivity(true); this._promptEntry.set_text(''); - + - this._sessionList.close(); + this._sessionMenuButton.close(); this._promptLoginHint.hide(); - + - this._buttonBox.destroy_all_children(); + this._buttonBox.remove_all_children(); this._signInButton = null; this._cancelButton = null; }, - + _askQuestion: function(verifier, serviceName, question, passwordChar) { this._promptLabel.set_text(question); - + this._updateSensitivity(true); this._promptEntry.set_text(''); this._promptEntry.clutter_text.set_password_char(passwordChar); - + let tasks = [function() { return this._showPrompt(!!passwordChar); }, - + function() { let text = this._promptEntry.get_text(); this._updateSensitivity(false); this._setWorking(true); this._userVerifier.answerQuery(serviceName, text); }]; - + let batch = new Batch.ConsecutiveBatch(this, tasks); return batch.run(); }, - + _showRealmLoginHint: function(realmManager, hint) { if (!hint) return; - --- + +-- 1.8.3.1 -From c06890a9aa0da2690422285f894a422c4d1780fa Mon Sep 17 00:00:00 2001 +From 4c0d3a19e59d556158cfdb4c58dc31b501d9a9e2 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 25 Jun 2013 13:35:38 -0400 -Subject: [PATCH 05/66] loginDialog: make spinner and session menu button share +Subject: [PATCH 05/69] loginDialog: make spinner and session menu button share position They never need to be shown at the same time, and the design has @@ -2061,7 +2061,7 @@ index 5557db9..f127460 100644 --- a/js/gdm/loginDialog.js +++ b/js/gdm/loginDialog.js @@ -20,68 +20,74 @@ - + const AccountsService = imports.gi.AccountsService; const Atk = imports.gi.Atk; const Clutter = imports.gi.Clutter; @@ -2075,7 +2075,7 @@ index 5557db9..f127460 100644 const Shell = imports.gi.Shell; const Signals = imports.signals; const St = imports.gi.St; - + const Panel = imports.ui.panel; const Batch = imports.gdm.batch; const BoxPointer = imports.ui.boxpointer; @@ -2088,7 +2088,7 @@ index 5557db9..f127460 100644 const Tweener = imports.ui.tweener; const UserMenu = imports.ui.userMenu; const UserWidget = imports.ui.userWidget; - + const _FADE_ANIMATION_TIME = 0.25; const _SCROLL_ANIMATION_TIME = 0.5; -const _WORK_SPINNER_ICON_SIZE = 24; @@ -2099,9 +2099,9 @@ index 5557db9..f127460 100644 +const _DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0; const _LOGO_ICON_HEIGHT = 48; - + let _loginDialog = null; - + +const DefaultButtonWellMode = { + NONE: 0, + SESSION_MENU_BUTTON: 1, @@ -2110,12 +2110,12 @@ index 5557db9..f127460 100644 + const UserListItem = new Lang.Class({ Name: 'UserListItem', - + _init: function(user) { this.user = user; this._userChangedId = this.user.connect('changed', Lang.bind(this, this._onUserChanged)); - + let layout = new St.BoxLayout({ vertical: false }); this.actor = new St.Button({ style_class: 'login-dialog-user-list-item', button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, @@ -2124,14 +2124,14 @@ index 5557db9..f127460 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._userAvatar = new UserMenu.UserAvatarWidget(this.user, { styleClass: 'login-dialog-user-list-item-icon' }); layout.add(this._userAvatar.actor); let textLayout = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-text-box', vertical: true }); layout.add(textLayout, { expand: true }); - + this._nameLabel = new St.Label({ style_class: 'login-dialog-user-list-item-name' }); this.actor.label_actor = this._nameLabel; textLayout.add(this._nameLabel, @@ -2140,7 +2140,7 @@ index 5557db9..f127460 100644 expand: true }); @@ -539,65 +545,81 @@ const LoginDialog = new Lang.Class({ x_fill: true }); - + this._logoBin = new St.Bin({ style_class: 'login-dialog-logo-bin', y_expand: true }); this._logoBin.set_y_align(Clutter.ActorAlign.END); this._logoBin.add_constraint(new Clutter.AlignConstraint({ source: this.actor, @@ -2151,7 +2151,7 @@ index 5557db9..f127460 100644 factor: 1.0 })); this.actor.add_child(this._logoBin); this._updateLogo(); - + if (!this._userManager.is_loaded) this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', Lang.bind(this, function() { @@ -2163,12 +2163,12 @@ index 5557db9..f127460 100644 })); else this._loadUserList(); - + this._userList.connect('activate', Lang.bind(this, function(userList, item) { this._onUserListActivated(item); })); - + + this._defaultButtonWell = new St.Widget(); + this._defaultButtonWellMode = DefaultButtonWellMode.NONE; + @@ -2194,26 +2194,26 @@ index 5557db9..f127460 100644 + align_axis: Clutter.AlignAxis.BOTH, + factor: 0.5 })); }, - + _updateDisableUserList: function() { let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); - + // If this is the first time around, set initial focus if (this._disableUserList == undefined && disableUserList) this.setInitialKeyFocus(this._promptEntry); - + if (disableUserList != this._disableUserList) { this._disableUserList = disableUserList; - + if (!this._verifyingUser) this._reset(); } }, - + _updateBanner: function() { let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); - + if (enabled && text) { this._bannerLabel.set_text(text); this._bannerLabel.show(); @@ -2221,39 +2221,39 @@ index 5557db9..f127460 100644 this._bannerLabel.hide(); } }, - + _updateLogoTexture: function(cache, uri) { @@ -605,278 +627,321 @@ const LoginDialog = new Lang.Class({ return; - + let icon = null; if (this._logoFileUri) icon = this._textureCache.load_uri_async(this._logoFileUri, -1, _LOGO_ICON_HEIGHT); this._logoBin.set_child(icon); }, - + _updateLogo: function() { let path = this._settings.get_string(GdmUtil.LOGO_KEY); - + this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; this._updateLogoTexture(this._textureCache, this._logoFileUri); }, - + _reset: function() { this._userVerifier.clear(); - + this._updateSensitivity(true); this._promptMessage.hide(); this._user = null; this._verifyingUser = false; - + if (this._disableUserList) this._hideUserListAndLogIn(); else this._showUserList(); }, - + - _setWorking: function(working) { - if (!this._workSpinner) + _getActorForDefaultButtonWellMode: function(mode) { @@ -2273,7 +2273,7 @@ index 5557db9..f127460 100644 + if (this._defaultButtonWellMode == DefaultButtonWellMode.NONE && + mode == DefaultButtonWellMode.NONE) return; - + - Tweener.removeTweens(this._workSpinner.actor); - if (working) { - this._workSpinner.play(); @@ -2337,19 +2337,19 @@ index 5557db9..f127460 100644 + + this._defaultButtonWellMode = mode; }, - + _verificationFailed: function() { this._promptEntry.text = ''; - + this._updateSensitivity(true); - this._setWorking(false); + this._setDefaultButtonWellMode(DefaultButtonWellMode.NONE, true); }, - + _onDefaultSessionChanged: function(client, sessionId) { this._sessionMenuButton.setActiveSession(sessionId); }, - + _showMessage: function(userVerifier, message, styleClass) { if (message) { this._promptMessage.text = message; @@ -2359,25 +2359,25 @@ index 5557db9..f127460 100644 this._promptMessage.hide(); } }, - + _showLoginHint: function(verifier, message) { this._promptLoginHint.set_text(message) this._promptLoginHint.show(); this._promptLoginHint.opacity = 255; }, - + _hideLoginHint: function() { this._promptLoginHint.hide(); this._promptLoginHint.set_text(''); }, - + cancel: function() { if (this._verifyingUser) this._userVerifier.cancel(); else this._reset(); }, - + + _shouldShowSessionMenuButton: function() { + if (this._verifyingUser) + return true; @@ -2403,32 +2403,32 @@ index 5557db9..f127460 100644 { opacity: 255, time: _FADE_ANIMATION_TIME, transition: 'easeOutQuad' }); - + - if ((this._user && !this._user.is_logged_in()) || this._verifyingUser) - this._sessionMenuButton.actor.show(); + if (this._shouldShowSessionMenuButton()) + this._setDefaultButtonWellMode(DefaultButtonWellMode.SESSION_MENU_BUTTON, true); + else + this._setDefaultButtonWellMode(DefaultButtonWellMode.NONE, true); - + this._promptEntry.grab_key_focus(); - + let hold = new Batch.Hold(); let tasks = [function() { this._prepareDialog(forSecret, hold); }, - + hold]; - + let batch = new Batch.ConcurrentBatch(this, tasks); - + return batch.run(); }, - + _prepareDialog: function(forSecret, hold) { this._buttonBox.visible = true; this._buttonBox.remove_all_children(); - + if (!this._disableUserList || this._verifyingUser) { this._cancelButton = new St.Button({ style_class: 'modal-dialog-button', button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, @@ -2447,7 +2447,7 @@ index 5557db9..f127460 100644 x_align: St.Align.START, y_align: St.Align.END }); } - + - let spinnerIcon = global.datadir + '/theme/process-working.svg'; - this._workSpinner = new Panel.AnimatedIcon(spinnerIcon, _WORK_SPINNER_ICON_SIZE); - this._workSpinner.actor.opacity = 0; @@ -2483,75 +2483,75 @@ index 5557db9..f127460 100644 y_fill: false, x_align: St.Align.END, y_align: St.Align.END }); - + this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0); - + this._promptEntryTextChangedId = this._promptEntry.clutter_text.connect('text-changed', Lang.bind(this, function() { this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0); })); - + this._promptEntryActivateId = this._promptEntry.clutter_text.connect('activate', function() { hold.release(); }); }, - + _updateSensitivity: function(sensitive) { this._promptEntry.reactive = sensitive; this._promptEntry.clutter_text.editable = sensitive; this._sessionMenuButton.updateSensitivity(sensitive); this._updateSignInButtonSensitivity(sensitive); }, - + _updateSignInButtonSensitivity: function(sensitive) { if (this._signInButton) { this._signInButton.reactive = sensitive; this._signInButton.can_focus = sensitive; } }, - + _hidePrompt: function() { if (this._promptEntryTextChangedId > 0) { this._promptEntry.clutter_text.disconnect(this._promptEntryTextChangedId); this._promptEntryTextChangedId = 0; } - + if (this._promptEntryActivateId > 0) { this._promptEntry.clutter_text.disconnect(this._promptEntryActivateId); this._promptEntryActivateId = 0; } - + - this._setWorking(false); + this._setDefaultButtonWellMode(DefaultButtonWellMode.NONE, true); this._promptBox.hide(); this._promptLoginHint.hide(); - + this._promptUser.set_child(null); - + this._updateSensitivity(true); this._promptEntry.set_text(''); - + this._sessionMenuButton.close(); this._promptLoginHint.hide(); - + this._buttonBox.remove_all_children(); this._signInButton = null; this._cancelButton = null; }, - + _askQuestion: function(verifier, serviceName, question, passwordChar) { this._promptLabel.set_text(question); - + this._updateSensitivity(true); this._promptEntry.set_text(''); this._promptEntry.clutter_text.set_password_char(passwordChar); - + let tasks = [function() { return this._showPrompt(!!passwordChar); }, - + function() { let text = this._promptEntry.get_text(); this._updateSensitivity(false); @@ -2559,42 +2559,42 @@ index 5557db9..f127460 100644 + this._setDefaultButtonWellMode(DefaultButtonWellMode.SPINNER, false); this._userVerifier.answerQuery(serviceName, text); }]; - + let batch = new Batch.ConsecutiveBatch(this, tasks); return batch.run(); }, - + _showRealmLoginHint: function(realmManager, hint) { if (!hint) return; - + hint = hint.replace(/%U/g, 'user'); hint = hint.replace(/%D/g, 'DOMAIN'); hint = hint.replace(/%[^UD]/g, ''); - + // Translators: this message is shown below the username entry field // to clue the user in on how to login to the local network realm this._showLoginHint(null, _("(e.g., user or %s)").format(hint)); }, - + _askForUsernameAndLogIn: function() { this._promptLabel.set_text(_("Username: ")); this._promptEntry.set_text(''); this._promptEntry.clutter_text.set_password_char(''); - + let realmManager = new Realmd.Manager(); let signalId = realmManager.connect('login-format-changed', - Lang.bind(this, this._showRealmLoginHint)); + Lang.bind(this, this._showRealmLoginHint)); this._showRealmLoginHint(realmManager.loginFormat); - --- + +-- 1.8.3.1 -From 4d225c2d2043762a345415b0438b6a92900410eb Mon Sep 17 00:00:00 2001 +From b9a4dfe6cc5056a2a0f81c20a28574e65e993684 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 9 Jul 2013 10:05:55 -0400 -Subject: [PATCH 06/66] loginDialog: don't call nonexistent setInitialKeyFocus +Subject: [PATCH 06/69] loginDialog: don't call nonexistent setInitialKeyFocus function commit ea02380c1524c28e6538ffedb789a12c298742ab changed the login @@ -2615,7 +2615,7 @@ index f127460..9f90664 100644 +++ b/js/gdm/loginDialog.js @@ -478,60 +478,62 @@ const LoginDialog = new Lang.Class({ })); - + this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); @@ -2628,7 +2628,7 @@ index f127460..9f90664 100644 y_fill: true, expand: true }); this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this._promptBox.add(this._promptLabel, { expand: true, x_fill: true, @@ -2643,16 +2643,16 @@ index f127460..9f90664 100644 x_fill: true, y_fill: false, x_align: St.Align.START }); - + + this._promptEntry.grab_key_focus(); + this._promptMessage = new St.Label({ visible: false }); this._promptBox.add(this._promptMessage, { x_fill: true }); - + this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' }); this._promptLoginHint.hide(); this._promptBox.add(this._promptLoginHint); - + this._buttonBox = new St.BoxLayout({ style_class: 'modal-dialog-button-box', vertical: false }); this._promptBox.add(this._buttonBox, @@ -2661,9 +2661,9 @@ index f127460..9f90664 100644 y_align: St.Align.END }); this._cancelButton = null; this._signInButton = null; - + this._promptBox.hide(); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -2680,10 +2680,10 @@ index f127460..9f90664 100644 Lang.bind(this, function(userList, item) { this._onUserListActivated(item); })); - + this._defaultButtonWell = new St.Widget(); this._defaultButtonWellMode = DefaultButtonWellMode.NONE; - + this._sessionMenuButton = new SessionMenuButton(); this._sessionMenuButton.connect('session-activated', Lang.bind(this, function(list, sessionId) { @@ -2692,37 +2692,37 @@ index f127460..9f90664 100644 this._sessionMenuButton.actor.opacity = 0; this._sessionMenuButton.actor.show(); this._defaultButtonWell.add_child(this._sessionMenuButton.actor); - + let spinnerIcon = global.datadir + '/theme/process-working.svg'; this._workSpinner = new Panel.AnimatedIcon(spinnerIcon, _DEFAULT_BUTTON_WELL_ICON_SIZE); this._workSpinner.actor.opacity = 0; this._workSpinner.actor.show(); - + this._defaultButtonWell.add_child(this._workSpinner.actor); this._sessionMenuButton.actor.add_constraint(new Clutter.AlignConstraint({ source: this._workSpinner.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); }, - + _updateDisableUserList: function() { let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); - + - // If this is the first time around, set initial focus - if (this._disableUserList == undefined && disableUserList) - this.setInitialKeyFocus(this._promptEntry); - if (disableUserList != this._disableUserList) { this._disableUserList = disableUserList; - + if (!this._verifyingUser) this._reset(); } }, - + _updateBanner: function() { let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); - + if (enabled && text) { this._bannerLabel.set_text(text); this._bannerLabel.show(); @@ -2730,25 +2730,25 @@ index f127460..9f90664 100644 this._bannerLabel.hide(); } }, - + _updateLogoTexture: function(cache, uri) { if (this._logoFileUri != uri) return; - + let icon = null; if (this._logoFileUri) icon = this._textureCache.load_uri_async(this._logoFileUri, -1, _LOGO_ICON_HEIGHT); this._logoBin.set_child(icon); }, --- +-- 1.8.3.1 -From 08b95ec01004a822bb456766797f7cae4e358340 Mon Sep 17 00:00:00 2001 +From a758d6e837f5a99dd2b1507d92c40d7dd09d7bdd Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 19 Jun 2013 12:56:23 -0400 -Subject: [PATCH 07/66] loginDialog: pre-allocate prompt message height +Subject: [PATCH 07/69] loginDialog: pre-allocate prompt message height Right now things jump around if a message comes in. This commit makes sure there's room for a message to start. @@ -2775,7 +2775,7 @@ index 9f90664..538364c 100644 y_fill: true, expand: true }); this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this._promptBox.add(this._promptLabel, { expand: true, x_fill: true, @@ -2790,17 +2790,17 @@ index 9f90664..538364c 100644 x_fill: true, y_fill: false, x_align: St.Align.START }); - + this._promptEntry.grab_key_focus(); - + - this._promptMessage = new St.Label({ visible: false }); + this._promptMessage = new St.Label({ opacity: 0 }); this._promptBox.add(this._promptMessage, { x_fill: true }); - + this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' }); - this._promptLoginHint.hide(); this._promptBox.add(this._promptLoginHint); - + this._buttonBox = new St.BoxLayout({ style_class: 'modal-dialog-button-box', vertical: false }); this._promptBox.add(this._buttonBox, @@ -2809,9 +2809,9 @@ index 9f90664..538364c 100644 y_align: St.Align.END }); this._cancelButton = null; this._signInButton = null; - + this._promptBox.hide(); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -2824,10 +2824,10 @@ index 9f90664..538364c 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn)); this._notListedButton.hide(); - + this._userSelectionBox.add(this._notListedButton, @@ -615,61 +614,61 @@ const LoginDialog = new Lang.Class({ if (enabled && text) { @@ -2837,64 +2837,64 @@ index 9f90664..538364c 100644 this._bannerLabel.hide(); } }, - + _updateLogoTexture: function(cache, uri) { if (this._logoFileUri != uri) return; - + let icon = null; if (this._logoFileUri) icon = this._textureCache.load_uri_async(this._logoFileUri, -1, _LOGO_ICON_HEIGHT); this._logoBin.set_child(icon); }, - + _updateLogo: function() { let path = this._settings.get_string(GdmUtil.LOGO_KEY); - + this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; this._updateLogoTexture(this._textureCache, this._logoFileUri); }, - + _reset: function() { this._userVerifier.clear(); - + this._updateSensitivity(true); - this._promptMessage.hide(); + this._promptMessage.opacity = 0; this._user = null; this._verifyingUser = false; - + if (this._disableUserList) this._hideUserListAndLogIn(); else this._showUserList(); }, - + _getActorForDefaultButtonWellMode: function(mode) { let actor; - + if (mode == DefaultButtonWellMode.NONE) actor = null; else if (mode == DefaultButtonWellMode.SPINNER) actor = this._workSpinner.actor; else if (mode == DefaultButtonWellMode.SESSION_MENU_BUTTON) actor = this._sessionMenuButton.actor; - + return actor; }, - + _setDefaultButtonWellMode: function(mode, immediately) { if (this._defaultButtonWellMode == DefaultButtonWellMode.NONE && mode == DefaultButtonWellMode.NONE) return; - + let oldActor = this._getActorForDefaultButtonWellMode(this._defaultButtonWellMode); - + if (oldActor) @@ -702,74 +701,73 @@ const LoginDialog = new Lang.Class({ this._workSpinner.play(); - + if (immediately) actor.opacity = 255; else @@ -2904,21 +2904,21 @@ index 9f90664..538364c 100644 delay: _DEFAULT_BUTTON_WELL_ANIMATION_DELAY, transition: 'linear' }); } - + this._defaultButtonWellMode = mode; }, - + _verificationFailed: function() { this._promptEntry.text = ''; - + this._updateSensitivity(true); this._setDefaultButtonWellMode(DefaultButtonWellMode.NONE, true); }, - + _onDefaultSessionChanged: function(client, sessionId) { this._sessionMenuButton.setActiveSession(sessionId); }, - + _showMessage: function(userVerifier, message, styleClass) { if (message) { this._promptMessage.text = message; @@ -2930,39 +2930,39 @@ index 9f90664..538364c 100644 + this._promptMessage.opacity = 0; } }, - + _showLoginHint: function(verifier, message) { this._promptLoginHint.set_text(message) - this._promptLoginHint.show(); this._promptLoginHint.opacity = 255; }, - + _hideLoginHint: function() { - this._promptLoginHint.hide(); + this._promptLoginHint.opacity = 0; this._promptLoginHint.set_text(''); }, - + cancel: function() { if (this._verifyingUser) this._userVerifier.cancel(); else this._reset(); }, - + _shouldShowSessionMenuButton: function() { if (this._verifyingUser) return true; - + if (!this._user) return false; - + if (this._user.is_logged_in) return false; - + return true; }, - + _showPrompt: function(forSecret) { this._promptLabel.show(); this._promptEntry.show(); @@ -2973,83 +2973,83 @@ index 9f90664..538364c 100644 @@ -856,69 +854,69 @@ const LoginDialog = new Lang.Class({ }); }, - + _updateSensitivity: function(sensitive) { this._promptEntry.reactive = sensitive; this._promptEntry.clutter_text.editable = sensitive; this._sessionMenuButton.updateSensitivity(sensitive); this._updateSignInButtonSensitivity(sensitive); }, - + _updateSignInButtonSensitivity: function(sensitive) { if (this._signInButton) { this._signInButton.reactive = sensitive; this._signInButton.can_focus = sensitive; } }, - + _hidePrompt: function() { if (this._promptEntryTextChangedId > 0) { this._promptEntry.clutter_text.disconnect(this._promptEntryTextChangedId); this._promptEntryTextChangedId = 0; } - + if (this._promptEntryActivateId > 0) { this._promptEntry.clutter_text.disconnect(this._promptEntryActivateId); this._promptEntryActivateId = 0; } - + this._setDefaultButtonWellMode(DefaultButtonWellMode.NONE, true); this._promptBox.hide(); - this._promptLoginHint.hide(); + this._promptLoginHint.opacity = 0; - + this._promptUser.set_child(null); - + this._updateSensitivity(true); this._promptEntry.set_text(''); - + this._sessionMenuButton.close(); - this._promptLoginHint.hide(); + this._promptLoginHint.opacity = 0; - + this._buttonBox.remove_all_children(); this._signInButton = null; this._cancelButton = null; }, - + _askQuestion: function(verifier, serviceName, question, passwordChar) { this._promptLabel.set_text(question); - + this._updateSensitivity(true); this._promptEntry.set_text(''); this._promptEntry.clutter_text.set_password_char(passwordChar); - + let tasks = [function() { return this._showPrompt(!!passwordChar); }, - + function() { let text = this._promptEntry.get_text(); this._updateSensitivity(false); this._setDefaultButtonWellMode(DefaultButtonWellMode.SPINNER, false); this._userVerifier.answerQuery(serviceName, text); }]; - + let batch = new Batch.ConsecutiveBatch(this, tasks); return batch.run(); }, - + _showRealmLoginHint: function(realmManager, hint) { if (!hint) --- +-- 1.8.3.1 -From a4efe892b4cdbabaaca1f0326627183906a4b760 Mon Sep 17 00:00:00 2001 +From b0d83be8ac98f254796dfca3eb0777a445727441 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 19 Jun 2013 09:23:14 -0400 -Subject: [PATCH 08/66] loginDialog: drop padding between buttons and entry +Subject: [PATCH 08/69] loginDialog: drop padding between buttons and entry Now that we preallocate space for the prompt message there is a lot of loose space between the entry and the buttons. @@ -3064,11 +3064,11 @@ https://bugzilla.gnome.org/show_bug.cgi?id=702308 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css -index 4c0a795..d871385 100644 +index 9f9830a..2a1fe1d 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css -@@ -2210,60 +2210,64 @@ StScrollBar StButton#vhandle:active { - +@@ -2215,60 +2215,64 @@ StScrollBar StButton#vhandle:active { + .login-dialog-banner { font-size: 10pt; font-weight: bold; @@ -3076,28 +3076,28 @@ index 4c0a795..d871385 100644 color: #666666; padding-bottom: 1em; } - + .login-dialog-title { font-size: 14pt; font-weight: bold; color: #666666; padding-bottom: 2em; } - + .login-dialog { /* Reset border and background */ border: none; background-color: transparent; - + padding-bottom: 80px; padding-top: 80px; - + border-radius: 16px; min-height: 150px; max-height: 700px; min-width: 350px; } - + +.login-dialog-button-box { + spacing: 5px; +} @@ -3105,29 +3105,29 @@ index 4c0a795..d871385 100644 .login-dialog-prompt-login-hint-message { font-size: 10.5pt; } - + .login-dialog-user-list-view { -st-vfade-offset: 1em; } - + .login-dialog-user-list { spacing: 12px; padding: .2em; } - + .login-dialog-user-list-item { border-radius: 10px; padding: .2em; } - + .login-dialog-user-list-item:ltr { padding-right: 1em; } - + .login-dialog-user-list-item:rtl { padding-left: 1em; } - + .login-dialog-user-list-item .login-dialog-user-list-item-name { font-size: 20pt; padding-left: 1em; @@ -3143,7 +3143,7 @@ index 538364c..365b45f 100644 y_fill: true, expand: true }); this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this._promptBox.add(this._promptLabel, { expand: true, x_fill: true, @@ -3158,15 +3158,15 @@ index 538364c..365b45f 100644 x_fill: true, y_fill: false, x_align: St.Align.START }); - + this._promptEntry.grab_key_focus(); - + this._promptMessage = new St.Label({ opacity: 0 }); this._promptBox.add(this._promptMessage, { x_fill: true }); - + this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' }); this._promptBox.add(this._promptLoginHint); - + - this._buttonBox = new St.BoxLayout({ style_class: 'modal-dialog-button-box', + this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box', vertical: false }); @@ -3176,9 +3176,9 @@ index 538364c..365b45f 100644 y_align: St.Align.END }); this._cancelButton = null; this._signInButton = null; - + this._promptBox.hide(); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -3191,22 +3191,22 @@ index 538364c..365b45f 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn)); this._notListedButton.hide(); - + this._userSelectionBox.add(this._notListedButton, { expand: false, x_align: St.Align.START, x_fill: true }); --- +-- 1.8.3.1 -From ea249fd9f79acf123f3603aa2f21369c99e98e8f Mon Sep 17 00:00:00 2001 +From 53cc7380b0945166cf3c27c1f5751289e69d0bd7 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 26 Jun 2013 22:32:07 -0400 -Subject: [PATCH 09/66] loginDialog: make prompt entry wider +Subject: [PATCH 09/69] loginDialog: make prompt entry wider This makes it match mock ups better and looks more visually pleasing. @@ -3217,20 +3217,20 @@ https://bugzilla.gnome.org/show_bug.cgi?id=702308 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css -index d871385..14ee74e 100644 +index 2a1fe1d..c42c19e 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css -@@ -2323,61 +2323,61 @@ StScrollBar StButton#vhandle:active { +@@ -2328,61 +2328,61 @@ StScrollBar StButton#vhandle:active { color: #666666; padding-top: 1em; padding-left: 2px; } - + .login-dialog-not-listed-button:focus .login-dialog-not-listed-label, .login-dialog-not-listed-button:hover .login-dialog-not-listed-label { color: #E8E8E8; } - + .login-dialog-username { font-size: 16pt; font-weight: bold; @@ -3238,59 +3238,59 @@ index d871385..14ee74e 100644 padding-left: 15px; text-shadow: black 0px 4px 3px 0px; } - + .login-dialog-prompt-layout { padding-top: 24px; padding-bottom: 12px; spacing: 8px; } - + .login-dialog-prompt-label { color: #eeeeee; font-size: 14px; } - + .login-dialog-prompt-entry { - width: 15em; + width: 20em; } - + .login-dialog-session-list-button StIcon { icon-size: 1.25em; } - + .login-dialog-session-list-button { color: #8b8b8b; } - + .login-dialog-session-list-button:hover, .login-dialog-session-list-button:active { color: white; } - + .login-dialog-logo-bin { padding: 24px 0px; } - + .login-dialog .modal-dialog-button-box { spacing: 3px; } - + .login-dialog .modal-dialog-button { border-radius: 5px; padding: 3px 18px; } - + .login-dialog .modal-dialog-button:focus { padding: 2px 17px; --- +-- 1.8.3.1 -From d42742e678ac9b1fd26ac923b96750af01ff3987 Mon Sep 17 00:00:00 2001 +From 21ab83972347f2ca1f3c44c014ed7514c7d25580 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 26 Jun 2013 12:36:10 -0400 -Subject: [PATCH 10/66] loginDialog: force user list and prompt to be the same +Subject: [PATCH 10/69] loginDialog: force user list and prompt to be the same width --- @@ -3307,28 +3307,28 @@ index 365b45f..15a2e0a 100644 align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); this.actor.add_child(this._userSelectionBox); - + this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', text: '' }); this._userSelectionBox.add(this._bannerLabel); this._updateBanner(); - + this._userList = new UserList(); this._userSelectionBox.add(this._userList.actor, { expand: true, x_fill: true, y_fill: true }); - + this._promptBox = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout', vertical: true }); - + this._promptBox.connect('button-press-event', Lang.bind(this, function(actor, event) { if (event.get_key_symbol() == Clutter.KEY_Escape) { this.cancel(); } })); - + this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); @@ -3345,7 +3345,7 @@ index 365b45f..15a2e0a 100644 y_fill: true, expand: true }); this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this._promptBox.add(this._promptLabel, { expand: true, x_fill: true, @@ -3360,21 +3360,21 @@ index 365b45f..15a2e0a 100644 x_fill: true, y_fill: false, x_align: St.Align.START }); - + this._promptEntry.grab_key_focus(); - + this._promptMessage = new St.Label({ opacity: 0 }); this._promptBox.add(this._promptMessage, { x_fill: true }); - + this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' }); --- +-- 1.8.3.1 -From d593c99700fda79b4e43822f6c50294472e61107 Mon Sep 17 00:00:00 2001 +From d899057a7d0b9326dcaede62b88711fbff3a1e15 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 16 Jul 2013 15:48:27 -0400 -Subject: [PATCH 11/66] util: Fix hasPendingMessages +Subject: [PATCH 11/69] util: Fix hasPendingMessages While the UserVerifier does indeed have a _userVerifier inside it, the hasPendingMessages property is on ourselves, not @@ -3396,29 +3396,29 @@ index cae3e1b..c79958d 100644 this._client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot)); } }, - + cancel: function() { if (this._cancellable) this._cancellable.cancel(); - + if (this._userVerifier) this._userVerifier.call_cancel_sync(null); }, - + clear: function() { if (this._cancellable) { this._cancellable.cancel(); this._cancellable = null; } - + if (this._userVerifier) { this._userVerifier.run_dispose(); this._userVerifier = null; } - + this._clearMessageQueue(); }, - + answerQuery: function(serviceName, answer) { - if (!this._userVerifier.hasPendingMessages) { + if (!this.hasPendingMessages) { @@ -3432,22 +3432,22 @@ index cae3e1b..c79958d 100644 })); } }, - + _getIntervalForMessage: function(message) { // We probably could be smarter here return message.length * USER_READ_TIME; }, - + finishMessageQueue: function() { if (!this.hasPendingMessages) return; - + this._messageQueue = []; - + this.hasPendingMessages = false; this.emit('no-more-messages'); }, - + _queueMessageTimeout: function() { if (this._messageQueue.length == 0) { this.finishMessageQueue(); @@ -3455,33 +3455,33 @@ index cae3e1b..c79958d 100644 @@ -396,66 +396,66 @@ const ShellUserVerifier = new Lang.Class({ // Clear previous attempts to authenticate this._failCounter = 0; - + this.emit('reset'); }, - + _onVerificationComplete: function() { this.emit('verification-complete'); }, - + _cancelAndReset: function() { this.cancel(); this._onReset(); }, - + _retry: function() { this.begin(this._userName, new Batch.Hold()); }, - + _verificationFailed: function(retry) { // For Not Listed / enterprise logins, immediately reset // the dialog // Otherwise, we allow ALLOWED_FAILURES attempts. After that, we // go back to the welcome screen. - + this._failCounter++; let canRetry = retry && this._userName && this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY); - + if (canRetry) { - if (!this._userVerifier.hasPendingMessages) { + if (!this.hasPendingMessages) { @@ -3505,10 +3505,10 @@ index cae3e1b..c79958d 100644 })); } } - + this.emit('verification-failed'); }, - + _onConversationStopped: function(client, serviceName) { // if the password service fails, then cancel everything. // But if, e.g., fingerprint fails, still give @@ -3516,19 +3516,19 @@ index cae3e1b..c79958d 100644 if (serviceName == PASSWORD_SERVICE_NAME) { this._verificationFailed(true); } - + this.emit('hide-login-hint'); }, }); Signals.addSignalMethods(ShellUserVerifier.prototype); --- +-- 1.8.3.1 -From 2f36ddcf43154fc68b7a6e115ca4ff708a59348f Mon Sep 17 00:00:00 2001 +From 4f31c7e209346ef4cbd2e5d833eea1250b29e165 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 17 Jul 2013 13:06:10 -0400 -Subject: [PATCH 12/66] util: Fix no-more-messages signal +Subject: [PATCH 12/69] util: Fix no-more-messages signal Now thas hasPendingMessages is fixed, we need to also fix the associated signal "no-more-messages" @@ -3545,29 +3545,29 @@ index c79958d..04b2d49 100644 @@ -140,65 +140,65 @@ const ShellUserVerifier = new Lang.Class({ } }, - + cancel: function() { if (this._cancellable) this._cancellable.cancel(); - + if (this._userVerifier) this._userVerifier.call_cancel_sync(null); }, - + clear: function() { if (this._cancellable) { this._cancellable.cancel(); this._cancellable = null; } - + if (this._userVerifier) { this._userVerifier.run_dispose(); this._userVerifier = null; } - + this._clearMessageQueue(); }, - + answerQuery: function(serviceName, answer) { if (!this.hasPendingMessages) { this._clearMessageQueue(); @@ -3585,61 +3585,61 @@ index c79958d..04b2d49 100644 + })); } }, - + _getIntervalForMessage: function(message) { // We probably could be smarter here return message.length * USER_READ_TIME; }, - + finishMessageQueue: function() { if (!this.hasPendingMessages) return; - + this._messageQueue = []; - + this.hasPendingMessages = false; this.emit('no-more-messages'); }, - + _queueMessageTimeout: function() { if (this._messageQueue.length == 0) { this.finishMessageQueue(); return; } - + if (this._messageQueueTimeoutId != 0) return; - + let message = this._messageQueue.shift(); this.emit('show-message', message.text, message.iconName); - + @@ -399,63 +399,63 @@ const ShellUserVerifier = new Lang.Class({ this.emit('reset'); }, - + _onVerificationComplete: function() { this.emit('verification-complete'); }, - + _cancelAndReset: function() { this.cancel(); this._onReset(); }, - + _retry: function() { this.begin(this._userName, new Batch.Hold()); }, - + _verificationFailed: function(retry) { // For Not Listed / enterprise logins, immediately reset // the dialog // Otherwise, we allow ALLOWED_FAILURES attempts. After that, we // go back to the welcome screen. - + this._failCounter++; let canRetry = retry && this._userName && this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY); - + if (canRetry) { if (!this.hasPendingMessages) { this._retry(); @@ -3671,10 +3671,10 @@ index c79958d..04b2d49 100644 + })); } } - + this.emit('verification-failed'); }, - + _onConversationStopped: function(client, serviceName) { // if the password service fails, then cancel everything. // But if, e.g., fingerprint fails, still give @@ -3682,19 +3682,19 @@ index c79958d..04b2d49 100644 if (serviceName == PASSWORD_SERVICE_NAME) { this._verificationFailed(true); } - + this.emit('hide-login-hint'); }, }); Signals.addSignalMethods(ShellUserVerifier.prototype); --- +-- 1.8.3.1 -From c377ccb3a6b5e2ad274cc3ab339137a346a8c702 Mon Sep 17 00:00:00 2001 +From 955d95254975d3aca7ccfda7225cbc02e4d700f9 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 17 Jul 2013 16:02:55 -0400 -Subject: [PATCH 13/66] util: drop call that can't do anything +Subject: [PATCH 13/69] util: drop call that can't do anything this._clearMessageQueue() is a noop when this.hasPendingMessages is false so calling it in that case doesn't make sense. @@ -3716,29 +3716,29 @@ index 04b2d49..c9af991 100644 this._client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot)); } }, - + cancel: function() { if (this._cancellable) this._cancellable.cancel(); - + if (this._userVerifier) this._userVerifier.call_cancel_sync(null); }, - + clear: function() { if (this._cancellable) { this._cancellable.cancel(); this._cancellable = null; } - + if (this._userVerifier) { this._userVerifier.run_dispose(); this._userVerifier = null; } - + this._clearMessageQueue(); }, - + answerQuery: function(serviceName, answer) { if (!this.hasPendingMessages) { - this._clearMessageQueue(); @@ -3751,35 +3751,35 @@ index 04b2d49..c9af991 100644 })); } }, - + _getIntervalForMessage: function(message) { // We probably could be smarter here return message.length * USER_READ_TIME; }, - + finishMessageQueue: function() { if (!this.hasPendingMessages) return; - + this._messageQueue = []; - + this.hasPendingMessages = false; this.emit('no-more-messages'); }, - + _queueMessageTimeout: function() { if (this._messageQueue.length == 0) { this.finishMessageQueue(); return; } --- +-- 1.8.3.1 -From a0bb4ea835b5d3fbee721101f2b018c1f3ffabc8 Mon Sep 17 00:00:00 2001 +From 63ca46cfff83937c3daf38ddfa9c651a9df94f04 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 17 Jul 2013 16:42:33 -0400 -Subject: [PATCH 14/66] unlockDialog: don't unlock explicitly on +Subject: [PATCH 14/69] unlockDialog: don't unlock explicitly on verification-complete logind sends out an "unlock" signal separately when @@ -3802,10 +3802,10 @@ index 4264f01..0aa9758 100644 } else { this._hideLockScreenComplete(); } - + global.stage.show_cursor(); }, - + _ensureUnlockDialog: function(onPrimary, allowCancel) { if (!this._dialog) { let constructor = Main.sessionMode.unlockDialog; @@ -3814,10 +3814,10 @@ index 4264f01..0aa9758 100644 this.deactivate(true); return; } - + this._dialog = new constructor(this._lockDialogGroup); - - + + let time = global.get_current_time(); if (!this._dialog.open(time, onPrimary)) { // This is kind of an impossible error: we're already modal @@ -3825,18 +3825,18 @@ index 4264f01..0aa9758 100644 log('Could not open login dialog: failed to acquire grab'); this.deactivate(true); } - + this._dialog.connect('failed', Lang.bind(this, this._onUnlockFailed)); - this._dialog.connect('unlocked', Lang.bind(this, this._onUnlockSucceded)); } - + this._dialog.allowCancel = allowCancel; }, - + _onUnlockFailed: function() { this._resetLockScreen(true, false); }, - + - _onUnlockSucceded: function() { - this.deactivate(true); - }, @@ -3848,14 +3848,14 @@ index 4264f01..0aa9758 100644 // to confuse our state) if (this._lockScreenState != MessageTray.State.HIDDEN) return; - + this._ensureLockScreen(); this._lockDialogGroup.scale_x = 1; this._lockDialogGroup.scale_y = 1; - + this._lockScreenGroup.show(); this._lockScreenState = MessageTray.State.SHOWING; - + if (animateLockScreen) { this._lockScreenGroup.y = -global.screen_height; Tweener.removeTweens(this._lockScreenGroup); @@ -3878,11 +3878,11 @@ index 16fdbfa..1d60448 100644 @@ -197,76 +197,62 @@ const UnlockDialog = new Lang.Class({ GdmUtil.fadeInActor(this._promptLoginHint); }, - + _hideLoginHint: function() { GdmUtil.fadeOutActor(this._promptLoginHint); }, - + _doUnlock: function() { if (this._firstQuestion) { // we haven't received a query yet, so stash the answer @@ -3893,19 +3893,19 @@ index 16fdbfa..1d60448 100644 this.setWorking(true); return; } - + if (!this._currentQuery) return; - + let query = this._currentQuery; this._currentQuery = null; - + this._updateSensitivity(false); this.setWorking(true); - + this._userVerifier.answerQuery(query, this._promptEntry.text); }, - + - _finishUnlock: function() { - this._userVerifier.clear(); - this.emit('unlocked'); @@ -3923,43 +3923,43 @@ index 16fdbfa..1d60448 100644 - })); - } }, - + _onReset: function() { if (!this._userVerified) { this._userVerifier.clear(); this.emit('failed'); } }, - + _onVerificationFailed: function() { this._currentQuery = null; this._firstQuestion = true; this._userVerified = false; - + this._promptEntry.text = ''; this._promptEntry.clutter_text.set_password_char('\u25cf'); this._promptEntry.menu.isPassword = true; - + this._updateSensitivity(false); this.setWorking(false); }, - + _escape: function() { if (this.allowCancel) { this._userVerifier.cancel(); this.emit('failed'); } }, - + _otherUserClicked: function(button, event) { --- +-- 1.8.3.1 -From 9d2bdeecc8a51db49a394b8fd5f87764d8735ca7 Mon Sep 17 00:00:00 2001 +From 45505ac56533a30aa81ba63fcfdc47302facd1ab Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 18 Jul 2013 08:58:58 -0400 -Subject: [PATCH 15/66] screenShield: defer deactivation until all messages are +Subject: [PATCH 15/69] screenShield: defer deactivation until all messages are shown Right now when a user types their password to unlock their session @@ -3981,35 +3981,35 @@ index 0aa9758..d9fe883 100644 --- a/js/ui/screenShield.js +++ b/js/ui/screenShield.js @@ -1083,60 +1083,66 @@ const ScreenShield = new Lang.Class({ - + _clearLockScreen: function() { this._clock.destroy(); this._clock = null; - + if (this._notificationsBox) { this._notificationsBox.destroy(); this._notificationsBox = null; } - + this._stopArrowAnimation(); - + this._lockScreenContentsBox.destroy(); - + this._hasLockScreen = false; }, - + get locked() { return this._isLocked; }, - + get active() { return this._isActive; }, - + get activationTime() { return this._activationTime; }, - + deactivate: function(animate) { + this._dialog.finish(Lang.bind(this, function() { + this._finishDeactivate(animate); @@ -4018,15 +4018,15 @@ index 0aa9758..d9fe883 100644 + + _finishDeactivate: function(animate) { this._hideLockScreen(animate, 0); - + if (this._hasLockScreen) this._clearLockScreen(); - + if (Main.sessionMode.currentMode == 'lock-screen') Main.sessionMode.popMode('lock-screen'); if (Main.sessionMode.currentMode == 'unlock-dialog') Main.sessionMode.popMode('unlock-dialog'); - + Tweener.addTween(this._lockDialogGroup, { scale_x: 0, scale_y: 0, @@ -4036,15 +4036,15 @@ index 0aa9758..d9fe883 100644 onCompleteScope: this }); }, - + _completeDeactivate: function() { if (this._dialog && !this._isGreeter) { this._dialog.destroy(); this._dialog = null; } - + this._lightbox.hide(); - + if (this._isModal) { Main.popModal(this.actor); diff --git a/js/ui/unlockDialog.js b/js/ui/unlockDialog.js @@ -4054,31 +4054,31 @@ index 1d60448..25bd92c 100644 @@ -255,31 +255,45 @@ const UnlockDialog = new Lang.Class({ } }, - + _otherUserClicked: function(button, event) { Gdm.goto_login_session_sync(null); - + this._userVerifier.cancel(); this.emit('failed'); }, - + destroy: function() { this._userVerifier.clear(); - + if (this._idleWatchId) { this._idleMonitor.remove_watch(this._idleWatchId); this._idleWatchId = 0; } - + this.parent(); }, - + cancel: function() { this._userVerifier.cancel(null); - + this.destroy(); }, - + addCharacter: function(unichar) { this._promptEntry.clutter_text.insert_unichar(unichar); }, @@ -4097,14 +4097,14 @@ index 1d60448..25bd92c 100644 + + } }); --- +-- 1.8.3.1 -From 7e1dd618980c490634bf42fcc6fab7ee4d994452 Mon Sep 17 00:00:00 2001 +From 816db83b95882fb8b63fccf07c7561c43e284904 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 18 Jul 2013 10:13:32 -0400 -Subject: [PATCH 16/66] loginDialog: avoid blinking user list when +Subject: [PATCH 16/69] loginDialog: avoid blinking user list when disable-user-list=true Right now if disable-user-list is true we show it briefly, just so @@ -4126,7 +4126,7 @@ index 15a2e0a..e132c72 100644 this._greeter.connect('timed-login-requested', Lang.bind(this, this._onTimedLoginRequested)); } - + this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient); this._userVerifier.connect('ask-question', Lang.bind(this, this._askQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage)); @@ -4135,9 +4135,9 @@ index 15a2e0a..e132c72 100644 this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint)); this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint)); this._verifyingUser = false; - + this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA }); - + this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY, Lang.bind(this, this._updateBanner)); this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY, @@ -4146,11 +4146,11 @@ index 15a2e0a..e132c72 100644 Lang.bind(this, this._updateDisableUserList)); this._settings.connect('changed::' + GdmUtil.LOGO_KEY, Lang.bind(this, this._updateLogo)); - + this._textureCache = St.TextureCache.get_default(); this._textureCache.connect('texture-file-changed', Lang.bind(this, this._updateLogoTexture)); - + this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', - vertical: true }); + vertical: true, @@ -4159,41 +4159,41 @@ index 15a2e0a..e132c72 100644 align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); this.actor.add_child(this._userSelectionBox); - + this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', text: '' }); this._userSelectionBox.add(this._bannerLabel); this._updateBanner(); - + this._userList = new UserList(); this._userSelectionBox.add(this._userList.actor, { expand: true, x_fill: true, y_fill: true }); - + this._promptBox = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout', vertical: true }); - + this._promptBox.connect('button-press-event', Lang.bind(this, function(actor, event) { if (event.get_key_symbol() == Clutter.KEY_Escape) { this.cancel(); } })); - + this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); - + @@ -1101,61 +1102,62 @@ const LoginDialog = new Lang.Class({ _onTimedLoginRequested: function(client, userName, seconds) { this._startTimedLogin(userName, seconds); - + global.stage.connect('captured-event', Lang.bind(this, function(actor, event) { if (this._timedLoginDelay == undefined) return false; - + if (event.type() == Clutter.EventType.KEY_PRESS || event.type() == Clutter.EventType.BUTTON_PRESS) { if (this._timedLoginBatch) { @@ -4204,16 +4204,16 @@ index 15a2e0a..e132c72 100644 event.type() == Clutter.EventType.BUTTON_RELEASE) { this._resetTimedLogin(); } - + return false; })); }, - + _setUserListExpanded: function(expanded) { this._userList.updateStyle(expanded); this._userSelectionBox.visible = expanded; }, - + _hideUserListAndLogIn: function() { this._setUserListExpanded(false); - GdmUtil.cloneAndFadeOutActor(this._userSelectionBox); @@ -4221,26 +4221,26 @@ index 15a2e0a..e132c72 100644 + GdmUtil.cloneAndFadeOutActor(this._userSelectionBox); this._askForUsernameAndLogIn(); }, - + _showUserList: function() { this._hidePrompt(); this._setUserListExpanded(true); this._notListedButton.show(); this._userList.actor.grab_key_focus(); }, - + _beginVerificationForUser: function(userName) { let hold = new Batch.Hold(); - + this._userVerifier.begin(userName, hold); this._verifyingUser = true; return hold; }, - + _beginVerificationForItem: function(item) { let userWidget = new UserWidget.UserWidget(item.user); this._promptUser.set_child(userWidget.actor); - + let tasks = [function() { let userName = item.user.get_user_name(); return this._beginVerificationForUser(userName); @@ -4248,15 +4248,15 @@ index 15a2e0a..e132c72 100644 let batch = new Batch.ConsecutiveBatch(this, tasks); return batch.run(); }, - --- + +-- 1.8.3.1 -From 8f2344677e73fad818ed8f160b6fd4affdb6777c Mon Sep 17 00:00:00 2001 +From 1faa288bd144570af05cbc7497a81fb9af62b9bc Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 17 Jul 2013 11:58:05 -0400 -Subject: [PATCH 17/66] unlockDialog: drop unused variable +Subject: [PATCH 17/69] unlockDialog: drop unused variable https://bugzilla.gnome.org/show_bug.cgi?id=702308 --- @@ -4275,68 +4275,68 @@ index 25bd92c..50e9502 100644 const Tweener = imports.ui.tweener; const UserMenu = imports.ui.userMenu; const UserWidget = imports.ui.userWidget; - + const Batch = imports.gdm.batch; const GdmUtil = imports.gdm.util; const LoginDialog = imports.gdm.loginDialog; - + // The timeout before going back automatically to the lock screen (in seconds) const IDLE_TIMEOUT = 2 * 60; - + const UnlockDialog = new Lang.Class({ Name: 'UnlockDialog', Extends: ModalDialog.ModalDialog, - + _init: function(parentActor) { this.parent({ shellReactive: true, styleClass: 'login-dialog', keybindingMode: Shell.KeyBindingMode.UNLOCK_SCREEN, parentActor: parentActor }); - + this._userManager = AccountsService.UserManager.get_default(); this._userName = GLib.get_user_name(); this._user = this._userManager.get_user(this._userName); - + - this._failCounter = 0; this._firstQuestion = true; - + this._greeterClient = new Gdm.Client(); this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true }); this._userVerified = false; - + this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage)); this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete)); this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed)); this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); - + this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint)); this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint)); - + this._userWidget = new UserWidget.UserWidget(this._user); this.contentLayout.add_actor(this._userWidget.actor); - + this._promptLayout = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout', vertical: true }); - + this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' }); this._promptLayout.add(this._promptLabel, { x_align: St.Align.START }); - + this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry', can_focus: true }); this._promptEntry.clutter_text.connect('activate', Lang.bind(this, this._doUnlock)); this._promptEntry.clutter_text.set_password_char('\u25cf'); ShellEntry.addContextMenu(this._promptEntry, { isPassword: true }); --- +-- 1.8.3.1 -From e2435d944d8fa155f9e02ba256fd6c746abcfe7a Mon Sep 17 00:00:00 2001 +From 858be94cb8c6793ffb6488f64dda087acdeaeace Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 17 Jul 2013 09:54:03 -0400 -Subject: [PATCH 18/66] loginDialog: s/button-press-event/key-press-event/ +Subject: [PATCH 18/69] loginDialog: s/button-press-event/key-press-event/ A bug got introduced when moving the login dialog away from modal dialog, such that it listens for escape key presses in a mouse @@ -4358,11 +4358,11 @@ index e132c72..a9ca615 100644 Lang.bind(this, this._updateDisableUserList)); this._settings.connect('changed::' + GdmUtil.LOGO_KEY, Lang.bind(this, this._updateLogo)); - + this._textureCache = St.TextureCache.get_default(); this._textureCache.connect('texture-file-changed', Lang.bind(this, this._updateLogoTexture)); - + this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', vertical: true, visible: false }); @@ -4370,21 +4370,21 @@ index e132c72..a9ca615 100644 align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); this.actor.add_child(this._userSelectionBox); - + this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', text: '' }); this._userSelectionBox.add(this._bannerLabel); this._updateBanner(); - + this._userList = new UserList(); this._userSelectionBox.add(this._userList.actor, { expand: true, x_fill: true, y_fill: true }); - + this._promptBox = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout', vertical: true }); - + - this._promptBox.connect('button-press-event', + this._promptBox.connect('key-press-event', Lang.bind(this, function(actor, event) { @@ -4392,15 +4392,15 @@ index e132c72..a9ca615 100644 this.cancel(); } })); - + this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); - + this.actor.add_child(this._promptBox); this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._promptBox, coordinate: Clutter.BindCoordinate.WIDTH })); - + this._promptUser = new St.Bin({ x_fill: true, x_align: St.Align.START }); this._promptBox.add(this._promptUser, @@ -4409,7 +4409,7 @@ index e132c72..a9ca615 100644 y_fill: true, expand: true }); this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this._promptBox.add(this._promptLabel, { expand: true, x_fill: true, @@ -4417,14 +4417,14 @@ index e132c72..a9ca615 100644 x_align: St.Align.START }); this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry', can_focus: true }); --- +-- 1.8.3.1 -From 8115fb33c1f69436a053d8e3322a6762f7231d7e Mon Sep 17 00:00:00 2001 +From 0ec3099c58ffa2b68c58fd472a593921326e7c85 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 15 Jul 2013 17:56:44 -0400 -Subject: [PATCH 19/66] loginDialog: factor auth prompt code out to utils +Subject: [PATCH 19/69] loginDialog: factor auth prompt code out to utils Right now there is a lot of duplicated code between the unlock dialog and the login dialog. @@ -4459,7 +4459,7 @@ index a9ca615..e9dd6b2 100644 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ - + const AccountsService = imports.gi.AccountsService; const Atk = imports.gi.Atk; const Clutter = imports.gi.Clutter; @@ -4473,7 +4473,7 @@ index a9ca615..e9dd6b2 100644 const Shell = imports.gi.Shell; const Signals = imports.signals; const St = imports.gi.St; - + -const Panel = imports.ui.panel; const Batch = imports.gdm.batch; const BoxPointer = imports.ui.boxpointer; @@ -4486,7 +4486,7 @@ index a9ca615..e9dd6b2 100644 const Tweener = imports.ui.tweener; const UserMenu = imports.ui.userMenu; const UserWidget = imports.ui.userWidget; - + const _FADE_ANIMATION_TIME = 0.25; const _SCROLL_ANIMATION_TIME = 0.5; -const _DEFAULT_BUTTON_WELL_ICON_SIZE = 24; @@ -4494,9 +4494,9 @@ index a9ca615..e9dd6b2 100644 -const _DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0; const _LOGO_ICON_HEIGHT = 48; - + let _loginDialog = null; - + -const DefaultButtonWellMode = { - NONE: 0, - SESSION_MENU_BUTTON: 1, @@ -4505,12 +4505,12 @@ index a9ca615..e9dd6b2 100644 - const UserListItem = new Lang.Class({ Name: 'UserListItem', - + _init: function(user) { this.user = user; this._userChangedId = this.user.connect('changed', Lang.bind(this, this._onUserChanged)); - + let layout = new St.BoxLayout({ vertical: false }); this.actor = new St.Button({ style_class: 'login-dialog-user-list-item', button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, @@ -4519,14 +4519,14 @@ index a9ca615..e9dd6b2 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._userAvatar = new UserMenu.UserAvatarWidget(this.user, { styleClass: 'login-dialog-user-list-item-icon' }); layout.add(this._userAvatar.actor); let textLayout = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-text-box', vertical: true }); layout.add(textLayout, { expand: true }); - + this._nameLabel = new St.Label({ style_class: 'login-dialog-user-list-item-name' }); this.actor.label_actor = this._nameLabel; textLayout.add(this._nameLabel, @@ -4540,11 +4540,11 @@ index a9ca615..e9dd6b2 100644 Lang.bind(this, this._updateDisableUserList)); this._settings.connect('changed::' + GdmUtil.LOGO_KEY, Lang.bind(this, this._updateLogo)); - + this._textureCache = St.TextureCache.get_default(); this._textureCache.connect('texture-file-changed', Lang.bind(this, this._updateLogoTexture)); - + this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', vertical: true, visible: false }); @@ -4552,18 +4552,18 @@ index a9ca615..e9dd6b2 100644 align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); this.actor.add_child(this._userSelectionBox); - + this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', text: '' }); this._userSelectionBox.add(this._bannerLabel); this._updateBanner(); - + this._userList = new UserList(); this._userSelectionBox.add(this._userList.actor, { expand: true, x_fill: true, y_fill: true }); - + - this._promptBox = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout', - vertical: true }); - @@ -4577,20 +4577,20 @@ index a9ca615..e9dd6b2 100644 this.cancel(); - } })); - + - this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor, - align_axis: Clutter.AlignAxis.BOTH, - factor: 0.5 })); + this._authPrompt.actor.add_constraint(new Clutter.AlignConstraint({ source: this.actor, + align_axis: Clutter.AlignAxis.BOTH, + factor: 0.5 })); - + - this.actor.add_child(this._promptBox); - this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._promptBox, + this.actor.add_child(this._authPrompt.actor); + this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._authPrompt.actor, coordinate: Clutter.BindCoordinate.WIDTH })); - + - this._promptUser = new St.Bin({ x_fill: true, - x_align: St.Align.START }); - this._promptBox.add(this._promptUser, @@ -4646,15 +4646,15 @@ index a9ca615..e9dd6b2 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn)); this._notListedButton.hide(); - + this._userSelectionBox.add(this._notListedButton, { expand: false, x_align: St.Align.START, x_fill: true }); - + this._logoBin = new St.Bin({ style_class: 'login-dialog-logo-bin', y_expand: true }); this._logoBin.set_y_align(Clutter.ActorAlign.END); this._logoBin.add_constraint(new Clutter.AlignConstraint({ source: this.actor, @@ -4665,7 +4665,7 @@ index a9ca615..e9dd6b2 100644 factor: 1.0 })); this.actor.add_child(this._logoBin); this._updateLogo(); - + if (!this._userManager.is_loaded) this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', Lang.bind(this, function() { @@ -4677,15 +4677,15 @@ index a9ca615..e9dd6b2 100644 })); else this._loadUserList(); - + this._userList.connect('activate', Lang.bind(this, function(userList, item) { this._onUserListActivated(item); })); - + - this._defaultButtonWell = new St.Widget(); - this._defaultButtonWellMode = DefaultButtonWellMode.NONE; - + this._sessionMenuButton = new SessionMenuButton(); this._sessionMenuButton.connect('session-activated', Lang.bind(this, function(list, sessionId) { @@ -4695,7 +4695,7 @@ index a9ca615..e9dd6b2 100644 this._sessionMenuButton.actor.show(); - this._defaultButtonWell.add_child(this._sessionMenuButton.actor); + this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor); - + - let spinnerIcon = global.datadir + '/theme/process-working.svg'; - this._workSpinner = new Panel.AnimatedIcon(spinnerIcon, _DEFAULT_BUTTON_WELL_ICON_SIZE); - this._workSpinner.actor.opacity = 0; @@ -4706,22 +4706,22 @@ index a9ca615..e9dd6b2 100644 - align_axis: Clutter.AlignAxis.BOTH, - factor: 0.5 })); }, - + _updateDisableUserList: function() { let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); - + if (disableUserList != this._disableUserList) { this._disableUserList = disableUserList; - + if (!this._verifyingUser) this._reset(); } }, - + _updateBanner: function() { let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); - + if (enabled && text) { this._bannerLabel.set_text(text); this._bannerLabel.show(); @@ -4729,41 +4729,41 @@ index a9ca615..e9dd6b2 100644 this._bannerLabel.hide(); } }, - + _updateLogoTexture: function(cache, uri) { if (this._logoFileUri != uri) return; - + let icon = null; if (this._logoFileUri) icon = this._textureCache.load_uri_async(this._logoFileUri, -1, _LOGO_ICON_HEIGHT); this._logoBin.set_child(icon); }, - + _updateLogo: function() { let path = this._settings.get_string(GdmUtil.LOGO_KEY); - + this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; this._updateLogoTexture(this._textureCache, this._logoFileUri); }, - + _reset: function() { this._userVerifier.clear(); - + this._updateSensitivity(true); - this._promptMessage.opacity = 0; + this._authPrompt.reset(); + this._user = null; this._verifyingUser = false; - + if (this._disableUserList) this._hideUserListAndLogIn(); else this._showUserList(); }, - + - _getActorForDefaultButtonWellMode: function(mode) { - let actor; - @@ -4829,16 +4829,16 @@ index a9ca615..e9dd6b2 100644 _verificationFailed: function() { - this._promptEntry.text = ''; + this._authPrompt.clear(); - + this._updateSensitivity(true); - this._setDefaultButtonWellMode(DefaultButtonWellMode.NONE, true); + this._authPrompt.setActorInDefaultButtonWell(null); }, - + _onDefaultSessionChanged: function(client, sessionId) { this._sessionMenuButton.setActiveSession(sessionId); }, - + _showMessage: function(userVerifier, message, styleClass) { - if (message) { - this._promptMessage.text = message; @@ -4849,39 +4849,39 @@ index a9ca615..e9dd6b2 100644 - } + this._authPrompt.setMessage(message, styleClass); }, - + _showLoginHint: function(verifier, message) { - this._promptLoginHint.set_text(message) - this._promptLoginHint.opacity = 255; + this._authPrompt.setHint(message); }, - + _hideLoginHint: function() { - this._promptLoginHint.opacity = 0; - this._promptLoginHint.set_text(''); + this._authPrompt.setHint(null); }, - + cancel: function() { if (this._verifyingUser) this._userVerifier.cancel(); else this._reset(); }, - + _shouldShowSessionMenuButton: function() { if (this._verifyingUser) return true; - + if (!this._user) return false; - + if (this._user.is_logged_in) return false; - + return true; }, - + _showPrompt: function(forSecret) { - this._promptLabel.show(); - this._promptEntry.show(); @@ -4896,7 +4896,7 @@ index a9ca615..e9dd6b2 100644 { opacity: 255, time: _FADE_ANIMATION_TIME, transition: 'easeOutQuad' }); - + - if (this._shouldShowSessionMenuButton()) - this._setDefaultButtonWellMode(DefaultButtonWellMode.SESSION_MENU_BUTTON, true); - else @@ -4909,14 +4909,14 @@ index a9ca615..e9dd6b2 100644 - this._prepareDialog(forSecret, hold); + this._preparePrompt(forSecret, hold); }, - + hold]; - + let batch = new Batch.ConcurrentBatch(this, tasks); - + return batch.run(); }, - + - _prepareDialog: function(forSecret, hold) { - this._buttonBox.visible = true; - this._buttonBox.remove_all_children(); @@ -4942,7 +4942,7 @@ index a9ca615..e9dd6b2 100644 + } else { + this._authPrompt.cancelButton.hide(); } - + - this._buttonBox.add(this._defaultButtonWell, - { expand: true, - x_fill: false, @@ -4989,7 +4989,7 @@ index a9ca615..e9dd6b2 100644 + hold.release(); + })); }, - + _updateSensitivity: function(sensitive) { - this._promptEntry.reactive = sensitive; - this._promptEntry.clutter_text.editable = sensitive; @@ -5032,12 +5032,12 @@ index a9ca615..e9dd6b2 100644 - this._cancelButton = null; + this._authPrompt.updateSensitivity(sensitive); }, - + _askQuestion: function(verifier, serviceName, question, passwordChar) { - this._promptLabel.set_text(question); + this._authPrompt.setPasswordChar(passwordChar); + this._authPrompt.setQuestion(question); - + this._updateSensitivity(true); - this._promptEntry.set_text(''); - this._promptEntry.clutter_text.set_password_char(passwordChar); @@ -5046,11 +5046,11 @@ index a9ca615..e9dd6b2 100644 + this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor); + else + this._authPrompt.setActorInDefaultButtonWell(null); - + let tasks = [function() { return this._showPrompt(!!passwordChar); }, - + function() { - let text = this._promptEntry.get_text(); + let text = this._authPrompt.getAnswer(); @@ -5060,38 +5060,38 @@ index a9ca615..e9dd6b2 100644 + this._authPrompt.startSpinning(); this._userVerifier.answerQuery(serviceName, text); }]; - + let batch = new Batch.ConsecutiveBatch(this, tasks); return batch.run(); }, - + _showRealmLoginHint: function(realmManager, hint) { if (!hint) return; - + hint = hint.replace(/%U/g, 'user'); hint = hint.replace(/%D/g, 'DOMAIN'); hint = hint.replace(/%[^UD]/g, ''); - + // Translators: this message is shown below the username entry field // to clue the user in on how to login to the local network realm this._showLoginHint(null, _("(e.g., user or %s)").format(hint)); }, - + _askForUsernameAndLogIn: function() { - this._promptLabel.set_text(_("Username: ")); - this._promptEntry.set_text(''); - this._promptEntry.clutter_text.set_password_char(''); + this._authPrompt.setPasswordChar(''); + this._authPrompt.setQuestion(_("Username: ")); - + let realmManager = new Realmd.Manager(); let signalId = realmManager.connect('login-format-changed', - Lang.bind(this, this._showRealmLoginHint)); + Lang.bind(this, this._showRealmLoginHint)); this._showRealmLoginHint(realmManager.loginFormat); - + let tasks = [this._showPrompt, - + function() { - let userName = this._promptEntry.get_text(); - this._promptEntry.reactive = false; @@ -5099,16 +5099,16 @@ index a9ca615..e9dd6b2 100644 + this._authPrompt._entry.reactive = false; return this._beginVerificationForUser(userName); }, - + function() { realmManager.disconnect(signalId) realmManager.release(); }]; - + let batch = new Batch.ConsecutiveBatch(this, tasks); return batch.run(); }, - + _startSession: function(serviceName) { Tweener.addTween(this.actor, { opacity: 0, @@ -5116,7 +5116,7 @@ index a9ca615..e9dd6b2 100644 transition: 'easeOutQuad', onUpdate: function() { let children = Main.layoutManager.uiGroup.get_children(); - + for (let i = 0; i < children.length; i++) { if (children[i] != Main.layoutManager.screenShieldGroup) children[i].opacity = this.actor.opacity; @@ -5129,7 +5129,7 @@ index a9ca615..e9dd6b2 100644 return false; @@ -1108,77 +888,77 @@ const LoginDialog = new Lang.Class({ return false; - + if (event.type() == Clutter.EventType.KEY_PRESS || event.type() == Clutter.EventType.BUTTON_PRESS) { if (this._timedLoginBatch) { @@ -5140,23 +5140,23 @@ index a9ca615..e9dd6b2 100644 event.type() == Clutter.EventType.BUTTON_RELEASE) { this._resetTimedLogin(); } - + return false; })); }, - + _setUserListExpanded: function(expanded) { this._userList.updateStyle(expanded); this._userSelectionBox.visible = expanded; }, - + _hideUserListAndLogIn: function() { this._setUserListExpanded(false); if (this._userSelectionBox.visible) GdmUtil.cloneAndFadeOutActor(this._userSelectionBox); this._askForUsernameAndLogIn(); }, - + _showUserList: function() { - this._hidePrompt(); + this._authPrompt.hide(); @@ -5165,20 +5165,20 @@ index a9ca615..e9dd6b2 100644 this._notListedButton.show(); this._userList.actor.grab_key_focus(); }, - + _beginVerificationForUser: function(userName) { let hold = new Batch.Hold(); - + this._userVerifier.begin(userName, hold); this._verifyingUser = true; return hold; }, - + _beginVerificationForItem: function(item) { - let userWidget = new UserWidget.UserWidget(item.user); - this._promptUser.set_child(userWidget.actor); + this._authPrompt.setUser(item.user); - + let tasks = [function() { let userName = item.user.get_user_name(); return this._beginVerificationForUser(userName); @@ -5186,7 +5186,7 @@ index a9ca615..e9dd6b2 100644 let batch = new Batch.ConsecutiveBatch(this, tasks); return batch.run(); }, - + _onUserListActivated: function(activatedItem) { let tasks = [function() { return GdmUtil.cloneAndFadeOutActor(this._userSelectionBox); @@ -5194,14 +5194,14 @@ index a9ca615..e9dd6b2 100644 function() { this._setUserListExpanded(false); }]; - + this._user = activatedItem.user; - + let batch = new Batch.ConcurrentBatch(this, [new Batch.ConsecutiveBatch(this, tasks), this._beginVerificationForItem(activatedItem)]); batch.run(); }, - + _onDestroy: function() { if (this._userManagerLoadedId) { this._userManager.disconnect(this._userManagerLoadedId); @@ -5209,20 +5209,20 @@ index a9ca615..e9dd6b2 100644 } }, @@ -1192,34 +972,34 @@ const LoginDialog = new Lang.Class({ - + this._updateDisableUserList(); - + this._userManager.connect('user-added', Lang.bind(this, function(userManager, user) { this._userList.addUser(user); })); - + this._userManager.connect('user-removed', Lang.bind(this, function(userManager, user) { this._userList.removeUser(user); })); }, - + open: function() { Main.ctrlAltTabManager.addGroup(this.actor, _("Login Window"), @@ -5230,14 +5230,14 @@ index a9ca615..e9dd6b2 100644 { sortGroup: CtrlAltTab.SortGroup.MIDDLE }); this._userList.actor.grab_key_focus(); this.actor.show(); - + return true; }, - + close: function() { Main.ctrlAltTabManager.removeGroup(this.dialogLayout); }, - + addCharacter: function(unichar) { - this._promptEntry.clutter_text.insert_unichar(unichar); + this._authPrompt.addCharacter(unichar); @@ -5250,7 +5250,7 @@ index c9af991..fbbbae0 100644 +++ b/js/gdm/util.js @@ -1,62 +1,69 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - + const Clutter = imports.gi.Clutter; const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; @@ -5258,7 +5258,7 @@ index c9af991..fbbbae0 100644 const Mainloop = imports.mainloop; const Signals = imports.signals; +const St = imports.gi.St; - + +const Panel = imports.ui.panel; const Batch = imports.gdm.batch; const Fprint = imports.gdm.fingerprint; @@ -5266,24 +5266,24 @@ index c9af991..fbbbae0 100644 const Params = imports.misc.params; const Tweener = imports.ui.tweener; +const UserWidget = imports.ui.userWidget; - + const PASSWORD_SERVICE_NAME = 'gdm-password'; const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint'; const FADE_ANIMATION_TIME = 0.16; const CLONE_FADE_ANIMATION_TIME = 0.25; - + const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen'; const FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication'; const BANNER_MESSAGE_KEY = 'banner-message-enable'; const BANNER_MESSAGE_TEXT_KEY = 'banner-message-text'; const ALLOWED_FAILURES_KEY = 'allowed-failures'; - + const LOGO_KEY = 'logo'; const DISABLE_USER_LIST_KEY = 'disable-user-list'; - + // Give user 16ms to read each character of a PAM message const USER_READ_TIME = 16 - + +const DEFAULT_BUTTON_WELL_ICON_SIZE = 24; +const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; +const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; @@ -5291,11 +5291,11 @@ index c9af991..fbbbae0 100644 function fadeInActor(actor) { if (actor.opacity == 255 && actor.visible) return null; - + let hold = new Batch.Hold(); actor.show(); let [minHeight, naturalHeight] = actor.get_preferred_height(-1); - + actor.opacity = 0; actor.set_height(0); Tweener.addTween(actor, @@ -5308,10 +5308,10 @@ index c9af991..fbbbae0 100644 hold.release(); }, }); - + return hold; } - + function fadeOutActor(actor) { if (!actor.visible || actor.opacity == 0) { actor.opacity = 0; @@ -5333,10 +5333,10 @@ index c9af991..fbbbae0 100644 })); } } - + this.emit('verification-failed'); }, - + _onConversationStopped: function(client, serviceName) { // if the password service fails, then cancel everything. // But if, e.g., fingerprint fails, still give @@ -5344,7 +5344,7 @@ index c9af991..fbbbae0 100644 if (serviceName == PASSWORD_SERVICE_NAME) { this._verificationFailed(true); } - + this.emit('hide-login-hint'); }, }); @@ -5625,14 +5625,14 @@ index c9af991..fbbbae0 100644 + } +}); +Signals.addSignalMethods(AuthPrompt.prototype); --- +-- 1.8.3.1 -From 8f568640c3dca0be88986515429380de28cc573d Mon Sep 17 00:00:00 2001 +From 664f9f789a46491da201319d72009a61ac79115e Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 18 Jul 2013 14:40:10 -0400 -Subject: [PATCH 20/66] util: add shell entry menu to auth prompt +Subject: [PATCH 20/69] util: add shell entry menu to auth prompt This brings us parity with the unlock dialog, and is a prerequisite for eventually moving the unlock dialog over to using the auth @@ -5649,7 +5649,7 @@ index fbbbae0..084bc7b 100644 +++ b/js/gdm/util.js @@ -1,45 +1,46 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - + const Clutter = imports.gi.Clutter; const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; @@ -5657,7 +5657,7 @@ index fbbbae0..084bc7b 100644 const Mainloop = imports.mainloop; const Signals = imports.signals; const St = imports.gi.St; - + const Panel = imports.ui.panel; const Batch = imports.gdm.batch; const Fprint = imports.gdm.fingerprint; @@ -5666,39 +5666,39 @@ index fbbbae0..084bc7b 100644 +const ShellEntry = imports.ui.shellEntry; const Tweener = imports.ui.tweener; const UserWidget = imports.ui.userWidget; - + const PASSWORD_SERVICE_NAME = 'gdm-password'; const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint'; const FADE_ANIMATION_TIME = 0.16; const CLONE_FADE_ANIMATION_TIME = 0.25; - + const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen'; const FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication'; const BANNER_MESSAGE_KEY = 'banner-message-enable'; const BANNER_MESSAGE_TEXT_KEY = 'banner-message-text'; const ALLOWED_FAILURES_KEY = 'allowed-failures'; - + const LOGO_KEY = 'logo'; const DISABLE_USER_LIST_KEY = 'disable-user-list'; - + // Give user 16ms to read each character of a PAM message const USER_READ_TIME = 16 - + const DEFAULT_BUTTON_WELL_ICON_SIZE = 24; const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; - + function fadeInActor(actor) { if (actor.opacity == 255 && actor.visible) return null; - + let hold = new Batch.Hold(); actor.show(); @@ -468,60 +469,62 @@ Signals.addSignalMethods(ShellUserVerifier.prototype); - + const AuthPrompt = new Lang.Class({ Name: 'AuthPrompt', - + _init: function() { this.actor = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout', vertical: true }); @@ -5708,7 +5708,7 @@ index fbbbae0..084bc7b 100644 this.emit('cancel'); } })); - + this._userWell = new St.Bin({ x_fill: true, x_align: St.Align.START }); this.actor.add(this._userWell, @@ -5717,7 +5717,7 @@ index fbbbae0..084bc7b 100644 y_fill: true, expand: true }); this._label = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this.actor.add(this._label, { expand: true, x_fill: true, @@ -5732,34 +5732,34 @@ index fbbbae0..084bc7b 100644 x_fill: true, y_fill: false, x_align: St.Align.START }); - + this._entry.grab_key_focus(); - + this._message = new St.Label({ opacity: 0 }); this.actor.add(this._message, { x_fill: true }); - + this._loginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' }); this.actor.add(this._loginHint); - + this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box', vertical: false }); this.actor.add(this._buttonBox, { expand: true, x_align: St.Align.MIDDLE, y_align: St.Align.END }); - + this._defaultButtonWell = new St.Widget(); this._defaultButtonWellActor = null; - + this._initButtons(); - + let spinnerIcon = global.datadir + '/theme/process-working.svg'; this._spinner = new Panel.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE); this._spinner.actor.opacity = 0; this._spinner.actor.show(); @@ -628,60 +631,61 @@ const AuthPrompt = new Lang.Class({ this._spinner.play(); - + if (!animate) actor.opacity = 255; else @@ -5769,46 +5769,46 @@ index fbbbae0..084bc7b 100644 delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY, transition: 'linear' }); } - + this._defaultButtonWellActor = actor; }, - + startSpinning: function() { this.setActorInDefaultButtonWell(this._spinner.actor, true); }, - + stopSpinning: function() { this.setActorInDefaultButtonWell(null, false); }, - + clear: function() { this._entry.text = ''; this.stopSpinning(); }, - + setPasswordChar: function(passwordChar) { this._entry.clutter_text.set_password_char(passwordChar); + this._entry.menu.isPassword = passwordChar != ''; }, - + setQuestion: function(question) { this._label.set_text(question); - + this._label.show(); this._entry.show(); - + this._loginHint.opacity = 0; this._loginHint.show(); - + this._entry.grab_key_focus(); }, - + getAnswer: function() { let text = this._entry.get_text(); - + return text; }, - + setMessage: function(message, styleClass) { if (message) { this._message.text = message; @@ -5818,15 +5818,15 @@ index fbbbae0..084bc7b 100644 this._message.opacity = 0; } }, - --- + +-- 1.8.3.1 -From b2f3b75ab632fe9a3ad4bd29e9a1cab9453c2f1b Mon Sep 17 00:00:00 2001 +From 7a92988dd7c65f020a2c986dfa6e73b79ba8410c Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 16 Jul 2013 07:31:22 -0400 -Subject: [PATCH 21/66] unlockDialog: Use GdmUtil.AuthPrompt instead of +Subject: [PATCH 21/69] unlockDialog: Use GdmUtil.AuthPrompt instead of ModalDialog commit ea02380c1524c28e6538ffedb789a12c298742ab made the login @@ -5851,7 +5851,7 @@ index 50e9502..4a36cd3 100644 +++ b/js/ui/unlockDialog.js @@ -1,298 +1,261 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - + const AccountsService = imports.gi.AccountsService; +const Atk = imports.gi.Atk; const Clutter = imports.gi.Clutter; @@ -5864,7 +5864,7 @@ index 50e9502..4a36cd3 100644 const Signals = imports.signals; const Shell = imports.gi.Shell; const St = imports.gi.St; - + +const Layout = imports.ui.layout; const Main = imports.ui.main; -const ModalDialog = imports.ui.modalDialog; @@ -5873,18 +5873,18 @@ index 50e9502..4a36cd3 100644 const Tweener = imports.ui.tweener; const UserMenu = imports.ui.userMenu; const UserWidget = imports.ui.userWidget; - + const Batch = imports.gdm.batch; const GdmUtil = imports.gdm.util; const LoginDialog = imports.gdm.loginDialog; - + // The timeout before going back automatically to the lock screen (in seconds) const IDLE_TIMEOUT = 2 * 60; - + const UnlockDialog = new Lang.Class({ Name: 'UnlockDialog', - Extends: ModalDialog.ModalDialog, - + _init: function(parentActor) { - this.parent({ shellReactive: true, - styleClass: 'login-dialog', @@ -5897,26 +5897,26 @@ index 50e9502..4a36cd3 100644 + + this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true })); + parentActor.add_child(this.actor); - + this._userManager = AccountsService.UserManager.get_default(); this._userName = GLib.get_user_name(); this._user = this._userManager.get_user(this._userName); - + this._firstQuestion = true; - + this._greeterClient = new Gdm.Client(); this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true }); this._userVerified = false; - + this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage)); this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete)); this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed)); this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); - + this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint)); this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint)); - + - this._userWidget = new UserWidget.UserWidget(this._user); - this.contentLayout.add_actor(this._userWidget.actor); - @@ -5947,7 +5947,7 @@ index 50e9502..4a36cd3 100644 + this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor, + align_axis: Clutter.AlignAxis.BOTH, + factor: 0.5 })); - + - this._promptMessage = new St.Label({ visible: false }); - this.contentLayout.add(this._promptMessage, { x_fill: true }); + this._authPrompt = new GdmUtil.AuthPrompt(); @@ -5956,12 +5956,12 @@ index 50e9502..4a36cd3 100644 + this._authPrompt.nextButton.label = _("Unlock"); + this._authPrompt.connect('cancel', Lang.bind(this, this._escape)); + this._authPrompt.connect('next', Lang.bind(this, this._doUnlock)); - + - this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint' }); - this._promptLoginHint.hide(); - this.contentLayout.add_actor(this._promptLoginHint); + this._promptBox.add_child(this._authPrompt.actor); - + this.allowCancel = false; - this.buttonLayout.visible = true; - this.addButton({ label: _("Cancel"), @@ -5985,7 +5985,7 @@ index 50e9502..4a36cd3 100644 - y_fill: false, - x_align: St.Align.END, - y_align: St.Align.MIDDLE }); - + let screenSaverSettings = new Gio.Settings({ schema: 'org.gnome.desktop.screensaver' }); if (screenSaverSettings.get_boolean('user-switch-enabled')) { let otherUserLabel = new St.Label({ text: _("Log in as another user"), @@ -6004,19 +6004,19 @@ index 50e9502..4a36cd3 100644 } else { this._otherUserButton = null; } - + this._updateSensitivity(true); - + let batch = new Batch.Hold(); this._userVerifier.begin(this._userName, batch); - + - Main.ctrlAltTabManager.addGroup(this.dialogLayout, _("Unlock Window"), 'dialog-password-symbolic'); + Main.ctrlAltTabManager.addGroup(this.actor, _("Unlock Window"), 'dialog-password-symbolic'); - + this._idleMonitor = new GnomeDesktop.IdleMonitor(); this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape)); }, - + _updateSensitivity: function(sensitive) { - this._promptEntry.reactive = sensitive; - this._promptEntry.clutter_text.editable = sensitive; @@ -6028,7 +6028,7 @@ index 50e9502..4a36cd3 100644 this._otherUserButton.can_focus = sensitive; } }, - + - _updateOkButtonSensitivity: function(sensitive) { - this._okButton.reactive = sensitive; - this._okButton.can_focus = sensitive; @@ -6044,7 +6044,7 @@ index 50e9502..4a36cd3 100644 - } + this._authPrompt.setMessage(message, styleClass); }, - + _onAskQuestion: function(verifier, serviceName, question, passwordChar) { if (this._firstQuestion && this._firstQuestionAnswer) { this._userVerifier.answerQuery(serviceName, this._firstQuestionAnswer); @@ -6052,37 +6052,37 @@ index 50e9502..4a36cd3 100644 this._firstQuestion = false; return; } - + - this._promptLabel.text = question; - if (!this._firstQuestion) this._promptEntry.text = ''; else this._firstQuestion = false; - + - this._promptEntry.clutter_text.set_password_char(passwordChar); - this._promptEntry.menu.isPassword = passwordChar != ''; + this._authPrompt.setPasswordChar(passwordChar); + this._authPrompt.setQuestion(question); - + this._currentQuery = serviceName; + this._updateSensitivity(true); - this.setWorking(false); + this._authPrompt.stopSpinning(); }, - + _showLoginHint: function(verifier, message) { - this._promptLoginHint.set_text(message) - GdmUtil.fadeInActor(this._promptLoginHint); + this._authPrompt.setHint(message); }, - + _hideLoginHint: function() { - GdmUtil.fadeOutActor(this._promptLoginHint); + this._authPrompt.setHint(null); }, - + _doUnlock: function() { if (this._firstQuestion) { // we haven't received a query yet, so stash the answer @@ -6094,65 +6094,65 @@ index 50e9502..4a36cd3 100644 + this._authPrompt.startSpinning(); return; } - + if (!this._currentQuery) return; - + let query = this._currentQuery; this._currentQuery = null; - + this._updateSensitivity(false); - this.setWorking(true); + this._authPrompt.startSpinning(); - + - this._userVerifier.answerQuery(query, this._promptEntry.text); + this._userVerifier.answerQuery(query, this._authPrompt.getAnswer()); }, - + _onVerificationComplete: function() { this._userVerified = true; }, - + _onReset: function() { if (!this._userVerified) { this._userVerifier.clear(); this.emit('failed'); } }, - + _onVerificationFailed: function() { this._currentQuery = null; this._firstQuestion = true; this._userVerified = false; - + - this._promptEntry.text = ''; - this._promptEntry.clutter_text.set_password_char('\u25cf'); - this._promptEntry.menu.isPassword = true; + this._authPrompt.clear(); - + this._updateSensitivity(false); - this.setWorking(false); + this._authPrompt.stopSpinning(); }, - + _escape: function() { if (this.allowCancel) { this._userVerifier.cancel(); this.emit('failed'); } }, - + _otherUserClicked: function(button, event) { Gdm.goto_login_session_sync(null); - + this._userVerifier.cancel(); this.emit('failed'); }, - + destroy: function() { this._userVerifier.clear(); + this.actor.destroy(); - + if (this._idleWatchId) { this._idleMonitor.remove_watch(this._idleWatchId); this._idleWatchId = 0; @@ -6160,24 +6160,24 @@ index 50e9502..4a36cd3 100644 - - this.parent(); }, - + cancel: function() { this._userVerifier.cancel(null); - + this.destroy(); }, - + addCharacter: function(unichar) { - this._promptEntry.clutter_text.insert_unichar(unichar); + this._authPrompt.addCharacter(unichar); }, - + finish: function(onComplete) { if (!this._userVerifier.hasPendingMessages) { onComplete(); return; } - + let signalId = this._userVerifier.connect('no-more-messages', Lang.bind(this, function() { this._userVerifier.disconnect(signalId); @@ -6190,7 +6190,7 @@ index 50e9502..4a36cd3 100644 + + if (this._isModal) + return true; - + + if (!Main.pushModal(this.actor, { timestamp: timestamp, + keybindingMode: Shell.KeyBindingMode.UNLOCK_SCREEN })) + return false; @@ -6208,14 +6208,14 @@ index 50e9502..4a36cd3 100644 } }); +Signals.addSignalMethods(UnlockDialog.prototype); --- +-- 1.8.3.1 -From 64036b7725a84cc2f47848c73ac9a1d6150c7089 Mon Sep 17 00:00:00 2001 +From 8e8f1e524eb010414379b0a2f1ca62cbe238c777 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 23 Jul 2013 20:37:42 -0400 -Subject: [PATCH 22/66] gdmUtil: separate AuthPrompt out into its own file +Subject: [PATCH 22/69] gdmUtil: separate AuthPrompt out into its own file It's cleaner to have it in its own file than to cram it into util.js, so this commit moves it. @@ -6236,55 +6236,55 @@ index e8dd927..57f08e2 100644 +++ b/js/Makefile.am @@ -1,49 +1,50 @@ NULL = - + EXTRA_DIST = misc/config.js.in CLEANFILES = misc/config.js - + misc/config.js: misc/config.js.in Makefile - [ -d $(@D) ] || $(mkdir_p) $(@D) ; \ - sed -e "s|[@]PACKAGE_NAME@|$(PACKAGE_NAME)|g" \ - -e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \ - -e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \ - -e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \ - -e "s|[@]datadir@|$(datadir)|g" \ - -e "s|[@]libexecdir@|$(libexecdir)|g" \ - -e "s|[@]sysconfdir@|$(sysconfdir)|g" \ + [ -d $(@D) ] || $(mkdir_p) $(@D) ; \ + sed -e "s|[@]PACKAGE_NAME@|$(PACKAGE_NAME)|g" \ + -e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \ + -e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \ + -e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \ + -e "s|[@]datadir@|$(datadir)|g" \ + -e "s|[@]libexecdir@|$(libexecdir)|g" \ + -e "s|[@]sysconfdir@|$(sysconfdir)|g" \ $< > $@ - + jsdir = $(pkgdatadir)/js - + nobase_dist_js_DATA = \ + gdm/authPrompt.js \ - gdm/batch.js \ - gdm/fingerprint.js \ - gdm/loginDialog.js \ - gdm/powerMenu.js \ - gdm/realmd.js \ - gdm/util.js \ - extensionPrefs/main.js \ - misc/config.js \ - misc/extensionUtils.js \ - misc/fileUtils.js \ - misc/gnomeSession.js \ - misc/hash.js \ - misc/history.js \ - misc/jsParse.js \ - misc/loginManager.js \ - misc/modemManager.js \ - misc/params.js \ - misc/util.js \ - perf/core.js \ - ui/altTab.js \ - ui/appDisplay.js \ - ui/appFavorites.js \ - ui/backgroundMenu.js \ - ui/background.js \ - ui/boxpointer.js \ - ui/calendar.js \ - ui/checkBox.js \ - ui/ctrlAltTab.js \ - ui/dash.js \ - ui/dateMenu.js \ + gdm/batch.js \ + gdm/fingerprint.js \ + gdm/loginDialog.js \ + gdm/powerMenu.js \ + gdm/realmd.js \ + gdm/util.js \ + extensionPrefs/main.js \ + misc/config.js \ + misc/extensionUtils.js \ + misc/fileUtils.js \ + misc/gnomeSession.js \ + misc/hash.js \ + misc/history.js \ + misc/jsParse.js \ + misc/loginManager.js \ + misc/modemManager.js \ + misc/params.js \ + misc/util.js \ + perf/core.js \ + ui/altTab.js \ + ui/appDisplay.js \ + ui/appFavorites.js \ + ui/backgroundMenu.js \ + ui/background.js \ + ui/boxpointer.js \ + ui/calendar.js \ + ui/checkBox.js \ + ui/ctrlAltTab.js \ + ui/dash.js \ + ui/dateMenu.js \ diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js new file mode 100644 index 0000000..bb59d96 @@ -6605,7 +6605,7 @@ index e9dd6b2..d9e3898 100644 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ - + const AccountsService = imports.gi.AccountsService; const Atk = imports.gi.Atk; const Clutter = imports.gi.Clutter; @@ -6619,7 +6619,7 @@ index e9dd6b2..d9e3898 100644 const Shell = imports.gi.Shell; const Signals = imports.signals; const St = imports.gi.St; - + +const AuthPrompt = imports.gdm.authPrompt; const Batch = imports.gdm.batch; const BoxPointer = imports.ui.boxpointer; @@ -6632,22 +6632,22 @@ index e9dd6b2..d9e3898 100644 const Tweener = imports.ui.tweener; const UserMenu = imports.ui.userMenu; const UserWidget = imports.ui.userWidget; - + const _FADE_ANIMATION_TIME = 0.25; const _SCROLL_ANIMATION_TIME = 0.5; const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0; const _LOGO_ICON_HEIGHT = 48; - + let _loginDialog = null; - + const UserListItem = new Lang.Class({ Name: 'UserListItem', - + _init: function(user) { this.user = user; this._userChangedId = this.user.connect('changed', Lang.bind(this, this._onUserChanged)); - + let layout = new St.BoxLayout({ vertical: false }); this.actor = new St.Button({ style_class: 'login-dialog-user-list-item', button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, @@ -6658,11 +6658,11 @@ index e9dd6b2..d9e3898 100644 Lang.bind(this, this._updateDisableUserList)); this._settings.connect('changed::' + GdmUtil.LOGO_KEY, Lang.bind(this, this._updateLogo)); - + this._textureCache = St.TextureCache.get_default(); this._textureCache.connect('texture-file-changed', Lang.bind(this, this._updateLogoTexture)); - + this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', vertical: true, visible: false }); @@ -6670,18 +6670,18 @@ index e9dd6b2..d9e3898 100644 align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); this.actor.add_child(this._userSelectionBox); - + this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', text: '' }); this._userSelectionBox.add(this._bannerLabel); this._updateBanner(); - + this._userList = new UserList(); this._userSelectionBox.add(this._userList.actor, { expand: true, x_fill: true, y_fill: true }); - + - this._authPrompt = new GdmUtil.AuthPrompt(); + this._authPrompt = new AuthPrompt.AuthPrompt(); this._authPrompt.hide(); @@ -6689,15 +6689,15 @@ index e9dd6b2..d9e3898 100644 Lang.bind(this, function() { this.cancel(); })); - + this._authPrompt.actor.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); - + this.actor.add_child(this._authPrompt.actor); this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._authPrompt.actor, coordinate: Clutter.BindCoordinate.WIDTH })); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -6710,17 +6710,17 @@ index e9dd6b2..d9e3898 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn)); this._notListedButton.hide(); - + diff --git a/js/gdm/util.js b/js/gdm/util.js index 084bc7b..20540b7 100644 --- a/js/gdm/util.js +++ b/js/gdm/util.js @@ -1,70 +1,64 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - + const Clutter = imports.gi.Clutter; const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; @@ -6728,7 +6728,7 @@ index 084bc7b..20540b7 100644 const Mainloop = imports.mainloop; const Signals = imports.signals; const St = imports.gi.St; - + -const Panel = imports.ui.panel; const Batch = imports.gdm.batch; const Fprint = imports.gdm.fingerprint; @@ -6737,24 +6737,24 @@ index 084bc7b..20540b7 100644 const ShellEntry = imports.ui.shellEntry; const Tweener = imports.ui.tweener; -const UserWidget = imports.ui.userWidget; - + const PASSWORD_SERVICE_NAME = 'gdm-password'; const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint'; const FADE_ANIMATION_TIME = 0.16; const CLONE_FADE_ANIMATION_TIME = 0.25; - + const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen'; const FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication'; const BANNER_MESSAGE_KEY = 'banner-message-enable'; const BANNER_MESSAGE_TEXT_KEY = 'banner-message-text'; const ALLOWED_FAILURES_KEY = 'allowed-failures'; - + const LOGO_KEY = 'logo'; const DISABLE_USER_LIST_KEY = 'disable-user-list'; - + // Give user 16ms to read each character of a PAM message const USER_READ_TIME = 16 - + -const DEFAULT_BUTTON_WELL_ICON_SIZE = 24; -const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; -const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; @@ -6762,11 +6762,11 @@ index 084bc7b..20540b7 100644 function fadeInActor(actor) { if (actor.opacity == 255 && actor.visible) return null; - + let hold = new Batch.Hold(); actor.show(); let [minHeight, naturalHeight] = actor.get_preferred_height(-1); - + actor.opacity = 0; actor.set_height(0); Tweener.addTween(actor, @@ -6779,10 +6779,10 @@ index 084bc7b..20540b7 100644 hold.release(); }, }); - + return hold; } - + function fadeOutActor(actor) { if (!actor.visible || actor.opacity == 0) { actor.opacity = 0; @@ -6804,10 +6804,10 @@ index 084bc7b..20540b7 100644 })); } } - + this.emit('verification-failed'); }, - + _onConversationStopped: function(client, serviceName) { // if the password service fails, then cancel everything. // But if, e.g., fingerprint fails, still give @@ -6815,7 +6815,7 @@ index 084bc7b..20540b7 100644 if (serviceName == PASSWORD_SERVICE_NAME) { this._verificationFailed(true); } - + this.emit('hide-login-hint'); }, }); @@ -7105,7 +7105,7 @@ index 4a36cd3..7fd5271 100644 +++ b/js/ui/unlockDialog.js @@ -1,96 +1,97 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - + const AccountsService = imports.gi.AccountsService; const Atk = imports.gi.Atk; const Clutter = imports.gi.Clutter; @@ -7118,58 +7118,58 @@ index 4a36cd3..7fd5271 100644 const Signals = imports.signals; const Shell = imports.gi.Shell; const St = imports.gi.St; - + const Layout = imports.ui.layout; const Main = imports.ui.main; const Panel = imports.ui.panel; const Tweener = imports.ui.tweener; const UserMenu = imports.ui.userMenu; const UserWidget = imports.ui.userWidget; - + +const AuthPrompt = imports.gdm.authPrompt; const Batch = imports.gdm.batch; const GdmUtil = imports.gdm.util; const LoginDialog = imports.gdm.loginDialog; - + // The timeout before going back automatically to the lock screen (in seconds) const IDLE_TIMEOUT = 2 * 60; - + const UnlockDialog = new Lang.Class({ Name: 'UnlockDialog', - + _init: function(parentActor) { this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW, style_class: 'login-dialog', visible: false }); - + this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true })); parentActor.add_child(this.actor); - + this._userManager = AccountsService.UserManager.get_default(); this._userName = GLib.get_user_name(); this._user = this._userManager.get_user(this._userName); - + this._firstQuestion = true; - + this._greeterClient = new Gdm.Client(); this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true }); this._userVerified = false; - + this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage)); this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete)); this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed)); this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); - + this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint)); this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint)); - + this._promptBox = new St.BoxLayout({ vertical: true }); this.actor.add_child(this._promptBox); this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); - + - this._authPrompt = new GdmUtil.AuthPrompt(); + this._authPrompt = new AuthPrompt.AuthPrompt(); this._authPrompt.setUser(this._user); @@ -7177,11 +7177,11 @@ index 4a36cd3..7fd5271 100644 this._authPrompt.nextButton.label = _("Unlock"); this._authPrompt.connect('cancel', Lang.bind(this, this._escape)); this._authPrompt.connect('next', Lang.bind(this, this._doUnlock)); - + this._promptBox.add_child(this._authPrompt.actor); - + this.allowCancel = false; - + let screenSaverSettings = new Gio.Settings({ schema: 'org.gnome.desktop.screensaver' }); if (screenSaverSettings.get_boolean('user-switch-enabled')) { let otherUserLabel = new St.Label({ text: _("Log in as another user"), @@ -7197,19 +7197,19 @@ index 4a36cd3..7fd5271 100644 } else { this._otherUserButton = null; } - + this._updateSensitivity(true); - + let batch = new Batch.Hold(); this._userVerifier.begin(this._userName, batch); --- +-- 1.8.3.1 -From 7a4ede993d72274f52161ee9979060911f3b6c18 Mon Sep 17 00:00:00 2001 +From 849b77a62febc33bf2b7c8a524247cac77800b39 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 22 Jul 2013 11:07:35 -0400 -Subject: [PATCH 23/66] authPrompt: move unlock and login user verifier code +Subject: [PATCH 23/69] authPrompt: move unlock and login user verifier code here There's quite a bit of duplicated code between the login dialog @@ -7231,12 +7231,12 @@ index bb59d96..b0dcd0d 100644 +++ b/js/gdm/authPrompt.js @@ -1,161 +1,266 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - + const Clutter = imports.gi.Clutter; const Lang = imports.lang; const Signals = imports.signals; const St = imports.gi.St; - + const Panel = imports.ui.panel; +const Batch = imports.gdm.batch; +const GdmUtil = imports.gdm.util; @@ -7244,11 +7244,11 @@ index bb59d96..b0dcd0d 100644 const ShellEntry = imports.ui.shellEntry; const Tweener = imports.ui.tweener; const UserWidget = imports.ui.userWidget; - + const DEFAULT_BUTTON_WELL_ICON_SIZE = 24; const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; - + +const AuthPromptMode = { + UNLOCK_ONLY: 0, + UNLOCK_OR_LOG_IN: 1 @@ -7256,7 +7256,7 @@ index bb59d96..b0dcd0d 100644 + const AuthPrompt = new Lang.Class({ Name: 'AuthPrompt', - + - _init: function() { + _init: function(gdmClient, mode) { + this.verifyingUser = false; @@ -7300,7 +7300,7 @@ index bb59d96..b0dcd0d 100644 + this.cancel(); } })); - + this._userWell = new St.Bin({ x_fill: true, x_align: St.Align.START }); this.actor.add(this._userWell, @@ -7309,7 +7309,7 @@ index bb59d96..b0dcd0d 100644 y_fill: true, expand: true }); this._label = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this.actor.add(this._label, { expand: true, x_fill: true, @@ -7318,40 +7318,40 @@ index bb59d96..b0dcd0d 100644 this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry', can_focus: true }); ShellEntry.addContextMenu(this._entry, { isPassword: true }); - + this.actor.add(this._entry, { expand: true, x_fill: true, y_fill: false, x_align: St.Align.START }); - + this._entry.grab_key_focus(); - + this._message = new St.Label({ opacity: 0 }); this.actor.add(this._message, { x_fill: true }); - + this._loginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' }); this.actor.add(this._loginHint); - + this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box', vertical: false }); this.actor.add(this._buttonBox, { expand: true, x_align: St.Align.MIDDLE, y_align: St.Align.END }); - + this._defaultButtonWell = new St.Widget(); this._defaultButtonWellActor = null; - + this._initButtons(); - + let spinnerIcon = global.datadir + '/theme/process-working.svg'; this._spinner = new Panel.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE); this._spinner.actor.opacity = 0; this._spinner.actor.show(); this._defaultButtonWell.add_child(this._spinner.actor); }, - + + _onDestroy: function() { + this._userVerifier.clear(); + }, @@ -7373,7 +7373,7 @@ index bb59d96..b0dcd0d 100644 y_fill: false, x_align: St.Align.START, y_align: St.Align.END }); - + this._buttonBox.add(this._defaultButtonWell, { expand: true, x_fill: false, @@ -7396,9 +7396,9 @@ index bb59d96..b0dcd0d 100644 y_fill: false, x_align: St.Align.END, y_align: St.Align.END }); - + this._updateNextButtonSensitivity(this._entry.text.length > 0); - + this._entry.clutter_text.connect('text-changed', Lang.bind(this, function() { this._updateNextButtonSensitivity(this._entry.text.length > 0); @@ -7407,7 +7407,7 @@ index bb59d96..b0dcd0d 100644 this.emit('next'); })); }, - + + _onAskQuestion: function(verifier, serviceName, question, passwordChar) { + if (this._preemptiveAnswer) { + this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer); @@ -7471,28 +7471,28 @@ index bb59d96..b0dcd0d 100644 + addActorToDefaultButtonWell: function(actor) { this._defaultButtonWell.add_child(actor); - + actor.add_constraint(new Clutter.AlignConstraint({ source: this._spinner.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); }, - + setActorInDefaultButtonWell: function(actor, animate) { if (!this._defaultButtonWellActor && !actor) return; - + let oldActor = this._defaultButtonWellActor; - + if (oldActor) Tweener.removeTweens(oldActor); - + let isSpinner; if (actor == this._spinner.actor) isSpinner = true; else isSpinner = false; - + if (this._defaultButtonWellActor != actor && oldActor) { if (!animate) { oldActor.opacity = 0; @@ -7503,13 +7503,13 @@ index bb59d96..b0dcd0d 100644 this.setActorInDefaultButtonWell(null, true); this.actor.hide(); this._loginHint.opacity = 0; - + this.setUser(null); - + this.updateSensitivity(true); this._entry.set_text(''); }, - + setUser: function(user) { if (user) { let userWidget = new UserWidget.UserWidget(user); @@ -7518,7 +7518,7 @@ index bb59d96..b0dcd0d 100644 this._userWell.set_child(null); } }, - + setHint: function(message) { if (message) { this._loginHint.set_text(message) @@ -7528,7 +7528,7 @@ index bb59d96..b0dcd0d 100644 this._loginHint.set_text(''); } }, - + reset: function() { + this.verifyingUser = false; + this.userVerified = false; @@ -7541,11 +7541,11 @@ index bb59d96..b0dcd0d 100644 + + this.emit('reset'); }, - + addCharacter: function(unichar) { if (!this._entry.visible) return; - + this._entry.grab_key_focus(); this._entry.clutter_text.insert_unichar(unichar); + }, @@ -7590,15 +7590,15 @@ index d9e3898..fe594e4 100644 --- a/js/gdm/loginDialog.js +++ b/js/gdm/loginDialog.js @@ -375,123 +375,112 @@ const SessionMenuButton = new Lang.Class({ - + let id = ids[i]; let item = new PopupMenu.PopupMenuItem(sessionName); this._menu.addMenuItem(item); this._items[id] = item; - + if (!this._activeSessionId) this.setActiveSession(id); - + item.connect('activate', Lang.bind(this, function() { this.setActiveSession(id); })); @@ -7606,36 +7606,36 @@ index d9e3898..fe594e4 100644 } }); Signals.addSignalMethods(SessionMenuButton.prototype); - + const LoginDialog = new Lang.Class({ Name: 'LoginDialog', - + _init: function(parentActor) { this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW, style_class: 'login-dialog', visible: false }); - + this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true })); this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); parentActor.add_child(this.actor); - + this._userManager = AccountsService.UserManager.get_default() - this._greeterClient = new Gdm.Client(); + let gdmClient = new Gdm.Client(); - + if (GLib.getenv('GDM_GREETER_TEST') != '1') { - this._greeter = this._greeterClient.get_greeter_sync(null); + this._greeter = gdmClient.get_greeter_sync(null); - + this._greeter.connect('default-session-name-changed', Lang.bind(this, this._onDefaultSessionChanged)); - + this._greeter.connect('session-opened', Lang.bind(this, this._onSessionOpened)); this._greeter.connect('timed-login-requested', Lang.bind(this, this._onTimedLoginRequested)); } - + - this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient); - this._userVerifier.connect('ask-question', Lang.bind(this, this._askQuestion)); - this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage)); @@ -7646,7 +7646,7 @@ index d9e3898..fe594e4 100644 - this._verifyingUser = false; - this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA }); - + this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY, Lang.bind(this, this._updateBanner)); this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY, @@ -7655,11 +7655,11 @@ index d9e3898..fe594e4 100644 Lang.bind(this, this._updateDisableUserList)); this._settings.connect('changed::' + GdmUtil.LOGO_KEY, Lang.bind(this, this._updateLogo)); - + this._textureCache = St.TextureCache.get_default(); this._textureCache.connect('texture-file-changed', Lang.bind(this, this._updateLogoTexture)); - + this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', vertical: true, visible: false }); @@ -7667,18 +7667,18 @@ index d9e3898..fe594e4 100644 align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); this.actor.add_child(this._userSelectionBox); - + this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', text: '' }); this._userSelectionBox.add(this._bannerLabel); this._updateBanner(); - + this._userList = new UserList(); this._userSelectionBox.add(this._userList.actor, { expand: true, x_fill: true, y_fill: true }); - + - this._authPrompt = new AuthPrompt.AuthPrompt(); + this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOGIN); + this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted)); @@ -7688,15 +7688,15 @@ index d9e3898..fe594e4 100644 - Lang.bind(this, function() { - this.cancel(); - })); - + this._authPrompt.actor.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); - + this.actor.add_child(this._authPrompt.actor); this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._authPrompt.actor, coordinate: Clutter.BindCoordinate.WIDTH })); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -7709,15 +7709,15 @@ index d9e3898..fe594e4 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn)); this._notListedButton.hide(); - + this._userSelectionBox.add(this._notListedButton, { expand: false, x_align: St.Align.START, x_fill: true }); - + @@ -514,296 +503,213 @@ const LoginDialog = new Lang.Class({ this._userManager.disconnect(this._userManagerLoadedId); this._userManagerLoadedId = 0; @@ -7725,13 +7725,13 @@ index d9e3898..fe594e4 100644 })); else this._loadUserList(); - + this._userList.connect('activate', Lang.bind(this, function(userList, item) { this._onUserListActivated(item); })); - - + + this._sessionMenuButton = new SessionMenuButton(); this._sessionMenuButton.connect('session-activated', Lang.bind(this, function(list, sessionId) { @@ -7740,25 +7740,25 @@ index d9e3898..fe594e4 100644 this._sessionMenuButton.actor.opacity = 0; this._sessionMenuButton.actor.show(); this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor); - + }, - + _updateDisableUserList: function() { let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); - + if (disableUserList != this._disableUserList) { this._disableUserList = disableUserList; - + - if (!this._verifyingUser) + if (!this._authPrompt.verifyingUser) this._reset(); } }, - + _updateBanner: function() { let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); - + if (enabled && text) { this._bannerLabel.set_text(text); this._bannerLabel.show(); @@ -7766,25 +7766,25 @@ index d9e3898..fe594e4 100644 this._bannerLabel.hide(); } }, - + _updateLogoTexture: function(cache, uri) { if (this._logoFileUri != uri) return; - + let icon = null; if (this._logoFileUri) icon = this._textureCache.load_uri_async(this._logoFileUri, -1, _LOGO_ICON_HEIGHT); this._logoBin.set_child(icon); }, - + _updateLogo: function() { let path = this._settings.get_string(GdmUtil.LOGO_KEY); - + this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; this._updateLogoTexture(this._textureCache, this._logoFileUri); }, - + + _onPrompted: function() { + this._sessionMenuButton.updateSensitivity(true); + @@ -7800,20 +7800,20 @@ index d9e3898..fe594e4 100644 - this._userVerifier.clear(); + if (this._authPrompt.verifyingUser) + return; - + - this._updateSensitivity(true); - this._authPrompt.reset(); + this._sessionMenuButton.updateSensitivity(true); - + this._user = null; - this._verifyingUser = false; - + if (this._disableUserList) this._hideUserListAndLogIn(); else this._showUserList(); }, - + - _verificationFailed: function() { - this._authPrompt.clear(); - @@ -7824,7 +7824,7 @@ index d9e3898..fe594e4 100644 _onDefaultSessionChanged: function(client, sessionId) { this._sessionMenuButton.setActiveSession(sessionId); }, - + - _showMessage: function(userVerifier, message, styleClass) { - this._authPrompt.setMessage(message, styleClass); - }, @@ -7848,16 +7848,16 @@ index d9e3898..fe594e4 100644 - if (this._verifyingUser) + if (this._authPrompt.verifyingUser) return true; - + if (!this._user) return false; - + if (this._user.is_logged_in) return false; - + return true; }, - + - _showPrompt: function(forSecret) { + _showPrompt: function() { + if (this._authPrompt.actor.visible) @@ -7931,32 +7931,32 @@ index d9e3898..fe594e4 100644 - let batch = new Batch.ConsecutiveBatch(this, tasks); - return batch.run(); }, - + _showRealmLoginHint: function(realmManager, hint) { if (!hint) return; - + hint = hint.replace(/%U/g, 'user'); hint = hint.replace(/%D/g, 'DOMAIN'); hint = hint.replace(/%[^UD]/g, ''); - + // Translators: this message is shown below the username entry field // to clue the user in on how to login to the local network realm - this._showLoginHint(null, _("(e.g., user or %s)").format(hint)); + this._authPrompt.setHint(_("(e.g., user or %s)").format(hint)); }, - + _askForUsernameAndLogIn: function() { this._authPrompt.setPasswordChar(''); this._authPrompt.setQuestion(_("Username: ")); - + let realmManager = new Realmd.Manager(); - let signalId = realmManager.connect('login-format-changed', - Lang.bind(this, this._showRealmLoginHint)); + let realmSignalId = realmManager.connect('login-format-changed', + Lang.bind(this, this._showRealmLoginHint)); this._showRealmLoginHint(realmManager.loginFormat); - + - let tasks = [this._showPrompt, - - function() { @@ -7977,7 +7977,7 @@ index d9e3898..fe594e4 100644 + this._authPrompt.clear(); + this._authPrompt.startSpinning(); + this._authPrompt.begin({ userName: answer }); - + - let batch = new Batch.ConsecutiveBatch(this, tasks); - return batch.run(); + realmManager.disconnect(realmSignalId) @@ -7986,7 +7986,7 @@ index d9e3898..fe594e4 100644 + this._authPrompt.cancelButton.hide(); + this._showPrompt(); }, - + _startSession: function(serviceName) { Tweener.addTween(this.actor, { opacity: 0, @@ -7994,7 +7994,7 @@ index d9e3898..fe594e4 100644 transition: 'easeOutQuad', onUpdate: function() { let children = Main.layoutManager.uiGroup.get_children(); - + for (let i = 0; i < children.length; i++) { if (children[i] != Main.layoutManager.screenShieldGroup) children[i].opacity = this.actor.opacity; @@ -8009,7 +8009,7 @@ index d9e3898..fe594e4 100644 }, onCompleteScope: this }); }, - + _onSessionOpened: function(client, serviceName) { - if (!this._userVerifier.hasPendingMessages) { + this._authPrompt.finish(Lang.bind(this, function() { @@ -8023,34 +8023,34 @@ index d9e3898..fe594e4 100644 - } + })); }, - + _waitForItemForUser: function(userName) { let item = this._userList.getItemFromUserName(userName); - + if (item) return null; - + let hold = new Batch.Hold(); let signalId = this._userList.connect('item-added', Lang.bind(this, function() { let item = this._userList.getItemFromUserName(userName); - + if (item) hold.release(); })); - + hold.connect('release', Lang.bind(this, function() { this._userList.disconnect(signalId); })); - + return hold; }, - + _showTimedLoginAnimation: function() { this._timedLoginItem.actor.grab_key_focus(); return this._timedLoginItem.showTimedLoginIndicator(this._timedLoginAnimationTime); }, - + _blockTimedLoginUntilIdle: function() { @@ -896,77 +802,69 @@ const LoginDialog = new Lang.Class({ } @@ -8058,23 +8058,23 @@ index d9e3898..fe594e4 100644 event.type() == Clutter.EventType.BUTTON_RELEASE) { this._resetTimedLogin(); } - + return false; })); }, - + _setUserListExpanded: function(expanded) { this._userList.updateStyle(expanded); this._userSelectionBox.visible = expanded; }, - + _hideUserListAndLogIn: function() { this._setUserListExpanded(false); if (this._userSelectionBox.visible) GdmUtil.cloneAndFadeOutActor(this._userSelectionBox); this._askForUsernameAndLogIn(); }, - + _showUserList: function() { this._authPrompt.hide(); this._sessionMenuButton.close(); @@ -8082,7 +8082,7 @@ index d9e3898..fe594e4 100644 this._notListedButton.show(); this._userList.actor.grab_key_focus(); }, - + - _beginVerificationForUser: function(userName) { - let hold = new Batch.Hold(); - @@ -8093,7 +8093,7 @@ index d9e3898..fe594e4 100644 - _beginVerificationForItem: function(item) { this._authPrompt.setUser(item.user); - + - let tasks = [function() { - let userName = item.user.get_user_name(); - return this._beginVerificationForUser(userName); @@ -8107,7 +8107,7 @@ index d9e3898..fe594e4 100644 + hold: hold }); + return hold; }, - + _onUserListActivated: function(activatedItem) { let tasks = [function() { return GdmUtil.cloneAndFadeOutActor(this._userSelectionBox); @@ -8115,24 +8115,24 @@ index d9e3898..fe594e4 100644 function() { this._setUserListExpanded(false); }]; - + this._user = activatedItem.user; - + let batch = new Batch.ConcurrentBatch(this, [new Batch.ConsecutiveBatch(this, tasks), this._beginVerificationForItem(activatedItem)]); batch.run(); }, - + _onDestroy: function() { if (this._userManagerLoadedId) { this._userManager.disconnect(this._userManagerLoadedId); this._userManagerLoadedId = 0; } }, - + _loadUserList: function() { let users = this._userManager.list_users(); - + for (let i = 0; i < users.length; i++) { this._userList.addUser(users[i]); } @@ -8147,30 +8147,30 @@ index 7fd5271..53ff9b6 100644 const Tweener = imports.ui.tweener; const UserMenu = imports.ui.userMenu; const UserWidget = imports.ui.userWidget; - + const AuthPrompt = imports.gdm.authPrompt; const Batch = imports.gdm.batch; const GdmUtil = imports.gdm.util; const LoginDialog = imports.gdm.loginDialog; - + // The timeout before going back automatically to the lock screen (in seconds) const IDLE_TIMEOUT = 2 * 60; - + const UnlockDialog = new Lang.Class({ Name: 'UnlockDialog', - + _init: function(parentActor) { this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW, style_class: 'login-dialog', visible: false }); - + this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true })); parentActor.add_child(this.actor); - + this._userManager = AccountsService.UserManager.get_default(); this._userName = GLib.get_user_name(); this._user = this._userManager.get_user(this._userName); - + - this._firstQuestion = true; - - this._greeterClient = new Gdm.Client(); @@ -8191,7 +8191,7 @@ index 7fd5271..53ff9b6 100644 this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); - + - this._authPrompt = new AuthPrompt.AuthPrompt(); + this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY); + this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); @@ -8200,11 +8200,11 @@ index 7fd5271..53ff9b6 100644 this._authPrompt.nextButton.label = _("Unlock"); - this._authPrompt.connect('cancel', Lang.bind(this, this._escape)); - this._authPrompt.connect('next', Lang.bind(this, this._doUnlock)); - + this._promptBox.add_child(this._authPrompt.actor); - + this.allowCancel = false; - + let screenSaverSettings = new Gio.Settings({ schema: 'org.gnome.desktop.screensaver' }); if (screenSaverSettings.get_boolean('user-switch-enabled')) { let otherUserLabel = new St.Label({ text: _("Log in as another user"), @@ -8220,28 +8220,28 @@ index 7fd5271..53ff9b6 100644 } else { this._otherUserButton = null; } - + + this._authPrompt.begin({ userName: this._userName }); this._updateSensitivity(true); - + - let batch = new Batch.Hold(); - this._userVerifier.begin(this._userName, batch); - Main.ctrlAltTabManager.addGroup(this.actor, _("Unlock Window"), 'dialog-password-symbolic'); - + this._idleMonitor = new GnomeDesktop.IdleMonitor(); this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape)); }, - + _updateSensitivity: function(sensitive) { this._authPrompt.updateSensitivity(sensitive); - + if (this._otherUserButton) { this._otherUserButton.reactive = sensitive; this._otherUserButton.can_focus = sensitive; } }, - + - _showMessage: function(userVerifier, message, styleClass) { - this._authPrompt.setMessage(message, styleClass); - }, @@ -8321,7 +8321,7 @@ index 7fd5271..53ff9b6 100644 - this._authPrompt.stopSpinning(); + this.emit('failed'); }, - + _escape: function() { if (this.allowCancel) { - this._userVerifier.cancel(); @@ -8329,37 +8329,37 @@ index 7fd5271..53ff9b6 100644 this.emit('failed'); } }, - + _otherUserClicked: function(button, event) { Gdm.goto_login_session_sync(null); - + - this._userVerifier.cancel(); - this.emit('failed'); + this._authPrompt.cancel(); }, - + destroy: function() { - this._userVerifier.clear(); + this.popModal(); this.actor.destroy(); - + if (this._idleWatchId) { this._idleMonitor.remove_watch(this._idleWatchId); this._idleWatchId = 0; } }, - + cancel: function() { - this._userVerifier.cancel(null); + this._authPrompt.cancel(); - + this.destroy(); }, - + addCharacter: function(unichar) { this._authPrompt.addCharacter(unichar); }, - + finish: function(onComplete) { - if (!this._userVerifier.hasPendingMessages) { - onComplete(); @@ -8373,22 +8373,22 @@ index 7fd5271..53ff9b6 100644 - })); + this._authPrompt.finish(onComplete); }, - + open: function(timestamp) { this.actor.show(); - + if (this._isModal) return true; - + if (!Main.pushModal(this.actor, { timestamp: timestamp, keybindingMode: Shell.KeyBindingMode.UNLOCK_SCREEN })) return false; - + this._isModal = true; - + return true; }, - + popModal: function(timestamp) { if (this._isModal) { Main.popModal(this.actor, timestamp); @@ -8397,14 +8397,14 @@ index 7fd5271..53ff9b6 100644 } }); Signals.addSignalMethods(UnlockDialog.prototype); --- +-- 1.8.3.1 -From fad242096f53bee21ac5667bd6c7e3285100c137 Mon Sep 17 00:00:00 2001 +From 03072fa74c2fdd3129c5329cca04a9789318cdbc Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 24 Jul 2013 11:25:02 -0400 -Subject: [PATCH 24/66] loginDialog: correct typo +Subject: [PATCH 24/69] loginDialog: correct typo commit 7e7295f259febf34c89659a9bcb05f9924fa1976 introduced a typo (LOGIN instead of LOG_IN). @@ -8425,11 +8425,11 @@ index fe594e4..8fecc28 100644 Lang.bind(this, this._updateDisableUserList)); this._settings.connect('changed::' + GdmUtil.LOGO_KEY, Lang.bind(this, this._updateLogo)); - + this._textureCache = St.TextureCache.get_default(); this._textureCache.connect('texture-file-changed', Lang.bind(this, this._updateLogoTexture)); - + this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', vertical: true, visible: false }); @@ -8437,32 +8437,32 @@ index fe594e4..8fecc28 100644 align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); this.actor.add_child(this._userSelectionBox); - + this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', text: '' }); this._userSelectionBox.add(this._bannerLabel); this._updateBanner(); - + this._userList = new UserList(); this._userSelectionBox.add(this._userList.actor, { expand: true, x_fill: true, y_fill: true }); - + - this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOGIN); + this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN); this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted)); this._authPrompt.connect('reset', Lang.bind(this, this._reset)); this._authPrompt.hide(); - + this._authPrompt.actor.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); - + this.actor.add_child(this._authPrompt.actor); this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._authPrompt.actor, coordinate: Clutter.BindCoordinate.WIDTH })); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -8475,20 +8475,20 @@ index fe594e4..8fecc28 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn)); this._notListedButton.hide(); - + this._userSelectionBox.add(this._notListedButton, { expand: false, --- +-- 1.8.3.1 -From b39cf4e43d81b72a203a4129b65a1755d11529a7 Mon Sep 17 00:00:00 2001 +From 1f9975a9098165d7e4649140aabafa8ed4d07058 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 24 Jul 2013 10:53:48 -0400 -Subject: [PATCH 25/66] authPrompt: fade out message if user starts to type +Subject: [PATCH 25/69] authPrompt: fade out message if user starts to type If there are no messages in the queue and a user starts to type then we can safely hide the message label since the @@ -8508,12 +8508,12 @@ index b0dcd0d..75cf392 100644 +++ b/js/gdm/authPrompt.js @@ -1,49 +1,51 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - + const Clutter = imports.gi.Clutter; const Lang = imports.lang; const Signals = imports.signals; const St = imports.gi.St; - + const Panel = imports.ui.panel; const Batch = imports.gdm.batch; const GdmUtil = imports.gdm.util; @@ -8521,35 +8521,35 @@ index b0dcd0d..75cf392 100644 const ShellEntry = imports.ui.shellEntry; const Tweener = imports.ui.tweener; const UserWidget = imports.ui.userWidget; - + const DEFAULT_BUTTON_WELL_ICON_SIZE = 24; const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; - + +const MESSAGE_FADE_OUT_ANIMATION_TIME = 0.5; + const AuthPromptMode = { UNLOCK_ONLY: 0, UNLOCK_OR_LOG_IN: 1 }; - + const AuthPrompt = new Lang.Class({ Name: 'AuthPrompt', - + _init: function(gdmClient, mode) { this.verifyingUser = false; - + this._gdmClient = gdmClient; this._mode = mode; - + let reauthenticationOnly; if (this._mode == AuthPromptMode.UNLOCK_ONLY) reauthenticationOnly = true; else if (this._mode == AuthPromptMode.UNLOCK_OR_LOG_IN) reauthenticationOnly = false; - + this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly }); - + this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._onShowMessage)); this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed)); @@ -8557,11 +8557,11 @@ index b0dcd0d..75cf392 100644 this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); this._userVerifier.connect('show-login-hint', Lang.bind(this, this._onShowLoginHint)); this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._onHideLoginHint)); - + @@ -139,60 +141,63 @@ const AuthPrompt = new Lang.Class({ x_align: St.Align.START, y_align: St.Align.END }); - + this._buttonBox.add(this._defaultButtonWell, { expand: true, x_fill: false, @@ -8584,9 +8584,9 @@ index b0dcd0d..75cf392 100644 y_fill: false, x_align: St.Align.END, y_align: St.Align.END }); - + this._updateNextButtonSensitivity(this._entry.text.length > 0); - + this._entry.clutter_text.connect('text-changed', Lang.bind(this, function() { + if (!this._userVerifier.hasPendingMessages) @@ -8598,61 +8598,61 @@ index b0dcd0d..75cf392 100644 this.emit('next'); })); }, - + _onAskQuestion: function(verifier, serviceName, question, passwordChar) { if (this._preemptiveAnswer) { this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer); this._preemptiveAnswer = null; return; } - + if (this._queryingService) this.clear(); - + this._queryingService = serviceName; this.setPasswordChar(passwordChar); this.setQuestion(question); - + if (this.verifyingUser) this.cancelButton.show(); else this.cancelButton.hide(); - + if (passwordChar) { if (this._mode == AuthPromptMode.UNLOCK_ONLY) this.nextButton.label = _("Unlock"); else if (this._mode == AuthPromptMode.UNLOCK_OR_LOG_IN) @@ -304,62 +309,74 @@ const AuthPrompt = new Lang.Class({ }, - + clear: function() { this._entry.text = ''; this.stopSpinning(); }, - + setPasswordChar: function(passwordChar) { this._entry.clutter_text.set_password_char(passwordChar); this._entry.menu.isPassword = passwordChar != ''; }, - + setQuestion: function(question) { this._label.set_text(question); - + this._label.show(); this._entry.show(); - + this._loginHint.opacity = 0; this._loginHint.show(); - + this._entry.grab_key_focus(); }, - + getAnswer: function() { let text = this._entry.get_text(); - + return text; }, - + + _fadeOutMessage: function() { + if (this._message.opacity == 0) + return; @@ -8674,37 +8674,37 @@ index b0dcd0d..75cf392 100644 this._message.opacity = 0; } }, - + _updateNextButtonSensitivity: function(sensitive) { this.nextButton.reactive = sensitive; this.nextButton.can_focus = sensitive; }, - + updateSensitivity: function(sensitive) { this._updateNextButtonSensitivity(sensitive); this._entry.reactive = sensitive; this._entry.clutter_text.editable = sensitive; }, - + hide: function() { this.setActorInDefaultButtonWell(null, true); this.actor.hide(); this._loginHint.opacity = 0; - + this.setUser(null); - + this.updateSensitivity(true); this._entry.set_text(''); }, - --- + +-- 1.8.3.1 -From 6a8c7f5c122dc093a2f189d1bbd2a83bf0148697 Mon Sep 17 00:00:00 2001 +From b242ad1649db947f5f002685a4834ba3d5bd8f42 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 28 Jul 2013 12:40:55 -0400 -Subject: [PATCH 26/66] authPrompt: let PAM message wrap if longer than entry +Subject: [PATCH 26/69] authPrompt: let PAM message wrap if longer than entry Right now the whole authPrompt spreads out if a PAM message comes in that longer than the entry. @@ -8720,15 +8720,15 @@ https://bugzilla.gnome.org/show_bug.cgi?id=705037 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css -index 14ee74e..15457fe 100644 +index c42c19e..e074554 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css -@@ -2315,71 +2315,68 @@ StScrollBar StButton#vhandle:active { +@@ -2320,71 +2320,68 @@ StScrollBar StButton#vhandle:active { border-radius: 8px; width: 64px; height: 64px; } - + .login-dialog-not-listed-label { font-size: 10.5pt; font-weight: bold; @@ -8736,12 +8736,12 @@ index 14ee74e..15457fe 100644 padding-top: 1em; padding-left: 2px; } - + .login-dialog-not-listed-button:focus .login-dialog-not-listed-label, .login-dialog-not-listed-button:hover .login-dialog-not-listed-label { color: #E8E8E8; } - + .login-dialog-username { font-size: 16pt; font-weight: bold; @@ -8749,19 +8749,19 @@ index 14ee74e..15457fe 100644 padding-left: 15px; text-shadow: black 0px 4px 3px 0px; } - + .login-dialog-prompt-layout { padding-top: 24px; padding-bottom: 12px; spacing: 8px; + width: 23em; } - + .login-dialog-prompt-label { color: #eeeeee; font-size: 14px; } - + -.login-dialog-prompt-entry { - width: 20em; -} @@ -8769,33 +8769,33 @@ index 14ee74e..15457fe 100644 .login-dialog-session-list-button StIcon { icon-size: 1.25em; } - + .login-dialog-session-list-button { color: #8b8b8b; } - + .login-dialog-session-list-button:hover, .login-dialog-session-list-button:active { color: white; } - + .login-dialog-logo-bin { padding: 24px 0px; } - + .login-dialog .modal-dialog-button-box { spacing: 3px; } - + .login-dialog .modal-dialog-button { border-radius: 5px; padding: 3px 18px; } - + .login-dialog .modal-dialog-button:focus { padding: 2px 17px; } - + diff --git a/js/gdm/authPrompt.js b/js/gdm/authPrompt.js index 75cf392..49b98fa 100644 --- a/js/gdm/authPrompt.js @@ -8803,7 +8803,7 @@ index 75cf392..49b98fa 100644 @@ -69,60 +69,61 @@ const AuthPrompt = new Lang.Class({ } })); - + this._userWell = new St.Bin({ x_fill: true, x_align: St.Align.START }); this.actor.add(this._userWell, @@ -8812,7 +8812,7 @@ index 75cf392..49b98fa 100644 y_fill: true, expand: true }); this._label = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this.actor.add(this._label, { expand: true, x_fill: true, @@ -8821,55 +8821,55 @@ index 75cf392..49b98fa 100644 this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry', can_focus: true }); ShellEntry.addContextMenu(this._entry, { isPassword: true }); - + this.actor.add(this._entry, { expand: true, x_fill: true, y_fill: false, x_align: St.Align.START }); - + this._entry.grab_key_focus(); - + this._message = new St.Label({ opacity: 0 }); + this._message.clutter_text.line_wrap = true; this.actor.add(this._message, { x_fill: true }); - + this._loginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' }); this.actor.add(this._loginHint); - + this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box', vertical: false }); this.actor.add(this._buttonBox, { expand: true, x_align: St.Align.MIDDLE, y_align: St.Align.END }); - + this._defaultButtonWell = new St.Widget(); this._defaultButtonWellActor = null; - + this._initButtons(); - + let spinnerIcon = global.datadir + '/theme/process-working.svg'; this._spinner = new Panel.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE); this._spinner.actor.opacity = 0; this._spinner.actor.show(); this._defaultButtonWell.add_child(this._spinner.actor); }, - + _onDestroy: function() { this._userVerifier.clear(); }, - + _initButtons: function() { this.cancelButton = new St.Button({ style_class: 'modal-dialog-button', --- +-- 1.8.3.1 -From 94d84beac768c1bc7ed13b1cbdb4da60c9e9b242 Mon Sep 17 00:00:00 2001 +From 542b0fae6238e108248e62fc1adc598b28bbe244 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 22 Jul 2013 10:59:57 -0400 -Subject: [PATCH 27/66] authPrompt: Call next button "Unlock" when user +Subject: [PATCH 27/69] authPrompt: Call next button "Unlock" when user switching When a ShellUserVerifier is asked to verify a user at the login @@ -8897,33 +8897,33 @@ index 49b98fa..706cbe0 100644 @@ -172,63 +172,63 @@ const AuthPrompt = new Lang.Class({ if (!this._userVerifier.hasPendingMessages) this._fadeOutMessage(); - + this._updateNextButtonSensitivity(this._entry.text.length > 0); })); this._entry.clutter_text.connect('activate', Lang.bind(this, function() { this.emit('next'); })); }, - + _onAskQuestion: function(verifier, serviceName, question, passwordChar) { if (this._preemptiveAnswer) { this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer); this._preemptiveAnswer = null; return; } - + if (this._queryingService) this.clear(); - + this._queryingService = serviceName; this.setPasswordChar(passwordChar); this.setQuestion(question); - + if (this.verifyingUser) this.cancelButton.show(); else this.cancelButton.hide(); - + if (passwordChar) { - if (this._mode == AuthPromptMode.UNLOCK_ONLY) + if (this._userVerifier.reauthenticating) @@ -8934,39 +8934,39 @@ index 49b98fa..706cbe0 100644 } else { this.nextButton.label = _("Next"); } - + this.updateSensitivity(true); this.emit('prompted'); }, - + _onShowMessage: function(userVerifier, message, styleClass) { this.setMessage(message, styleClass); }, - + _onVerificationFailed: function() { this.clear(); - + this.updateSensitivity(true); this.setActorInDefaultButtonWell(null); this.userVerified = false; }, - + _onVerificationComplete: function() { this.userVerified = true; }, - + _onReset: function() { if (!this.userVerified) this.reset(); }, - + diff --git a/js/gdm/util.js b/js/gdm/util.js index 20540b7..1facf98 100644 --- a/js/gdm/util.js +++ b/js/gdm/util.js @@ -94,68 +94,70 @@ function cloneAndFadeOutActor(actor) { clone.set_position(x, y); - + let hold = new Batch.Hold(); Tweener.addTween(clone, { opacity: 0, @@ -8979,35 +8979,35 @@ index 20540b7..1facf98 100644 }); return hold; } - + const ShellUserVerifier = new Lang.Class({ Name: 'ShellUserVerifier', - + _init: function(client, params) { params = Params.parse(params, { reauthenticationOnly: false }); this._reauthOnly = params.reauthenticationOnly; - + this._client = client; - + this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA }); - + this._fprintManager = new Fprint.FprintManager(); this._messageQueue = []; this._messageQueueTimeoutId = 0; this.hasPendingMessages = false; + this.reauthenticating = false; - + this._failCounter = 0; }, - + begin: function(userName, hold) { this._cancellable = new Gio.Cancellable(); this._hold = hold; this._userName = userName; + this.reauthenticating = false; - + this._checkForFingerprintReader(); - + if (userName) { // If possible, reauthenticate an already running session, // so any session specific credentials get updated appropriately @@ -9017,21 +9017,21 @@ index 20540b7..1facf98 100644 this._client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot)); } }, - + cancel: function() { if (this._cancellable) this._cancellable.cancel(); - + if (this._userVerifier) this._userVerifier.call_cancel_sync(null); }, - + clear: function() { if (this._cancellable) { this._cancellable.cancel(); this._cancellable = null; } - + if (this._userVerifier) { this._userVerifier.run_dispose(); this._userVerifier = null; @@ -9040,15 +9040,15 @@ index 20540b7..1facf98 100644 this._haveFingerprintReader = true; })); }, - + _reportInitError: function(where, error) { logError(error, where); this._hold.release(); - + this._queueMessage(_("Authentication error"), 'login-dialog-message-warning'); this._verificationFailed(false); }, - + _reauthenticationChannelOpened: function(client, result) { try { this._userVerifier = client.open_reauthentication_channel_finish(result); @@ -9065,13 +9065,13 @@ index 20540b7..1facf98 100644 this._reportInitError('Failed to open reauthentication channel', e); return; } - + + this.reauthenticating = true; this._connectSignals(); this._beginVerification(); this._hold.release(); }, - + _userVerifierGot: function(client, result) { try { this._userVerifier = client.get_user_verifier_finish(result); @@ -9081,12 +9081,12 @@ index 20540b7..1facf98 100644 this._reportInitError('Failed to obtain user verifier', e); return; } - + this._connectSignals(); this._beginVerification(); this._hold.release(); }, - + _connectSignals: function() { this._userVerifier.connect('info', Lang.bind(this, this._onInfo)); this._userVerifier.connect('problem', Lang.bind(this, this._onProblem)); @@ -9096,15 +9096,15 @@ index 20540b7..1facf98 100644 this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete)); }, - --- + +-- 1.8.3.1 -From 309050b22017825ebe8ae8e7d307b7f0845951f5 Mon Sep 17 00:00:00 2001 +From 2fc335431dc903b7353745e3670df8c63237e6b7 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 29 Jul 2013 13:24:36 -0400 -Subject: [PATCH 28/66] authPrompt: disassociate from userVerifier when +Subject: [PATCH 28/69] authPrompt: disassociate from userVerifier when destroyed Otherwise, it won't get GC'd and we'll end up potentially calling @@ -9121,39 +9121,39 @@ index 706cbe0..d50f0fb 100644 +++ b/js/gdm/authPrompt.js @@ -96,60 +96,62 @@ const AuthPrompt = new Lang.Class({ this._entry.grab_key_focus(); - + this._message = new St.Label({ opacity: 0 }); this._message.clutter_text.line_wrap = true; this.actor.add(this._message, { x_fill: true }); - + this._loginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' }); this.actor.add(this._loginHint); - + this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box', vertical: false }); this.actor.add(this._buttonBox, { expand: true, x_align: St.Align.MIDDLE, y_align: St.Align.END }); - + this._defaultButtonWell = new St.Widget(); this._defaultButtonWellActor = null; - + this._initButtons(); - + let spinnerIcon = global.datadir + '/theme/process-working.svg'; this._spinner = new Panel.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE); this._spinner.actor.opacity = 0; this._spinner.actor.show(); this._defaultButtonWell.add_child(this._spinner.actor); }, - + _onDestroy: function() { this._userVerifier.clear(); + this._userVerifier.disconnectAll(); + this._userVerifier = null; }, - + _initButtons: function() { this.cancelButton = new St.Button({ style_class: 'modal-dialog-button', button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, @@ -9170,7 +9170,7 @@ index 706cbe0..d50f0fb 100644 y_fill: false, x_align: St.Align.START, y_align: St.Align.END }); - + this._buttonBox.add(this._defaultButtonWell, { expand: true, x_fill: false, @@ -9182,14 +9182,14 @@ index 706cbe0..d50f0fb 100644 reactive: true, can_focus: true, label: _("Next") }); --- +-- 1.8.3.1 -From c2c79e291c22d7abea617a4c8e1cb0299f7cc17a Mon Sep 17 00:00:00 2001 +From 04cd7cae1f815fccc55cd85ae5d1f085a2fd9dc1 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 28 Jul 2013 15:55:09 -0400 -Subject: [PATCH 29/66] loginDialog: don't ever call _reset directly +Subject: [PATCH 29/69] loginDialog: don't ever call _reset directly The only time we ever call _reset directly is when detecting changes to disable-user-list. We can implicitly @@ -9213,11 +9213,11 @@ index 8fecc28..1ed68ba 100644 Lang.bind(this, this._updateDisableUserList)); this._settings.connect('changed::' + GdmUtil.LOGO_KEY, Lang.bind(this, this._updateLogo)); - + this._textureCache = St.TextureCache.get_default(); this._textureCache.connect('texture-file-changed', Lang.bind(this, this._updateLogoTexture)); - + this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', vertical: true, visible: false }); @@ -9225,32 +9225,32 @@ index 8fecc28..1ed68ba 100644 align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); this.actor.add_child(this._userSelectionBox); - + this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', text: '' }); this._userSelectionBox.add(this._bannerLabel); this._updateBanner(); - + this._userList = new UserList(); this._userSelectionBox.add(this._userList.actor, { expand: true, x_fill: true, y_fill: true }); - + this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN); this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted)); - this._authPrompt.connect('reset', Lang.bind(this, this._reset)); + this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); this._authPrompt.hide(); - + this._authPrompt.actor.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); - + this.actor.add_child(this._authPrompt.actor); this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._authPrompt.actor, coordinate: Clutter.BindCoordinate.WIDTH })); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -9263,10 +9263,10 @@ index 8fecc28..1ed68ba 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn)); this._notListedButton.hide(); - + this._userSelectionBox.add(this._notListedButton, { expand: false, x_align: St.Align.START, @@ -9277,13 +9277,13 @@ index 8fecc28..1ed68ba 100644 })); else this._loadUserList(); - + this._userList.connect('activate', Lang.bind(this, function(userList, item) { this._onUserListActivated(item); })); - - + + this._sessionMenuButton = new SessionMenuButton(); this._sessionMenuButton.connect('session-activated', Lang.bind(this, function(list, sessionId) { @@ -9292,25 +9292,25 @@ index 8fecc28..1ed68ba 100644 this._sessionMenuButton.actor.opacity = 0; this._sessionMenuButton.actor.show(); this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor); - + }, - + _updateDisableUserList: function() { let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); - + if (disableUserList != this._disableUserList) { this._disableUserList = disableUserList; - + if (!this._authPrompt.verifyingUser) - this._reset(); + this._authPrompt.reset(); } }, - + _updateBanner: function() { let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); - + if (enabled && text) { this._bannerLabel.set_text(text); this._bannerLabel.show(); @@ -9318,79 +9318,79 @@ index 8fecc28..1ed68ba 100644 this._bannerLabel.hide(); } }, - + _updateLogoTexture: function(cache, uri) { if (this._logoFileUri != uri) return; - + let icon = null; if (this._logoFileUri) icon = this._textureCache.load_uri_async(this._logoFileUri, -1, _LOGO_ICON_HEIGHT); this._logoBin.set_child(icon); }, - + _updateLogo: function() { let path = this._settings.get_string(GdmUtil.LOGO_KEY); - + this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; this._updateLogoTexture(this._textureCache, this._logoFileUri); }, - + _onPrompted: function() { this._sessionMenuButton.updateSensitivity(true); - + if (this._shouldShowSessionMenuButton()) this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor); - + this._authPrompt.cancelButton.show(); - + this._showPrompt(); }, - + - _reset: function() { - if (this._authPrompt.verifyingUser) - return; - + _onReset: function() { this._sessionMenuButton.updateSensitivity(true); - + this._user = null; - + if (this._disableUserList) this._hideUserListAndLogIn(); else this._showUserList(); }, - + _onDefaultSessionChanged: function(client, sessionId) { this._sessionMenuButton.setActiveSession(sessionId); }, - + _shouldShowSessionMenuButton: function() { if (this._authPrompt.verifyingUser) return true; - + if (!this._user) return false; - + if (this._user.is_logged_in) return false; - + return true; }, - + _showPrompt: function() { if (this._authPrompt.actor.visible) return; --- +-- 1.8.3.1 -From 47486c4ec7daf316044ba9b61aed95cf68bd8a2f Mon Sep 17 00:00:00 2001 +From 25b4b72076d8fb8f5ec896574d8e9ef8dd3a2ccc Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 28 Jul 2013 16:24:31 -0400 -Subject: [PATCH 30/66] authPrompt: consolidate verifyingUser/userVerified +Subject: [PATCH 30/69] authPrompt: consolidate verifyingUser/userVerified Right now we have two booleans that specify when user verification is happening and when it succeeded, respectively. @@ -9412,12 +9412,12 @@ index d50f0fb..f915bf9 100644 +++ b/js/gdm/authPrompt.js @@ -1,61 +1,68 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - + const Clutter = imports.gi.Clutter; const Lang = imports.lang; const Signals = imports.signals; const St = imports.gi.St; - + const Panel = imports.ui.panel; const Batch = imports.gdm.batch; const GdmUtil = imports.gdm.util; @@ -9425,18 +9425,18 @@ index d50f0fb..f915bf9 100644 const ShellEntry = imports.ui.shellEntry; const Tweener = imports.ui.tweener; const UserWidget = imports.ui.userWidget; - + const DEFAULT_BUTTON_WELL_ICON_SIZE = 24; const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; - + const MESSAGE_FADE_OUT_ANIMATION_TIME = 0.5; - + const AuthPromptMode = { UNLOCK_ONLY: 0, UNLOCK_OR_LOG_IN: 1 }; - + +const AuthPromptStatus = { + NOT_VERIFYING: 0, + VERIFYING: 1, @@ -9446,22 +9446,22 @@ index d50f0fb..f915bf9 100644 + const AuthPrompt = new Lang.Class({ Name: 'AuthPrompt', - + _init: function(gdmClient, mode) { - this.verifyingUser = false; + this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; - + this._gdmClient = gdmClient; this._mode = mode; - + let reauthenticationOnly; if (this._mode == AuthPromptMode.UNLOCK_ONLY) reauthenticationOnly = true; else if (this._mode == AuthPromptMode.UNLOCK_OR_LOG_IN) reauthenticationOnly = false; - + this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly }); - + this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._onShowMessage)); this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed)); @@ -9469,7 +9469,7 @@ index d50f0fb..f915bf9 100644 this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); this._userVerifier.connect('show-login-hint', Lang.bind(this, this._onShowLoginHint)); this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._onHideLoginHint)); - + this.connect('next', Lang.bind(this, function() { this.updateSensitivity(false); this.startSpinning(); @@ -9479,16 +9479,16 @@ index d50f0fb..f915bf9 100644 this._preemptiveAnswer = this._entry.text; } })); - + @@ -195,69 +202,69 @@ const AuthPrompt = new Lang.Class({ this.setPasswordChar(passwordChar); this.setQuestion(question); - + if (this.verifyingUser) this.cancelButton.show(); else this.cancelButton.hide(); - + if (passwordChar) { if (this._userVerifier.reauthenticating) this.nextButton.label = _("Unlock"); @@ -9497,73 +9497,73 @@ index d50f0fb..f915bf9 100644 } else { this.nextButton.label = _("Next"); } - + this.updateSensitivity(true); this.emit('prompted'); }, - + _onShowMessage: function(userVerifier, message, styleClass) { this.setMessage(message, styleClass); }, - + _onVerificationFailed: function() { this.clear(); - + this.updateSensitivity(true); this.setActorInDefaultButtonWell(null); - this.userVerified = false; + this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED; }, - + _onVerificationComplete: function() { - this.userVerified = true; + this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED; }, - + _onReset: function() { - if (!this.userVerified) + if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) this.reset(); }, - + _onShowLoginHint: function(verifier, message) { this.setHint(message); }, - + _onHideLoginHint: function() { this.setHint(null); }, - + addActorToDefaultButtonWell: function(actor) { this._defaultButtonWell.add_child(actor); - + actor.add_constraint(new Clutter.AlignConstraint({ source: this._spinner.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); }, - + setActorInDefaultButtonWell: function(actor, animate) { if (!this._defaultButtonWellActor && !actor) return; - + let oldActor = this._defaultButtonWellActor; - + if (oldActor) Tweener.removeTweens(oldActor); - + let isSpinner; @@ -376,85 +383,84 @@ const AuthPrompt = new Lang.Class({ this.setActorInDefaultButtonWell(null, true); this.actor.hide(); this._loginHint.opacity = 0; - + this.setUser(null); - + this.updateSensitivity(true); this._entry.set_text(''); }, - + setUser: function(user) { if (user) { let userWidget = new UserWidget.UserWidget(user); @@ -9572,7 +9572,7 @@ index d50f0fb..f915bf9 100644 this._userWell.set_child(null); } }, - + setHint: function(message) { if (message) { this._loginHint.set_text(message) @@ -9582,7 +9582,7 @@ index d50f0fb..f915bf9 100644 this._loginHint.set_text(''); } }, - + reset: function() { - this.verifyingUser = false; - this.userVerified = false; @@ -9593,51 +9593,51 @@ index d50f0fb..f915bf9 100644 this.setUser(null); this.stopSpinning(); this.setHint(null); - + this.emit('reset'); }, - + addCharacter: function(unichar) { if (!this._entry.visible) return; - + this._entry.grab_key_focus(); this._entry.clutter_text.insert_unichar(unichar); }, - + begin: function(params) { params = Params.parse(params, { userName: null, hold: null }); - + this.updateSensitivity(false); - + let hold = params.hold; if (!hold) hold = new Batch.Hold(); - + this._userVerifier.begin(params.userName, hold); - this.verifyingUser = true; + this.verificationStatus = AuthPromptStatus.VERIFYING; }, - + finish: function(onComplete) { if (!this._userVerifier.hasPendingMessages) { onComplete(); return; } - + let signalId = this._userVerifier.connect('no-more-messages', Lang.bind(this, function() { this._userVerifier.disconnect(signalId); onComplete(); })); }, - + cancel: function() { - if (this.verifyingUser) + if (this.verificationStatus == AuthPromptStatus.VERIFYING) this._userVerifier.cancel(); - + this.reset(); } }); @@ -9653,13 +9653,13 @@ index 1ed68ba..c5c42f1 100644 })); else this._loadUserList(); - + this._userList.connect('activate', Lang.bind(this, function(userList, item) { this._onUserListActivated(item); })); - - + + this._sessionMenuButton = new SessionMenuButton(); this._sessionMenuButton.connect('session-activated', Lang.bind(this, function(list, sessionId) { @@ -9668,25 +9668,25 @@ index 1ed68ba..c5c42f1 100644 this._sessionMenuButton.actor.opacity = 0; this._sessionMenuButton.actor.show(); this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor); - + }, - + _updateDisableUserList: function() { let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); - + if (disableUserList != this._disableUserList) { this._disableUserList = disableUserList; - + - if (!this._authPrompt.verifyingUser) + if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING) this._authPrompt.reset(); } }, - + _updateBanner: function() { let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); - + if (enabled && text) { this._bannerLabel.set_text(text); this._bannerLabel.show(); @@ -9694,29 +9694,29 @@ index 1ed68ba..c5c42f1 100644 this._bannerLabel.hide(); } }, - + _updateLogoTexture: function(cache, uri) { if (this._logoFileUri != uri) return; - + let icon = null; if (this._logoFileUri) icon = this._textureCache.load_uri_async(this._logoFileUri, -1, _LOGO_ICON_HEIGHT); this._logoBin.set_child(icon); }, - + _updateLogo: function() { let path = this._settings.get_string(GdmUtil.LOGO_KEY); - --- + +-- 1.8.3.1 -From 6945dd07b5b29e4f9efa753e867a88906447cdd6 Mon Sep 17 00:00:00 2001 +From ce3e6485c61a7d95aefe473347527ea262d4ed9d Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 29 Jul 2013 10:52:02 -0400 -Subject: [PATCH 31/66] util: clear user verifier after cancelling it +Subject: [PATCH 31/69] util: clear user verifier after cancelling it If we don't clear it, then the connection to gdm will remain open. @@ -9734,18 +9734,18 @@ index 1facf98..9557c66 100644 this._messageQueueTimeoutId = 0; this.hasPendingMessages = false; this.reauthenticating = false; - + this._failCounter = 0; }, - + begin: function(userName, hold) { this._cancellable = new Gio.Cancellable(); this._hold = hold; this._userName = userName; this.reauthenticating = false; - + this._checkForFingerprintReader(); - + if (userName) { // If possible, reauthenticate an already running session, // so any session specific credentials get updated appropriately @@ -9755,32 +9755,32 @@ index 1facf98..9557c66 100644 this._client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot)); } }, - + cancel: function() { if (this._cancellable) this._cancellable.cancel(); - + - if (this._userVerifier) + if (this._userVerifier) { this._userVerifier.call_cancel_sync(null); + this.clear(); + } }, - + clear: function() { if (this._cancellable) { this._cancellable.cancel(); this._cancellable = null; } - + if (this._userVerifier) { this._userVerifier.run_dispose(); this._userVerifier = null; } - + this._clearMessageQueue(); }, - + answerQuery: function(serviceName, answer) { if (!this.hasPendingMessages) { this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null); @@ -9792,17 +9792,17 @@ index 1facf98..9557c66 100644 })); } }, - + _getIntervalForMessage: function(message) { // We probably could be smarter here --- +-- 1.8.3.1 -From b059c30b27973a492439b7f4ad50c1441e884137 Mon Sep 17 00:00:00 2001 +From 810fc0f00ea35940b634a31602b34b7867256e33 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 29 Jul 2013 08:46:37 -0400 -Subject: [PATCH 32/66] authPrompt: cancel user verification if verifying when +Subject: [PATCH 32/69] authPrompt: cancel user verification if verifying when reset authPrompt.reset() currently only leaves the authPrompt in a @@ -9829,27 +9829,27 @@ index f915bf9..07549c8 100644 } else { this.nextButton.label = _("Next"); } - + this.updateSensitivity(true); this.emit('prompted'); }, - + _onShowMessage: function(userVerifier, message, styleClass) { this.setMessage(message, styleClass); }, - + _onVerificationFailed: function() { this.clear(); - + this.updateSensitivity(true); this.setActorInDefaultButtonWell(null); this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED; }, - + _onVerificationComplete: function() { this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED; }, - + _onReset: function() { - if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) + if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) { @@ -9857,46 +9857,46 @@ index f915bf9..07549c8 100644 this.reset(); + } }, - + _onShowLoginHint: function(verifier, message) { this.setHint(message); }, - + _onHideLoginHint: function() { this.setHint(null); }, - + addActorToDefaultButtonWell: function(actor) { this._defaultButtonWell.add_child(actor); - + actor.add_constraint(new Clutter.AlignConstraint({ source: this._spinner.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); }, - + setActorInDefaultButtonWell: function(actor, animate) { if (!this._defaultButtonWellActor && !actor) return; - + let oldActor = this._defaultButtonWellActor; - + if (oldActor) Tweener.removeTweens(oldActor); - + let isSpinner; if (actor == this._spinner.actor) @@ -383,84 +385,86 @@ const AuthPrompt = new Lang.Class({ this.setActorInDefaultButtonWell(null, true); this.actor.hide(); this._loginHint.opacity = 0; - + this.setUser(null); - + this.updateSensitivity(true); this._entry.set_text(''); }, - + setUser: function(user) { if (user) { let userWidget = new UserWidget.UserWidget(user); @@ -9905,7 +9905,7 @@ index f915bf9..07549c8 100644 this._userWell.set_child(null); } }, - + setHint: function(message) { if (message) { this._loginHint.set_text(message) @@ -9915,7 +9915,7 @@ index f915bf9..07549c8 100644 this._loginHint.set_text(''); } }, - + reset: function() { + let oldStatus = this.verificationStatus; this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; @@ -9929,45 +9929,45 @@ index f915bf9..07549c8 100644 this.setUser(null); this.stopSpinning(); this.setHint(null); - + this.emit('reset'); }, - + addCharacter: function(unichar) { if (!this._entry.visible) return; - + this._entry.grab_key_focus(); this._entry.clutter_text.insert_unichar(unichar); }, - + begin: function(params) { params = Params.parse(params, { userName: null, hold: null }); - + this.updateSensitivity(false); - + let hold = params.hold; if (!hold) hold = new Batch.Hold(); - + this._userVerifier.begin(params.userName, hold); this.verificationStatus = AuthPromptStatus.VERIFYING; }, - + finish: function(onComplete) { if (!this._userVerifier.hasPendingMessages) { onComplete(); return; } - + let signalId = this._userVerifier.connect('no-more-messages', Lang.bind(this, function() { this._userVerifier.disconnect(signalId); onComplete(); })); }, - + cancel: function() { - if (this.verificationStatus == AuthPromptStatus.VERIFYING) - this._userVerifier.cancel(); @@ -9976,14 +9976,14 @@ index f915bf9..07549c8 100644 } }); Signals.addSignalMethods(AuthPrompt.prototype); --- +-- 1.8.3.1 -From c924ad2d3a4b10df3aa3757f8058f89c00fe5cd2 Mon Sep 17 00:00:00 2001 +From dc52d1d2ddaefb1fe2845e8b6efee0d9407c20d1 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 28 Jul 2013 16:06:04 -0400 -Subject: [PATCH 33/66] unlockDialog: only emit 'failed' on reset after +Subject: [PATCH 33/69] unlockDialog: only emit 'failed' on reset after failure/cancel We currently emit "failed" any time the UserVerifier is reset, @@ -10013,7 +10013,7 @@ index 07549c8..c10a178 100644 this._userWell.set_child(null); } }, - + setHint: function(message) { if (message) { this._loginHint.set_text(message) @@ -10023,62 +10023,62 @@ index 07549c8..c10a178 100644 this._loginHint.set_text(''); } }, - + reset: function() { let oldStatus = this.verificationStatus; this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; - + if (oldStatus == AuthPromptStatus.VERIFYING) this._userVerifier.cancel(); - + this._queryingService = null; this.clear(); this._message.opacity = 0; this.setUser(null); this.stopSpinning(); this.setHint(null); - + + if (oldStatus == AuthPromptStatus.VERIFICATION_FAILED) + this.emit('failed'); + this.emit('reset'); }, - + addCharacter: function(unichar) { if (!this._entry.visible) return; - + this._entry.grab_key_focus(); this._entry.clutter_text.insert_unichar(unichar); }, - + begin: function(params) { params = Params.parse(params, { userName: null, hold: null }); - + this.updateSensitivity(false); - + let hold = params.hold; if (!hold) hold = new Batch.Hold(); - + this._userVerifier.begin(params.userName, hold); this.verificationStatus = AuthPromptStatus.VERIFYING; }, - + finish: function(onComplete) { if (!this._userVerifier.hasPendingMessages) { onComplete(); return; } - + let signalId = this._userVerifier.connect('no-more-messages', Lang.bind(this, function() { this._userVerifier.disconnect(signalId); onComplete(); })); }, - + cancel: function() { this.reset(); + this.emit('cancelled'); @@ -10094,31 +10094,31 @@ index 53ff9b6..bfc97f3 100644 const Batch = imports.gdm.batch; const GdmUtil = imports.gdm.util; const LoginDialog = imports.gdm.loginDialog; - + // The timeout before going back automatically to the lock screen (in seconds) const IDLE_TIMEOUT = 2 * 60; - + const UnlockDialog = new Lang.Class({ Name: 'UnlockDialog', - + _init: function(parentActor) { this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW, style_class: 'login-dialog', visible: false }); - + this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true })); parentActor.add_child(this.actor); - + this._userManager = AccountsService.UserManager.get_default(); this._userName = GLib.get_user_name(); this._user = this._userManager.get_user(this._userName); - + this._promptBox = new St.BoxLayout({ vertical: true }); this.actor.add_child(this._promptBox); this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); - + this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY); - this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); + this._authPrompt.connect('failed', Lang.bind(this, this._fail)); @@ -10126,11 +10126,11 @@ index 53ff9b6..bfc97f3 100644 this._authPrompt.setUser(this._user); this._authPrompt.setPasswordChar('\u25cf'); this._authPrompt.nextButton.label = _("Unlock"); - + this._promptBox.add_child(this._authPrompt.actor); - + this.allowCancel = false; - + let screenSaverSettings = new Gio.Settings({ schema: 'org.gnome.desktop.screensaver' }); if (screenSaverSettings.get_boolean('user-switch-enabled')) { let otherUserLabel = new St.Label({ text: _("Log in as another user"), @@ -10146,30 +10146,30 @@ index 53ff9b6..bfc97f3 100644 } else { this._otherUserButton = null; } - + this._authPrompt.begin({ userName: this._userName }); this._updateSensitivity(true); - + Main.ctrlAltTabManager.addGroup(this.actor, _("Unlock Window"), 'dialog-password-symbolic'); - + this._idleMonitor = new GnomeDesktop.IdleMonitor(); this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape)); }, - + _updateSensitivity: function(sensitive) { this._authPrompt.updateSensitivity(sensitive); - + if (this._otherUserButton) { this._otherUserButton.reactive = sensitive; this._otherUserButton.can_focus = sensitive; } }, - + - _onReset: function() { + _fail: function() { this.emit('failed'); }, - + _escape: function() { - if (this.allowCancel) { + if (this.allowCancel) @@ -10177,43 +10177,43 @@ index 53ff9b6..bfc97f3 100644 - this.emit('failed'); - } }, - + _otherUserClicked: function(button, event) { Gdm.goto_login_session_sync(null); - + this._authPrompt.cancel(); }, - + destroy: function() { this.popModal(); this.actor.destroy(); - + if (this._idleWatchId) { this._idleMonitor.remove_watch(this._idleWatchId); this._idleWatchId = 0; } }, - + cancel: function() { this._authPrompt.cancel(); - + this.destroy(); }, - + addCharacter: function(unichar) { this._authPrompt.addCharacter(unichar); }, - + finish: function(onComplete) { this._authPrompt.finish(onComplete); --- +-- 1.8.3.1 -From 059a6c0e6255e5c504f24d56f956c067296b64e9 Mon Sep 17 00:00:00 2001 +From c89eee9198fbc22eda40d74c9c778b7ed82c51e4 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 16 Aug 2013 13:26:13 -0400 -Subject: [PATCH 34/66] loginDialog: fix session menu visibility +Subject: [PATCH 34/69] loginDialog: fix session menu visibility The shouldShowSessionMenu function has a few bugs in it. This fixes them. @@ -10230,33 +10230,33 @@ index c5c42f1..6808902 100644 @@ -565,67 +565,64 @@ const LoginDialog = new Lang.Class({ this._updateLogoTexture(this._textureCache, this._logoFileUri); }, - + _onPrompted: function() { this._sessionMenuButton.updateSensitivity(true); - + if (this._shouldShowSessionMenuButton()) this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor); - + this._authPrompt.cancelButton.show(); - + this._showPrompt(); }, - + _onReset: function() { this._sessionMenuButton.updateSensitivity(true); - + this._user = null; - + if (this._disableUserList) this._hideUserListAndLogIn(); else this._showUserList(); }, - + _onDefaultSessionChanged: function(client, sessionId) { this._sessionMenuButton.setActiveSession(sessionId); }, - + _shouldShowSessionMenuButton: function() { - if (this._authPrompt.verifyingUser) - return true; @@ -10264,14 +10264,14 @@ index c5c42f1..6808902 100644 - if (!this._user) + if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING) return false; - + - if (this._user.is_logged_in) + if (this._user && this._user.is_logged_in()) return false; - + return true; }, - + _showPrompt: function() { if (this._authPrompt.actor.visible) return; @@ -10282,29 +10282,29 @@ index c5c42f1..6808902 100644 time: _FADE_ANIMATION_TIME, transition: 'easeOutQuad' }); }, - + _showRealmLoginHint: function(realmManager, hint) { if (!hint) return; - + hint = hint.replace(/%U/g, 'user'); hint = hint.replace(/%D/g, 'DOMAIN'); hint = hint.replace(/%[^UD]/g, ''); - + // Translators: this message is shown below the username entry field // to clue the user in on how to login to the local network realm this._authPrompt.setHint(_("(e.g., user or %s)").format(hint)); }, - + _askForUsernameAndLogIn: function() { --- +-- 1.8.3.1 -From 198813b83cfc04638e72adb110def48035f8244e Mon Sep 17 00:00:00 2001 +From eb341ad40b886d1556ea4c9549afe9bad606ab45 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 28 Jul 2013 17:49:50 -0400 -Subject: [PATCH 35/66] authPrompt: add support for auth without username +Subject: [PATCH 35/69] authPrompt: add support for auth without username This commit introduces a new BeginRequestType enum which gets passed to the 'call-begin-when-ready' signal to specify whether @@ -10333,7 +10333,7 @@ index c10a178..e987d25 100644 const Lang = imports.lang; const Signals = imports.signals; const St = imports.gi.St; - + const Panel = imports.ui.panel; const Batch = imports.gdm.batch; const GdmUtil = imports.gdm.util; @@ -10341,25 +10341,25 @@ index c10a178..e987d25 100644 const ShellEntry = imports.ui.shellEntry; const Tweener = imports.ui.tweener; const UserWidget = imports.ui.userWidget; - + const DEFAULT_BUTTON_WELL_ICON_SIZE = 24; const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; - + const MESSAGE_FADE_OUT_ANIMATION_TIME = 0.5; - + const AuthPromptMode = { UNLOCK_ONLY: 0, UNLOCK_OR_LOG_IN: 1 }; - + const AuthPromptStatus = { NOT_VERIFYING: 0, VERIFYING: 1, VERIFICATION_FAILED: 2, VERIFICATION_SUCCEEDED: 3 }; - + +const BeginRequestType = { + PROVIDE_USERNAME: 0, + DONT_PROVIDE_USERNAME: 1 @@ -10367,21 +10367,21 @@ index c10a178..e987d25 100644 + const AuthPrompt = new Lang.Class({ Name: 'AuthPrompt', - + _init: function(gdmClient, mode) { this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; - + this._gdmClient = gdmClient; this._mode = mode; - + let reauthenticationOnly; if (this._mode == AuthPromptMode.UNLOCK_ONLY) reauthenticationOnly = true; else if (this._mode == AuthPromptMode.UNLOCK_OR_LOG_IN) reauthenticationOnly = false; - + this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly }); - + this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._onShowMessage)); this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed)); @@ -10389,7 +10389,7 @@ index c10a178..e987d25 100644 this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); this._userVerifier.connect('show-login-hint', Lang.bind(this, this._onShowLoginHint)); this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._onHideLoginHint)); - + this.connect('next', Lang.bind(this, function() { this.updateSensitivity(false); this.startSpinning(); @@ -10398,7 +10398,7 @@ index c10a178..e987d25 100644 @@ -401,61 +406,61 @@ const AuthPrompt = new Lang.Class({ } }, - + setHint: function(message) { if (message) { this._loginHint.set_text(message) @@ -10408,56 +10408,56 @@ index c10a178..e987d25 100644 this._loginHint.set_text(''); } }, - + reset: function() { let oldStatus = this.verificationStatus; this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; - + if (oldStatus == AuthPromptStatus.VERIFYING) this._userVerifier.cancel(); - + this._queryingService = null; this.clear(); this._message.opacity = 0; this.setUser(null); this.stopSpinning(); this.setHint(null); - + if (oldStatus == AuthPromptStatus.VERIFICATION_FAILED) this.emit('failed'); - + - this.emit('reset'); + this.emit('reset', BeginRequestType.PROVIDE_USERNAME); }, - + addCharacter: function(unichar) { if (!this._entry.visible) return; - + this._entry.grab_key_focus(); this._entry.clutter_text.insert_unichar(unichar); }, - + begin: function(params) { params = Params.parse(params, { userName: null, hold: null }); - + this.updateSensitivity(false); - + let hold = params.hold; if (!hold) hold = new Batch.Hold(); - + this._userVerifier.begin(params.userName, hold); this.verificationStatus = AuthPromptStatus.VERIFYING; }, - + finish: function(onComplete) { if (!this._userVerifier.hasPendingMessages) { onComplete(); return; } - + diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js index 6808902..b40aa85 100644 --- a/js/gdm/loginDialog.js @@ -10466,20 +10466,20 @@ index 6808902..b40aa85 100644 { expand: true, x_fill: true, y_fill: true }); - + this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN); this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted)); this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); this._authPrompt.hide(); - + this._authPrompt.actor.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); - + this.actor.add_child(this._authPrompt.actor); this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._authPrompt.actor, coordinate: Clutter.BindCoordinate.WIDTH })); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -10492,7 +10492,7 @@ index 6808902..b40aa85 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + - this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAndLogIn)); + this._notListedButton.connect('clicked', + Lang.bind(this, function() { @@ -10501,12 +10501,12 @@ index 6808902..b40aa85 100644 + })); + this._notListedButton.hide(); - + this._userSelectionBox.add(this._notListedButton, { expand: false, x_align: St.Align.START, x_fill: true }); - + this._logoBin = new St.Bin({ style_class: 'login-dialog-logo-bin', y_expand: true }); this._logoBin.set_y_align(Clutter.ActorAlign.END); this._logoBin.add_constraint(new Clutter.AlignConstraint({ source: this.actor, @@ -10517,7 +10517,7 @@ index 6808902..b40aa85 100644 factor: 1.0 })); this.actor.add_child(this._logoBin); this._updateLogo(); - + if (!this._userManager.is_loaded) this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', Lang.bind(this, function() { @@ -10529,44 +10529,44 @@ index 6808902..b40aa85 100644 })); else this._loadUserList(); - + @@ -549,110 +554,112 @@ const LoginDialog = new Lang.Class({ - + _updateLogoTexture: function(cache, uri) { if (this._logoFileUri != uri) return; - + let icon = null; if (this._logoFileUri) icon = this._textureCache.load_uri_async(this._logoFileUri, -1, _LOGO_ICON_HEIGHT); this._logoBin.set_child(icon); }, - + _updateLogo: function() { let path = this._settings.get_string(GdmUtil.LOGO_KEY); - + this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; this._updateLogoTexture(this._textureCache, this._logoFileUri); }, - + _onPrompted: function() { this._sessionMenuButton.updateSensitivity(true); - + if (this._shouldShowSessionMenuButton()) this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor); - + this._authPrompt.cancelButton.show(); - + this._showPrompt(); }, - + - _onReset: function() { + _onReset: function(authPrompt, beginRequest) { this._sessionMenuButton.updateSensitivity(true); - + this._user = null; - + - if (this._disableUserList) + if (this._disableUserList) { + this._authPrompt.cancelButton.hide(); @@ -10577,21 +10577,21 @@ index 6808902..b40aa85 100644 + this._showUserList(); + } }, - + _onDefaultSessionChanged: function(client, sessionId) { this._sessionMenuButton.setActiveSession(sessionId); }, - + _shouldShowSessionMenuButton: function() { if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING) return false; - + if (this._user && this._user.is_logged_in()) return false; - + return true; }, - + _showPrompt: function() { if (this._authPrompt.actor.visible) return; @@ -10602,30 +10602,30 @@ index 6808902..b40aa85 100644 time: _FADE_ANIMATION_TIME, transition: 'easeOutQuad' }); }, - + _showRealmLoginHint: function(realmManager, hint) { if (!hint) return; - + hint = hint.replace(/%U/g, 'user'); hint = hint.replace(/%D/g, 'DOMAIN'); hint = hint.replace(/%[^UD]/g, ''); - + // Translators: this message is shown below the username entry field // to clue the user in on how to login to the local network realm this._authPrompt.setHint(_("(e.g., user or %s)").format(hint)); }, - + - _askForUsernameAndLogIn: function() { + _askForUsernameAndBeginVerification: function() { this._authPrompt.setPasswordChar(''); this._authPrompt.setQuestion(_("Username: ")); - + let realmManager = new Realmd.Manager(); let realmSignalId = realmManager.connect('login-format-changed', Lang.bind(this, this._showRealmLoginHint)); this._showRealmLoginHint(realmManager.loginFormat); - + let nextSignalId = this._authPrompt.connect('next', Lang.bind(this, function() { this._authPrompt.disconnect(nextSignalId); @@ -10634,14 +10634,14 @@ index 6808902..b40aa85 100644 this._authPrompt.clear(); this._authPrompt.startSpinning(); this._authPrompt.begin({ userName: answer }); - + realmManager.disconnect(realmSignalId) realmManager.release(); })); this._authPrompt.cancelButton.hide(); this._showPrompt(); }, - + _startSession: function(serviceName) { Tweener.addTween(this.actor, { opacity: 0, @@ -10650,15 +10650,15 @@ index 6808902..b40aa85 100644 onUpdate: function() { @@ -781,65 +788,74 @@ const LoginDialog = new Lang.Class({ }, - + _onTimedLoginRequested: function(client, userName, seconds) { this._startTimedLogin(userName, seconds); - + global.stage.connect('captured-event', Lang.bind(this, function(actor, event) { if (this._timedLoginDelay == undefined) return false; - + if (event.type() == Clutter.EventType.KEY_PRESS || event.type() == Clutter.EventType.BUTTON_PRESS) { if (this._timedLoginBatch) { @@ -10669,16 +10669,16 @@ index 6808902..b40aa85 100644 event.type() == Clutter.EventType.BUTTON_RELEASE) { this._resetTimedLogin(); } - + return false; })); }, - + _setUserListExpanded: function(expanded) { this._userList.updateStyle(expanded); this._userSelectionBox.visible = expanded; }, - + - _hideUserListAndLogIn: function() { + _hideUserList: function() { this._setUserListExpanded(false); @@ -10696,7 +10696,7 @@ index 6808902..b40aa85 100644 + this._hideUserList(); + this._authPrompt.begin(); }, - + _showUserList: function() { this._authPrompt.hide(); this._sessionMenuButton.close(); @@ -10704,18 +10704,18 @@ index 6808902..b40aa85 100644 this._notListedButton.show(); this._userList.actor.grab_key_focus(); }, - + _beginVerificationForItem: function(item) { this._authPrompt.setUser(item.user); - + let userName = item.user.get_user_name(); let hold = new Batch.Hold(); - + this._authPrompt.begin({ userName: userName, hold: hold }); return hold; }, - + _onUserListActivated: function(activatedItem) { let tasks = [function() { return GdmUtil.cloneAndFadeOutActor(this._userSelectionBox); @@ -10723,7 +10723,7 @@ index 6808902..b40aa85 100644 function() { this._setUserListExpanded(false); }]; - + this._user = activatedItem.user; diff --git a/js/ui/unlockDialog.js b/js/ui/unlockDialog.js index bfc97f3..09024ba 100644 @@ -10732,31 +10732,31 @@ index bfc97f3..09024ba 100644 @@ -25,106 +25,118 @@ const Batch = imports.gdm.batch; const GdmUtil = imports.gdm.util; const LoginDialog = imports.gdm.loginDialog; - + // The timeout before going back automatically to the lock screen (in seconds) const IDLE_TIMEOUT = 2 * 60; - + const UnlockDialog = new Lang.Class({ Name: 'UnlockDialog', - + _init: function(parentActor) { this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW, style_class: 'login-dialog', visible: false }); - + this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true })); parentActor.add_child(this.actor); - + this._userManager = AccountsService.UserManager.get_default(); this._userName = GLib.get_user_name(); this._user = this._userManager.get_user(this._userName); - + this._promptBox = new St.BoxLayout({ vertical: true }); this.actor.add_child(this._promptBox); this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); - + this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY); this._authPrompt.connect('failed', Lang.bind(this, this._fail)); this._authPrompt.connect('cancelled', Lang.bind(this, this._fail)); @@ -10764,11 +10764,11 @@ index bfc97f3..09024ba 100644 + this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); this._authPrompt.setPasswordChar('\u25cf'); this._authPrompt.nextButton.label = _("Unlock"); - + this._promptBox.add_child(this._authPrompt.actor); - + this.allowCancel = false; - + let screenSaverSettings = new Gio.Settings({ schema: 'org.gnome.desktop.screensaver' }); if (screenSaverSettings.get_boolean('user-switch-enabled')) { let otherUserLabel = new St.Label({ text: _("Log in as another user"), @@ -10784,30 +10784,30 @@ index bfc97f3..09024ba 100644 } else { this._otherUserButton = null; } - + - this._authPrompt.begin({ userName: this._userName }); + this._authPrompt.reset(); this._updateSensitivity(true); - + Main.ctrlAltTabManager.addGroup(this.actor, _("Unlock Window"), 'dialog-password-symbolic'); - + this._idleMonitor = new GnomeDesktop.IdleMonitor(); this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape)); }, - + _updateSensitivity: function(sensitive) { this._authPrompt.updateSensitivity(sensitive); - + if (this._otherUserButton) { this._otherUserButton.reactive = sensitive; this._otherUserButton.can_focus = sensitive; } }, - + _fail: function() { this.emit('failed'); }, - + + _onReset: function(authPrompt, beginRequest) { + let userName; + if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) { @@ -10824,40 +10824,40 @@ index bfc97f3..09024ba 100644 if (this.allowCancel) this._authPrompt.cancel(); }, - + _otherUserClicked: function(button, event) { Gdm.goto_login_session_sync(null); - + this._authPrompt.cancel(); }, - + destroy: function() { this.popModal(); this.actor.destroy(); - + if (this._idleWatchId) { this._idleMonitor.remove_watch(this._idleWatchId); this._idleWatchId = 0; } }, - + cancel: function() { this._authPrompt.cancel(); - + this.destroy(); }, - + addCharacter: function(unichar) { this._authPrompt.addCharacter(unichar); }, --- +-- 1.8.3.1 -From e38b3ad85b9ac860862aaab0c6e2a8fb4559810c Mon Sep 17 00:00:00 2001 +From d7c6ef5e0f8e9d6f036e5d61a6f458d7067b2998 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 28 Jul 2013 19:42:26 -0400 -Subject: [PATCH 36/66] util: abstract out main auth service in code +Subject: [PATCH 36/69] util: abstract out main auth service in code Right now, the primary way a user logs in is with a password. They can also swipe their finger, if their @@ -10889,12 +10889,12 @@ index 9557c66..eba8b27 100644 +++ b/js/gdm/util.js @@ -89,60 +89,61 @@ function cloneAndFadeOutActor(actor) { reactive: false }); - + Main.uiGroup.add_child(clone); - + let [x, y] = actor.get_transformed_position(); clone.set_position(x, y); - + let hold = new Batch.Hold(); Tweener.addTween(clone, { opacity: 0, @@ -10907,36 +10907,36 @@ index 9557c66..eba8b27 100644 }); return hold; } - + const ShellUserVerifier = new Lang.Class({ Name: 'ShellUserVerifier', - + _init: function(client, params) { params = Params.parse(params, { reauthenticationOnly: false }); this._reauthOnly = params.reauthenticationOnly; - + this._client = client; - + this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA }); + this._updateDefaultService(); - + this._fprintManager = new Fprint.FprintManager(); this._messageQueue = []; this._messageQueueTimeoutId = 0; this.hasPendingMessages = false; this.reauthenticating = false; - + this._failCounter = 0; }, - + begin: function(userName, hold) { this._cancellable = new Gio.Cancellable(); this._hold = hold; this._userName = userName; this.reauthenticating = false; - + this._checkForFingerprintReader(); - + if (userName) { // If possible, reauthenticate an already running session, // so any session specific credentials get updated appropriately @@ -10946,7 +10946,7 @@ index 9557c66..eba8b27 100644 this._client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot)); } }, - + cancel: function() { if (this._cancellable) @@ -275,193 +276,205 @@ const ShellUserVerifier = new Lang.Class({ @@ -10954,7 +10954,7 @@ index 9557c66..eba8b27 100644 this._beginVerification(); this._hold.release(); }, - + _userVerifierGot: function(client, result) { try { this._userVerifier = client.get_user_verifier_finish(result); @@ -10964,12 +10964,12 @@ index 9557c66..eba8b27 100644 this._reportInitError('Failed to obtain user verifier', e); return; } - + this._connectSignals(); this._beginVerification(); this._hold.release(); }, - + _connectSignals: function() { this._userVerifier.connect('info', Lang.bind(this, this._onInfo)); this._userVerifier.connect('problem', Lang.bind(this, this._onProblem)); @@ -10979,7 +10979,7 @@ index 9557c66..eba8b27 100644 this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete)); }, - + + _getForegroundService: function() { + // For now, the foreground service is always the default service + return this._defaultService; @@ -10996,7 +10996,7 @@ index 9557c66..eba8b27 100644 + _beginVerification: function() { this._hold.acquire(); - + if (this._userName) { - this._userVerifier.call_begin_verification_for_user(PASSWORD_SERVICE_NAME, + this._userVerifier.call_begin_verification_for_user(this._getForegroundService(), @@ -11011,13 +11011,13 @@ index 9557c66..eba8b27 100644 this._reportInitError('Failed to start verification for user', e); return; } - + this._hold.release(); })); - + if (this._haveFingerprintReader) { this._hold.acquire(); - + this._userVerifier.call_begin_verification_for_user(FINGERPRINT_SERVICE_NAME, this._userName, this._cancellable, @@ -11030,7 +11030,7 @@ index 9557c66..eba8b27 100644 this._reportInitError('Failed to start fingerprint verification for user', e); return; } - + this._hold.release(); })); } @@ -11047,19 +11047,19 @@ index 9557c66..eba8b27 100644 this._reportInitError('Failed to start verification', e); return; } - + this._hold.release(); })); } }, - + _onInfo: function(client, serviceName, info) { // We don't display fingerprint messages, because they // have words like UPEK in them. Instead we use the messages // as a cue to display our own message. if (serviceName == FINGERPRINT_SERVICE_NAME && this._haveFingerprintReader) { - + // Translators: this message is shown below the password entry field // to indicate the user can swipe their finger instead this.emit('show-login-hint', _("(or swipe finger)")); @@ -11068,7 +11068,7 @@ index 9557c66..eba8b27 100644 this._queueMessage(info, 'login-dialog-message-info'); } }, - + _onProblem: function(client, serviceName, problem) { - // we don't want to show auth failed messages to - // users who haven't enrolled their fingerprint. @@ -11078,56 +11078,56 @@ index 9557c66..eba8b27 100644 + this._queueMessage(problem, 'login-dialog-message-warning'); }, - + _onInfoQuery: function(client, serviceName, question) { - // We only expect questions to come from the main auth service - if (serviceName != PASSWORD_SERVICE_NAME) + if (!this.serviceIsForeground(serviceName)) return; - + this.emit('ask-question', serviceName, question, ''); }, - + _onSecretInfoQuery: function(client, serviceName, secretQuestion) { - // We only expect secret requests to come from the main auth service - if (serviceName != PASSWORD_SERVICE_NAME) + if (!this.serviceIsForeground(serviceName)) return; - + this.emit('ask-question', serviceName, secretQuestion, '\u25cf'); }, - + _onReset: function() { // Clear previous attempts to authenticate this._failCounter = 0; + this._updateDefaultService(); - + this.emit('reset'); }, - + _onVerificationComplete: function() { this.emit('verification-complete'); }, - + _cancelAndReset: function() { this.cancel(); this._onReset(); }, - + _retry: function() { this.begin(this._userName, new Batch.Hold()); }, - + _verificationFailed: function(retry) { // For Not Listed / enterprise logins, immediately reset // the dialog // Otherwise, we allow ALLOWED_FAILURES attempts. After that, we // go back to the welcome screen. - + this._failCounter++; let canRetry = retry && this._userName && this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY); - + if (canRetry) { if (!this.hasPendingMessages) { this._retry(); @@ -11149,10 +11149,10 @@ index 9557c66..eba8b27 100644 })); } } - + this.emit('verification-failed'); }, - + _onConversationStopped: function(client, serviceName) { // if the password service fails, then cancel everything. // But if, e.g., fingerprint fails, still give @@ -11161,19 +11161,19 @@ index 9557c66..eba8b27 100644 + if (this.serviceIsForeground(serviceName)) { this._verificationFailed(true); } - + this.emit('hide-login-hint'); }, }); Signals.addSignalMethods(ShellUserVerifier.prototype); --- +-- 1.8.3.1 -From 76b405fad8884a4d11265eba58ade6e780dfea4c Mon Sep 17 00:00:00 2001 +From f3dd2a7bfd911de064555b4b69626b2262f25eec Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 29 Jul 2013 14:23:45 -0400 -Subject: [PATCH 37/66] gdmUtil: pave way for fingeprint to optionally be +Subject: [PATCH 37/69] gdmUtil: pave way for fingeprint to optionally be default auth service Currently, fingerprint authentication is always a secondary thing. @@ -11205,7 +11205,7 @@ index eba8b27..f41b2b2 100644 this._reportInitError('Failed to start fingerprint verification for user', e); return; } - + this._hold.release(); })); } @@ -11221,12 +11221,12 @@ index eba8b27..f41b2b2 100644 this._reportInitError('Failed to start verification', e); return; } - + this._hold.release(); })); } }, - + _onInfo: function(client, serviceName, info) { - // We don't display fingerprint messages, because they - // have words like UPEK in them. Instead we use the messages @@ -11239,7 +11239,7 @@ index eba8b27..f41b2b2 100644 + // We don't show fingerprint messages directly since it's + // not the main auth service. Instead we use the messages + // as a cue to display our own message. - + // Translators: this message is shown below the password entry field // to indicate the user can swipe their finger instead this.emit('show-login-hint', _("(or swipe finger)")); @@ -11247,42 +11247,42 @@ index eba8b27..f41b2b2 100644 - this._queueMessage(info, 'login-dialog-message-info'); } }, - + _onProblem: function(client, serviceName, problem) { if (!this.serviceIsForeground(serviceName)) return; - + this._queueMessage(problem, 'login-dialog-message-warning'); }, - + _onInfoQuery: function(client, serviceName, question) { if (!this.serviceIsForeground(serviceName)) return; - + this.emit('ask-question', serviceName, question, ''); }, - + _onSecretInfoQuery: function(client, serviceName, secretQuestion) { if (!this.serviceIsForeground(serviceName)) return; - + this.emit('ask-question', serviceName, secretQuestion, '\u25cf'); }, - + _onReset: function() { // Clear previous attempts to authenticate this._failCounter = 0; this._updateDefaultService(); - + this.emit('reset'); --- +-- 1.8.3.1 -From 372d18389bd3674b8e03c052a1fc3e4119567f8f Mon Sep 17 00:00:00 2001 +From 01894a09e35086a8a9f887d56d873c98ee52edb9 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 29 Jul 2013 14:37:10 -0400 -Subject: [PATCH 38/66] authPrompt: emit prompted when given a message +Subject: [PATCH 38/69] authPrompt: emit prompted when given a message Some pam modules prompt without expecting the user to type an answer back (e.g. "Please swipe finger"). We need to @@ -11300,19 +11300,19 @@ index e987d25..3f5e4fe 100644 @@ -200,60 +200,61 @@ const AuthPrompt = new Lang.Class({ return; } - + if (this._queryingService) this.clear(); - + this._queryingService = serviceName; this.setPasswordChar(passwordChar); this.setQuestion(question); - + if (this.verifyingUser) this.cancelButton.show(); else this.cancelButton.hide(); - + if (passwordChar) { if (this._userVerifier.reauthenticating) this.nextButton.label = _("Unlock"); @@ -11321,52 +11321,52 @@ index e987d25..3f5e4fe 100644 } else { this.nextButton.label = _("Next"); } - + this.updateSensitivity(true); this.emit('prompted'); }, - + _onShowMessage: function(userVerifier, message, styleClass) { this.setMessage(message, styleClass); + this.emit('prompted'); }, - + _onVerificationFailed: function() { this.clear(); - + this.updateSensitivity(true); this.setActorInDefaultButtonWell(null); this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED; }, - + _onVerificationComplete: function() { this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED; }, - + _onReset: function() { if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) { this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; this.reset(); } }, - + _onShowLoginHint: function(verifier, message) { this.setHint(message); }, - + _onHideLoginHint: function() { this.setHint(null); }, - + addActorToDefaultButtonWell: function(actor) { --- +-- 1.8.3.1 -From e025ebcf3344545c124962b493ddd2a28f1339b8 Mon Sep 17 00:00:00 2001 +From 893a0a63e1b9fd911ef17c7f72ade6f92121cb2d Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 16 Aug 2013 10:29:26 -0400 -Subject: [PATCH 39/66] gdmUtil: factor out some duplicated code in +Subject: [PATCH 39/69] gdmUtil: factor out some duplicated code in beginVerification The duplication makes the function look a lot more complicated @@ -11384,12 +11384,12 @@ index f41b2b2..acab471 100644 --- a/js/gdm/util.js +++ b/js/gdm/util.js @@ -290,115 +290,84 @@ const ShellUserVerifier = new Lang.Class({ - + this._connectSignals(); this._beginVerification(); this._hold.release(); }, - + _connectSignals: function() { this._userVerifier.connect('info', Lang.bind(this, this._onInfo)); this._userVerifier.connect('problem', Lang.bind(this, this._onProblem)); @@ -11399,21 +11399,21 @@ index f41b2b2..acab471 100644 this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete)); }, - + _getForegroundService: function() { // For now, the foreground service is always the default service return this._defaultService; }, - + serviceIsForeground: function(serviceName) { return serviceName == this._getForegroundService(); }, - + _updateDefaultService: function() { // For now, the default service is always the password service this._defaultService = PASSWORD_SERVICE_NAME; }, - + - _beginVerification: function() { + _startService: function(serviceName) { this._hold.acquire(); @@ -11429,7 +11429,7 @@ index f41b2b2..acab471 100644 + this._reportInitError('Failed to start verification for user', e); + return; + } - + - if (this._userName) { - this._userVerifier.call_begin_verification_for_user(this._getForegroundService(), - this._userName, @@ -11449,7 +11449,7 @@ index f41b2b2..acab471 100644 + this._hold.release(); + })); + }, - + - if (this._haveFingerprintReader) { - this._hold.acquire(); - @@ -11491,7 +11491,7 @@ index f41b2b2..acab471 100644 + if (this._userName && this._haveFingerprintReader) + this._startService(FINGERPRINT_SERVICE_NAME); }, - + _onInfo: function(client, serviceName, info) { if (this.serviceIsForeground(serviceName)) { this._queueMessage(info, 'login-dialog-message-info'); @@ -11500,34 +11500,34 @@ index f41b2b2..acab471 100644 // We don't show fingerprint messages directly since it's // not the main auth service. Instead we use the messages // as a cue to display our own message. - + // Translators: this message is shown below the password entry field // to indicate the user can swipe their finger instead this.emit('show-login-hint', _("(or swipe finger)")); } }, - + _onProblem: function(client, serviceName, problem) { if (!this.serviceIsForeground(serviceName)) return; - + this._queueMessage(problem, 'login-dialog-message-warning'); }, - + _onInfoQuery: function(client, serviceName, question) { if (!this.serviceIsForeground(serviceName)) return; - + this.emit('ask-question', serviceName, question, ''); }, --- +-- 1.8.3.1 -From e4b42dbae8404c51143a3e1b7bc99b8a8143a396 Mon Sep 17 00:00:00 2001 +From 85dc68df12383429c03292684170c1419045ea9a Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 29 Jul 2013 14:18:30 -0400 -Subject: [PATCH 40/66] gdmUtil: support disabling password authentication +Subject: [PATCH 40/69] gdmUtil: support disabling password authentication This commit skips trying password authentication if it's disallowed, favoring fingerprint login instead. @@ -11543,7 +11543,7 @@ index acab471..a7b8b62 100644 +++ b/js/gdm/util.js @@ -1,53 +1,54 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - + const Clutter = imports.gi.Clutter; const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; @@ -11551,40 +11551,40 @@ index acab471..a7b8b62 100644 const Mainloop = imports.mainloop; const Signals = imports.signals; const St = imports.gi.St; - + const Batch = imports.gdm.batch; const Fprint = imports.gdm.fingerprint; const Main = imports.ui.main; const Params = imports.misc.params; const ShellEntry = imports.ui.shellEntry; const Tweener = imports.ui.tweener; - + const PASSWORD_SERVICE_NAME = 'gdm-password'; const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint'; const FADE_ANIMATION_TIME = 0.16; const CLONE_FADE_ANIMATION_TIME = 0.25; - + const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen'; +const PASSWORD_AUTHENTICATION_KEY = 'enable-password-authentication'; const FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication'; const BANNER_MESSAGE_KEY = 'banner-message-enable'; const BANNER_MESSAGE_TEXT_KEY = 'banner-message-text'; const ALLOWED_FAILURES_KEY = 'allowed-failures'; - + const LOGO_KEY = 'logo'; const DISABLE_USER_LIST_KEY = 'disable-user-list'; - + // Give user 16ms to read each character of a PAM message const USER_READ_TIME = 16 - + function fadeInActor(actor) { if (actor.opacity == 255 && actor.visible) return null; - + let hold = new Batch.Hold(); actor.show(); let [minHeight, naturalHeight] = actor.get_preferred_height(-1); - + actor.opacity = 0; actor.set_height(0); Tweener.addTween(actor, @@ -11598,12 +11598,12 @@ index acab471..a7b8b62 100644 }, @@ -89,60 +90,62 @@ function cloneAndFadeOutActor(actor) { reactive: false }); - + Main.uiGroup.add_child(clone); - + let [x, y] = actor.get_transformed_position(); clone.set_position(x, y); - + let hold = new Batch.Hold(); Tweener.addTween(clone, { opacity: 0, @@ -11616,38 +11616,38 @@ index acab471..a7b8b62 100644 }); return hold; } - + const ShellUserVerifier = new Lang.Class({ Name: 'ShellUserVerifier', - + _init: function(client, params) { params = Params.parse(params, { reauthenticationOnly: false }); this._reauthOnly = params.reauthenticationOnly; - + this._client = client; - + this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA }); + this._settings.connect('changed', + Lang.bind(this, this._updateDefaultService)); this._updateDefaultService(); - + this._fprintManager = new Fprint.FprintManager(); this._messageQueue = []; this._messageQueueTimeoutId = 0; this.hasPendingMessages = false; this.reauthenticating = false; - + this._failCounter = 0; }, - + begin: function(userName, hold) { this._cancellable = new Gio.Cancellable(); this._hold = hold; this._userName = userName; this.reauthenticating = false; - + this._checkForFingerprintReader(); - + if (userName) { // If possible, reauthenticate an already running session, // so any session specific credentials get updated appropriately @@ -11657,10 +11657,10 @@ index acab471..a7b8b62 100644 this._client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot)); } }, - + cancel: function() { @@ -210,67 +213,70 @@ const ShellUserVerifier = new Lang.Class({ - + this._messageQueueTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, message.interval, Lang.bind(this, function() { @@ -11668,34 +11668,34 @@ index acab471..a7b8b62 100644 this._queueMessageTimeout(); })); }, - + _queueMessage: function(message, iconName) { let interval = this._getIntervalForMessage(message); - + this.hasPendingMessages = true; this._messageQueue.push({ text: message, interval: interval, iconName: iconName }); this._queueMessageTimeout(); }, - + _clearMessageQueue: function() { this.finishMessageQueue(); - + if (this._messageQueueTimeoutId != 0) { GLib.source_remove(this._messageQueueTimeoutId); this._messageQueueTimeoutId = 0; } this.emit('show-message', null, null); }, - + _checkForFingerprintReader: function() { this._haveFingerprintReader = false; - + - if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY)) + if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY)) { + this._updateDefaultService(); return; + } - + this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable, Lang.bind(this, function(device, error) { if (!error && device) @@ -11703,15 +11703,15 @@ index acab471..a7b8b62 100644 + this._updateDefaultService(); })); }, - + _reportInitError: function(where, error) { logError(error, where); this._hold.release(); - + this._queueMessage(_("Authentication error"), 'login-dialog-message-warning'); this._verificationFailed(false); }, - + _reauthenticationChannelOpened: function(client, result) { try { this._userVerifier = client.open_reauthentication_channel_finish(result); @@ -11728,7 +11728,7 @@ index acab471..a7b8b62 100644 this._reportInitError('Failed to open reauthentication channel', e); return; } - + this.reauthenticating = true; this._connectSignals(); @@ -286,87 +292,89 @@ const ShellUserVerifier = new Lang.Class({ @@ -11736,12 +11736,12 @@ index acab471..a7b8b62 100644 this._reportInitError('Failed to obtain user verifier', e); return; } - + this._connectSignals(); this._beginVerification(); this._hold.release(); }, - + _connectSignals: function() { this._userVerifier.connect('info', Lang.bind(this, this._onInfo)); this._userVerifier.connect('problem', Lang.bind(this, this._onProblem)); @@ -11751,16 +11751,16 @@ index acab471..a7b8b62 100644 this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete)); }, - + _getForegroundService: function() { // For now, the foreground service is always the default service return this._defaultService; }, - + serviceIsForeground: function(serviceName) { return serviceName == this._getForegroundService(); }, - + _updateDefaultService: function() { - // For now, the default service is always the password service - this._defaultService = PASSWORD_SERVICE_NAME; @@ -11769,7 +11769,7 @@ index acab471..a7b8b62 100644 + else if (this._haveFingerprintReader) + this._defaultService = FINGERPRINT_SERVICE_NAME; }, - + _startService: function(serviceName) { this._hold.acquire(); this._userVerifier.call_begin_verification_for_user(serviceName, @@ -11784,19 +11784,19 @@ index acab471..a7b8b62 100644 this._reportInitError('Failed to start verification for user', e); return; } - + this._hold.release(); })); }, - + _beginVerification: function() { this._startService(this._getForegroundService()); - + - if (this._userName && this._haveFingerprintReader) + if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME)) this._startService(FINGERPRINT_SERVICE_NAME); }, - + _onInfo: function(client, serviceName, info) { if (this.serviceIsForeground(serviceName)) { this._queueMessage(info, 'login-dialog-message-info'); @@ -11805,33 +11805,33 @@ index acab471..a7b8b62 100644 // We don't show fingerprint messages directly since it's // not the main auth service. Instead we use the messages // as a cue to display our own message. - + // Translators: this message is shown below the password entry field // to indicate the user can swipe their finger instead this.emit('show-login-hint', _("(or swipe finger)")); } }, - + _onProblem: function(client, serviceName, problem) { if (!this.serviceIsForeground(serviceName)) return; - + this._queueMessage(problem, 'login-dialog-message-warning'); }, - + _onInfoQuery: function(client, serviceName, question) { if (!this.serviceIsForeground(serviceName)) return; - + this.emit('ask-question', serviceName, question, ''); --- +-- 1.8.3.1 -From c40b68571f8cf8928bf855474becfe80b6f9eb83 Mon Sep 17 00:00:00 2001 +From ebb92fbc5adb2534c1a5d5604c76a515d8f73da7 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 30 May 2013 10:15:09 -0400 -Subject: [PATCH 41/66] misc: add objectManager class +Subject: [PATCH 41/69] misc: add objectManager class The D-Bus ObjectManager interface is fairly recent addition to the D-Bus specification. Its purpose is to provide a standardized way @@ -11857,67 +11857,67 @@ index 57f08e2..8740678 100644 --- a/js/Makefile.am +++ b/js/Makefile.am @@ -7,60 +7,61 @@ misc/config.js: misc/config.js.in Makefile - [ -d $(@D) ] || $(mkdir_p) $(@D) ; \ - sed -e "s|[@]PACKAGE_NAME@|$(PACKAGE_NAME)|g" \ - -e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \ - -e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \ - -e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \ - -e "s|[@]datadir@|$(datadir)|g" \ - -e "s|[@]libexecdir@|$(libexecdir)|g" \ - -e "s|[@]sysconfdir@|$(sysconfdir)|g" \ + [ -d $(@D) ] || $(mkdir_p) $(@D) ; \ + sed -e "s|[@]PACKAGE_NAME@|$(PACKAGE_NAME)|g" \ + -e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \ + -e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \ + -e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \ + -e "s|[@]datadir@|$(datadir)|g" \ + -e "s|[@]libexecdir@|$(libexecdir)|g" \ + -e "s|[@]sysconfdir@|$(sysconfdir)|g" \ $< > $@ - + jsdir = $(pkgdatadir)/js - + nobase_dist_js_DATA = \ - gdm/authPrompt.js \ - gdm/batch.js \ - gdm/fingerprint.js \ - gdm/loginDialog.js \ - gdm/powerMenu.js \ - gdm/realmd.js \ - gdm/util.js \ - extensionPrefs/main.js \ - misc/config.js \ - misc/extensionUtils.js \ - misc/fileUtils.js \ - misc/gnomeSession.js \ - misc/hash.js \ - misc/history.js \ - misc/jsParse.js \ - misc/loginManager.js \ - misc/modemManager.js \ + gdm/authPrompt.js \ + gdm/batch.js \ + gdm/fingerprint.js \ + gdm/loginDialog.js \ + gdm/powerMenu.js \ + gdm/realmd.js \ + gdm/util.js \ + extensionPrefs/main.js \ + misc/config.js \ + misc/extensionUtils.js \ + misc/fileUtils.js \ + misc/gnomeSession.js \ + misc/hash.js \ + misc/history.js \ + misc/jsParse.js \ + misc/loginManager.js \ + misc/modemManager.js \ + misc/objectManager.js \ - misc/params.js \ - misc/util.js \ - perf/core.js \ - ui/altTab.js \ - ui/appDisplay.js \ - ui/appFavorites.js \ - ui/backgroundMenu.js \ - ui/background.js \ - ui/boxpointer.js \ - ui/calendar.js \ - ui/checkBox.js \ - ui/ctrlAltTab.js \ - ui/dash.js \ - ui/dateMenu.js \ - ui/dnd.js \ - ui/endSessionDialog.js \ - ui/extensionSystem.js \ - ui/extensionDownloader.js \ - ui/environment.js \ - ui/ibusCandidatePopup.js\ - ui/grabHelper.js \ - ui/iconGrid.js \ - ui/keyboard.js \ - ui/layout.js \ - ui/lightbox.js \ - ui/lookingGlass.js \ - ui/magnifier.js \ - ui/magnifierDBus.js \ - ui/main.js \ - ui/messageTray.js \ + misc/params.js \ + misc/util.js \ + perf/core.js \ + ui/altTab.js \ + ui/appDisplay.js \ + ui/appFavorites.js \ + ui/backgroundMenu.js \ + ui/background.js \ + ui/boxpointer.js \ + ui/calendar.js \ + ui/checkBox.js \ + ui/ctrlAltTab.js \ + ui/dash.js \ + ui/dateMenu.js \ + ui/dnd.js \ + ui/endSessionDialog.js \ + ui/extensionSystem.js \ + ui/extensionDownloader.js \ + ui/environment.js \ + ui/ibusCandidatePopup.js\ + ui/grabHelper.js \ + ui/iconGrid.js \ + ui/keyboard.js \ + ui/layout.js \ + ui/lightbox.js \ + ui/lookingGlass.js \ + ui/magnifier.js \ + ui/magnifierDBus.js \ + ui/main.js \ + ui/messageTray.js \ diff --git a/js/misc/objectManager.js b/js/misc/objectManager.js new file mode 100644 index 0000000..b954f1b @@ -12178,14 +12178,14 @@ index 0000000..b954f1b + } +}); +Signals.addSignalMethods(ObjectManager.prototype); --- +-- 1.8.3.1 -From 183614d09aacbd6e62ae27dbb28a903f9abdd99c Mon Sep 17 00:00:00 2001 +From 71c033d5b31daa0b5bcef155d1c8aee9405d8b10 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 30 May 2013 10:18:51 -0400 -Subject: [PATCH 42/66] misc: add code to use settings-daemon smartcard service +Subject: [PATCH 42/69] misc: add code to use settings-daemon smartcard service gnome-settings-daemon monitors smartcard insertion and removal events on the system and then exports a model of the current @@ -12209,67 +12209,67 @@ index 8740678..425b6fb 100644 --- a/js/Makefile.am +++ b/js/Makefile.am @@ -9,60 +9,61 @@ misc/config.js: misc/config.js.in Makefile - -e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \ - -e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \ - -e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \ - -e "s|[@]datadir@|$(datadir)|g" \ - -e "s|[@]libexecdir@|$(libexecdir)|g" \ - -e "s|[@]sysconfdir@|$(sysconfdir)|g" \ + -e "s|[@]PACKAGE_VERSION@|$(PACKAGE_VERSION)|g" \ + -e "s|[@]HAVE_BLUETOOTH@|$(HAVE_BLUETOOTH)|g" \ + -e "s|[@]GETTEXT_PACKAGE@|$(GETTEXT_PACKAGE)|g" \ + -e "s|[@]datadir@|$(datadir)|g" \ + -e "s|[@]libexecdir@|$(libexecdir)|g" \ + -e "s|[@]sysconfdir@|$(sysconfdir)|g" \ $< > $@ - + jsdir = $(pkgdatadir)/js - + nobase_dist_js_DATA = \ - gdm/authPrompt.js \ - gdm/batch.js \ - gdm/fingerprint.js \ - gdm/loginDialog.js \ - gdm/powerMenu.js \ - gdm/realmd.js \ - gdm/util.js \ - extensionPrefs/main.js \ - misc/config.js \ - misc/extensionUtils.js \ - misc/fileUtils.js \ - misc/gnomeSession.js \ - misc/hash.js \ - misc/history.js \ - misc/jsParse.js \ - misc/loginManager.js \ - misc/modemManager.js \ - misc/objectManager.js \ - misc/params.js \ + gdm/authPrompt.js \ + gdm/batch.js \ + gdm/fingerprint.js \ + gdm/loginDialog.js \ + gdm/powerMenu.js \ + gdm/realmd.js \ + gdm/util.js \ + extensionPrefs/main.js \ + misc/config.js \ + misc/extensionUtils.js \ + misc/fileUtils.js \ + misc/gnomeSession.js \ + misc/hash.js \ + misc/history.js \ + misc/jsParse.js \ + misc/loginManager.js \ + misc/modemManager.js \ + misc/objectManager.js \ + misc/params.js \ + misc/smartcardManager.js \ - misc/util.js \ - perf/core.js \ - ui/altTab.js \ - ui/appDisplay.js \ - ui/appFavorites.js \ - ui/backgroundMenu.js \ - ui/background.js \ - ui/boxpointer.js \ - ui/calendar.js \ - ui/checkBox.js \ - ui/ctrlAltTab.js \ - ui/dash.js \ - ui/dateMenu.js \ - ui/dnd.js \ - ui/endSessionDialog.js \ - ui/extensionSystem.js \ - ui/extensionDownloader.js \ - ui/environment.js \ - ui/ibusCandidatePopup.js\ - ui/grabHelper.js \ - ui/iconGrid.js \ - ui/keyboard.js \ - ui/layout.js \ - ui/lightbox.js \ - ui/lookingGlass.js \ - ui/magnifier.js \ - ui/magnifierDBus.js \ - ui/main.js \ - ui/messageTray.js \ - ui/modalDialog.js \ + misc/util.js \ + perf/core.js \ + ui/altTab.js \ + ui/appDisplay.js \ + ui/appFavorites.js \ + ui/backgroundMenu.js \ + ui/background.js \ + ui/boxpointer.js \ + ui/calendar.js \ + ui/checkBox.js \ + ui/ctrlAltTab.js \ + ui/dash.js \ + ui/dateMenu.js \ + ui/dnd.js \ + ui/endSessionDialog.js \ + ui/extensionSystem.js \ + ui/extensionDownloader.js \ + ui/environment.js \ + ui/ibusCandidatePopup.js\ + ui/grabHelper.js \ + ui/iconGrid.js \ + ui/keyboard.js \ + ui/layout.js \ + ui/lightbox.js \ + ui/lookingGlass.js \ + ui/magnifier.js \ + ui/magnifierDBus.js \ + ui/main.js \ + ui/messageTray.js \ + ui/modalDialog.js \ diff --git a/js/misc/smartcardManager.js b/js/misc/smartcardManager.js new file mode 100644 index 0000000..644b033 @@ -12393,14 +12393,14 @@ index 0000000..644b033 + +}); +Signals.addSignalMethods(SmartcardManager.prototype); --- +-- 1.8.3.1 -From 106431c7f61dad0e2cc8bdbff2d2a3a31f94e670 Mon Sep 17 00:00:00 2001 +From cf8eee82c8603f331a3de0bd7046f352634c7200 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 27 Jun 2013 08:54:19 -0400 -Subject: [PATCH 43/66] authPrompt: support smartcard authentication +Subject: [PATCH 43/69] authPrompt: support smartcard authentication This commit detects when a user inserts a smartcard, and then initiates user verification using the gdm-smartcard @@ -12421,29 +12421,29 @@ index 3f5e4fe..cfdf052 100644 --- a/js/gdm/authPrompt.js +++ b/js/gdm/authPrompt.js @@ -33,60 +33,62 @@ const AuthPromptStatus = { - + const BeginRequestType = { PROVIDE_USERNAME: 0, DONT_PROVIDE_USERNAME: 1 }; - + const AuthPrompt = new Lang.Class({ Name: 'AuthPrompt', - + _init: function(gdmClient, mode) { this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; - + this._gdmClient = gdmClient; this._mode = mode; - + let reauthenticationOnly; if (this._mode == AuthPromptMode.UNLOCK_ONLY) reauthenticationOnly = true; else if (this._mode == AuthPromptMode.UNLOCK_OR_LOG_IN) reauthenticationOnly = false; - + this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly }); - + this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._onShowMessage)); this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed)); @@ -12453,7 +12453,7 @@ index 3f5e4fe..cfdf052 100644 this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._onHideLoginHint)); + this._userVerifier.connect('smartcard-status-changed', Lang.bind(this, this._onSmartcardStatusChanged)); + this.smartcardDetected = this._userVerifier.smartcardDetected; - + this.connect('next', Lang.bind(this, function() { this.updateSensitivity(false); this.startSpinning(); @@ -12463,7 +12463,7 @@ index 3f5e4fe..cfdf052 100644 this._preemptiveAnswer = this._entry.text; } })); - + this.actor = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout', vertical: true }); this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); @@ -12473,7 +12473,7 @@ index 3f5e4fe..cfdf052 100644 this.cancel(); } })); - + this._userWell = new St.Bin({ x_fill: true, x_align: St.Align.START }); this.actor.add(this._userWell, @@ -12482,25 +12482,25 @@ index 3f5e4fe..cfdf052 100644 y_fill: true, expand: true }); this._label = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + @@ -198,60 +200,79 @@ const AuthPrompt = new Lang.Class({ this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer); this._preemptiveAnswer = null; return; } - + if (this._queryingService) this.clear(); - + this._queryingService = serviceName; this.setPasswordChar(passwordChar); this.setQuestion(question); - + if (this.verifyingUser) this.cancelButton.show(); else this.cancelButton.hide(); - + if (passwordChar) { if (this._userVerifier.reauthenticating) this.nextButton.label = _("Unlock"); @@ -12509,11 +12509,11 @@ index 3f5e4fe..cfdf052 100644 } else { this.nextButton.label = _("Next"); } - + this.updateSensitivity(true); this.emit('prompted'); }, - + + _onSmartcardStatusChanged: function() { + this.smartcardDetected = this._userVerifier.smartcardDetected; + @@ -12537,36 +12537,36 @@ index 3f5e4fe..cfdf052 100644 this.setMessage(message, styleClass); this.emit('prompted'); }, - + _onVerificationFailed: function() { this.clear(); - + this.updateSensitivity(true); this.setActorInDefaultButtonWell(null); this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED; }, - + _onVerificationComplete: function() { this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED; }, - + _onReset: function() { if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) { this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; this.reset(); } }, - + _onShowLoginHint: function(verifier, message) { this.setHint(message); }, - + _onHideLoginHint: function() { this.setHint(null); @@ -407,61 +428,77 @@ const AuthPrompt = new Lang.Class({ } }, - + setHint: function(message) { if (message) { this._loginHint.set_text(message) @@ -12576,24 +12576,24 @@ index 3f5e4fe..cfdf052 100644 this._loginHint.set_text(''); } }, - + reset: function() { let oldStatus = this.verificationStatus; this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; - + if (oldStatus == AuthPromptStatus.VERIFYING) this._userVerifier.cancel(); - + this._queryingService = null; this.clear(); this._message.opacity = 0; this.setUser(null); this.stopSpinning(); this.setHint(null); - + if (oldStatus == AuthPromptStatus.VERIFICATION_FAILED) this.emit('failed'); - + - this.emit('reset', BeginRequestType.PROVIDE_USERNAME); + let beginRequestType; + @@ -12601,8 +12601,7 @@ index 3f5e4fe..cfdf052 100644 + // The user is constant at the unlock screen, so it will immediately + // respond to the request with the username + beginRequestType = BeginRequestType.PROVIDE_USERNAME; -+ } else if (this.smartcardDetected && -+ this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME)) { ++ } else if (this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME)) { + // We don't need to know the username if the user preempted the login screen + // with a smartcard. + beginRequestType = BeginRequestType.DONT_PROVIDE_USERNAME; @@ -12612,43 +12611,44 @@ index 3f5e4fe..cfdf052 100644 + } + + this.emit('reset', beginRequestType); ++ }, - + addCharacter: function(unichar) { if (!this._entry.visible) return; - + this._entry.grab_key_focus(); this._entry.clutter_text.insert_unichar(unichar); }, - + begin: function(params) { params = Params.parse(params, { userName: null, hold: null }); - + this.updateSensitivity(false); - + let hold = params.hold; if (!hold) hold = new Batch.Hold(); - + this._userVerifier.begin(params.userName, hold); this.verificationStatus = AuthPromptStatus.VERIFYING; }, - + finish: function(onComplete) { if (!this._userVerifier.hasPendingMessages) { onComplete(); return; } - + diff --git a/js/gdm/util.js b/js/gdm/util.js index a7b8b62..7ed5097 100644 --- a/js/gdm/util.js +++ b/js/gdm/util.js @@ -1,55 +1,58 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - + const Clutter = imports.gi.Clutter; const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; @@ -12656,7 +12656,7 @@ index a7b8b62..7ed5097 100644 const Mainloop = imports.mainloop; const Signals = imports.signals; const St = imports.gi.St; - + const Batch = imports.gdm.batch; const Fprint = imports.gdm.fingerprint; const Main = imports.ui.main; @@ -12664,13 +12664,13 @@ index a7b8b62..7ed5097 100644 const ShellEntry = imports.ui.shellEntry; +const SmartcardManager = imports.misc.smartcardManager; const Tweener = imports.ui.tweener; - + const PASSWORD_SERVICE_NAME = 'gdm-password'; const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint'; +const SMARTCARD_SERVICE_NAME = 'gdm-smartcard'; const FADE_ANIMATION_TIME = 0.16; const CLONE_FADE_ANIMATION_TIME = 0.25; - + const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen'; const PASSWORD_AUTHENTICATION_KEY = 'enable-password-authentication'; const FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication'; @@ -12678,21 +12678,21 @@ index a7b8b62..7ed5097 100644 const BANNER_MESSAGE_KEY = 'banner-message-enable'; const BANNER_MESSAGE_TEXT_KEY = 'banner-message-text'; const ALLOWED_FAILURES_KEY = 'allowed-failures'; - + const LOGO_KEY = 'logo'; const DISABLE_USER_LIST_KEY = 'disable-user-list'; - + // Give user 16ms to read each character of a PAM message const USER_READ_TIME = 16 - + function fadeInActor(actor) { if (actor.opacity == 255 && actor.visible) return null; - + let hold = new Batch.Hold(); actor.show(); let [minHeight, naturalHeight] = actor.get_preferred_height(-1); - + actor.opacity = 0; actor.set_height(0); Tweener.addTween(actor, @@ -12707,7 +12707,7 @@ index a7b8b62..7ed5097 100644 }); @@ -95,60 +98,73 @@ function cloneAndFadeOutActor(actor) { clone.set_position(x, y); - + let hold = new Batch.Hold(); Tweener.addTween(clone, { opacity: 0, @@ -12720,21 +12720,21 @@ index a7b8b62..7ed5097 100644 }); return hold; } - + const ShellUserVerifier = new Lang.Class({ Name: 'ShellUserVerifier', - + _init: function(client, params) { params = Params.parse(params, { reauthenticationOnly: false }); this._reauthOnly = params.reauthenticationOnly; - + this._client = client; - + this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA }); this._settings.connect('changed', Lang.bind(this, this._updateDefaultService)); this._updateDefaultService(); - + this._fprintManager = new Fprint.FprintManager(); + this._smartcardManager = SmartcardManager.getSmartcardManager(); + @@ -12753,18 +12753,18 @@ index a7b8b62..7ed5097 100644 this._messageQueueTimeoutId = 0; this.hasPendingMessages = false; this.reauthenticating = false; - + this._failCounter = 0; }, - + begin: function(userName, hold) { this._cancellable = new Gio.Cancellable(); this._hold = hold; this._userName = userName; this.reauthenticating = false; - + this._checkForFingerprintReader(); - + if (userName) { // If possible, reauthenticate an already running session, // so any session specific credentials get updated appropriately @@ -12774,34 +12774,34 @@ index a7b8b62..7ed5097 100644 this._client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot)); } }, - + cancel: function() { if (this._cancellable) this._cancellable.cancel(); - + @@ -226,128 +242,158 @@ const ShellUserVerifier = new Lang.Class({ this._messageQueue.push({ text: message, interval: interval, iconName: iconName }); this._queueMessageTimeout(); }, - + _clearMessageQueue: function() { this.finishMessageQueue(); - + if (this._messageQueueTimeoutId != 0) { GLib.source_remove(this._messageQueueTimeoutId); this._messageQueueTimeoutId = 0; } this.emit('show-message', null, null); }, - + _checkForFingerprintReader: function() { this._haveFingerprintReader = false; - + if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY)) { this._updateDefaultService(); return; } - + this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable, Lang.bind(this, function(device, error) { if (!error && device) @@ -12809,13 +12809,13 @@ index a7b8b62..7ed5097 100644 this._updateDefaultService(); })); }, - + + _checkForSmartcard: function() { + let smartcardDetected; + + if (!this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY)) + smartcardDetected = false; -+ else if (this.reauthenticating) ++ else if (this._reauthOnly) + smartcardDetected = this._smartcardManager.hasInsertedLoginToken(); + else + smartcardDetected = this._smartcardManager.hasInsertedTokens(); @@ -12835,11 +12835,11 @@ index a7b8b62..7ed5097 100644 _reportInitError: function(where, error) { logError(error, where); this._hold.release(); - + this._queueMessage(_("Authentication error"), 'login-dialog-message-warning'); this._verificationFailed(false); }, - + _reauthenticationChannelOpened: function(client, result) { try { this._userVerifier = client.open_reauthentication_channel_finish(result); @@ -12856,13 +12856,13 @@ index a7b8b62..7ed5097 100644 this._reportInitError('Failed to open reauthentication channel', e); return; } - + this.reauthenticating = true; this._connectSignals(); this._beginVerification(); this._hold.release(); }, - + _userVerifierGot: function(client, result) { try { this._userVerifier = client.get_user_verifier_finish(result); @@ -12872,12 +12872,12 @@ index a7b8b62..7ed5097 100644 this._reportInitError('Failed to obtain user verifier', e); return; } - + this._connectSignals(); this._beginVerification(); this._hold.release(); }, - + _connectSignals: function() { this._userVerifier.connect('info', Lang.bind(this, this._onInfo)); this._userVerifier.connect('problem', Lang.bind(this, this._onProblem)); @@ -12887,7 +12887,7 @@ index a7b8b62..7ed5097 100644 this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete)); }, - + _getForegroundService: function() { - // For now, the foreground service is always the default service + if (this._preemptingService) @@ -12895,11 +12895,11 @@ index a7b8b62..7ed5097 100644 + return this._defaultService; }, - + serviceIsForeground: function(serviceName) { return serviceName == this._getForegroundService(); }, - + + serviceIsDefault: function(serviceName) { + return serviceName == this._defaultService; + }, @@ -12912,7 +12912,7 @@ index a7b8b62..7ed5097 100644 else if (this._haveFingerprintReader) this._defaultService = FINGERPRINT_SERVICE_NAME; }, - + _startService: function(serviceName) { this._hold.acquire(); this._userVerifier.call_begin_verification_for_user(serviceName, @@ -12927,25 +12927,25 @@ index a7b8b62..7ed5097 100644 this._reportInitError('Failed to start verification for user', e); return; } - + this._hold.release(); })); }, - + _beginVerification: function() { this._startService(this._getForegroundService()); - + if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME)) this._startService(FINGERPRINT_SERVICE_NAME); }, - + diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js index d9fe883..2c812f5 100644 --- a/js/ui/screenShield.js +++ b/js/ui/screenShield.js @@ -1,55 +1,56 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- - + const Cairo = imports.cairo; const Clutter = imports.gi.Clutter; const Gio = imports.gi.Gio; @@ -12958,7 +12958,7 @@ index d9fe883..2c812f5 100644 const Signals = imports.signals; const St = imports.gi.St; const TweenerEquations = imports.tweener.equations; - + const Background = imports.ui.background; const GnomeSession = imports.misc.gnomeSession; const Hash = imports.misc.hash; @@ -12972,23 +12972,23 @@ index d9fe883..2c812f5 100644 +const SmartcardManager = imports.misc.smartcardManager; const Tweener = imports.ui.tweener; const Util = imports.misc.util; - + const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver'; const LOCK_ENABLED_KEY = 'lock-enabled'; const LOCK_DELAY_KEY = 'lock-delay'; - + // fraction of screen height the arrow must reach before completing // the slide up automatically const ARROW_DRAG_THRESHOLD = 0.1; - + // Parameters for the arrow animation const N_ARROWS = 3; const ARROW_ANIMATION_TIME = 0.6; const ARROW_ANIMATION_PEAK_OPACITY = 0.4; const ARROW_IDLE_TIME = 30000; // ms - + const SUMMARY_ICON_SIZE = 48; - + // ScreenShield animation time // - STANDARD_FADE_TIME is used when the session goes idle // - MANUAL_FADE_TIME is used for lowering the shield when asked by the user, @@ -13001,39 +13001,39 @@ index d9fe883..2c812f5 100644 const BACKGROUND_FADE_TIME = 1.0; const CURTAIN_SLIDE_TIME = 0.3; @@ -478,60 +479,67 @@ const ScreenShield = new Lang.Class({ - + this._lockDialogGroup = new St.Widget({ x_expand: true, y_expand: true, opacity: 0, pivot_point: new Clutter.Point({ x: 0.5, y: 0.5 }), name: 'lockDialogGroup' }); - + Tweener.addTween(this._lockDialogGroup, { opacity: 255, time: INITIAL_FADE_IN_TIME, transition: 'easeInQuad', }); - + this.actor.add_actor(this._lockDialogGroup); this.actor.add_actor(this._lockScreenGroup); - + this._presence = new GnomeSession.Presence(Lang.bind(this, function(proxy, error) { if (error) { logError(error, 'Error while reading gnome-session presence'); return; } - + this._onStatusChanged(proxy.status); })); this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) { this._onStatusChanged(status); })); - + this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this); - + + this._smartcardManager = SmartcardManager.getSmartcardManager(); + this._smartcardManager.connect('smartcard-inserted', -+ Lang.bind(this, function(token) { ++ Lang.bind(this, function(manager, token) { + if (this._isLocked && token.UsedToLogin) + this._liftShield(true, 0); + })); @@ -13044,16 +13044,16 @@ index d9fe883..2c812f5 100644 this._loginManager.connect('prepare-for-sleep', Lang.bind(this, this._prepareForSleep)); this._inhibitSuspend(); - + this._loginManager.getCurrentSessionProxy(Lang.bind(this, function(sessionProxy) { this._loginSession = sessionProxy; this._loginSession.connectSignal('Lock', Lang.bind(this, function() { this.lock(false); })); this._loginSession.connectSignal('Unlock', Lang.bind(this, function() { this.deactivate(false); })); })); - + this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA }); - + this._isModal = false; this._hasLockScreen = false; this._isGreeter = false; @@ -13063,19 +13063,19 @@ index d9fe883..2c812f5 100644 this._activationTime = 0; this._becameActiveId = 0; this._lockTimeoutId = 0; - + this._lightbox = new Lightbox.Lightbox(Main.uiGroup, { inhibitEvents: true, fadeInTime: STANDARD_FADE_TIME, fadeFactor: 1 }); --- +-- 1.8.3.1 -From f63abd535aee82424bb98395b2cfbd22cac310d6 Mon Sep 17 00:00:00 2001 +From 8365ce925bf451718882e554ff89b6a7aa36ee07 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 28 Jul 2013 20:55:12 -0400 -Subject: [PATCH 44/66] loginDialog: fix up cancel button visibility +Subject: [PATCH 44/69] loginDialog: fix up cancel button visibility This commit makes sure we hide when there's nothing to cancel to and show it when there's something to cancel to. @@ -13091,13 +13091,13 @@ index b40aa85..643c7d6 100644 +++ b/js/gdm/loginDialog.js @@ -513,98 +513,108 @@ const LoginDialog = new Lang.Class({ this._loadUserList(); - + this._userList.connect('activate', Lang.bind(this, function(userList, item) { this._onUserListActivated(item); })); - - + + this._sessionMenuButton = new SessionMenuButton(); this._sessionMenuButton.connect('session-activated', Lang.bind(this, function(list, sessionId) { @@ -13106,20 +13106,20 @@ index b40aa85..643c7d6 100644 this._sessionMenuButton.actor.opacity = 0; this._sessionMenuButton.actor.show(); this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor); - + }, - + _updateDisableUserList: function() { let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); - + if (disableUserList != this._disableUserList) { this._disableUserList = disableUserList; - + if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING) this._authPrompt.reset(); } }, - + + _updateCancelButton: function() { + let cancelVisible; + @@ -13136,7 +13136,7 @@ index b40aa85..643c7d6 100644 _updateBanner: function() { let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); - + if (enabled && text) { this._bannerLabel.set_text(text); this._bannerLabel.show(); @@ -13144,28 +13144,28 @@ index b40aa85..643c7d6 100644 this._bannerLabel.hide(); } }, - + _updateLogoTexture: function(cache, uri) { if (this._logoFileUri != uri) return; - + let icon = null; if (this._logoFileUri) icon = this._textureCache.load_uri_async(this._logoFileUri, -1, _LOGO_ICON_HEIGHT); this._logoBin.set_child(icon); }, - + _updateLogo: function() { let path = this._settings.get_string(GdmUtil.LOGO_KEY); - + this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; this._updateLogoTexture(this._textureCache, this._logoFileUri); }, - + _onPrompted: function() { this._sessionMenuButton.updateSensitivity(true); - + if (this._shouldShowSessionMenuButton()) this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor); - @@ -13173,12 +13173,12 @@ index b40aa85..643c7d6 100644 - this._showPrompt(); }, - + _onReset: function(authPrompt, beginRequest) { this._sessionMenuButton.updateSensitivity(true); - + this._user = null; - + if (this._disableUserList) { this._authPrompt.cancelButton.hide(); this._hideUserListAndLogIn(); @@ -13186,44 +13186,44 @@ index b40aa85..643c7d6 100644 this._showUserList(); } }, - + _onDefaultSessionChanged: function(client, sessionId) { this._sessionMenuButton.setActiveSession(sessionId); }, - + _shouldShowSessionMenuButton: function() { if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING) return false; - + if (this._user && this._user.is_logged_in()) return false; - + return true; }, - + @@ -622,65 +632,66 @@ const LoginDialog = new Lang.Class({ _showRealmLoginHint: function(realmManager, hint) { if (!hint) return; - + hint = hint.replace(/%U/g, 'user'); hint = hint.replace(/%D/g, 'DOMAIN'); hint = hint.replace(/%[^UD]/g, ''); - + // Translators: this message is shown below the username entry field // to clue the user in on how to login to the local network realm this._authPrompt.setHint(_("(e.g., user or %s)").format(hint)); }, - + _askForUsernameAndBeginVerification: function() { this._authPrompt.setPasswordChar(''); this._authPrompt.setQuestion(_("Username: ")); - + let realmManager = new Realmd.Manager(); let realmSignalId = realmManager.connect('login-format-changed', Lang.bind(this, this._showRealmLoginHint)); this._showRealmLoginHint(realmManager.loginFormat); - + let nextSignalId = this._authPrompt.connect('next', Lang.bind(this, function() { this._authPrompt.disconnect(nextSignalId); @@ -13233,7 +13233,7 @@ index b40aa85..643c7d6 100644 this._authPrompt.startSpinning(); this._authPrompt.begin({ userName: answer }); + this._updateCancelButton(); - + realmManager.disconnect(realmSignalId) realmManager.release(); })); @@ -13241,7 +13241,7 @@ index b40aa85..643c7d6 100644 + this._updateCancelButton(); this._showPrompt(); }, - + _startSession: function(serviceName) { Tweener.addTween(this.actor, { opacity: 0, @@ -13249,7 +13249,7 @@ index b40aa85..643c7d6 100644 transition: 'easeOutQuad', onUpdate: function() { let children = Main.layoutManager.uiGroup.get_children(); - + for (let i = 0; i < children.length; i++) { if (children[i] != Main.layoutManager.screenShieldGroup) children[i].opacity = this.actor.opacity; @@ -13264,13 +13264,13 @@ index b40aa85..643c7d6 100644 }, onCompleteScope: this }); }, - + _onSessionOpened: function(client, serviceName) { this._authPrompt.finish(Lang.bind(this, function() { this._startSession(serviceName); })); @@ -833,60 +844,62 @@ const LoginDialog = new Lang.Class({ - + _showUserList: function() { this._authPrompt.hide(); this._sessionMenuButton.close(); @@ -13278,18 +13278,18 @@ index b40aa85..643c7d6 100644 this._notListedButton.show(); this._userList.actor.grab_key_focus(); }, - + _beginVerificationForItem: function(item) { this._authPrompt.setUser(item.user); - + let userName = item.user.get_user_name(); let hold = new Batch.Hold(); - + this._authPrompt.begin({ userName: userName, hold: hold }); return hold; }, - + _onUserListActivated: function(activatedItem) { let tasks = [function() { return GdmUtil.cloneAndFadeOutActor(this._userSelectionBox); @@ -13297,49 +13297,49 @@ index b40aa85..643c7d6 100644 function() { this._setUserListExpanded(false); }]; - + this._user = activatedItem.user; - + + this._updateCancelButton(); + let batch = new Batch.ConcurrentBatch(this, [new Batch.ConsecutiveBatch(this, tasks), this._beginVerificationForItem(activatedItem)]); batch.run(); }, - + _onDestroy: function() { if (this._userManagerLoadedId) { this._userManager.disconnect(this._userManagerLoadedId); this._userManagerLoadedId = 0; } }, - + _loadUserList: function() { let users = this._userManager.list_users(); - + for (let i = 0; i < users.length; i++) { this._userList.addUser(users[i]); } - + this._updateDisableUserList(); - + this._userManager.connect('user-added', Lang.bind(this, function(userManager, user) { this._userList.addUser(user); })); - + this._userManager.connect('user-removed', Lang.bind(this, function(userManager, user) { this._userList.removeUser(user); })); --- +-- 1.8.3.1 -From 411106a834623b1bcbf2f4360dcbecbed2f13b0f Mon Sep 17 00:00:00 2001 +From 9b3d0f302a216f70bb23685f08318afc6cfc21c4 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Sun, 28 Jul 2013 16:15:43 -0400 -Subject: [PATCH 45/66] authPrompt: don't muck with cancelButton in +Subject: [PATCH 45/69] authPrompt: don't muck with cancelButton in onAskQuestion onAskQuestion has this code: @@ -13367,35 +13367,35 @@ index cfdf052..cbd2c46 100644 +++ b/js/gdm/authPrompt.js @@ -182,65 +182,60 @@ const AuthPrompt = new Lang.Class({ y_align: St.Align.END }); - + this._updateNextButtonSensitivity(this._entry.text.length > 0); - + this._entry.clutter_text.connect('text-changed', Lang.bind(this, function() { if (!this._userVerifier.hasPendingMessages) this._fadeOutMessage(); - + this._updateNextButtonSensitivity(this._entry.text.length > 0); })); this._entry.clutter_text.connect('activate', Lang.bind(this, function() { this.emit('next'); })); }, - + _onAskQuestion: function(verifier, serviceName, question, passwordChar) { if (this._preemptiveAnswer) { this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer); this._preemptiveAnswer = null; return; } - + if (this._queryingService) this.clear(); - + this._queryingService = serviceName; this.setPasswordChar(passwordChar); this.setQuestion(question); - + - if (this.verifyingUser) - this.cancelButton.show(); - else @@ -13409,14 +13409,14 @@ index cfdf052..cbd2c46 100644 } else { this.nextButton.label = _("Next"); } - + this.updateSensitivity(true); this.emit('prompted'); }, - + _onSmartcardStatusChanged: function() { this.smartcardDetected = this._userVerifier.smartcardDetected; - + // Most of the time we want to reset if the user inserts or removes // a smartcard. Smartcard insertion "preempts" what the user was // doing, and smartcard removal aborts the preemption. @@ -13428,17 +13428,17 @@ index cfdf052..cbd2c46 100644 this.verificationStatus == AuthPromptStatus.VERIFYING && this.smartcardDetected) return; - + if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) this.reset(); --- +-- 1.8.3.1 -From 69d736de7259f86673fd54c02886527bb547463f Mon Sep 17 00:00:00 2001 +From aa83e0e4c6a6d5963fb33f2a43d440431155a378 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 2 Aug 2013 14:10:16 -0400 -Subject: [PATCH 46/66] authPrompt: fix disable-user-list / Not Listed? +Subject: [PATCH 46/69] authPrompt: fix disable-user-list / Not Listed? If the first question asked to a user is from the shell and not from the PAM service (i.e. Username: ), @@ -13472,21 +13472,21 @@ index cbd2c46..d09e5b6 100644 y_fill: false, x_align: St.Align.END, y_align: St.Align.END }); - + this._updateNextButtonSensitivity(this._entry.text.length > 0); - + this._entry.clutter_text.connect('text-changed', Lang.bind(this, function() { if (!this._userVerifier.hasPendingMessages) this._fadeOutMessage(); - + this._updateNextButtonSensitivity(this._entry.text.length > 0); })); this._entry.clutter_text.connect('activate', Lang.bind(this, function() { this.emit('next'); })); }, - + _onAskQuestion: function(verifier, serviceName, question, passwordChar) { if (this._preemptiveAnswer) { - this._userVerifier.answerQuery(this._queryingService, this._preemptiveAnswer); @@ -13495,14 +13495,14 @@ index cbd2c46..d09e5b6 100644 this._preemptiveAnswer = null; return; } - + if (this._queryingService) this.clear(); - + this._queryingService = serviceName; this.setPasswordChar(passwordChar); this.setQuestion(question); - + if (passwordChar) { if (this._userVerifier.reauthenticating) this.nextButton.label = _("Unlock"); @@ -13511,47 +13511,47 @@ index cbd2c46..d09e5b6 100644 } else { this.nextButton.label = _("Next"); } - + this.updateSensitivity(true); this.emit('prompted'); }, - + _onSmartcardStatusChanged: function() { this.smartcardDetected = this._userVerifier.smartcardDetected; - + // Most of the time we want to reset if the user inserts or removes // a smartcard. Smartcard insertion "preempts" what the user was // doing, and smartcard removal aborts the preemption. @@ -338,61 +339,68 @@ const AuthPrompt = new Lang.Class({ this.setActorInDefaultButtonWell(this._spinner.actor, true); }, - + stopSpinning: function() { this.setActorInDefaultButtonWell(null, false); }, - + clear: function() { this._entry.text = ''; this.stopSpinning(); }, - + setPasswordChar: function(passwordChar) { this._entry.clutter_text.set_password_char(passwordChar); this._entry.menu.isPassword = passwordChar != ''; }, - + setQuestion: function(question) { this._label.set_text(question); - + this._label.show(); this._entry.show(); - + this._loginHint.opacity = 0; this._loginHint.show(); - + this._entry.grab_key_focus(); }, - + getAnswer: function() { - let text = this._entry.get_text(); + let text; @@ -13562,10 +13562,10 @@ index cbd2c46..d09e5b6 100644 + } else { + text = this._entry.get_text(); + } - + return text; }, - + _fadeOutMessage: function() { if (this._message.opacity == 0) return; @@ -13576,7 +13576,7 @@ index cbd2c46..d09e5b6 100644 transition: 'easeOutQuad' }); }, - + setMessage: function(message, styleClass) { if (message) { Tweener.removeTweens(this._message); @@ -13587,19 +13587,19 @@ index cbd2c46..d09e5b6 100644 this._message.opacity = 0; } }, - + _updateNextButtonSensitivity: function(sensitive) { this.nextButton.reactive = sensitive; this.nextButton.can_focus = sensitive; }, --- +-- 1.8.3.1 -From 086b6a1ecdbef2610663aae4993300993dbea8f7 Mon Sep 17 00:00:00 2001 +From 482a7e0c2e9a00b5393f871e848f356b2c0a600a Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 6 Aug 2013 09:22:48 -0400 -Subject: [PATCH 47/66] screenShield: Don't crash when trying to deactivate the +Subject: [PATCH 47/69] screenShield: Don't crash when trying to deactivate the shield If the user has a lock delay, or deactivate() has been called at @@ -13614,35 +13614,35 @@ index 2c812f5..bdce9e8 100644 --- a/js/ui/screenShield.js +++ b/js/ui/screenShield.js @@ -1091,63 +1091,66 @@ const ScreenShield = new Lang.Class({ - + _clearLockScreen: function() { this._clock.destroy(); this._clock = null; - + if (this._notificationsBox) { this._notificationsBox.destroy(); this._notificationsBox = null; } - + this._stopArrowAnimation(); - + this._lockScreenContentsBox.destroy(); - + this._hasLockScreen = false; }, - + get locked() { return this._isLocked; }, - + get active() { return this._isActive; }, - + get activationTime() { return this._activationTime; }, - + deactivate: function(animate) { - this._dialog.finish(Lang.bind(this, function() { + if (this._dialog) @@ -13653,18 +13653,18 @@ index 2c812f5..bdce9e8 100644 this._finishDeactivate(animate); - })); }, - + _finishDeactivate: function(animate) { this._hideLockScreen(animate, 0); - + if (this._hasLockScreen) this._clearLockScreen(); - + if (Main.sessionMode.currentMode == 'lock-screen') Main.sessionMode.popMode('lock-screen'); if (Main.sessionMode.currentMode == 'unlock-dialog') Main.sessionMode.popMode('unlock-dialog'); - + Tweener.addTween(this._lockDialogGroup, { scale_x: 0, scale_y: 0, @@ -13674,22 +13674,22 @@ index 2c812f5..bdce9e8 100644 onCompleteScope: this }); }, - + _completeDeactivate: function() { if (this._dialog && !this._isGreeter) { this._dialog.destroy(); this._dialog = null; } - + this._lightbox.hide(); --- +-- 1.8.3.1 -From c128890b2bc5c21acca5dd8f786f1b4d84a474a1 Mon Sep 17 00:00:00 2001 +From d5a1f4e4846b0fc4d9a695bd520289fefc508dfd Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Tue, 6 Aug 2013 09:49:00 -0400 -Subject: [PATCH 48/66] screenShield: Remove confusing name +Subject: [PATCH 48/69] screenShield: Remove confusing name We have both finishDeactivate and completeDeactivate. Don't. --- @@ -13703,31 +13703,31 @@ index bdce9e8..2a8001e 100644 @@ -1093,67 +1093,67 @@ const ScreenShield = new Lang.Class({ this._clock.destroy(); this._clock = null; - + if (this._notificationsBox) { this._notificationsBox.destroy(); this._notificationsBox = null; } - + this._stopArrowAnimation(); - + this._lockScreenContentsBox.destroy(); - + this._hasLockScreen = false; }, - + get locked() { return this._isLocked; }, - + get active() { return this._isActive; }, - + get activationTime() { return this._activationTime; }, - + deactivate: function(animate) { if (this._dialog) this._dialog.finish(Lang.bind(this, function() { @@ -13738,19 +13738,19 @@ index bdce9e8..2a8001e 100644 - this._finishDeactivate(animate); + this._continueDeactivate(animate); }, - + - _finishDeactivate: function(animate) { + _continueDeactivate: function(animate) { this._hideLockScreen(animate, 0); - + if (this._hasLockScreen) this._clearLockScreen(); - + if (Main.sessionMode.currentMode == 'lock-screen') Main.sessionMode.popMode('lock-screen'); if (Main.sessionMode.currentMode == 'unlock-dialog') Main.sessionMode.popMode('unlock-dialog'); - + Tweener.addTween(this._lockDialogGroup, { scale_x: 0, scale_y: 0, @@ -13760,25 +13760,25 @@ index bdce9e8..2a8001e 100644 onCompleteScope: this }); }, - + _completeDeactivate: function() { if (this._dialog && !this._isGreeter) { this._dialog.destroy(); this._dialog = null; } - + this._lightbox.hide(); - + if (this._isModal) { Main.popModal(this.actor); --- +-- 1.8.3.1 -From 7be80c08a3ad9bd33150fa568ff8e3956567d087 Mon Sep 17 00:00:00 2001 +From 3d6f7008778f671a573888b0ea47b134b50691ef Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 3 Jun 2013 23:45:31 +0200 -Subject: [PATCH 49/66] ScreenShield: remove curtain animation when hiding +Subject: [PATCH 49/69] ScreenShield: remove curtain animation when hiding without animation If we don't remove the animation, we might leave a pending call @@ -13800,31 +13800,31 @@ index 2a8001e..8fea66a 100644 log('Could not acquire modal grab for the login screen. Aborting login process.'); Meta.quit(Meta.ExitCode.ERROR); } - + return false; })); - + this.actor.show(); this._isGreeter = Main.sessionMode.isGreeter; this._isLocked = true; this._ensureUnlockDialog(true, true); this._hideLockScreen(false, 0); }, - + _hideLockScreenComplete: function() { if (Main.sessionMode.currentMode == 'lock-screen') Main.sessionMode.popMode('lock-screen'); - + this._lockScreenState = MessageTray.State.HIDDEN; this._lockScreenGroup.hide(); }, - + _hideLockScreen: function(animate, velocity) { if (this._lockScreenState == MessageTray.State.HIDDEN) return; - + this._lockScreenState = MessageTray.State.HIDING; - + + Tweener.removeTweens(this._lockScreenGroup); + if (animate) { @@ -13835,10 +13835,10 @@ index 2a8001e..8fea66a 100644 let h = global.stage.height; let delta = (h + this._lockScreenGroup.y); let min_velocity = global.stage.height / (CURTAIN_SLIDE_TIME * 1000); - + velocity = Math.max(min_velocity, velocity); let time = (delta / velocity) / 1000; - + - Tweener.removeTweens(this._lockScreenGroup); Tweener.addTween(this._lockScreenGroup, { y: -h, @@ -13849,10 +13849,10 @@ index 2a8001e..8fea66a 100644 } else { this._hideLockScreenComplete(); } - + global.stage.show_cursor(); }, - + _ensureUnlockDialog: function(onPrimary, allowCancel) { if (!this._dialog) { let constructor = Main.sessionMode.unlockDialog; @@ -13861,23 +13861,23 @@ index 2a8001e..8fea66a 100644 this.deactivate(true); return; } - + this._dialog = new constructor(this._lockDialogGroup); - - + + let time = global.get_current_time(); if (!this._dialog.open(time, onPrimary)) { // This is kind of an impossible error: we're already modal // by the time we reach this... log('Could not open login dialog: failed to acquire grab'); --- +-- 1.8.3.1 -From fe3f4d95ccd61d54e06f247ae49058d86802f1fa Mon Sep 17 00:00:00 2001 +From 0db93a2e049dc1ba1db7864754ac2004e5486d50 Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Thu, 6 Jun 2013 22:09:28 +0200 -Subject: [PATCH 50/66] ScreenShield: don't really deactivate when acting as a +Subject: [PATCH 50/69] ScreenShield: don't really deactivate when acting as a greeter In greeter mode, we don't want to hide the login dialog, drop the @@ -13894,15 +13894,15 @@ index 8fea66a..862fd1e 100644 +++ b/js/ui/screenShield.js @@ -1111,72 +1111,86 @@ const ScreenShield = new Lang.Class({ }, - + get active() { return this._isActive; }, - + get activationTime() { return this._activationTime; }, - + deactivate: function(animate) { if (this._dialog) this._dialog.finish(Lang.bind(this, function() { @@ -13911,18 +13911,18 @@ index 8fea66a..862fd1e 100644 else this._continueDeactivate(animate); }, - + _continueDeactivate: function(animate) { this._hideLockScreen(animate, 0); - + if (this._hasLockScreen) this._clearLockScreen(); - + if (Main.sessionMode.currentMode == 'lock-screen') Main.sessionMode.popMode('lock-screen'); if (Main.sessionMode.currentMode == 'unlock-dialog') Main.sessionMode.popMode('unlock-dialog'); - + + if (this._isGreeter) { + // We don't want to "deactivate" any more than + // this. In particular, we don't want to drop @@ -13946,48 +13946,48 @@ index 8fea66a..862fd1e 100644 onCompleteScope: this }); }, - + _completeDeactivate: function() { - if (this._dialog && !this._isGreeter) { + if (this._dialog) { this._dialog.destroy(); this._dialog = null; } - + this._lightbox.hide(); - + if (this._isModal) { Main.popModal(this.actor); this._isModal = false; } - + this.actor.hide(); - + if (this._becameActiveId != 0) { this.idleMonitor.remove_watch(this._becameActiveId); this._becameActiveId = 0; } - + if (this._lockTimeoutId != 0) { Mainloop.source_remove(this._lockTimeoutId); this._lockTimeoutId = 0; } - + this._activationTime = 0; this._isActive = false; this._isLocked = false; this.emit('active-changed'); this.emit('locked-changed'); }, - --- + +-- 1.8.3.1 -From 0eb83adb659536086594bb737f9d841031b93a1e Mon Sep 17 00:00:00 2001 +From c2deee5a4d58a8f873498751621c244c2ff2df1f Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Mon, 12 Aug 2013 15:14:37 +0200 -Subject: [PATCH 51/66] ScreenShield: don't allow events through the lock +Subject: [PATCH 51/69] ScreenShield: don't allow events through the lock dialog Make the lock dialog group reactive, to intercept any events @@ -14007,10 +14007,10 @@ index 862fd1e..1d296a2 100644 --- a/js/ui/screenShield.js +++ b/js/ui/screenShield.js @@ -452,60 +452,61 @@ const ScreenShield = new Lang.Class({ - + this._updateBackgrounds(); Main.layoutManager.connect('monitors-changed', Lang.bind(this, this._updateBackgrounds)); - + this._arrowAnimationId = 0; this._arrowWatchId = 0; this._arrowActiveWatchId = 0; @@ -14022,60 +14022,60 @@ index 862fd1e..1d296a2 100644 // ignores alignment properties on the actor x_expand: true, y_expand: true }); - + for (let i = 0; i < N_ARROWS; i++) { let arrow = new Arrow({ opacity: 0 }); this._arrowContainer.add_actor(arrow); } this._lockScreenContents.add_actor(this._arrowContainer); - + this._dragAction = new Clutter.GestureAction(); this._dragAction.connect('gesture-begin', Lang.bind(this, this._onDragBegin)); this._dragAction.connect('gesture-progress', Lang.bind(this, this._onDragMotion)); this._dragAction.connect('gesture-end', Lang.bind(this, this._onDragEnd)); this._lockScreenGroup.add_action(this._dragAction); - + this._lockDialogGroup = new St.Widget({ x_expand: true, y_expand: true, + reactive: true, opacity: 0, pivot_point: new Clutter.Point({ x: 0.5, y: 0.5 }), name: 'lockDialogGroup' }); - + Tweener.addTween(this._lockDialogGroup, { opacity: 255, time: INITIAL_FADE_IN_TIME, transition: 'easeInQuad', }); - + this.actor.add_actor(this._lockDialogGroup); this.actor.add_actor(this._lockScreenGroup); - + this._presence = new GnomeSession.Presence(Lang.bind(this, function(proxy, error) { if (error) { logError(error, 'Error while reading gnome-session presence'); return; } - + this._onStatusChanged(proxy.status); })); this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) { this._onStatusChanged(status); })); - + this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this); - + this._smartcardManager = SmartcardManager.getSmartcardManager(); this._smartcardManager.connect('smartcard-inserted', - Lang.bind(this, function(token) { --- + Lang.bind(this, function(manager, token) { +-- 1.8.3.1 -From df3d72c639cdd49b4b58ef3b8e0ab05046b71201 Mon Sep 17 00:00:00 2001 +From 3618ce49f59f00eb08b040e33ff64aae592c30fd Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 21 Aug 2013 11:54:03 -0400 -Subject: [PATCH 52/66] loginDialog: add support for auth without username / +Subject: [PATCH 52/69] loginDialog: add support for auth without username / fix Not Listed? commit 93f072d1fcf578c4e7550bd755e84bd46abcd493 attempted to @@ -14097,20 +14097,20 @@ index 643c7d6..887bedb 100644 { expand: true, x_fill: true, y_fill: true }); - + this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN); this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted)); this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); this._authPrompt.hide(); - + this._authPrompt.actor.add_constraint(new Clutter.AlignConstraint({ source: this.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); - + this.actor.add_child(this._authPrompt.actor); this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._authPrompt.actor, coordinate: Clutter.BindCoordinate.WIDTH })); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -14123,21 +14123,21 @@ index 643c7d6..887bedb 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + - this._notListedButton.connect('clicked', - Lang.bind(this, function() { - this._authPrompt.cancelButton.show(); - this._hideUserListAndLogIn(); - })); + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAskForUsernameAndBeginVerification)); - + this._notListedButton.hide(); - + this._userSelectionBox.add(this._notListedButton, { expand: false, x_align: St.Align.START, x_fill: true }); - + this._logoBin = new St.Bin({ style_class: 'login-dialog-logo-bin', y_expand: true }); this._logoBin.set_y_align(Clutter.ActorAlign.END); this._logoBin.add_constraint(new Clutter.AlignConstraint({ source: this.actor, @@ -14148,7 +14148,7 @@ index 643c7d6..887bedb 100644 factor: 1.0 })); this.actor.add_child(this._logoBin); this._updateLogo(); - + if (!this._userManager.is_loaded) this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', Lang.bind(this, function() { @@ -14163,34 +14163,34 @@ index 643c7d6..887bedb 100644 @@ -569,66 +565,65 @@ const LoginDialog = new Lang.Class({ if (this._logoFileUri != uri) return; - + let icon = null; if (this._logoFileUri) icon = this._textureCache.load_uri_async(this._logoFileUri, -1, _LOGO_ICON_HEIGHT); this._logoBin.set_child(icon); }, - + _updateLogo: function() { let path = this._settings.get_string(GdmUtil.LOGO_KEY); - + this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; this._updateLogoTexture(this._textureCache, this._logoFileUri); }, - + _onPrompted: function() { this._sessionMenuButton.updateSensitivity(true); - + if (this._shouldShowSessionMenuButton()) this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor); this._showPrompt(); }, - + _onReset: function(authPrompt, beginRequest) { this._sessionMenuButton.updateSensitivity(true); - + this._user = null; - + - if (this._disableUserList) { - this._authPrompt.cancelButton.hide(); - this._hideUserListAndLogIn(); @@ -14203,21 +14203,21 @@ index 643c7d6..887bedb 100644 + else + this._hideUserListAndBeginVerification(); }, - + _onDefaultSessionChanged: function(client, sessionId) { this._sessionMenuButton.setActiveSession(sessionId); }, - + _shouldShowSessionMenuButton: function() { if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING) return false; - + if (this._user && this._user.is_logged_in()) return false; - + return true; }, - + _showPrompt: function() { if (this._authPrompt.actor.visible) return; @@ -14228,18 +14228,18 @@ index 643c7d6..887bedb 100644 time: _FADE_ANIMATION_TIME, transition: 'easeOutQuad' }); }, - + _showRealmLoginHint: function(realmManager, hint) { if (!hint) return; --- +-- 1.8.3.1 -From 96cc4400c7c3aca9b89a5c48574048ee5183092d Mon Sep 17 00:00:00 2001 +From 891a19f8c381772a4e235b014c2c106279bcd940 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Fri, 16 Aug 2013 08:48:35 -0400 -Subject: [PATCH 53/66] theme: minor user item tweaks +Subject: [PATCH 53/69] theme: minor user item tweaks too much padding between avatar and name - https://cloud.gnome.org/public.php?service=files&t=2a4b3383b568a7986edfcb3501bdd020 @@ -14251,48 +14251,48 @@ https://cloud.gnome.org/public.php?service=files&t=16b6eaa8f607650bcd11a4d4236fe 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css -index 15457fe..72a7ad9 100644 +index e074554..2885a6e 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css -@@ -2242,61 +2242,61 @@ StScrollBar StButton#vhandle:active { +@@ -2247,61 +2247,61 @@ StScrollBar StButton#vhandle:active { } - + .login-dialog-prompt-login-hint-message { font-size: 10.5pt; } - + .login-dialog-user-list-view { -st-vfade-offset: 1em; } - + .login-dialog-user-list { spacing: 12px; padding: .2em; } - + .login-dialog-user-list-item { border-radius: 10px; padding: .2em; } - + .login-dialog-user-list-item:ltr { padding-right: 1em; } - + .login-dialog-user-list-item:rtl { padding-left: 1em; } - + .login-dialog-user-list-item .login-dialog-user-list-item-name { font-size: 20pt; - padding-left: 1em; + padding-left: 9px; } - + .login-dialog-user-list:expanded .login-dialog-user-list-item { color: #666666; } - + .login-dialog-user-list-item, .login-dialog-user-list-item:hover .login-dialog-user-list-item-name, .login-dialog-user-list:expanded .login-dialog-user-list-item:focus .login-dialog-user-list-item-name, @@ -14300,36 +14300,36 @@ index 15457fe..72a7ad9 100644 color: white; text-shadow: black 0px 2px 2px; } - + .login-dialog-user-list-item:hover { background-color: rgba(255,255,255,0.1); } - + .login-dialog-user-list:expanded .login-dialog-user-list-item:focus { background-color: rgba(255,255,255,0.33); } - + .login-dialog-user-list:expanded .login-dialog-user-list-item:logged-in { background-image: url("logged-in-indicator.svg"); background-size: contain; } - + .login-dialog-user-list-item-text-box { padding: 0 0.5em; } -@@ -2321,60 +2321,61 @@ StScrollBar StButton#vhandle:active { +@@ -2326,60 +2326,61 @@ StScrollBar StButton#vhandle:active { font-size: 10.5pt; font-weight: bold; color: #666666; padding-top: 1em; padding-left: 2px; } - + .login-dialog-not-listed-button:focus .login-dialog-not-listed-label, .login-dialog-not-listed-button:hover .login-dialog-not-listed-label { color: #E8E8E8; } - + .login-dialog-username { font-size: 16pt; font-weight: bold; @@ -14337,79 +14337,79 @@ index 15457fe..72a7ad9 100644 padding-left: 15px; text-shadow: black 0px 4px 3px 0px; } - + .login-dialog-prompt-layout { padding-top: 24px; padding-bottom: 12px; spacing: 8px; width: 23em; } - + .login-dialog-prompt-label { color: #eeeeee; font-size: 14px; + padding-top: 11px; } - + .login-dialog-session-list-button StIcon { icon-size: 1.25em; } - + .login-dialog-session-list-button { color: #8b8b8b; } - + .login-dialog-session-list-button:hover, .login-dialog-session-list-button:active { color: white; } - + .login-dialog-logo-bin { padding: 24px 0px; } - + .login-dialog .modal-dialog-button-box { spacing: 3px; } - + .login-dialog .modal-dialog-button { border-radius: 5px; padding: 3px 18px; } - + .login-dialog .modal-dialog-button:focus { padding: 2px 17px; -@@ -2386,64 +2387,60 @@ StScrollBar StButton#vhandle:active { +@@ -2391,64 +2392,60 @@ StScrollBar StButton#vhandle:active { background-gradient-direction: vertical; border-color: #16335d; } - + .login-dialog .modal-dialog-button:default:focus { border: 2px solid #377fe7; } - + .login-dialog .modal-dialog-button:default:hover { background-gradient-start: #74a0d0; background-gradient-end: #436d9f; } - + .login-dialog .modal-dialog-button:default:active, .login-dialog .modal-dialog-button:default:pressed { background-gradient-start: #436d9f; background-gradient-end: #74a0d0; } - + .login-dialog .modal-dialog-button:default:insensitive { border-color: #666666; color: #9f9f9f; background-gradient-direction: none; background-color: rgba(102, 102, 102, 0.15); } - + .login-dialog-message-warning { color: orange; } - + -.user-widget { - spacing: .4em; -} @@ -14421,22 +14421,22 @@ index 15457fe..72a7ad9 100644 padding-left: 15px; text-shadow: black 0px 4px 3px 0px; } - + /* Screen shield */ - + .screen-shield-background { background: black; } - + #lockDialogGroup { background: #2e3436 url(noise-texture.png); background-repeat: repeat; } - + .screen-shield-arrows { padding-bottom: 3em; } - + .screen-shield-arrows Gjs_Arrow { color: white; width: 80px; @@ -14444,14 +14444,14 @@ index 15457fe..72a7ad9 100644 -arrow-thickness: 12px; -arrow-shadow: 0 1px 1px rgba(0,0,0,0.4); } --- +-- 1.8.3.1 -From 2b398b84d57c23947b64b43d0d1672b533537882 Mon Sep 17 00:00:00 2001 +From 2700af5367c39b33a37f08b9c049074458db18a9 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Mon, 19 Aug 2013 12:00:33 -0400 -Subject: [PATCH 54/66] loginDialog: consolidate message label and login hint +Subject: [PATCH 54/69] loginDialog: consolidate message label and login hint label Right now the login hint is showing up just above the the cancel @@ -14474,40 +14474,40 @@ https://bugzilla.gnome.org/show_bug.cgi?id=706324 4 files changed, 51 insertions(+), 48 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css -index 72a7ad9..91a6092 100644 +index 2885a6e..d0578c2 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css -@@ -2214,64 +2214,60 @@ StScrollBar StButton#vhandle:active { +@@ -2219,64 +2219,60 @@ StScrollBar StButton#vhandle:active { text-align: center; color: #666666; padding-bottom: 1em; } - + .login-dialog-title { font-size: 14pt; font-weight: bold; color: #666666; padding-bottom: 2em; } - + .login-dialog { /* Reset border and background */ border: none; background-color: transparent; - + padding-bottom: 80px; padding-top: 80px; - + border-radius: 16px; min-height: 150px; max-height: 700px; min-width: 350px; } - + .login-dialog-button-box { spacing: 5px; } - + -.login-dialog-prompt-login-hint-message { - font-size: 10.5pt; -} @@ -14515,64 +14515,64 @@ index 72a7ad9..91a6092 100644 .login-dialog-user-list-view { -st-vfade-offset: 1em; } - + .login-dialog-user-list { spacing: 12px; padding: .2em; } - + .login-dialog-user-list-item { border-radius: 10px; padding: .2em; } - + .login-dialog-user-list-item:ltr { padding-right: 1em; } - + .login-dialog-user-list-item:rtl { padding-left: 1em; } - + .login-dialog-user-list-item .login-dialog-user-list-item-name { font-size: 20pt; padding-left: 9px; } - + .login-dialog-user-list:expanded .login-dialog-user-list-item { color: #666666; } -@@ -2383,64 +2379,76 @@ StScrollBar StButton#vhandle:active { - +@@ -2388,64 +2384,76 @@ StScrollBar StButton#vhandle:active { + .login-dialog .modal-dialog-button:default { background-gradient-start: #6793c4; background-gradient-end: #335d8f; background-gradient-direction: vertical; border-color: #16335d; } - + .login-dialog .modal-dialog-button:default:focus { border: 2px solid #377fe7; } - + .login-dialog .modal-dialog-button:default:hover { background-gradient-start: #74a0d0; background-gradient-end: #436d9f; } - + .login-dialog .modal-dialog-button:default:active, .login-dialog .modal-dialog-button:default:pressed { background-gradient-start: #436d9f; background-gradient-end: #74a0d0; } - + .login-dialog .modal-dialog-button:default:insensitive { border-color: #666666; color: #9f9f9f; background-gradient-direction: none; background-color: rgba(102, 102, 102, 0.15); } - + +.login-dialog-message-warning, +.login-dialog-message-info { + padding-top: 4px; @@ -14583,7 +14583,7 @@ index 72a7ad9..91a6092 100644 .login-dialog-message-warning { color: orange; } - + +.login-dialog-message-hint { + padding-bottom: 16px; + min-height: 2em; @@ -14596,22 +14596,22 @@ index 72a7ad9..91a6092 100644 padding-left: 15px; text-shadow: black 0px 4px 3px 0px; } - + /* Screen shield */ - + .screen-shield-background { background: black; } - + #lockDialogGroup { background: #2e3436 url(noise-texture.png); background-repeat: repeat; } - + .screen-shield-arrows { padding-bottom: 3em; } - + .screen-shield-arrows Gjs_Arrow { color: white; width: 80px; @@ -14630,49 +14630,49 @@ index d09e5b6..732ad1a 100644 const ShellEntry = imports.ui.shellEntry; const Tweener = imports.ui.tweener; const UserWidget = imports.ui.userWidget; - + const DEFAULT_BUTTON_WELL_ICON_SIZE = 24; const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; - + const MESSAGE_FADE_OUT_ANIMATION_TIME = 0.5; - + const AuthPromptMode = { UNLOCK_ONLY: 0, UNLOCK_OR_LOG_IN: 1 }; - + const AuthPromptStatus = { NOT_VERIFYING: 0, VERIFYING: 1, VERIFICATION_FAILED: 2, VERIFICATION_SUCCEEDED: 3 }; - + const BeginRequestType = { PROVIDE_USERNAME: 0, DONT_PROVIDE_USERNAME: 1 }; - + +let _messageStyleMap; + const AuthPrompt = new Lang.Class({ Name: 'AuthPrompt', - + _init: function(gdmClient, mode) { this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; - + this._gdmClient = gdmClient; this._mode = mode; - + let reauthenticationOnly; if (this._mode == AuthPromptMode.UNLOCK_ONLY) reauthenticationOnly = true; else if (this._mode == AuthPromptMode.UNLOCK_OR_LOG_IN) reauthenticationOnly = false; - + this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly }); - + this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._onShowMessage)); this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed)); @@ -14682,7 +14682,7 @@ index d09e5b6..732ad1a 100644 - this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._onHideLoginHint)); this._userVerifier.connect('smartcard-status-changed', Lang.bind(this, this._onSmartcardStatusChanged)); this.smartcardDetected = this._userVerifier.smartcardDetected; - + this.connect('next', Lang.bind(this, function() { this.updateSensitivity(false); this.startSpinning(); @@ -14692,7 +14692,7 @@ index d09e5b6..732ad1a 100644 this._preemptiveAnswer = this._entry.text; } })); - + this.actor = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout', vertical: true }); this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); @@ -14702,7 +14702,7 @@ index d09e5b6..732ad1a 100644 this.cancel(); } })); - + this._userWell = new St.Bin({ x_fill: true, x_align: St.Align.START }); this.actor.add(this._userWell, @@ -14711,7 +14711,7 @@ index d09e5b6..732ad1a 100644 y_fill: true, expand: true }); this._label = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this.actor.add(this._label, { expand: true, x_fill: true, @@ -14720,15 +14720,15 @@ index d09e5b6..732ad1a 100644 this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry', can_focus: true }); ShellEntry.addContextMenu(this._entry, { isPassword: true }); - + this.actor.add(this._entry, { expand: true, x_fill: true, y_fill: false, x_align: St.Align.START }); - + this._entry.grab_key_focus(); - + this._message = new St.Label({ opacity: 0 }); this._message.clutter_text.line_wrap = true; - this.actor.add(this._message, { x_fill: true }); @@ -14736,32 +14736,32 @@ index d09e5b6..732ad1a 100644 - this._loginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint-message' }); - this.actor.add(this._loginHint); + this.actor.add(this._message, { x_fill: true, y_align: St.Align.START }); - + this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box', vertical: false }); this.actor.add(this._buttonBox, { expand: true, x_align: St.Align.MIDDLE, y_align: St.Align.END }); - + this._defaultButtonWell = new St.Widget(); this._defaultButtonWellActor = null; - + this._initButtons(); - + let spinnerIcon = global.datadir + '/theme/process-working.svg'; this._spinner = new Panel.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE); this._spinner.actor.opacity = 0; this._spinner.actor.show(); this._defaultButtonWell.add_child(this._spinner.actor); }, - + _onDestroy: function() { this._userVerifier.clear(); this._userVerifier.disconnectAll(); this._userVerifier = null; }, - + _initButtons: function() { this.cancelButton = new St.Button({ style_class: 'modal-dialog-button', button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, @@ -14773,14 +14773,14 @@ index d09e5b6..732ad1a 100644 } else { this.nextButton.label = _("Next"); } - + this.updateSensitivity(true); this.emit('prompted'); }, - + _onSmartcardStatusChanged: function() { this.smartcardDetected = this._userVerifier.smartcardDetected; - + // Most of the time we want to reset if the user inserts or removes // a smartcard. Smartcard insertion "preempts" what the user was // doing, and smartcard removal aborts the preemption. @@ -14792,37 +14792,37 @@ index d09e5b6..732ad1a 100644 this.verificationStatus == AuthPromptStatus.VERIFYING && this.smartcardDetected) return; - + if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) this.reset(); }, - + - _onShowMessage: function(userVerifier, message, styleClass) { - this.setMessage(message, styleClass); + _onShowMessage: function(userVerifier, message, type) { + this.setMessage(message, type); this.emit('prompted'); }, - + _onVerificationFailed: function() { this.clear(); - + this.updateSensitivity(true); this.setActorInDefaultButtonWell(null); this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED; }, - + _onVerificationComplete: function() { this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED; }, - + _onReset: function() { if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) { this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; this.reset(); } }, - + - _onShowLoginHint: function(verifier, message) { - this.setHint(message); - }, @@ -14833,28 +14833,28 @@ index d09e5b6..732ad1a 100644 - addActorToDefaultButtonWell: function(actor) { this._defaultButtonWell.add_child(actor); - + actor.add_constraint(new Clutter.AlignConstraint({ source: this._spinner.actor, align_axis: Clutter.AlignAxis.BOTH, factor: 0.5 })); }, - + setActorInDefaultButtonWell: function(actor, animate) { if (!this._defaultButtonWellActor && !actor) return; - + let oldActor = this._defaultButtonWellActor; - + if (oldActor) Tweener.removeTweens(oldActor); - + let isSpinner; if (actor == this._spinner.actor) isSpinner = true; else isSpinner = false; - + if (this._defaultButtonWellActor != actor && oldActor) { if (!animate) { oldActor.opacity = 0; @@ -14864,53 +14864,53 @@ index d09e5b6..732ad1a 100644 @@ -332,155 +321,155 @@ const AuthPrompt = new Lang.Class({ transition: 'linear' }); } - + this._defaultButtonWellActor = actor; }, - + startSpinning: function() { this.setActorInDefaultButtonWell(this._spinner.actor, true); }, - + stopSpinning: function() { this.setActorInDefaultButtonWell(null, false); }, - + clear: function() { this._entry.text = ''; this.stopSpinning(); }, - + setPasswordChar: function(passwordChar) { this._entry.clutter_text.set_password_char(passwordChar); this._entry.menu.isPassword = passwordChar != ''; }, - + setQuestion: function(question) { this._label.set_text(question); - + this._label.show(); this._entry.show(); - + - this._loginHint.opacity = 0; - this._loginHint.show(); - this._entry.grab_key_focus(); }, - + getAnswer: function() { let text; - + if (this._preemptiveAnswer) { text = this._preemptiveAnswer; this._preemptiveAnswer = null; } else { text = this._entry.get_text(); } - + return text; }, - + _fadeOutMessage: function() { if (this._message.opacity == 0) return; @@ -14921,7 +14921,7 @@ index d09e5b6..732ad1a 100644 transition: 'easeOutQuad' }); }, - + - setMessage: function(message, styleClass) { + _initMessageStyleMap: function() { + if (_messageStyleMap) @@ -14948,30 +14948,30 @@ index d09e5b6..732ad1a 100644 this._message.opacity = 0; } }, - + _updateNextButtonSensitivity: function(sensitive) { this.nextButton.reactive = sensitive; this.nextButton.can_focus = sensitive; }, - + updateSensitivity: function(sensitive) { this._updateNextButtonSensitivity(sensitive); this._entry.reactive = sensitive; this._entry.clutter_text.editable = sensitive; }, - + hide: function() { this.setActorInDefaultButtonWell(null, true); this.actor.hide(); - this._loginHint.opacity = 0; + this._message.opacity = 0; - + this.setUser(null); - + this.updateSensitivity(true); this._entry.set_text(''); }, - + setUser: function(user) { if (user) { let userWidget = new UserWidget.UserWidget(user); @@ -14980,7 +14980,7 @@ index d09e5b6..732ad1a 100644 this._userWell.set_child(null); } }, - + - setHint: function(message) { - if (message) { - this._loginHint.set_text(message) @@ -14994,28 +14994,27 @@ index d09e5b6..732ad1a 100644 reset: function() { let oldStatus = this.verificationStatus; this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; - + if (oldStatus == AuthPromptStatus.VERIFYING) this._userVerifier.cancel(); - + this._queryingService = null; this.clear(); this._message.opacity = 0; this.setUser(null); this.stopSpinning(); - this.setHint(null); - + if (oldStatus == AuthPromptStatus.VERIFICATION_FAILED) this.emit('failed'); - + let beginRequestType; - + if (this._mode == AuthPromptMode.UNLOCK_ONLY) { // The user is constant at the unlock screen, so it will immediately // respond to the request with the username beginRequestType = BeginRequestType.PROVIDE_USERNAME; - } else if (this.smartcardDetected && - this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME)) { + } else if (this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME)) { // We don't need to know the username if the user preempted the login screen // with a smartcard. beginRequestType = BeginRequestType.DONT_PROVIDE_USERNAME; @@ -15023,14 +15022,15 @@ index d09e5b6..732ad1a 100644 // In all other cases, we should get the username up front. beginRequestType = BeginRequestType.PROVIDE_USERNAME; } - + this.emit('reset', beginRequestType); + }, - + addCharacter: function(unichar) { if (!this._entry.visible) return; - + this._entry.grab_key_focus(); this._entry.clutter_text.insert_unichar(unichar); }, @@ -15041,13 +15041,13 @@ index 887bedb..26028c8 100644 @@ -607,61 +607,61 @@ const LoginDialog = new Lang.Class({ if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING) return false; - + if (this._user && this._user.is_logged_in()) return false; - + return true; }, - + _showPrompt: function() { if (this._authPrompt.actor.visible) return; @@ -15058,30 +15058,30 @@ index 887bedb..26028c8 100644 time: _FADE_ANIMATION_TIME, transition: 'easeOutQuad' }); }, - + _showRealmLoginHint: function(realmManager, hint) { if (!hint) return; - + hint = hint.replace(/%U/g, 'user'); hint = hint.replace(/%D/g, 'DOMAIN'); hint = hint.replace(/%[^UD]/g, ''); - + // Translators: this message is shown below the username entry field // to clue the user in on how to login to the local network realm - this._authPrompt.setHint(_("(e.g., user or %s)").format(hint)); + this._authPrompt.setMessage(_("(e.g., user or %s)").format(hint), AuthPrompt.MessageType.HINT); }, - + _askForUsernameAndBeginVerification: function() { this._authPrompt.setPasswordChar(''); this._authPrompt.setQuestion(_("Username: ")); - + let realmManager = new Realmd.Manager(); let realmSignalId = realmManager.connect('login-format-changed', Lang.bind(this, this._showRealmLoginHint)); this._showRealmLoginHint(realmManager.loginFormat); - + let nextSignalId = this._authPrompt.connect('next', Lang.bind(this, function() { this._authPrompt.disconnect(nextSignalId); @@ -15091,14 +15091,14 @@ index 887bedb..26028c8 100644 this._authPrompt.startSpinning(); this._authPrompt.begin({ userName: answer }); this._updateCancelButton(); - + realmManager.disconnect(realmSignalId) realmManager.release(); })); this._updateCancelButton(); this._showPrompt(); }, - + _startSession: function(serviceName) { Tweener.addTween(this.actor, diff --git a/js/gdm/util.js b/js/gdm/util.js @@ -15107,7 +15107,7 @@ index 7ed5097..bfbd1b3 100644 +++ b/js/gdm/util.js @@ -9,60 +9,67 @@ const Signals = imports.signals; const St = imports.gi.St; - + const Batch = imports.gdm.batch; const Fprint = imports.gdm.fingerprint; const Main = imports.ui.main; @@ -15115,13 +15115,13 @@ index 7ed5097..bfbd1b3 100644 const ShellEntry = imports.ui.shellEntry; const SmartcardManager = imports.misc.smartcardManager; const Tweener = imports.ui.tweener; - + const PASSWORD_SERVICE_NAME = 'gdm-password'; const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint'; const SMARTCARD_SERVICE_NAME = 'gdm-smartcard'; const FADE_ANIMATION_TIME = 0.16; const CLONE_FADE_ANIMATION_TIME = 0.25; - + const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen'; const PASSWORD_AUTHENTICATION_KEY = 'enable-password-authentication'; const FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication'; @@ -15129,13 +15129,13 @@ index 7ed5097..bfbd1b3 100644 const BANNER_MESSAGE_KEY = 'banner-message-enable'; const BANNER_MESSAGE_TEXT_KEY = 'banner-message-text'; const ALLOWED_FAILURES_KEY = 'allowed-failures'; - + const LOGO_KEY = 'logo'; const DISABLE_USER_LIST_KEY = 'disable-user-list'; - + // Give user 16ms to read each character of a PAM message const USER_READ_TIME = 16 - + +const MessageType = { + NONE: 0, + ERROR: 1, @@ -15146,11 +15146,11 @@ index 7ed5097..bfbd1b3 100644 function fadeInActor(actor) { if (actor.opacity == 255 && actor.visible) return null; - + let hold = new Batch.Hold(); actor.show(); let [minHeight, naturalHeight] = actor.get_preferred_height(-1); - + actor.opacity = 0; actor.set_height(0); Tweener.addTween(actor, @@ -15163,10 +15163,10 @@ index 7ed5097..bfbd1b3 100644 hold.release(); }, }); - + return hold; } - + function fadeOutActor(actor) { if (!actor.visible || actor.opacity == 0) { actor.opacity = 0; @@ -15178,36 +15178,36 @@ index 7ed5097..bfbd1b3 100644 })); } }, - + _getIntervalForMessage: function(message) { // We probably could be smarter here return message.length * USER_READ_TIME; }, - + finishMessageQueue: function() { if (!this.hasPendingMessages) return; - + this._messageQueue = []; - + this.hasPendingMessages = false; this.emit('no-more-messages'); }, - + _queueMessageTimeout: function() { if (this._messageQueue.length == 0) { this.finishMessageQueue(); return; } - + if (this._messageQueueTimeoutId != 0) return; - + let message = this._messageQueue.shift(); - this.emit('show-message', message.text, message.iconName); + + this.emit('show-message', message.text, message.type); - + this._messageQueueTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT, message.interval, Lang.bind(this, function() { @@ -15215,20 +15215,20 @@ index 7ed5097..bfbd1b3 100644 this._queueMessageTimeout(); })); }, - + - _queueMessage: function(message, iconName) { + _queueMessage: function(message, messageType) { let interval = this._getIntervalForMessage(message); - + this.hasPendingMessages = true; - this._messageQueue.push({ text: message, interval: interval, iconName: iconName }); + this._messageQueue.push({ text: message, type: messageType, interval: interval }); this._queueMessageTimeout(); }, - + _clearMessageQueue: function() { this.finishMessageQueue(); - + if (this._messageQueueTimeoutId != 0) { GLib.source_remove(this._messageQueueTimeoutId); this._messageQueueTimeoutId = 0; @@ -15236,15 +15236,15 @@ index 7ed5097..bfbd1b3 100644 - this.emit('show-message', null, null); + this.emit('show-message', null, MessageType.NONE); }, - + _checkForFingerprintReader: function() { this._haveFingerprintReader = false; - + if (!this._settings.get_boolean(FINGERPRINT_AUTHENTICATION_KEY)) { this._updateDefaultService(); return; } - + this._fprintManager.GetDefaultDeviceRemote(Gio.DBusCallFlags.NONE, this._cancellable, Lang.bind(this, function(device, error) { if (!error && device) @@ -15252,38 +15252,38 @@ index 7ed5097..bfbd1b3 100644 this._updateDefaultService(); })); }, - + _checkForSmartcard: function() { let smartcardDetected; - + if (!this._settings.get_boolean(SMARTCARD_AUTHENTICATION_KEY)) smartcardDetected = false; - else if (this.reauthenticating) + else if (this._reauthOnly) smartcardDetected = this._smartcardManager.hasInsertedLoginToken(); else smartcardDetected = this._smartcardManager.hasInsertedTokens(); - + if (smartcardDetected != this.smartcardDetected) { this.smartcardDetected = smartcardDetected; - + if (this.smartcardDetected) this._preemptingService = SMARTCARD_SERVICE_NAME; else if (this._preemptingService == SMARTCARD_SERVICE_NAME) this._preemptingService = null; - + this.emit('smartcard-status-changed'); } }, - + _reportInitError: function(where, error) { logError(error, where); this._hold.release(); - + - this._queueMessage(_("Authentication error"), 'login-dialog-message-warning'); + this._queueMessage(_("Authentication error"), MessageType.ERROR); this._verificationFailed(false); }, - + _reauthenticationChannelOpened: function(client, result) { try { this._userVerifier = client.open_reauthentication_channel_finish(result); @@ -15300,20 +15300,20 @@ index 7ed5097..bfbd1b3 100644 this._reportInitError('Failed to open reauthentication channel', e); return; } - + this.reauthenticating = true; this._connectSignals(); this._beginVerification(); this._hold.release(); }, - + _userVerifierGot: function(client, result) { try { this._userVerifier = client.get_user_verifier_finish(result); } catch(e if e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) { @@ -372,78 +380,78 @@ const ShellUserVerifier = new Lang.Class({ }, - + _startService: function(serviceName) { this._hold.acquire(); this._userVerifier.call_begin_verification_for_user(serviceName, @@ -15328,18 +15328,18 @@ index 7ed5097..bfbd1b3 100644 this._reportInitError('Failed to start verification for user', e); return; } - + this._hold.release(); })); }, - + _beginVerification: function() { this._startService(this._getForegroundService()); - + if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME)) this._startService(FINGERPRINT_SERVICE_NAME); }, - + _onInfo: function(client, serviceName, info) { if (this.serviceIsForeground(serviceName)) { - this._queueMessage(info, 'login-dialog-message-info'); @@ -15349,48 +15349,48 @@ index 7ed5097..bfbd1b3 100644 // We don't show fingerprint messages directly since it's // not the main auth service. Instead we use the messages // as a cue to display our own message. - + // Translators: this message is shown below the password entry field // to indicate the user can swipe their finger instead - this.emit('show-login-hint', _("(or swipe finger)")); + this._queueMessage(_("(or swipe finger)"), MessageType.HINT); } }, - + _onProblem: function(client, serviceName, problem) { if (!this.serviceIsForeground(serviceName)) return; - + - this._queueMessage(problem, 'login-dialog-message-warning'); + this._queueMessage(problem, MessageType.ERROR); }, - + _onInfoQuery: function(client, serviceName, question) { if (!this.serviceIsForeground(serviceName)) return; - + this.emit('ask-question', serviceName, question, ''); }, - + _onSecretInfoQuery: function(client, serviceName, secretQuestion) { if (!this.serviceIsForeground(serviceName)) return; - + this.emit('ask-question', serviceName, secretQuestion, '\u25cf'); }, - + _onReset: function() { // Clear previous attempts to authenticate this._failCounter = 0; this._updateDefaultService(); - + this.emit('reset'); }, - + _onVerificationComplete: function() { this.emit('verification-complete'); }, - + _cancelAndReset: function() { this.cancel(); @@ -469,35 +477,33 @@ const ShellUserVerifier = new Lang.Class({ @@ -15413,10 +15413,10 @@ index 7ed5097..bfbd1b3 100644 })); } } - + this.emit('verification-failed'); }, - + _onConversationStopped: function(client, serviceName) { // if the password service fails, then cancel everything. // But if, e.g., fingerprint fails, still give @@ -15429,14 +15429,14 @@ index 7ed5097..bfbd1b3 100644 }, }); Signals.addSignalMethods(ShellUserVerifier.prototype); --- +-- 1.8.3.1 -From 56c4d03253cffefe9e311931c68ea16a30ff92d1 Mon Sep 17 00:00:00 2001 +From e0f9cbf201a2c41e8049a37bd97ae1b6e92cba71 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 21 Aug 2013 18:00:40 -0400 -Subject: [PATCH 55/66] objectManager: clear inhibitor on unregistered +Subject: [PATCH 55/69] objectManager: clear inhibitor on unregistered interfaces A D-Bus service can export more supported interfaces than the @@ -15459,15 +15459,15 @@ index b954f1b..f7265fe 100644 @@ -46,62 +46,65 @@ const ObjectManager = new Lang.Class({ g_object_path: this._managerPath, g_flags: Gio.DBusProxyFlags.NONE }); - + this._interfaceInfos = {}; this._objects = {}; this._interfaces = {}; this._onLoaded = params.onLoaded; - + if (params.knownInterfaces) this._registerInterfaces(params.knownInterfaces); - + // Start out inhibiting load until at least the proxy // manager is loaded and the remote objects are fetched this._numLoadInhibitors = 1; @@ -15475,7 +15475,7 @@ index b954f1b..f7265fe 100644 this._cancellable, Lang.bind(this, this._onManagerProxyLoaded)); }, - + _tryToCompleteLoad: function() { this._numLoadInhibitors--; if (this._numLoadInhibitors == 0) { @@ -15483,24 +15483,24 @@ index b954f1b..f7265fe 100644 this._onLoaded(); } }, - + _addInterface: function(objectPath, interfaceName, onFinished) { let info = this._interfaceInfos[interfaceName]; - + - if (!info) + if (!info) { + if (onFinished) + onFinished(); return; + } - + let proxy = new Gio.DBusProxy({ g_connection: this._connection, g_name: this._serviceName, g_object_path: objectPath, g_interface_name: interfaceName, g_interface_info: info, g_flags: Gio.DBusProxyFlags.NONE }); - + proxy.init_async(GLib.PRIORITY_DEFAULT, this._cancellable, Lang.bind(this, function(initable, result) { @@ -15509,12 +15509,12 @@ index b954f1b..f7265fe 100644 initable.init_finish(result); } catch(e) { logError(e, 'could not initialize proxy for interface ' + interfaceName); - + if (onFinished) onFinished(); return; } - + let isNewObject; if (!this._objects[objectPath]) { this._objects[objectPath] = {}; @@ -15522,15 +15522,15 @@ index b954f1b..f7265fe 100644 } else { isNewObject = false; } - --- + +-- 1.8.3.1 -From c48c761e17f996fbb3be4825cb4ac81cc4b24c58 Mon Sep 17 00:00:00 2001 +From 8fa149b7be4dd6d364a62d3329eed092f0678b52 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 22 Aug 2013 09:40:12 -0400 -Subject: [PATCH 56/66] objectManager: fix indentation +Subject: [PATCH 56/69] objectManager: fix indentation --- js/misc/objectManager.js | 34 +++++++++++++++++----------------- @@ -15545,15 +15545,15 @@ index f7265fe..6998dd2 100644 g_name: this._serviceName, g_object_path: this._managerPath, g_flags: Gio.DBusProxyFlags.NONE }); - + this._interfaceInfos = {}; this._objects = {}; this._interfaces = {}; this._onLoaded = params.onLoaded; - + if (params.knownInterfaces) this._registerInterfaces(params.knownInterfaces); - + // Start out inhibiting load until at least the proxy // manager is loaded and the remote objects are fetched this._numLoadInhibitors = 1; @@ -15561,7 +15561,7 @@ index f7265fe..6998dd2 100644 this._cancellable, Lang.bind(this, this._onManagerProxyLoaded)); }, - + _tryToCompleteLoad: function() { this._numLoadInhibitors--; if (this._numLoadInhibitors == 0) { @@ -15569,11 +15569,11 @@ index f7265fe..6998dd2 100644 this._onLoaded(); } }, - + _addInterface: function(objectPath, interfaceName, onFinished) { - let info = this._interfaceInfos[interfaceName]; + let info = this._interfaceInfos[interfaceName]; - + - if (!info) { - if (onFinished) - onFinished(); @@ -15611,12 +15611,12 @@ index f7265fe..6998dd2 100644 initable.init_finish(result); } catch(e) { logError(e, 'could not initialize proxy for interface ' + interfaceName); - + if (onFinished) onFinished(); return; } - + let isNewObject; if (!this._objects[objectPath]) { this._objects[objectPath] = {}; @@ -15624,26 +15624,26 @@ index f7265fe..6998dd2 100644 } else { isNewObject = false; } - + this._objects[objectPath][interfaceName] = proxy; - + if (!this._interfaces[interfaceName]) this._interfaces[interfaceName] = []; - + this._interfaces[interfaceName].push(proxy); - + if (isNewObject) this.emit('object-added', objectPath); - + this.emit('interface-added', interfaceName, proxy); --- +-- 1.8.3.1 -From c8cce4f83c6842e817f145be2c8a94893729a04e Mon Sep 17 00:00:00 2001 +From c2b2051f772839bebb387e81c58156f9f20966bf Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Wed, 21 Aug 2013 18:05:55 -0400 -Subject: [PATCH 57/66] gdmUtil: make _startService support no username +Subject: [PATCH 57/69] gdmUtil: make _startService support no username commit fd11ad95f61b904d6f7014f8d56c1c27d88af65c factored out duplicated code, but unintentionally dropped support @@ -15664,22 +15664,22 @@ index bfbd1b3..f421902 100644 this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete)); }, - + _getForegroundService: function() { if (this._preemptingService) return this._preemptingService; - + return this._defaultService; }, - + serviceIsForeground: function(serviceName) { return serviceName == this._getForegroundService(); }, - + serviceIsDefault: function(serviceName) { return serviceName == this._defaultService; }, - + _updateDefaultService: function() { if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY)) this._defaultService = PASSWORD_SERVICE_NAME; @@ -15688,7 +15688,7 @@ index bfbd1b3..f421902 100644 else if (this._haveFingerprintReader) this._defaultService = FINGERPRINT_SERVICE_NAME; }, - + _startService: function(serviceName) { this._hold.acquire(); - this._userVerifier.call_begin_verification_for_user(serviceName, @@ -15739,14 +15739,14 @@ index bfbd1b3..f421902 100644 + })); + } }, - + _beginVerification: function() { this._startService(this._getForegroundService()); - + if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME)) this._startService(FINGERPRINT_SERVICE_NAME); }, - + _onInfo: function(client, serviceName, info) { if (this.serviceIsForeground(serviceName)) { this._queueMessage(info, MessageType.INFO); @@ -15755,27 +15755,27 @@ index bfbd1b3..f421902 100644 // We don't show fingerprint messages directly since it's // not the main auth service. Instead we use the messages // as a cue to display our own message. - + // Translators: this message is shown below the password entry field // to indicate the user can swipe their finger instead this._queueMessage(_("(or swipe finger)"), MessageType.HINT); } }, - + _onProblem: function(client, serviceName, problem) { if (!this.serviceIsForeground(serviceName)) return; - + this._queueMessage(problem, MessageType.ERROR); }, --- +-- 1.8.3.1 -From 5992a2b073ca8e514ae92051f1e5ef2ee468f395 Mon Sep 17 00:00:00 2001 +From 1292f8268952af0fb25f13f3d857d7b848ccf4d6 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 22 Aug 2013 16:18:20 -0400 -Subject: [PATCH 58/66] loginDialog: ask for username up front if +Subject: [PATCH 58/69] loginDialog: ask for username up front if disable-user-list==TRUE Right now, we rely on PAM to ask for the username if disable-user-list @@ -15797,34 +15797,34 @@ index 26028c8..315a863 100644 @@ -565,119 +565,123 @@ const LoginDialog = new Lang.Class({ if (this._logoFileUri != uri) return; - + let icon = null; if (this._logoFileUri) icon = this._textureCache.load_uri_async(this._logoFileUri, -1, _LOGO_ICON_HEIGHT); this._logoBin.set_child(icon); }, - + _updateLogo: function() { let path = this._settings.get_string(GdmUtil.LOGO_KEY); - + this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; this._updateLogoTexture(this._textureCache, this._logoFileUri); }, - + _onPrompted: function() { this._sessionMenuButton.updateSensitivity(true); - + if (this._shouldShowSessionMenuButton()) this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor); this._showPrompt(); }, - + _onReset: function(authPrompt, beginRequest) { this._sessionMenuButton.updateSensitivity(true); - + this._user = null; - + - if (!this._disableUserList && - beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) - this._showUserList(); @@ -15838,22 +15838,22 @@ index 26028c8..315a863 100644 this._hideUserListAndBeginVerification(); + } }, - + _onDefaultSessionChanged: function(client, sessionId) { this._sessionMenuButton.setActiveSession(sessionId); }, - + _shouldShowSessionMenuButton: function() { if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING) return false; - + - if (this._user && this._user.is_logged_in()) + if (this._user && this._user.is_loaded && this._user.is_logged_in()) return false; - + return true; }, - + _showPrompt: function() { if (this._authPrompt.actor.visible) return; @@ -15864,29 +15864,29 @@ index 26028c8..315a863 100644 time: _FADE_ANIMATION_TIME, transition: 'easeOutQuad' }); }, - + _showRealmLoginHint: function(realmManager, hint) { if (!hint) return; - + hint = hint.replace(/%U/g, 'user'); hint = hint.replace(/%D/g, 'DOMAIN'); hint = hint.replace(/%[^UD]/g, ''); - + // Translators: this message is shown below the username entry field // to clue the user in on how to login to the local network realm this._authPrompt.setMessage(_("(e.g., user or %s)").format(hint), AuthPrompt.MessageType.HINT); }, - + _askForUsernameAndBeginVerification: function() { this._authPrompt.setPasswordChar(''); this._authPrompt.setQuestion(_("Username: ")); - + let realmManager = new Realmd.Manager(); let realmSignalId = realmManager.connect('login-format-changed', Lang.bind(this, this._showRealmLoginHint)); this._showRealmLoginHint(realmManager.loginFormat); - + let nextSignalId = this._authPrompt.connect('next', Lang.bind(this, function() { this._authPrompt.disconnect(nextSignalId); @@ -15897,14 +15897,14 @@ index 26028c8..315a863 100644 this._authPrompt.startSpinning(); this._authPrompt.begin({ userName: answer }); this._updateCancelButton(); - + realmManager.disconnect(realmSignalId) realmManager.release(); })); this._updateCancelButton(); this._showPrompt(); }, - + _startSession: function(serviceName) { Tweener.addTween(this.actor, { opacity: 0, @@ -15912,7 +15912,7 @@ index 26028c8..315a863 100644 transition: 'easeOutQuad', onUpdate: function() { let children = Main.layoutManager.uiGroup.get_children(); - + for (let i = 0; i < children.length; i++) { if (children[i] != Main.layoutManager.screenShieldGroup) children[i].opacity = this.actor.opacity; @@ -15923,14 +15923,14 @@ index 26028c8..315a863 100644 Mainloop.idle_add(Lang.bind(this, function() { this._greeter.call_start_session_when_ready_sync(serviceName, true, null); return false; --- +-- 1.8.3.1 -From 87ca2f703b29f97c47ceed12886c23deb0339b4f Mon Sep 17 00:00:00 2001 +From a00b1674fbb3278e3763e662c9176b394c17d2b4 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 26 Aug 2013 18:02:04 -0400 -Subject: [PATCH 59/66] loginDialog: Provide a finish method +Subject: [PATCH 59/69] loginDialog: Provide a finish method The screenShield expects to be able to call finish on the dialog. --- @@ -15942,18 +15942,18 @@ index 315a863..0224bd2 100644 --- a/js/gdm/loginDialog.js +++ b/js/gdm/loginDialog.js @@ -895,32 +895,36 @@ const LoginDialog = new Lang.Class({ - + this._userManager.connect('user-added', Lang.bind(this, function(userManager, user) { this._userList.addUser(user); })); - + this._userManager.connect('user-removed', Lang.bind(this, function(userManager, user) { this._userList.removeUser(user); })); }, - + open: function() { Main.ctrlAltTabManager.addGroup(this.actor, _("Login Window"), @@ -15961,14 +15961,14 @@ index 315a863..0224bd2 100644 { sortGroup: CtrlAltTab.SortGroup.MIDDLE }); this._userList.actor.grab_key_focus(); this.actor.show(); - + return true; }, - + close: function() { Main.ctrlAltTabManager.removeGroup(this.dialogLayout); }, - + addCharacter: function(unichar) { this._authPrompt.addCharacter(unichar); }, @@ -15978,14 +15978,14 @@ index 315a863..0224bd2 100644 + }, }); Signals.addSignalMethods(LoginDialog.prototype); --- +-- 1.8.3.1 -From 508f357490a26a2f6c0f01a6be436dafac145a18 Mon Sep 17 00:00:00 2001 +From bfc9443c5ff4d4968b2944a009084959684171a1 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 26 Aug 2013 18:04:09 -0400 -Subject: [PATCH 60/66] loginDialog: Fade in the gdm auth prompt on login +Subject: [PATCH 60/69] loginDialog: Fade in the gdm auth prompt on login --- js/gdm/loginDialog.js | 6 ++++++ @@ -15998,27 +15998,27 @@ index 0224bd2..d99d79b 100644 @@ -884,47 +884,53 @@ const LoginDialog = new Lang.Class({ } }, - + _loadUserList: function() { let users = this._userManager.list_users(); - + for (let i = 0; i < users.length; i++) { this._userList.addUser(users[i]); } - + this._updateDisableUserList(); - + this._userManager.connect('user-added', Lang.bind(this, function(userManager, user) { this._userList.addUser(user); })); - + this._userManager.connect('user-removed', Lang.bind(this, function(userManager, user) { this._userList.removeUser(user); })); }, - + open: function() { Main.ctrlAltTabManager.addGroup(this.actor, _("Login Window"), @@ -16032,31 +16032,31 @@ index 0224bd2..d99d79b 100644 + { opacity: 255, + time: 1, + transition: 'easeInQuad' }); - + return true; }, - + close: function() { Main.ctrlAltTabManager.removeGroup(this.dialogLayout); }, - + addCharacter: function(unichar) { this._authPrompt.addCharacter(unichar); }, - + finish: function(onComplete) { this._authPrompt.finish(onComplete); }, }); Signals.addSignalMethods(LoginDialog.prototype); --- +-- 1.8.3.1 -From 86ef60f2bbca5b10b260c1dc78b234e53d66f990 Mon Sep 17 00:00:00 2001 +From 0534d84dbc65938fe5bea26dcd5749f2e438e428 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 26 Aug 2013 15:43:27 -0400 -Subject: [PATCH 61/66] unlockDialog: Remove clutter constraints from the code +Subject: [PATCH 61/69] unlockDialog: Remove clutter constraints from the code These cause annoying allocation cycle warnings, and it's simpler to just express our desired layout in terms of nested containers. @@ -16069,21 +16069,21 @@ https://bugzilla.gnome.org/show_bug.cgi?id=706843 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css -index 91a6092..dbf5f27 100644 +index d0578c2..a0642f2 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css -@@ -2200,68 +2200,60 @@ StScrollBar StButton#vhandle:active { - +@@ -2205,68 +2205,60 @@ StScrollBar StButton#vhandle:active { + .candidate-page-button-next { border-radius: 0px 4px 4px 0px; } - + .candidate-page-button-icon { icon-size: 1em; } - + /* Login Dialog */ - + .login-dialog-banner { font-size: 10pt; font-weight: bold; @@ -16091,14 +16091,14 @@ index 91a6092..dbf5f27 100644 color: #666666; padding-bottom: 1em; } - + .login-dialog-title { font-size: 14pt; font-weight: bold; color: #666666; padding-bottom: 2em; } - + .login-dialog { /* Reset border and background */ border: none; @@ -16112,33 +16112,33 @@ index 91a6092..dbf5f27 100644 - max-height: 700px; - min-width: 350px; } - + .login-dialog-button-box { spacing: 5px; } - + .login-dialog-user-list-view { -st-vfade-offset: 1em; } - + .login-dialog-user-list { spacing: 12px; padding: .2em; } - + .login-dialog-user-list-item { border-radius: 10px; padding: .2em; } - + .login-dialog-user-list-item:ltr { padding-right: 1em; } - + .login-dialog-user-list-item:rtl { padding-left: 1em; } - + .login-dialog-user-list-item .login-dialog-user-list-item-name { font-size: 20pt; diff --git a/js/ui/unlockDialog.js b/js/ui/unlockDialog.js @@ -16154,38 +16154,38 @@ index 09024ba..abbe8c4 100644 const Signals = imports.signals; const Shell = imports.gi.Shell; const St = imports.gi.St; - + const Layout = imports.ui.layout; const Main = imports.ui.main; const Panel = imports.ui.panel; const Tweener = imports.ui.tweener; const UserMenu = imports.ui.userMenu; const UserWidget = imports.ui.userWidget; - + const AuthPrompt = imports.gdm.authPrompt; const Batch = imports.gdm.batch; const GdmUtil = imports.gdm.util; const LoginDialog = imports.gdm.loginDialog; - + // The timeout before going back automatically to the lock screen (in seconds) const IDLE_TIMEOUT = 2 * 60; - + const UnlockDialog = new Lang.Class({ Name: 'UnlockDialog', - + _init: function(parentActor) { this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW, style_class: 'login-dialog', + layout_manager: new Clutter.BoxLayout(), visible: false }); - + this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true })); parentActor.add_child(this.actor); - + this._userManager = AccountsService.UserManager.get_default(); this._userName = GLib.get_user_name(); this._user = this._userManager.get_user(this._userName); - + - this._promptBox = new St.BoxLayout({ vertical: true }); + this._promptBox = new St.BoxLayout({ vertical: true, + x_align: Clutter.ActorAlign.CENTER, @@ -16196,18 +16196,18 @@ index 09024ba..abbe8c4 100644 - this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor, - align_axis: Clutter.AlignAxis.BOTH, - factor: 0.5 })); - + this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY); this._authPrompt.connect('failed', Lang.bind(this, this._fail)); this._authPrompt.connect('cancelled', Lang.bind(this, this._fail)); this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); this._authPrompt.setPasswordChar('\u25cf'); this._authPrompt.nextButton.label = _("Unlock"); - + this._promptBox.add_child(this._authPrompt.actor); - + this.allowCancel = false; - + let screenSaverSettings = new Gio.Settings({ schema: 'org.gnome.desktop.screensaver' }); if (screenSaverSettings.get_boolean('user-switch-enabled')) { let otherUserLabel = new St.Label({ text: _("Log in as another user"), @@ -16223,17 +16223,17 @@ index 09024ba..abbe8c4 100644 } else { this._otherUserButton = null; } - + this._authPrompt.reset(); this._updateSensitivity(true); --- +-- 1.8.3.1 -From 828a62bd652077e75e6ce8919dfee9d3011cedcc Mon Sep 17 00:00:00 2001 +From 7173c7501671002b986a70187d5b9c029a063b17 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Mon, 26 Aug 2013 15:47:52 -0400 -Subject: [PATCH 62/66] gdm: Remove constraints from authPrompt / loginDialog +Subject: [PATCH 62/69] gdm: Remove constraints from authPrompt / loginDialog as well https://bugzilla.gnome.org/show_bug.cgi?id=706843 @@ -16244,65 +16244,65 @@ https://bugzilla.gnome.org/show_bug.cgi?id=706843 3 files changed, 15 insertions(+), 27 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css -index dbf5f27..56c34de 100644 +index a0642f2..9b7fe4a 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css -@@ -2213,60 +2213,61 @@ StScrollBar StButton#vhandle:active { +@@ -2218,60 +2218,61 @@ StScrollBar StButton#vhandle:active { font-weight: bold; text-align: center; color: #666666; padding-bottom: 1em; } - + .login-dialog-title { font-size: 14pt; font-weight: bold; color: #666666; padding-bottom: 2em; } - + .login-dialog { /* Reset border and background */ border: none; background-color: transparent; } - + .login-dialog-button-box { spacing: 5px; } - + .login-dialog-user-list-view { -st-vfade-offset: 1em; } - + .login-dialog-user-list { spacing: 12px; padding: .2em; + width: 23em; } - + .login-dialog-user-list-item { border-radius: 10px; padding: .2em; } - + .login-dialog-user-list-item:ltr { padding-right: 1em; } - + .login-dialog-user-list-item:rtl { padding-left: 1em; } - + .login-dialog-user-list-item .login-dialog-user-list-item-name { font-size: 20pt; padding-left: 9px; } - + .login-dialog-user-list:expanded .login-dialog-user-list-item { color: #666666; } - + .login-dialog-user-list-item, .login-dialog-user-list-item:hover .login-dialog-user-list-item-name, .login-dialog-user-list:expanded .login-dialog-user-list-item:focus .login-dialog-user-list-item-name, @@ -16315,7 +16315,7 @@ index 732ad1a..674dd3a 100644 +++ b/js/gdm/authPrompt.js @@ -93,61 +93,61 @@ const AuthPrompt = new Lang.Class({ this._label = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this.actor.add(this._label, { expand: true, x_fill: true, @@ -16324,45 +16324,45 @@ index 732ad1a..674dd3a 100644 this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry', can_focus: true }); ShellEntry.addContextMenu(this._entry, { isPassword: true }); - + this.actor.add(this._entry, { expand: true, x_fill: true, y_fill: false, x_align: St.Align.START }); - + this._entry.grab_key_focus(); - + this._message = new St.Label({ opacity: 0 }); this._message.clutter_text.line_wrap = true; this.actor.add(this._message, { x_fill: true, y_align: St.Align.START }); - + this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box', vertical: false }); this.actor.add(this._buttonBox, { expand: true, x_align: St.Align.MIDDLE, y_align: St.Align.END }); - + - this._defaultButtonWell = new St.Widget(); + this._defaultButtonWell = new St.Widget({ layout_manager: new Clutter.BinLayout() }); this._defaultButtonWellActor = null; - + this._initButtons(); - + let spinnerIcon = global.datadir + '/theme/process-working.svg'; this._spinner = new Panel.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE); this._spinner.actor.opacity = 0; this._spinner.actor.show(); this._defaultButtonWell.add_child(this._spinner.actor); }, - + _onDestroy: function() { this._userVerifier.clear(); this._userVerifier.disconnectAll(); this._userVerifier = null; }, - + _initButtons: function() { this.cancelButton = new St.Button({ style_class: 'modal-dialog-button', button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, @@ -16380,31 +16380,31 @@ index 732ad1a..674dd3a 100644 if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) this.reset(); }, - + _onShowMessage: function(userVerifier, message, type) { this.setMessage(message, type); this.emit('prompted'); }, - + _onVerificationFailed: function() { this.clear(); - + this.updateSensitivity(true); this.setActorInDefaultButtonWell(null); this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED; }, - + _onVerificationComplete: function() { this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED; }, - + _onReset: function() { if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) { this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; this.reset(); } }, - + addActorToDefaultButtonWell: function(actor) { this._defaultButtonWell.add_child(actor); - @@ -16412,23 +16412,23 @@ index 732ad1a..674dd3a 100644 - align_axis: Clutter.AlignAxis.BOTH, - factor: 0.5 })); }, - + setActorInDefaultButtonWell: function(actor, animate) { if (!this._defaultButtonWellActor && !actor) return; - + let oldActor = this._defaultButtonWellActor; - + if (oldActor) Tweener.removeTweens(oldActor); - + let isSpinner; if (actor == this._spinner.actor) isSpinner = true; else isSpinner = false; - + if (this._defaultButtonWellActor != actor && oldActor) { if (!animate) { oldActor.opacity = 0; @@ -16446,23 +16446,23 @@ index d99d79b..1649e4e 100644 --- a/js/gdm/loginDialog.js +++ b/js/gdm/loginDialog.js @@ -367,159 +367,151 @@ const SessionMenuButton = new Lang.Class({ - + if (ids.length <= 1) { this._button.hide(); return; } - + for (let i = 0; i < ids.length; i++) { let [sessionName, sessionDescription] = Gdm.get_session_name_and_description(ids[i]); - + let id = ids[i]; let item = new PopupMenu.PopupMenuItem(sessionName); this._menu.addMenuItem(item); this._items[id] = item; - + if (!this._activeSessionId) this.setActiveSession(id); - + item.connect('activate', Lang.bind(this, function() { this.setActiveSession(id); })); @@ -16470,37 +16470,37 @@ index d99d79b..1649e4e 100644 } }); Signals.addSignalMethods(SessionMenuButton.prototype); - + const LoginDialog = new Lang.Class({ Name: 'LoginDialog', - + _init: function(parentActor) { this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW, + layout_manager: new Clutter.BinLayout(), style_class: 'login-dialog', visible: false }); - + this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true })); this.actor.connect('destroy', Lang.bind(this, this._onDestroy)); parentActor.add_child(this.actor); - + this._userManager = AccountsService.UserManager.get_default() let gdmClient = new Gdm.Client(); - + if (GLib.getenv('GDM_GREETER_TEST') != '1') { this._greeter = gdmClient.get_greeter_sync(null); - + this._greeter.connect('default-session-name-changed', Lang.bind(this, this._onDefaultSessionChanged)); - + this._greeter.connect('session-opened', Lang.bind(this, this._onSessionOpened)); this._greeter.connect('timed-login-requested', Lang.bind(this, this._onTimedLoginRequested)); } - + this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA }); - + this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY, Lang.bind(this, this._updateBanner)); this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY, @@ -16509,11 +16509,11 @@ index d99d79b..1649e4e 100644 Lang.bind(this, this._updateDisableUserList)); this._settings.connect('changed::' + GdmUtil.LOGO_KEY, Lang.bind(this, this._updateLogo)); - + this._textureCache = St.TextureCache.get_default(); this._textureCache.connect('texture-file-changed', Lang.bind(this, this._updateLogoTexture)); - + this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', + x_align: Clutter.ActorAlign.CENTER, + y_align: Clutter.ActorAlign.CENTER, @@ -16525,18 +16525,18 @@ index d99d79b..1649e4e 100644 - align_axis: Clutter.AlignAxis.BOTH, - factor: 0.5 })); this.actor.add_child(this._userSelectionBox); - + this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', text: '' }); this._userSelectionBox.add(this._bannerLabel); this._updateBanner(); - + this._userList = new UserList(); this._userSelectionBox.add(this._userList.actor, { expand: true, x_fill: true, y_fill: true }); - + this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN); this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted)); this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); @@ -16549,7 +16549,7 @@ index d99d79b..1649e4e 100644 this.actor.add_child(this._authPrompt.actor); - this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._authPrompt.actor, - coordinate: Clutter.BindCoordinate.WIDTH })); - + // translators: this message is shown below the user list on the // login screen. It can be activated to reveal an entry for // manually entering the username. @@ -16562,16 +16562,16 @@ index d99d79b..1649e4e 100644 reactive: true, x_align: St.Align.START, x_fill: true }); - + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAskForUsernameAndBeginVerification)); - + this._notListedButton.hide(); - + this._userSelectionBox.add(this._notListedButton, { expand: false, x_align: St.Align.START, x_fill: true }); - + - this._logoBin = new St.Bin({ style_class: 'login-dialog-logo-bin', y_expand: true }); - this._logoBin.set_y_align(Clutter.ActorAlign.END); - this._logoBin.add_constraint(new Clutter.AlignConstraint({ source: this.actor, @@ -16587,7 +16587,7 @@ index d99d79b..1649e4e 100644 + y_expand: true }); this.actor.add_child(this._logoBin); this._updateLogo(); - + if (!this._userManager.is_loaded) this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', Lang.bind(this, function() { @@ -16599,13 +16599,13 @@ index d99d79b..1649e4e 100644 })); else this._loadUserList(); - + this._userList.connect('activate', Lang.bind(this, function(userList, item) { this._onUserListActivated(item); })); - - + + this._sessionMenuButton = new SessionMenuButton(); this._sessionMenuButton.connect('session-activated', Lang.bind(this, function(list, sessionId) { @@ -16614,26 +16614,26 @@ index d99d79b..1649e4e 100644 this._sessionMenuButton.actor.opacity = 0; this._sessionMenuButton.actor.show(); this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor); - + @@ -538,65 +530,64 @@ const LoginDialog = new Lang.Class({ - + _updateCancelButton: function() { let cancelVisible; - + // Hide the cancel button if the user list is disabled and we're asking for // a username if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING && this._disableUserList) cancelVisible = false; else cancelVisible = true; - + this._authPrompt.cancelButton.visible = cancelVisible; }, - + _updateBanner: function() { let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY); let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY); - + if (enabled && text) { this._bannerLabel.set_text(text); this._bannerLabel.show(); @@ -16641,11 +16641,11 @@ index d99d79b..1649e4e 100644 this._bannerLabel.hide(); } }, - + _updateLogoTexture: function(cache, uri) { if (this._logoFileUri != uri) return; - + - let icon = null; + this._logoBin.destroy_all_children(); if (this._logoFileUri) @@ -16655,27 +16655,27 @@ index d99d79b..1649e4e 100644 + this._logoBin.add_child(this._textureCache.load_uri_async(this._logoFileUri, + -1, _LOGO_ICON_HEIGHT)); }, - + _updateLogo: function() { let path = this._settings.get_string(GdmUtil.LOGO_KEY); - + this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; this._updateLogoTexture(this._textureCache, this._logoFileUri); }, - + _onPrompted: function() { this._sessionMenuButton.updateSensitivity(true); - + if (this._shouldShowSessionMenuButton()) this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor); this._showPrompt(); }, - + _onReset: function(authPrompt, beginRequest) { this._sessionMenuButton.updateSensitivity(true); - + this._user = null; - + if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) { if (!this._disableUserList) this._showUserList(); @@ -16684,14 +16684,14 @@ index d99d79b..1649e4e 100644 } else { this._hideUserListAndBeginVerification(); } --- +-- 1.8.3.1 -From 6939e19dfdc3f3ab2696eeaa589252577d706b8e Mon Sep 17 00:00:00 2001 +From 0f101cb83ce429d209a55be8e8071be51ea1bdf6 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 27 Aug 2013 10:17:26 -0400 -Subject: [PATCH 63/66] authPrompt: give message label an initial style +Subject: [PATCH 63/69] authPrompt: give message label an initial style This commit consolidates the styles of the various message types into one 'login-dialog-message' style @@ -16709,40 +16709,40 @@ https://bugzilla.gnome.org/show_bug.cgi?id=706670 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css -index 56c34de..32b6eab 100644 +index 9b7fe4a..40b4835 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css -@@ -2372,74 +2372,72 @@ StScrollBar StButton#vhandle:active { - +@@ -2377,74 +2377,72 @@ StScrollBar StButton#vhandle:active { + .login-dialog .modal-dialog-button:default { background-gradient-start: #6793c4; background-gradient-end: #335d8f; background-gradient-direction: vertical; border-color: #16335d; } - + .login-dialog .modal-dialog-button:default:focus { border: 2px solid #377fe7; } - + .login-dialog .modal-dialog-button:default:hover { background-gradient-start: #74a0d0; background-gradient-end: #436d9f; } - + .login-dialog .modal-dialog-button:default:active, .login-dialog .modal-dialog-button:default:pressed { background-gradient-start: #436d9f; background-gradient-end: #74a0d0; } - + .login-dialog .modal-dialog-button:default:insensitive { border-color: #666666; color: #9f9f9f; background-gradient-direction: none; background-color: rgba(102, 102, 102, 0.15); } - + -.login-dialog-message-warning, -.login-dialog-message-info { +.login-dialog-message { @@ -16750,17 +16750,17 @@ index 56c34de..32b6eab 100644 padding-bottom: 16px; min-height: 2em; } - + .login-dialog-message-warning { color: orange; } - + .login-dialog-message-hint { - padding-bottom: 16px; - min-height: 2em; + padding-top: 0px; } - + .user-widget-label { font-size: 16pt; font-weight: bold; @@ -16768,22 +16768,22 @@ index 56c34de..32b6eab 100644 padding-left: 15px; text-shadow: black 0px 4px 3px 0px; } - + /* Screen shield */ - + .screen-shield-background { background: black; } - + #lockDialogGroup { background: #2e3436 url(noise-texture.png); background-repeat: repeat; } - + .screen-shield-arrows { padding-bottom: 3em; } - + .screen-shield-arrows Gjs_Arrow { color: white; width: 80px; @@ -16800,49 +16800,49 @@ index 674dd3a..2121f2e 100644 const ShellEntry = imports.ui.shellEntry; const Tweener = imports.ui.tweener; const UserWidget = imports.ui.userWidget; - + const DEFAULT_BUTTON_WELL_ICON_SIZE = 24; const DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0; const DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3; - + const MESSAGE_FADE_OUT_ANIMATION_TIME = 0.5; - + const AuthPromptMode = { UNLOCK_ONLY: 0, UNLOCK_OR_LOG_IN: 1 }; - + const AuthPromptStatus = { NOT_VERIFYING: 0, VERIFYING: 1, VERIFICATION_FAILED: 2, VERIFICATION_SUCCEEDED: 3 }; - + const BeginRequestType = { PROVIDE_USERNAME: 0, DONT_PROVIDE_USERNAME: 1 }; - + -let _messageStyleMap; - const AuthPrompt = new Lang.Class({ Name: 'AuthPrompt', - + _init: function(gdmClient, mode) { this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; - + this._gdmClient = gdmClient; this._mode = mode; - + let reauthenticationOnly; if (this._mode == AuthPromptMode.UNLOCK_ONLY) reauthenticationOnly = true; else if (this._mode == AuthPromptMode.UNLOCK_OR_LOG_IN) reauthenticationOnly = false; - + this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly }); - + this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); this._userVerifier.connect('show-message', Lang.bind(this, this._onShowMessage)); this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed)); @@ -16850,7 +16850,7 @@ index 674dd3a..2121f2e 100644 this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); this._userVerifier.connect('smartcard-status-changed', Lang.bind(this, this._onSmartcardStatusChanged)); this.smartcardDetected = this._userVerifier.smartcardDetected; - + this.connect('next', Lang.bind(this, function() { this.updateSensitivity(false); this.startSpinning(); @@ -16860,7 +16860,7 @@ index 674dd3a..2121f2e 100644 this.cancel(); } })); - + this._userWell = new St.Bin({ x_fill: true, x_align: St.Align.START }); this.actor.add(this._userWell, @@ -16869,7 +16869,7 @@ index 674dd3a..2121f2e 100644 y_fill: true, expand: true }); this._label = new St.Label({ style_class: 'login-dialog-prompt-label' }); - + this.actor.add(this._label, { expand: true, x_fill: true, @@ -16878,68 +16878,68 @@ index 674dd3a..2121f2e 100644 this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry', can_focus: true }); ShellEntry.addContextMenu(this._entry, { isPassword: true }); - + this.actor.add(this._entry, { expand: true, x_fill: true, y_fill: false, x_align: St.Align.START }); - + this._entry.grab_key_focus(); - + - this._message = new St.Label({ opacity: 0 }); + this._message = new St.Label({ opacity: 0, + styleClass: 'login-dialog-message' }); this._message.clutter_text.line_wrap = true; this.actor.add(this._message, { x_fill: true, y_align: St.Align.START }); - + this._buttonBox = new St.BoxLayout({ style_class: 'login-dialog-button-box', vertical: false }); this.actor.add(this._buttonBox, { expand: true, x_align: St.Align.MIDDLE, y_align: St.Align.END }); - + this._defaultButtonWell = new St.Widget({ layout_manager: new Clutter.BinLayout() }); this._defaultButtonWellActor = null; - + this._initButtons(); - + let spinnerIcon = global.datadir + '/theme/process-working.svg'; this._spinner = new Panel.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE); this._spinner.actor.opacity = 0; this._spinner.actor.show(); this._defaultButtonWell.add_child(this._spinner.actor); }, - + _onDestroy: function() { this._userVerifier.clear(); this._userVerifier.disconnectAll(); this._userVerifier = null; }, - + _initButtons: function() { this.cancelButton = new St.Button({ style_class: 'modal-dialog-button', @@ -344,81 +343,76 @@ const AuthPrompt = new Lang.Class({ this._label.show(); this._entry.show(); - + this._entry.grab_key_focus(); }, - + getAnswer: function() { let text; - + if (this._preemptiveAnswer) { text = this._preemptiveAnswer; this._preemptiveAnswer = null; } else { text = this._entry.get_text(); } - + return text; }, - + _fadeOutMessage: function() { if (this._message.opacity == 0) return; @@ -16950,7 +16950,7 @@ index 674dd3a..2121f2e 100644 transition: 'easeOutQuad' }); }, - + - _initMessageStyleMap: function() { - if (_messageStyleMap) - return; @@ -16965,13 +16965,13 @@ index 674dd3a..2121f2e 100644 + this._message.add_style_class_name('login-dialog-message-warning'); + else + this._message.remove_style_class_name('login-dialog-message-warning'); - + - }, + if (type == GdmUtil.MessageType.HINT) + this._message.add_style_class_name('login-dialog-message-hint'); + else + this._message.remove_style_class_name('login-dialog-message-hint'); - + - setMessage: function(message, type) { - this._initMessageStyleMap(); if (message) { @@ -16984,41 +16984,41 @@ index 674dd3a..2121f2e 100644 this._message.opacity = 0; } }, - + _updateNextButtonSensitivity: function(sensitive) { this.nextButton.reactive = sensitive; this.nextButton.can_focus = sensitive; }, - + updateSensitivity: function(sensitive) { this._updateNextButtonSensitivity(sensitive); this._entry.reactive = sensitive; this._entry.clutter_text.editable = sensitive; }, - + hide: function() { this.setActorInDefaultButtonWell(null, true); this.actor.hide(); this._message.opacity = 0; - + this.setUser(null); - + this.updateSensitivity(true); this._entry.set_text(''); }, - + setUser: function(user) { if (user) { let userWidget = new UserWidget.UserWidget(user); this._userWell.set_child(userWidget.actor); --- +-- 1.8.3.1 -From 835b7a328ef9272c34a99a577f484224dc3e9f2d Mon Sep 17 00:00:00 2001 +From 6f8fdc032baf8641759d0b03e1873660dbe9c4a5 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 27 Aug 2013 10:28:26 -0400 -Subject: [PATCH 64/66] theme: add bottom badding for login dialog hint +Subject: [PATCH 64/69] theme: add bottom badding for login dialog hint Since we're getting rid of the top padding, we need to add what we take away to the bottom padding to keep the size the same. @@ -17029,43 +17029,43 @@ https://bugzilla.gnome.org/show_bug.cgi?id=706670 1 file changed, 1 insertion(+) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css -index 32b6eab..71d7ec2 100644 +index 40b4835..fe33fe5 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css -@@ -2384,60 +2384,61 @@ StScrollBar StButton#vhandle:active { +@@ -2389,60 +2389,61 @@ StScrollBar StButton#vhandle:active { .login-dialog .modal-dialog-button:default:hover { background-gradient-start: #74a0d0; background-gradient-end: #436d9f; } - + .login-dialog .modal-dialog-button:default:active, .login-dialog .modal-dialog-button:default:pressed { background-gradient-start: #436d9f; background-gradient-end: #74a0d0; } - + .login-dialog .modal-dialog-button:default:insensitive { border-color: #666666; color: #9f9f9f; background-gradient-direction: none; background-color: rgba(102, 102, 102, 0.15); } - + .login-dialog-message { padding-top: 4px; padding-bottom: 16px; min-height: 2em; } - + .login-dialog-message-warning { color: orange; } - + .login-dialog-message-hint { padding-top: 0px; + padding-bottom: 20px; } - + .user-widget-label { font-size: 16pt; font-weight: bold; @@ -17073,35 +17073,35 @@ index 32b6eab..71d7ec2 100644 padding-left: 15px; text-shadow: black 0px 4px 3px 0px; } - + /* Screen shield */ - + .screen-shield-background { background: black; } - + #lockDialogGroup { background: #2e3436 url(noise-texture.png); background-repeat: repeat; } - + .screen-shield-arrows { padding-bottom: 3em; } - + .screen-shield-arrows Gjs_Arrow { color: white; width: 80px; height: 48px; -arrow-thickness: 12px; --- +-- 1.8.3.1 -From 521b48fc4fd4d8adaa630dc22e9df4282629b942 Mon Sep 17 00:00:00 2001 +From 331987e35c3846939a232de758ef513f3e97174c Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 29 Aug 2013 11:46:56 -0400 -Subject: [PATCH 65/66] loginDialog: show session menu button when in auth +Subject: [PATCH 65/69] loginDialog: show session menu button when in auth failed Right now we only show the session menu button when verifying, @@ -17120,20 +17120,20 @@ index 1649e4e..9d5e243 100644 +++ b/js/gdm/loginDialog.js @@ -571,61 +571,62 @@ const LoginDialog = new Lang.Class({ }, - + _onPrompted: function() { this._sessionMenuButton.updateSensitivity(true); - + if (this._shouldShowSessionMenuButton()) this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor); this._showPrompt(); }, - + _onReset: function(authPrompt, beginRequest) { this._sessionMenuButton.updateSensitivity(true); - + this._user = null; - + if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) { if (!this._disableUserList) this._showUserList(); @@ -17143,23 +17143,23 @@ index 1649e4e..9d5e243 100644 this._hideUserListAndBeginVerification(); } }, - + _onDefaultSessionChanged: function(client, sessionId) { this._sessionMenuButton.setActiveSession(sessionId); }, - + _shouldShowSessionMenuButton: function() { - if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING) + if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING && + this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFICATION_FAILED) return false; - + if (this._user && this._user.is_loaded && this._user.is_logged_in()) return false; - + return true; }, - + _showPrompt: function() { if (this._authPrompt.actor.visible) return; @@ -17170,26 +17170,26 @@ index 1649e4e..9d5e243 100644 time: _FADE_ANIMATION_TIME, transition: 'easeOutQuad' }); }, - + _showRealmLoginHint: function(realmManager, hint) { if (!hint) return; - + hint = hint.replace(/%U/g, 'user'); hint = hint.replace(/%D/g, 'DOMAIN'); hint = hint.replace(/%[^UD]/g, ''); - + // Translators: this message is shown below the username entry field // to clue the user in on how to login to the local network realm this._authPrompt.setMessage(_("(e.g., user or %s)").format(hint), AuthPrompt.MessageType.HINT); --- +-- 1.8.3.1 -From d1baf411e7a2f45f6c588dabbdb7db8226b7f63d Mon Sep 17 00:00:00 2001 +From 253f51209898c1b9a96d12319e15c97261a621c0 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Thu, 7 Nov 2013 23:15:39 -0500 -Subject: [PATCH 66/66] loginDialog: display banner message when +Subject: [PATCH 66/69] loginDialog: display banner message when disable-user-list=true The login screen supports showing a banner message which admins @@ -17205,15 +17205,15 @@ the user instead of when showing the user list. It also moves the banner to a more aesthetically pleasing location on screen, and adds a scrollbar if the message is too long. --- - data/theme/gnome-shell.css | 10 ++++---- - js/gdm/loginDialog.js | 60 ++++++++++++++++++++++++++++++++++++++-------- - 2 files changed, 56 insertions(+), 14 deletions(-) + data/theme/gnome-shell.css | 10 ++++--- + js/gdm/loginDialog.js | 66 +++++++++++++++++++++++++++++++++++++++------- + 2 files changed, 62 insertions(+), 14 deletions(-) diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css -index 71d7ec2..3727197 100644 +index fe33fe5..4191817 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css -@@ -2180,67 +2180,69 @@ StScrollBar StButton#vhandle:active { +@@ -2185,67 +2185,69 @@ StScrollBar StButton#vhandle:active { .candidate-box:hover { border-radius: 4px; background-color: rgba(255,255,255,0.1); @@ -17655,3 +17655,527 @@ index 9d5e243..7b2b1d6 100644 -- 1.8.3.1 + +From e0f3dfb3a34b00898a436a2baffa65901ba6f6f1 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Thu, 9 Jan 2014 10:42:08 -0500 +Subject: [PATCH 67/69] loginDialog: defer loading user list until idle + +In some cases we load the user list after going back +to main loop and in other cases we load the user list +right away (depending on if accounts service is ready). + +In the case we load the user list right away we cause a +traceback because loading the user list forces a reset, +which then tries to reset actors which aren't instantiated +yet. + +This commit ensures the user list is loaded after the constructor +finishes and the event loop runs irregardless of the accountsservice +state. + +https://bugzilla.gnome.org/show_bug.cgi?id=721868 +--- + js/gdm/loginDialog.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js +index 7b2b1d6..c8d3231 100644 +--- a/js/gdm/loginDialog.js ++++ b/js/gdm/loginDialog.js +@@ -503,61 +503,61 @@ const LoginDialog = new Lang.Class({ + let innerBox = new St.BoxLayout({ vertical: true }); + + this._bannerView.add_actor(innerBox); + this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', + text: '' }); + this._bannerLabel.clutter_text.line_wrap = true; + this._bannerLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; + innerBox.add_child(this._bannerLabel); + this._updateBanner(); + + table.pack(this._logoBin, 0, 2); + table.set_span(this._logoBin, 1, 1); + this._updateLogo(); + + // We have overlapping widgets to obtain the kind of centering we want. + // We need to make sure the widgets that take input are on top of the + // stack. + this.actor.set_child_above_sibling(this._userSelectionBox, null); + this.actor.set_child_above_sibling(this._authPrompt.actor, null); + + if (!this._userManager.is_loaded) + this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', + Lang.bind(this, function() { + if (this._userManager.is_loaded) { + this._loadUserList(); + this._userManager.disconnect(this._userManagerLoadedId); + this._userManagerLoadedId = 0; + } + })); + else +- this._loadUserList(); ++ GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList)); + + this._userList.connect('activate', + Lang.bind(this, function(userList, item) { + this._onUserListActivated(item); + })); + + + this._sessionMenuButton = new SessionMenuButton(); + this._sessionMenuButton.connect('session-activated', + Lang.bind(this, function(list, sessionId) { + this._greeter.call_select_session_sync (sessionId, null); + })); + this._sessionMenuButton.actor.opacity = 0; + this._sessionMenuButton.actor.show(); + this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor); + + }, + + _updateDisableUserList: function() { + let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); + + if (disableUserList != this._disableUserList) { + this._disableUserList = disableUserList; + + if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING) + this._authPrompt.reset(); + } + }, + + _updateCancelButton: function() { +-- +1.8.3.1 + + +From 06245cfa219edeac9c9a4f879b3a4bc9b64c209f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 26 Nov 2013 20:52:24 +0100 +Subject: [PATCH 68/69] loginDialog: Implement cancel() + +The screen shield expects a cancel() method on the unlockDialog +implementation, but LoginDialog does not provide it currently. + +https://bugzilla.gnome.org/show_bug.cgi?id=719378 +--- + js/gdm/loginDialog.js | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js +index c8d3231..ca2b060 100644 +--- a/js/gdm/loginDialog.js ++++ b/js/gdm/loginDialog.js +@@ -936,39 +936,43 @@ const LoginDialog = new Lang.Class({ + this._userList.addUser(user); + })); + + this._userManager.connect('user-removed', + Lang.bind(this, function(userManager, user) { + this._userList.removeUser(user); + })); + }, + + open: function() { + Main.ctrlAltTabManager.addGroup(this.actor, + _("Login Window"), + 'dialog-password-symbolic', + { sortGroup: CtrlAltTab.SortGroup.MIDDLE }); + this._userList.actor.grab_key_focus(); + this.actor.show(); + this.actor.opacity = 0; + + Tweener.addTween(this.actor, + { opacity: 255, + time: 1, + transition: 'easeInQuad' }); + + return true; + }, + + close: function() { + Main.ctrlAltTabManager.removeGroup(this.dialogLayout); + }, + ++ cancel: function() { ++ this._authPrompt.cancel(); ++ }, ++ + addCharacter: function(unichar) { + this._authPrompt.addCharacter(unichar); + }, + + finish: function(onComplete) { + this._authPrompt.finish(onComplete); + }, + }); + Signals.addSignalMethods(LoginDialog.prototype); +-- +1.8.3.1 + + +From 7e0f3897195f5e64bca04dc5fab9e5d0553272d2 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Mon, 17 Feb 2014 14:20:31 -0500 +Subject: [PATCH 69/69] loginDialog: make banner message more prominent. + +This commit moves the login banner to the top of the screen, and +ensures it gets shown right away at the Username prompt. +--- + data/theme/gnome-shell.css | 13 +++++-------- + js/gdm/loginDialog.js | 44 ++++++++++++++++++++++---------------------- + 2 files changed, 27 insertions(+), 30 deletions(-) + +diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css +index 4191817..532c8a5 100644 +--- a/data/theme/gnome-shell.css ++++ b/data/theme/gnome-shell.css +@@ -2186,68 +2186,65 @@ StScrollBar StButton#vhandle:active { + border-radius: 4px; + background-color: rgba(255,255,255,0.1); + } + .candidate-page-button-box { + height: 2em; + width: 80px; + } + + .vertical .candidate-page-button-box { + padding-top: 0.5em; + } + + .horizontal .candidate-page-button-box { + padding-left: 0.5em; + } + + .candidate-page-button-previous { + border-radius: 4px 0px 0px 4px; + } + + .candidate-page-button-next { + border-radius: 0px 4px 4px 0px; + } + + .candidate-page-button-icon { + icon-size: 1em; + } + + /* Login Dialog */ + .login-dialog-banner-view { +- padding-top: 10em; +- height: 10em; +-} +- +-.login-dialog-banner { +- font-size: 9pt; +- color: #666666; +- width: 30em; ++ padding-top: 96px; ++ padding-left: 1em; ++ height: 14em; ++ max-width: 42em; ++ min-width: 25em; + } + + .login-dialog-title { + font-size: 14pt; + font-weight: bold; + color: #666666; + padding-bottom: 2em; + } + + .login-dialog { + /* Reset border and background */ + border: none; + background-color: transparent; + } + + .login-dialog-button-box { + spacing: 5px; + } + + .login-dialog-user-list-view { + -st-vfade-offset: 1em; + } + + .login-dialog-user-list { + spacing: 12px; + padding: .2em; + width: 23em; + } + + .login-dialog-user-list-item { +diff --git a/js/gdm/loginDialog.js b/js/gdm/loginDialog.js +index ca2b060..ee0199c 100644 +--- a/js/gdm/loginDialog.js ++++ b/js/gdm/loginDialog.js +@@ -407,136 +407,136 @@ const LoginDialog = new Lang.Class({ + this._userManager = AccountsService.UserManager.get_default() + let gdmClient = new Gdm.Client(); + + if (GLib.getenv('GDM_GREETER_TEST') != '1') { + this._greeter = gdmClient.get_greeter_sync(null); + + this._greeter.connect('default-session-name-changed', + Lang.bind(this, this._onDefaultSessionChanged)); + + this._greeter.connect('session-opened', + Lang.bind(this, this._onSessionOpened)); + this._greeter.connect('timed-login-requested', + Lang.bind(this, this._onTimedLoginRequested)); + } + + this._settings = new Gio.Settings({ schema: GdmUtil.LOGIN_SCREEN_SCHEMA }); + + this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY, + Lang.bind(this, this._updateBanner)); + this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY, + Lang.bind(this, this._updateBanner)); + this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY, + Lang.bind(this, this._updateDisableUserList)); + this._settings.connect('changed::' + GdmUtil.LOGO_KEY, + Lang.bind(this, this._updateLogo)); + + this._textureCache = St.TextureCache.get_default(); + this._textureCache.connect('texture-file-changed', + Lang.bind(this, this._updateLogoTexture)); + ++ let outerBox = new St.BoxLayout({ x_align: Clutter.ActorAlign.CENTER, ++ y_align: Clutter.ActorAlign.START, ++ y_expand: true, ++ vertical: true }); ++ table.pack(outerBox, 0, 0); ++ this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view', ++ opacity: 0, ++ vscrollbar_policy: Gtk.PolicyType.AUTOMATIC, ++ hscrollbar_policy: Gtk.PolicyType.NEVER }); ++ outerBox.add_actor(this._bannerView); ++ ++ let innerBox = new St.BoxLayout({ vertical: true }); ++ ++ this._bannerView.add_actor(innerBox); ++ this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', ++ text: '' }); ++ this._bannerLabel.clutter_text.line_wrap = true; ++ this._bannerLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; ++ innerBox.add_child(this._bannerLabel); ++ this._updateBanner(); ++ + this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box', + x_align: Clutter.ActorAlign.CENTER, + y_align: Clutter.ActorAlign.CENTER, + x_expand: true, + y_expand: true, + vertical: true, + visible: false }); + this._userList = new UserList(); + this._userSelectionBox.add(this._userList.actor, + { expand: true, + x_fill: true, + y_fill: true }); + + this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN); + this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted)); + this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); + this._authPrompt.hide(); + this._authPrompt.actor.x_align = Clutter.ActorAlign.CENTER; + this._authPrompt.actor.y_align = Clutter.ActorAlign.CENTER; + this._authPrompt.actor.x_expand = false; + this._authPrompt.actor.y_expand = false; + table.pack(this._authPrompt.actor, 0, 0); + table.set_span(this._authPrompt.actor, 1, 3); + + // translators: this message is shown below the user list on the + // login screen. It can be activated to reveal an entry for + // manually entering the username. + let notListedLabel = new St.Label({ text: _("Not listed?"), + style_class: 'login-dialog-not-listed-label' }); + this._notListedButton = new St.Button({ style_class: 'login-dialog-not-listed-button', + button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, + can_focus: true, + child: notListedLabel, + reactive: true, + x_align: St.Align.START, + x_fill: true }); + + this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAskForUsernameAndBeginVerification)); + + this._notListedButton.hide(); + + this._userSelectionBox.add(this._notListedButton, + { expand: false, + x_align: St.Align.START, + x_fill: true }); + + this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin', + x_align: Clutter.ActorAlign.CENTER, + y_align: Clutter.ActorAlign.END, + x_expand: true, + y_expand: true }); + + table.pack(this._userSelectionBox, 0, 0); + table.set_span(this._userSelectionBox, 1, 3); + +- let outerBox = new St.BoxLayout({ x_align: Clutter.ActorAlign.CENTER, +- y_align: Clutter.ActorAlign.CENTER, +- vertical: true }); +- table.pack(outerBox, 0, 2); +- table.set_span(outerBox, 1, 1); +- this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view', +- opacity: 0, +- vscrollbar_policy: Gtk.PolicyType.AUTOMATIC, +- hscrollbar_policy: Gtk.PolicyType.NEVER }); +- outerBox.add_actor(this._bannerView); +- +- let innerBox = new St.BoxLayout({ vertical: true }); +- +- this._bannerView.add_actor(innerBox); +- this._bannerLabel = new St.Label({ style_class: 'login-dialog-banner', +- text: '' }); +- this._bannerLabel.clutter_text.line_wrap = true; +- this._bannerLabel.clutter_text.ellipsize = Pango.EllipsizeMode.NONE; +- innerBox.add_child(this._bannerLabel); +- this._updateBanner(); +- + table.pack(this._logoBin, 0, 2); + table.set_span(this._logoBin, 1, 1); + this._updateLogo(); + + // We have overlapping widgets to obtain the kind of centering we want. + // We need to make sure the widgets that take input are on top of the + // stack. + this.actor.set_child_above_sibling(this._userSelectionBox, null); + this.actor.set_child_above_sibling(this._authPrompt.actor, null); + + if (!this._userManager.is_loaded) + this._userManagerLoadedId = this._userManager.connect('notify::is-loaded', + Lang.bind(this, function() { + if (this._userManager.is_loaded) { + this._loadUserList(); + this._userManager.disconnect(this._userManagerLoadedId); + this._userManagerLoadedId = 0; + } + })); + else + GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList)); + + this._userList.connect('activate', + Lang.bind(this, function(userList, item) { + this._onUserListActivated(item); + })); + + + this._sessionMenuButton = new SessionMenuButton(); + this._sessionMenuButton.connect('session-activated', +@@ -589,107 +589,107 @@ const LoginDialog = new Lang.Class({ + Tweener.addTween(this._bannerView, + { opacity: 255, + time: _FADE_ANIMATION_TIME, + transition: 'easeOutQuad' }); + }, + + _hideBannerView: function() { + Tweener.removeTweens(this._bannerView); + this._bannerView.opacity = 0; + }, + + _updateLogoTexture: function(cache, uri) { + if (this._logoFileUri != uri) + return; + + this._logoBin.destroy_all_children(); + if (this._logoFileUri) + this._logoBin.add_child(this._textureCache.load_uri_async(this._logoFileUri, + -1, _LOGO_ICON_HEIGHT)); + }, + + _updateLogo: function() { + let path = this._settings.get_string(GdmUtil.LOGO_KEY); + + this._logoFileUri = path ? Gio.file_new_for_path(path).get_uri() : null; + this._updateLogoTexture(this._textureCache, this._logoFileUri); + }, + + _onPrompted: function() { + this._sessionMenuButton.updateSensitivity(true); +- this._fadeInBannerView(); + + if (this._shouldShowSessionMenuButton()) + this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor); + this._showPrompt(); + }, + + _onReset: function(authPrompt, beginRequest) { + this._sessionMenuButton.updateSensitivity(true); + this._hideBannerView(); + + this._user = null; + + if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) { + if (!this._disableUserList) + this._showUserList(); + else + this._hideUserListAskForUsernameAndBeginVerification(); + } else { + this._hideUserListAndBeginVerification(); + } + }, + + _onDefaultSessionChanged: function(client, sessionId) { + this._sessionMenuButton.setActiveSession(sessionId); + }, + + _shouldShowSessionMenuButton: function() { + if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING && + this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFICATION_FAILED) + return false; + + if (this._user && this._user.is_loaded && this._user.is_logged_in()) + return false; + + return true; + }, + + _showPrompt: function() { + if (this._authPrompt.actor.visible) + return; + this._authPrompt.actor.opacity = 0; + this._authPrompt.actor.show(); + Tweener.addTween(this._authPrompt.actor, + { opacity: 255, + time: _FADE_ANIMATION_TIME, + transition: 'easeOutQuad' }); ++ this._fadeInBannerView(); + }, + + _showRealmLoginHint: function(realmManager, hint) { + if (!hint) + return; + + hint = hint.replace(/%U/g, 'user'); + hint = hint.replace(/%D/g, 'DOMAIN'); + hint = hint.replace(/%[^UD]/g, ''); + + // Translators: this message is shown below the username entry field + // to clue the user in on how to login to the local network realm + this._authPrompt.setMessage(_("(e.g., user or %s)").format(hint), AuthPrompt.MessageType.HINT); + }, + + _askForUsernameAndBeginVerification: function() { + this._authPrompt.setPasswordChar(''); + this._authPrompt.setQuestion(_("Username: ")); + + let realmManager = new Realmd.Manager(); + let realmSignalId = realmManager.connect('login-format-changed', + Lang.bind(this, this._showRealmLoginHint)); + this._showRealmLoginHint(realmManager.loginFormat); + + let nextSignalId = this._authPrompt.connect('next', + Lang.bind(this, function() { + this._authPrompt.disconnect(nextSignalId); + this._authPrompt.updateSensitivity(false); + let answer = this._authPrompt.getAnswer(); + this._user = this._userManager.get_user(answer); +-- +1.8.3.1 + diff --git a/SPECS/gnome-shell.spec b/SPECS/gnome-shell.spec index 1039583..ecddbcb 100644 --- a/SPECS/gnome-shell.spec +++ b/SPECS/gnome-shell.spec @@ -1,6 +1,6 @@ Name: gnome-shell Version: 3.8.4 -Release: 14%{?dist} +Release: 31%{?dist} Summary: Window management and application launching for GNOME Group: User Interface/Desktops @@ -14,14 +14,25 @@ Source1: org.gnome.shell.gschema.override # Replace Epiphany with Firefox in the default favourite apps list Patch1: gnome-shell-favourite-apps-firefox.patch Patch2: gnome-shell-favourite-apps-yelp.patch +Patch3: gnome-shell-favourite-apps-terminal.patch +Patch4: gnome-shell-favourite-apps-empathy.patch Patch10: 0001-popupMenu-Fix-removing-the-active-menu-from-PopupMen.patch Patch11: 0001-catch-more-errors-on-extensions-enable-and-disable.patch +Patch20: 0001-main-allow-session-mode-to-be-specified-in-the-envir.patch + Patch30: 0001-network-Do-not-use-timestamp-to-identify-connections.patch Patch31: 0001-network-Don-t-disable-switch-in-wifi-section-while-c.patch +Patch40: fix-remote-search-provider-loading.patch + +Patch50: fix-background-leaks.patch + Patch60: 0001-main-Actually-respect-hasWorkspaces.patch +Patch61: 0001-main-Close-runDialog-as-necessary-on-session-mode-ch.patch +Patch62: 0001-keyring-Don-t-unregister-the-prompt-when-disabled.patch +Patch63: 0002-keyring-Cancel-active-prompts-on-disable.patch Patch70: 0001-screenshot-Extend-ScreenshotArea-parameter-validatio.patch Patch71: 0002-screencast-Fix-disabling-screencasts-via-session-mod.patch @@ -30,8 +41,11 @@ Patch72: 0003-screencast-Validate-parameters-of-ScreencastArea.patch Patch80: 0001-shellDBus-Add-a-DBus-method-to-load-a-single-extensi.patch Patch81: 0002-extensions-Add-a-SESSION_MODE-extension-type.patch +Patch90: 0001-panel-add-an-icon-to-the-ActivitiesButton.patch + Patch99: login-screen-backport.patch Patch100: gdm-support-pre-authenticated-logins-from-oVirt.patch +Patch101: dont-load-user-list-when-disabled.patch %define clutter_version 1.13.4 %define gnome_bluetooth_version 3.5.5 @@ -143,14 +157,25 @@ be used only by extensions.gnome.org. %setup -q %patch1 -p1 -b .firefox %patch2 -p1 -b .yelp +%patch3 -p1 -b .terminal +%patch4 -p1 -b .empathy %patch10 -p1 -b .fix-popup-menu-manager-exception %patch11 -p1 -b .catch-extension-errors +%patch20 -p1 -b .main-allow-session-mode-to-be-specified-in-the-envir + %patch30 -p1 -b .fix-stuck-network-icon %patch31 -p1 -b .keep-wifi-switch +%patch40 -p1 -b .fix-remote-search-provider-loading + +%patch50 -p1 -b .fix-background-leaks + %patch60 -p1 -b .support-has-workspaces +%patch61 -p1 -b .close-run-dialog-on-lock +%patch62 -p1 -b .prevent-fallback-keyring-dialog +%patch63 -p1 -b .cancel-keyring-dialog-on-lock %patch70 -p1 -b .validate-screenshot-params %patch71 -p1 -b .fix-disable-screencasts @@ -159,8 +184,11 @@ be used only by extensions.gnome.org. %patch80 -p1 %patch81 -p1 +%patch90 -p1 -b .panel-add-an-icon-to-the-ActivitiesButton + %patch99 -p1 -b .login-screen-backport %patch100 -p1 -b .gdm-support-pre-authenticated-logins-from-oVirt +%patch101 -p1 -b .dont-load-user-list-when-disabled %build autoreconf -f @@ -232,6 +260,68 @@ glib-compile-schemas --allow-any-name %{_datadir}/glib-2.0/schemas &> /dev/null %{_libdir}/mozilla/plugins/*.so %changelog +* Wed Mar 19 2014 Florian Müllner - 3.8.4-31 +- Fix some more background memory leaks + Resolves: rhbz#1027192 + +* Wed Mar 12 2014 Ray Strode 3.8.4-30 +- Fix automatic shield lifting when smartcard is inserted + Resolves: #1063488 + +* Mon Mar 10 2014 Ray Strode 3.8.4-29 +- Don't show user list if require smartcard is true + Resolves: #1063390 + +* Mon Mar 10 2014 Ray Strode 3.8.4-28 +- Only react to login token (not any token) when performing unlock + Resolves: #1064972 + +* Sat Mar 08 2014 Florian Müllner - 3.8.4-27 +- Backport background memory leak fixes + Resolves: rhbz#1027192 + +* Sat Mar 08 2014 Florian Müllner - 3.8.4-26 +- Do not load user list in login screen when disabled + Resolves: rhbz#1053102 + +* Thu Mar 06 2014 Florian Müllner - 3.8.4-25 +- Fix loading of remote search providers + Resolves: #1030948 + +* Mon Feb 17 2014 Ray Strode 3.8.4-24 +- Make login banner more prominent + Resolves: #1061996 + +* Wed Jan 29 2014 Ray Strode 3.8.4-23 +- Fix traceback in log + Resolves: #1034966 + +* Fri Jan 24 2014 Daniel Mach - 3.8.4-22 +- Mass rebuild 2014-01-24 + +* Tue Jan 21 2014 Ray Strode 3.8.4-21 +- Add branding next to activities button + Resolves: #1052984 + +* Mon Jan 13 2014 Ray Strode 3.8.4-20 +- Fix undefined variable + Resolves: #1049897 + +* Wed Jan 08 2014 Ray Strode 3.8.4-19 +- Allow session mode to be specified by environment variable + +* Fri Dec 27 2013 Daniel Mach - 3.8.4-18 +- Mass rebuild 2013-12-27 + +* Wed Dec 4 2013 Matthias Clasen - 3.8.4-17 +- Add gnome-terminal to favorites, remove empathy +- Resolves: #1038168 + +* Fri Nov 15 2013 Florian Müllner - 3.8.4-15 +- Close run dialog on mode changes when the new session mode doesn't allow it + Resolves: rhbz#1031142 +- Prevent fallback keyring dialog to appear on lock screen + * Fri Nov 8 2013 Rui Matos - 3.8.4-14 - Add a DBus method to load a single extension Resolves: rhbz#1028466