2011-09-28 09:16:26 -04:00
|
|
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
2009-11-10 12:13:58 -05:00
|
|
|
|
2011-05-10 10:13:05 -04:00
|
|
|
const AccountsService = imports.gi.AccountsService;
|
2013-08-23 11:09:51 -04:00
|
|
|
const Clutter = imports.gi.Clutter;
|
2012-05-19 19:19:25 -04:00
|
|
|
const Gdm = imports.gi.Gdm;
|
2011-03-21 08:51:46 -04:00
|
|
|
const Gio = imports.gi.Gio;
|
2009-11-10 12:13:58 -05:00
|
|
|
const GLib = imports.gi.GLib;
|
|
|
|
const Lang = imports.lang;
|
2016-04-20 14:26:49 -04:00
|
|
|
const Meta = imports.gi.Meta;
|
2013-06-11 17:17:09 -04:00
|
|
|
const Shell = imports.gi.Shell;
|
2009-11-10 12:13:58 -05:00
|
|
|
const St = imports.gi.St;
|
|
|
|
|
2012-09-18 23:02:15 -04:00
|
|
|
const BoxPointer = imports.ui.boxpointer;
|
2010-04-29 13:13:20 -04:00
|
|
|
const GnomeSession = imports.misc.gnomeSession;
|
2012-10-19 11:41:10 -04:00
|
|
|
const LoginManager = imports.misc.loginManager;
|
2010-06-03 19:21:08 -04:00
|
|
|
const Main = imports.ui.main;
|
2010-06-22 17:02:26 -04:00
|
|
|
const PanelMenu = imports.ui.panelMenu;
|
2010-05-20 11:18:46 -04:00
|
|
|
const PopupMenu = imports.ui.popupMenu;
|
2009-11-10 12:13:58 -05:00
|
|
|
|
2011-03-21 08:51:46 -04:00
|
|
|
const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
|
2013-10-31 23:33:10 -04:00
|
|
|
const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
|
2011-03-21 08:51:46 -04:00
|
|
|
const DISABLE_USER_SWITCH_KEY = 'disable-user-switching';
|
|
|
|
const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen';
|
|
|
|
const DISABLE_LOG_OUT_KEY = 'disable-log-out';
|
2013-10-31 23:33:10 -04:00
|
|
|
const DISABLE_RESTART_KEY = 'disable-restart-buttons';
|
2012-10-29 00:27:18 -04:00
|
|
|
const ALWAYS_SHOW_LOG_OUT_KEY = 'always-show-log-out';
|
2011-03-21 08:51:46 -04:00
|
|
|
|
2015-03-05 09:46:57 -05:00
|
|
|
const SENSOR_BUS_NAME = 'net.hadess.SensorProxy';
|
|
|
|
const SENSOR_OBJECT_PATH = '/net/hadess/SensorProxy';
|
|
|
|
|
|
|
|
const SensorProxyInterface = '<node> \
|
|
|
|
<interface name="net.hadess.SensorProxy"> \
|
|
|
|
<property name="HasAccelerometer" type="b" access="read"/> \
|
|
|
|
</interface> \
|
|
|
|
</node>';
|
|
|
|
|
|
|
|
const SensorProxy = Gio.DBusProxy.makeProxyWrapper(SensorProxyInterface);
|
|
|
|
|
2017-07-18 13:41:25 -04:00
|
|
|
var AltSwitcher = new Lang.Class({
|
2013-08-23 11:09:51 -04:00
|
|
|
Name: 'AltSwitcher',
|
|
|
|
|
|
|
|
_init: function(standard, alternate) {
|
|
|
|
this._standard = standard;
|
|
|
|
this._standard.connect('notify::visible', Lang.bind(this, this._sync));
|
2017-06-16 11:08:07 -04:00
|
|
|
if (this._standard instanceof St.Button)
|
|
|
|
this._standard.connect('clicked',
|
|
|
|
() => { this._clickAction.release(); });
|
2013-08-23 11:09:51 -04:00
|
|
|
|
|
|
|
this._alternate = alternate;
|
|
|
|
this._alternate.connect('notify::visible', Lang.bind(this, this._sync));
|
2017-06-16 11:08:07 -04:00
|
|
|
if (this._alternate instanceof St.Button)
|
|
|
|
this._alternate.connect('clicked',
|
|
|
|
() => { this._clickAction.release(); });
|
2013-08-23 11:09:51 -04:00
|
|
|
|
|
|
|
this._capturedEventId = global.stage.connect('captured-event', Lang.bind(this, this._onCapturedEvent));
|
|
|
|
|
2015-03-02 06:14:54 -05:00
|
|
|
this._flipped = false;
|
|
|
|
|
|
|
|
this._clickAction = new Clutter.ClickAction();
|
|
|
|
this._clickAction.connect('long-press', Lang.bind(this, this._onLongPress));
|
|
|
|
|
2013-08-23 11:09:51 -04:00
|
|
|
this.actor = new St.Bin();
|
|
|
|
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
|
2015-03-02 06:14:54 -05:00
|
|
|
this.actor.connect('notify::mapped', () => { this._flipped = false; });
|
2013-08-23 11:09:51 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_sync: function() {
|
|
|
|
let childToShow = null;
|
|
|
|
|
|
|
|
if (this._standard.visible && this._alternate.visible) {
|
|
|
|
let [x, y, mods] = global.get_pointer();
|
|
|
|
let altPressed = (mods & Clutter.ModifierType.MOD1_MASK) != 0;
|
2015-03-02 06:14:54 -05:00
|
|
|
if (this._flipped)
|
|
|
|
childToShow = altPressed ? this._standard : this._alternate;
|
|
|
|
else
|
|
|
|
childToShow = altPressed ? this._alternate : this._standard;
|
2013-08-23 11:09:51 -04:00
|
|
|
} else if (this._standard.visible) {
|
|
|
|
childToShow = this._standard;
|
|
|
|
} else if (this._alternate.visible) {
|
|
|
|
childToShow = this._alternate;
|
|
|
|
}
|
|
|
|
|
2015-03-02 06:14:54 -05:00
|
|
|
let childShown = this.actor.get_child();
|
|
|
|
if (childShown != childToShow) {
|
|
|
|
if (childShown) {
|
|
|
|
if (childShown.fake_release)
|
|
|
|
childShown.fake_release();
|
|
|
|
childShown.remove_action(this._clickAction);
|
|
|
|
}
|
|
|
|
childToShow.add_action(this._clickAction);
|
|
|
|
|
2014-04-26 15:48:46 -04:00
|
|
|
let hasFocus = this.actor.contains(global.stage.get_key_focus());
|
2013-08-23 11:09:51 -04:00
|
|
|
this.actor.set_child(childToShow);
|
2014-04-26 15:48:46 -04:00
|
|
|
if (hasFocus)
|
|
|
|
childToShow.grab_key_focus();
|
2013-08-23 11:09:51 -04:00
|
|
|
|
|
|
|
// The actors might respond to hover, so
|
|
|
|
// sync the pointer to make sure they update.
|
|
|
|
global.sync_pointer();
|
|
|
|
}
|
2013-08-26 15:21:23 -04:00
|
|
|
|
|
|
|
this.actor.visible = (childToShow != null);
|
2013-08-23 11:09:51 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_onDestroy: function() {
|
|
|
|
if (this._capturedEventId > 0) {
|
|
|
|
global.stage.disconnect(this._capturedEventId);
|
|
|
|
this._capturedEventId = 0;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
_onCapturedEvent: function(actor, event) {
|
|
|
|
let type = event.type();
|
|
|
|
if (type == Clutter.EventType.KEY_PRESS || type == Clutter.EventType.KEY_RELEASE) {
|
|
|
|
let key = event.get_key_symbol();
|
|
|
|
if (key == Clutter.KEY_Alt_L || key == Clutter.KEY_Alt_R)
|
|
|
|
this._sync();
|
|
|
|
}
|
|
|
|
|
2013-11-29 13:17:34 -05:00
|
|
|
return Clutter.EVENT_PROPAGATE;
|
2013-08-23 11:09:51 -04:00
|
|
|
},
|
2015-03-02 06:14:54 -05:00
|
|
|
|
|
|
|
_onLongPress: function(action, actor, state) {
|
|
|
|
if (state == Clutter.LongPressState.QUERY ||
|
|
|
|
state == Clutter.LongPressState.CANCEL)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
this._flipped = !this._flipped;
|
|
|
|
this._sync();
|
|
|
|
return true;
|
|
|
|
}
|
2013-08-23 11:09:51 -04:00
|
|
|
});
|
|
|
|
|
2017-07-18 13:41:25 -04:00
|
|
|
var Indicator = new Lang.Class({
|
2013-05-22 14:46:47 -04:00
|
|
|
Name: 'SystemIndicator',
|
2013-06-06 17:27:25 -04:00
|
|
|
Extends: PanelMenu.SystemIndicator,
|
2010-05-10 09:46:54 -04:00
|
|
|
|
2009-11-10 12:13:58 -05:00
|
|
|
_init: function() {
|
2013-06-06 17:27:25 -04:00
|
|
|
this.parent();
|
|
|
|
|
2014-06-24 15:17:09 -04:00
|
|
|
this._loginScreenSettings = new Gio.Settings({ schema_id: LOGIN_SCREEN_SCHEMA });
|
|
|
|
this._lockdownSettings = new Gio.Settings({ schema_id: LOCKDOWN_SCHEMA });
|
|
|
|
this._orientationSettings = new Gio.Settings({ schema_id: 'org.gnome.settings-daemon.peripherals.touchscreen' });
|
2011-03-21 08:51:46 -04:00
|
|
|
|
2011-03-12 15:34:01 -05:00
|
|
|
this._session = new GnomeSession.SessionManager();
|
2013-08-23 11:09:51 -04:00
|
|
|
this._loginManager = LoginManager.getLoginManager();
|
2016-04-20 14:26:49 -04:00
|
|
|
this._monitorManager = Meta.MonitorManager.get();
|
2011-06-03 18:10:55 -04:00
|
|
|
this._haveShutdown = true;
|
2013-08-23 11:09:51 -04:00
|
|
|
this._haveSuspend = true;
|
2009-11-10 12:13:58 -05:00
|
|
|
|
2013-04-23 17:33:54 -04:00
|
|
|
this._userManager = AccountsService.UserManager.get_default();
|
|
|
|
this._user = this._userManager.get_user(GLib.get_user_name());
|
2013-06-11 15:25:32 -04:00
|
|
|
|
|
|
|
this._createSubMenu();
|
|
|
|
|
2011-05-10 10:13:05 -04:00
|
|
|
this._userManager.connect('notify::is-loaded',
|
2012-05-10 07:16:15 -04:00
|
|
|
Lang.bind(this, this._updateMultiUser));
|
2011-10-18 14:57:24 -04:00
|
|
|
this._userManager.connect('notify::has-multiple-users',
|
2012-05-10 07:16:15 -04:00
|
|
|
Lang.bind(this, this._updateMultiUser));
|
2011-05-10 10:13:05 -04:00
|
|
|
this._userManager.connect('user-added',
|
2012-05-10 07:16:15 -04:00
|
|
|
Lang.bind(this, this._updateMultiUser));
|
2011-05-10 10:13:05 -04:00
|
|
|
this._userManager.connect('user-removed',
|
2012-05-10 07:16:15 -04:00
|
|
|
Lang.bind(this, this._updateMultiUser));
|
2011-03-21 08:51:46 -04:00
|
|
|
this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY,
|
2013-06-11 15:25:32 -04:00
|
|
|
Lang.bind(this, this._updateMultiUser));
|
2011-03-21 08:51:46 -04:00
|
|
|
this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
|
2013-06-11 15:25:32 -04:00
|
|
|
Lang.bind(this, this._updateMultiUser));
|
2011-03-21 08:51:46 -04:00
|
|
|
this._lockdownSettings.connect('changed::' + DISABLE_LOCK_SCREEN_KEY,
|
|
|
|
Lang.bind(this, this._updateLockScreen));
|
2013-01-30 09:19:54 -05:00
|
|
|
global.settings.connect('changed::' + ALWAYS_SHOW_LOG_OUT_KEY,
|
2013-06-11 15:25:32 -04:00
|
|
|
Lang.bind(this, this._updateMultiUser));
|
2011-03-21 08:51:46 -04:00
|
|
|
this._updateSwitchUser();
|
2013-06-11 15:25:32 -04:00
|
|
|
this._updateMultiUser();
|
2015-03-20 15:57:30 -04:00
|
|
|
this._updateLockScreen();
|
2011-02-04 18:37:54 -05:00
|
|
|
|
2011-06-03 18:10:55 -04:00
|
|
|
// Whether shutdown is available or not depends on both lockdown
|
|
|
|
// settings (disable-log-out) and Polkit policy - the latter doesn't
|
|
|
|
// notify, so we update the menu item each time the menu opens or
|
|
|
|
// the lockdown setting changes, which should be close enough.
|
|
|
|
this.menu.connect('open-state-changed', Lang.bind(this,
|
|
|
|
function(menu, open) {
|
2012-10-19 11:41:10 -04:00
|
|
|
if (!open)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this._updateHaveShutdown();
|
2013-08-23 11:09:51 -04:00
|
|
|
this._updateHaveSuspend();
|
2011-06-03 18:10:55 -04:00
|
|
|
}));
|
|
|
|
this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY,
|
|
|
|
Lang.bind(this, this._updateHaveShutdown));
|
|
|
|
|
2013-07-17 02:33:09 -04:00
|
|
|
this._orientationSettings.connect('changed::orientation-lock',
|
|
|
|
Lang.bind(this, this._updateOrientationLock));
|
2016-04-20 14:26:49 -04:00
|
|
|
Main.layoutManager.connect('monitors-changed',
|
|
|
|
Lang.bind(this, this._updateOrientationLock));
|
2015-03-05 09:46:57 -05:00
|
|
|
Gio.DBus.system.watch_name(SENSOR_BUS_NAME,
|
|
|
|
Gio.BusNameWatcherFlags.NONE,
|
|
|
|
Lang.bind(this, this._sensorProxyAppeared),
|
|
|
|
Lang.bind(this, function() {
|
|
|
|
this._sensorProxy = null;
|
|
|
|
this._updateOrientationLock();
|
|
|
|
}));
|
2013-07-17 02:33:09 -04:00
|
|
|
this._updateOrientationLock();
|
|
|
|
|
2012-09-01 08:42:53 -04:00
|
|
|
Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated));
|
|
|
|
this._sessionUpdated();
|
2009-11-10 12:13:58 -05:00
|
|
|
},
|
|
|
|
|
2015-03-05 09:46:57 -05:00
|
|
|
_sensorProxyAppeared: function() {
|
|
|
|
this._sensorProxy = new SensorProxy(Gio.DBus.system, SENSOR_BUS_NAME, SENSOR_OBJECT_PATH,
|
|
|
|
Lang.bind(this, function(proxy, error) {
|
|
|
|
if (error) {
|
|
|
|
log(error.message);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
this._sensorProxy.connect('g-properties-changed',
|
|
|
|
Lang.bind(this, this._updateOrientationLock));
|
|
|
|
this._updateOrientationLock();
|
|
|
|
}));
|
|
|
|
},
|
|
|
|
|
2013-08-12 13:08:53 -04:00
|
|
|
_updateActionsVisibility: function() {
|
|
|
|
let visible = (this._settingsAction.visible ||
|
|
|
|
this._orientationLockAction.visible ||
|
|
|
|
this._lockScreenAction.visible ||
|
2013-08-23 11:09:51 -04:00
|
|
|
this._altSwitcher.actor.visible);
|
2013-08-12 13:08:53 -04:00
|
|
|
|
|
|
|
this._actionsItem.actor.visible = visible;
|
|
|
|
},
|
|
|
|
|
2012-09-01 08:42:53 -04:00
|
|
|
_sessionUpdated: function() {
|
2013-06-11 17:17:09 -04:00
|
|
|
this._updateLockScreen();
|
|
|
|
this._updatePowerOff();
|
2013-08-23 11:09:51 -04:00
|
|
|
this._updateSuspend();
|
2013-08-12 13:15:13 -04:00
|
|
|
this._updateMultiUser();
|
2013-06-11 17:17:09 -04:00
|
|
|
this._settingsAction.visible = Main.sessionMode.allowSettings;
|
2013-08-12 13:08:53 -04:00
|
|
|
this._updateActionsVisibility();
|
2009-11-10 12:13:58 -05:00
|
|
|
},
|
|
|
|
|
2012-05-10 07:16:15 -04:00
|
|
|
_updateMultiUser: function() {
|
2013-06-11 17:17:09 -04:00
|
|
|
let shouldShowInMode = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
|
2013-06-11 15:25:32 -04:00
|
|
|
let hasSwitchUser = this._updateSwitchUser();
|
|
|
|
let hasLogout = this._updateLogout();
|
|
|
|
|
2013-06-11 17:17:09 -04:00
|
|
|
this._switchUserSubMenu.actor.visible = shouldShowInMode && (hasSwitchUser || hasLogout);
|
2012-05-10 07:16:15 -04:00
|
|
|
},
|
|
|
|
|
2009-11-10 12:13:58 -05:00
|
|
|
_updateSwitchUser: function() {
|
2011-03-21 08:51:46 -04:00
|
|
|
let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY);
|
2012-05-13 11:11:06 -04:00
|
|
|
let multiUser = this._userManager.can_switch() && this._userManager.has_multiple_users;
|
|
|
|
|
2013-06-11 15:25:32 -04:00
|
|
|
let visible = allowSwitch && multiUser;
|
|
|
|
this._loginScreenItem.actor.visible = visible;
|
|
|
|
return visible;
|
2011-03-21 08:51:46 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_updateLogout: function() {
|
|
|
|
let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY);
|
2012-10-29 00:27:18 -04:00
|
|
|
let alwaysShow = global.settings.get_boolean(ALWAYS_SHOW_LOG_OUT_KEY);
|
2012-10-28 23:55:43 -04:00
|
|
|
let systemAccount = this._user.system_account;
|
|
|
|
let localAccount = this._user.local_account;
|
2012-05-13 11:11:06 -04:00
|
|
|
let multiUser = this._userManager.has_multiple_users;
|
2012-05-19 19:19:25 -04:00
|
|
|
let multiSession = Gdm.get_session_ids().length > 1;
|
2012-05-13 11:11:06 -04:00
|
|
|
|
2013-06-11 15:25:32 -04:00
|
|
|
let visible = allowLogout && (alwaysShow || multiUser || multiSession || systemAccount || !localAccount);
|
|
|
|
this._logoutItem.actor.visible = visible;
|
|
|
|
return visible;
|
|
|
|
},
|
|
|
|
|
|
|
|
_updateSwitchUserSubMenu: function() {
|
|
|
|
this._switchUserSubMenu.label.text = this._user.get_real_name();
|
2013-08-12 06:56:51 -04:00
|
|
|
let clutterText = this._switchUserSubMenu.label.clutter_text;
|
|
|
|
|
|
|
|
// XXX -- for some reason, the ClutterText's width changes
|
|
|
|
// rapidly unless we force a relayout of the actor. Probably
|
|
|
|
// a size cache issue or something. Moving this to be a layout
|
|
|
|
// manager would be a much better idea.
|
|
|
|
clutterText.get_allocation_box();
|
|
|
|
|
|
|
|
let layout = clutterText.get_layout();
|
|
|
|
if (layout.is_ellipsized())
|
|
|
|
this._switchUserSubMenu.label.text = this._user.get_user_name();
|
2013-06-11 15:25:32 -04:00
|
|
|
|
|
|
|
let iconFile = this._user.get_icon_file();
|
|
|
|
if (iconFile && !GLib.file_test(iconFile, GLib.FileTest.EXISTS))
|
|
|
|
iconFile = null;
|
|
|
|
|
|
|
|
if (iconFile) {
|
|
|
|
let file = Gio.File.new_for_path(iconFile);
|
|
|
|
let gicon = new Gio.FileIcon({ file: file });
|
|
|
|
this._switchUserSubMenu.icon.gicon = gicon;
|
2015-08-06 05:19:37 -04:00
|
|
|
|
|
|
|
this._switchUserSubMenu.icon.add_style_class_name('user-icon');
|
|
|
|
this._switchUserSubMenu.icon.remove_style_class_name('default-icon');
|
2013-06-11 15:25:32 -04:00
|
|
|
} else {
|
2013-08-12 13:10:18 -04:00
|
|
|
this._switchUserSubMenu.icon.icon_name = 'avatar-default-symbolic';
|
2015-08-06 05:19:37 -04:00
|
|
|
|
|
|
|
this._switchUserSubMenu.icon.add_style_class_name('default-icon');
|
|
|
|
this._switchUserSubMenu.icon.remove_style_class_name('user-icon');
|
2013-06-11 15:25:32 -04:00
|
|
|
}
|
2011-03-21 08:51:46 -04:00
|
|
|
},
|
|
|
|
|
2013-07-17 02:33:09 -04:00
|
|
|
_updateOrientationLock: function() {
|
2015-03-05 09:46:57 -05:00
|
|
|
if (this._sensorProxy)
|
2016-04-20 14:26:49 -04:00
|
|
|
this._orientationLockAction.visible = this._sensorProxy.HasAccelerometer &&
|
|
|
|
this._monitorManager.get_is_builtin_display_on();
|
2015-03-05 09:46:57 -05:00
|
|
|
else
|
|
|
|
this._orientationLockAction.visible = false;
|
2013-07-17 02:33:09 -04:00
|
|
|
|
|
|
|
let locked = this._orientationSettings.get_boolean('orientation-lock');
|
|
|
|
let icon = this._orientationLockAction.child;
|
|
|
|
icon.icon_name = locked ? 'rotation-locked-symbolic' : 'rotation-allowed-symbolic';
|
2013-08-12 13:08:53 -04:00
|
|
|
|
|
|
|
this._updateActionsVisibility();
|
2013-07-17 02:33:09 -04:00
|
|
|
},
|
|
|
|
|
2011-03-21 08:51:46 -04:00
|
|
|
_updateLockScreen: function() {
|
2013-06-11 17:17:09 -04:00
|
|
|
let showLock = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
|
2011-03-21 08:51:46 -04:00
|
|
|
let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
|
2013-06-11 17:17:09 -04:00
|
|
|
this._lockScreenAction.visible = showLock && allowLockScreen && LoginManager.canLock();
|
2013-08-12 13:08:53 -04:00
|
|
|
this._updateActionsVisibility();
|
2009-11-10 12:13:58 -05:00
|
|
|
},
|
|
|
|
|
2011-06-03 18:10:55 -04:00
|
|
|
_updateHaveShutdown: function() {
|
2013-08-23 11:09:51 -04:00
|
|
|
this._session.CanShutdownRemote(Lang.bind(this, function(result, error) {
|
|
|
|
if (error)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this._haveShutdown = result[0];
|
|
|
|
this._updatePowerOff();
|
|
|
|
}));
|
2011-06-03 18:10:55 -04:00
|
|
|
},
|
|
|
|
|
2013-06-11 14:33:59 -04:00
|
|
|
_updatePowerOff: function() {
|
2013-10-31 23:33:10 -04:00
|
|
|
let disabled = Main.sessionMode.isLocked ||
|
|
|
|
(Main.sessionMode.isGreeter &&
|
|
|
|
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
|
|
|
|
this._powerOffAction.visible = this._haveShutdown && !disabled;
|
2013-08-12 13:08:53 -04:00
|
|
|
this._updateActionsVisibility();
|
2013-06-11 17:17:09 -04:00
|
|
|
},
|
|
|
|
|
2013-08-23 11:09:51 -04:00
|
|
|
_updateHaveSuspend: function() {
|
2015-03-18 18:54:25 -04:00
|
|
|
this._loginManager.canSuspend(Lang.bind(this,
|
|
|
|
function(canSuspend, needsAuth) {
|
|
|
|
this._haveSuspend = canSuspend;
|
|
|
|
this._suspendNeedsAuth = needsAuth;
|
|
|
|
this._updateSuspend();
|
|
|
|
}));
|
2013-08-23 11:09:51 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_updateSuspend: function() {
|
2015-03-18 18:54:25 -04:00
|
|
|
let disabled = (Main.sessionMode.isLocked &&
|
|
|
|
this._suspendNeedsAuth) ||
|
2013-10-31 23:33:10 -04:00
|
|
|
(Main.sessionMode.isGreeter &&
|
|
|
|
this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY));
|
2015-02-04 06:01:47 -05:00
|
|
|
this._suspendAction.visible = this._haveSuspend && !disabled;
|
2013-08-23 11:09:51 -04:00
|
|
|
this._updateActionsVisibility();
|
|
|
|
},
|
|
|
|
|
2013-06-11 17:17:09 -04:00
|
|
|
_createActionButton: function(iconName, accessibleName) {
|
|
|
|
let icon = new St.Button({ reactive: true,
|
|
|
|
can_focus: true,
|
|
|
|
track_hover: true,
|
|
|
|
accessible_name: accessibleName,
|
|
|
|
style_class: 'system-menu-action' });
|
|
|
|
icon.child = new St.Icon({ icon_name: iconName });
|
|
|
|
return icon;
|
2011-02-04 18:37:54 -05:00
|
|
|
},
|
|
|
|
|
2009-11-10 12:13:58 -05:00
|
|
|
_createSubMenu: function() {
|
|
|
|
let item;
|
|
|
|
|
2013-06-11 15:25:32 -04:00
|
|
|
this._switchUserSubMenu = new PopupMenu.PopupSubMenuMenuItem('', true);
|
|
|
|
this._switchUserSubMenu.icon.style_class = 'system-switch-user-submenu-icon';
|
2009-11-10 12:13:58 -05:00
|
|
|
|
2013-08-12 06:56:51 -04:00
|
|
|
// Since the label of the switch user submenu depends on the width of
|
|
|
|
// the popup menu, and we can't easily connect on allocation-changed
|
|
|
|
// or notify::width without creating layout cycles, simply update the
|
|
|
|
// label whenever the menu is opened.
|
|
|
|
this.menu.connect('open-state-changed', Lang.bind(this, function(menu, isOpen) {
|
|
|
|
if (isOpen)
|
|
|
|
this._updateSwitchUserSubMenu();
|
|
|
|
}));
|
|
|
|
|
2010-10-19 11:59:23 -04:00
|
|
|
item = new PopupMenu.PopupMenuItem(_("Switch User"));
|
2009-11-10 12:13:58 -05:00
|
|
|
item.connect('activate', Lang.bind(this, this._onLoginScreenActivate));
|
2013-06-11 15:25:32 -04:00
|
|
|
this._switchUserSubMenu.menu.addMenuItem(item);
|
2009-11-10 12:13:58 -05:00
|
|
|
this._loginScreenItem = item;
|
|
|
|
|
2012-05-10 07:24:12 -04:00
|
|
|
item = new PopupMenu.PopupMenuItem(_("Log Out"));
|
2009-11-10 12:13:58 -05:00
|
|
|
item.connect('activate', Lang.bind(this, this._onQuitSessionActivate));
|
2013-06-11 15:25:32 -04:00
|
|
|
this._switchUserSubMenu.menu.addMenuItem(item);
|
2011-03-21 08:51:46 -04:00
|
|
|
this._logoutItem = item;
|
2009-11-10 12:13:58 -05:00
|
|
|
|
2015-08-06 05:19:37 -04:00
|
|
|
this._switchUserSubMenu.menu.addSettingsAction(_("Account Settings"),
|
|
|
|
'gnome-user-accounts-panel.desktop');
|
|
|
|
|
2013-06-11 15:25:32 -04:00
|
|
|
this._user.connect('notify::is-loaded', Lang.bind(this, this._updateSwitchUserSubMenu));
|
|
|
|
this._user.connect('changed', Lang.bind(this, this._updateSwitchUserSubMenu));
|
|
|
|
|
2013-06-11 17:17:09 -04:00
|
|
|
this.menu.addMenuItem(this._switchUserSubMenu);
|
2013-06-11 15:25:32 -04:00
|
|
|
|
2013-06-11 17:17:09 -04:00
|
|
|
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
|
|
|
|
|
2013-07-15 20:00:41 -04:00
|
|
|
item = new PopupMenu.PopupBaseMenuItem({ reactive: false,
|
|
|
|
can_focus: false });
|
2013-06-11 17:17:09 -04:00
|
|
|
|
|
|
|
this._settingsAction = this._createActionButton('preferences-system-symbolic', _("Settings"));
|
|
|
|
this._settingsAction.connect('clicked', Lang.bind(this, this._onSettingsClicked));
|
2013-07-15 20:00:41 -04:00
|
|
|
item.actor.add(this._settingsAction, { expand: true, x_fill: false });
|
2013-06-11 17:17:09 -04:00
|
|
|
|
2013-07-17 02:33:09 -04:00
|
|
|
this._orientationLockAction = this._createActionButton('', _("Orientation Lock"));
|
|
|
|
this._orientationLockAction.connect('clicked', Lang.bind(this, this._onOrientationLockClicked));
|
|
|
|
item.actor.add(this._orientationLockAction, { expand: true, x_fill: false });
|
|
|
|
|
2013-06-11 17:17:09 -04:00
|
|
|
this._lockScreenAction = this._createActionButton('changes-prevent-symbolic', _("Lock"));
|
|
|
|
this._lockScreenAction.connect('clicked', Lang.bind(this, this._onLockScreenClicked));
|
2013-07-15 20:00:41 -04:00
|
|
|
item.actor.add(this._lockScreenAction, { expand: true, x_fill: false });
|
2013-06-11 17:17:09 -04:00
|
|
|
|
2013-08-23 11:09:51 -04:00
|
|
|
this._suspendAction = this._createActionButton('media-playback-pause-symbolic', _("Suspend"));
|
|
|
|
this._suspendAction.connect('clicked', Lang.bind(this, this._onSuspendClicked));
|
|
|
|
|
2013-06-11 17:17:09 -04:00
|
|
|
this._powerOffAction = this._createActionButton('system-shutdown-symbolic', _("Power Off"));
|
|
|
|
this._powerOffAction.connect('clicked', Lang.bind(this, this._onPowerOffClicked));
|
2013-08-23 11:09:51 -04:00
|
|
|
|
|
|
|
this._altSwitcher = new AltSwitcher(this._powerOffAction, this._suspendAction);
|
|
|
|
item.actor.add(this._altSwitcher.actor, { expand: true, x_fill: false });
|
2012-06-28 06:22:17 -04:00
|
|
|
|
2013-08-12 13:08:53 -04:00
|
|
|
this._actionsItem = item;
|
2012-06-28 06:22:17 -04:00
|
|
|
this.menu.addMenuItem(item);
|
2009-11-10 12:13:58 -05:00
|
|
|
},
|
|
|
|
|
2013-06-11 17:17:09 -04:00
|
|
|
_onSettingsClicked: function() {
|
|
|
|
this.menu.itemActivated();
|
|
|
|
let app = Shell.AppSystem.get_default().lookup_app('gnome-control-center.desktop');
|
|
|
|
Main.overview.hide();
|
|
|
|
app.activate();
|
|
|
|
},
|
|
|
|
|
2013-07-17 02:33:09 -04:00
|
|
|
_onOrientationLockClicked: function() {
|
|
|
|
this.menu.itemActivated();
|
|
|
|
let locked = this._orientationSettings.get_boolean('orientation-lock');
|
|
|
|
this._orientationSettings.set_boolean('orientation-lock', !locked);
|
|
|
|
this._updateOrientationLock();
|
|
|
|
},
|
|
|
|
|
2013-06-11 17:17:09 -04:00
|
|
|
_onLockScreenClicked: function() {
|
2013-06-18 04:46:44 -04:00
|
|
|
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
|
2010-06-03 19:21:08 -04:00
|
|
|
Main.overview.hide();
|
2012-06-02 18:10:23 -04:00
|
|
|
Main.screenShield.lock(true);
|
2009-11-10 12:13:58 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
_onLoginScreenActivate: function() {
|
2013-06-18 04:46:44 -04:00
|
|
|
this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
|
2010-06-03 19:21:08 -04:00
|
|
|
Main.overview.hide();
|
2013-03-04 13:33:36 -05:00
|
|
|
if (Main.screenShield)
|
|
|
|
Main.screenShield.lock(false);
|
2013-09-25 08:02:56 -04:00
|
|
|
|
|
|
|
Clutter.threads_add_repaint_func_full(Clutter.RepaintFlags.POST_PAINT, function() {
|
|
|
|
Gdm.goto_login_session_sync(null);
|
|
|
|
return false;
|
|
|
|
});
|
2009-11-10 12:13:58 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
_onQuitSessionActivate: function() {
|
2010-06-03 19:21:08 -04:00
|
|
|
Main.overview.hide();
|
2011-03-12 15:34:01 -05:00
|
|
|
this._session.LogoutRemote(0);
|
2009-11-10 12:13:58 -05:00
|
|
|
},
|
|
|
|
|
2013-06-11 17:17:09 -04:00
|
|
|
_onPowerOffClicked: function() {
|
|
|
|
this.menu.itemActivated();
|
2010-06-03 19:21:08 -04:00
|
|
|
Main.overview.hide();
|
2013-08-22 14:35:28 -04:00
|
|
|
this._session.ShutdownRemote(0);
|
2013-08-23 11:09:51 -04:00
|
|
|
},
|
|
|
|
|
|
|
|
_onSuspendClicked: function() {
|
|
|
|
this.menu.itemActivated();
|
|
|
|
this._loginManager.suspend();
|
|
|
|
},
|
2011-11-20 09:38:48 -05:00
|
|
|
});
|