dunst icon indicating copy to clipboard operation
dunst copied to clipboard

[meta] Support multiple windows.

Open fwsmit opened this issue 4 years ago • 8 comments

Dunst should be able to use multiple windows to diplay notifications. This would open the possibility to solve a lot of issues like:

#45 #265 #770 #869 #1011 #1049

Initially this could allow for:

  • width to be a rule
  • a good way to implement spacing between notifications.
  • notifications on multiple screens.

But after that, it would also open up possibilities to place notifications in two different positions on the screen. For example, important notifications could be put in the centre.

fwsmit avatar Jan 16 '22 17:01 fwsmit

I was thinking that instead of just having every notification in a window, a rule can be added to specify if a separate window should be used. So that the default would be using just one window (like now) mainly for performance reason. But is a user wants to customize origin etc he can set a separate_window or something like that

bynect avatar Feb 21 '24 16:02 bynect

Yeah, I would do that as well. Before building the config, it's good to specify the exact way it is configured. I was thinking about a set_window for changing a notifications window and window for filtering by window and changing its properties. Gaps could also automatically be made separate windows in the back end, but the same window number

fwsmit avatar Feb 22 '24 08:02 fwsmit

Yeah, I would do that as well. Before building the config, it's good to specify the exact way it is configured. I was thinking about a set_window for changing a notifications window and window for filtering by window and changing its properties. Gaps could also automatically be made separate windows in the back end, but the same window number

Maybe we could add a window_group of some kind that basically lets you group togheter notification in different windows, so by default you have everything in one. But you can set two group so dunst spawns 2 windows and sends the different notification to different windows. This will work especially well if you have 2 screens and want to send specific notification only to a screen

bynect avatar Feb 22 '24 11:02 bynect

I wanted to start working on this.

Here is my proposal, obviously open to ideas and criticisms.

For performance reasons I don't think we really need to spawn a new window for every single notification (unless the user is specific about that). I was thinking of creating "window groups" of notification. Basically you create a window, associate it with a name, a geometry and a theme. Then, you can use a rule to set_window to the name given. (If none is set it will go to the default window)

The window declaration may look something like this

# additional window compared to the "default"
# create a window called "center"
[window.center]
  width = ...
  origin = ...
  color = ...
# etc

# you can change the default
[window.default]
  # this is like the global window settings

# Then on a rule
[battery-low]
  appname = battery
  history_ignore = yes
  set_window = center

I am still thinking about:

  1. How to allow the user to create new windows for every single notification
  2. How to handle follow and similar settings
  3. How to duplicate window in all screens

Current idea: To fix 1) we can create another special window name (like default), that creates a new window every time a notification is assigned to it (and closes the window when the notification is closed). Something like "new" or "create"

To fix 2) we should deprecate the general follow and add follow to the single windows (with the caveat of overlapping windows)

For 3) I think creating a duplicate option for windows would suffice. Basically you list the name of the screens (or "all") and the window group is duplicated verbatim in different screens.

Note: Every single window (unless otherwise specified) behaves like a normal today's dunst window. So there are multiple notification in the same window, with the gaps or separators and layout etc. The idea is not to eliminate the current functionality, but rather adapt it to multiple concurrent windows.


I know that this is a lot to digest (and read). However I really think this kind of planning is the best for such a mature project. Because when a major feature like this gets added it will become really hard to change or fix in the future. My personal philosophy is to put much thought in the planning process rather than doing half-assed things that need fixes in the future.

Anyway, this is obviously a feature more fit for the v2 milestone. I was thinking of covering this entire window subsystem by a experimental.multiple_windows until v2.

@fwsmit @bebehei sorry to disturb you, but could you please tell me what do you think about this proposal, so that I can change it or start an implementation? (also I wish to prioritize this as compared to the theming and other things in #1289)

bynect avatar Feb 23 '24 16:02 bynect

Coming back to it I think that instead of the window section we can define a group section, that works like I described above with some differences.

A group is like a container for notifications. It could be a single window of multiple window "grouped" together.

To fix 1) we can create another special window name (like default), that creates a new window every time a notification is assigned to it (and closes the window when the notification is closed). Something like "new" or "create"

Instead of this we can make an option in the group definition to split every notification in its window. So by default a group is a single window or could be multiple windows. This really simplifies the origin & offset calculation.

For 3) I think creating a duplicate option for windows would suffice. Basically you list the name of the screens (or "all") and the window group is duplicated verbatim in different screens.

Instead, a group could have an option like monitor(s) or mirror that accepts a list of monitor (or all) to be added to. So a single group (with its properties and origin) is represented by multiple windows (one on each selected screen).

Obviously this presents some problems with the follow behavior, so it should be reworked to be specific to groups. And when a group is set to follow it overrides the monitor list.

anyway, this is the updated proposal. It's better because it is a little more generic than windows, so you can create a group with multiple windows (mirroring and single-window-notifications).

Also, in the previous comment I forgot to talk about "group rules". Just like you can match on a notification with regular rules, we may match on a group (group_name, monitor, theme, ...) to change some settings about that group.

For example we may create a rule that matches a follow group and depending on which monitor (match_monitor) changes the theme (set_theme). This is just an example/idea, but it could be quite powerful. My only concern is how to make them distinct from normal rules, but I guess a validation on which match/set are used is enough.

This is what a config might look like

[global]
  # not much here, since most settings are group specific anyway
  title = Dunst
  force_xwayland = false

[experimental]
  group_feature = true

# maybe the settings in global actually refer to the default group?
[group.default]
  origin = top-right
  theme = gruvbox
  follow = mouse

[group.center]
  monitor = all
  follow = none
  origin = center 
  theme = custom-notif
  progress_bar = true

# normal rules
[battery-low]
  appname = battery
  history_ignore = yes
  set_group = center

[brightness]
  appname = brightness
  set_group = center

# this is a group rule
[set-dark-theme]
  match_group = center
  set_theme = dark-custom-notif

again, sorry for the stream of consciousness 🤣

bynect avatar Feb 23 '24 19:02 bynect

I don't have much of an opinion about the way it should be written in the config. But I wanted to say that you should not optimize for using as few windows as possible. Just do what's easiest. "Premature optimization is the root of all evil". You might just start with rewriting the drawing code to allow multiple windows to be drawn at all.

fwsmit avatar Feb 26 '24 16:02 fwsmit

I don't have much of an opinion about the way it should be written in the config. But I wanted to say that you should not optimize for using as few windows as possible. Just do what's easiest. "Premature optimization is the root of all evil". You might just start with rewriting the drawing code to allow multiple windows to be drawn at all.

I wanted to start rewriting the x backend, maybe even rewriting it from scratch with xcb (which I know better than xlib).

Anyway, I can allow the x backend in creating/storing/managing multiple windows however I don't see much point in doing it without a way to actually use it.

So I was thinking of making a refactor first and then creating the aforesaid group implementation.

At least if you like the idea. I mean, I can still start with what I said and do changes as we go. But if you don't like the idea at all that would be a waste of time so please let me know if what I said makes any sense to you.

Also it's not as much as premature optimization as it is about consistency. Also without creating some similar scaffolding I don't think you can do create window per notification at all (because they would be one on top of the other if you don't calculate the origin)

bynect avatar Feb 26 '24 18:02 bynect

Okay, I've looked a but at the configuration example. I don't think nested sections (group.*) are needed. You can just make the window properties a rule.

fwsmit avatar Feb 29 '24 04:02 fwsmit