Compare commits
	
		
			5 Commits
		
	
	
		
			gbsneto/ne
			...
			wip/raresv
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					328c8e2138 | ||
| 
						 | 
					29ecb0514e | ||
| 
						 | 
					9f496bac8c | ||
| 
						 | 
					4adf992e94 | ||
| 
						 | 
					928d22a5b5 | 
@@ -1210,6 +1210,12 @@ StScrollBar {
 | 
			
		||||
  .icon-grid .overview-icon {
 | 
			
		||||
    icon-size: 96px; }
 | 
			
		||||
 | 
			
		||||
.system-action-icon {
 | 
			
		||||
  background-color: black;
 | 
			
		||||
  color: white;
 | 
			
		||||
  border-radius: 99px;
 | 
			
		||||
  icon-size: 48px; }
 | 
			
		||||
 | 
			
		||||
.app-view-controls {
 | 
			
		||||
  padding-bottom: 32px; }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1210,6 +1210,12 @@ StScrollBar {
 | 
			
		||||
  .icon-grid .overview-icon {
 | 
			
		||||
    icon-size: 96px; }
 | 
			
		||||
 | 
			
		||||
.system-action-icon {
 | 
			
		||||
  background-color: black;
 | 
			
		||||
  color: white;
 | 
			
		||||
  border-radius: 99px;
 | 
			
		||||
  icon-size: 48px; }
 | 
			
		||||
 | 
			
		||||
.app-view-controls {
 | 
			
		||||
  padding-bottom: 32px; }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										440
									
								
								js/misc/systemActions.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										440
									
								
								js/misc/systemActions.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,440 @@
 | 
			
		||||
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 POWER_OFF_ACTION_ID        = 'power-off';
 | 
			
		||||
const LOCK_SCREEN_ACTION_ID      = 'lock-screen';
 | 
			
		||||
const LOGOUT_ACTION_ID           = 'logout';
 | 
			
		||||
const SUSPEND_ACTION_ID          = 'suspend';
 | 
			
		||||
const SWITCH_USER_ACTION_ID      = 'switch-user';
 | 
			
		||||
const LOCK_ORIENTATION_ACTION_ID = 'lock-orientation';
 | 
			
		||||
 | 
			
		||||
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._canHavePowerOff = true;
 | 
			
		||||
        this._canHaveSuspend = true;
 | 
			
		||||
 | 
			
		||||
        this._actions = new Map();
 | 
			
		||||
        this._actions.set(POWER_OFF_ACTION_ID,
 | 
			
		||||
                          { // Translators: The name of the power-off action in search
 | 
			
		||||
                            name: _("Power off"),
 | 
			
		||||
                            iconName: 'system-shutdown-symbolic',
 | 
			
		||||
                            // Translators: A list of keywords that match the power-off action, separated by semicolons
 | 
			
		||||
                            keywords: _("power off;shutdown").split(';'),
 | 
			
		||||
                            available: false });
 | 
			
		||||
        this._actions.set(LOCK_SCREEN_ACTION_ID,
 | 
			
		||||
                          { // Translators: The name of the lock screen action in search
 | 
			
		||||
                            name: _("Lock screen"),
 | 
			
		||||
                            iconName: 'system-lock-screen-symbolic',
 | 
			
		||||
                            // Translators: A list of keywords that match the lock screen action, separated by semicolons
 | 
			
		||||
                            keywords: _("lock screen").split(';'),
 | 
			
		||||
                            available: false });
 | 
			
		||||
        this._actions.set(LOGOUT_ACTION_ID,
 | 
			
		||||
                          { // Translators: The name of the logout action in search
 | 
			
		||||
                            name: _("Log out"),
 | 
			
		||||
                            iconName: 'application-exit-symbolic',
 | 
			
		||||
                            // Translators: A list of keywords that match the logout action, separated by semicolons
 | 
			
		||||
                            keywords: _("logout;sign off").split(';'),
 | 
			
		||||
                            available: false });
 | 
			
		||||
        this._actions.set(SUSPEND_ACTION_ID,
 | 
			
		||||
                          { // Translators: The name of the suspend action in search
 | 
			
		||||
                            name: _("Suspend"),
 | 
			
		||||
                            iconName: 'media-playback-pause-symbolic',
 | 
			
		||||
                            // Translators: A list of keywords that match the suspend action, separated by semicolons
 | 
			
		||||
                            keywords: _("suspend;sleep").split(';'),
 | 
			
		||||
                            available: false });
 | 
			
		||||
        this._actions.set(SWITCH_USER_ACTION_ID,
 | 
			
		||||
                          { // Translators: The name of the switch user action in search
 | 
			
		||||
                            name: _("Switch user"),
 | 
			
		||||
                            iconName: 'system-switch-user-symbolic',
 | 
			
		||||
                            // Translators: A list of keywords that match the switch user action, separated by semicolons
 | 
			
		||||
                            keywords: _("switch user").split(';'),
 | 
			
		||||
                            available: false });
 | 
			
		||||
        this._actions.set(LOCK_ORIENTATION_ACTION_ID,
 | 
			
		||||
                          { // Translators: The name of the lock orientation action in search
 | 
			
		||||
                            name: _("Lock orientation"),
 | 
			
		||||
                            iconName: '',
 | 
			
		||||
                            // Translators: A list of keywords that match the lock orientation action, separated by semicolons
 | 
			
		||||
                            keywords: _("lock orientation").split(';'),
 | 
			
		||||
                            available: false });
 | 
			
		||||
 | 
			
		||||
        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._actions.get(POWER_OFF_ACTION_ID).available;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get can_suspend() {
 | 
			
		||||
        return this._actions.get(SUSPEND_ACTION_ID).available;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get can_lock_screen() {
 | 
			
		||||
        return this._actions.get(LOCK_SCREEN_ACTION_ID).available;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get can_switch_user() {
 | 
			
		||||
        return this._actions.get(SWITCH_USER_ACTION_ID).available;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get can_logout() {
 | 
			
		||||
        return this._actions.get(LOGOUT_ACTION_ID).available;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get can_lock_orientation() {
 | 
			
		||||
        return this._actions.get(LOCK_ORIENTATION_ACTION_ID).available;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    get orientation_lock_icon() {
 | 
			
		||||
        return this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _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() {
 | 
			
		||||
        let available = false;
 | 
			
		||||
        if (this._sensorProxy)
 | 
			
		||||
            available = this._sensorProxy.HasAccelerometer &&
 | 
			
		||||
                        this._monitorManager.get_is_builtin_display_on();
 | 
			
		||||
 | 
			
		||||
        this._actions.get(LOCK_ORIENTATION_ACTION_ID).available = available;
 | 
			
		||||
 | 
			
		||||
        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._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName = 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();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getMatchingActions: function(terms) {
 | 
			
		||||
        // terms is a list of strings
 | 
			
		||||
        terms = terms.map((term) => { return term.toLowerCase(); });
 | 
			
		||||
 | 
			
		||||
        let results = [];
 | 
			
		||||
 | 
			
		||||
        for (let [key, {available, keywords}] of this._actions)
 | 
			
		||||
            if (available && terms.every(t => keywords.some(k => (k.indexOf(t) >= 0))))
 | 
			
		||||
                results.push(key);
 | 
			
		||||
 | 
			
		||||
        return results;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getName: function(id) {
 | 
			
		||||
        return this._actions.get(id).name;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getIconName: function(id) {
 | 
			
		||||
        return this._actions.get(id).iconName;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateAction: function(id) {
 | 
			
		||||
        switch (id) {
 | 
			
		||||
            case POWER_OFF_ACTION_ID:
 | 
			
		||||
                this.activatePowerOff();
 | 
			
		||||
                break;
 | 
			
		||||
            case LOCK_SCREEN_ACTION_ID:
 | 
			
		||||
                this.activateLockScreen();
 | 
			
		||||
                break;
 | 
			
		||||
            case LOGOUT_ACTION_ID:
 | 
			
		||||
                this.activateLogout();
 | 
			
		||||
                break;
 | 
			
		||||
            case SUSPEND_ACTION_ID:
 | 
			
		||||
                this.activateSuspend();
 | 
			
		||||
                break;
 | 
			
		||||
            case SWITCH_USER_ACTION_ID:
 | 
			
		||||
                this.activateSwitchUser();
 | 
			
		||||
                break;
 | 
			
		||||
            case LOCK_ORIENTATION_ACTION_ID:
 | 
			
		||||
                this.activateLockOrientation();
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _updateLockScreen() {
 | 
			
		||||
        let showLock = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
 | 
			
		||||
        let allowLockScreen = !this._lockdownSettings.get_boolean(DISABLE_LOCK_SCREEN_KEY);
 | 
			
		||||
        this._actions.get(LOCK_SCREEN_ACTION_ID).available = 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._actions.get(POWER_OFF_ACTION_ID).available = 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._actions.get(SUSPEND_ACTION_ID).available = 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._actions.get(SWITCH_USER_ACTION_ID).available = 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._actions.get(LOGOUT_ACTION_ID).available = visible;
 | 
			
		||||
        this.notify('can-logout');
 | 
			
		||||
 | 
			
		||||
        return visible;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateLockOrientation: function() {
 | 
			
		||||
        if (!this._actions.get(LOCK_ORIENTATION_ACTION_ID).available)
 | 
			
		||||
            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._actions.get(LOCK_SCREEN_ACTION_ID).available)
 | 
			
		||||
            throw new Error('The lock-screen action is not available!');
 | 
			
		||||
 | 
			
		||||
        Main.screenShield.lock(true);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateSwitchUser: function() {
 | 
			
		||||
        if (!this._actions.get(SWITCH_USER_ACTION_ID).available)
 | 
			
		||||
            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._actions.get(LOGOUT_ACTION_ID).available)
 | 
			
		||||
            throw new Error('The logout action is not available!');
 | 
			
		||||
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        this._session.LogoutRemote(0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activatePowerOff: function() {
 | 
			
		||||
        if (!this._actions.get(POWER_OFF_ACTION_ID).available)
 | 
			
		||||
            throw new Error('The power-off action is not available!');
 | 
			
		||||
 | 
			
		||||
        this._session.ShutdownRemote(0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    activateSuspend: function() {
 | 
			
		||||
        if (!this._actions.get(SUSPEND_ACTION_ID).available)
 | 
			
		||||
            throw new Error('The suspend action is not available!');
 | 
			
		||||
 | 
			
		||||
        this._loginManager.suspend();
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -24,8 +24,11 @@ const OverviewControls = imports.ui.overviewControls;
 | 
			
		||||
const PopupMenu = imports.ui.popupMenu;
 | 
			
		||||
const Tweener = imports.ui.tweener;
 | 
			
		||||
const Workspace = imports.ui.workspace;
 | 
			
		||||
const Search = imports.ui.search;
 | 
			
		||||
const System = imports.ui.status.system;
 | 
			
		||||
const Params = imports.misc.params;
 | 
			
		||||
const Util = imports.misc.util;
 | 
			
		||||
const SystemActions = imports.misc.systemActions;
 | 
			
		||||
 | 
			
		||||
var MAX_APPLICATION_WORK_MILLIS = 75;
 | 
			
		||||
var MENU_POPUP_TIMEOUT = 600;
 | 
			
		||||
@@ -1085,19 +1088,35 @@ var AppSearchProvider = new Lang.Class({
 | 
			
		||||
        this.id = 'applications';
 | 
			
		||||
        this.isRemoteProvider = false;
 | 
			
		||||
        this.canLaunchSearch = false;
 | 
			
		||||
 | 
			
		||||
        this._systemActions = new SystemActions.getDefault();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getResultMetas: function(apps, callback) {
 | 
			
		||||
        let metas = [];
 | 
			
		||||
        for (let i = 0; i < apps.length; i++) {
 | 
			
		||||
            let app = this._appSys.lookup_app(apps[i]);
 | 
			
		||||
            metas.push({ 'id': app.get_id(),
 | 
			
		||||
                         'name': app.get_name(),
 | 
			
		||||
                         'createIcon': function(size) {
 | 
			
		||||
                             return app.create_icon_texture(size);
 | 
			
		||||
                         }
 | 
			
		||||
                       });
 | 
			
		||||
        for (let id of apps) {
 | 
			
		||||
            if (id.endsWith('.desktop')) {
 | 
			
		||||
                let app = this._appSys.lookup_app(id);
 | 
			
		||||
 | 
			
		||||
                metas.push({ 'id': app.get_id(),
 | 
			
		||||
                             'name': app.get_name(),
 | 
			
		||||
                             'createIcon': function(size) {
 | 
			
		||||
                                 return app.create_icon_texture(size);
 | 
			
		||||
                           }
 | 
			
		||||
                });
 | 
			
		||||
            } else {
 | 
			
		||||
                let name = this._systemActions.getName(id);
 | 
			
		||||
                let iconName = this._systemActions.getIconName(id);
 | 
			
		||||
 | 
			
		||||
                let createIcon = size => new St.Icon({ icon_name: iconName,
 | 
			
		||||
                                                       width: size,
 | 
			
		||||
                                                       height: size,
 | 
			
		||||
                                                       style_class: 'system-action-icon' });
 | 
			
		||||
 | 
			
		||||
                metas.push({ id, name, createIcon });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        callback(metas);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -1119,6 +1138,9 @@ var AppSearchProvider = new Lang.Class({
 | 
			
		||||
                return usage.compare('', a, b);
 | 
			
		||||
            }));
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        results = results.concat(this._systemActions.getMatchingActions(terms));
 | 
			
		||||
 | 
			
		||||
        callback(results);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
@@ -1127,8 +1149,10 @@ var AppSearchProvider = new Lang.Class({
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    createResultObject: function (resultMeta) {
 | 
			
		||||
        let app = this._appSys.lookup_app(resultMeta['id']);
 | 
			
		||||
        return new AppIcon(app);
 | 
			
		||||
        if (resultMeta.id.endsWith('.desktop'))
 | 
			
		||||
            return new AppIcon(this._appSys.lookup_app(resultMeta['id']));
 | 
			
		||||
        else
 | 
			
		||||
            return new SystemActionIcon(this, resultMeta);
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@@ -1983,3 +2007,13 @@ var AppIconMenu = new Lang.Class({
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
Signals.addSignalMethods(AppIconMenu.prototype);
 | 
			
		||||
 | 
			
		||||
var SystemActionIcon = new Lang.Class({
 | 
			
		||||
    Name: 'SystemActionIcon',
 | 
			
		||||
    Extends: Search.GridSearchResult,
 | 
			
		||||
 | 
			
		||||
    activate: function() {
 | 
			
		||||
        SystemActions.getDefault().activateAction(this.metaInfo['id']);
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -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' });
 | 
			
		||||
        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,46 +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.overview.hide();
 | 
			
		||||
        Main.screenShield.lock(true);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onLoginScreenActivate: function() {
 | 
			
		||||
        this.menu.itemActivated(BoxPointer.PopupAnimation.NONE);
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        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() {
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        this._session.LogoutRemote(0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onPowerOffClicked: function() {
 | 
			
		||||
        this.menu.itemActivated();
 | 
			
		||||
        Main.overview.hide();
 | 
			
		||||
        this._session.ShutdownRemote(0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    _onSuspendClicked: function() {
 | 
			
		||||
        this.menu.itemActivated();
 | 
			
		||||
        this._loginManager.suspend();
 | 
			
		||||
    },
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ js/extensionPrefs/main.js
 | 
			
		||||
js/gdm/authPrompt.js
 | 
			
		||||
js/gdm/loginDialog.js
 | 
			
		||||
js/gdm/util.js
 | 
			
		||||
js/misc/systemActions.js
 | 
			
		||||
js/misc/util.js
 | 
			
		||||
js/portalHelper/main.js
 | 
			
		||||
js/ui/accessDialog.js
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user