[gnome-shell/wip/raresv/system-actions: 2/5] system: Split out system actions to its own module



commit 4027b616e7569c0ff880b65262f802159bcae889
Author: Rares Visalom <rares visalom gmail com>
Date:   Wed Aug 2 23:57:54 2017 +0300

    system: Split out system actions to its own module

 js/js-resources.gresource.xml |    1 +
 js/misc/systemActions.js      |  351 +++++++++++++++++++++++++++++++++++++++++
 js/ui/status/system.js        |  295 +++++++++-------------------------
 3 files changed, 431 insertions(+), 216 deletions(-)
---
diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml
index 79a200e..afd08d5 100644
--- a/js/js-resources.gresource.xml
+++ b/js/js-resources.gresource.xml
@@ -25,6 +25,7 @@
     <file>misc/params.js</file>
     <file>misc/permissionStore.js</file>
     <file>misc/smartcardManager.js</file>
+    <file>misc/systemActions.js</file>
     <file>misc/util.js</file>
     <file>misc/weather.js</file>
 
diff --git a/js/misc/systemActions.js b/js/misc/systemActions.js
new file mode 100644
index 0000000..6988875
--- /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 = '<node> \
+<interface name="net.hadess.SensorProxy"> \
+  <property name="HasAccelerometer" type="b" access="read"/> \
+</interface> \
+</node>';
+
+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 27c9e23..2a8ca47 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 = '<node> \
-<interface name="net.hadess.SensorProxy"> \
-  <property name="HasAccelerometer" type="b" access="read"/> \
-</interface> \
-</node>';
-
-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' });
-
-        this._session = new GnomeSession.SessionManager();
-        this._loginManager = LoginManager.getLoginManager();
-        this._monitorManager = Meta.MonitorManager.get();
-        this._haveShutdown = true;
-        this._haveSuspend = true;
+        let userManager = AccountsService.UserManager.get_default();
+        this._user = userManager.get_user(GLib.get_user_name());
 
-        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();
-    },
+    }
 });


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]