2012-02-06 17:28:48 -05:00
|
|
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
|
|
|
2019-11-28 16:35:13 -05:00
|
|
|
const { AccountsService, Clutter, Gio,
|
|
|
|
GLib, Graphene, Meta, Shell, St } = imports.gi;
|
2012-05-21 12:42:45 -04:00
|
|
|
const Signals = imports.signals;
|
2012-02-06 17:28:48 -05:00
|
|
|
|
|
|
|
const GnomeSession = imports.misc.gnomeSession;
|
2013-10-10 04:21:47 -04:00
|
|
|
const OVirt = imports.gdm.oVirt;
|
2012-08-18 08:05:52 -04:00
|
|
|
const LoginManager = imports.misc.loginManager;
|
2012-02-06 17:28:48 -05:00
|
|
|
const Lightbox = imports.ui.lightbox;
|
|
|
|
const Main = imports.ui.main;
|
2012-09-01 15:59:53 -04:00
|
|
|
const Overview = imports.ui.overview;
|
2012-05-22 18:02:00 -04:00
|
|
|
const MessageTray = imports.ui.messageTray;
|
2012-07-08 11:42:15 -04:00
|
|
|
const ShellDBus = imports.ui.shellDBus;
|
2013-06-27 08:54:19 -04:00
|
|
|
const SmartcardManager = imports.misc.smartcardManager;
|
2012-02-06 17:28:48 -05:00
|
|
|
|
2019-10-04 05:04:43 -04:00
|
|
|
const { adjustAnimationTime } = imports.ui.environment;
|
|
|
|
|
2012-02-06 17:28:48 -05:00
|
|
|
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
|
|
|
|
const LOCK_ENABLED_KEY = 'lock-enabled';
|
2012-12-24 19:13:52 -05:00
|
|
|
const LOCK_DELAY_KEY = 'lock-delay';
|
2012-02-06 17:28:48 -05:00
|
|
|
|
2017-03-17 10:48:22 -04:00
|
|
|
const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
|
|
|
|
const DISABLE_LOCK_KEY = 'disable-lock-screen';
|
|
|
|
|
2013-01-17 14:39:54 -05:00
|
|
|
const LOCKED_STATE_STR = 'screenShield.locked';
|
2012-05-24 16:47:48 -04:00
|
|
|
|
2013-01-29 10:04:19 -05:00
|
|
|
// ScreenShield animation time
|
|
|
|
// - STANDARD_FADE_TIME is used when the session goes idle
|
|
|
|
// - MANUAL_FADE_TIME is used for lowering the shield when asked by the user,
|
|
|
|
// or when cancelling the dialog
|
|
|
|
// - CURTAIN_SLIDE_TIME is used when raising the shield before unlocking
|
2019-08-01 19:13:10 -04:00
|
|
|
var STANDARD_FADE_TIME = 10000;
|
|
|
|
var MANUAL_FADE_TIME = 300;
|
|
|
|
var CURTAIN_SLIDE_TIME = 300;
|
2012-06-02 18:10:23 -04:00
|
|
|
|
2012-02-06 17:28:48 -05:00
|
|
|
/**
|
|
|
|
* If you are setting org.gnome.desktop.session.idle-delay directly in dconf,
|
|
|
|
* rather than through System Settings, you also need to set
|
|
|
|
* org.gnome.settings-daemon.plugins.power.sleep-display-ac and
|
|
|
|
* org.gnome.settings-daemon.plugins.power.sleep-display-battery to the same value.
|
|
|
|
* This will ensure that the screen blanks at the right time when it fades out.
|
2014-08-21 16:48:43 -04:00
|
|
|
* https://bugzilla.gnome.org/show_bug.cgi?id=668703 explains the dependency.
|
2012-02-06 17:28:48 -05:00
|
|
|
*/
|
2017-10-30 21:19:44 -04:00
|
|
|
var ScreenShield = class {
|
|
|
|
constructor() {
|
2012-05-22 17:22:38 -04:00
|
|
|
this.actor = Main.layoutManager.screenShieldGroup;
|
|
|
|
|
2012-08-26 17:15:59 -04:00
|
|
|
this._lockScreenState = MessageTray.State.HIDDEN;
|
2019-02-12 09:02:09 -05:00
|
|
|
this._lockScreenGroup = new St.Widget({
|
|
|
|
x_expand: true,
|
|
|
|
y_expand: true,
|
|
|
|
reactive: true,
|
|
|
|
can_focus: true,
|
|
|
|
name: 'lockScreenGroup',
|
|
|
|
visible: false,
|
|
|
|
});
|
2012-05-24 16:47:48 -04:00
|
|
|
|
2019-12-02 10:35:00 -05:00
|
|
|
this._lockDialogGroup = new St.Widget({
|
|
|
|
x_expand: true,
|
|
|
|
y_expand: true,
|
|
|
|
reactive: true,
|
|
|
|
can_focus: true,
|
|
|
|
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
|
|
|
|
name: 'lockDialogGroup',
|
|
|
|
});
|
2012-08-14 09:39:17 -04:00
|
|
|
|
2012-05-24 16:47:48 -04:00
|
|
|
this.actor.add_actor(this._lockScreenGroup);
|
2019-11-29 10:30:23 -05:00
|
|
|
this.actor.add_actor(this._lockDialogGroup);
|
2012-05-24 16:47:48 -04:00
|
|
|
|
2017-10-30 20:38:18 -04:00
|
|
|
this._presence = new GnomeSession.Presence((proxy, error) => {
|
2012-02-06 17:28:48 -05:00
|
|
|
if (error) {
|
|
|
|
logError(error, 'Error while reading gnome-session presence');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._onStatusChanged(proxy.status);
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
|
|
|
this._presence.connectSignal('StatusChanged', (proxy, senderName, [status]) => {
|
2012-02-06 17:28:48 -05:00
|
|
|
this._onStatusChanged(status);
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2012-02-06 17:28:48 -05:00
|
|
|
|
2012-07-08 11:42:15 -04:00
|
|
|
this._screenSaverDBus = new ShellDBus.ScreenSaverDBus(this);
|
|
|
|
|
2013-06-27 08:54:19 -04:00
|
|
|
this._smartcardManager = SmartcardManager.getSmartcardManager();
|
|
|
|
this._smartcardManager.connect('smartcard-inserted',
|
2017-10-30 20:38:18 -04:00
|
|
|
(manager, token) => {
|
2013-06-27 08:54:19 -04:00
|
|
|
if (this._isLocked && token.UsedToLogin)
|
2020-01-30 09:30:55 -05:00
|
|
|
this._activateDialog();
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2013-06-27 08:54:19 -04:00
|
|
|
|
2013-10-10 04:21:47 -04:00
|
|
|
this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager();
|
|
|
|
this._oVirtCredentialsManager.connect('user-authenticated',
|
2017-10-30 20:38:18 -04:00
|
|
|
() => {
|
2013-10-10 04:21:47 -04:00
|
|
|
if (this._isLocked)
|
2020-01-30 09:30:55 -05:00
|
|
|
this._activateDialog();
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2013-10-10 04:21:47 -04:00
|
|
|
|
2012-08-18 08:05:52 -04:00
|
|
|
this._loginManager = LoginManager.getLoginManager();
|
2012-10-23 09:48:49 -04:00
|
|
|
this._loginManager.connect('prepare-for-sleep',
|
2017-12-01 19:27:35 -05:00
|
|
|
this._prepareForSleep.bind(this));
|
2012-10-23 09:48:49 -04:00
|
|
|
|
2015-05-13 15:42:13 -04:00
|
|
|
this._loginSession = null;
|
2017-10-30 20:38:18 -04:00
|
|
|
this._loginManager.getCurrentSessionProxy(sessionProxy => {
|
|
|
|
this._loginSession = sessionProxy;
|
|
|
|
this._loginSession.connectSignal('Lock',
|
2019-01-27 19:42:00 -05:00
|
|
|
() => this.lock(false));
|
2017-10-30 20:38:18 -04:00
|
|
|
this._loginSession.connectSignal('Unlock',
|
2019-01-27 19:42:00 -05:00
|
|
|
() => this.deactivate(false));
|
2017-12-01 19:27:35 -05:00
|
|
|
this._loginSession.connect('g-properties-changed', this._syncInhibitor.bind(this));
|
2017-10-30 20:38:18 -04:00
|
|
|
this._syncInhibitor();
|
|
|
|
});
|
2012-08-17 08:24:17 -04:00
|
|
|
|
2014-06-24 15:17:09 -04:00
|
|
|
this._settings = new Gio.Settings({ schema_id: SCREENSAVER_SCHEMA });
|
2020-02-14 10:10:34 -05:00
|
|
|
this._settings.connect('changed::%s'.format(LOCK_ENABLED_KEY), this._syncInhibitor.bind(this));
|
2012-02-06 17:28:48 -05:00
|
|
|
|
2017-03-17 10:48:22 -04:00
|
|
|
this._lockSettings = new Gio.Settings({ schema_id: LOCKDOWN_SCHEMA });
|
2020-02-14 10:10:34 -05:00
|
|
|
this._lockSettings.connect('changed::%s'.format(DISABLE_LOCK_KEY), this._syncInhibitor.bind(this));
|
2017-03-17 10:48:22 -04:00
|
|
|
|
2012-05-21 12:42:45 -04:00
|
|
|
this._isModal = false;
|
2012-08-26 10:53:08 -04:00
|
|
|
this._isGreeter = false;
|
|
|
|
this._isActive = false;
|
2013-02-02 11:10:45 -05:00
|
|
|
this._isLocked = false;
|
2012-09-21 18:06:26 -04:00
|
|
|
this._inUnlockAnimation = false;
|
2012-10-16 10:38:32 -04:00
|
|
|
this._activationTime = 0;
|
2013-01-17 17:55:17 -05:00
|
|
|
this._becameActiveId = 0;
|
2013-01-27 09:45:04 -05:00
|
|
|
this._lockTimeoutId = 0;
|
2012-05-22 17:22:38 -04:00
|
|
|
|
2013-08-17 13:40:09 -04:00
|
|
|
// The "long" lightbox is used for the longer (20 seconds) fade from session
|
|
|
|
// to idle status, the "short" is used for quickly fading to black when locking
|
|
|
|
// manually
|
|
|
|
this._longLightbox = new Lightbox.Lightbox(Main.uiGroup,
|
|
|
|
{ inhibitEvents: true,
|
|
|
|
fadeFactor: 1 });
|
2019-07-16 05:24:13 -04:00
|
|
|
this._longLightbox.connect('notify::active', this._onLongLightbox.bind(this));
|
2013-08-17 13:40:09 -04:00
|
|
|
this._shortLightbox = new Lightbox.Lightbox(Main.uiGroup,
|
|
|
|
{ inhibitEvents: true,
|
|
|
|
fadeFactor: 1 });
|
2019-07-16 05:24:13 -04:00
|
|
|
this._shortLightbox.connect('notify::active', this._onShortLightbox.bind(this));
|
2012-10-28 07:26:21 -04:00
|
|
|
|
2021-05-06 16:31:11 -04:00
|
|
|
this.idleMonitor = global.backend.get_core_idle_monitor();
|
2018-01-03 02:55:38 -05:00
|
|
|
this._cursorTracker = Meta.CursorTracker.get_for_display(global.display);
|
2015-05-13 15:41:07 -04:00
|
|
|
|
|
|
|
this._syncInhibitor();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2015-05-13 15:41:07 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_setActive(active) {
|
2015-05-13 15:41:07 -04:00
|
|
|
let prevIsActive = this._isActive;
|
|
|
|
this._isActive = active;
|
|
|
|
|
|
|
|
if (prevIsActive != this._isActive)
|
|
|
|
this.emit('active-changed');
|
|
|
|
|
|
|
|
this._syncInhibitor();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-05-22 17:22:38 -04:00
|
|
|
|
2021-01-07 16:33:47 -05:00
|
|
|
_setLocked(locked) {
|
|
|
|
let prevIsLocked = this._isLocked;
|
|
|
|
this._isLocked = locked;
|
|
|
|
|
|
|
|
if (prevIsLocked !== this._isLocked)
|
|
|
|
this.emit('locked-changed');
|
|
|
|
|
|
|
|
if (this._loginSession)
|
|
|
|
this._loginSession.SetLockedHintRemote(locked);
|
|
|
|
}
|
|
|
|
|
2020-01-30 09:30:55 -05:00
|
|
|
_activateDialog() {
|
2013-01-27 09:45:04 -05:00
|
|
|
if (this._isLocked) {
|
2020-01-30 09:44:43 -05:00
|
|
|
this._ensureUnlockDialog(true /* allowCancel */);
|
|
|
|
this._dialog.activate();
|
2013-01-27 09:45:04 -05:00
|
|
|
} else {
|
|
|
|
this.deactivate(true /* animate */);
|
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-01-27 09:45:04 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_maybeCancelDialog() {
|
2013-06-08 13:04:36 -04:00
|
|
|
if (!this._dialog)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this._dialog.cancel();
|
|
|
|
if (this._isGreeter) {
|
|
|
|
// LoginDialog.cancel() will grab the key focus
|
|
|
|
// on its own, so ensure it stays on lock screen
|
|
|
|
// instead
|
2019-12-02 10:35:00 -05:00
|
|
|
this._dialog.grab_key_focus();
|
2013-06-08 13:04:36 -04:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-06-08 13:04:36 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_becomeModal() {
|
2012-11-26 14:18:57 -05:00
|
|
|
if (this._isModal)
|
|
|
|
return true;
|
|
|
|
|
2014-12-11 09:35:40 -05:00
|
|
|
this._isModal = Main.pushModal(this.actor, { actionMode: Shell.ActionMode.LOCK_SCREEN });
|
2012-11-26 14:18:57 -05:00
|
|
|
if (this._isModal)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// We failed to get a pointer grab, it means that
|
|
|
|
// something else has it. Try with a keyboard grab only
|
|
|
|
this._isModal = Main.pushModal(this.actor, { options: Meta.ModalOptions.POINTER_ALREADY_GRABBED,
|
2014-12-11 09:35:40 -05:00
|
|
|
actionMode: Shell.ActionMode.LOCK_SCREEN });
|
2012-11-26 14:18:57 -05:00
|
|
|
return this._isModal;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-11-26 14:18:57 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_syncInhibitor() {
|
2017-03-17 10:48:22 -04:00
|
|
|
let lockEnabled = this._settings.get_boolean(LOCK_ENABLED_KEY);
|
|
|
|
let lockLocked = this._lockSettings.get_boolean(DISABLE_LOCK_KEY);
|
2019-08-19 15:38:51 -04:00
|
|
|
let inhibit = this._loginSession && this._loginSession.Active &&
|
2020-04-24 17:42:52 -04:00
|
|
|
!this._isActive && lockEnabled && !lockLocked && Main.sessionMode.unlockDialog;
|
2015-05-13 15:41:07 -04:00
|
|
|
if (inhibit) {
|
|
|
|
this._loginManager.inhibit(_("GNOME needs to lock the screen"),
|
2017-10-30 20:38:18 -04:00
|
|
|
inhibitor => {
|
|
|
|
if (this._inhibitor)
|
|
|
|
this._inhibitor.close(null);
|
|
|
|
this._inhibitor = inhibitor;
|
|
|
|
});
|
2015-05-13 15:41:07 -04:00
|
|
|
} else {
|
|
|
|
if (this._inhibitor)
|
|
|
|
this._inhibitor.close(null);
|
|
|
|
this._inhibitor = null;
|
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-10-23 09:48:49 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_prepareForSleep(loginManager, aboutToSuspend) {
|
2012-10-23 09:48:49 -04:00
|
|
|
if (aboutToSuspend) {
|
2015-05-13 15:41:07 -04:00
|
|
|
if (this._settings.get_boolean(LOCK_ENABLED_KEY))
|
|
|
|
this.lock(true);
|
2012-10-23 09:48:49 -04:00
|
|
|
} else {
|
2014-03-14 18:12:28 -04:00
|
|
|
this._wakeUpScreen();
|
2012-10-23 09:48:49 -04:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-10-23 09:48:49 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_onStatusChanged(status) {
|
2012-10-28 07:26:21 -04:00
|
|
|
if (status != GnomeSession.PresenceStatus.IDLE)
|
|
|
|
return;
|
2012-05-21 12:42:45 -04:00
|
|
|
|
2013-06-08 13:04:36 -04:00
|
|
|
this._maybeCancelDialog();
|
2012-05-21 12:42:45 -04:00
|
|
|
|
2019-07-16 05:24:13 -04:00
|
|
|
if (this._longLightbox.visible) {
|
2019-03-14 21:13:27 -04:00
|
|
|
// We're in the process of showing.
|
2013-01-17 17:55:17 -05:00
|
|
|
return;
|
2012-10-28 07:26:21 -04:00
|
|
|
}
|
2012-10-16 10:38:32 -04:00
|
|
|
|
2013-06-04 12:58:58 -04:00
|
|
|
if (!this._becomeModal()) {
|
|
|
|
// We could not become modal, so we can't activate the
|
|
|
|
// screenshield. The user is probably very upset at this
|
|
|
|
// point, but any application using global grabs is broken
|
|
|
|
// Just tell him to stop using this app
|
2013-08-17 13:40:09 -04:00
|
|
|
//
|
2013-06-04 12:58:58 -04:00
|
|
|
// XXX: another option is to kick the user into the gdm login
|
|
|
|
// screen, where we're not affected by grabs
|
|
|
|
Main.notifyError(_("Unable to lock"),
|
|
|
|
_("Lock was blocked by an application"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-01-17 17:55:17 -05:00
|
|
|
if (this._activationTime == 0)
|
|
|
|
this._activationTime = GLib.get_monotonic_time();
|
2012-10-28 07:26:21 -04:00
|
|
|
|
2013-01-27 09:45:04 -05:00
|
|
|
let shouldLock = this._settings.get_boolean(LOCK_ENABLED_KEY) && !this._isLocked;
|
|
|
|
|
|
|
|
if (shouldLock) {
|
2019-08-01 19:13:10 -04:00
|
|
|
let lockTimeout = Math.max(
|
2019-10-04 05:04:43 -04:00
|
|
|
adjustAnimationTime(STANDARD_FADE_TIME),
|
2019-08-01 19:13:10 -04:00
|
|
|
this._settings.get_uint(LOCK_DELAY_KEY) * 1000);
|
2019-08-19 14:50:33 -04:00
|
|
|
this._lockTimeoutId = GLib.timeout_add(
|
|
|
|
GLib.PRIORITY_DEFAULT,
|
|
|
|
lockTimeout,
|
|
|
|
() => {
|
|
|
|
this._lockTimeoutId = 0;
|
|
|
|
this.lock(false);
|
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
});
|
2014-04-10 13:26:52 -04:00
|
|
|
GLib.Source.set_name_by_id(this._lockTimeoutId, '[gnome-shell] this.lock');
|
2013-01-27 09:45:04 -05:00
|
|
|
}
|
2013-08-17 13:40:09 -04:00
|
|
|
|
|
|
|
this._activateFade(this._longLightbox, STANDARD_FADE_TIME);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-08-17 13:40:09 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_activateFade(lightbox, time) {
|
2019-07-16 05:24:13 -04:00
|
|
|
Main.uiGroup.set_child_above_sibling(lightbox, null);
|
2019-08-28 16:06:14 -04:00
|
|
|
lightbox.lightOn(time);
|
2013-08-17 13:40:09 -04:00
|
|
|
|
|
|
|
if (this._becameActiveId == 0)
|
2017-12-01 19:27:35 -05:00
|
|
|
this._becameActiveId = this.idleMonitor.add_user_active_watch(this._onUserBecameActive.bind(this));
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-10-28 07:26:21 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_onUserBecameActive() {
|
2013-01-17 17:55:17 -05:00
|
|
|
// This function gets called here when the user becomes active
|
2013-08-17 13:40:09 -04:00
|
|
|
// after we activated a lightbox
|
|
|
|
// There are two possibilities here:
|
2020-02-14 16:26:56 -05:00
|
|
|
// - we're called when already locked; we just go back to the lock screen curtain
|
2013-08-17 13:40:09 -04:00
|
|
|
// - we're called because the session is IDLE but before the lightbox
|
|
|
|
// is fully shown; at this point isActive is false, so we just hide
|
|
|
|
// the lightbox, reset the activationTime and go back to the unlocked
|
|
|
|
// desktop
|
|
|
|
// using deactivate() is a little of overkill, but it ensures we
|
|
|
|
// don't forget of some bit like modal, DBus properties or idle watches
|
|
|
|
//
|
|
|
|
// Note: if the (long) lightbox is shown then we're necessarily
|
|
|
|
// active, because we call activate() without animation.
|
2013-01-17 17:55:17 -05:00
|
|
|
|
2013-01-18 00:24:32 -05:00
|
|
|
this.idleMonitor.remove_watch(this._becameActiveId);
|
2013-01-17 17:55:17 -05:00
|
|
|
this._becameActiveId = 0;
|
|
|
|
|
2020-02-14 16:26:56 -05:00
|
|
|
if (this._isLocked) {
|
2019-08-28 16:06:14 -04:00
|
|
|
this._longLightbox.lightOff();
|
|
|
|
this._shortLightbox.lightOff();
|
2013-08-17 13:40:09 -04:00
|
|
|
} else {
|
2013-01-27 09:45:04 -05:00
|
|
|
this.deactivate(false);
|
2012-02-06 17:28:48 -05:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-02-06 17:28:48 -05:00
|
|
|
|
2019-08-28 16:06:14 -04:00
|
|
|
_onLongLightbox(lightBox) {
|
|
|
|
if (lightBox.active)
|
|
|
|
this.activate(false);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-01-17 17:55:17 -05:00
|
|
|
|
2019-08-28 16:06:14 -04:00
|
|
|
_onShortLightbox(lightBox) {
|
|
|
|
if (lightBox.active)
|
|
|
|
this._completeLockScreenShown();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-08-17 13:40:09 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
showDialog() {
|
2014-07-31 10:38:44 -04:00
|
|
|
if (!this._becomeModal()) {
|
|
|
|
// In the login screen, this is a hard error. Fail-whale
|
2021-07-16 15:39:51 -04:00
|
|
|
const error = new GLib.Error(
|
|
|
|
Gio.IOErrorEnum, Gio.IOErrorEnum.FAILED,
|
|
|
|
'Could not acquire modal grab for the login screen. Aborting login process.');
|
|
|
|
global.context.terminate_with_error(error);
|
2014-07-31 10:38:44 -04:00
|
|
|
}
|
2012-08-26 10:53:08 -04:00
|
|
|
|
|
|
|
this.actor.show();
|
|
|
|
this._isGreeter = Main.sessionMode.isGreeter;
|
2013-01-27 09:45:04 -05:00
|
|
|
this._isLocked = true;
|
2019-12-02 10:36:38 -05:00
|
|
|
this._ensureUnlockDialog(true);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-05-20 12:30:14 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_hideLockScreenComplete() {
|
2013-03-02 15:21:20 -05:00
|
|
|
this._lockScreenState = MessageTray.State.HIDDEN;
|
|
|
|
this._lockScreenGroup.hide();
|
2014-10-06 16:38:03 -04:00
|
|
|
|
2014-10-08 09:39:44 -04:00
|
|
|
if (this._dialog) {
|
2019-09-20 07:14:40 -04:00
|
|
|
this._dialog.grab_key_focus();
|
|
|
|
this._dialog.navigate_focus(null, St.DirectionType.TAB_FORWARD, false);
|
2014-10-08 09:39:44 -04:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-03-02 15:21:20 -05:00
|
|
|
|
2020-09-28 22:28:08 -04:00
|
|
|
_showPointer() {
|
|
|
|
this._cursorTracker.set_pointer_visible(true);
|
|
|
|
|
|
|
|
if (this._motionId) {
|
|
|
|
global.stage.disconnect(this._motionId);
|
|
|
|
this._motionId = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_hidePointerUntilMotion() {
|
|
|
|
this._motionId = global.stage.connect('captured-event', (stage, event) => {
|
|
|
|
if (event.type() === Clutter.EventType.MOTION)
|
|
|
|
this._showPointer();
|
|
|
|
|
|
|
|
return Clutter.EVENT_PROPAGATE;
|
|
|
|
});
|
|
|
|
this._cursorTracker.set_pointer_visible(false);
|
|
|
|
}
|
|
|
|
|
2019-11-28 18:05:51 -05:00
|
|
|
_hideLockScreen(animate) {
|
2013-01-27 09:45:04 -05:00
|
|
|
if (this._lockScreenState == MessageTray.State.HIDDEN)
|
|
|
|
return;
|
|
|
|
|
2012-08-26 17:15:59 -04:00
|
|
|
this._lockScreenState = MessageTray.State.HIDING;
|
|
|
|
|
2019-11-29 10:29:41 -05:00
|
|
|
this._lockDialogGroup.remove_all_transitions();
|
2013-06-03 17:45:31 -04:00
|
|
|
|
2012-05-26 11:04:25 -04:00
|
|
|
if (animate) {
|
2020-04-15 05:24:10 -04:00
|
|
|
// Animate the lock screen out of screen
|
2012-08-31 10:36:40 -04:00
|
|
|
// if velocity is not specified (i.e. we come here from pressing ESC),
|
|
|
|
// use the same speed regardless of original position
|
|
|
|
// if velocity is specified, it's in pixels per milliseconds
|
2012-05-26 11:04:25 -04:00
|
|
|
let h = global.stage.height;
|
2019-11-29 10:29:41 -05:00
|
|
|
let delta = h + this._lockDialogGroup.translation_y;
|
2019-11-28 18:05:51 -05:00
|
|
|
let velocity = global.stage.height / CURTAIN_SLIDE_TIME;
|
2018-07-20 15:46:19 -04:00
|
|
|
let duration = delta / velocity;
|
|
|
|
|
2019-11-29 10:24:17 -05:00
|
|
|
this._lockDialogGroup.ease({
|
|
|
|
translation_y: -h,
|
|
|
|
duration,
|
|
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
2019-08-20 17:43:54 -04:00
|
|
|
onComplete: () => this._hideLockScreenComplete(),
|
2018-07-20 15:46:19 -04:00
|
|
|
});
|
2012-05-26 11:04:25 -04:00
|
|
|
} else {
|
2013-03-02 15:21:20 -05:00
|
|
|
this._hideLockScreenComplete();
|
2012-05-26 11:04:25 -04:00
|
|
|
}
|
|
|
|
|
2020-09-28 22:28:08 -04:00
|
|
|
this._showPointer();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-08-26 17:15:59 -04:00
|
|
|
|
2019-11-28 16:53:46 -05:00
|
|
|
_ensureUnlockDialog(allowCancel) {
|
2012-05-26 11:04:25 -04:00
|
|
|
if (!this._dialog) {
|
2012-09-04 13:28:19 -04:00
|
|
|
let constructor = Main.sessionMode.unlockDialog;
|
2012-11-06 17:41:51 -05:00
|
|
|
if (!constructor) {
|
2012-05-26 11:04:25 -04:00
|
|
|
// This session mode has no locking capabilities
|
2013-01-27 09:45:04 -05:00
|
|
|
this.deactivate(true);
|
2013-06-08 10:03:14 -04:00
|
|
|
return false;
|
2012-05-26 11:04:25 -04:00
|
|
|
}
|
|
|
|
|
2012-11-06 17:41:51 -05:00
|
|
|
this._dialog = new constructor(this._lockDialogGroup);
|
|
|
|
|
2012-10-14 12:34:22 -04:00
|
|
|
let time = global.get_current_time();
|
2019-11-28 16:53:46 -05:00
|
|
|
if (!this._dialog.open(time)) {
|
2013-03-05 01:51:28 -05:00
|
|
|
// This is kind of an impossible error: we're already modal
|
|
|
|
// by the time we reach this...
|
|
|
|
log('Could not open login dialog: failed to acquire grab');
|
|
|
|
this.deactivate(true);
|
2013-06-08 10:03:14 -04:00
|
|
|
return false;
|
2013-03-05 01:51:28 -05:00
|
|
|
}
|
2012-05-26 11:04:25 -04:00
|
|
|
|
2017-12-01 19:27:35 -05:00
|
|
|
this._dialog.connect('failed', this._onUnlockFailed.bind(this));
|
2019-11-28 16:22:55 -05:00
|
|
|
this._wakeUpScreenId = this._dialog.connect(
|
|
|
|
'wake-up-screen', this._wakeUpScreen.bind(this));
|
2012-05-26 11:04:25 -04:00
|
|
|
}
|
2012-10-24 11:53:19 -04:00
|
|
|
|
|
|
|
this._dialog.allowCancel = allowCancel;
|
2020-01-30 09:44:43 -05:00
|
|
|
this._dialog.grab_key_focus();
|
2013-06-08 10:03:14 -04:00
|
|
|
return true;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-02-06 17:28:48 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_onUnlockFailed() {
|
2013-05-12 11:32:02 -04:00
|
|
|
this._resetLockScreen({ animateLockScreen: true,
|
2013-08-17 13:40:09 -04:00
|
|
|
fadeToBlack: false });
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-05-20 12:30:14 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_resetLockScreen(params) {
|
2013-01-27 09:45:04 -05:00
|
|
|
// Don't reset the lock screen unless it is completely hidden
|
|
|
|
// This prevents the shield going down if the lock-delay timeout
|
|
|
|
// fires while the user is dragging (which has the potential
|
|
|
|
// to confuse our state)
|
|
|
|
if (this._lockScreenState != MessageTray.State.HIDDEN)
|
2012-12-29 09:25:03 -05:00
|
|
|
return;
|
|
|
|
|
2012-08-03 13:42:43 -04:00
|
|
|
this._lockScreenGroup.show();
|
2012-08-26 17:15:59 -04:00
|
|
|
this._lockScreenState = MessageTray.State.SHOWING;
|
2012-08-03 13:42:43 -04:00
|
|
|
|
2013-08-17 13:40:09 -04:00
|
|
|
let fadeToBlack = params.fadeToBlack;
|
|
|
|
|
2013-05-12 11:32:02 -04:00
|
|
|
if (params.animateLockScreen) {
|
2019-11-29 10:24:17 -05:00
|
|
|
this._lockDialogGroup.translation_y = -global.screen_height;
|
|
|
|
this._lockDialogGroup.remove_all_transitions();
|
|
|
|
this._lockDialogGroup.ease({
|
|
|
|
translation_y: 0,
|
|
|
|
duration: Overview.ANIMATION_TIME,
|
|
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
2018-07-20 15:46:19 -04:00
|
|
|
onComplete: () => {
|
|
|
|
this._lockScreenShown({ fadeToBlack, animateFade: true });
|
2019-08-20 17:43:54 -04:00
|
|
|
},
|
2018-07-20 15:46:19 -04:00
|
|
|
});
|
2012-08-13 19:43:59 -04:00
|
|
|
} else {
|
2020-02-14 19:57:06 -05:00
|
|
|
this._lockDialogGroup.translation_y = 0;
|
2019-08-19 15:06:04 -04:00
|
|
|
this._lockScreenShown({ fadeToBlack, animateFade: false });
|
2012-08-13 19:43:59 -04:00
|
|
|
}
|
2012-08-03 13:42:43 -04:00
|
|
|
|
2019-12-02 10:35:00 -05:00
|
|
|
this._dialog.grab_key_focus();
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-05-21 12:42:45 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_lockScreenShown(params) {
|
2020-09-28 22:28:08 -04:00
|
|
|
this._hidePointerUntilMotion();
|
2012-08-31 11:51:32 -04:00
|
|
|
|
2012-08-26 17:15:59 -04:00
|
|
|
this._lockScreenState = MessageTray.State.SHOWN;
|
|
|
|
|
2013-08-17 13:40:09 -04:00
|
|
|
if (params.fadeToBlack && params.animateFade) {
|
|
|
|
// Take a beat
|
|
|
|
|
2019-08-19 14:50:33 -04:00
|
|
|
let id = GLib.timeout_add(GLib.PRIORITY_DEFAULT, MANUAL_FADE_TIME, () => {
|
2013-08-17 13:40:09 -04:00
|
|
|
this._activateFade(this._shortLightbox, MANUAL_FADE_TIME);
|
2013-11-28 19:45:39 -05:00
|
|
|
return GLib.SOURCE_REMOVE;
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2014-04-10 13:26:52 -04:00
|
|
|
GLib.Source.set_name_by_id(id, '[gnome-shell] this._activateFade');
|
2013-08-17 13:40:09 -04:00
|
|
|
} else {
|
|
|
|
if (params.fadeToBlack)
|
|
|
|
this._activateFade(this._shortLightbox, 0);
|
|
|
|
|
|
|
|
this._completeLockScreenShown();
|
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-08-17 13:40:09 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_completeLockScreenShown() {
|
2015-05-13 15:41:07 -04:00
|
|
|
this._setActive(true);
|
2012-08-26 17:15:59 -04:00
|
|
|
this.emit('lock-screen-shown');
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-08-26 17:15:59 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_wakeUpScreen() {
|
2014-03-10 14:16:03 -04:00
|
|
|
this._onUserBecameActive();
|
|
|
|
this.emit('wake-up-screen');
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2014-03-10 14:16:03 -04:00
|
|
|
|
2012-05-21 12:42:45 -04:00
|
|
|
get locked() {
|
2013-01-27 09:45:04 -05:00
|
|
|
return this._isLocked;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-01-27 09:45:04 -05:00
|
|
|
|
|
|
|
get active() {
|
2012-08-26 10:53:08 -04:00
|
|
|
return this._isActive;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-05-21 12:42:45 -04:00
|
|
|
|
2012-10-16 10:38:32 -04:00
|
|
|
get activationTime() {
|
|
|
|
return this._activationTime;
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-10-16 10:38:32 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
deactivate(animate) {
|
2013-08-06 09:22:48 -04:00
|
|
|
if (this._dialog)
|
2019-01-27 19:42:00 -05:00
|
|
|
this._dialog.finish(() => this._continueDeactivate(animate));
|
2013-08-06 09:22:48 -04:00
|
|
|
else
|
2013-08-06 09:49:00 -04:00
|
|
|
this._continueDeactivate(animate);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-07-18 08:58:58 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_continueDeactivate(animate) {
|
2019-11-28 18:05:51 -05:00
|
|
|
this._hideLockScreen(animate);
|
2013-01-27 09:45:04 -05:00
|
|
|
|
2013-02-01 05:36:21 -05:00
|
|
|
if (Main.sessionMode.currentMode == 'unlock-dialog')
|
|
|
|
Main.sessionMode.popMode('unlock-dialog');
|
|
|
|
|
2020-03-31 15:07:59 -04:00
|
|
|
this.emit('wake-up-screen');
|
|
|
|
|
2013-06-06 16:09:28 -04:00
|
|
|
if (this._isGreeter) {
|
|
|
|
// We don't want to "deactivate" any more than
|
|
|
|
// this. In particular, we don't want to drop
|
|
|
|
// the modal, hide ourselves or destroy the dialog
|
|
|
|
// But we do want to set isActive to false, so that
|
|
|
|
// gnome-session will reset the idle counter, and
|
|
|
|
// gnome-settings-daemon will stop blanking the screen
|
|
|
|
|
|
|
|
this._activationTime = 0;
|
2015-05-13 15:41:07 -04:00
|
|
|
this._setActive(false);
|
2013-06-06 16:09:28 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-05-22 12:06:11 -04:00
|
|
|
if (this._dialog && !this._isGreeter)
|
|
|
|
this._dialog.popModal();
|
|
|
|
|
|
|
|
if (this._isModal) {
|
|
|
|
Main.popModal(this.actor);
|
|
|
|
this._isModal = false;
|
|
|
|
}
|
|
|
|
|
2020-04-01 08:48:10 -04:00
|
|
|
this._longLightbox.lightOff();
|
|
|
|
this._shortLightbox.lightOff();
|
|
|
|
|
2018-07-20 15:46:19 -04:00
|
|
|
this._lockDialogGroup.ease({
|
2019-11-29 10:24:17 -05:00
|
|
|
translation_y: -global.screen_height,
|
|
|
|
duration: Overview.ANIMATION_TIME,
|
2018-07-20 15:46:19 -04:00
|
|
|
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
2019-08-20 17:43:54 -04:00
|
|
|
onComplete: () => this._completeDeactivate(),
|
2012-09-01 15:59:53 -04:00
|
|
|
});
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-09-01 15:59:53 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
_completeDeactivate() {
|
2013-06-06 16:09:28 -04:00
|
|
|
if (this._dialog) {
|
2012-09-04 13:28:19 -04:00
|
|
|
this._dialog.destroy();
|
|
|
|
this._dialog = null;
|
2012-05-26 11:04:25 -04:00
|
|
|
}
|
|
|
|
|
2013-01-27 09:45:04 -05:00
|
|
|
this.actor.hide();
|
2012-08-26 10:53:08 -04:00
|
|
|
|
2013-01-17 17:55:17 -05:00
|
|
|
if (this._becameActiveId != 0) {
|
2013-01-18 00:24:32 -05:00
|
|
|
this.idleMonitor.remove_watch(this._becameActiveId);
|
2013-01-17 17:55:17 -05:00
|
|
|
this._becameActiveId = 0;
|
|
|
|
}
|
|
|
|
|
2013-01-27 09:45:04 -05:00
|
|
|
if (this._lockTimeoutId != 0) {
|
2019-08-19 14:50:33 -04:00
|
|
|
GLib.source_remove(this._lockTimeoutId);
|
2013-01-27 09:45:04 -05:00
|
|
|
this._lockTimeoutId = 0;
|
|
|
|
}
|
|
|
|
|
2012-10-16 10:38:32 -04:00
|
|
|
this._activationTime = 0;
|
2015-05-13 15:41:07 -04:00
|
|
|
this._setActive(false);
|
2021-01-07 16:33:47 -05:00
|
|
|
this._setLocked(false);
|
2013-01-17 14:39:54 -05:00
|
|
|
global.set_runtime_state(LOCKED_STATE_STR, null);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2012-05-24 16:47:48 -04:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
activate(animate) {
|
2012-10-16 10:38:32 -04:00
|
|
|
if (this._activationTime == 0)
|
|
|
|
this._activationTime = GLib.get_monotonic_time();
|
|
|
|
|
2020-04-23 20:42:16 -04:00
|
|
|
if (!this._ensureUnlockDialog(true))
|
|
|
|
return;
|
2019-11-28 17:30:02 -05:00
|
|
|
|
2012-05-21 12:42:45 -04:00
|
|
|
this.actor.show();
|
2012-08-26 10:53:08 -04:00
|
|
|
|
2019-11-29 10:43:18 -05:00
|
|
|
if (Main.sessionMode.currentMode !== 'unlock-dialog') {
|
2012-08-26 10:53:08 -04:00
|
|
|
this._isGreeter = Main.sessionMode.isGreeter;
|
|
|
|
if (!this._isGreeter)
|
|
|
|
Main.sessionMode.pushMode('unlock-dialog');
|
|
|
|
}
|
|
|
|
|
2013-05-12 11:32:02 -04:00
|
|
|
this._resetLockScreen({ animateLockScreen: animate,
|
2013-08-17 13:40:09 -04:00
|
|
|
fadeToBlack: true });
|
2018-02-05 05:37:09 -05:00
|
|
|
// On wayland, a crash brings down the entire session, so we don't
|
|
|
|
// need to defend against being restarted unlocked
|
|
|
|
if (!Meta.is_wayland_compositor())
|
|
|
|
global.set_runtime_state(LOCKED_STATE_STR, GLib.Variant.new('b', true));
|
2012-05-21 12:42:45 -04:00
|
|
|
|
2013-02-02 11:10:45 -05:00
|
|
|
// We used to set isActive and emit active-changed here,
|
2013-01-29 09:49:18 -05:00
|
|
|
// but now we do that from lockScreenShown, which means
|
|
|
|
// there is a 0.3 seconds window during which the lock
|
|
|
|
// screen is effectively visible and the screen is locked, but
|
|
|
|
// the DBus interface reports the screensaver is off.
|
|
|
|
// This is because when we emit ActiveChanged(true),
|
|
|
|
// gnome-settings-daemon blanks the screen, and we don't want
|
|
|
|
// blank during the animation.
|
|
|
|
// This is not a problem for the idle fade case, because we
|
|
|
|
// activate without animation in that case.
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-01-27 09:45:04 -05:00
|
|
|
|
2017-10-30 20:03:21 -04:00
|
|
|
lock(animate) {
|
2017-03-17 10:48:22 -04:00
|
|
|
if (this._lockSettings.get_boolean(DISABLE_LOCK_KEY)) {
|
2019-01-28 20:18:52 -05:00
|
|
|
log('Screen lock is locked down, not locking'); // lock, lock - who's there?
|
2017-03-17 10:48:22 -04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-11-26 14:18:57 -05:00
|
|
|
// Warn the user if we can't become modal
|
|
|
|
if (!this._becomeModal()) {
|
|
|
|
Main.notifyError(_("Unable to lock"),
|
|
|
|
_("Lock was blocked by an application"));
|
|
|
|
return;
|
2013-01-27 09:45:04 -05:00
|
|
|
}
|
|
|
|
|
2013-05-16 11:51:31 -04:00
|
|
|
// Clear the clipboard - otherwise, its contents may be leaked
|
|
|
|
// to unauthorized parties by pasting into the unlock dialog's
|
|
|
|
// password entry and unmasking the entry
|
|
|
|
St.Clipboard.get_default().set_text(St.ClipboardType.CLIPBOARD, '');
|
|
|
|
St.Clipboard.get_default().set_text(St.ClipboardType.PRIMARY, '');
|
|
|
|
|
2013-06-08 11:22:43 -04:00
|
|
|
let userManager = AccountsService.UserManager.get_default();
|
|
|
|
let user = userManager.get_user(GLib.get_user_name());
|
|
|
|
|
2013-01-27 09:45:04 -05:00
|
|
|
this.activate(animate);
|
2013-02-02 11:10:45 -05:00
|
|
|
|
2021-01-07 16:33:47 -05:00
|
|
|
const lock = this._isGreeter
|
|
|
|
? true
|
|
|
|
: user.password_mode !== AccountsService.UserPasswordMode.NONE;
|
|
|
|
this._setLocked(lock);
|
2017-10-30 21:19:44 -04:00
|
|
|
}
|
2013-01-17 14:39:54 -05:00
|
|
|
|
|
|
|
// If the previous shell crashed, and gnome-session restarted us, then re-lock
|
2017-10-30 20:03:21 -04:00
|
|
|
lockIfWasLocked() {
|
2013-07-25 18:21:30 -04:00
|
|
|
if (!this._settings.get_boolean(LOCK_ENABLED_KEY))
|
|
|
|
return;
|
2013-01-17 14:39:54 -05:00
|
|
|
let wasLocked = global.get_runtime_state('b', LOCKED_STATE_STR);
|
|
|
|
if (wasLocked === null)
|
|
|
|
return;
|
2017-10-30 20:38:18 -04:00
|
|
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
2013-01-17 14:39:54 -05:00
|
|
|
this.lock(false);
|
2019-07-22 14:37:33 -04:00
|
|
|
return GLib.SOURCE_REMOVE;
|
2017-10-30 20:38:18 -04:00
|
|
|
});
|
2013-01-17 14:39:54 -05:00
|
|
|
}
|
2017-10-30 21:19:44 -04:00
|
|
|
};
|
2012-05-21 12:42:45 -04:00
|
|
|
Signals.addSignalMethods(ScreenShield.prototype);
|