2011-09-28 09:16:26 -04:00
|
|
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
|
|
/*
|
2011-08-23 22:12:57 -04:00
|
|
|
* Copyright 2011 Red Hat, Inc
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2014-01-07 16:32:37 -05:00
|
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
2011-08-23 22:12:57 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
const AccountsService = imports.gi.AccountsService;
|
2013-06-25 12:55:21 -04:00
|
|
|
const Atk = imports.gi.Atk;
|
2011-08-23 22:12:57 -04:00
|
|
|
const Clutter = imports.gi.Clutter;
|
2013-06-14 08:14:34 -04:00
|
|
|
const Gdm = imports.gi.Gdm;
|
2011-08-23 22:12:57 -04:00
|
|
|
const Gio = imports.gi.Gio;
|
|
|
|
const GLib = imports.gi.GLib;
|
2015-03-06 10:56:11 -05:00
|
|
|
const GObject = imports.gi.GObject;
|
2011-08-23 22:12:57 -04:00
|
|
|
const Gtk = imports.gi.Gtk;
|
2013-06-14 08:14:34 -04:00
|
|
|
const Lang = imports.lang;
|
2011-08-23 22:12:57 -04:00
|
|
|
const Mainloop = imports.mainloop;
|
2012-10-05 04:00:32 -04:00
|
|
|
const Meta = imports.gi.Meta;
|
2014-11-11 09:11:01 -05:00
|
|
|
const Pango = imports.gi.Pango;
|
2011-08-23 22:12:57 -04:00
|
|
|
const Shell = imports.gi.Shell;
|
2013-06-14 08:14:34 -04:00
|
|
|
const Signals = imports.signals;
|
2011-08-23 22:12:57 -04:00
|
|
|
const St = imports.gi.St;
|
|
|
|
|
2013-07-23 20:37:42 -04:00
|
|
|
const AuthPrompt = imports.gdm.authPrompt;
|
2011-08-30 07:52:25 -04:00
|
|
|
const Batch = imports.gdm.batch;
|
2013-06-23 23:14:10 -04:00
|
|
|
const BoxPointer = imports.ui.boxpointer;
|
2013-06-14 08:14:34 -04:00
|
|
|
const CtrlAltTab = imports.ui.ctrlAltTab;
|
2012-07-17 14:54:07 -04:00
|
|
|
const GdmUtil = imports.gdm.util;
|
2013-06-25 12:55:21 -04:00
|
|
|
const Layout = imports.ui.layout;
|
2014-03-07 19:35:02 -05:00
|
|
|
const LoginManager = imports.misc.loginManager;
|
2011-08-23 22:12:57 -04:00
|
|
|
const Main = imports.ui.main;
|
2013-06-23 23:14:10 -04:00
|
|
|
const PopupMenu = imports.ui.popupMenu;
|
2013-06-14 08:14:34 -04:00
|
|
|
const Realmd = imports.gdm.realmd;
|
2011-08-23 22:12:57 -04:00
|
|
|
const Tweener = imports.ui.tweener;
|
2013-02-06 16:17:27 -05:00
|
|
|
const UserWidget = imports.ui.userWidget;
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2013-02-06 15:18:22 -05:00
|
|
|
const _FADE_ANIMATION_TIME = 0.25;
|
2012-07-25 13:08:29 -04:00
|
|
|
const _SCROLL_ANIMATION_TIME = 0.5;
|
2011-08-23 22:12:57 -04:00
|
|
|
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
2013-03-22 20:27:22 -04:00
|
|
|
const _LOGO_ICON_HEIGHT = 48;
|
2015-03-20 09:29:40 -04:00
|
|
|
const _MAX_BOTTOM_MENU_ITEMS = 5;
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2011-11-20 12:56:27 -05:00
|
|
|
const UserListItem = new Lang.Class({
|
|
|
|
Name: 'UserListItem',
|
2011-08-23 22:12:57 -04:00
|
|
|
|
|
|
|
_init: function(user) {
|
|
|
|
this.user = user;
|
|
|
|
this._userChangedId = this.user.connect('changed',
|
|
|
|
Lang.bind(this, this._onUserChanged));
|
|
|
|
|
2013-08-26 18:41:29 -04:00
|
|
|
let layout = new St.BoxLayout({ vertical: true });
|
2011-08-23 22:12:57 -04:00
|
|
|
this.actor = new St.Button({ style_class: 'login-dialog-user-list-item',
|
2013-01-11 14:05:17 -05:00
|
|
|
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
2011-08-23 22:12:57 -04:00
|
|
|
can_focus: true,
|
2012-07-13 18:43:58 -04:00
|
|
|
child: layout,
|
2011-08-23 22:12:57 -04:00
|
|
|
reactive: true,
|
|
|
|
x_align: St.Align.START,
|
|
|
|
x_fill: true });
|
2014-10-09 14:10:12 -04:00
|
|
|
this.actor.connect('destroy',
|
|
|
|
Lang.bind(this, this._onDestroy));
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2013-08-26 18:41:29 -04:00
|
|
|
this._userWidget = new UserWidget.UserWidget(this.user);
|
|
|
|
layout.add(this._userWidget.actor);
|
2012-07-13 18:43:58 -04:00
|
|
|
|
2015-03-06 10:56:11 -05:00
|
|
|
this._userWidget.actor.bind_property('label-actor', this.actor, 'label-actor',
|
|
|
|
GObject.BindingFlags.SYNC_CREATE);
|
|
|
|
|
2012-07-13 18:43:58 -04:00
|
|
|
this._timedLoginIndicator = new St.Bin({ style_class: 'login-dialog-timed-login-indicator',
|
|
|
|
scale_x: 0 });
|
2013-08-26 18:41:29 -04:00
|
|
|
layout.add(this._timedLoginIndicator);
|
2011-08-23 22:12:57 -04:00
|
|
|
|
|
|
|
this.actor.connect('clicked', Lang.bind(this, this._onClicked));
|
2012-09-01 07:06:41 -04:00
|
|
|
this._onUserChanged();
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_onUserChanged: function() {
|
2012-07-09 14:04:23 -04:00
|
|
|
this._updateLoggedIn();
|
2012-07-09 17:46:35 -04:00
|
|
|
},
|
|
|
|
|
2012-07-09 14:04:23 -04:00
|
|
|
_updateLoggedIn: function() {
|
|
|
|
if (this.user.is_logged_in())
|
|
|
|
this.actor.add_style_pseudo_class('logged-in');
|
|
|
|
else
|
|
|
|
this.actor.remove_style_pseudo_class('logged-in');
|
|
|
|
},
|
|
|
|
|
2014-10-09 14:10:12 -04:00
|
|
|
_onDestroy: function() {
|
2015-11-23 18:21:49 -05:00
|
|
|
this.user.disconnect(this._userChangedId);
|
2014-10-09 14:10:12 -04:00
|
|
|
},
|
|
|
|
|
2011-08-23 22:12:57 -04:00
|
|
|
_onClicked: function() {
|
|
|
|
this.emit('activate');
|
|
|
|
},
|
|
|
|
|
2012-07-13 18:43:58 -04:00
|
|
|
showTimedLoginIndicator: function(time) {
|
2011-08-23 22:12:57 -04:00
|
|
|
let hold = new Batch.Hold();
|
|
|
|
|
2012-07-13 18:43:58 -04:00
|
|
|
this.hideTimedLoginIndicator();
|
|
|
|
Tweener.addTween(this._timedLoginIndicator,
|
2012-07-12 13:49:31 -04:00
|
|
|
{ scale_x: 1.,
|
2011-08-23 22:12:57 -04:00
|
|
|
time: time,
|
|
|
|
transition: 'linear',
|
|
|
|
onComplete: function() {
|
|
|
|
hold.release();
|
|
|
|
},
|
|
|
|
onCompleteScope: this
|
|
|
|
});
|
|
|
|
return hold;
|
2012-07-13 18:43:58 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
hideTimedLoginIndicator: function() {
|
|
|
|
Tweener.removeTweens(this._timedLoginIndicator);
|
|
|
|
this._timedLoginIndicator.scale_x = 0.;
|
2011-08-23 22:12:57 -04:00
|
|
|
}
|
2011-11-20 12:56:27 -05:00
|
|
|
});
|
2011-08-23 22:12:57 -04:00
|
|
|
Signals.addSignalMethods(UserListItem.prototype);
|
|
|
|
|
2011-11-20 12:56:27 -05:00
|
|
|
const UserList = new Lang.Class({
|
|
|
|
Name: 'UserList',
|
2011-08-23 22:12:57 -04:00
|
|
|
|
|
|
|
_init: function() {
|
|
|
|
this.actor = new St.ScrollView({ style_class: 'login-dialog-user-list-view'});
|
|
|
|
this.actor.set_policy(Gtk.PolicyType.NEVER,
|
|
|
|
Gtk.PolicyType.AUTOMATIC);
|
|
|
|
|
|
|
|
this._box = new St.BoxLayout({ vertical: true,
|
2012-08-01 11:14:00 -04:00
|
|
|
style_class: 'login-dialog-user-list',
|
|
|
|
pseudo_class: 'expanded' });
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2012-07-18 20:15:04 -04:00
|
|
|
this.actor.add_actor(this._box);
|
2011-08-23 22:12:57 -04:00
|
|
|
this._items = {};
|
2011-10-17 02:56:44 -04:00
|
|
|
|
|
|
|
this.actor.connect('key-focus-in', Lang.bind(this, this._moveFocusToItems));
|
|
|
|
},
|
|
|
|
|
|
|
|
_moveFocusToItems: function() {
|
|
|
|
let hasItems = Object.keys(this._items).length > 0;
|
|
|
|
|
|
|
|
if (!hasItems)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (global.stage.get_key_focus() != this.actor)
|
|
|
|
return;
|
|
|
|
|
2012-10-05 04:00:32 -04:00
|
|
|
let focusSet = this.actor.navigate_focus(null, Gtk.DirectionType.TAB_FORWARD, false);
|
|
|
|
if (!focusSet) {
|
|
|
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, Lang.bind(this, function() {
|
|
|
|
this._moveFocusToItems();
|
|
|
|
return false;
|
|
|
|
}));
|
|
|
|
}
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_onItemActivated: function(activatedItem) {
|
|
|
|
this.emit('activate', activatedItem);
|
|
|
|
},
|
|
|
|
|
2013-02-06 16:37:47 -05:00
|
|
|
updateStyle: function(isExpanded) {
|
2011-08-23 22:12:57 -04:00
|
|
|
let tasks = [];
|
|
|
|
|
2013-02-06 16:37:47 -05:00
|
|
|
if (isExpanded)
|
|
|
|
this._box.add_style_pseudo_class('expanded');
|
|
|
|
else
|
|
|
|
this._box.remove_style_pseudo_class('expanded');
|
2013-02-04 16:50:46 -05:00
|
|
|
|
2011-08-23 22:12:57 -04:00
|
|
|
for (let userName in this._items) {
|
|
|
|
let item = this._items[userName];
|
2012-07-09 17:46:35 -04:00
|
|
|
item.actor.sync_hover();
|
2011-08-23 22:12:57 -04:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
scrollToItem: function(item) {
|
|
|
|
let box = item.actor.get_allocation_box();
|
|
|
|
|
|
|
|
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
|
|
|
|
|
|
|
|
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
|
|
|
Tweener.removeTweens(adjustment);
|
|
|
|
Tweener.addTween (adjustment,
|
|
|
|
{ value: value,
|
|
|
|
time: _SCROLL_ANIMATION_TIME,
|
2012-07-25 13:08:29 -04:00
|
|
|
transition: 'easeOutQuad' });
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
jumpToItem: function(item) {
|
|
|
|
let box = item.actor.get_allocation_box();
|
|
|
|
|
|
|
|
let adjustment = this.actor.get_vscroll_bar().get_adjustment();
|
|
|
|
|
|
|
|
let value = (box.y1 + adjustment.step_increment / 2.0) - (adjustment.page_size / 2.0);
|
|
|
|
|
|
|
|
adjustment.set_value(value);
|
|
|
|
},
|
|
|
|
|
|
|
|
getItemFromUserName: function(userName) {
|
|
|
|
let item = this._items[userName];
|
|
|
|
|
|
|
|
if (!item)
|
|
|
|
return null;
|
|
|
|
|
|
|
|
return item;
|
|
|
|
},
|
|
|
|
|
2015-11-23 19:24:19 -05:00
|
|
|
containsUser: function(user) {
|
|
|
|
return this._items[user.get_user_name()] != null;
|
|
|
|
},
|
|
|
|
|
2011-08-23 22:12:57 -04:00
|
|
|
addUser: function(user) {
|
|
|
|
if (!user.is_loaded)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (user.is_system_account())
|
|
|
|
return;
|
|
|
|
|
2012-04-09 12:43:44 -04:00
|
|
|
if (user.locked)
|
|
|
|
return;
|
|
|
|
|
2011-08-23 22:12:57 -04:00
|
|
|
let userName = user.get_user_name();
|
|
|
|
|
|
|
|
if (!userName)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this.removeUser(user);
|
|
|
|
|
|
|
|
let item = new UserListItem(user);
|
|
|
|
this._box.add(item.actor, { x_fill: true });
|
|
|
|
|
|
|
|
this._items[userName] = item;
|
|
|
|
|
|
|
|
item.connect('activate',
|
|
|
|
Lang.bind(this, this._onItemActivated));
|
|
|
|
|
|
|
|
// Try to keep the focused item front-and-center
|
|
|
|
item.actor.connect('key-focus-in',
|
|
|
|
Lang.bind(this,
|
|
|
|
function() {
|
|
|
|
this.scrollToItem(item);
|
|
|
|
}));
|
|
|
|
|
2011-10-17 02:56:44 -04:00
|
|
|
this._moveFocusToItems();
|
|
|
|
|
2011-08-23 22:12:57 -04:00
|
|
|
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];
|
|
|
|
}
|
2011-11-20 12:56:27 -05:00
|
|
|
});
|
2011-08-23 22:12:57 -04:00
|
|
|
Signals.addSignalMethods(UserList.prototype);
|
|
|
|
|
2013-06-23 23:14:10 -04:00
|
|
|
const SessionMenuButton = new Lang.Class({
|
|
|
|
Name: 'SessionMenuButton',
|
2011-08-23 22:12:57 -04:00
|
|
|
|
|
|
|
_init: function() {
|
2013-06-23 23:14:10 -04:00
|
|
|
let gearIcon = new St.Icon({ icon_name: 'emblem-system-symbolic' });
|
2011-08-23 22:12:57 -04:00
|
|
|
this._button = new St.Button({ style_class: 'login-dialog-session-list-button',
|
2013-06-23 23:14:10 -04:00
|
|
|
reactive: true,
|
|
|
|
track_hover: true,
|
2011-08-23 22:12:57 -04:00
|
|
|
can_focus: true,
|
2013-06-23 23:14:10 -04:00
|
|
|
accessible_name: _("Choose Session"),
|
|
|
|
accessible_role: Atk.Role.MENU,
|
|
|
|
child: gearIcon });
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2013-06-23 23:14:10 -04:00
|
|
|
this.actor = new St.Bin({ child: this._button });
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2015-03-20 09:29:40 -04:00
|
|
|
let side = St.Side.TOP;
|
|
|
|
let align = 0;
|
|
|
|
if (Gdm.get_session_ids().length > _MAX_BOTTOM_MENU_ITEMS) {
|
|
|
|
if (this.actor.text_direction == Clutter.TextDirection.RTL)
|
|
|
|
side = St.Side.RIGHT;
|
|
|
|
else
|
|
|
|
side = St.Side.LEFT;
|
|
|
|
align = 0.5;
|
|
|
|
}
|
|
|
|
this._menu = new PopupMenu.PopupMenu(this._button, align, side);
|
2013-06-23 23:14:10 -04:00
|
|
|
Main.uiGroup.add_actor(this._menu.actor);
|
|
|
|
this._menu.actor.hide();
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2013-06-23 23:14:10 -04:00
|
|
|
this._menu.connect('open-state-changed',
|
|
|
|
Lang.bind(this, function(menu, isOpen) {
|
|
|
|
if (isOpen)
|
|
|
|
this._button.add_style_pseudo_class('active');
|
|
|
|
else
|
|
|
|
this._button.remove_style_pseudo_class('active');
|
|
|
|
}));
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2013-06-23 23:14:10 -04:00
|
|
|
this._manager = new PopupMenu.PopupMenuManager({ actor: this._button });
|
|
|
|
this._manager.addMenu(this._menu);
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2013-06-23 23:14:10 -04:00
|
|
|
this._button.connect('clicked', Lang.bind(this, function() {
|
|
|
|
this._menu.toggle();
|
|
|
|
}));
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2013-06-23 23:14:10 -04:00
|
|
|
this._items = {};
|
|
|
|
this._activeSessionId = null;
|
|
|
|
this._populate();
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
2012-11-18 16:36:17 -05:00
|
|
|
updateSensitivity: function(sensitive) {
|
|
|
|
this._button.reactive = sensitive;
|
|
|
|
this._button.can_focus = sensitive;
|
2013-06-23 23:14:10 -04:00
|
|
|
this._menu.close(BoxPointer.PopupAnimation.NONE);
|
|
|
|
},
|
2012-11-18 16:36:17 -05:00
|
|
|
|
2013-06-23 23:14:10 -04:00
|
|
|
_updateOrnament: function() {
|
|
|
|
let itemIds = Object.keys(this._items);
|
|
|
|
for (let i = 0; i < itemIds.length; i++) {
|
|
|
|
if (itemIds[i] == this._activeSessionId)
|
|
|
|
this._items[itemIds[i]].setOrnament(PopupMenu.Ornament.DOT);
|
|
|
|
else
|
|
|
|
this._items[itemIds[i]].setOrnament(PopupMenu.Ornament.NONE);
|
|
|
|
}
|
2012-11-18 16:36:17 -05:00
|
|
|
},
|
|
|
|
|
2015-03-18 12:43:58 -04:00
|
|
|
setActiveSession: function(sessionId) {
|
2011-08-23 22:12:57 -04:00
|
|
|
if (sessionId == this._activeSessionId)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this._activeSessionId = sessionId;
|
2013-06-23 23:14:10 -04:00
|
|
|
this._updateOrnament();
|
2011-08-23 22:12:57 -04:00
|
|
|
|
|
|
|
this.emit('session-activated', this._activeSessionId);
|
|
|
|
},
|
|
|
|
|
2013-06-23 23:14:10 -04:00
|
|
|
close: function() {
|
|
|
|
this._menu.close();
|
|
|
|
},
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2013-06-23 23:14:10 -04:00
|
|
|
_populate: function() {
|
2012-05-19 19:19:25 -04:00
|
|
|
let ids = Gdm.get_session_ids();
|
2011-08-23 22:12:57 -04:00
|
|
|
ids.sort();
|
|
|
|
|
2011-10-11 13:34:04 -04:00
|
|
|
if (ids.length <= 1) {
|
|
|
|
this._button.hide();
|
2013-06-23 23:14:10 -04:00
|
|
|
return;
|
2011-10-11 13:34:04 -04:00
|
|
|
}
|
2011-08-23 22:12:57 -04:00
|
|
|
|
|
|
|
for (let i = 0; i < ids.length; i++) {
|
2012-05-19 19:19:25 -04:00
|
|
|
let [sessionName, sessionDescription] = Gdm.get_session_name_and_description(ids[i]);
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2013-06-23 23:14:10 -04:00
|
|
|
let id = ids[i];
|
|
|
|
let item = new PopupMenu.PopupMenuItem(sessionName);
|
|
|
|
this._menu.addMenuItem(item);
|
|
|
|
this._items[id] = item;
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2015-03-18 12:44:19 -04:00
|
|
|
if (!this._activeSessionId)
|
|
|
|
this.setActiveSession(id);
|
|
|
|
|
2013-06-23 23:14:10 -04:00
|
|
|
item.connect('activate', Lang.bind(this, function() {
|
|
|
|
this.setActiveSession(id);
|
|
|
|
}));
|
2011-08-23 22:12:57 -04:00
|
|
|
}
|
|
|
|
}
|
2011-11-20 12:56:27 -05:00
|
|
|
});
|
2013-06-23 23:14:10 -04:00
|
|
|
Signals.addSignalMethods(SessionMenuButton.prototype);
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2011-11-20 10:32:59 -05:00
|
|
|
const LoginDialog = new Lang.Class({
|
|
|
|
Name: 'LoginDialog',
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2012-05-26 11:04:25 -04:00
|
|
|
_init: function(parentActor) {
|
2014-11-10 14:36:07 -05:00
|
|
|
this.actor = new Shell.GenericContainer({ style_class: 'login-dialog',
|
|
|
|
visible: false });
|
|
|
|
this.actor.get_accessible().set_role(Atk.Role.WINDOW);
|
2013-06-25 12:55:21 -04:00
|
|
|
|
|
|
|
this.actor.add_constraint(new Layout.MonitorConstraint({ primary: true }));
|
2014-11-10 14:36:07 -05:00
|
|
|
this.actor.connect('allocate', Lang.bind(this, this._onAllocate));
|
2013-06-25 12:55:21 -04:00
|
|
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
|
|
|
parentActor.add_child(this.actor);
|
2011-08-23 22:12:57 -04:00
|
|
|
|
|
|
|
this._userManager = AccountsService.UserManager.get_default()
|
2015-01-22 13:39:46 -05:00
|
|
|
this._gdmClient = new Gdm.Client();
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2014-06-24 15:17:09 -04:00
|
|
|
this._settings = new Gio.Settings({ schema_id: GdmUtil.LOGIN_SCREEN_SCHEMA });
|
2012-07-17 14:54:07 -04:00
|
|
|
|
|
|
|
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_KEY,
|
2012-07-05 21:11:22 -04:00
|
|
|
Lang.bind(this, this._updateBanner));
|
2012-07-17 14:54:07 -04:00
|
|
|
this._settings.connect('changed::' + GdmUtil.BANNER_MESSAGE_TEXT_KEY,
|
2012-07-05 21:11:22 -04:00
|
|
|
Lang.bind(this, this._updateBanner));
|
2012-10-30 13:26:30 -04:00
|
|
|
this._settings.connect('changed::' + GdmUtil.DISABLE_USER_LIST_KEY,
|
|
|
|
Lang.bind(this, this._updateDisableUserList));
|
2013-03-22 20:27:22 -04:00
|
|
|
this._settings.connect('changed::' + GdmUtil.LOGO_KEY,
|
|
|
|
Lang.bind(this, this._updateLogo));
|
|
|
|
|
|
|
|
this._textureCache = St.TextureCache.get_default();
|
2014-10-09 14:10:12 -04:00
|
|
|
this._updateLogoTextureId = this._textureCache.connect('texture-file-changed',
|
|
|
|
Lang.bind(this, this._updateLogoTexture));
|
2011-09-06 08:37:16 -04:00
|
|
|
|
2013-02-06 16:37:47 -05:00
|
|
|
this._userSelectionBox = new St.BoxLayout({ style_class: 'login-dialog-user-selection-box',
|
2013-08-26 15:47:52 -04:00
|
|
|
x_align: Clutter.ActorAlign.CENTER,
|
|
|
|
y_align: Clutter.ActorAlign.CENTER,
|
2013-07-18 10:13:32 -04:00
|
|
|
vertical: true,
|
|
|
|
visible: false });
|
2013-06-25 12:55:21 -04:00
|
|
|
this.actor.add_child(this._userSelectionBox);
|
2013-02-06 16:37:47 -05:00
|
|
|
|
2012-10-04 12:31:50 -04:00
|
|
|
this._userList = new UserList();
|
2013-02-06 16:37:47 -05:00
|
|
|
this._userSelectionBox.add(this._userList.actor,
|
|
|
|
{ expand: true,
|
|
|
|
x_fill: true,
|
|
|
|
y_fill: true });
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2015-01-22 13:39:46 -05:00
|
|
|
this._authPrompt = new AuthPrompt.AuthPrompt(this._gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN);
|
2013-07-22 11:07:35 -04:00
|
|
|
this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted));
|
2013-07-28 15:55:09 -04:00
|
|
|
this._authPrompt.connect('reset', Lang.bind(this, this._onReset));
|
2013-07-15 17:56:44 -04:00
|
|
|
this._authPrompt.hide();
|
|
|
|
this.actor.add_child(this._authPrompt.actor);
|
2013-06-26 12:36:10 -04:00
|
|
|
|
2011-10-29 12:36:51 -04:00
|
|
|
// 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.
|
2011-08-23 22:12:57 -04:00
|
|
|
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',
|
2013-01-11 14:05:17 -05:00
|
|
|
button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE,
|
2011-08-23 22:12:57 -04:00
|
|
|
can_focus: true,
|
|
|
|
child: notListedLabel,
|
|
|
|
reactive: true,
|
|
|
|
x_align: St.Align.START,
|
|
|
|
x_fill: true });
|
|
|
|
|
2013-08-22 15:12:46 -04:00
|
|
|
this._notListedButton.connect('clicked', Lang.bind(this, this._hideUserListAskForUsernameAndBeginVerification));
|
2013-07-28 17:49:50 -04:00
|
|
|
|
2013-06-26 10:52:02 -04:00
|
|
|
this._notListedButton.hide();
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2013-02-06 16:37:47 -05:00
|
|
|
this._userSelectionBox.add(this._notListedButton,
|
|
|
|
{ expand: false,
|
|
|
|
x_align: St.Align.START,
|
|
|
|
x_fill: true });
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2014-11-11 09:11:01 -05:00
|
|
|
this._bannerView = new St.ScrollView({ style_class: 'login-dialog-banner-view',
|
|
|
|
opacity: 0,
|
|
|
|
vscrollbar_policy: Gtk.PolicyType.AUTOMATIC,
|
|
|
|
hscrollbar_policy: Gtk.PolicyType.NEVER });
|
|
|
|
this.actor.add_child(this._bannerView);
|
|
|
|
|
|
|
|
let bannerBox = new St.BoxLayout({ vertical: true });
|
|
|
|
|
|
|
|
this._bannerView.add_actor(bannerBox);
|
|
|
|
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;
|
|
|
|
bannerBox.add_child(this._bannerLabel);
|
|
|
|
this._updateBanner();
|
|
|
|
|
2013-08-26 15:47:52 -04:00
|
|
|
this._logoBin = new St.Widget({ style_class: 'login-dialog-logo-bin',
|
|
|
|
x_align: Clutter.ActorAlign.CENTER,
|
2014-11-10 14:36:07 -05:00
|
|
|
y_align: Clutter.ActorAlign.END });
|
2013-06-25 12:55:21 -04:00
|
|
|
this.actor.add_child(this._logoBin);
|
2013-03-22 20:27:22 -04:00
|
|
|
this._updateLogo();
|
|
|
|
|
2011-08-23 22:12:57 -04:00
|
|
|
this._userList.connect('activate',
|
|
|
|
Lang.bind(this, function(userList, item) {
|
|
|
|
this._onUserListActivated(item);
|
|
|
|
}));
|
|
|
|
|
2013-06-25 13:35:38 -04:00
|
|
|
|
2013-06-23 23:14:10 -04:00
|
|
|
this._sessionMenuButton = new SessionMenuButton();
|
|
|
|
this._sessionMenuButton.connect('session-activated',
|
2013-06-25 13:35:38 -04:00
|
|
|
Lang.bind(this, function(list, sessionId) {
|
|
|
|
this._greeter.call_select_session_sync (sessionId, null);
|
|
|
|
}));
|
|
|
|
this._sessionMenuButton.actor.opacity = 0;
|
|
|
|
this._sessionMenuButton.actor.show();
|
2013-07-15 17:56:44 -04:00
|
|
|
this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor);
|
2013-06-25 13:35:38 -04:00
|
|
|
|
2014-03-07 10:04:01 -05:00
|
|
|
this._disableUserList = undefined;
|
|
|
|
this._userListLoaded = false;
|
|
|
|
|
2015-02-26 15:40:56 -05:00
|
|
|
this._realmManager = new Realmd.Manager();
|
|
|
|
this._realmSignalId = this._realmManager.connect('login-format-changed',
|
|
|
|
Lang.bind(this, this._showRealmLoginHint));
|
|
|
|
|
2014-03-07 19:35:02 -05:00
|
|
|
LoginManager.getLoginManager().getCurrentSessionProxy(Lang.bind(this, this._gotGreeterSessionProxy));
|
|
|
|
|
2014-03-07 10:04:01 -05:00
|
|
|
// 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
|
2014-10-09 14:10:12 -04:00
|
|
|
this._startupCompleteId = Main.layoutManager.connect('startup-complete',
|
|
|
|
Lang.bind(this, this._updateDisableUserList));
|
2014-03-07 10:04:01 -05:00
|
|
|
},
|
|
|
|
|
2014-11-11 09:11:01 -05:00
|
|
|
_getBannerAllocation: function (dialogBox) {
|
|
|
|
let actorBox = new Clutter.ActorBox();
|
|
|
|
|
|
|
|
let [minWidth, minHeight, natWidth, natHeight] = this._bannerView.get_preferred_size();
|
|
|
|
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
|
|
|
|
2015-03-27 17:19:47 -04:00
|
|
|
actorBox.x1 = Math.floor(centerX - natWidth / 2);
|
2014-11-11 09:11:01 -05:00
|
|
|
actorBox.y1 = dialogBox.y1 + Main.layoutManager.panelBox.height;
|
|
|
|
actorBox.x2 = actorBox.x1 + natWidth;
|
|
|
|
actorBox.y2 = actorBox.y1 + natHeight;
|
|
|
|
|
|
|
|
return actorBox;
|
|
|
|
},
|
|
|
|
|
2014-11-10 14:36:07 -05:00
|
|
|
_getLogoBinAllocation: function (dialogBox) {
|
|
|
|
let actorBox = new Clutter.ActorBox();
|
|
|
|
|
|
|
|
let [minWidth, minHeight, natWidth, natHeight] = this._logoBin.get_preferred_size();
|
|
|
|
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
|
|
|
|
2015-03-27 17:19:47 -04:00
|
|
|
actorBox.x1 = Math.floor(centerX - natWidth / 2);
|
2014-11-10 14:36:07 -05:00
|
|
|
actorBox.y1 = dialogBox.y2 - natHeight;
|
|
|
|
actorBox.x2 = actorBox.x1 + natWidth;
|
|
|
|
actorBox.y2 = actorBox.y1 + natHeight;
|
|
|
|
|
|
|
|
return actorBox;
|
|
|
|
},
|
|
|
|
|
|
|
|
_getCenterActorAllocation: function (dialogBox, actor) {
|
|
|
|
let actorBox = new Clutter.ActorBox();
|
|
|
|
|
|
|
|
let [minWidth, minHeight, natWidth, natHeight] = actor.get_preferred_size();
|
|
|
|
let centerX = dialogBox.x1 + (dialogBox.x2 - dialogBox.x1) / 2;
|
|
|
|
let centerY = dialogBox.y1 + (dialogBox.y2 - dialogBox.y1) / 2;
|
|
|
|
|
2015-07-10 12:58:05 -04:00
|
|
|
natWidth = Math.min(natWidth, dialogBox.x2 - dialogBox.x1);
|
|
|
|
natHeight = Math.min(natHeight, dialogBox.y2 - dialogBox.y1);
|
|
|
|
|
2015-03-27 17:19:47 -04:00
|
|
|
actorBox.x1 = Math.floor(centerX - natWidth / 2);
|
|
|
|
actorBox.y1 = Math.floor(centerY - natHeight / 2);
|
2014-11-10 14:36:07 -05:00
|
|
|
actorBox.x2 = actorBox.x1 + natWidth;
|
|
|
|
actorBox.y2 = actorBox.y1 + natHeight;
|
|
|
|
|
|
|
|
return actorBox;
|
|
|
|
},
|
|
|
|
|
|
|
|
_onAllocate: function (actor, dialogBox, flags) {
|
2014-11-11 09:11:01 -05:00
|
|
|
let dialogWidth = dialogBox.x2 - dialogBox.x1;
|
2014-11-10 14:36:07 -05:00
|
|
|
let dialogHeight = dialogBox.y2 - dialogBox.y1;
|
|
|
|
|
|
|
|
// First find out what space the children require
|
2014-11-11 09:11:01 -05:00
|
|
|
let bannerAllocation = null;
|
|
|
|
let bannerHeight = 0;
|
|
|
|
let bannerWidth = 0;
|
|
|
|
if (this._bannerView.visible) {
|
|
|
|
bannerAllocation = this._getBannerAllocation(dialogBox, this._bannerView);
|
|
|
|
bannerHeight = bannerAllocation.y2 - bannerAllocation.y1;
|
|
|
|
bannerWidth = bannerAllocation.x2 - bannerAllocation.x1;
|
|
|
|
}
|
|
|
|
|
2014-11-10 14:36:07 -05:00
|
|
|
let authPromptAllocation = null;
|
2014-11-11 09:11:01 -05:00
|
|
|
let authPromptHeight = 0;
|
2014-11-11 09:11:01 -05:00
|
|
|
let authPromptWidth = 0;
|
2014-11-11 09:11:01 -05:00
|
|
|
if (this._authPrompt.actor.visible) {
|
2014-11-10 14:36:07 -05:00
|
|
|
authPromptAllocation = this._getCenterActorAllocation(dialogBox, this._authPrompt.actor);
|
2014-11-11 09:11:01 -05:00
|
|
|
authPromptHeight = authPromptAllocation.y2 - authPromptAllocation.y1;
|
2014-11-11 09:11:01 -05:00
|
|
|
authPromptWidth = authPromptAllocation.x2 - authPromptAllocation.x1;
|
2014-11-11 09:11:01 -05:00
|
|
|
}
|
2014-11-10 14:36:07 -05:00
|
|
|
|
|
|
|
let userSelectionAllocation = null;
|
|
|
|
let userSelectionHeight = 0;
|
|
|
|
if (this._userSelectionBox.visible) {
|
|
|
|
userSelectionAllocation = this._getCenterActorAllocation(dialogBox, this._userSelectionBox);
|
|
|
|
userSelectionHeight = userSelectionAllocation.y2 - userSelectionAllocation.y1;
|
|
|
|
}
|
|
|
|
|
|
|
|
let logoAllocation = null;
|
|
|
|
let logoHeight = 0;
|
|
|
|
if (this._logoBin.visible) {
|
|
|
|
logoAllocation = this._getLogoBinAllocation(dialogBox);
|
|
|
|
logoHeight = logoAllocation.y2 - logoAllocation.y1;
|
|
|
|
}
|
|
|
|
|
2014-11-11 09:11:01 -05:00
|
|
|
// Then figure out if we're overly constrained and need to
|
|
|
|
// try a different layout, or if we have what extra space we
|
|
|
|
// can hand out
|
2014-11-11 09:11:01 -05:00
|
|
|
if (bannerAllocation) {
|
2015-06-25 15:39:58 -04:00
|
|
|
let bannerSpace;
|
|
|
|
|
|
|
|
if (authPromptAllocation)
|
|
|
|
bannerSpace = authPromptAllocation.y1 - bannerAllocation.y1;
|
|
|
|
else
|
|
|
|
bannerSpace = 0;
|
|
|
|
|
|
|
|
let leftOverYSpace = bannerSpace - bannerHeight;
|
2014-11-11 09:11:01 -05:00
|
|
|
|
|
|
|
if (leftOverYSpace > 0) {
|
|
|
|
// First figure out how much left over space is up top
|
|
|
|
let leftOverTopSpace = leftOverYSpace / 2;
|
2014-11-10 14:36:07 -05:00
|
|
|
|
2014-11-11 09:11:01 -05:00
|
|
|
// Then, shift the banner into the middle of that extra space
|
2015-03-27 17:19:47 -04:00
|
|
|
let yShift = Math.floor(leftOverTopSpace / 2);
|
2014-11-11 09:11:01 -05:00
|
|
|
|
|
|
|
bannerAllocation.y1 += yShift;
|
|
|
|
bannerAllocation.y2 += yShift;
|
|
|
|
} else {
|
2014-11-11 09:11:01 -05:00
|
|
|
// Then figure out how much space there would be if we switched to a
|
|
|
|
// wide layout with banner on one side and authprompt on the other.
|
|
|
|
let leftOverXSpace = dialogWidth - authPromptWidth;
|
|
|
|
|
|
|
|
// In a wide view, half of the available space goes to the banner,
|
|
|
|
// and the other half goes to the margins.
|
|
|
|
let wideBannerWidth = leftOverXSpace / 2;
|
|
|
|
let wideSpacing = leftOverXSpace - wideBannerWidth;
|
|
|
|
|
|
|
|
// If we do go with a wide layout, we need there to be at least enough
|
|
|
|
// space for the banner and the auth prompt to be the same width,
|
|
|
|
// so it doesn't look unbalanced.
|
|
|
|
if (authPromptWidth > 0 && wideBannerWidth > authPromptWidth) {
|
|
|
|
let centerX = dialogBox.x1 + dialogWidth / 2;
|
|
|
|
let centerY = dialogBox.y1 + dialogHeight / 2;
|
|
|
|
|
|
|
|
// A small portion of the spacing goes down the center of the
|
|
|
|
// screen to help delimit the two columns of the wide view
|
|
|
|
let centerGap = wideSpacing / 8;
|
|
|
|
|
|
|
|
// place the banner along the left edge of the center margin
|
2015-03-27 17:19:47 -04:00
|
|
|
bannerAllocation.x2 = Math.floor(centerX - centerGap / 2);
|
|
|
|
bannerAllocation.x1 = Math.floor(bannerAllocation.x2 - wideBannerWidth);
|
2014-11-11 09:11:01 -05:00
|
|
|
|
|
|
|
// figure out how tall it would like to be and try to accomodate
|
|
|
|
// but don't let it get too close to the logo
|
|
|
|
let [wideMinHeight, wideBannerHeight] = this._bannerView.get_preferred_height(wideBannerWidth);
|
|
|
|
|
|
|
|
let maxWideHeight = dialogHeight - 3 * logoHeight;
|
|
|
|
wideBannerHeight = Math.min(maxWideHeight, wideBannerHeight);
|
2015-03-27 17:19:47 -04:00
|
|
|
bannerAllocation.y1 = Math.floor(centerY - wideBannerHeight / 2);
|
2014-11-11 09:11:01 -05:00
|
|
|
bannerAllocation.y2 = bannerAllocation.y1 + wideBannerHeight;
|
|
|
|
|
|
|
|
// place the auth prompt along the right edge of the center margin
|
2015-03-27 17:19:47 -04:00
|
|
|
authPromptAllocation.x1 = Math.floor(centerX + centerGap / 2);
|
2014-11-11 09:11:01 -05:00
|
|
|
authPromptAllocation.x2 = authPromptAllocation.x1 + authPromptWidth;
|
|
|
|
} else {
|
|
|
|
// If we aren't going to do a wide view, then we need to limit
|
|
|
|
// the height of the banner so it will present scrollbars
|
|
|
|
|
|
|
|
// First figure out how much space there is without the banner
|
|
|
|
leftOverYSpace += bannerHeight;
|
|
|
|
|
|
|
|
// Then figure out how much of that space is up top
|
2015-03-27 17:19:47 -04:00
|
|
|
let availableTopSpace = Math.floor(leftOverYSpace / 2);
|
2014-11-11 09:11:01 -05:00
|
|
|
|
|
|
|
// Then give all of that space to the banner
|
|
|
|
bannerAllocation.y2 = bannerAllocation.y1 + availableTopSpace;
|
|
|
|
}
|
2014-11-11 09:11:01 -05:00
|
|
|
}
|
|
|
|
} else if (userSelectionAllocation) {
|
|
|
|
// Grow the user list to fill the space
|
|
|
|
let leftOverYSpace = dialogHeight - userSelectionHeight - logoHeight;
|
2014-11-10 14:36:07 -05:00
|
|
|
|
2014-11-11 09:11:01 -05:00
|
|
|
if (leftOverYSpace > 0) {
|
2015-03-27 17:19:47 -04:00
|
|
|
let topExpansion = Math.floor(leftOverYSpace / 2);
|
2014-11-10 14:36:07 -05:00
|
|
|
let bottomExpansion = topExpansion;
|
|
|
|
|
|
|
|
userSelectionAllocation.y1 -= topExpansion;
|
|
|
|
userSelectionAllocation.y2 += bottomExpansion;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finally hand out the allocations
|
2014-11-11 09:11:01 -05:00
|
|
|
if (bannerAllocation) {
|
|
|
|
this._bannerView.allocate(bannerAllocation, flags);
|
|
|
|
}
|
|
|
|
|
2014-11-10 14:36:07 -05:00
|
|
|
if (authPromptAllocation)
|
|
|
|
this._authPrompt.actor.allocate(authPromptAllocation, flags);
|
|
|
|
|
|
|
|
if (userSelectionAllocation)
|
|
|
|
this._userSelectionBox.allocate(userSelectionAllocation, flags);
|
|
|
|
|
|
|
|
if (logoAllocation)
|
|
|
|
this._logoBin.allocate(logoAllocation, flags);
|
|
|
|
},
|
|
|
|
|
2014-03-07 10:04:01 -05:00
|
|
|
_ensureUserListLoaded: function() {
|
2014-04-10 13:26:52 -04:00
|
|
|
if (!this._userManager.is_loaded) {
|
2014-01-10 09:27:46 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}));
|
2014-04-10 13:26:52 -04:00
|
|
|
} else {
|
|
|
|
let id = GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList));
|
|
|
|
GLib.Source.set_name_by_id(id, '[gnome-shell] _loadUserList');
|
|
|
|
}
|
2014-03-07 10:04:01 -05:00
|
|
|
},
|
2011-09-06 16:17:08 -04:00
|
|
|
|
2012-10-30 13:26:30 -04:00
|
|
|
_updateDisableUserList: function() {
|
|
|
|
let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY);
|
|
|
|
|
|
|
|
if (disableUserList != this._disableUserList) {
|
|
|
|
this._disableUserList = disableUserList;
|
|
|
|
|
2013-07-28 16:24:31 -04:00
|
|
|
if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
2013-07-28 15:55:09 -04:00
|
|
|
this._authPrompt.reset();
|
2012-10-30 13:26:30 -04:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-07-28 20:55:12 -04:00
|
|
|
_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;
|
|
|
|
},
|
|
|
|
|
2012-07-05 21:11:22 -04:00
|
|
|
_updateBanner: function() {
|
2012-07-17 14:54:07 -04:00
|
|
|
let enabled = this._settings.get_boolean(GdmUtil.BANNER_MESSAGE_KEY);
|
|
|
|
let text = this._settings.get_string(GdmUtil.BANNER_MESSAGE_TEXT_KEY);
|
2012-07-05 21:11:22 -04:00
|
|
|
|
|
|
|
if (enabled && text) {
|
|
|
|
this._bannerLabel.set_text(text);
|
2013-02-04 16:50:46 -05:00
|
|
|
this._bannerLabel.show();
|
2012-07-05 21:11:22 -04:00
|
|
|
} else {
|
2013-02-04 16:50:46 -05:00
|
|
|
this._bannerLabel.hide();
|
2012-07-05 21:11:22 -04:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2014-11-11 09:11:01 -05:00
|
|
|
_fadeInBannerView: function() {
|
2015-01-22 14:00:01 -05:00
|
|
|
this._bannerView.show();
|
2014-11-11 09:11:01 -05:00
|
|
|
Tweener.addTween(this._bannerView,
|
|
|
|
{ opacity: 255,
|
|
|
|
time: _FADE_ANIMATION_TIME,
|
|
|
|
transition: 'easeOutQuad' });
|
|
|
|
},
|
|
|
|
|
|
|
|
_hideBannerView: function() {
|
|
|
|
Tweener.removeTweens(this._bannerView);
|
|
|
|
this._bannerView.opacity = 0;
|
2015-01-22 14:00:01 -05:00
|
|
|
this._bannerView.hide();
|
2014-11-11 09:11:01 -05:00
|
|
|
},
|
|
|
|
|
2014-09-18 20:04:00 -04:00
|
|
|
_updateLogoTexture: function(cache, file) {
|
2014-10-14 22:59:29 -04:00
|
|
|
if (this._logoFile && !this._logoFile.equal(file))
|
2013-03-22 20:27:22 -04:00
|
|
|
return;
|
|
|
|
|
2013-08-26 15:47:52 -04:00
|
|
|
this._logoBin.destroy_all_children();
|
2014-09-18 20:04:00 -04:00
|
|
|
if (this._logoFile) {
|
2014-03-23 00:05:53 -04:00
|
|
|
let scaleFactor = St.ThemeContext.get_for_stage(global.stage).scale_factor;
|
2014-09-18 20:04:00 -04:00
|
|
|
this._logoBin.add_child(this._textureCache.load_file_async(this._logoFile,
|
|
|
|
-1, _LOGO_ICON_HEIGHT,
|
|
|
|
scaleFactor));
|
2014-03-23 00:05:53 -04:00
|
|
|
}
|
2013-03-22 20:27:22 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_updateLogo: function() {
|
|
|
|
let path = this._settings.get_string(GdmUtil.LOGO_KEY);
|
|
|
|
|
2014-09-18 20:04:00 -04:00
|
|
|
this._logoFile = path ? Gio.file_new_for_path(path) : null;
|
|
|
|
this._updateLogoTexture(this._textureCache, this._logoFile);
|
2013-03-22 20:27:22 -04:00
|
|
|
},
|
|
|
|
|
2013-07-22 11:07:35 -04:00
|
|
|
_onPrompted: function() {
|
|
|
|
this._sessionMenuButton.updateSensitivity(true);
|
|
|
|
|
|
|
|
if (this._shouldShowSessionMenuButton())
|
|
|
|
this._authPrompt.setActorInDefaultButtonWell(this._sessionMenuButton.actor);
|
|
|
|
this._showPrompt();
|
|
|
|
},
|
|
|
|
|
2015-01-22 13:39:46 -05:00
|
|
|
_resetGreeterProxy: function() {
|
|
|
|
if (GLib.getenv('GDM_GREETER_TEST') != '1') {
|
|
|
|
if (this._greeter) {
|
|
|
|
this._greeter.run_dispose();
|
|
|
|
}
|
|
|
|
this._greeter = this._gdmClient.get_greeter_sync(null);
|
|
|
|
|
|
|
|
this._defaultSessionChangedId = this._greeter.connect('default-session-name-changed',
|
|
|
|
Lang.bind(this, this._onDefaultSessionChanged));
|
|
|
|
this._sessionOpenedId = this._greeter.connect('session-opened',
|
|
|
|
Lang.bind(this, this._onSessionOpened));
|
|
|
|
this._timedLoginRequestedId = this._greeter.connect('timed-login-requested',
|
|
|
|
Lang.bind(this, this._onTimedLoginRequested));
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2013-07-28 17:49:50 -04:00
|
|
|
_onReset: function(authPrompt, beginRequest) {
|
2015-01-22 13:39:46 -05:00
|
|
|
this._resetGreeterProxy();
|
2013-07-22 11:07:35 -04:00
|
|
|
this._sessionMenuButton.updateSensitivity(true);
|
2013-07-15 17:56:44 -04:00
|
|
|
|
2011-08-23 22:12:57 -04:00
|
|
|
this._user = null;
|
|
|
|
|
2013-08-22 16:18:20 -04:00
|
|
|
if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) {
|
|
|
|
if (!this._disableUserList)
|
|
|
|
this._showUserList();
|
|
|
|
else
|
|
|
|
this._hideUserListAskForUsernameAndBeginVerification();
|
|
|
|
} else {
|
2013-08-22 15:12:46 -04:00
|
|
|
this._hideUserListAndBeginVerification();
|
2013-08-22 16:18:20 -04:00
|
|
|
}
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_onDefaultSessionChanged: function(client, sessionId) {
|
2015-03-18 12:43:58 -04:00
|
|
|
this._sessionMenuButton.setActiveSession(sessionId);
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
2013-06-25 13:35:38 -04:00
|
|
|
_shouldShowSessionMenuButton: function() {
|
2013-08-29 11:46:56 -04:00
|
|
|
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING &&
|
|
|
|
this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFICATION_FAILED)
|
2013-06-25 13:35:38 -04:00
|
|
|
return false;
|
|
|
|
|
2013-08-22 16:18:20 -04:00
|
|
|
if (this._user && this._user.is_loaded && this._user.is_logged_in())
|
2013-06-25 13:35:38 -04:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
|
2013-07-22 11:07:35 -04:00
|
|
|
_showPrompt: function() {
|
|
|
|
if (this._authPrompt.actor.visible)
|
|
|
|
return;
|
2013-07-15 17:56:44 -04:00
|
|
|
this._authPrompt.actor.opacity = 0;
|
|
|
|
this._authPrompt.actor.show();
|
|
|
|
Tweener.addTween(this._authPrompt.actor,
|
2013-02-06 14:18:26 -05:00
|
|
|
{ opacity: 255,
|
|
|
|
time: _FADE_ANIMATION_TIME,
|
|
|
|
transition: 'easeOutQuad' });
|
2014-11-11 09:11:01 -05:00
|
|
|
this._fadeInBannerView();
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
2013-04-19 03:07:04 -04:00
|
|
|
_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
|
2013-10-02 13:09:14 -04:00
|
|
|
this._authPrompt.setMessage(_("(e.g., user or %s)").format(hint), GdmUtil.MessageType.HINT);
|
2013-04-19 03:07:04 -04:00
|
|
|
},
|
|
|
|
|
2013-07-28 17:49:50 -04:00
|
|
|
_askForUsernameAndBeginVerification: function() {
|
2013-07-15 17:56:44 -04:00
|
|
|
this._authPrompt.setPasswordChar('');
|
|
|
|
this._authPrompt.setQuestion(_("Username: "));
|
2012-10-30 15:06:44 -04:00
|
|
|
|
2015-02-26 15:40:56 -05:00
|
|
|
this._showRealmLoginHint(this._realmManager.loginFormat);
|
|
|
|
|
|
|
|
if (this._nextSignalId)
|
|
|
|
this._authPrompt.disconnect(this._nextSignalId);
|
|
|
|
this._nextSignalId = this._authPrompt.connect('next',
|
|
|
|
Lang.bind(this, function() {
|
|
|
|
this._authPrompt.disconnect(this._nextSignalId);
|
|
|
|
this._nextSignalId = 0;
|
|
|
|
this._authPrompt.updateSensitivity(false);
|
|
|
|
let answer = this._authPrompt.getAnswer();
|
|
|
|
this._user = this._userManager.get_user(answer);
|
|
|
|
this._authPrompt.clear();
|
|
|
|
this._authPrompt.startSpinning();
|
|
|
|
this._authPrompt.begin({ userName: answer });
|
|
|
|
this._updateCancelButton();
|
|
|
|
}));
|
2013-07-28 20:55:12 -04:00
|
|
|
this._updateCancelButton();
|
2014-10-07 14:30:34 -04:00
|
|
|
|
|
|
|
this._authPrompt.updateSensitivity(true);
|
2013-07-22 11:07:35 -04:00
|
|
|
this._showPrompt();
|
2012-10-30 15:06:44 -04:00
|
|
|
},
|
|
|
|
|
2014-03-07 19:35:02 -05:00
|
|
|
_loginScreenSessionActivated: function() {
|
2015-08-04 09:53:04 -04:00
|
|
|
if (this.actor.opacity == 255 && this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
2014-03-07 19:35:02 -05:00
|
|
|
return;
|
|
|
|
|
|
|
|
Tweener.addTween(this.actor,
|
|
|
|
{ opacity: 255,
|
|
|
|
time: _FADE_ANIMATION_TIME,
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
onUpdateScope: this,
|
|
|
|
onComplete: function() {
|
2015-08-04 09:53:04 -04:00
|
|
|
if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.NOT_VERIFYING)
|
|
|
|
this._authPrompt.reset();
|
2014-03-07 19:35:02 -05:00
|
|
|
},
|
|
|
|
onCompleteScope: this });
|
|
|
|
},
|
|
|
|
|
|
|
|
_gotGreeterSessionProxy: function(proxy) {
|
2014-10-09 14:10:12 -04:00
|
|
|
this._greeterSessionProxy = proxy;
|
|
|
|
this._greeterSessionProxyChangedId =
|
|
|
|
proxy.connect('g-properties-changed', Lang.bind(this, function() {
|
|
|
|
if (proxy.Active)
|
|
|
|
this._loginScreenSessionActivated();
|
|
|
|
}));
|
2014-03-07 19:35:02 -05:00
|
|
|
},
|
|
|
|
|
2013-03-18 00:59:56 -04:00
|
|
|
_startSession: function(serviceName) {
|
2013-06-25 12:55:21 -04:00
|
|
|
Tweener.addTween(this.actor,
|
2013-02-06 15:18:22 -05:00
|
|
|
{ opacity: 0,
|
|
|
|
time: _FADE_ANIMATION_TIME,
|
|
|
|
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)
|
2013-06-25 12:55:21 -04:00
|
|
|
children[i].opacity = this.actor.opacity;
|
2013-02-06 15:18:22 -05:00
|
|
|
}
|
|
|
|
},
|
|
|
|
onUpdateScope: this,
|
|
|
|
onComplete: function() {
|
2015-10-20 16:50:15 -04:00
|
|
|
this._greeter.call_start_session_when_ready_sync(serviceName, true, null);
|
2013-02-06 15:18:22 -05:00
|
|
|
},
|
|
|
|
onCompleteScope: this });
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
2013-03-18 00:59:56 -04:00
|
|
|
_onSessionOpened: function(client, serviceName) {
|
2013-07-22 11:07:35 -04:00
|
|
|
this._authPrompt.finish(Lang.bind(this, function() {
|
2013-03-18 00:59:56 -04:00
|
|
|
this._startSession(serviceName);
|
2013-07-22 11:07:35 -04:00
|
|
|
}));
|
2013-03-18 00:59:56 -04:00
|
|
|
},
|
|
|
|
|
2011-08-23 22:12:57 -04:00
|
|
|
_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();
|
2012-07-13 18:43:58 -04:00
|
|
|
return this._timedLoginItem.showTimedLoginIndicator(this._timedLoginAnimationTime);
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_blockTimedLoginUntilIdle: function() {
|
|
|
|
// This blocks timed login from starting until a few
|
|
|
|
// seconds after the user stops interacting with the
|
|
|
|
// login screen.
|
|
|
|
//
|
|
|
|
// We skip this step if the timed login delay is very
|
|
|
|
// short.
|
|
|
|
if ((this._timedLoginDelay - _TIMED_LOGIN_IDLE_THRESHOLD) <= 0)
|
|
|
|
return null;
|
|
|
|
|
|
|
|
let hold = new Batch.Hold();
|
|
|
|
|
|
|
|
this._timedLoginIdleTimeOutId = Mainloop.timeout_add_seconds(_TIMED_LOGIN_IDLE_THRESHOLD,
|
|
|
|
function() {
|
|
|
|
this._timedLoginAnimationTime -= _TIMED_LOGIN_IDLE_THRESHOLD;
|
|
|
|
hold.release();
|
2013-11-28 19:45:39 -05:00
|
|
|
return GLib.SOURCE_REMOVE;
|
2011-08-23 22:12:57 -04:00
|
|
|
});
|
2014-04-10 13:26:52 -04:00
|
|
|
GLib.Source.set_name_by_id(this._timedLoginIdleTimeOutId, '[gnome-shell] this._timedLoginAnimationTime');
|
2011-08-23 22:12:57 -04:00
|
|
|
return hold;
|
|
|
|
},
|
|
|
|
|
|
|
|
_startTimedLogin: function(userName, delay) {
|
|
|
|
this._timedLoginItem = null;
|
|
|
|
this._timedLoginDelay = delay;
|
|
|
|
this._timedLoginAnimationTime = delay;
|
|
|
|
|
|
|
|
let tasks = [function() {
|
|
|
|
return this._waitForItemForUser(userName);
|
|
|
|
},
|
|
|
|
|
|
|
|
function() {
|
|
|
|
this._timedLoginItem = this._userList.getItemFromUserName(userName);
|
|
|
|
},
|
|
|
|
|
|
|
|
function() {
|
|
|
|
// If we're just starting out, start on the right
|
|
|
|
// item.
|
2013-03-05 01:51:28 -05:00
|
|
|
if (!this._userManager.is_loaded) {
|
2011-08-23 22:12:57 -04:00
|
|
|
this._userList.jumpToItem(this._timedLoginItem);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
this._blockTimedLoginUntilIdle,
|
|
|
|
|
|
|
|
function() {
|
|
|
|
this._userList.scrollToItem(this._timedLoginItem);
|
|
|
|
},
|
|
|
|
|
|
|
|
this._showTimedLoginAnimation,
|
|
|
|
|
|
|
|
function() {
|
|
|
|
this._timedLoginBatch = null;
|
2012-05-19 19:19:25 -04:00
|
|
|
this._greeter.call_begin_auto_login_sync(userName, null);
|
2011-08-23 22:12:57 -04:00
|
|
|
}];
|
|
|
|
|
|
|
|
this._timedLoginBatch = new Batch.ConsecutiveBatch(this, tasks);
|
|
|
|
|
|
|
|
return this._timedLoginBatch.run();
|
|
|
|
},
|
|
|
|
|
|
|
|
_resetTimedLogin: function() {
|
|
|
|
if (this._timedLoginBatch) {
|
|
|
|
this._timedLoginBatch.cancel();
|
|
|
|
this._timedLoginBatch = null;
|
|
|
|
}
|
|
|
|
|
2012-07-13 18:43:58 -04:00
|
|
|
if (this._timedLoginItem)
|
|
|
|
this._timedLoginItem.hideTimedLoginIndicator();
|
|
|
|
|
2011-08-23 22:12:57 -04:00
|
|
|
let userName = this._timedLoginItem.user.get_user_name();
|
|
|
|
|
|
|
|
if (userName)
|
|
|
|
this._startTimedLogin(userName, this._timedLoginDelay);
|
|
|
|
},
|
|
|
|
|
|
|
|
_onTimedLoginRequested: function(client, userName, seconds) {
|
|
|
|
this._startTimedLogin(userName, seconds);
|
|
|
|
|
|
|
|
global.stage.connect('captured-event',
|
|
|
|
Lang.bind(this, function(actor, event) {
|
|
|
|
if (this._timedLoginDelay == undefined)
|
2013-11-29 13:17:34 -05:00
|
|
|
return Clutter.EVENT_PROPAGATE;
|
2011-08-23 22:12:57 -04:00
|
|
|
|
|
|
|
if (event.type() == Clutter.EventType.KEY_PRESS ||
|
|
|
|
event.type() == Clutter.EventType.BUTTON_PRESS) {
|
|
|
|
if (this._timedLoginBatch) {
|
|
|
|
this._timedLoginBatch.cancel();
|
|
|
|
this._timedLoginBatch = null;
|
|
|
|
}
|
|
|
|
} else if (event.type() == Clutter.EventType.KEY_RELEASE ||
|
|
|
|
event.type() == Clutter.EventType.BUTTON_RELEASE) {
|
|
|
|
this._resetTimedLogin();
|
|
|
|
}
|
|
|
|
|
2013-11-29 13:17:34 -05:00
|
|
|
return Clutter.EVENT_PROPAGATE;
|
2011-08-23 22:12:57 -04:00
|
|
|
}));
|
|
|
|
},
|
|
|
|
|
2013-02-06 16:37:47 -05:00
|
|
|
_setUserListExpanded: function(expanded) {
|
|
|
|
this._userList.updateStyle(expanded);
|
|
|
|
this._userSelectionBox.visible = expanded;
|
|
|
|
},
|
|
|
|
|
2013-07-28 17:49:50 -04:00
|
|
|
_hideUserList: function() {
|
2013-02-06 16:37:47 -05:00
|
|
|
this._setUserListExpanded(false);
|
2013-07-18 10:13:32 -04:00
|
|
|
if (this._userSelectionBox.visible)
|
|
|
|
GdmUtil.cloneAndFadeOutActor(this._userSelectionBox);
|
2013-07-28 17:49:50 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_hideUserListAskForUsernameAndBeginVerification: function() {
|
|
|
|
this._hideUserList();
|
|
|
|
this._askForUsernameAndBeginVerification();
|
|
|
|
},
|
|
|
|
|
|
|
|
_hideUserListAndBeginVerification: function() {
|
|
|
|
this._hideUserList();
|
|
|
|
this._authPrompt.begin();
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
2012-10-30 13:26:30 -04:00
|
|
|
_showUserList: function() {
|
2014-03-07 10:04:01 -05:00
|
|
|
this._ensureUserListLoaded();
|
2013-07-15 17:56:44 -04:00
|
|
|
this._authPrompt.hide();
|
2014-11-11 09:11:01 -05:00
|
|
|
this._hideBannerView();
|
2013-07-15 17:56:44 -04:00
|
|
|
this._sessionMenuButton.close();
|
2013-02-06 16:37:47 -05:00
|
|
|
this._setUserListExpanded(true);
|
2013-06-26 10:52:02 -04:00
|
|
|
this._notListedButton.show();
|
2013-02-04 16:50:46 -05:00
|
|
|
this._userList.actor.grab_key_focus();
|
2012-05-19 19:19:25 -04:00
|
|
|
},
|
|
|
|
|
2013-02-06 14:18:26 -05:00
|
|
|
_beginVerificationForItem: function(item) {
|
2013-07-15 17:56:44 -04:00
|
|
|
this._authPrompt.setUser(item.user);
|
2013-02-06 16:17:27 -05:00
|
|
|
|
2013-07-22 11:07:35 -04:00
|
|
|
let userName = item.user.get_user_name();
|
|
|
|
let hold = new Batch.Hold();
|
|
|
|
|
|
|
|
this._authPrompt.begin({ userName: userName,
|
|
|
|
hold: hold });
|
|
|
|
return hold;
|
2013-02-06 14:18:26 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
_onUserListActivated: function(activatedItem) {
|
2011-08-23 22:12:57 -04:00
|
|
|
this._user = activatedItem.user;
|
2013-02-06 14:18:26 -05:00
|
|
|
|
2013-07-28 20:55:12 -04:00
|
|
|
this._updateCancelButton();
|
|
|
|
|
2015-03-16 07:38:04 -04:00
|
|
|
let batch = new Batch.ConcurrentBatch(this, [GdmUtil.cloneAndFadeOutActor(this._userSelectionBox),
|
2013-02-06 14:18:26 -05:00
|
|
|
this._beginVerificationForItem(activatedItem)]);
|
|
|
|
batch.run();
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_onDestroy: function() {
|
|
|
|
if (this._userManagerLoadedId) {
|
|
|
|
this._userManager.disconnect(this._userManagerLoadedId);
|
|
|
|
this._userManagerLoadedId = 0;
|
|
|
|
}
|
2014-10-09 14:10:12 -04:00
|
|
|
if (this._userAddedId) {
|
|
|
|
this._userManager.disconnect(this._userAddedId);
|
|
|
|
this._userAddedId = 0;
|
|
|
|
}
|
|
|
|
if (this._userRemovedId) {
|
|
|
|
this._userManager.disconnect(this._userRemovedId);
|
|
|
|
this._userRemovedId = 0;
|
|
|
|
}
|
2015-11-23 19:24:19 -05:00
|
|
|
if (this._userChangedId) {
|
|
|
|
this._userManager.disconnect(this._userChangedId);
|
|
|
|
this._userChangedId = 0;
|
|
|
|
}
|
2014-10-09 14:10:12 -04:00
|
|
|
this._textureCache.disconnect(this._updateLogoTextureId);
|
|
|
|
Main.layoutManager.disconnect(this._startupCompleteId);
|
|
|
|
if (this._settings) {
|
|
|
|
this._settings.run_dispose();
|
|
|
|
this._settings = null;
|
|
|
|
}
|
|
|
|
if (this._greeter) {
|
|
|
|
this._greeter.disconnect(this._defaultSessionChangedId);
|
|
|
|
this._greeter.disconnect(this._sessionOpenedId);
|
|
|
|
this._greeter.disconnect(this._timedLoginRequestedId);
|
|
|
|
this._greeter = null;
|
|
|
|
}
|
|
|
|
if (this._greeterSessionProxy) {
|
|
|
|
this._greeterSessionProxy.disconnect(this._greeterSessionProxyChangedId);
|
|
|
|
this._greeterSessionProxy = null;
|
|
|
|
}
|
2015-02-26 15:40:56 -05:00
|
|
|
if (this._realmManager) {
|
|
|
|
this._realmManager.disconnect(this._realmSignalId);
|
|
|
|
this._realmSignalId = 0;
|
|
|
|
this._realmManager.release();
|
|
|
|
this._realmManager = null;
|
|
|
|
}
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_loadUserList: function() {
|
2014-03-07 10:04:01 -05:00
|
|
|
if (this._userListLoaded)
|
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
|
|
|
|
this._userListLoaded = true;
|
|
|
|
|
2011-08-23 22:12:57 -04:00
|
|
|
let users = this._userManager.list_users();
|
|
|
|
|
|
|
|
for (let i = 0; i < users.length; i++) {
|
|
|
|
this._userList.addUser(users[i]);
|
|
|
|
}
|
|
|
|
|
2014-10-09 14:10:12 -04:00
|
|
|
this._userAddedId = this._userManager.connect('user-added',
|
|
|
|
Lang.bind(this, function(userManager, user) {
|
|
|
|
this._userList.addUser(user);
|
|
|
|
}));
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2014-10-09 14:10:12 -04:00
|
|
|
this._userRemovedId = this._userManager.connect('user-removed',
|
|
|
|
Lang.bind(this, function(userManager, user) {
|
|
|
|
this._userList.removeUser(user);
|
|
|
|
}));
|
2014-03-07 10:16:20 -05:00
|
|
|
|
2015-11-23 19:24:19 -05:00
|
|
|
this._userChangedId = this._userManager.connect('user-changed',
|
|
|
|
Lang.bind(this, function(userManager, user) {
|
|
|
|
if (this._userList.containsUser(user) && user.locked)
|
|
|
|
this._userList.removeUser(user);
|
|
|
|
else if (!this._userList.containsUser(user) && !user.locked)
|
|
|
|
this._userList.addUser(user);
|
|
|
|
}));
|
|
|
|
|
2014-03-07 10:16:20 -05:00
|
|
|
return GLib.SOURCE_REMOVE;
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
2013-06-25 12:55:21 -04:00
|
|
|
open: function() {
|
|
|
|
Main.ctrlAltTabManager.addGroup(this.actor,
|
2011-08-23 22:12:57 -04:00
|
|
|
_("Login Window"),
|
2012-11-10 19:09:09 -05:00
|
|
|
'dialog-password-symbolic',
|
2011-08-23 22:12:57 -04:00
|
|
|
{ sortGroup: CtrlAltTab.SortGroup.MIDDLE });
|
2013-06-25 12:55:21 -04:00
|
|
|
this._userList.actor.grab_key_focus();
|
|
|
|
this.actor.show();
|
2013-08-26 18:04:09 -04:00
|
|
|
this.actor.opacity = 0;
|
|
|
|
|
2014-12-11 09:35:40 -05:00
|
|
|
Main.pushModal(this.actor, { actionMode: Shell.ActionMode.LOGIN_SCREEN });
|
2014-07-27 08:18:51 -04:00
|
|
|
|
2013-08-26 18:04:09 -04:00
|
|
|
Tweener.addTween(this.actor,
|
|
|
|
{ opacity: 255,
|
|
|
|
time: 1,
|
|
|
|
transition: 'easeInQuad' });
|
2011-08-23 22:12:57 -04:00
|
|
|
|
2013-06-25 12:55:21 -04:00
|
|
|
return true;
|
2011-08-23 22:12:57 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
close: function() {
|
2014-07-27 08:18:51 -04:00
|
|
|
Main.popModal(this.actor);
|
2014-07-27 08:12:27 -04:00
|
|
|
Main.ctrlAltTabManager.removeGroup(this.actor);
|
2013-03-05 00:55:54 -05:00
|
|
|
},
|
|
|
|
|
2013-11-26 14:52:24 -05:00
|
|
|
cancel: function() {
|
|
|
|
this._authPrompt.cancel();
|
|
|
|
},
|
|
|
|
|
2013-03-05 00:55:54 -05:00
|
|
|
addCharacter: function(unichar) {
|
2013-07-15 17:56:44 -04:00
|
|
|
this._authPrompt.addCharacter(unichar);
|
2013-03-05 00:55:54 -05:00
|
|
|
},
|
2013-08-26 18:02:04 -04:00
|
|
|
|
|
|
|
finish: function(onComplete) {
|
|
|
|
this._authPrompt.finish(onComplete);
|
|
|
|
},
|
2011-11-20 10:32:59 -05:00
|
|
|
});
|
2013-06-25 12:55:21 -04:00
|
|
|
Signals.addSignalMethods(LoginDialog.prototype);
|