![Florian Müllner](/assets/img/avatar_default.png)
We are currently inconsistent whether to put the operators in front of the corresponding line or at the end of the preceding one. The most dominant style for now is to put condition and first branch on the same line, and then align the second branch: let foo = condition ? fooValue : notFooValue; Unfortunately that's a style that eslint doesn't support, so to account for it, our legacy configuration currently plainly ignores all indentation in conditionals. In order to drop that exception and not let messed up indentation slip through, change all ternary operators to the non-legacy style. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/725
442 lines
17 KiB
JavaScript
442 lines
17 KiB
JavaScript
/* exported getDefault */
|
|
const { AccountsService, Clutter, Gdm, Gio, GLib, GObject, Meta } = imports.gi;
|
|
|
|
const GnomeSession = imports.misc.gnomeSession;
|
|
const LoginManager = imports.misc.loginManager;
|
|
const Main = imports.ui.main;
|
|
|
|
const { loadInterfaceXML } = imports.misc.fileUtils;
|
|
|
|
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 = loadInterfaceXML('net.hadess.SensorProxy');
|
|
|
|
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 = GObject.registerClass({
|
|
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)
|
|
}
|
|
}, class SystemActions extends GObject.Object {
|
|
_init() {
|
|
super._init();
|
|
|
|
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: C_("search-result", "Power Off"),
|
|
iconName: 'system-shutdown-symbolic',
|
|
// Translators: A list of keywords that match the power-off action, separated by semicolons
|
|
keywords: _("power off;shutdown;reboot;restart").split(/[; ]/),
|
|
available: false
|
|
});
|
|
this._actions.set(LOCK_SCREEN_ACTION_ID, {
|
|
// Translators: The name of the lock screen action in search
|
|
name: C_("search-result", "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: C_("search-result", "Log Out"),
|
|
iconName: 'application-exit-symbolic',
|
|
// Translators: A list of keywords that match the logout action, separated by semicolons
|
|
keywords: _("logout;log out;sign off").split(/[; ]/),
|
|
available: false
|
|
});
|
|
this._actions.set(SUSPEND_ACTION_ID, {
|
|
// Translators: The name of the suspend action in search
|
|
name: C_("search-result", "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: C_("search-result", "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: C_("search-result", "Lock Orientation"),
|
|
iconName: '',
|
|
// Translators: A list of keywords that match the lock orientation action, separated by semicolons
|
|
keywords: _("lock orientation;screen;rotation").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());
|
|
this._sensorProxy = new SensorProxy(Gio.DBus.system,
|
|
SENSOR_BUS_NAME,
|
|
SENSOR_OBJECT_PATH,
|
|
(proxy, error) => {
|
|
if (error)
|
|
log(error.message);
|
|
},
|
|
null,
|
|
Gio.DBusProxyFlags.DO_NOT_AUTO_START);
|
|
this._sensorProxy.connect('g-properties-changed', () => {
|
|
this._updateOrientationLock();
|
|
});
|
|
this._sensorProxy.connect('notify::g-name-owner', () => {
|
|
this._updateOrientationLock();
|
|
});
|
|
this._updateOrientationLock();
|
|
this._updateOrientationLockIcon();
|
|
|
|
Main.sessionMode.connect('updated', () => this._sessionUpdated());
|
|
this._sessionUpdated();
|
|
}
|
|
|
|
// eslint-disable-next-line camelcase
|
|
get can_power_off() {
|
|
return this._actions.get(POWER_OFF_ACTION_ID).available;
|
|
}
|
|
|
|
// eslint-disable-next-line camelcase
|
|
get can_suspend() {
|
|
return this._actions.get(SUSPEND_ACTION_ID).available;
|
|
}
|
|
|
|
// eslint-disable-next-line camelcase
|
|
get can_lock_screen() {
|
|
return this._actions.get(LOCK_SCREEN_ACTION_ID).available;
|
|
}
|
|
|
|
// eslint-disable-next-line camelcase
|
|
get can_switch_user() {
|
|
return this._actions.get(SWITCH_USER_ACTION_ID).available;
|
|
}
|
|
|
|
// eslint-disable-next-line camelcase
|
|
get can_logout() {
|
|
return this._actions.get(LOGOUT_ACTION_ID).available;
|
|
}
|
|
|
|
// eslint-disable-next-line camelcase
|
|
get can_lock_orientation() {
|
|
return this._actions.get(LOCK_ORIENTATION_ACTION_ID).available;
|
|
}
|
|
|
|
// eslint-disable-next-line camelcase
|
|
get orientation_lock_icon() {
|
|
return this._actions.get(LOCK_ORIENTATION_ACTION_ID).iconName;
|
|
}
|
|
|
|
_updateOrientationLock() {
|
|
let available = false;
|
|
if (this._sensorProxy.g_name_owner)
|
|
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() {
|
|
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() {
|
|
this._updateLockScreen();
|
|
this._updatePowerOff();
|
|
this._updateSuspend();
|
|
this._updateMultiUser();
|
|
}
|
|
|
|
forceUpdate() {
|
|
// 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(terms) {
|
|
// terms is a list of strings
|
|
terms = terms.map((term) => term.toLowerCase());
|
|
|
|
let results = [];
|
|
|
|
for (let [key, { available, keywords }] of this._actions)
|
|
if (available && terms.every(t => keywords.some(k => k.startsWith(t))))
|
|
results.push(key);
|
|
|
|
return results;
|
|
}
|
|
|
|
getName(id) {
|
|
return this._actions.get(id).name;
|
|
}
|
|
|
|
getIconName(id) {
|
|
return this._actions.get(id).iconName;
|
|
}
|
|
|
|
activateAction(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() {
|
|
this._session.CanShutdownRemote((result, error) => {
|
|
if (error)
|
|
return;
|
|
|
|
this._canHavePowerOff = result[0];
|
|
this._updatePowerOff();
|
|
});
|
|
}
|
|
|
|
_updatePowerOff() {
|
|
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() {
|
|
this._loginManager.canSuspend(
|
|
(canSuspend, needsAuth) => {
|
|
this._canHaveSuspend = canSuspend;
|
|
this._suspendNeedsAuth = needsAuth;
|
|
this._updateSuspend();
|
|
});
|
|
}
|
|
|
|
_updateSuspend() {
|
|
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() {
|
|
this._updateLogout();
|
|
this._updateSwitchUser();
|
|
}
|
|
|
|
_updateSwitchUser() {
|
|
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() {
|
|
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() {
|
|
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() {
|
|
if (!this._actions.get(LOCK_SCREEN_ACTION_ID).available)
|
|
throw new Error('The lock-screen action is not available!');
|
|
|
|
Main.screenShield.lock(true);
|
|
}
|
|
|
|
activateSwitchUser() {
|
|
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, () => {
|
|
Gdm.goto_login_session_sync(null);
|
|
return false;
|
|
});
|
|
}
|
|
|
|
activateLogout() {
|
|
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() {
|
|
if (!this._actions.get(POWER_OFF_ACTION_ID).available)
|
|
throw new Error('The power-off action is not available!');
|
|
|
|
this._session.ShutdownRemote(0);
|
|
}
|
|
|
|
activateSuspend() {
|
|
if (!this._actions.get(SUSPEND_ACTION_ID).available)
|
|
throw new Error('The suspend action is not available!');
|
|
|
|
this._loginManager.suspend();
|
|
}
|
|
});
|