diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml index 79a200e91..afd08d51a 100644 --- a/js/js-resources.gresource.xml +++ b/js/js-resources.gresource.xml @@ -25,6 +25,7 @@ misc/params.js misc/permissionStore.js misc/smartcardManager.js + misc/systemActions.js misc/util.js misc/weather.js diff --git a/js/misc/systemActions.js b/js/misc/systemActions.js new file mode 100644 index 000000000..69888751f --- /dev/null +++ b/js/misc/systemActions.js @@ -0,0 +1,351 @@ +const AccountsService = imports.gi.AccountsService; +const Clutter = imports.gi.Clutter; +const Gdm = imports.gi.Gdm; +const Gio = imports.gi.Gio; +const GLib = imports.gi.GLib; +const Lang = imports.lang; +const Meta = imports.gi.Meta; +const GObject = imports.gi.GObject; + +const GnomeSession = imports.misc.gnomeSession; +const LoginManager = imports.misc.loginManager; +const Main = imports.ui.main; + +const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown'; +const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen'; +const DISABLE_USER_SWITCH_KEY = 'disable-user-switching'; +const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen'; +const DISABLE_LOG_OUT_KEY = 'disable-log-out'; +const DISABLE_RESTART_KEY = 'disable-restart-buttons'; +const ALWAYS_SHOW_LOG_OUT_KEY = 'always-show-log-out'; + +const SENSOR_BUS_NAME = 'net.hadess.SensorProxy'; +const SENSOR_OBJECT_PATH = '/net/hadess/SensorProxy'; + +const SensorProxyInterface = ' \ + \ + \ + \ +'; + +const SensorProxy = Gio.DBusProxy.makeProxyWrapper(SensorProxyInterface); + +let _singleton = null; + +function getDefault() { + if (_singleton == null) + _singleton = new SystemActions(); + + return _singleton; +} + +const SystemActions = new Lang.Class({ + Name: 'SystemActions', + Extends: GObject.Object, + Properties: { + 'can-power-off': GObject.ParamSpec.boolean('can-power-off', + 'can-power-off', + 'can-power-off', + GObject.ParamFlags.READABLE, + false), + 'can-suspend': GObject.ParamSpec.boolean('can-suspend', + 'can-suspend', + 'can-suspend', + GObject.ParamFlags.READABLE, + false), + 'can-lock-screen': GObject.ParamSpec.boolean('can-lock-screen', + 'can-lock-screen', + 'can-lock-screen', + GObject.ParamFlags.READABLE, + false), + 'can-switch-user': GObject.ParamSpec.boolean('can-switch-user', + 'can-switch-user', + 'can-switch-user', + GObject.ParamFlags.READABLE, + false), + 'can-logout': GObject.ParamSpec.boolean('can-logout', + 'can-logout', + 'can-logout', + GObject.ParamFlags.READABLE, + false), + 'can-lock-orientation': GObject.ParamSpec.boolean('can-lock-orientation', + 'can-lock-orientation', + 'can-lock-orientation', + GObject.ParamFlags.READABLE, + false), + 'orientation-lock-icon': GObject.ParamSpec.string('orientation-lock-icon', + 'orientation-lock-icon', + 'orientation-lock-icon', + GObject.ParamFlags.READWRITE, + null) + }, + + _init: function() { + this.parent(); + + this._canPowerOff = false; + this._canHavePowerOff = true; + this._canSuspend = false; + this._canHaveSuspend = true; + this._canLockScreen = false; + this._canSwitchUser = false; + this._canLogout = false; + this._canLockOrientation = false; + this._orientationLockIcon = null; + + 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' }); + + this._session = new GnomeSession.SessionManager(); + this._loginManager = LoginManager.getLoginManager(); + this._monitorManager = Meta.MonitorManager.get(); + + this._userManager = AccountsService.UserManager.get_default(); + + this._userManager.connect('notify::is-loaded', + () => { this._updateMultiUser(); }); + this._userManager.connect('notify::has-multiple-users', + () => { this._updateMultiUser(); }); + this._userManager.connect('user-added', + () => { this._updateMultiUser(); }); + this._userManager.connect('user-removed', + () => { this._updateMultiUser(); }); + + this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY, + () => { this._updateSwitchUser(); }); + this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY, + () => { this._updateLogout(); }); + global.settings.connect('changed::' + ALWAYS_SHOW_LOG_OUT_KEY, + () => { this._updateLogout(); }); + + this._lockdownSettings.connect('changed::' + DISABLE_LOCK_SCREEN_KEY, + () => { this._updateLockScreen(); }); + + this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY, + () => { this._updateHaveShutdown(); }); + + this.forceUpdate(); + + this._orientationSettings.connect('changed::orientation-lock', + () => { this._updateOrientationLock(); + this._updateOrientationLockIcon(); }); + Main.layoutManager.connect('monitors-changed', + () => { this._updateOrientationLock(); }); + Gio.DBus.system.watch_name(SENSOR_BUS_NAME, + Gio.BusNameWatcherFlags.NONE, + () => { this._sensorProxyAppeared(); }, + () => { + this._sensorProxy = null; + this._updateOrientationLock(); + }); + this._updateOrientationLock(); + this._updateOrientationLockIcon(); + + Main.sessionMode.connect('updated', () => { this._sessionUpdated(); }); + this._sessionUpdated(); + }, + + get can_power_off() { + return this._canPowerOff; + }, + + get can_suspend() { + return this._canSuspend; + }, + + get can_lock_screen() { + return this._canLockScreen; + }, + + get can_switch_user() { + return this._canSwitchUser; + }, + + get can_logout() { + return this._canLogout; + }, + + get can_lock_orientation() { + return this._canLockOrientation; + }, + + get orientation_lock_icon() { + return this._orientationLockIcon; + }, + + _sensorProxyAppeared: function() { + this._sensorProxy = new SensorProxy(Gio.DBus.system, SENSOR_BUS_NAME, SENSOR_OBJECT_PATH, + (proxy, error) => { + if (error) { + log(error.message); + return; + } + this._sensorProxy.connect('g-properties-changed', + () => { this._updateOrientationLock(); }); + this._updateOrientationLock(); + }); + }, + + _updateOrientationLock: function() { + if (this._sensorProxy) + this._canLockOrientation = this._sensorProxy.HasAccelerometer && + this._monitorManager.get_is_builtin_display_on(); + else + this._canLockOrientation = false; + + this.notify('can-lock-orientation'); + }, + + _updateOrientationLockIcon: function() { + let locked = this._orientationSettings.get_boolean('orientation-lock'); + let iconName = locked ? 'rotation-locked-symbolic' + : 'rotation-allowed-symbolic'; + this._orientationLockIcon = iconName; + + this.notify('orientation-lock-icon'); + }, + + _sessionUpdated: function() { + this._updateLockScreen(); + this._updatePowerOff(); + this._updateSuspend(); + this._updateMultiUser(); + }, + + forceUpdate: function() { + // Whether those actions are available or not depends on both lockdown + // settings and Polkit policy - we don't get change notifications for the + // latter, so their value may be outdated; force an update now + this._updateHaveShutdown(); + this._updateHaveSuspend(); + }, + + _updateLockScreen() { + let showLock = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter; + let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY); + this._canLockScreen = showLock && allowLockScreen && LoginManager.canLock(); + this.notify('can-lock-screen'); + }, + + _updateHaveShutdown: function() { + this._session.CanShutdownRemote((result, error) => { + if (error) + return; + + this._canHavePowerOff = result[0]; + this._updatePowerOff(); + }); + }, + + _updatePowerOff: function() { + let disabled = Main.sessionMode.isLocked || + (Main.sessionMode.isGreeter && + this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY)); + this._canPowerOff = this._canHavePowerOff && !disabled; + this.notify('can-power-off'); + }, + + _updateHaveSuspend: function() { + this._loginManager.canSuspend( + (canSuspend, needsAuth) => { + this._canHaveSuspend = canSuspend; + this._suspendNeedsAuth = needsAuth; + this._updateSuspend(); + }); + }, + + _updateSuspend: function() { + let disabled = (Main.sessionMode.isLocked && + this._suspendNeedsAuth) || + (Main.sessionMode.isGreeter && + this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY)); + this._canSuspend = this._canHaveSuspend && !disabled; + this.notify('can-suspend'); + }, + + _updateMultiUser: function() { + this._updateLogout(); + this._updateSwitchUser(); + }, + + _updateSwitchUser: function() { + let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY); + let multiUser = this._userManager.can_switch() && this._userManager.has_multiple_users; + let shouldShowInMode = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter; + + let visible = allowSwitch && multiUser && shouldShowInMode; + this._canSwitchUser = visible; + this.notify('can-switch-user'); + + return visible; + }, + + _updateLogout: function() { + let user = this._userManager.get_user(GLib.get_user_name()); + + let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY); + let alwaysShow = global.settings.get_boolean(ALWAYS_SHOW_LOG_OUT_KEY); + let systemAccount = user.system_account; + let localAccount = user.local_account; + let multiUser = this._userManager.has_multiple_users; + let multiSession = Gdm.get_session_ids().length > 1; + let shouldShowInMode = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter; + + let visible = allowLogout && (alwaysShow || multiUser || multiSession || systemAccount || !localAccount) && shouldShowInMode; + this._canLogout = visible; + this.notify('can-logout'); + + return visible; + }, + + activateLockOrientation: function() { + if (!this._canLockOrientation) + throw new Error('The lock-orientation action is not available!'); + + let locked = this._orientationSettings.get_boolean('orientation-lock'); + this._orientationSettings.set_boolean('orientation-lock', !locked); + }, + + activateLockScreen: function() { + if (!this._canLockScreen) + throw new Error('The lock-screen action is not available!'); + + Main.screenShield.lock(true); + }, + + activateSwitchUser: function() { + if (!this._canSwitchUser) + throw new Error('The switch-user action is not available!'); + + if (Main.screenShield) + Main.screenShield.lock(false); + + Clutter.threads_add_repaint_func_full(Clutter.RepaintFlags.POST_PAINT, function() { + Gdm.goto_login_session_sync(null); + return false; + }); + }, + + activateLogout: function() { + if (!this._canLogout) + throw new Error('The logout action is not available!'); + + Main.overview.hide(); + this._session.LogoutRemote(0); + }, + + activatePowerOff: function() { + if (!this._canPowerOff) + throw new Error('The power-off action is not available!'); + + this._session.ShutdownRemote(0); + }, + + activateSuspend: function() { + if (!this._canSuspend) + throw new Error('The suspend action is not available!'); + + this._loginManager.suspend(); + } +}); diff --git a/js/ui/status/system.js b/js/ui/status/system.js index 27c9e2387..2a8ca4789 100644 --- a/js/ui/status/system.js +++ b/js/ui/status/system.js @@ -2,39 +2,19 @@ const AccountsService = imports.gi.AccountsService; const Clutter = imports.gi.Clutter; -const Gdm = imports.gi.Gdm; const Gio = imports.gi.Gio; const GLib = imports.gi.GLib; const Lang = imports.lang; -const Meta = imports.gi.Meta; const Shell = imports.gi.Shell; const St = imports.gi.St; +const GObject = imports.gi.GObject; const BoxPointer = imports.ui.boxpointer; -const GnomeSession = imports.misc.gnomeSession; -const LoginManager = imports.misc.loginManager; +const SystemActions = imports.misc.systemActions; const Main = imports.ui.main; const PanelMenu = imports.ui.panelMenu; const PopupMenu = imports.ui.popupMenu; -const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown'; -const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen'; -const DISABLE_USER_SWITCH_KEY = 'disable-user-switching'; -const DISABLE_LOCK_SCREEN_KEY = 'disable-lock-screen'; -const DISABLE_LOG_OUT_KEY = 'disable-log-out'; -const DISABLE_RESTART_KEY = 'disable-restart-buttons'; -const ALWAYS_SHOW_LOG_OUT_KEY = 'always-show-log-out'; - -const SENSOR_BUS_NAME = 'net.hadess.SensorProxy'; -const SENSOR_OBJECT_PATH = '/net/hadess/SensorProxy'; - -const SensorProxyInterface = ' \ - \ - \ - \ -'; - -const SensorProxy = Gio.DBusProxy.makeProxyWrapper(SensorProxyInterface); var AltSwitcher = new Lang.Class({ Name: 'AltSwitcher', @@ -138,41 +118,17 @@ var Indicator = new Lang.Class({ _init: function() { this.parent(); - 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' }); + let userManager = AccountsService.UserManager.get_default(); + this._user = userManager.get_user(GLib.get_user_name()); - this._session = new GnomeSession.SessionManager(); - this._loginManager = LoginManager.getLoginManager(); - this._monitorManager = Meta.MonitorManager.get(); - this._haveShutdown = true; - this._haveSuspend = true; - - this._userManager = AccountsService.UserManager.get_default(); - this._user = this._userManager.get_user(GLib.get_user_name()); + this._systemActions = new SystemActions.getDefault(); this._createSubMenu(); - this._userManager.connect('notify::is-loaded', - Lang.bind(this, this._updateMultiUser)); - this._userManager.connect('notify::has-multiple-users', - Lang.bind(this, this._updateMultiUser)); - this._userManager.connect('user-added', - Lang.bind(this, this._updateMultiUser)); - this._userManager.connect('user-removed', - Lang.bind(this, this._updateMultiUser)); - this._lockdownSettings.connect('changed::' + DISABLE_USER_SWITCH_KEY, - Lang.bind(this, this._updateMultiUser)); - this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY, - Lang.bind(this, this._updateMultiUser)); - this._lockdownSettings.connect('changed::' + DISABLE_LOCK_SCREEN_KEY, - Lang.bind(this, this._updateLockScreen)); - global.settings.connect('changed::' + ALWAYS_SHOW_LOG_OUT_KEY, - Lang.bind(this, this._updateMultiUser)); - this._updateSwitchUser(); - this._updateMultiUser(); - this._updateLockScreen(); - + this._loginScreenItem.actor.connect('notify::visible', + () => { this._updateMultiUser(); }); + this._logoutItem.actor.connect('notify::visible', + () => { this._updateMultiUser(); }); // 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 @@ -182,42 +138,14 @@ var Indicator = new Lang.Class({ if (!open) return; - this._updateHaveShutdown(); - this._updateHaveSuspend(); + this._systemActions.forceUpdate(); })); - this._lockdownSettings.connect('changed::' + DISABLE_LOG_OUT_KEY, - Lang.bind(this, this._updateHaveShutdown)); - - this._orientationSettings.connect('changed::orientation-lock', - Lang.bind(this, this._updateOrientationLock)); - Main.layoutManager.connect('monitors-changed', - Lang.bind(this, this._updateOrientationLock)); - 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(); - })); - this._updateOrientationLock(); + this._updateMultiUser(); Main.sessionMode.connect('updated', Lang.bind(this, this._sessionUpdated)); this._sessionUpdated(); }, - _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(); - })); - }, - _updateActionsVisibility: function() { let visible = (this._settingsAction.visible || this._orientationLockAction.visible || @@ -228,42 +156,14 @@ var Indicator = new Lang.Class({ }, _sessionUpdated: function() { - this._updateLockScreen(); - this._updatePowerOff(); - this._updateSuspend(); - this._updateMultiUser(); this._settingsAction.visible = Main.sessionMode.allowSettings; - this._updateActionsVisibility(); }, _updateMultiUser: function() { - let shouldShowInMode = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter; - let hasSwitchUser = this._updateSwitchUser(); - let hasLogout = this._updateLogout(); + let hasSwitchUser = this._loginScreenItem.actor.visible; + let hasLogout = this._logoutItem.actor.visible; - this._switchUserSubMenu.actor.visible = shouldShowInMode && (hasSwitchUser || hasLogout); - }, - - _updateSwitchUser: function() { - let allowSwitch = !this._lockdownSettings.get_boolean(DISABLE_USER_SWITCH_KEY); - let multiUser = this._userManager.can_switch() && this._userManager.has_multiple_users; - - let visible = allowSwitch && multiUser; - this._loginScreenItem.actor.visible = visible; - return visible; - }, - - _updateLogout: function() { - let allowLogout = !this._lockdownSettings.get_boolean(DISABLE_LOG_OUT_KEY); - let alwaysShow = global.settings.get_boolean(ALWAYS_SHOW_LOG_OUT_KEY); - let systemAccount = this._user.system_account; - let localAccount = this._user.local_account; - let multiUser = this._userManager.has_multiple_users; - let multiSession = Gdm.get_session_ids().length > 1; - - let visible = allowLogout && (alwaysShow || multiUser || multiSession || systemAccount || !localAccount); - this._logoutItem.actor.visible = visible; - return visible; + this._switchUserSubMenu.actor.visible = hasSwitchUser || hasLogout; }, _updateSwitchUserSubMenu: function() { @@ -299,63 +199,6 @@ var Indicator = new Lang.Class({ } }, - _updateOrientationLock: function() { - if (this._sensorProxy) - this._orientationLockAction.visible = this._sensorProxy.HasAccelerometer && - this._monitorManager.get_is_builtin_display_on(); - else - this._orientationLockAction.visible = false; - - let locked = this._orientationSettings.get_boolean('orientation-lock'); - let icon = this._orientationLockAction.child; - icon.icon_name = locked ? 'rotation-locked-symbolic' : 'rotation-allowed-symbolic'; - - this._updateActionsVisibility(); - }, - - _updateLockScreen: function() { - let showLock = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter; - let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY); - this._lockScreenAction.visible = showLock && allowLockScreen && LoginManager.canLock(); - this._updateActionsVisibility(); - }, - - _updateHaveShutdown: function() { - this._session.CanShutdownRemote(Lang.bind(this, function(result, error) { - if (error) - return; - - this._haveShutdown = result[0]; - this._updatePowerOff(); - })); - }, - - _updatePowerOff: function() { - let disabled = Main.sessionMode.isLocked || - (Main.sessionMode.isGreeter && - this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY)); - this._powerOffAction.visible = this._haveShutdown && !disabled; - this._updateActionsVisibility(); - }, - - _updateHaveSuspend: function() { - this._loginManager.canSuspend(Lang.bind(this, - function(canSuspend, needsAuth) { - this._haveSuspend = canSuspend; - this._suspendNeedsAuth = needsAuth; - this._updateSuspend(); - })); - }, - - _updateSuspend: function() { - let disabled = (Main.sessionMode.isLocked && - this._suspendNeedsAuth) || - (Main.sessionMode.isGreeter && - this._loginScreenSettings.get_boolean(DISABLE_RESTART_KEY)); - this._suspendAction.visible = this._haveSuspend && !disabled; - this._updateActionsVisibility(); - }, - _createActionButton: function(iconName, accessibleName) { let icon = new St.Button({ reactive: true, can_focus: true, @@ -367,6 +210,7 @@ var Indicator = new Lang.Class({ }, _createSubMenu: function() { + let bindFlags = GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE; let item; this._switchUserSubMenu = new PopupMenu.PopupSubMenuMenuItem('', true); @@ -382,14 +226,28 @@ var Indicator = new Lang.Class({ })); item = new PopupMenu.PopupMenuItem(_("Switch User")); - item.connect('activate', Lang.bind(this, this._onLoginScreenActivate)); + item.connect('activate', () => { + this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); + this._systemActions.activateSwitchUser(); + }); this._switchUserSubMenu.menu.addMenuItem(item); this._loginScreenItem = item; + this._systemActions.bind_property('can-switch-user', + this._loginScreenItem.actor, + 'visible', + bindFlags); item = new PopupMenu.PopupMenuItem(_("Log Out")); - item.connect('activate', Lang.bind(this, this._onQuitSessionActivate)); + item.connect('activate', () => { + this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); + this._systemActions.activateLogout(); + }); this._switchUserSubMenu.menu.addMenuItem(item); this._logoutItem = item; + this._systemActions.bind_property('can-logout', + this._logoutItem.actor, + 'visible', + bindFlags); this._switchUserSubMenu.menu.addSettingsAction(_("Account Settings"), 'gnome-user-accounts-panel.desktop'); @@ -405,28 +263,70 @@ var Indicator = new Lang.Class({ can_focus: false }); this._settingsAction = this._createActionButton('preferences-system-symbolic', _("Settings")); - this._settingsAction.connect('clicked', Lang.bind(this, this._onSettingsClicked)); + this._settingsAction.connect('clicked', () => { this._onSettingsClicked(); }); item.actor.add(this._settingsAction, { expand: true, x_fill: false }); this._orientationLockAction = this._createActionButton('', _("Orientation Lock")); - this._orientationLockAction.connect('clicked', Lang.bind(this, this._onOrientationLockClicked)); + this._orientationLockAction.connect('clicked', () => { + this.menu.itemActivated(BoxPointer.PopupAnimation.NONE), + this._systemActions.activateLockOrientation(); + }); item.actor.add(this._orientationLockAction, { expand: true, x_fill: false }); + this._systemActions.bind_property('can-lock-orientation', + this._orientationLockAction, + 'visible', + bindFlags); + this._systemActions.bind_property('orientation-lock-icon', + this._orientationLockAction.child, + 'icon-name', + bindFlags); this._lockScreenAction = this._createActionButton('changes-prevent-symbolic', _("Lock")); - this._lockScreenAction.connect('clicked', Lang.bind(this, this._onLockScreenClicked)); + this._lockScreenAction.connect('clicked', () => { + this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); + this._systemActions.activateLockScreen(); + }); item.actor.add(this._lockScreenAction, { expand: true, x_fill: false }); + this._systemActions.bind_property('can-lock-screen', + this._lockScreenAction, + 'visible', + bindFlags); this._suspendAction = this._createActionButton('media-playback-pause-symbolic', _("Suspend")); - this._suspendAction.connect('clicked', Lang.bind(this, this._onSuspendClicked)); + this._suspendAction.connect('clicked', () => { + this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); + this._systemActions.activateSuspend(); + }); + this._systemActions.bind_property('can-suspend', + this._suspendAction, + 'visible', + bindFlags); this._powerOffAction = this._createActionButton('system-shutdown-symbolic', _("Power Off")); - this._powerOffAction.connect('clicked', Lang.bind(this, this._onPowerOffClicked)); + this._powerOffAction.connect('clicked', () => { + this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); + this._systemActions.activatePowerOff(); + }); + this._systemActions.bind_property('can-power-off', + this._powerOffAction, + 'visible', + bindFlags); this._altSwitcher = new AltSwitcher(this._powerOffAction, this._suspendAction); item.actor.add(this._altSwitcher.actor, { expand: true, x_fill: false }); this._actionsItem = item; this.menu.addMenuItem(item); + + + this._settingsAction.connect('notify::visible', + () => { this._updateActionsVisibility(); }); + this._orientationLockAction.connect('notify::visible', + () => { this._updateActionsVisibility(); }); + this._lockScreenAction.connect('notify::visible', + () => { this._updateActionsVisibility(); }); + this._altSwitcher.actor.connect('notify::visible', + () => { this._updateActionsVisibility(); }); }, _onSettingsClicked: function() { @@ -434,42 +334,5 @@ var Indicator = new Lang.Class({ let app = Shell.AppSystem.get_default().lookup_app('gnome-control-center.desktop'); Main.overview.hide(); app.activate(); - }, - - _onOrientationLockClicked: function() { - this.menu.itemActivated(); - let locked = this._orientationSettings.get_boolean('orientation-lock'); - this._orientationSettings.set_boolean('orientation-lock', !locked); - this._updateOrientationLock(); - }, - - _onLockScreenClicked: function() { - this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); - Main.screenShield.lock(true); - }, - - _onLoginScreenActivate: function() { - this.menu.itemActivated(BoxPointer.PopupAnimation.NONE); - if (Main.screenShield) - Main.screenShield.lock(false); - - Clutter.threads_add_repaint_func_full(Clutter.RepaintFlags.POST_PAINT, function() { - Gdm.goto_login_session_sync(null); - return false; - }); - }, - - _onQuitSessionActivate: function() { - this._session.LogoutRemote(0); - }, - - _onPowerOffClicked: function() { - this.menu.itemActivated(); - this._session.ShutdownRemote(0); - }, - - _onSuspendClicked: function() { - this.menu.itemActivated(); - this._loginManager.suspend(); - }, + } });