Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add i3-nagbar style popups for important notifications #4

Draft
wants to merge 27 commits into
base: master
Choose a base branch
from

Conversation

tpb1908
Copy link

@tpb1908 tpb1908 commented May 1, 2020

In response to regolith-linux/regolith-desktop#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.

@kgilmer kgilmer requested a review from farsil May 2, 2020 18:33
@tpb1908
Copy link
Author

tpb1908 commented May 3, 2020

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
Copy link
Author

tpb1908 commented May 4, 2020

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.

@jacksonbenete
Copy link

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.

@tpb1908
Copy link
Author

tpb1908 commented Dec 30, 2020

@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.

@mhalano
Copy link

mhalano commented Jun 19, 2021

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants