[gnome-shell] polkit: don't show authentication dialog until needed
- From: David Zeuthen <davidz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] polkit: don't show authentication dialog until needed
- Date: Wed, 23 Feb 2011 19:49:15 +0000 (UTC)
commit adb04eb010d9a485a99ba8ad8a0b2e1ee801de6c
Author: David Zeuthen <davidz redhat com>
Date: Wed Feb 23 13:34:29 2011 -0500
polkit: don't show authentication dialog until needed
See https://bugs.freedesktop.org/show_bug.cgi?id=27788#c1 for details
about the problem this patch is solving
In particular, we should never bring up the dialog if there is no
password on the account. While this sounds like a weird corner case,
it's not.. the Live CD, for example, does not have a root password.
This also avoids the initial dialog resize.. before the patch the
authentication dialog appears and a split-second later an StEntry
widget is added.
Also print out more diagnostic information if showing the modal dialog
fails. Also add a comment about how to easily make this happen.
Signed-off-by: David Zeuthen <davidz redhat com>
js/ui/polkitAuthenticationAgent.js | 71 ++++++++++++++++++++++++++----------
1 files changed, 51 insertions(+), 20 deletions(-)
---
diff --git a/js/ui/polkitAuthenticationAgent.js b/js/ui/polkitAuthenticationAgent.js
index cc5e591..9002683 100644
--- a/js/ui/polkitAuthenticationAgent.js
+++ b/js/ui/polkitAuthenticationAgent.js
@@ -36,16 +36,17 @@ const PolkitAgent = imports.gi.PolkitAgent;
const ModalDialog = imports.ui.modalDialog;
-function AuthenticationDialog(message, cookie, userNames) {
- this._init(message, cookie, userNames);
+function AuthenticationDialog(actionId, message, cookie, userNames) {
+ this._init(actionId, message, cookie, userNames);
}
AuthenticationDialog.prototype = {
__proto__: ModalDialog.ModalDialog.prototype,
- _init: function(message, cookie, userNames) {
+ _init: function(actionId, message, cookie, userNames) {
ModalDialog.ModalDialog.prototype._init.call(this, { styleClass: 'polkit-dialog' });
+ this.actionId = actionId;
this.message = message;
this.userNames = userNames;
@@ -186,12 +187,41 @@ AuthenticationDialog.prototype = {
this._session.connect('request', Lang.bind(this, this._onSessionRequest));
this._session.connect('show-error', Lang.bind(this, this._onSessionShowError));
this._session.connect('show-info', Lang.bind(this, this._onSessionShowInfo));
+
+ // Delay focus grab to avoid ModalDialog stealing focus with
+ // its buttons
this.connect('opened',
Lang.bind(this, function() {
- this._session.initiate();
+ this._passwordEntry.grab_key_focus();
}));
},
+ startAuthentication: function() {
+ this._session.initiate();
+ },
+
+ _ensureOpen: function() {
+ // NOTE: ModalDialog.open() is safe to call if the dialog is
+ // already open - it just returns true without side-effects
+ if (!this.open(global.get_current_time())) {
+ // This can fail if e.g. unable to get input grab
+ //
+ // In an ideal world this wouldn't happen (because the
+ // Shell is in complete control of the session) but that's
+ // just not how things work right now.
+ //
+ // One way to make this happen is by running 'sleep 3;
+ // pkexec bash' and then opening a popup menu.
+ //
+ // We could add retrying if this turns out to be a problem
+
+ log('polkitAuthenticationAgent: Failed to show modal dialog.' +
+ ' Dismissing authentication request for action-id ' + this.actionId +
+ ' cookie ' + this._cookie);
+ this._emitDone(false, true);
+ }
+ },
+
_emitDone: function(keepVisible, dismissed) {
if (!this._doneEmitted) {
this._doneEmitted = true;
@@ -232,18 +262,21 @@ AuthenticationDialog.prototype = {
this._passwordBox.show();
this._passwordEntry.set_text('');
this._passwordEntry.grab_key_focus();
+ this._ensureOpen();
},
_onSessionShowError: function(session, text) {
this._passwordEntry.set_text('');
this._errorMessage.set_text(text);
this._errorBox.show();
+ this._ensureOpen();
},
_onSessionShowInfo: function(session, text) {
this._passwordEntry.set_text('');
this._infoMessage.set_text(text);
this._infoBox.show();
+ this._ensureOpen();
},
destroySession: function() {
@@ -290,22 +323,20 @@ AuthenticationAgent.prototype = {
},
_onInitiate: function(nativeAgent, actionId, message, iconName, cookie, userNames) {
- this._currentDialog = new AuthenticationDialog(message, cookie, userNames);
- if (!this._currentDialog.open(global.get_current_time())) {
- // This can fail if e.g. unable to get input grab
- //
- // In an ideal world this wouldn't happen (because the
- // Shell is in complete control of the session) but that's
- // just not how things work right now.
- //
- // We could add retrying if this turns out to be a problem
- log('polkitAuthenticationAgent: Failed to show modal dialog');
- this._currentDialog.destroySession();
- this._currentDialog = null;
- this._native.complete(false)
- } else {
- this._currentDialog.connect('done', Lang.bind(this, this._onDialogDone));
- }
+ this._currentDialog = new AuthenticationDialog(actionId, message, cookie, userNames);
+
+ // We actually don't want to open the dialog until we know for
+ // sure that we're going to interact with the user. For
+ // example, if the password for the identity to auth is blank
+ // (which it will be on a live CD) then there will be no
+ // conversation at all... of course, we don't *know* that
+ // until we actually try it.
+ //
+ // See https://bugzilla.gnome.org/show_bug.cgi?id=643062 for more
+ // discussion.
+
+ this._currentDialog.connect('done', Lang.bind(this, this._onDialogDone));
+ this._currentDialog.startAuthentication();
},
_onCancel: function(nativeAgent) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]