Traveling laptop use case.
DPI can change on the fly, but running dunst will continue using outdated value that was in effect back when it was started.
I assume you're using an external monitor sometimes and others the laptop screen and that's why the dpi changes.
Have you tried the per_monitor_dpi setting under experimental? It was designed with a similar usecase in mind.
As I see from description, this option calculates DPI directly from xrandr's monitor geometry, bypassing fontconfig/xrdb/xrandr --dpi. So that isn't exactly what I need.
I'm fine with single DPI for the whole framebuffer, since this is effectively how X works. I just would like dunst to re-check that value.
There was a pretty big discussion about DPI handling in #240, from a comment in that thread:
It's worth noting that X's
xorg.conf/DisplaySizeconfiguration andxrandr's --dpicontrol the same thing; changing the DPI updates the determined displaysize, and v-v.
So theoretically it should be affected by xrandr --dpi.
I've just tested it. No, it ignores xrandr --dpi and uses calculated display dpi.
I'm not sure about xrandr --dpi and xorg.conf/DisplaySize governing the same thing, since DisplaySize parameter is from SectionMonitor context, and xrandr --dpi affects the whole X screen.
Looks like you're right, I'll look into this tomorrow.
The best way to implement this would probably be to re-query Xft.dpi when receiving a RRScreenChangeNotify event.
Upside:
Downside:
BTW, does dunst ignore fontconfig DPI setting? It may be a good idea to just rely on fontconfig to get DPI, because it would simplify and unify things. Many applications effectively get DPI form fontconfig, and fontconfig itself falls back to xrdb and then [supposedly] to xrandr in case its own DPI is unset.
BTW, does dunst ignore fontconfig DPI setting
Currently yes, haven't looked into fontconfig at all.
The dpi logic is basically
If per_monitor_dpi is enabled query xrandr and calculate based on screen dimentions
else if Xft.dpi is set use that
else assume 96.
Well, one way or another, fontconfig is already used in text rendering in dunst anyway, so it would be logical to also use it for DPI handling when per_monitor_dpi = false. Just update when needed.
I've implemented this in the feature/382-reload-dpi branch, it works fine according to my tests. Can you test it too on your end and make sure it works as intended?
I expect a draw call to also be needed there but if it works fine without it even better.
Well, one way or another, fontconfig is already used in text rendering in dunst anyway
That's because of pango, dunst internally doesn't use fontconfig directly.
It does not work in my case.
DPI=96
echo "Xft.dpi: $DPI" | xrdb -merge ; xrandr --dpi $DPI
notify-send -a ht test1 test1
# remove notifications
DPI=128
echo "Xft.dpi: $DPI" | xrdb -merge ; xrandr --dpi $DPI
notify-send -a ht test2 test2
Also tried disconnecting and reconnecting the external monitor for my rerandr3 script to apply basically the same values as above automatically. Dunst does not get new DPI.
I'm using Intel GPU with modesetting driver and Openbox+Compton as WM.
Oops apparently I forgot to post an update on this, I thought that I could simply add the code to re-read the dpi and the existing render functionality would take over from there but this isn't the case, pango_cairo_context_set_resolution has to be called to update the dpi as-well which unfortunately can't be done without touching x.c which is currently under a major refactor in a different branch and doing so would cause all sorts of conflicts.
Yet another issue that is on-hold waiting for the drawing refactor.
@Vladimir-csp Could you please test the PR #608. I'd love to see it fixed.
Unfortunately, I see no difference. The next notification after changing DPI appears with the size consistent with dunst startup conditions.
Mhmm. That's not cool.
Changing it via echo "Xft.dpi: $DPI" | xrdb -merge is still not possible (and it's not intended to get changed). Do you set the dpi with xrandr --dpi <DPI>, too?
Are you running off the right branch?
git clone https://github.com/bebehei/dunst.git dunst-bebehei
cd dunst-bebehei
git checkout xrandr-dpi
make -j
pkill dunst && ./dunst
What's your setting of per_monitor_dpi in the experimental section?
I use a script that sets DPI via xrandr --dpi and also syncs it to xrdb and fontconfig, so all sources covered.
$ git status
On branch xrandr-dpi
Your branch is up to date with 'origin/xrandr-dpi'.
I've built a package from it.
per_monitor_dpi = false
What does
xdpyinfo | grep -B1 resolution
Report after changing the DPI?
it reports correct values
So, it does report correct DPI, matching with the DPI set by xrandr --dpi?
Yes. I'm switching between 96 and 120, changes are applied correctly in all three ways: xrandr, xrdb, fontconfig
Ok, I added another debug commit. Could you please rebuild it and start dunst with dunst -verbosity info? And tell, what "Drawing with screen dpi" says?
Launched dunst -verbosity info while DPI was set to 96, switched DPI to 120
$ xrdb -q | grep dpi
Xft.dpi: 120
$ xdpyinfo | grep -B1 resolution
dimensions: 1920x1200 pixels (406x254 millimeters)
resolution: 120x120 dots per inch
$ grep -ri dpi ~/.config/fontconfig/
~/.config/fontconfig/conf.d/90-xrandr-sync-dpi.conf: <edit name="dpi" mode="assign"><double>120</double></edit>
notify-send test test, dunst reported:
INFO: Drawing with screen DPI: 96.000000
INFO: Drawing with screen DPI: 96.000000
This isn't working because the impementation in #608 favors Xft over the xrandr --dpi value and additionally screen_dpi_get_from_xft only reads from xft on the first call and after that it returns the cached value. So this will only work if Xft.dpi is correct when dunst receives the first notification.
Is it possible to delay read until a new notification is shown?
Oh yes, @tsipinakis is right. Sorry, I failed communicating my own code :see_no_evil:
Is it possible to delay read until a new notification is shown?
When should we query it? There's no event semantics to listen on for changed values. It's huge overhead to query the DB per notification.
The only way is either to invalidate the Xft value:
echo "Xft.dpi: 0" | xrdb -merge
dunst &
echo "Xft.dpi: <olddpi>" | xrdb -merge
Then dunst will use the value given by xrandr --dpi. With xrandr, we've got an event for screen changes and we listen to it.
Invalidating xrdb value will affect some software that for some reason relies exclusively on it. I've experimented extensively with DPI setting and came to conclusion that the best way to reach out to all the apps it is to carpet-bomb every source of the value: xrandr, xrdb, fontconfig. I have a hook in autorandr that does just that.
To avoid any race with the settings or overhead from constant querying, rely on xrandr event, but postpone the actual read till next notification.
@Vladimir-csp #608 has been updated to invalidate the cached dpi value when a screen update is received as you suggested. Can you try it out and see if that works for you?
I do not see any change in behavior, still using startup dpi and not reacting to changes.
I finally found out. Long story short: it was an odyssey.
@Vladimir-csp Could you please test this again? It should work like a charm.
When should we query it? There's no event semantics to listen on for changed values. It's huge overhead to query the DB per notification.
I have to step back of this. There is actually an event, which you can listen on. And it's super easy to listen on it. The only thing: xlib doesn't do it :imp:
at commit 2d37902. No change.
echo "Xft.dpi: 96" | xrdb -merge
./dunst -config dunstrc &
notify-send -u critical Test 1234
echo "Xft.dpi: 120" | xrdb -merge
@Vladimir-csp The above commands work for me for switching dunst to 120 dpi with 2d37902, can you try again with the default dunstrc?
It works with default config, but does not work with mine.
Here is the diff:
$ diff /usr/share/dunst/dunstrc .config/dunst/dunstrc
18c18
< follow = mouse
---
> follow = none
32c32
< geometry = "300x5-30+20"
---
> geometry = "512x3+37-0"
44c44
< transparency = 0
---
> transparency = 14
57c57
< padding = 8
---
> padding = 4
60c60
< horizontal_padding = 8
---
> horizontal_padding = 4
64c64
< frame_width = 3
---
> frame_width = 1
84c84
< idle_threshold = 120
---
> idle_threshold = 60
88c88
< font = Monospace 8
---
> font = Monospace 12
128c128
< format = "<b>%s</b>\n%b"
---
> format = "%a:\n<b>%s</b>\n%b %p"
162c162
< icon_position = off
---
> icon_position = left
165c165
< max_icon_size = 32
---
> max_icon_size = 64
168c168
< icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
---
> #icon_path = /usr/share/icons/gnome/16x16/status/:/usr/share/icons/gnome/16x16/devices/
177c177
< history_length = 20
---
> history_length = 50
185c185
< browser = /usr/bin/firefox -new-tab
---
> browser = xdg-open
260c260
< close = ctrl+space
---
> close = mod4+BackSpace
263c263
< close_all = ctrl+shift+space
---
> close_all = mod4+shift+BackSpace
269c269
< history = ctrl+grave
---
> history = mod4+ctrl+BackSpace
272c272
< context = ctrl+shift+period
---
> context = mod4+Insert
277,278c277,279
< background = "#222222"
< foreground = "#888888"
---
> background = "#161616"
> foreground = "#aaaaaa"
> frame_color = "#aaaaaa"
284,285c285,287
< background = "#285577"
< foreground = "#ffffff"
---
> background = "#323232"
> foreground = "#dddddd"
> frame_color = "#dddddd"
291c293
< background = "#900000"
---
> background = "#ff1616"
293c295
< frame_color = "#ff0000"
---
> frame_color = "#ffffff"
Debug messages with default config contain Checking for active screen changes:
DEBUG: XEvent: processing 'Expose'
DEBUG: XEvent: Ignoring '65'
DEBUG: XEvent: Checking for active screen changes
DEBUG: XEvent: Checking for active screen changes
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: Ignoring '22'
DEBUG: XEvent: Ignoring '22'
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: Ignoring '22'
DEBUG: XEvent: Ignoring '22'
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: Ignoring '22'
DEBUG: XEvent: Ignoring '22'
DEBUG: XEvent: Ignoring '18'
DEBUG: XEvent: Ignoring '21'
DEBUG: XEvent: Checking for active screen changes
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: Ignoring '22'
DEBUG: XEvent: Ignoring '22'
DEBUG: XEvent: Ignoring '22'
but with my config they are absent:
DEBUG: XEvent: Ignoring '22'
DEBUG: XEvent: processing 'RRScreenChangeNotify'
DEBUG: XEvent: Ignoring '21'
DEBUG: XEvent: Ignoring '21'
DEBUG: XEvent: Ignoring '21'
DEBUG: XEvent: Ignoring '21'
DEBUG: XEvent: Ignoring '21'
DEBUG: XEvent: Ignoring '21'
DEBUG: XEvent: Ignoring '18'
DEBUG: XEvent: Ignoring '17'
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: Ignoring '18'
DEBUG: XEvent: Ignoring '17'
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: Ignoring '21'
DEBUG: XEvent: Ignoring '21'
DEBUG: XEvent: Ignoring '21'
DEBUG: XEvent: Ignoring '18'
DEBUG: XEvent: Ignoring '17'
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: Ignoring '18'
DEBUG: XEvent: Ignoring '17'
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: Ignoring '18'
DEBUG: XEvent: Ignoring '17'
DEBUG: XEvent: processing 'CreateNotify'
DEBUG: XEvent: Ignoring '22'
There has to be the message XEvent: processing PropertyNotify for Resource manager in your debug log of dunst.
Please recompile with a make clean and fire the echo "Xft.dpi: 120" | xrdb -merge manually. The PropertyNotify event has to come somewhere.
The only thing, which could be wrong, would be the atom check:
if (ev.xproperty.atom == XA_RESOURCE_MANAGER) {
But this time, it works flawless on my machine. I checked everything.
make clean ; make, launched fresh binary from build dir with -config option. Same thing. XEvent: processing PropertyNotify for Resource manager appears only with default config.
Here is my config (without comments):
[global]
monitor = 0
follow = none
geometry = "512x3+37-0"
indicate_hidden = yes
shrink = no
transparency = 14
notification_height = 0
separator_height = 2
padding = 4
horizontal_padding = 4
frame_width = 1
frame_color = "#aaaaaa"
separator_color = frame
sort = yes
idle_threshold = 60
font = Monospace 12
line_height = 0
markup = full
format = "%a:\n<b>%s</b>\n%b %p"
alignment = left
show_age_threshold = 60
word_wrap = yes
ellipsize = middle
ignore_newline = no
stack_duplicates = true
hide_duplicate_count = false
show_indicators = yes
icon_position = left
max_icon_size = 64
sticky_history = yes
history_length = 50
dmenu = /usr/bin/dmenu -p dunst:
browser = xdg-open
always_run_script = true
title = Dunst
class = Dunst
startup_notification = false
verbosity = debug
corner_radius = 0
force_xinerama = false
mouse_left_click = close_current
mouse_middle_click = do_action
mouse_right_click = close_all
[experimental]
per_monitor_dpi = false
[shortcuts]
close = mod4+BackSpace
close_all = mod4+shift+BackSpace
history = mod4+ctrl+BackSpace
context = mod4+Insert
[urgency_low]
background = "#161616"
foreground = "#aaaaaa"
frame_color = "#aaaaaa"
timeout = 10
[urgency_normal]
background = "#323232"
foreground = "#dddddd"
frame_color = "#dddddd"
timeout = 10
[urgency_critical]
background = "#ff1616"
foreground = "#ffffff"
frame_color = "#ffffff"
timeout = 0
Reproduced with the dunstrc provided.
@bebehei Found the bug ;)
The problem is with
follow = none
With any other follow mode we subscribe to PropertyChangeMask which apparently includes resource manager events but with follow = none we don't receive them so we don't know when to update.
@bebehei seems inactive/busy and hasn't responded to my pings or email, I'll take over until the 1.4 release which I'm not proud of how much it's been delayed.
@Vladimir-csp I've pushed a fix for the bug mentioned above can you confirm this works for you now?
It works!
Awesome! Merged, it'll be included in the 1.4 release which will be the next week or so.
Most helpful comment
Awesome! Merged, it'll be included in the 1.4 release which will be the next week or so.