screenShield: add initial functionality

We are replacing the gnome-screensaver module with with a screen shield
that is part of gnome-shell.

This patch fades out the screen on idle and shows a shield with a background
image when there is activity again. The shield can be removed with a key or
button press.
This commit is contained in:
Marina Zhurakhinskaya 2012-02-06 17:28:48 -05:00
parent 0b8470421c
commit 478e546a77
6 changed files with 124 additions and 12 deletions

View File

@ -1717,7 +1717,7 @@ StScrollBar StButton#vhandle:hover
}
.lightbox {
background-color: rgba(0, 0, 0, 0.4);
background-color: black;
}
.flashspot {

View File

@ -78,6 +78,7 @@ nobase_dist_js_DATA = \
ui/popupMenu.js \
ui/remoteSearch.js \
ui/runDialog.js \
ui/screenShield.js \
ui/scripting.js \
ui/search.js \
ui/searchDisplay.js \

View File

@ -8,6 +8,8 @@ const St = imports.gi.St;
const Params = imports.misc.params;
const Tweener = imports.ui.tweener;
const DEFAULT_FADE_FACTOR = 0.4;
/**
* Lightbox:
* @container: parent Clutter.Container
@ -15,7 +17,8 @@ const Tweener = imports.ui.tweener;
* - inhibitEvents: whether to inhibit events for @container
* - width: shade actor width
* - height: shade actor height
* - fadeTime: seconds used to fade in/out
* - fadeInTime: seconds used to fade in
* - fadeOutTime: seconds used to fade out
*
* Lightbox creates a dark translucent "shade" actor to hide the
* contents of @container, and allows you to specify particular actors
@ -38,12 +41,16 @@ const Lightbox = new Lang.Class({
params = Params.parse(params, { inhibitEvents: false,
width: null,
height: null,
fadeTime: null
fadeInTime: null,
fadeOutTime: null,
fadeFactor: DEFAULT_FADE_FACTOR
});
this._container = container;
this._children = container.get_children();
this._fadeTime = params.fadeTime;
this._fadeInTime = params.fadeInTime;
this._fadeOutTime = params.fadeOutTime;
this._fadeFactor = params.fadeFactor;
this.actor = new St.Bin({ x: 0,
y: 0,
style_class: 'lightbox',
@ -52,6 +59,7 @@ const Lightbox = new Lang.Class({
container.add_actor(this.actor);
this.actor.raise_top();
this.actor.hide();
this.shown = false;
this.actor.connect('destroy', Lang.bind(this, this._onDestroy));
@ -93,24 +101,29 @@ const Lightbox = new Lang.Class({
},
show: function() {
if (this._fadeTime) {
if (this._fadeInTime) {
this.actor.opacity = 0;
Tweener.addTween(this.actor,
{ opacity: 255,
time: this._fadeTime,
transition: 'easeOutQuad'
{ opacity: 255 * this._fadeFactor,
time: this._fadeInTime,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
this.shown = true;
})
});
} else {
this.actor.opacity = 255;
this.actor.opacity = 255 * this._fadeFactor;
this.shown = true;
}
this.actor.show();
},
hide: function() {
if (this._fadeTime) {
this.shown = false;
if (this._fadeOutTime) {
Tweener.addTween(this.actor,
{ opacity: 0,
time: this._fadeTime,
time: this._fadeOutTime,
transition: 'easeOutQuad',
onComplete: Lang.bind(this, function() {
this.actor.hide();

View File

@ -29,6 +29,7 @@ const LookingGlass = imports.ui.lookingGlass;
const NetworkAgent = imports.ui.networkAgent;
const NotificationDaemon = imports.ui.notificationDaemon;
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
const ScreenShield = imports.ui.screenShield;
const Scripting = imports.ui.scripting;
const ShellDBus = imports.ui.shellDBus;
const TelepathyClient = imports.ui.telepathyClient;
@ -52,6 +53,7 @@ let runDialog = null;
let lookingGlass = null;
let wm = null;
let messageTray = null;
let screenShield = null;
let notificationDaemon = null;
let windowAttentionHandler = null;
let telepathyClient = null;
@ -211,6 +213,7 @@ function start() {
panel = new Panel.Panel();
wm = new WindowManager.WindowManager();
messageTray = new MessageTray.MessageTray();
screenShield = new ScreenShield.ScreenShield();
keyboard = new Keyboard.Keyboard();
notificationDaemon = new NotificationDaemon.NotificationDaemon();
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
@ -670,6 +673,10 @@ function _findModal(actor) {
return -1;
}
function isInModalStack(actor) {
return _findModal(actor) != -1;
}
/**
* pushModal:
* @actor: #ClutterActor which will be given keyboard focus

90
js/ui/screenShield.js Normal file
View File

@ -0,0 +1,90 @@
// -*- 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 LoginDialog = imports.gdm.loginDialog;
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._group = new St.Group({ 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._group.connect('key-press-event', Lang.bind(this, this._onKeyPressEvent));
this._group.connect('button-press-event', Lang.bind(this, this._onButtonPressEvent));
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");
this._group.reactive = true;
Main.pushModal(this._group);
this._lightbox.show();
} else {
let lightboxWasShown = this._lightbox.shown;
this._lightbox.hide();
if (lightboxWasShown && this._settings.get_boolean(LOCK_ENABLED_KEY)) {
this._background.show();
this._background.raise_top();
} else {
this._popModal();
}
}
},
_popModal: function() {
this._group.reactive = false;
if (Main.isInModalStack(this._group))
Main.popModal(this._group);
this._background.hide();
},
_onKeyPressEvent: function(object, keyPressEvent) {
log("in _onKeyPressEvent - lock is enabled: " + this._settings.get_boolean(LOCK_ENABLED_KEY));
this._popModal();
},
_onButtonPressEvent: function(object, buttonPressEvent) {
log("in _onButtonPressEvent - lock is enabled: " + this._settings.get_boolean(LOCK_ENABLED_KEY));
this._popModal();
},
});

View File

@ -301,7 +301,8 @@ const WindowClone = new Lang.Class({
if (!this._zoomLightbox)
this._zoomLightbox = new Lightbox.Lightbox(Main.uiGroup,
{ fadeTime: LIGHTBOX_FADE_TIME });
{ fadeInTime: LIGHTBOX_FADE_TIME,
fadeOutTime: LIGHTBOX_FADE_TIME });
this._zoomLightbox.show();
this._zoomLocalOrig = new ScaledPoint(this.actor.x, this.actor.y, this.actor.scale_x, this.actor.scale_y);