Compare commits
	
		
			5 Commits
		
	
	
		
			3.36.4
			...
			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