regolith-rofication icon indicating copy to clipboard operation
regolith-rofication copied to clipboard

Add i3-nagbar style popups for important notifications

Open tpb1908 opened this issue 4 years ago • 5 comments

In response to https://github.com/regolith-linux/regolith-desktop/issues/355 I wrote an extension to rofication to match notifications and provide a visible notification alongside rofication.

I think this is fairly useful, since I find changes to the i3blocks counter easy to miss.

Notification matching

The configuration file defines a list of matchers, each either whitelisting or blacklisting whatever they match. It also defines some flags for other behaviours.

A matcher consists of a line [!](all|summary|body|application|urgency):[RegEx]. '!' denoting whether the matcher is a blacklist item, a keyword denoting which part(s) of the notification to match on, and a RegEx string to use for matching.

The matchers are executed in the order that they are defined, and the notification is displayed (or not) on the basis of the first matcher which matches.

An example config file:

[config]
# Always mark the notification viewed when the popup closes
consume_on_dismiss=true

[list]
# Whitelist
all:[Tt]est
all:another
# Blacklist
!application:[Cc]hrome

In order to allow updating the config without restarting the daemon, pyinotify is used to watch the config directory (specifically for the CLOSE_WRITE event).

Displaying notifications

The initial mechanism for displaying the notification was i3-nagbar. This works nicely with i3, but isn't really meant for this use, and it doesn't support dismissal through the keyboard because it's meant to be annoying.

The nagbar I wrote in Python supports

  • The standard parameters for a notification
  • Displaying notification icons
  • Displaying buttons for notification actions, and dispatching ActionEvent through dbus.
  • Closing after a timeout. Unfortunately I still haven't found an obvious way for the bar to grab focus.

Without specifying any theming the bar looks like this:

python-bar-screenshot

GTK3 seems to be fairly simple to theme. A flatter appearance would match i3xrocks better. It would also make sense to use the same urgency based colours as rofication.

Changes to rofication

The overall system structure doesn't really change, there's just the launching of the bar.

The changes are in _dbus and _notification

  • The app_icon field was added to Notification for display
  • RoficationDbusService takes a DefaultInterceptor instance and calls intercept in Notify

If this system is useful to anyone else I'm happy to finish it off and clean it up. In particular, I need to

  • Make sure that the Interceptor doesn't crash. I don't expect it to, but when it's executed as part of the notification daemon it should be fault tolerant
  • Cleanup the UI, it's a bit ugly
  • Document the system
  • Possibly refactor _interceptor. The class hierarchy is not really necessary, I'm too used to Java.

tpb1908 avatar May 01 '20 23:05 tpb1908

Unfortunately I have still been unable to focus the nagbar window. I have tried the gtk.Window.present method which

may mean raising the window in the stacking order, deiconifying it, moving it to the current desktop, and/or giving it the keyboard focus, possibly dependent on the user's platform, window manager, and preferences

I also tried gtk.Widget.grab_focus, which has no effect. In fact, when I added a TextView widget I couldn't select it to type.

I took a look at the i3 source, and found this code for checking the next focused container with a comment saying that docks cannot be focused. Similarly, docks cannot demand attention, even for their/any workspace (i.e. _NET_WM_STATE_DEMANDS_ATTENTION).

A possible solution would be to define a notification binding mode, such that keys (i.e. the number keys) send an IPC message to select an option.

mode "Notification Action Mode" {
  bindsym $mod+1 exec nagbar-action 1
  # etc 
  bindsym Return mode "default"
  bindsym Escape mode "default"
}

This seems perfectly doable, but overly complex.

tpb1908 avatar May 03 '20 21:05 tpb1908

Here is an implementation of the above idea.

It adds an i3 mode which sends 1-9 to the notification bar on $mod+1-9. The mode is activated when the bar is shown and returned to default when it exits. (An issue with this is that the mode name is hardcoded. I suppose it could be an Xresource value).

Here's a video (YouTube link) of the nagbar using an i3 mode.

Demo on YouTube

Since notify-send doesn't support notification actions, it just shows the default (OK button) which responds to any message sent and closes the nagbar. As dismiss_on_close is set, this sends a dbus message to close the notification.

... perhaps I should just have switched to dunst.

tpb1908 avatar May 04 '20 13:05 tpb1908

How is this going? Are you still working on it or dropped it? Is there anything I can do to help?

I'm afraid to install dunst and break something as apt says that installing dunst will REMOVE regolith-rotification, and I don't know if there something using rotification that I'm not aware of.

jacksonbenete avatar Dec 28 '20 16:12 jacksonbenete

@jacksonbenete I haven't touched it since May.

The latest version of the popup is here and the latest version of rofication is here.

It's now 10 commits behind, and there were quite extensive changes here.

My notifbar implementation should still work, but I'm not planning on supporting it.

tpb1908 avatar Dec 30 '20 21:12 tpb1908

@tpb1908 This still is a work in progress? I really would like visible notifications. My use case is when some command takes too much to execute, a notification pops up, but because just shows a new notification in the blocklet, but I really read the notifications there. Something simple, similar to dunst notifications, would do the trick. The problem is dunst don't have the blocklet and the notification queue.

mhalano avatar Jun 19 '21 11:06 mhalano