GNOME Bugzilla – Bug 643014
show message tray when the user is inactive
Last modified: 2012-03-17 21:14:38 UTC
This is slightly different than showing the tray when returning from idle or screen lock. If the user is not busy, actively using the computer, or something has proactively identified the user as active (ie. a idleness inhibit) we should take the opportunity to present the message tray. It should stay visible until one of the above conditions is met. Normally this means hiding a short time after the user moves the mouse or uses the keyboard. Subject to the usual conditions such as if the pointer is moving toward the tray, etc. In combination with this, we probably need a key to instantly dismiss the tray so it won't be too annoying or revealing. One possible complication is what to do with banners during this time. I don't think we want them to immediately collapse into the summary area nor do we want the to expand and block. Probably just the typical banner mode. Might need to iterate on this part. The timeout default is something we'll have to feel out. Perhaps a minute. My guess is that for implementation you'll need to hook into both the list of session inhibitors and the xorg sync counters.
Another issue to keep in mind is that the system dims the screen after a short time as well. We need to make sure these things are properly harmonized.
The problem I can see with this is that often the user isn't inactive, but may be reading something on the screen, or watching a movie... It would be highly annoying to get the bar moving when you're OTC concentrating on something else. Or imagine you're showing another person something (text, video...) and suddenly all of your chat contacts from the background are listed on screen - not very good for privacy. The only time when we're sure the user isn't active is when the screensaver starts, but obviously at that point we can't show anything. Or maybe the bar should appear ~10 seconds before the screensaver is started? This would 1) allow user to react if wanted, which will inhibit the screensaver, and 2) warn that screen is going to be blank soon. (Doesn't solve the privacy question, though.)
Watching a movie inhibits idleness. The same issues apply to screen dimming.
Yes, but : 1) reading a PDF or a webpage, or doing anything on a computer doesn't 2) most movies on the Web are still in Flash, and don't inhibit the screensaver So the inhibit feature basically only helps for videos played in Totem/VLC. (BTW, I disable screen dimming for the same reasons, but maybe I'm weird. This 5 seconds timeout is incredibly short for considering user "inactive".)
This bug is closely related to bug 636838, which should implement keeping track of what notifications were received while the user was inactive. The summary should only be shown if a notification was received within the period of inactivity AND the inactivity timeout was reached. I.e. we should not show the summary once the inactivity timeout was reached if there were no new notifications. The same applies to only showing the summary if there are new notifications once the user comes back from being idle. So synchronizing the inactivity timeout used for showing the summary with the dim timeout will only have a limited effect in that the summary will be shown and the screen will dim at the same time only if there were notifications received during the period of inactivity. Bug 636838 also describes that we should hide the summary if it is not being interacted with if a new notification arrives, show the banner for the new notification, and then show the summary again once the banner is hidden. This behavior applies well to the case when the user is inactive. Jon, do you mean that we should have a keyboard shortcut for hiding the tray or an actual visual representation on the tray? The later is not necessary because both the notification and the summary hide if you mouse to them and then mouse away from them. Btw, setting the status to Busy also immediately hides the notification banner or summary. Milan, when the user is concerned about privacy or doesn't want to see any non-urgent notifications, they can set their status to Busy. If the user is reading a PDF or a webpage, or watching a movie on the Web, but still wants to see the notifications, they will either have to ignore the summary that will appear after the first notification or just move the mouse or press any key to signal activity.
(In reply to comment #5) > Milan, when the user is concerned about privacy or doesn't want to see any > non-urgent notifications, they can set their status to Busy. If the user is > reading a PDF or a webpage, or watching a movie on the Web, but still wants to > see the notifications, they will either have to ignore the summary that will > appear after the first notification or just move the mouse or press any key to > signal activity. The scenario I particularly fear is when you read a web page or a PDF: you move the mouse to scroll the page, stop for, say, 15 seconds, then scroll, etc. IT would really feel terrible if each time you have scrolled the summary appears after 10 seconds. Maybe changing status to busy is the solution, I'm not sure. Or maybe we can avoid showing the summary it has been shown already and the user has dismissed it (provided nothing new happened)?
(In reply to comment #6) > Or maybe we can avoid showing the summary it has been shown already and the > user has dismissed it (provided nothing new happened)? or at least have a much longer timeout in that case (eg, if nothing has changed, then don't pop the tray up until the screensaver idle timeout is hit)
So, perhaps an easier way to implement this may be to only start timing out the tray when user activity is detected. That way when the summary is shown after a new message arrives it will stay around.
(In reply to comment #8) > So, perhaps an easier way to implement this may be to only start timing out the > tray when user activity is detected. I was going to open a new bug exactly suggesting this behaviour, because I'm missing a lot of notifications because I'm afk for awhile and when I go back I forget to check the message tray for news. So I personally think this is a good solution.
Still, we need to detect user activity, any idea how to do that? An intensive search brings me to a point where I can use the XScreenSaverQueryExtension from X11/extensions/scrnsaver.h. you can poll that way to see how long it's been idle, but you cant get it to poke u when you are out of idleness. so no choice but to use g_timeout_add to poll it at regular intervals, then set it to hide when user movement is detected. any comments/suggestions before i start implementing on this?
*** Bug 648142 has been marked as a duplicate of this bug. ***
FWIW, I still think that comment 8 is a pretty good approach.
I don't think the activity based idea is a good approach because it makes fragile assumptions about user behaviour. For example, mice can move unintentionally (someone bumping your table is a bad reason for notifications you're interested in going away without being noticed). This is definitely a trivial edge-case, but there's bound to be more examples like this, and IMO having a gentle flashing somewhere on the screen (perhaps a corner) is more robust.
*** Bug 654414 has been marked as a duplicate of this bug. ***
Created attachment 209579 [details] [review] messageTray: show the summary with new notifications when the user becomes active If the user was inactive while a notification was shown, we show the summary when the user becomes active again. This ensures that we inform the user of the existance of new notifications that the user might have missed. When the user comes back from away, the summary is now only shown if it has new notifications. This is better than showing the summary as soon as the user was inactive while a new notification was shown because this avoids the message tray from persistently showing while user might be reading or watching something on the screen. The g_debug statements in the C files are commented out because they are currently not getting correctly disabled by default. Calling remove_watch() from within _onIdleMonitorWatch() callback function currently causes gjs errors because it results in the callback function information being freed while it is still needed. Gjs needs to be fixed to not free the callback function information until the return value for the function has been processed.
I looked into the GJS warnings, and it was indeed pretty simple - filed a patch as bug 672003
Review of attachment 209579 [details] [review]: I'm not well versed in the XSync protocol, but I'm going to assume that since the code was stolen from g-s that it works properly. Now that I understand the intent here, code looks good for the most part. Just a few stylistic comments here and there. ::: js/ui/messageTray.js @@ +1641,2 @@ _onNotificationDestroy: function(notification) { + No whitespace at the beginning of functions. @@ +2114,3 @@ }, + _onIdleMonitorWatch: function(monitor, id, condition) { Use a more descriptive name like userBecameIdle, please @@ +2117,3 @@ + // If 'condition' is true, it means that the user became idle and was previously active when we set up the watch. + // If 'condition' is false and we have only one unseen notification, which is the one that is being curently shown, + // then the user will see it, and we no longer will have unseen notifications. These comments aren't necessary. See below. @@ +2121,3 @@ + this._idleMonitorWatchId = 0; + + if (condition || (this._unseenNotifications.length == 1 && this._unseenNotifications[0] == this._notification)) { Using an OR hides the fact that these are really two separate cases with the same end result. I'd do this as: if (userBecameIdle) { // User became idle after it was showed, which means that // the notification was seen. this._unseenNotiications = []; } else if (this._unseenNotifications.length == 1 && this._unseenNotifications[0] == this._notification) { // User became active. If we're already showing the only // "unseen notification", then we don't need to do // anything special here. this._unseenNotifications = []; } else { // User became active and we have unseen notifications. // Show the message tray. this._backFromAway = true; this._updateState(); }
Created attachment 209799 [details] [review] messageTray: show the summary with new notifications when the user becomes active If the user was inactive while a notification was shown, we show the summary when the user becomes active again. This ensures that we inform the user of the existance of new notifications that the user might have missed. When the user comes back from away, the summary is now only shown if it has new notifications. This patch is ready to be committed per previous review. The only addition after the previous review is that now that we use a longer automatic summary timeout, it became apparent that we need to unset it if the tray is no longer hovered over or if the tray is escaped. I added the logic to unset this._summaryTimeoutId in _onTrayLeftTimeout() and in _escapeTray() . I will file a UI freeze break request about this patch to be sure the documentation team is aware of this change.
Review of attachment 209799 [details] [review]: Looks fine.
Filed a UI freeze break request: https://mail.gnome.org/archives/release-team/2012-March/msg00106.html
(In reply to comment #15) > The g_debug statements in the C files are commented out because they are > currently not getting correctly disabled by default. libfolks was setting G_MESSAGES_DEBUG to "all" by default. This is now fixed.