gnome-shell/js/ui/screenShield.js

143 lines
4.8 KiB
JavaScript
Raw Normal View History

// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Meta = imports.gi.Meta;
const St = imports.gi.St;
const GnomeSession = imports.misc.gnomeSession;
const Lightbox = imports.ui.lightbox;
const UnlockDialog = imports.ui.unlockDialog;
const Main = imports.ui.main;
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
const LOCK_ENABLED_KEY = 'lock-enabled';
/**
* To test screen shield, make sure to kill gnome-screensaver.
*
* 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.
* https://bugzilla.gnome.org/show_bug.cgi?id=668703 explains the dependance.
*/
const ScreenShield = new Lang.Class({
Name: 'ScreenShield',
_init: function() {
this._presence = new GnomeSession.Presence(Lang.bind(this, function(proxy, error) {
this._onStatusChanged(proxy.status);
}));
this._presence.connectSignal('StatusChanged', Lang.bind(this, function(proxy, senderName, [status]) {
this._onStatusChanged(status);
}));
this._settings = new Gio.Settings({ schema: SCREENSAVER_SCHEMA });
this._isModal = false;
this._isLocked = false;
this._group = new St.Widget({ x: 0,
y: 0 });
Main.uiGroup.add_actor(this._group);
let constraint = new Clutter.BindConstraint({ source: global.stage,
coordinate: Clutter.BindCoordinate.POSITION | Clutter.BindCoordinate.SIZE });
this._group.add_constraint(constraint);
this._lightbox = new Lightbox.Lightbox(this._group,
{ inhibitEvents: true, fadeInTime: 10, fadeFactor: 1 });
this._background = Meta.BackgroundActor.new_for_screen(global.screen);
this._background.hide();
Main.uiGroup.add_actor(this._background);
},
_onStatusChanged: function(status) {
log ("in _onStatusChanged");
if (status == GnomeSession.PresenceStatus.IDLE) {
log("session gone idle");
if (this._dialog) {
log('canceling existing dialog');
this._dialog.cancel();
this._dialog = null;
}
this._group.reactive = true;
if (!this._isModal) {
Main.pushModal(this._group);
this._isModal = true;
}
this._group.raise_top();
this._lightbox.show();
} else {
log('status is now ' + status);
let lightboxWasShown = this._lightbox.shown;
log("this._lightbox.shown " + this._lightbox.shown);
this._lightbox.hide();
let shouldLock = lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY);
if (shouldLock || this._isLocked) {
this._isLocked = true;
this._background.show();
this._background.raise_top();
this._showUnlockDialog();
} else if (this._isModal) {
this._popModal();
}
}
},
_popModal: function() {
this._group.reactive = false;
Main.popModal(this._group);
this._background.hide();
},
_showUnlockDialog: function() {
if (this._dialog) {
log ('_showUnlockDialog called again when the dialog was already there');
return;
}
try {
this._dialog = new UnlockDialog.UnlockDialog();
this._dialog.connect('failed', Lang.bind(this, this._onUnlockFailed));
this._dialog.connect('unlocked', Lang.bind(this, this._onUnlockSucceded));
if (!this._dialog.open(global.get_current_time()))
throw new Error('open failed!')
this._dialog._group.raise_top();
} catch(e) {
// FIXME: this is for debugging purposes
logError(e, 'error while creating unlock dialog');
this._popModal();
}
},
_onUnlockFailed: function() {
// FIXME: for now, on failure we just destroy the dialog and create a new
// one (this is what gnome-screensaver does)
// in the future, we may want to go back to the lock screen instead
this._dialog.destroy();
this._dialog = null;
this._showUnlockDialog();
},
_onUnlockSucceded: function() {
this._dialog.destroy();
this._dialog = null;
this._popModal();
},
});