summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasper St. Pierre <jstpierre@mecheye.net>2014-06-13 12:08:09 -0400
committerJasper St. Pierre <jstpierre@mecheye.net>2014-06-13 14:23:24 -0400
commit50395cded88773f86200a51ebffc1c9cc0579379 (patch)
treef1038daa922a91eb58d3fd96df44418f6530ca98
parente8ae8f75a058f2944125adc1ae09ff1a4abf0f2b (diff)
downloadgnome-shell-wip/notif-d3.tar.gz
-rw-r--r--data/theme/gnome-shell.css4
-rw-r--r--js/ui/main.js2
-rw-r--r--js/ui/messageTray.js89
-rw-r--r--js/ui/panel.js47
4 files changed, 139 insertions, 3 deletions
diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css
index 73f6f20cc..fa378db8e 100644
--- a/data/theme/gnome-shell.css
+++ b/data/theme/gnome-shell.css
@@ -2591,3 +2591,7 @@ StScrollBar StButton#vhandle:active {
-boxpointer-gap: 4px;
-arrow-rise: 0px;
}
+
+.top-bar-notification-preview {
+ font-weight: normal;
+}
diff --git a/js/ui/main.js b/js/ui/main.js
index 36c374f60..50b22fbaf 100644
--- a/js/ui/main.js
+++ b/js/ui/main.js
@@ -150,8 +150,8 @@ function _initializeUI() {
if (LoginManager.canLock())
screenShield = new ScreenShield.ScreenShield();
- panel = new Panel.Panel();
messageTray = new MessageTray.MessageTray();
+ panel = new Panel.Panel();
keyboard = new Keyboard.Keyboard();
notificationDaemon = new NotificationDaemon.NotificationDaemon();
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js
index c6e8c551d..86138059a 100644
--- a/js/ui/messageTray.js
+++ b/js/ui/messageTray.js
@@ -559,6 +559,8 @@ const Notification = new Lang.Class({
this._buttonBox.destroy_all_children();
}
+ this.gicon = params.gicon;
+
if (this._icon && (params.gicon || params.clear)) {
this._icon.destroy();
this._icon = null;
@@ -603,6 +605,8 @@ const Notification = new Lang.Class({
// is done correctly automatically.
this.actor.set_text_direction(titleDirection);
+ this.bannerBodyText = banner;
+
this._bodyUrlHighlighter.setMarkup(banner, params.bannerMarkup);
if (this._soundName != params.soundName ||
@@ -918,11 +922,94 @@ const Source = new Lang.Class({
});
Signals.addSignalMethods(Source.prototype);
+const TopBarNotificationPreview = new Lang.Class({
+ Name: 'TopBarNotificationPreview',
+
+ _init: function() {
+ this.actor = new St.BoxLayout({ style_class: 'top-bar-notification-preview' });
+
+ this._icon = new St.Icon({ icon_size: 22 });
+ this.actor.add_child(this._icon);
+
+ this._title = new St.Label({ style_class: 'top-bar-notification-preview-title' });
+ this.actor.add_child(this._title);
+
+ this._body = new St.Label({ style_class: 'top-bar-notification-preview-body' });
+ this.actor.add_child(this._body);
+ },
+
+ setNotification: function(notification) {
+ this._icon.gicon = notification.gicon;
+
+ let title = notification.title;
+ title = title ? _fixMarkup(title.replace(/\n/g, ' '), false) : '';
+ this._title.clutter_text.set_markup('<b>' + title + '</b>');
+
+ this._body.clutter_text.set_text(_fixMarkup(notification.bannerBodyText, false));
+ },
+});
+
+const TopBarNotificationController = new Lang.Class({
+ Name: 'TopBarNotificationController',
+
+ _init: function() {
+ this.actor = new St.Widget();
+
+ this._notificationPreview = new TopBarNotificationPreview();
+ this.actor.add_child(this._notificationPreview.actor);
+
+ this._notificationQueue = [];
+ this._timeoutId = 0;
+ },
+
+ _timeout: function() {
+ this._notificationQueue.shift();
+ this._update();
+ this._timeoutId = 0;
+ return GLib.SOURCE_REMOVE;
+ },
+
+ _ensureTimeout: function() {
+ if (this._timeoutId == 0)
+ this._timeoutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, 2, Lang.bind(this, this._timeout));
+ },
+
+ get hasNotification() {
+ return (this._notificationQueue.length > 0);
+ },
+
+ _update: function() {
+ if (this._notificationQueue.length > 0) {
+ let notification = this._notificationQueue[0];
+ this._notificationPreview.setNotification(notification);
+
+ this._ensureTimeout();
+ }
+
+ this.emit('updated');
+ },
+
+ pushNotification: function(notification) {
+ this._notificationQueue.push(notification);
+
+ notification.connect('destroy', Lang.bind(this, function() {
+ let idx = this._notificationQueue.indexOf(notification);
+ this._notificationQueue.splice(idx, 1);
+ this._update();
+ }));
+
+ this._update();
+ },
+});
+Signals.addSignalMethods(TopBarNotificationController.prototype);
+
const MessageTray = new Lang.Class({
Name: 'MessageTray',
_init: function() {
this._sources = new Map();
+
+ this.notificationPreview = new TopBarNotificationController();
},
_expireNotification: function() {
@@ -1003,7 +1090,7 @@ const MessageTray = new Lang.Class({
},
_onNotify: function(source, notification) {
- // Fill in here.
+ this.notificationPreview.pushNotification(notification);
},
});
Signals.addSignalMethods(MessageTray.prototype);
diff --git a/js/ui/panel.js b/js/ui/panel.js
index 750149e58..d750a5aea 100644
--- a/js/ui/panel.js
+++ b/js/ui/panel.js
@@ -862,11 +862,56 @@ const AggregateMenu = new Lang.Class({
},
});
+const DateMenuButton2 = new Lang.Class({
+ Name: 'DateMenuButton2',
+
+ _init: function() {
+ this.container = new St.Widget({ layout_manager: new Clutter.BinLayout() });
+
+ this._notificationPreview = Main.messageTray.notificationPreview;
+ this.container.add_child(this._notificationPreview.actor);
+ this._notificationPreview.actor.x_expand = true;
+ this._notificationPreview.actor.x_align = Clutter.ActorAlign.CENTER;
+ this._notificationPreview.connect('updated', Lang.bind(this, this._sync));
+
+ let dateMenu = new imports.ui.dateMenu.DateMenuButton();
+ this._clock = dateMenu.container;
+ this._clock.x_expand = true;
+ this._clock.x_align = Clutter.ActorAlign.CENTER;
+ this.container.add_child(this._clock);
+
+ this._currentlyShowing = 'clock';
+ this._sync();
+ },
+
+ _show: function(which, animate) {
+ if (this._currentlyShowing == which)
+ return;
+
+ this._currentlyShowing = which;
+ if (this._currentlyShowing == 'clock') {
+ this._notificationPreview.actor.visible = false;
+ this._clock.visible = true;
+ } else if (this._currentlyShowing == 'notification') {
+ this._notificationPreview.actor.visible = true;
+ this._clock.visible = false;
+ }
+ },
+
+ _sync: function() {
+ if (this._currentlyShowing == 'clock' && this._notificationPreview.hasNotification)
+ this._show('notification', true);
+ else if (this._currentlyShowing == 'notification' && !this._notificationPreview.hasNotification)
+ this._show('clock', false);
+ },
+});
+Signals.addSignalMethods(DateMenuButton2.prototype);
+
const PANEL_ITEM_IMPLEMENTATIONS = {
'activities': ActivitiesButton,
'aggregateMenu': AggregateMenu,
'appMenu': AppMenuButton,
- 'dateMenu': imports.ui.dateMenu.DateMenuButton,
+ 'dateMenu': DateMenuButton2,
'a11y': imports.ui.status.accessibility.ATIndicator,
'a11yGreeter': imports.ui.status.accessibility.ATGreeterIndicator,
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,