2012-05-20 12:30:14 -04:00
|
|
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
|
|
|
|
|
|
const AccountsService = imports.gi.AccountsService;
|
2013-07-16 07:31:22 -04:00
|
|
|
const Atk = imports.gi.Atk;
|
2012-05-20 12:30:14 -04:00
|
|
|
const Clutter = imports.gi.Clutter;
|
2012-07-08 11:42:15 -04:00
|
|
|
const Gdm = imports.gi.Gdm;
|
2012-05-20 12:30:14 -04:00
|
|
|
const Gio = imports.gi.Gio;
|
|
|
|
const GLib = imports.gi.GLib;
|
2012-08-20 00:06:50 -04:00
|
|
|
const GnomeDesktop = imports.gi.GnomeDesktop;
|
2012-05-20 12:30:14 -04:00
|
|
|
const Gtk = imports.gi.Gtk;
|
|
|
|
const Lang = imports.lang;
|
|
|
|
const Signals = imports.signals;
|
|
|
|
const Shell = imports.gi.Shell;
|
|
|
|
const St = imports.gi.St;
|
|
|
|
|
2013-07-16 07:31:22 -04:00
|
|
|
const Layout = imports.ui.layout;
|
2012-05-20 12:30:14 -04:00
|
|
|
const Main = imports.ui.main;
|
2012-11-18 16:49:54 -05:00
|
|
|
const Panel = imports.ui.panel;
|
2012-05-20 12:30:14 -04:00
|
|
|
const Tweener = imports.ui.tweener;
|
2013-02-17 20:54:46 -05:00
|
|
|
const UserWidget = imports.ui.userWidget;
|
2012-05-20 12:30:14 -04:00
|
|
|
|
|
|
|
const Batch = imports.gdm.batch;
|
|
|
|
const GdmUtil = imports.gdm.util;
|
2012-11-18 16:49:54 -05:00
|
|
|
const LoginDialog = imports.gdm.loginDialog;
|
2012-05-20 12:30:14 -04:00
|
|
|
|
2012-08-16 15:24:53 -04:00
|
|
|
// The timeout before going back automatically to the lock screen (in seconds)
|
|
|
|
const IDLE_TIMEOUT = 2 * 60;
|
|
|
|
|
2012-05-20 12:30:14 -04:00
|
|
|
const UnlockDialog = new Lang.Class({
|
|
|
|
Name: 'UnlockDialog',
|
|
|
|
|
2012-05-24 16:47:48 -04:00
|
|
|
_init: function(parentActor) {
|
2013-07-16 07:31:22 -04:00
|
|
|
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);
|
2012-05-20 12:30:14 -04:00
|
|
|
|
|
|
|
this._userManager = AccountsService.UserManager.get_default();
|
|
|
|
this._userName = GLib.get_user_name();
|
|
|
|
this._user = this._userManager.get_user(this._userName);
|
|
|
|
|
2012-08-13 06:49:04 -04:00
|
|
|
this._firstQuestion = true;
|
2012-08-07 10:49:22 -04:00
|
|
|
|
2012-05-20 12:30:14 -04:00
|
|
|
this._greeterClient = new Gdm.Client();
|
2012-08-03 11:10:45 -04:00
|
|
|
this._userVerifier = new GdmUtil.ShellUserVerifier(this._greeterClient, { reauthenticationOnly: true });
|
2013-03-18 01:14:44 -04:00
|
|
|
this._userVerified = false;
|
2012-05-20 12:30:14 -04:00
|
|
|
|
|
|
|
this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion));
|
2012-08-07 10:49:22 -04:00
|
|
|
this._userVerifier.connect('show-message', Lang.bind(this, this._showMessage));
|
2012-05-20 12:30:14 -04:00
|
|
|
this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete));
|
2012-10-03 17:15:41 -04:00
|
|
|
this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed));
|
2012-08-07 10:49:22 -04:00
|
|
|
this._userVerifier.connect('reset', Lang.bind(this, this._onReset));
|
2012-05-20 12:30:14 -04:00
|
|
|
|
2012-08-19 20:15:18 -04:00
|
|
|
this._userVerifier.connect('show-login-hint', Lang.bind(this, this._showLoginHint));
|
|
|
|
this._userVerifier.connect('hide-login-hint', Lang.bind(this, this._hideLoginHint));
|
2012-05-20 12:30:14 -04:00
|
|
|
|
2013-07-16 07:31:22 -04:00
|
|
|
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 }));
|
2012-05-20 12:30:14 -04:00
|
|
|
|
2013-07-16 07:31:22 -04:00
|
|
|
this._authPrompt = new GdmUtil.AuthPrompt();
|
|
|
|
this._authPrompt.setUser(this._user);
|
|
|
|
this._authPrompt.setPasswordChar('\u25cf');
|
|
|
|
this._authPrompt.nextButton.label = _("Unlock");
|
|
|
|
this._authPrompt.connect('cancel', Lang.bind(this, this._escape));
|
|
|
|
this._authPrompt.connect('next', Lang.bind(this, this._doUnlock));
|
2012-08-07 10:49:22 -04:00
|
|
|
|
2013-07-16 07:31:22 -04:00
|
|
|
this._promptBox.add_child(this._authPrompt.actor);
|
2012-05-20 12:30:14 -04:00
|
|
|
|
2012-10-24 11:53:19 -04:00
|
|
|
this.allowCancel = false;
|
2012-08-07 11:38:12 -04:00
|
|
|
|
2013-01-02 19:02:13 -05:00
|
|
|
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"),
|
|
|
|
style_class: 'login-dialog-not-listed-label' });
|
|
|
|
this._otherUserButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
|
|
|
|
can_focus: true,
|
|
|
|
child: otherUserLabel,
|
|
|
|
reactive: true,
|
|
|
|
x_align: St.Align.START,
|
|
|
|
x_fill: true });
|
|
|
|
this._otherUserButton.connect('clicked', Lang.bind(this, this._otherUserClicked));
|
2013-07-16 07:31:22 -04:00
|
|
|
this._promptBox.add_child(this._otherUserButton);
|
2013-01-02 19:02:13 -05:00
|
|
|
} else {
|
|
|
|
this._otherUserButton = null;
|
|
|
|
}
|
2012-05-26 11:04:25 -04:00
|
|
|
|
2012-11-18 16:36:17 -05:00
|
|
|
this._updateSensitivity(true);
|
|
|
|
|
2012-08-07 10:49:22 -04:00
|
|
|
let batch = new Batch.Hold();
|
|
|
|
this._userVerifier.begin(this._userName, batch);
|
|
|
|
|
2013-07-16 07:31:22 -04:00
|
|
|
Main.ctrlAltTabManager.addGroup(this.actor, _("Unlock Window"), 'dialog-password-symbolic');
|
2012-08-10 23:53:59 -04:00
|
|
|
|
2012-08-20 00:06:50 -04:00
|
|
|
this._idleMonitor = new GnomeDesktop.IdleMonitor();
|
2013-02-15 12:19:49 -05:00
|
|
|
this._idleWatchId = this._idleMonitor.add_idle_watch(IDLE_TIMEOUT * 1000, Lang.bind(this, this._escape));
|
2012-05-20 12:30:14 -04:00
|
|
|
},
|
|
|
|
|
2012-10-03 16:43:38 -04:00
|
|
|
_updateSensitivity: function(sensitive) {
|
2013-07-16 07:31:22 -04:00
|
|
|
this._authPrompt.updateSensitivity(sensitive);
|
|
|
|
|
2013-01-02 19:02:13 -05:00
|
|
|
if (this._otherUserButton) {
|
|
|
|
this._otherUserButton.reactive = sensitive;
|
|
|
|
this._otherUserButton.can_focus = sensitive;
|
|
|
|
}
|
2012-11-01 11:19:17 -04:00
|
|
|
},
|
|
|
|
|
2012-08-07 10:49:22 -04:00
|
|
|
_showMessage: function(userVerifier, message, styleClass) {
|
2013-07-16 07:31:22 -04:00
|
|
|
this._authPrompt.setMessage(message, styleClass);
|
2012-05-20 12:30:14 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_onAskQuestion: function(verifier, serviceName, question, passwordChar) {
|
2012-08-13 06:49:04 -04:00
|
|
|
if (this._firstQuestion && this._firstQuestionAnswer) {
|
|
|
|
this._userVerifier.answerQuery(serviceName, this._firstQuestionAnswer);
|
|
|
|
this._firstQuestionAnswer = null;
|
|
|
|
this._firstQuestion = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this._firstQuestion)
|
|
|
|
this._promptEntry.text = '';
|
|
|
|
else
|
|
|
|
this._firstQuestion = false;
|
|
|
|
|
2013-07-16 07:31:22 -04:00
|
|
|
this._authPrompt.setPasswordChar(passwordChar);
|
|
|
|
this._authPrompt.setQuestion(question);
|
2012-05-20 12:30:14 -04:00
|
|
|
|
|
|
|
this._currentQuery = serviceName;
|
2013-07-16 07:31:22 -04:00
|
|
|
|
2012-10-03 16:43:38 -04:00
|
|
|
this._updateSensitivity(true);
|
2013-07-16 07:31:22 -04:00
|
|
|
this._authPrompt.stopSpinning();
|
2012-05-20 12:30:14 -04:00
|
|
|
},
|
|
|
|
|
2012-08-19 20:15:18 -04:00
|
|
|
_showLoginHint: function(verifier, message) {
|
2013-07-16 07:31:22 -04:00
|
|
|
this._authPrompt.setHint(message);
|
2012-05-20 12:30:14 -04:00
|
|
|
},
|
|
|
|
|
2012-08-19 20:15:18 -04:00
|
|
|
_hideLoginHint: function() {
|
2013-07-16 07:31:22 -04:00
|
|
|
this._authPrompt.setHint(null);
|
2012-05-20 12:30:14 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_doUnlock: function() {
|
2012-08-13 06:49:04 -04:00
|
|
|
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;
|
2012-10-03 16:43:38 -04:00
|
|
|
this._updateSensitivity(false);
|
2013-07-16 07:31:22 -04:00
|
|
|
this._authPrompt.startSpinning();
|
2012-08-13 06:49:04 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-05-20 12:30:14 -04:00
|
|
|
if (!this._currentQuery)
|
|
|
|
return;
|
|
|
|
|
|
|
|
let query = this._currentQuery;
|
|
|
|
this._currentQuery = null;
|
|
|
|
|
2012-10-03 16:43:38 -04:00
|
|
|
this._updateSensitivity(false);
|
2013-07-16 07:31:22 -04:00
|
|
|
this._authPrompt.startSpinning();
|
2012-05-20 12:30:14 -04:00
|
|
|
|
2013-07-16 07:31:22 -04:00
|
|
|
this._userVerifier.answerQuery(query, this._authPrompt.getAnswer());
|
2012-05-20 12:30:14 -04:00
|
|
|
},
|
|
|
|
|
2013-03-18 00:59:56 -04:00
|
|
|
_onVerificationComplete: function() {
|
|
|
|
this._userVerified = true;
|
|
|
|
},
|
|
|
|
|
2012-08-07 10:49:22 -04:00
|
|
|
_onReset: function() {
|
2013-03-18 01:14:44 -04:00
|
|
|
if (!this._userVerified) {
|
|
|
|
this._userVerifier.clear();
|
|
|
|
this.emit('failed');
|
|
|
|
}
|
2012-05-20 12:30:14 -04:00
|
|
|
},
|
|
|
|
|
2012-10-03 17:15:41 -04:00
|
|
|
_onVerificationFailed: function() {
|
|
|
|
this._currentQuery = null;
|
|
|
|
this._firstQuestion = true;
|
2013-03-18 01:14:44 -04:00
|
|
|
this._userVerified = false;
|
2012-10-03 17:15:41 -04:00
|
|
|
|
2013-07-16 07:31:22 -04:00
|
|
|
this._authPrompt.clear();
|
2012-10-03 17:15:41 -04:00
|
|
|
|
|
|
|
this._updateSensitivity(false);
|
2013-07-16 07:31:22 -04:00
|
|
|
this._authPrompt.stopSpinning();
|
2012-10-03 17:15:41 -04:00
|
|
|
},
|
|
|
|
|
2012-08-03 13:26:30 -04:00
|
|
|
_escape: function() {
|
2012-10-24 11:53:19 -04:00
|
|
|
if (this.allowCancel) {
|
|
|
|
this._userVerifier.cancel();
|
|
|
|
this.emit('failed');
|
|
|
|
}
|
2012-08-03 13:26:30 -04:00
|
|
|
},
|
|
|
|
|
2012-05-20 12:30:14 -04:00
|
|
|
_otherUserClicked: function(button, event) {
|
2012-08-14 11:49:46 -04:00
|
|
|
Gdm.goto_login_session_sync(null);
|
2012-05-20 12:30:14 -04:00
|
|
|
|
|
|
|
this._userVerifier.cancel();
|
|
|
|
this.emit('failed');
|
|
|
|
},
|
|
|
|
|
|
|
|
destroy: function() {
|
|
|
|
this._userVerifier.clear();
|
2013-07-16 07:31:22 -04:00
|
|
|
this.actor.destroy();
|
2012-08-16 15:24:53 -04:00
|
|
|
|
|
|
|
if (this._idleWatchId) {
|
|
|
|
this._idleMonitor.remove_watch(this._idleWatchId);
|
|
|
|
this._idleWatchId = 0;
|
|
|
|
}
|
2012-05-20 12:30:14 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
cancel: function() {
|
|
|
|
this._userVerifier.cancel(null);
|
|
|
|
|
|
|
|
this.destroy();
|
|
|
|
},
|
2013-03-05 00:55:54 -05:00
|
|
|
|
|
|
|
addCharacter: function(unichar) {
|
2013-07-16 07:31:22 -04:00
|
|
|
this._authPrompt.addCharacter(unichar);
|
2013-03-05 00:55:54 -05:00
|
|
|
},
|
2013-07-18 08:58:58 -04:00
|
|
|
|
|
|
|
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();
|
|
|
|
}));
|
2013-07-16 07:31:22 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
open: function(timestamp) {
|
|
|
|
this.actor.show();
|
|
|
|
|
|
|
|
if (this._isModal)
|
|
|
|
return true;
|
2013-07-18 08:58:58 -04:00
|
|
|
|
2013-07-16 07:31:22 -04:00
|
|
|
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;
|
|
|
|
}
|
2013-07-18 08:58:58 -04:00
|
|
|
}
|
2012-05-20 12:30:14 -04:00
|
|
|
});
|
2013-07-16 07:31:22 -04:00
|
|
|
Signals.addSignalMethods(UnlockDialog.prototype);
|