From d6eea0e380afc544b90a964e29e899c9fb0066bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sat, 14 Feb 2015 03:17:16 +0100 Subject: [PATCH] dateMenu: Show indicator for messages that skipped banner mode The summary may contain notifications that have not been seen by the user and won't be shown as banner. Currently this is only the case for resident notifications that are emitted by the focused app, but it will become more common as we will start limiting the number of queued notifications. Indicate to the user that more notifications are available by displaying a small dot in the top bar button. https://bugzilla.gnome.org/show_bug.cgi?id=744850 --- js/ui/dateMenu.js | 73 +++++++++++++++++++++++++++++++++++++++++++- js/ui/messageTray.js | 4 +++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/js/ui/dateMenu.js b/js/ui/dateMenu.js index 4e88411a5..7e2cb5c2a 100644 --- a/js/ui/dateMenu.js +++ b/js/ui/dateMenu.js @@ -220,6 +220,69 @@ const WorldClocksSection = new Lang.Class({ } }); +const MessagesIndicator = new Lang.Class({ + Name: 'MessagesIndicator', + + _init: function() { + this.actor = new St.Label({ text: '⚫', visible: false, y_expand: true, + y_align: Clutter.ActorAlign.CENTER }); + + this._sources = []; + + Main.messageTray.connect('source-added', Lang.bind(this, this._onSourceAdded)); + Main.messageTray.connect('source-removed', Lang.bind(this, this._onSourceRemoved)); + + let sources = Main.messageTray.getSources(); + sources.forEach(Lang.bind(this, function(source) { this._onSourceAdded(null, source); })); + }, + + _onSourceAdded: function(tray, source) { + source.connect('count-updated', Lang.bind(this, this._updateCount)); + this._sources.push(source); + this._updateCount(); + }, + + _onSourceRemoved: function(tray, source) { + this._sources.splice(this._sources.indexOf(source), 1); + this._updateCount(); + }, + + _updateCount: function() { + let count = 0; + this._sources.forEach(Lang.bind(this, + function(source) { + count += source.unseenCount; + })); + count -= Main.messageTray.queueCount; + + this.actor.visible = (count > 0); + } +}); + +const IndicatorPad = new Lang.Class({ + Name: 'IndicatorPad', + Extends: St.Widget, + + _init: function(actor) { + this._source = actor; + this._source.connect('notify::visible', + Lang.bind(this, this.queue_relayout)); + this.parent(); + }, + + vfunc_get_preferred_width: function(container, forHeight) { + if (this._source.visible) + return this._source.get_preferred_width(forHeight); + return [0, 0]; + }, + + vfunc_get_preferred_height: function(container, forWidth) { + if (this._source.visible) + return this._source.get_preferred_height(forWidth); + return [0, 0]; + } +}); + const FreezableBinLayout = new Lang.Class({ Name: 'FreezableBinLayout', Extends: Clutter.BinLayout, @@ -269,10 +332,18 @@ const DateMenuButton = new Lang.Class({ this.parent(menuAlignment); this._clockDisplay = new St.Label({ y_align: Clutter.ActorAlign.CENTER }); + this._indicator = new MessagesIndicator(); + + let box = new St.BoxLayout(); + box.add_actor(new IndicatorPad(this._indicator.actor)); + box.add_actor(this._clockDisplay); + box.add_actor(this._indicator.actor); + this.actor.label_actor = this._clockDisplay; - this.actor.add_actor(this._clockDisplay); + this.actor.add_actor(box); this.actor.add_style_class_name ('clock-display'); + let layout = new FreezableBinLayout(); let bin = new St.Widget({ layout_manager: layout }); this.menu.box.add_child(bin); diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js index 7d22a425b..eea354cf7 100644 --- a/js/ui/messageTray.js +++ b/js/ui/messageTray.js @@ -1456,6 +1456,10 @@ const MessageTray = new Lang.Class({ } }, + get queueCount() { + return this._notificationQueue.length; + }, + contains: function(source) { return this._sources.has(source); },