Compare commits

...

8 Commits

Author SHA1 Message Date
Giovanni Campagna
6e448a2711 ScreenShield: fix spacing of notifications and sources
Reduce padding around persistent sources, and ensure that spacing
around resident notifications is only applied once.
Also, add some padding to the clock.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
Giovanni Campagna
1d484e2278 ScreenSheild: make notification view scrollable
Place a maximum height on the notification view, and show scrollbars
if the list of persistent sources would overflow.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
Giovanni Campagna
0b7ca098ad ScreenShield: update the displayed title when the source changes
Notifications in the lock screen need to watch signals on source
and react accordingly.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
Jasper St. Pierre
5cb9aa9cf3 messageTray: Hook SourceActor up to source icon changes automatically
Instead of manually tracking source icon changes, or requiring a manual
call to _setSummaryIcon, add a way to emit a signal when we're guaranteed
the icon has been changed, and then the source actor will automatically
update the icon.
_setSummaryIcon is still available for sources such as the notification
daemon, that require special treatment for the summary icon (to be used
with tray icons)

https://bugzilla.gnome.org/show_bug.cgi?id=680426
2012-08-06 21:43:54 +02:00
Giovanni Campagna
0171e561f2 ScreenShield: bump the lock screen slightly when pressing a key
When pressing a key different from escape (one thus that has no
effect), bump the screen up, to indicate that it eats keyboard
input and it must be lifted up.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
Giovanni Campagna
82f7431a28 ScreenShield: handle Escape on the stage, not on the lock screen
This allows to press esc to unlock even if the focus is not on
the lock screen (for example after dismissing the auth failure
notification).

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
Giovanni Campagna
29958df7e7 ScreenShield: when explicitly locking, tween the shield from the top
The curtain should appear to be an overlay on top of the system,
and since it is lifted by dragging up, it makes sense to slide it
down on lock.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
Giovanni Campagna
2f990346df ScreenShield: blur and desaturate the screenshield background
The background is the same as the normal desktop, so we blur and
desaturate it to clearly show that it's not the normal system state.

Includes a noticeable slowdown due to GLSL shading and FBO redirection.

https://bugzilla.gnome.org/show_bug.cgi?id=681143
2012-08-06 21:43:54 +02:00
5 changed files with 106 additions and 45 deletions

View File

@ -1220,17 +1220,17 @@ StButton.popup-menu-item:insensitive {
padding-bottom: 12px; padding-bottom: 12px;
} }
#summary-notification-stack-scrollview { .summary-notification-stack-scrollview {
max-height: 18em; max-height: 18em;
padding-top: 6px; padding-top: 6px;
padding-bottom: 6px; padding-bottom: 6px;
} }
#summary-notification-stack-scrollview:ltr { .summary-notification-stack-scrollview:ltr {
padding-right: 8px; padding-right: 8px;
} }
#summary-notification-stack-scrollview:rtl { .summary-notification-stack-scrollview:rtl {
padding-left: 8px; padding-left: 8px;
} }
@ -2216,6 +2216,7 @@ StButton.popup-menu-item:insensitive {
text-shadow: 0px 1px 2px rgba(0,0,0,0.6); text-shadow: 0px 1px 2px rgba(0,0,0,0.6);
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
padding-bottom: 1.5em;
} }
.screen-shield-clock-time { .screen-shield-clock-time {
@ -2228,17 +2229,19 @@ StButton.popup-menu-item:insensitive {
} }
#screenShieldNotifications { #screenShieldNotifications {
border-radius: 24px; border-radius: 8px;
background-color: rgba(0.0, 0.0, 0.0, 0.9); background-color: rgba(0.0, 0.0, 0.0, 0.9);
border: 2px solid #868686; border: 2px solid #868686;
max-height: 500px;
padding: 12px 0;
} }
#screenShieldNotifications, .screen-shield-notifications-box { .screen-shield-notifications-box {
spacing: 8px; spacing: 12px;
} }
.screen-shield-notification-source { .screen-shield-notification-source {
padding: 24px 8px; padding: 0 24px;
spacing: 5px; spacing: 5px;
} }
@ -2253,3 +2256,12 @@ StButton.popup-menu-item:insensitive {
.screen-shield-notifications-box .notification { .screen-shield-notifications-box .notification {
background-color: transparent; background-color: transparent;
} }
/* Override padding on resident notifications, since
the notifications box has its own spacing
*/
.screen-shield-notifications-box .summary-notification-stack-scrollview {
padding-top: 0px;
padding-bottom: 0px;
}

View File

@ -1039,6 +1039,7 @@ const SourceActor = new Lang.Class({
_init: function(source, size) { _init: function(source, size) {
this._source = source; this._source = source;
this._size = size;
this.actor = new Shell.GenericContainer(); this.actor = new Shell.GenericContainer();
this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth)); this.actor.connect('get-preferred-width', Lang.bind(this, this._getPreferredWidth));
@ -1064,10 +1065,14 @@ const SourceActor = new Lang.Class({
this._source.connect('count-changed', Lang.bind(this, this._updateCount)); this._source.connect('count-changed', Lang.bind(this, this._updateCount));
this._updateCount(); this._updateCount();
this._source.connect('icon-updated', Lang.bind(this, this._updateIcon));
this._updateIcon();
}, },
setIcon: function(icon) { setIcon: function(icon) {
this._iconBin.child = icon; this._iconBin.child = icon;
this._iconSet = true;
}, },
_getPreferredWidth: function (actor, forHeight, alloc) { _getPreferredWidth: function (actor, forHeight, alloc) {
@ -1105,13 +1110,21 @@ const SourceActor = new Lang.Class({
this._counterBin.allocate(childBox, flags); this._counterBin.allocate(childBox, flags);
}, },
_updateIcon: function() {
if (this._actorDestroyed)
return;
if (!this._iconSet)
this._iconBin.child = this._source.createIcon(this._size);
},
_updateCount: function() { _updateCount: function() {
if (this._actorDestroyed) if (this._actorDestroyed)
return; return;
this._counterBin.visible = this._source.countVisible; this._counterBin.visible = this._source.countVisible;
this._counterLabel.set_text(this._source.count.toString()); this._counterLabel.set_text(this._source.count.toString());
}, }
}); });
const Source = new Lang.Class({ const Source = new Lang.Class({
@ -1133,7 +1146,6 @@ const Source = new Lang.Class({
this.notifications = []; this.notifications = [];
this.mainIcon = new SourceActor(this, this.ICON_SIZE); this.mainIcon = new SourceActor(this, this.ICON_SIZE);
this._setSummaryIcon(this.createIcon(this.ICON_SIZE));
}, },
_setCount: function(count, visible) { _setCount: function(count, visible) {
@ -1222,9 +1234,14 @@ const Source = new Lang.Class({
return false; return false;
}, },
iconUpdated: function() {
this.emit('icon-updated');
},
//// Protected methods //// //// Protected methods ////
_setSummaryIcon: function(icon) { _setSummaryIcon: function(icon) {
this.mainIcon.setIcon(icon); this.mainIcon.setIcon(icon);
this.iconUpdated();
}, },
open: function(notification) { open: function(notification) {
@ -1284,12 +1301,12 @@ const SummaryItem = new Lang.Class({
this._sourceBox.add(this._sourceTitleBin, { expand: true, y_fill: false }); this._sourceBox.add(this._sourceTitleBin, { expand: true, y_fill: false });
this.actor.child = this._sourceBox; this.actor.child = this._sourceBox;
this.notificationStackView = new St.ScrollView({ name: source.isChat ? '' : 'summary-notification-stack-scrollview', this.notificationStackView = new St.ScrollView({ style_class: source.isChat ? '' : 'summary-notification-stack-scrollview',
vscrollbar_policy: source.isChat ? Gtk.PolicyType.NEVER : Gtk.PolicyType.AUTOMATIC, vscrollbar_policy: source.isChat ? Gtk.PolicyType.NEVER : Gtk.PolicyType.AUTOMATIC,
hscrollbar_policy: Gtk.PolicyType.NEVER, hscrollbar_policy: Gtk.PolicyType.NEVER });
style_class: 'vfade' }); this.notificationStackView.add_style_class_name('vfade');
this.notificationStack = new St.BoxLayout({ name: 'summary-notification-stack', this.notificationStack = new St.BoxLayout({ style_class: 'summary-notification-stack',
vertical: true }); vertical: true });
this.notificationStackView.add_actor(this.notificationStack); this.notificationStackView.add_actor(this.notificationStack);
this._stackedNotifications = []; this._stackedNotifications = [];

View File

@ -557,7 +557,8 @@ const Source = new Lang.Class({
processNotification: function(notification, gicon) { processNotification: function(notification, gicon) {
if (gicon) if (gicon)
this._gicon = gicon; this._gicon = gicon;
this._setSummaryIcon(this.createIcon(this.ICON_SIZE)); if (!this.trayIcon)
this.iconUpdated();
let tracker = Shell.WindowTracker.get_default(); let tracker = Shell.WindowTracker.get_default();
if (notification.resident && this.app && tracker.focus_app == this.app) if (notification.resident && this.app && tracker.focus_app == this.app)
@ -625,7 +626,7 @@ const Source = new Lang.Class({
// notification-based icons (ie, not a trayicon) or if it was unset before // notification-based icons (ie, not a trayicon) or if it was unset before
if (!this.trayIcon) { if (!this.trayIcon) {
this.useNotificationIcon = false; this.useNotificationIcon = false;
this._setSummaryIcon(this.createIcon(this.ICON_SIZE)); this.iconUpdated();
} }
}, },

View File

@ -17,18 +17,23 @@ const Tweener = imports.ui.tweener;
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver'; const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
const LOCK_ENABLED_KEY = 'lock-enabled'; const LOCK_ENABLED_KEY = 'lock-enabled';
const CURTAIN_SLIDE_TIME = 1.2; const CURTAIN_SLIDE_TIME = 0.8;
// fraction of screen height the arrow must reach before completing // fraction of screen height the arrow must reach before completing
// the slide up automatically // the slide up automatically
const ARROW_DRAG_TRESHOLD = 0.1; const ARROW_DRAG_TRESHOLD = 0.1;
// The distance in px that the lock screen will move to when pressing
// a key that has no effect in the lock screen (bumping it)
const BUMP_SIZE = 25;
const BUMP_TIME = 0.3;
const SUMMARY_ICON_SIZE = 48; const SUMMARY_ICON_SIZE = 48;
// Lightbox fading times // Lightbox fading times
// STANDARD_FADE_TIME is used when the session goes idle, while // STANDARD_FADE_TIME is used when the session goes idle, while
// SHORT_FADE_TIME is used when requesting lock explicitly from the user menu // SHORT_FADE_TIME is used when requesting lock explicitly from the user menu
const STANDARD_FADE_TIME = 10; const STANDARD_FADE_TIME = 10;
const SHORT_FADE_TIME = 2; const SHORT_FADE_TIME = 0.8;
const Clock = new Lang.Class({ const Clock = new Lang.Class({
Name: 'ScreenShieldClock', Name: 'ScreenShieldClock',
@ -72,17 +77,18 @@ const NotificationsBox = new Lang.Class({
_init: function() { _init: function() {
this.actor = new St.BoxLayout({ vertical: true, this.actor = new St.BoxLayout({ vertical: true,
name: 'screenShieldNotifications', name: 'screenShieldNotifications',
margin_top: 20 style_class: 'screen-shield-notifications-box' });
});
this._residentNotificationBox = new St.BoxLayout({ vertical: true, this._residentNotificationBox = new St.BoxLayout({ vertical: true,
style_class: 'screen-shield-notifications-box' }); style_class: 'screen-shield-notifications-box' });
let scrollView = new St.ScrollView({ x_fill: false, x_align: St.Align.MIDDLE });
this._persistentNotificationBox = new St.BoxLayout({ vertical: true, this._persistentNotificationBox = new St.BoxLayout({ vertical: true,
style_class: 'screen-shield-notifications-box' }); style_class: 'screen-shield-notifications-box' });
scrollView.add_actor(this._persistentNotificationBox);
this.actor.add(this._residentNotificationBox, { x_fill: true }); this.actor.add(this._residentNotificationBox, { x_fill: true });
this.actor.add(this._persistentNotificationBox, { x_fill: false, x_align: St.Align.MIDDLE }); this.actor.add(scrollView, { x_fill: true, x_align: St.Align.MIDDLE });
this._items = []; this._items = [];
Main.messageTray.getSummaryItems().forEach(Lang.bind(this, function(item) { Main.messageTray.getSummaryItems().forEach(Lang.bind(this, function(item) {
@ -129,13 +135,11 @@ const NotificationsBox = new Lang.Class({
_makeNotificationSource: function(source) { _makeNotificationSource: function(source) {
let box = new St.BoxLayout({ style_class: 'screen-shield-notification-source' }); let box = new St.BoxLayout({ style_class: 'screen-shield-notification-source' });
let iconClone = source.createIcon(SUMMARY_ICON_SIZE);
let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE); let sourceActor = new MessageTray.SourceActor(source, SUMMARY_ICON_SIZE);
sourceActor.setIcon(iconClone);
box.add(sourceActor.actor, { y_fill: true }); box.add(sourceActor.actor, { y_fill: true });
let textBox = new St.BoxLayout({ vertical: true }); let textBox = new St.BoxLayout({ vertical: true });
box.add(textBox, { y_fill: true, expand: true }); box.add(textBox);
let label = new St.Label({ text: source.title, let label = new St.Label({ text: source.title,
style_class: 'screen-shield-notification-label' }); style_class: 'screen-shield-notification-label' });
@ -169,11 +173,12 @@ const NotificationsBox = new Lang.Class({
this._residentNotificationBox.add(item.notificationStackView); this._residentNotificationBox.add(item.notificationStackView);
} else { } else {
[obj.sourceBox, obj.countLabel] = this._makeNotificationSource(item.source); [obj.sourceBox, obj.countLabel] = this._makeNotificationSource(item.source);
this._persistentNotificationBox.add(obj.sourceBox); this._persistentNotificationBox.add(obj.sourceBox, { x_fill: false, x_align: St.Align.MIDDLE });
} }
obj.contentUpdatedId = item.connect('content-updated', Lang.bind(this, this._onItemContentUpdated)); obj.contentUpdatedId = item.connect('content-updated', Lang.bind(this, this._onItemContentUpdated));
obj.sourceCountChangedId = item.source.connect('count-changed', Lang.bind(this, this._onSourceCountChanged)); obj.sourceCountChangedId = item.source.connect('count-changed', Lang.bind(this, this._onSourceChanged));
obj.sourceTitleChangedId = item.source.connect('title-changed', Lang.bind(this, this._onSourceChanged));
obj.sourceDestroyId = item.source.connect('destroy', Lang.bind(this, this._onSourceDestroy)); obj.sourceDestroyId = item.source.connect('destroy', Lang.bind(this, this._onSourceDestroy));
this._items.push(obj); this._items.push(obj);
@ -194,7 +199,7 @@ const NotificationsBox = new Lang.Class({
this._updateItem(obj); this._updateItem(obj);
}, },
_onSourceCountChanged: function(source) { _onSourceChanged: function(source) {
let obj = this._items[this._findSource(source)]; let obj = this._items[this._findSource(source)];
this._updateItem(obj); this._updateItem(obj);
}, },
@ -274,13 +279,12 @@ const ScreenShield = new Lang.Class({
can_focus: true, can_focus: true,
layout_manager: new Clutter.BinLayout() layout_manager: new Clutter.BinLayout()
}); });
this._lockScreenGroup.connect('key-release-event',
Lang.bind(this, this._onLockScreenKeyRelease));
this._background = Meta.BackgroundActor.new_for_screen(global.screen); this._background = Meta.BackgroundActor.new_for_screen(global.screen);
this._lockScreenGroup.add_actor(this._background); this._background.add_effect(new Clutter.BlurEffect());
this._background.add_effect(new Clutter.DesaturateEffect({ factor: 0.6 }));
// FIXME: build the rest of the lock screen here this._lockScreenGroup.add_actor(this._background);
this._arrow = new St.DrawingArea({ style_class: 'arrow', this._arrow = new St.DrawingArea({ style_class: 'arrow',
reactive: true, reactive: true,
@ -329,13 +333,17 @@ const ScreenShield = new Lang.Class({
fadeFactor: 1 }); fadeFactor: 1 });
}, },
_onLockScreenKeyRelease: function(actor, event) { _onStageKeyRelease: function(actor, event) {
if (!this._isLocked)
return false;
if (event.get_key_symbol() == Clutter.KEY_Escape) { if (event.get_key_symbol() == Clutter.KEY_Escape) {
this._showUnlockDialog(true); this._showUnlockDialog(true);
return true; return true;
} }
return false; this._bumpLockScreen();
return true;
}, },
_drawArrow: function() { _drawArrow: function() {
@ -410,6 +418,21 @@ const ScreenShield = new Lang.Class({
this._showUnlockDialog(false); this._showUnlockDialog(false);
}, },
_bumpLockScreen: function() {
Tweener.removeTweens(this._lockScreenGroup);
Tweener.addTween(this._lockScreenGroup,
{ y: -BUMP_SIZE,
time: BUMP_TIME / 2,
transition: 'easeOutQuad',
onComplete: function() {
Tweener.addTween(this,
{ y: 0,
time: BUMP_TIME / 2,
transition: 'easeInQuad' });
}
});
},
_showUnlockDialog: function(animate) { _showUnlockDialog: function(animate) {
if (animate) { if (animate) {
// Tween the lock screen out of screen // Tween the lock screen out of screen
@ -473,27 +496,30 @@ const ScreenShield = new Lang.Class({
}, },
_resetLockScreen: function(animate) { _resetLockScreen: function(animate) {
this._lockScreenGroup.show();
this._arrow.show();
if (animate) { if (animate) {
this.actor.opacity = 0; this._lockScreenGroup.y = -global.screen_height;
Tweener.removeTweens(this.actor); Tweener.removeTweens(this._lockScreenGroup);
Tweener.addTween(this.actor, Tweener.addTween(this._lockScreenGroup,
{ opacity: 255, { y: 0,
time: SHORT_FADE_TIME, time: SHORT_FADE_TIME,
transition: 'easeOutQuad', transition: 'linear',
onComplete: function() { onComplete: function() {
this._lockScreenGroup.fixed_position_set = false;
this.emit('lock-screen-shown'); this.emit('lock-screen-shown');
}, },
onCompleteScope: this onCompleteScope: this
}); });
} else { } else {
this._lockScreenGroup.fixed_position_set = false;
this.emit('lock-screen-shown'); this.emit('lock-screen-shown');
} }
this._lockScreenGroup.fixed_position_set = false; if (!this._stageKeyHandler)
this._lockScreenGroup.show(); this._stageKeyHandler = global.stage.connect('key-release-event',
this._arrow.show(); Lang.bind(this, this._onStageKeyRelease));
this._lockScreenGroup.grab_key_focus();
}, },
// Some of the actors in the lock screen are heavy in // Some of the actors in the lock screen are heavy in
@ -542,6 +568,11 @@ const ScreenShield = new Lang.Class({
if (this._hasLockScreen) if (this._hasLockScreen)
this._clearLockScreen(); this._clearLockScreen();
if (this._stageKeyHandler) {
global.stage.disconnect(this._stageKeyHandler);
this._stageKeyHandler = 0;
}
if (this._keepDialog) { if (this._keepDialog) {
// The dialog must be kept alive, // The dialog must be kept alive,
// so immediately go back to it // so immediately go back to it

View File

@ -532,7 +532,7 @@ const ChatSource = new Lang.Class({
}, },
_updateAvatarIcon: function() { _updateAvatarIcon: function() {
this._setSummaryIcon(this.createIcon(this.ICON_SIZE)); this.iconUpdated();
this._notification.update(this._notification.title, null, { customContent: true }); this._notification.update(this._notification.title, null, { customContent: true });
}, },