Compare commits
4 Commits
3.33.2
...
wip/login-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b19cef9dd5 | ||
|
|
2d4473c35a | ||
|
|
6d9fb50207 | ||
|
|
86b8885d96 |
@@ -2320,6 +2320,9 @@ StScrollBar StButton#vhandle:active {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #666666;
|
color: #666666;
|
||||||
padding-top: 1em;
|
padding-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-dialog-user-selection-box .login-dialog-not-listed-label {
|
||||||
padding-left: 2px;
|
padding-left: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ const Shell = imports.gi.Shell;
|
|||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
const Animation = imports.ui.animation;
|
|
||||||
const Batch = imports.gdm.batch;
|
const Batch = imports.gdm.batch;
|
||||||
const BoxPointer = imports.ui.boxpointer;
|
const BoxPointer = imports.ui.boxpointer;
|
||||||
const CtrlAltTab = imports.ui.ctrlAltTab;
|
const CtrlAltTab = imports.ui.ctrlAltTab;
|
||||||
@@ -46,20 +45,11 @@ const UserWidget = imports.ui.userWidget;
|
|||||||
|
|
||||||
const _FADE_ANIMATION_TIME = 0.25;
|
const _FADE_ANIMATION_TIME = 0.25;
|
||||||
const _SCROLL_ANIMATION_TIME = 0.5;
|
const _SCROLL_ANIMATION_TIME = 0.5;
|
||||||
const _DEFAULT_BUTTON_WELL_ICON_SIZE = 24;
|
|
||||||
const _DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1.0;
|
|
||||||
const _DEFAULT_BUTTON_WELL_ANIMATION_TIME = 0.3;
|
|
||||||
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
||||||
const _LOGO_ICON_HEIGHT = 48;
|
const _LOGO_ICON_HEIGHT = 48;
|
||||||
|
|
||||||
let _loginDialog = null;
|
let _loginDialog = null;
|
||||||
|
|
||||||
const DefaultButtonWellMode = {
|
|
||||||
NONE: 0,
|
|
||||||
SESSION_MENU_BUTTON: 1,
|
|
||||||
SPINNER: 2
|
|
||||||
};
|
|
||||||
|
|
||||||
const UserListItem = new Lang.Class({
|
const UserListItem = new Lang.Class({
|
||||||
Name: 'UserListItem',
|
Name: 'UserListItem',
|
||||||
|
|
||||||
@@ -466,67 +456,20 @@ const LoginDialog = new Lang.Class({
|
|||||||
x_fill: true,
|
x_fill: true,
|
||||||
y_fill: true });
|
y_fill: true });
|
||||||
|
|
||||||
this._promptBox = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
|
this._authPrompt = new GdmUtil.AuthPrompt({ visible: false });
|
||||||
vertical: true });
|
this._authPrompt.connect('cancel',
|
||||||
|
Lang.bind(this, function() {
|
||||||
this._promptBox.connect('button-press-event',
|
|
||||||
Lang.bind(this, function(actor, event) {
|
|
||||||
if (event.get_key_symbol() == Clutter.KEY_Escape) {
|
|
||||||
this.cancel();
|
this.cancel();
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._promptBox.add_constraint(new Clutter.AlignConstraint({ source: this.actor,
|
this._authPrompt.actor.add_constraint(new Clutter.AlignConstraint({ source: this.actor,
|
||||||
align_axis: Clutter.AlignAxis.BOTH,
|
align_axis: Clutter.AlignAxis.BOTH,
|
||||||
factor: 0.5 }));
|
factor: 0.5 }));
|
||||||
|
|
||||||
this.actor.add_child(this._promptBox);
|
this.actor.add_child(this._authPrompt.actor);
|
||||||
this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._promptBox,
|
this._userList.actor.add_constraint(new Clutter.BindConstraint({ source: this._authPrompt.actor,
|
||||||
coordinate: Clutter.BindCoordinate.WIDTH }));
|
coordinate: Clutter.BindCoordinate.WIDTH }));
|
||||||
|
|
||||||
this._promptUser = new St.Bin({ x_fill: true,
|
|
||||||
x_align: St.Align.START });
|
|
||||||
this._promptBox.add(this._promptUser,
|
|
||||||
{ x_align: St.Align.START,
|
|
||||||
x_fill: true,
|
|
||||||
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,
|
|
||||||
y_fill: true,
|
|
||||||
x_align: St.Align.START });
|
|
||||||
this._promptEntry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
|
|
||||||
can_focus: true });
|
|
||||||
this._promptEntryTextChangedId = 0;
|
|
||||||
this._promptEntryActivateId = 0;
|
|
||||||
this._promptBox.add(this._promptEntry,
|
|
||||||
{ expand: true,
|
|
||||||
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: 'login-dialog-button-box',
|
|
||||||
vertical: false });
|
|
||||||
this._promptBox.add(this._buttonBox,
|
|
||||||
{ expand: true,
|
|
||||||
x_align: St.Align.MIDDLE,
|
|
||||||
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
|
// translators: this message is shown below the user list on the
|
||||||
// login screen. It can be activated to reveal an entry for
|
// login screen. It can be activated to reveal an entry for
|
||||||
// manually entering the username.
|
// manually entering the username.
|
||||||
@@ -576,8 +519,6 @@ const LoginDialog = new Lang.Class({
|
|||||||
this._onUserListActivated(item);
|
this._onUserListActivated(item);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this._defaultButtonWell = new St.Widget();
|
|
||||||
this._defaultButtonWellMode = DefaultButtonWellMode.NONE;
|
|
||||||
|
|
||||||
this._sessionMenuButton = new SessionMenuButton();
|
this._sessionMenuButton = new SessionMenuButton();
|
||||||
this._sessionMenuButton.connect('session-activated',
|
this._sessionMenuButton.connect('session-activated',
|
||||||
@@ -586,17 +527,8 @@ const LoginDialog = new Lang.Class({
|
|||||||
}));
|
}));
|
||||||
this._sessionMenuButton.actor.opacity = 0;
|
this._sessionMenuButton.actor.opacity = 0;
|
||||||
this._sessionMenuButton.actor.show();
|
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 Animation.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() {
|
_updateDisableUserList: function() {
|
||||||
@@ -644,7 +576,8 @@ const LoginDialog = new Lang.Class({
|
|||||||
this._userVerifier.clear();
|
this._userVerifier.clear();
|
||||||
|
|
||||||
this._updateSensitivity(true);
|
this._updateSensitivity(true);
|
||||||
this._promptMessage.opacity = 0;
|
this._authPrompt.reset();
|
||||||
|
|
||||||
this._user = null;
|
this._user = null;
|
||||||
this._verifyingUser = false;
|
this._verifyingUser = false;
|
||||||
|
|
||||||
@@ -654,73 +587,11 @@ const LoginDialog = new Lang.Class({
|
|||||||
this._showUserList();
|
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)
|
|
||||||
Tweener.removeTweens(oldActor);
|
|
||||||
|
|
||||||
let actor = this._getActorForDefaultButtonWellMode(mode);
|
|
||||||
|
|
||||||
if (this._defaultButtonWellMode != mode && oldActor) {
|
|
||||||
if (immediately)
|
|
||||||
oldActor.opacity = 0;
|
|
||||||
else
|
|
||||||
Tweener.addTween(oldActor,
|
|
||||||
{ opacity: 0,
|
|
||||||
time: _DEFAULT_BUTTON_WELL_ANIMATION_TIME,
|
|
||||||
delay: _DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
|
|
||||||
transition: 'linear',
|
|
||||||
onCompleteScope: this,
|
|
||||||
onComplete: function() {
|
|
||||||
if (mode == DefaultButtonWellMode.SPINNER) {
|
|
||||||
if (this._workSpinner)
|
|
||||||
this._workSpinner.stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (actor) {
|
|
||||||
if (mode == DefaultButtonWellMode.SPINNER)
|
|
||||||
this._workSpinner.play();
|
|
||||||
|
|
||||||
if (immediately)
|
|
||||||
actor.opacity = 255;
|
|
||||||
else
|
|
||||||
Tweener.addTween(actor,
|
|
||||||
{ opacity: 255,
|
|
||||||
time: _DEFAULT_BUTTON_WELL_ANIMATION_TIME,
|
|
||||||
delay: _DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
|
|
||||||
transition: 'linear' });
|
|
||||||
}
|
|
||||||
|
|
||||||
this._defaultButtonWellMode = mode;
|
|
||||||
},
|
|
||||||
|
|
||||||
_verificationFailed: function() {
|
_verificationFailed: function() {
|
||||||
this._promptEntry.text = '';
|
this._authPrompt.clear();
|
||||||
|
|
||||||
this._updateSensitivity(true);
|
this._updateSensitivity(true);
|
||||||
this._setDefaultButtonWellMode(DefaultButtonWellMode.NONE, true);
|
this._authPrompt.setActorInDefaultButtonWell(null, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
_onDefaultSessionChanged: function(client, sessionId) {
|
_onDefaultSessionChanged: function(client, sessionId) {
|
||||||
@@ -728,23 +599,15 @@ const LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_showMessage: function(userVerifier, message, styleClass) {
|
_showMessage: function(userVerifier, message, styleClass) {
|
||||||
if (message) {
|
this._authPrompt.setMessage(message, styleClass);
|
||||||
this._promptMessage.text = message;
|
|
||||||
this._promptMessage.styleClass = styleClass;
|
|
||||||
this._promptMessage.opacity = 255;
|
|
||||||
} else {
|
|
||||||
this._promptMessage.opacity = 0;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_showLoginHint: function(verifier, message) {
|
_showLoginHint: function(verifier, message) {
|
||||||
this._promptLoginHint.set_text(message)
|
this._authPrompt.setHint(message);
|
||||||
this._promptLoginHint.opacity = 255;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_hideLoginHint: function() {
|
_hideLoginHint: function() {
|
||||||
this._promptLoginHint.opacity = 0;
|
this._authPrompt.setHint(null);
|
||||||
this._promptLoginHint.set_text('');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
cancel: function() {
|
cancel: function() {
|
||||||
@@ -768,27 +631,16 @@ const LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_showPrompt: function(forSecret) {
|
_showPrompt: function(forSecret) {
|
||||||
this._promptLabel.show();
|
this._authPrompt.actor.opacity = 0;
|
||||||
this._promptEntry.show();
|
this._authPrompt.actor.show();
|
||||||
this._promptLoginHint.opacity = 0;
|
Tweener.addTween(this._authPrompt.actor,
|
||||||
this._promptLoginHint.show();
|
|
||||||
this._promptBox.opacity = 0;
|
|
||||||
this._promptBox.show();
|
|
||||||
Tweener.addTween(this._promptBox,
|
|
||||||
{ opacity: 255,
|
{ opacity: 255,
|
||||||
time: _FADE_ANIMATION_TIME,
|
time: _FADE_ANIMATION_TIME,
|
||||||
transition: 'easeOutQuad' });
|
transition: 'easeOutQuad' });
|
||||||
|
|
||||||
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 hold = new Batch.Hold();
|
||||||
let tasks = [function() {
|
let tasks = [function() {
|
||||||
this._prepareDialog(forSecret, hold);
|
this._preparePrompt(forSecret, hold);
|
||||||
},
|
},
|
||||||
|
|
||||||
hold];
|
hold];
|
||||||
@@ -798,122 +650,54 @@ const LoginDialog = new Lang.Class({
|
|||||||
return batch.run();
|
return batch.run();
|
||||||
},
|
},
|
||||||
|
|
||||||
_prepareDialog: function(forSecret, hold) {
|
_preparePrompt: function(forSecret, hold) {
|
||||||
this._buttonBox.visible = true;
|
let cancelLabel;
|
||||||
this._buttonBox.remove_all_children();
|
|
||||||
|
|
||||||
if (!this._disableUserList || this._verifyingUser) {
|
if (!this._disableUserList || this._verifyingUser) {
|
||||||
this._cancelButton = new St.Button({ style_class: 'modal-dialog-button',
|
cancelLabel = _("Cancel");
|
||||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
} else {
|
||||||
reactive: true,
|
cancelLabel = null;
|
||||||
can_focus: true,
|
|
||||||
label: _("Cancel") });
|
|
||||||
this._cancelButton.connect('clicked',
|
|
||||||
Lang.bind(this, function() {
|
|
||||||
this.cancel();
|
|
||||||
}));
|
|
||||||
this._buttonBox.add(this._cancelButton,
|
|
||||||
{ expand: false,
|
|
||||||
x_fill: false,
|
|
||||||
y_fill: false,
|
|
||||||
x_align: St.Align.START,
|
|
||||||
y_align: St.Align.END });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this._buttonBox.add(this._defaultButtonWell,
|
let nextLabel;
|
||||||
{ expand: true,
|
if (forSecret) {
|
||||||
x_fill: false,
|
nextLabel = C_("button", "Sign In");
|
||||||
y_fill: false,
|
} else {
|
||||||
x_align: St.Align.END,
|
nextLabel = _("Next");
|
||||||
y_align: St.Align.MIDDLE });
|
}
|
||||||
this._signInButton = new St.Button({ style_class: 'modal-dialog-button',
|
|
||||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
|
||||||
reactive: true,
|
|
||||||
can_focus: true,
|
|
||||||
label: forSecret ? C_("button", "Sign In") : _("Next") });
|
|
||||||
this._signInButton.connect('clicked',
|
|
||||||
Lang.bind(this, function() {
|
|
||||||
hold.release();
|
|
||||||
}));
|
|
||||||
this._signInButton.add_style_pseudo_class('default');
|
|
||||||
this._buttonBox.add(this._signInButton,
|
|
||||||
{ expand: false,
|
|
||||||
x_fill: false,
|
|
||||||
y_fill: false,
|
|
||||||
x_align: St.Align.END,
|
|
||||||
y_align: St.Align.END });
|
|
||||||
|
|
||||||
this._updateSignInButtonSensitivity(this._promptEntry.text.length > 0);
|
let signalId = this._authPrompt.connect('next', Lang.bind(this, function() {
|
||||||
|
this._authPrompt.disconnect(signalId);
|
||||||
|
hold.release();
|
||||||
|
}));
|
||||||
|
|
||||||
this._promptEntryTextChangedId =
|
this._authPrompt.resetButtons(cancelLabel, nextLabel);
|
||||||
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) {
|
_updateSensitivity: function(sensitive) {
|
||||||
this._promptEntry.reactive = sensitive;
|
|
||||||
this._promptEntry.clutter_text.editable = sensitive;
|
|
||||||
this._sessionMenuButton.updateSensitivity(sensitive);
|
this._sessionMenuButton.updateSensitivity(sensitive);
|
||||||
this._updateSignInButtonSensitivity(sensitive);
|
this._authPrompt.updateSensitivity(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.opacity = 0;
|
|
||||||
|
|
||||||
this._promptUser.set_child(null);
|
|
||||||
|
|
||||||
this._updateSensitivity(true);
|
|
||||||
this._promptEntry.set_text('');
|
|
||||||
|
|
||||||
this._sessionMenuButton.close();
|
|
||||||
this._promptLoginHint.opacity = 0;
|
|
||||||
|
|
||||||
this._buttonBox.remove_all_children();
|
|
||||||
this._signInButton = null;
|
|
||||||
this._cancelButton = null;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_askQuestion: function(verifier, serviceName, question, passwordChar) {
|
_askQuestion: function(verifier, serviceName, question, passwordChar) {
|
||||||
this._promptLabel.set_text(question);
|
this._authPrompt.setPasswordChar(passwordChar);
|
||||||
|
this._authPrompt.setQuestion(question);
|
||||||
|
|
||||||
this._updateSensitivity(true);
|
this._updateSensitivity(true);
|
||||||
this._promptEntry.set_text('');
|
|
||||||
this._promptEntry.clutter_text.set_password_char(passwordChar);
|
if (this._shouldShowSessionMenuButton())
|
||||||
|
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor, true);
|
||||||
|
else
|
||||||
|
this._authPrompt.setActorInDefaultButtonWell(null, true);
|
||||||
|
|
||||||
let tasks = [function() {
|
let tasks = [function() {
|
||||||
return this._showPrompt(!!passwordChar);
|
return this._showPrompt(!!passwordChar);
|
||||||
},
|
},
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
let text = this._promptEntry.get_text();
|
let text = this._authPrompt.getAnswer();
|
||||||
|
|
||||||
this._updateSensitivity(false);
|
this._updateSensitivity(false);
|
||||||
this._setDefaultButtonWellMode(DefaultButtonWellMode.SPINNER, false);
|
this._authPrompt.startSpinning();
|
||||||
this._userVerifier.answerQuery(serviceName, text);
|
this._userVerifier.answerQuery(serviceName, text);
|
||||||
}];
|
}];
|
||||||
|
|
||||||
@@ -935,9 +719,8 @@ const LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_askForUsernameAndLogIn: function() {
|
_askForUsernameAndLogIn: function() {
|
||||||
this._promptLabel.set_text(_("Username: "));
|
this._authPrompt.setPasswordChar('');
|
||||||
this._promptEntry.set_text('');
|
this._authPrompt.setQuestion(_("Username: "));
|
||||||
this._promptEntry.clutter_text.set_password_char('');
|
|
||||||
|
|
||||||
let realmManager = new Realmd.Manager();
|
let realmManager = new Realmd.Manager();
|
||||||
let signalId = realmManager.connect('login-format-changed',
|
let signalId = realmManager.connect('login-format-changed',
|
||||||
@@ -947,8 +730,8 @@ const LoginDialog = new Lang.Class({
|
|||||||
let tasks = [this._showPrompt,
|
let tasks = [this._showPrompt,
|
||||||
|
|
||||||
function() {
|
function() {
|
||||||
let userName = this._promptEntry.get_text();
|
let userName = this._authPrompt.getAnswer();
|
||||||
this._promptEntry.reactive = false;
|
this._authPrompt._entry.reactive = false;
|
||||||
return this._beginVerificationForUser(userName);
|
return this._beginVerificationForUser(userName);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1132,7 +915,8 @@ const LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_showUserList: function() {
|
_showUserList: function() {
|
||||||
this._hidePrompt();
|
this._authPrompt.hide();
|
||||||
|
this._sessionMenuButton.close();
|
||||||
this._setUserListExpanded(true);
|
this._setUserListExpanded(true);
|
||||||
this._notListedButton.show();
|
this._notListedButton.show();
|
||||||
this._userList.actor.grab_key_focus();
|
this._userList.actor.grab_key_focus();
|
||||||
@@ -1147,8 +931,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
_beginVerificationForItem: function(item) {
|
_beginVerificationForItem: function(item) {
|
||||||
let userWidget = new UserWidget.UserWidget(item.user);
|
this._authPrompt.setUser(item.user);
|
||||||
this._promptUser.set_child(userWidget.actor);
|
|
||||||
|
|
||||||
let tasks = [function() {
|
let tasks = [function() {
|
||||||
let userName = item.user.get_user_name();
|
let userName = item.user.get_user_name();
|
||||||
@@ -1216,7 +999,7 @@ const LoginDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
addCharacter: function(unichar) {
|
addCharacter: function(unichar) {
|
||||||
this._promptEntry.clutter_text.insert_unichar(unichar);
|
this._authPrompt.addCharacter(unichar);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(LoginDialog.prototype);
|
Signals.addSignalMethods(LoginDialog.prototype);
|
||||||
|
|||||||
342
js/gdm/util.js
342
js/gdm/util.js
@@ -6,12 +6,16 @@ const GLib = imports.gi.GLib;
|
|||||||
const Lang = imports.lang;
|
const Lang = imports.lang;
|
||||||
const Mainloop = imports.mainloop;
|
const Mainloop = imports.mainloop;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Animation = imports.ui.animation;
|
||||||
const Batch = imports.gdm.batch;
|
const Batch = imports.gdm.batch;
|
||||||
const Fprint = imports.gdm.fingerprint;
|
const Fprint = imports.gdm.fingerprint;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const Params = imports.misc.params;
|
const Params = imports.misc.params;
|
||||||
|
const ShellEntry = imports.ui.shellEntry;
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
|
const UserWidget = imports.ui.userWidget;
|
||||||
|
|
||||||
const PASSWORD_SERVICE_NAME = 'gdm-password';
|
const PASSWORD_SERVICE_NAME = 'gdm-password';
|
||||||
const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
|
const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
|
||||||
@@ -30,6 +34,10 @@ const DISABLE_USER_LIST_KEY = 'disable-user-list';
|
|||||||
// Give user 16ms to read each character of a PAM message
|
// Give user 16ms to read each character of a PAM message
|
||||||
const USER_READ_TIME = 16
|
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) {
|
function fadeInActor(actor) {
|
||||||
if (actor.opacity == 255 && actor.visible)
|
if (actor.opacity == 255 && actor.visible)
|
||||||
return null;
|
return null;
|
||||||
@@ -459,3 +467,337 @@ const ShellUserVerifier = new Lang.Class({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
Signals.addSignalMethods(ShellUserVerifier.prototype);
|
Signals.addSignalMethods(ShellUserVerifier.prototype);
|
||||||
|
|
||||||
|
const AuthPrompt = new Lang.Class({
|
||||||
|
Name: 'AuthPrompt',
|
||||||
|
|
||||||
|
_init: function(params) {
|
||||||
|
params = Params.parse(params,
|
||||||
|
{ style_class: 'login-dialog-prompt-layout',
|
||||||
|
vertical: true }, true);
|
||||||
|
this.actor = new St.BoxLayout(params);
|
||||||
|
this.actor.connect('button-press-event',
|
||||||
|
Lang.bind(this, function(actor, event) {
|
||||||
|
if (event.get_key_symbol() == Clutter.KEY_Escape) {
|
||||||
|
this.emit('cancel');
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._userWell = new St.Bin({ x_fill: true,
|
||||||
|
x_align: St.Align.START });
|
||||||
|
this.actor.add(this._userWell,
|
||||||
|
{ x_align: St.Align.START,
|
||||||
|
x_fill: true,
|
||||||
|
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,
|
||||||
|
y_fill: true,
|
||||||
|
x_align: St.Align.START });
|
||||||
|
this._entry = new St.Entry({ style_class: 'login-dialog-prompt-entry',
|
||||||
|
can_focus: true });
|
||||||
|
ShellEntry.addContextMenu(this._entry, { isPassword: true });
|
||||||
|
this._entryTextChangedId = 0;
|
||||||
|
this._entryActivateId = 0;
|
||||||
|
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._cancelButton = null;
|
||||||
|
this._nextButton = null;
|
||||||
|
|
||||||
|
this._defaultButtonWell = new St.Widget();
|
||||||
|
this._defaultButtonWellActor = null;
|
||||||
|
|
||||||
|
let spinnerIcon = global.datadir + '/theme/process-working.svg';
|
||||||
|
this._spinner = new Animation.AnimatedIcon(spinnerIcon, DEFAULT_BUTTON_WELL_ICON_SIZE);
|
||||||
|
this._spinner.actor.opacity = 0;
|
||||||
|
this._spinner.actor.show();
|
||||||
|
this._defaultButtonWell.add_child(this._spinner.actor);
|
||||||
|
},
|
||||||
|
|
||||||
|
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, immediately) {
|
||||||
|
if (!this._defaultButtonWellActor &&
|
||||||
|
!actor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let oldActor = this._defaultButtonWellActor;
|
||||||
|
|
||||||
|
if (oldActor)
|
||||||
|
Tweener.removeTweens(oldActor);
|
||||||
|
|
||||||
|
let isWorkSpinner;
|
||||||
|
if (actor == this._spinner.actor)
|
||||||
|
isWorkSpinner = true;
|
||||||
|
else
|
||||||
|
isWorkSpinner = false;
|
||||||
|
|
||||||
|
if (this._defaultButtonWellActor != actor && oldActor) {
|
||||||
|
if (immediately)
|
||||||
|
oldActor.opacity = 0;
|
||||||
|
else
|
||||||
|
Tweener.addTween(oldActor,
|
||||||
|
{ opacity: 0,
|
||||||
|
time: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
|
||||||
|
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
|
||||||
|
transition: 'linear',
|
||||||
|
onCompleteScope: this,
|
||||||
|
onComplete: function() {
|
||||||
|
if (isWorkSpinner) {
|
||||||
|
if (this._spinner)
|
||||||
|
this._spinner.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actor) {
|
||||||
|
if (isWorkSpinner)
|
||||||
|
this._spinner.play();
|
||||||
|
|
||||||
|
if (immediately)
|
||||||
|
actor.opacity = 255;
|
||||||
|
else
|
||||||
|
Tweener.addTween(actor,
|
||||||
|
{ opacity: 255,
|
||||||
|
time: DEFAULT_BUTTON_WELL_ANIMATION_TIME,
|
||||||
|
delay: DEFAULT_BUTTON_WELL_ANIMATION_DELAY,
|
||||||
|
transition: 'linear' });
|
||||||
|
}
|
||||||
|
|
||||||
|
this._defaultButtonWellActor = actor;
|
||||||
|
},
|
||||||
|
|
||||||
|
startSpinning: function() {
|
||||||
|
this.setActorInDefaultButtonWell(this._spinner.actor, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
stopSpinning: function() {
|
||||||
|
this.setActorInDefaultButtonWell(null, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
clear: function() {
|
||||||
|
this._entry.text = '';
|
||||||
|
},
|
||||||
|
|
||||||
|
setPasswordChar: function(passwordChar) {
|
||||||
|
this._entry.clutter_text.set_password_char(passwordChar);
|
||||||
|
this._entry.menu.isPassword = passwordChar != '';
|
||||||
|
},
|
||||||
|
|
||||||
|
setQuestion: function(question) {
|
||||||
|
if (!this._initialAnswer) {
|
||||||
|
this.clear();
|
||||||
|
} else if (this._initialAnswer['activate-id']) {
|
||||||
|
this._entry.clutter_text.disconnect(this._initialAnswer['activate-id']);
|
||||||
|
delete this._initialAnswer['activate-id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
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._initialAnswer && this._initialAnswer['text']) {
|
||||||
|
text = this._initialAnswer['text'];
|
||||||
|
this._initialAnswer = null;
|
||||||
|
} else {
|
||||||
|
text = this._entry.get_text();
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
},
|
||||||
|
|
||||||
|
setMessage: function(message, styleClass) {
|
||||||
|
if (message) {
|
||||||
|
this._message.text = message;
|
||||||
|
this._message.styleClass = styleClass;
|
||||||
|
this._message.opacity = 255;
|
||||||
|
} else {
|
||||||
|
this._message.opacity = 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
resetButtons: function(cancelLabel, nextLabel) {
|
||||||
|
if (this._initialAnswer && this._initialAnswer['text']) {
|
||||||
|
this.emit('next');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._buttonBox.visible = true;
|
||||||
|
this._buttonBox.remove_all_children();
|
||||||
|
|
||||||
|
if (cancelLabel) {
|
||||||
|
this._cancelButton = new St.Button({ style_class: 'modal-dialog-button',
|
||||||
|
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
||||||
|
reactive: true,
|
||||||
|
can_focus: true,
|
||||||
|
label: cancelLabel });
|
||||||
|
this._cancelButton.connect('clicked',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this.emit('cancel');
|
||||||
|
}));
|
||||||
|
this._buttonBox.add(this._cancelButton,
|
||||||
|
{ expand: false,
|
||||||
|
x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.START,
|
||||||
|
y_align: St.Align.END });
|
||||||
|
}
|
||||||
|
|
||||||
|
this._buttonBox.add(this._defaultButtonWell,
|
||||||
|
{ expand: true,
|
||||||
|
x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.END,
|
||||||
|
y_align: St.Align.MIDDLE });
|
||||||
|
this._nextButton = new St.Button({ style_class: 'modal-dialog-button',
|
||||||
|
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
||||||
|
reactive: true,
|
||||||
|
can_focus: true,
|
||||||
|
label: nextLabel });
|
||||||
|
this._nextButton.connect('clicked',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this.emit('next');
|
||||||
|
}));
|
||||||
|
this._nextButton.add_style_pseudo_class('default');
|
||||||
|
this._buttonBox.add(this._nextButton,
|
||||||
|
{ expand: false,
|
||||||
|
x_fill: false,
|
||||||
|
y_fill: false,
|
||||||
|
x_align: St.Align.END,
|
||||||
|
y_align: St.Align.END });
|
||||||
|
|
||||||
|
this._updateNextButtonSensitivity(this._entry.text.length > 0);
|
||||||
|
|
||||||
|
this._entryTextChangedId =
|
||||||
|
this._entry.clutter_text.connect('text-changed',
|
||||||
|
Lang.bind(this, function() {
|
||||||
|
this._updateNextButtonSensitivity(this._entry.text.length > 0);
|
||||||
|
}));
|
||||||
|
|
||||||
|
this._entryActivateId =
|
||||||
|
this._entry.clutter_text.connect('activate', Lang.bind(this, function() {
|
||||||
|
this.emit('next');
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateNextButtonSensitivity: function(sensitive) {
|
||||||
|
if (this._nextButton) {
|
||||||
|
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() {
|
||||||
|
if (this._entryTextChangedId > 0) {
|
||||||
|
this._entry.clutter_text.disconnect(this._entryTextChangedId);
|
||||||
|
this._entryTextChangedId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this._entryActivateId > 0) {
|
||||||
|
this._entry.clutter_text.disconnect(this._entryActivateId);
|
||||||
|
this._entryActivateId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setActorInDefaultButtonWell(null, true);
|
||||||
|
this.actor.hide();
|
||||||
|
this._loginHint.opacity = 0;
|
||||||
|
|
||||||
|
this.setUser(null);
|
||||||
|
|
||||||
|
this.updateSensitivity(true);
|
||||||
|
this._entry.set_text('');
|
||||||
|
|
||||||
|
this._buttonBox.remove_all_children();
|
||||||
|
this._nextButton = null;
|
||||||
|
this._cancelButton = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
setUser: function(user) {
|
||||||
|
if (user) {
|
||||||
|
let userWidget = new UserWidget.UserWidget(user);
|
||||||
|
this._userWell.set_child(userWidget.actor);
|
||||||
|
} else {
|
||||||
|
this._userWell.set_child(null);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setHint: function(message) {
|
||||||
|
if (message) {
|
||||||
|
this._loginHint.set_text(message)
|
||||||
|
this._loginHint.opacity = 255;
|
||||||
|
} else {
|
||||||
|
this._loginHint.opacity = 0;
|
||||||
|
this._loginHint.set_text('');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
reset: function() {
|
||||||
|
this._message.opacity = 0;
|
||||||
|
this.setUser(null);
|
||||||
|
},
|
||||||
|
|
||||||
|
addCharacter: function(unichar) {
|
||||||
|
if (!this._entry.visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!this._initialAnswer)
|
||||||
|
this._initialAnswer = {};
|
||||||
|
|
||||||
|
this._entry.grab_key_focus();
|
||||||
|
this._entry.clutter_text.insert_unichar(unichar);
|
||||||
|
|
||||||
|
if (!this._initialAnswer['activate-id'])
|
||||||
|
this._initialAnswer['activate-id'] =
|
||||||
|
this._entry.clutter_text.connect('activate', Lang.bind(this, function() {
|
||||||
|
this._entry.clutter_text.disconnect(this._initialAnswer['activate-id']);
|
||||||
|
delete this._initialAnswer['activate-id'];
|
||||||
|
|
||||||
|
this._initialAnswer['text'] = this._entry.get_text();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Signals.addSignalMethods(AuthPrompt.prototype);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
|
|
||||||
const AccountsService = imports.gi.AccountsService;
|
const AccountsService = imports.gi.AccountsService;
|
||||||
|
const Atk = imports.gi.Atk;
|
||||||
const Clutter = imports.gi.Clutter;
|
const Clutter = imports.gi.Clutter;
|
||||||
const Gdm = imports.gi.Gdm;
|
const Gdm = imports.gi.Gdm;
|
||||||
const Gio = imports.gi.Gio;
|
const Gio = imports.gi.Gio;
|
||||||
@@ -12,10 +13,9 @@ const Signals = imports.signals;
|
|||||||
const Shell = imports.gi.Shell;
|
const Shell = imports.gi.Shell;
|
||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
|
|
||||||
|
const Layout = imports.ui.layout;
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const ModalDialog = imports.ui.modalDialog;
|
|
||||||
const Panel = imports.ui.panel;
|
const Panel = imports.ui.panel;
|
||||||
const ShellEntry = imports.ui.shellEntry;
|
|
||||||
const Tweener = imports.ui.tweener;
|
const Tweener = imports.ui.tweener;
|
||||||
const UserWidget = imports.ui.userWidget;
|
const UserWidget = imports.ui.userWidget;
|
||||||
|
|
||||||
@@ -28,21 +28,20 @@ const IDLE_TIMEOUT = 2 * 60;
|
|||||||
|
|
||||||
const UnlockDialog = new Lang.Class({
|
const UnlockDialog = new Lang.Class({
|
||||||
Name: 'UnlockDialog',
|
Name: 'UnlockDialog',
|
||||||
Extends: ModalDialog.ModalDialog,
|
|
||||||
|
|
||||||
_init: function(parentActor) {
|
_init: function(parentActor) {
|
||||||
this.parent({ shellReactive: true,
|
this.actor = new St.Widget({ accessible_role: Atk.Role.WINDOW,
|
||||||
styleClass: 'login-dialog',
|
style_class: 'login-dialog',
|
||||||
keybindingMode: Shell.KeyBindingMode.UNLOCK_SCREEN,
|
visible: false });
|
||||||
parentActor: parentActor
|
|
||||||
});
|
this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
||||||
|
parentActor.add_child(this.actor);
|
||||||
|
|
||||||
this._userManager = AccountsService.UserManager.get_default();
|
this._userManager = AccountsService.UserManager.get_default();
|
||||||
this._userName = GLib.get_user_name();
|
this._userName = GLib.get_user_name();
|
||||||
this._user = this._userManager.get_user(this._userName);
|
this._user = this._userManager.get_user(this._userName);
|
||||||
|
|
||||||
this._failCounter = 0;
|
this._failCounter = 0;
|
||||||
this._firstQuestion = true;
|
|
||||||
|
|
||||||
this._greeterClient = new Gdm.Client();
|
this._greeterClient = new Gdm.Client();
|
||||||
this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true });
|
this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true });
|
||||||
@@ -57,62 +56,21 @@ const UnlockDialog = new Lang.Class({
|
|||||||
this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint));
|
this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint));
|
||||||
this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint));
|
this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint));
|
||||||
|
|
||||||
this._userWidget = new UserWidget.UserWidget(this._user);
|
this._promptBox = new St.BoxLayout({ vertical: true });
|
||||||
this.contentLayout.add_actor(this._userWidget.actor);
|
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._promptLayout = new St.BoxLayout({ style_class: 'login-dialog-prompt-layout',
|
this._authPrompt = new GdmUtil.AuthPrompt({ style_class: 'login-dialog-prompt-layout',
|
||||||
vertical: true });
|
vertical: true });
|
||||||
|
this._authPrompt.setUser(this._user);
|
||||||
this._promptLabel = new St.Label({ style_class: 'login-dialog-prompt-label' });
|
this._authPrompt.setPasswordChar('\u25cf');
|
||||||
this._promptLayout.add(this._promptLabel,
|
this._authPrompt.resetButtons(_("Cancel"), _("Unlock"));
|
||||||
{ x_align: St.Align.START });
|
this._authPrompt.connect('cancel', Lang.bind(this, this._escape));
|
||||||
|
this._promptBox.add_child(this._authPrompt.actor);
|
||||||
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 });
|
|
||||||
this.setInitialKeyFocus(this._promptEntry);
|
|
||||||
this._promptEntry.clutter_text.connect('text-changed', Lang.bind(this, function() {
|
|
||||||
this._updateOkButtonSensitivity(this._promptEntry.text.length > 0);
|
|
||||||
}));
|
|
||||||
|
|
||||||
this._promptLayout.add(this._promptEntry,
|
|
||||||
{ expand: true,
|
|
||||||
x_fill: true });
|
|
||||||
|
|
||||||
this.contentLayout.add_actor(this._promptLayout);
|
|
||||||
|
|
||||||
this._promptMessage = new St.Label({ visible: false });
|
|
||||||
this.contentLayout.add(this._promptMessage, { x_fill: true });
|
|
||||||
|
|
||||||
this._promptLoginHint = new St.Label({ style_class: 'login-dialog-prompt-login-hint' });
|
|
||||||
this._promptLoginHint.hide();
|
|
||||||
this.contentLayout.add_actor(this._promptLoginHint);
|
|
||||||
|
|
||||||
this.allowCancel = false;
|
this.allowCancel = false;
|
||||||
this.buttonLayout.visible = true;
|
|
||||||
this.addButton({ label: _("Cancel"),
|
|
||||||
action: Lang.bind(this, this._escape),
|
|
||||||
key: Clutter.KEY_Escape },
|
|
||||||
{ expand: true,
|
|
||||||
x_fill: false,
|
|
||||||
y_fill: false,
|
|
||||||
x_align: St.Align.START,
|
|
||||||
y_align: St.Align.MIDDLE });
|
|
||||||
this.placeSpinner({ expand: false,
|
|
||||||
x_fill: false,
|
|
||||||
y_fill: false,
|
|
||||||
x_align: St.Align.END,
|
|
||||||
y_align: St.Align.MIDDLE });
|
|
||||||
this._okButton = this.addButton({ label: _("Unlock"),
|
|
||||||
action: Lang.bind(this, this._doUnlock),
|
|
||||||
default: true },
|
|
||||||
{ expand: false,
|
|
||||||
x_fill: false,
|
|
||||||
y_fill: false,
|
|
||||||
x_align: St.Align.END,
|
|
||||||
y_align: St.Align.MIDDLE });
|
|
||||||
|
|
||||||
let screenSaverSettings = new Gio.Settings({ schema: 'org.gnome.desktop.screensaver' });
|
let screenSaverSettings = new Gio.Settings({ schema: 'org.gnome.desktop.screensaver' });
|
||||||
if (screenSaverSettings.get_boolean('user-switch-enabled')) {
|
if (screenSaverSettings.get_boolean('user-switch-enabled')) {
|
||||||
@@ -125,9 +83,7 @@ const UnlockDialog = new Lang.Class({
|
|||||||
x_align: St.Align.START,
|
x_align: St.Align.START,
|
||||||
x_fill: true });
|
x_fill: true });
|
||||||
this._otherUserButton.connect('clicked', Lang.bind(this, this._otherUserClicked));
|
this._otherUserButton.connect('clicked', Lang.bind(this, this._otherUserClicked));
|
||||||
this.dialogLayout.add(this._otherUserButton,
|
this._promptBox.add_child(this._otherUserButton);
|
||||||
{ x_align: St.Align.START,
|
|
||||||
x_fill: false });
|
|
||||||
} else {
|
} else {
|
||||||
this._otherUserButton = null;
|
this._otherUserButton = null;
|
||||||
}
|
}
|
||||||
@@ -137,80 +93,49 @@ const UnlockDialog = new Lang.Class({
|
|||||||
let batch = new Batch.Hold();
|
let batch = new Batch.Hold();
|
||||||
this._userVerifier.begin(this._userName, batch);
|
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._idleMonitor = new GnomeDesktop.IdleMonitor();
|
||||||
this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape));
|
this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape));
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateSensitivity: function(sensitive) {
|
_updateSensitivity: function(sensitive) {
|
||||||
this._promptEntry.reactive = sensitive;
|
this._authPrompt.updateSensitivity(sensitive);
|
||||||
this._promptEntry.clutter_text.editable = sensitive;
|
|
||||||
this._updateOkButtonSensitivity(sensitive && this._promptEntry.text.length > 0);
|
|
||||||
if (this._otherUserButton) {
|
if (this._otherUserButton) {
|
||||||
this._otherUserButton.reactive = sensitive;
|
this._otherUserButton.reactive = sensitive;
|
||||||
this._otherUserButton.can_focus = sensitive;
|
this._otherUserButton.can_focus = sensitive;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateOkButtonSensitivity: function(sensitive) {
|
|
||||||
this._okButton.reactive = sensitive;
|
|
||||||
this._okButton.can_focus = sensitive;
|
|
||||||
},
|
|
||||||
|
|
||||||
_showMessage: function(userVerifier, message, styleClass) {
|
_showMessage: function(userVerifier, message, styleClass) {
|
||||||
if (message) {
|
this._authPrompt.setMessage(message, styleClass);
|
||||||
this._promptMessage.text = message;
|
|
||||||
this._promptMessage.styleClass = styleClass;
|
|
||||||
GdmUtil.fadeInActor(this._promptMessage);
|
|
||||||
} else {
|
|
||||||
GdmUtil.fadeOutActor(this._promptMessage);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_onAskQuestion: function(verifier, serviceName, question, passwordChar) {
|
_onAskQuestion: function(verifier, serviceName, question, passwordChar) {
|
||||||
if (this._firstQuestion && this._firstQuestionAnswer) {
|
|
||||||
this._userVerifier.answerQuery(serviceName, this._firstQuestionAnswer);
|
|
||||||
this._firstQuestionAnswer = null;
|
|
||||||
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._currentQuery = serviceName;
|
this._currentQuery = serviceName;
|
||||||
|
|
||||||
|
this._authPrompt.setPasswordChar(passwordChar);
|
||||||
|
this._authPrompt.setQuestion(question);
|
||||||
|
|
||||||
|
let signalId = this._authPrompt.connect('next', Lang.bind(this, function() {
|
||||||
|
this._authPrompt.disconnect(signalId);
|
||||||
|
this._doUnlock();
|
||||||
|
}));
|
||||||
|
|
||||||
this._updateSensitivity(true);
|
this._updateSensitivity(true);
|
||||||
this.setWorking(false);
|
this._authPrompt.stopSpinning();
|
||||||
},
|
},
|
||||||
|
|
||||||
_showLoginHint: function(verifier, message) {
|
_showLoginHint: function(verifier, message) {
|
||||||
this._promptLoginHint.set_text(message)
|
this._authPrompt.setHint(message);
|
||||||
GdmUtil.fadeInActor(this._promptLoginHint);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_hideLoginHint: function() {
|
_hideLoginHint: function() {
|
||||||
GdmUtil.fadeOutActor(this._promptLoginHint);
|
this._authPrompt.setHint(null);
|
||||||
},
|
},
|
||||||
|
|
||||||
_doUnlock: function() {
|
_doUnlock: function() {
|
||||||
if (this._firstQuestion) {
|
|
||||||
// we haven't received a query yet, so stash the answer
|
|
||||||
// and make ourself non-reactive
|
|
||||||
// the actual reply to GDM will be sent as soon as asked
|
|
||||||
this._firstQuestionAnswer = this._promptEntry.text;
|
|
||||||
this._updateSensitivity(false);
|
|
||||||
this.setWorking(true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this._currentQuery)
|
if (!this._currentQuery)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -218,13 +143,16 @@ const UnlockDialog = new Lang.Class({
|
|||||||
this._currentQuery = null;
|
this._currentQuery = null;
|
||||||
|
|
||||||
this._updateSensitivity(false);
|
this._updateSensitivity(false);
|
||||||
this.setWorking(true);
|
this._authPrompt.startSpinning();
|
||||||
|
|
||||||
this._userVerifier.answerQuery(query, this._promptEntry.text);
|
this._userVerifier.answerQuery(query, this._authPrompt.getAnswer());
|
||||||
},
|
},
|
||||||
|
|
||||||
_finishUnlock: function() {
|
_finishUnlock: function() {
|
||||||
this._userVerifier.clear();
|
this._userVerifier.clear();
|
||||||
|
this._authPrompt.clear();
|
||||||
|
this._authPrompt.stopSpinning();
|
||||||
|
this._updateSensitivity(true);
|
||||||
this.emit('unlocked');
|
this.emit('unlocked');
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -253,12 +181,10 @@ const UnlockDialog = new Lang.Class({
|
|||||||
this._firstQuestion = true;
|
this._firstQuestion = true;
|
||||||
this._userVerified = false;
|
this._userVerified = false;
|
||||||
|
|
||||||
this._promptEntry.text = '';
|
this._authPrompt.clear();
|
||||||
this._promptEntry.clutter_text.set_password_char('\u25cf');
|
|
||||||
this._promptEntry.menu.isPassword = true;
|
|
||||||
|
|
||||||
this._updateSensitivity(false);
|
this._updateSensitivity(false);
|
||||||
this.setWorking(false);
|
this._authPrompt.stopSpinning();
|
||||||
},
|
},
|
||||||
|
|
||||||
_escape: function() {
|
_escape: function() {
|
||||||
@@ -282,8 +208,6 @@ const UnlockDialog = new Lang.Class({
|
|||||||
this._idleMonitor.remove_watch(this._idleWatchId);
|
this._idleMonitor.remove_watch(this._idleWatchId);
|
||||||
this._idleWatchId = 0;
|
this._idleWatchId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.parent();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
cancel: function() {
|
cancel: function() {
|
||||||
@@ -293,6 +217,29 @@ const UnlockDialog = new Lang.Class({
|
|||||||
},
|
},
|
||||||
|
|
||||||
addCharacter: function(unichar) {
|
addCharacter: function(unichar) {
|
||||||
this._promptEntry.clutter_text.insert_unichar(unichar);
|
this._authPrompt.addCharacter(unichar);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
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);
|
||||||
|
this._isModal = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
Signals.addSignalMethods(UnlockDialog.prototype);
|
||||||
|
|||||||
Reference in New Issue
Block a user