After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 745910 - Classic mode - move notification banners to the top-right
Classic mode - move notification banners to the top-right
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: message-tray
3.15.x
Other Linux
: Normal normal
: ---
Assigned To: gnome-shell-maint
gnome-shell-maint
Depends on:
Blocks:
 
 
Reported: 2015-03-09 18:20 UTC by Allan Day
Modified: 2015-04-30 16:33 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Hide banners when any menu in box of time+date dropdown is open (2.24 KB, patch)
2015-04-18 12:21 UTC, Meet
needs-work Details | Review
Move notification banners below the time+date dropdown (1.69 KB, patch)
2015-04-19 13:43 UTC, Meet
needs-work Details | Review
messageTray: Move notification banners below the time+date dropdown to reinforce their relationship (2.29 KB, patch)
2015-04-22 13:06 UTC, Meet
none Details | Review
messageTray: Move notification banners below the time+date dropdown to reinforce their relationship (2.31 KB, patch)
2015-04-22 13:15 UTC, Meet
needs-work Details | Review
panel: Hide banners when any menu in box of time+date dropdown is open (1.43 KB, patch)
2015-04-22 13:27 UTC, Meet
none Details | Review
panel: Hide banners when any menu in box of time+date dropdown is open (1.41 KB, patch)
2015-04-22 13:31 UTC, Meet
needs-work Details | Review
Not working temp commit (2.45 KB, patch)
2015-04-23 10:43 UTC, Meet
none Details | Review
Move notification banners below time+date dropdown (1.81 KB, patch)
2015-04-23 16:09 UTC, Meet
none Details | Review
Move notification banners below time+date dropdown (1.81 KB, patch)
2015-04-23 16:12 UTC, Meet
none Details | Review
Hide banners when notification banners and opened menus may have overlapped (2.11 KB, patch)
2015-04-23 16:47 UTC, Meet
none Details | Review
panel: Move notification banners below time+date dropdown (2.20 KB, patch)
2015-04-25 07:52 UTC, Florian Müllner
committed Details | Review
panel: Block banners when opening menus that would overlap (2.34 KB, patch)
2015-04-25 07:53 UTC, Florian Müllner
committed Details | Review
panel: Set up 'open-state-changed' handler on menu changes (4.00 KB, patch)
2015-04-30 12:22 UTC, Florian Müllner
committed Details | Review

Description Allan Day 2015-03-09 18:20:52 UTC
In classic mode, the time and date drop down is located to the right side of the top panel. It would be good if notification banners popped up below this, in order to reinforce the relationship between the two elements.
Comment 1 Florian Müllner 2015-03-09 18:26:11 UTC
It's not only the notification position (which is relatively easy to change): we are hiding banners while the time+date drop-down is shown, but with banners on the right, other menus like the system one get in the way of banners just as much as the calendar drop-down.
I think this would be best addressed generically in gnome-shell proper, by setting the banner position according to the panel box (left, center, right) the dateMenu is in, and extend the hide-banner behavior to all menus which are in the same box.
Comment 2 Jasper St. Pierre (not reading bugmail) 2015-03-09 18:27:22 UTC
Wouldn't placing notifications at the top right obscure the window close button?
Comment 3 Allan Day 2015-03-09 18:43:43 UTC
(In reply to Jasper St. Pierre from comment #2)
> Wouldn't placing notifications at the top right obscure the window close
> button?

You could offset it from the screen edge? The clock isn't right in the corner, anyway.
Comment 4 Meet 2015-04-18 12:21:48 UTC
Created attachment 301896 [details] [review]
Hide banners when any menu in box of time+date dropdown is open
Comment 5 Meet 2015-04-19 13:43:17 UTC
Created attachment 301929 [details] [review]
Move notification banners below the time+date dropdown
Comment 6 Florian Müllner 2015-04-21 20:06:48 UTC
Please provide better commit messages - a one-line subject which describes what the patch does is not enough, you should also outline the reason for the change[0]. You will likely find that the patches are in the wrong order then (the reason for moving banners is that there's a strong relationship with the calendar drop-down, which holds the message list; without that change, there is no reason for hiding banners when opening a menu in the same group)

[0] http://lists.cairographics.org/archives/cairo/2008-September/015092.html
Comment 7 Florian Müllner 2015-04-21 20:07:03 UTC
Review of attachment 301896 [details] [review]:

::: js/ui/panel.js
@@ +980,3 @@
         let nChildren = box.get_n_children();
 
+        this._boxWithDateMenu = (elements.indexOf('dateMenu') != -1) ? box : this._boxWithDateMenu;

This does not handle the case of no dateMenu (e.g. by default the dateMenu is centered and hidden on the lock screen, however boxWithDateMenu will still point to the centerBox)

@@ +1014,3 @@
+            indicator.menu.connect('open-state-changed', Lang.bind(this, function(menu, isOpen) {
+                Main.messageTray.bannerBlocked = isOpen;
+            }));

The signal is never disconnected, so menus that *were* in the same group as the dateMenu will still block notification banners.
Comment 8 Florian Müllner 2015-04-21 20:07:11 UTC
Review of attachment 301929 [details] [review]:

::: js/ui/messageTray.js
@@ +977,3 @@
+    // so that they appear below the dateMenu
+    updateAlignment: function(boxWithDateMenu) {
+        if (boxWithDateMenu == "panelLeft")

Ugh, no - actor names are used as element IDs in CSS and are useful for debugging, but don't treat them as public API. This should be something like setBannerAlignment(align), so you don't need any implementation details from panel.js or comments explaining what the function does.
Comment 9 Meet 2015-04-22 13:06:33 UTC
Created attachment 302146 [details] [review]
messageTray: Move notification banners below the time+date dropdown to reinforce their relationship
Comment 10 Meet 2015-04-22 13:15:38 UTC
Created attachment 302148 [details] [review]
messageTray: Move notification banners below the time+date dropdown to reinforce their relationship
Comment 11 Meet 2015-04-22 13:27:13 UTC
Created attachment 302151 [details] [review]
panel: Hide banners when any menu in box of time+date dropdown is open
Comment 12 Meet 2015-04-22 13:31:36 UTC
Created attachment 302152 [details] [review]
panel: Hide banners when any menu in box of time+date dropdown is open

https://bugzilla.gnome.org/show_bug.cgi?id=745910

panel: Hide banners when any menu in box of time+date dropdown is open
Comment 13 Florian Müllner 2015-04-22 14:17:30 UTC
Review of attachment 302148 [details] [review]:

The commit message still needs improvement - I did not suggest to cramp everything into a super-long subject line (it should be limited to around 72 characters!), but to add some reasoning to the *body* of the commit message.

::: js/ui/messageTray.js
@@ +977,3 @@
     },
 
+    setBannerAlignment: function(align) {

Please pass in the alignment, not some string

::: js/ui/panel.js
@@ +980,3 @@
         let nChildren = box.get_n_children();
 
+        this._boxWithDateMenu = (elements.indexOf('dateMenu') != -1) ? box : this._boxWithDateMenu;

As noted in the previous review, this will not catch a removed dateMenu.
Comment 14 Florian Müllner 2015-04-22 14:18:11 UTC
Review of attachment 302152 [details] [review]:

In addition to the error pointed out below, the commit message is missing a body

::: js/ui/panel.js
@@ +1013,3 @@
         let destroyId = indicator.connect('destroy', Lang.bind(this, function(emitter) {
+            if (blockBannerSignal)
+                indicator.menu.disconnect(blockBannerSignal);

This does not work for indicators that are hidden/moved rather than destroyed, namely *all* the built-in ones
Comment 15 Meet 2015-04-22 14:47:28 UTC
(In reply to Florian Müllner from comment #13) 
> ::: js/ui/panel.js
> @@ +980,3 @@
>          let nChildren = box.get_n_children();
>  
> +        this._boxWithDateMenu = (elements.indexOf('dateMenu') != -1) ? box
> : this._boxWithDateMenu;
> 
> As noted in the previous review, this will not catch a removed dateMenu.

But if there's no dateMenu shouldn't the default alignment be Center?
Comment 16 Florian Müllner 2015-04-22 14:51:03 UTC
(In reply to Meet from comment #15)
> But if there's no dateMenu shouldn't the default alignment be Center?

It should be *some* alignment, and 'center' looks like a reasonable pick.
Comment 17 Florian Müllner 2015-04-22 14:56:21 UTC
(In reply to Florian Müllner from comment #16)
> (In reply to Meet from comment #15)
> > But if there's no dateMenu shouldn't the default alignment be Center?
> 
> It should be *some* alignment, and 'center' looks like a reasonable pick.

I guess you could make a point for the current behavior of "wherever the dateMenu used to be", but that would at least need a comment
Comment 18 Meet 2015-04-22 15:23:12 UTC
(In reply to Florian Müllner from comment #14)
> Review of attachment 302152 [details] [review] [review]:
> 
> In addition to the error pointed out below, the commit message is missing a
> body
> 
> ::: js/ui/panel.js
> @@ +1013,3 @@
>          let destroyId = indicator.connect('destroy', Lang.bind(this,
> function(emitter) {
> +            if (blockBannerSignal)
> +                indicator.menu.disconnect(blockBannerSignal);
> 
> This does not work for indicators that are hidden/moved rather than
> destroyed, namely *all* the built-in ones

How are indicators moved? ( I cant find a function for that. If an indicator is hidden its state can never be changed so what is the purpose of disconnecting the signal?
Comment 19 Florian Müllner 2015-04-22 15:34:48 UTC
(In reply to Meet from comment #18)
> > This does not work for indicators that are hidden/moved rather than
> > destroyed, namely *all* the built-in ones
> 
> How are indicators moved?

https://git.gnome.org/browse/gnome-shell/tree/js/ui/panel.js#n994


> If an indicator is hidden its state can never be changed so what is 
> the purpose of disconnecting the signal?

True, it just seems easier to remove the connection when the indicator is no longer in the same box as the dateMenu (including the "no box" case) instead of checking whether the indicator is still in the same box as the dateMenu the next time it is shown.
Comment 20 Florian Müllner 2015-04-23 09:31:24 UTC
Some more thoughts on this:

Banners should be blocked when a menu is in the way, which is not necessarily the dateMenu box in the case where the dateMenu is missing. So you either need to handle that case when checking for the box, or lie and set _boxWithDateMenu to centerBox.
I think a nicer way than either option is to reflect the intention of the code, and set the banner alignment from position of the dateMenu (falling back to centering as you do now), then figure out whether a menu should block banners from that. Something like:

if (indicator._openChangedId > 0)
    indicator.menu.disconnect(indicator._openChangedId);
indicator._openChangedId = 0;

if (indicator.menu)
    indicator._openChangedId = indicator.menu.connect('open-state-changed',
        Lang.bind(this, function(menu, isOpen) {
            let boxes = { Clutter.ActorAlign.START: this._leftBox,
                          Clutter.ActorAlign.END: this._rightBox,
                          Clutter.ActorAlign.CENTER: this._centerBox };
            if (boxes[this._bannerAlignment] == box)
                Main.messageTray.bannerBlocked = isOpen;
        }));
Comment 21 Meet 2015-04-23 10:43:46 UTC
Created attachment 302211 [details] [review]
Not working temp commit
Comment 22 Meet 2015-04-23 10:45:55 UTC
It builds correctly but exits on execution with error :

(gnome-shell:23009): Gjs-CRITICAL **: JS ERROR: SyntaxError: missing : after property id @ resource:///org/gnome/shell/ui/panel.js:986
** Message: Execution of main.js threw exception: JS_EvaluateScript() failed

There is no missing ':'? Any help?
Comment 23 Florian Müllner 2015-04-23 15:26:39 UTC
It's complaining about non-string property names in an object literal - this would work:

let alignments = {};
alignments[this._leftBox] = Clutter.ActorAlign.LEFT;
alignments[this._rightBox] = Clutter.ActorAlign.RIGHT;

I'd just use

if (panel.left.indexOf('dateMenu') != -1)
    this._bannerAlignment = Clutter.ActorAlign.LEFT;
else if (panel.right.indexOf('dateMenu') != -1)
    this._bannerAlignment = Clutter.ActorAlign.RIGHT;
else
    this._bannerAlignment = Clutter.ActorAlign.CENTER;
Main.messageTray.setBannerAlignment(this._bannerAlignment);

It's not really more code, and the fallback is in the right place ...

(Another option would be to use getters/setters in MessageTray, so that bannerAlignment appears as a public property:

get bannerAlignment() {
    return this._bannerBin.get_x_align();
},

set bannerAlignment(align) {
    this._bannerBin.set_x_align(align);
}

Then you would not have to keep a separate _bannerAlignment property in panel ...
Comment 24 Meet 2015-04-23 16:09:42 UTC
Created attachment 302232 [details] [review]
Move notification banners below time+date dropdown

This enforces the relationship between the two.
Comment 25 Meet 2015-04-23 16:12:37 UTC
Created attachment 302234 [details] [review]
Move notification banners below time+date dropdown

This reinforces the relationship between the two.
Comment 26 Meet 2015-04-23 16:14:22 UTC
(In reply to Florian Müllner from comment #20)
> if (indicator.menu)
>     indicator._openChangedId = indicator.menu.connect('open-state-changed',
>         Lang.bind(this, function(menu, isOpen) {
>             let boxes = { Clutter.ActorAlign.START: this._leftBox,
>                           Clutter.ActorAlign.END: this._rightBox,
>                           Clutter.ActorAlign.CENTER: this._centerBox };
>             if (boxes[this._bannerAlignment] == box)
>                 Main.messageTray.bannerBlocked = isOpen;
>         }));

Wouldnt this not work due to the same reason as above?
Comment 27 Meet 2015-04-23 16:17:18 UTC
(In reply to Florian Müllner from comment #20)

> if (indicator._openChangedId > 0)
>     indicator.menu.disconnect(indicator._openChangedId);
> indicator._openChangedId = 0;

What is indicator._openChangedId ?
Comment 28 Meet 2015-04-23 16:47:09 UTC
Created attachment 302242 [details] [review]
Hide banners when notification banners and opened menus may have overlapped
Comment 29 Meet 2015-04-23 16:49:03 UTC
(In reply to Meet from comment #27)
> (In reply to Florian Müllner from comment #20)
> 
> > if (indicator._openChangedId > 0)
> >     indicator.menu.disconnect(indicator._openChangedId);
> > indicator._openChangedId = 0;
> 
> What is indicator._openChangedId ?

I understood it.
Comment 30 Florian Müllner 2015-04-24 06:48:21 UTC
Review of attachment 302234 [details] [review]:

Subject of the commit message should be prefixed, otherwise looks good to me - thanks!
Comment 31 Florian Müllner 2015-04-24 06:48:48 UTC
Review of attachment 302242 [details] [review]:

Missing prefix in commit message, otherwise fine
Comment 32 Meet 2015-04-24 10:50:03 UTC
Should I reword the commits with respective prefixes messageTray and panel? I did not add prefix as multiple components were being modified.
Comment 33 Florian Müllner 2015-04-25 07:52:34 UTC
Created attachment 302326 [details] [review]
panel: Move notification banners below time+date dropdown

Reattaching patches with beefed-up commit messages - the changes in messageTray/dateMenu are only secondary to the ones in panel, so the latter is the right prefix.
Comment 34 Florian Müllner 2015-04-25 07:53:22 UTC
Created attachment 302327 [details] [review]
panel: Block banners when opening menus that would overlap

Dto.
Comment 35 Florian Müllner 2015-04-25 07:58:28 UTC
Attachment 302326 [details] pushed as 674325e - panel: Move notification banners below time+date dropdown
Attachment 302327 [details] pushed as 08690d6 - panel: Block banners when opening menus that would overlap
Comment 36 Florian Müllner 2015-04-25 08:03:20 UTC
I pushed this to gnome-3-16 as well.
Comment 37 Meet 2015-04-25 09:04:58 UTC
Ok. Read the new commit messages as well and learnt how to type commit messages.
Comment 38 Florian Müllner 2015-04-30 12:22:33 UTC
Created attachment 302644 [details] [review]
panel: Set up 'open-state-changed' handler on menu changes

Commit 08690d658f42 generalized the banner-blocking behavior of the
dateMenu to all menus that would obscure the banner. However setting
up the 'open-state-changed' handler only when an indicator is added
does not work for indicators that change their entire menu (like the
app menu) - we currently end up with menus with no connected signal
handler, and throw an error when trying to disconnect an invalid
signal ID.
To address this, add a new PanelButton::menu-set signal and use that
to set up the 'open-state-changed' handler.
Comment 39 Rui Matos 2015-04-30 13:23:29 UTC
Review of attachment 302644 [details] [review]:

::: js/ui/panel.js
@@ +1060,3 @@
+
+        if (indicator.menu._openChangedId)
+            indicator.menu.disconnect(indicator.menu._openChangedId);

If indicator.menu gets replaced by a different instance we never execute this. Returning the previous menu instance as an argument to the menu-set signal would allow us do disconnect here
Comment 40 Florian Müllner 2015-04-30 13:36:04 UTC
(In reply to Rui Matos from comment #39)
> Review of attachment 302644 [details] [review] [review]:
> If indicator.menu gets replaced by a different instance we never execute
> this. Returning the previous menu instance as an argument to the menu-set
> signal would allow us do disconnect here

If there was a previous menu instance, setMenu() destroys it before emitting ::menu-set. I think we could just as well not disconnect the signal at all, and use
  if (!indicator.menu || indicator.menu._openChangedId > 0)
      return;
to avoid multiple connections in case the menu did not change. Or just not care about multiple connections now that we figure out the panel box in the signal handler, dunno - we already end up with multiple connections to the ::destroy and ::menu-set signals ...
Comment 41 Rui Matos 2015-04-30 16:07:29 UTC
(In reply to Florian Müllner from comment #40)
> If there was a previous menu instance, setMenu() destroys it before emitting
> ::menu-set.

We could emit the signal before destroying the old instance but I don't think it's worth it.

> I think we could just as well not disconnect the signal at all,
> and use
>   if (!indicator.menu || indicator.menu._openChangedId > 0)
>       return;

Sounds good to me, feel free to push with that.
Comment 42 Florian Müllner 2015-04-30 16:33:17 UTC
Attachment 302644 [details] pushed as 1092f55 - panel: Set up 'open-state-changed' handler on menu changes