From bbbb6b685ff7c618426ce1e400fc2e36fc0e6635 Mon Sep 17 00:00:00 2001 From: Marina Zhurakhinskaya Date: Mon, 6 Feb 2012 17:28:48 -0500 Subject: [PATCH] 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. --- data/theme/gnome-shell.css | 2 +- js/Makefile.am | 1 + js/ui/lightbox.js | 33 +++++++++----- js/ui/main.js | 7 +++ js/ui/screenShield.js | 90 ++++++++++++++++++++++++++++++++++++++ js/ui/workspace.js | 3 +- 6 files changed, 124 insertions(+), 12 deletions(-) create mode 100644 js/ui/screenShield.js diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css index a229653bd..32ab39392 100644 --- a/data/theme/gnome-shell.css +++ b/data/theme/gnome-shell.css @@ -1715,7 +1715,7 @@ StScrollBar StButton#vhandle:hover } .lightbox { - background-color: rgba(0, 0, 0, 0.4); + background-color: black; } .flashspot { diff --git a/js/Makefile.am b/js/Makefile.am index e7751cce4..a422abc2e 100644 --- a/js/Makefile.am +++ b/js/Makefile.am @@ -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 \ diff --git a/js/ui/lightbox.js b/js/ui/lightbox.js index aa1516094..c6261dd1d 100644 --- a/js/ui/lightbox.js +++ b/js/ui/lightbox.js @@ -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(); diff --git a/js/ui/main.js b/js/ui/main.js index f1795946f..30e3f6db1 100644 --- a/js/ui/main.js +++ b/js/ui/main.js @@ -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; @@ -51,6 +52,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; @@ -216,6 +218,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(); @@ -621,6 +624,10 @@ function _findModal(actor) { return -1; } +function isInModalStack(actor) { + return _findModal(actor) != -1; +} + /** * pushModal: * @actor: #ClutterActor which will be given keyboard focus diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js new file mode 100644 index 000000000..1266550c2 --- /dev/null +++ b/js/ui/screenShield.js @@ -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.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._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(); + }, +}); diff --git a/js/ui/workspace.js b/js/ui/workspace.js index a1631a00a..4f3edfe7d 100644 --- a/js/ui/workspace.js +++ b/js/ui/workspace.js @@ -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);