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

Allow changing X11 DPI at runtime #1228

Closed
chrisduerr opened this issue Oct 17, 2019 · 15 comments · Fixed by #3222 or #3309
Closed

Allow changing X11 DPI at runtime #1228

chrisduerr opened this issue Oct 17, 2019 · 15 comments · Fixed by #3222 or #3309
Labels
DS - x11 S - enhancement Wouldn't this be the coolest?

Comments

@chrisduerr
Copy link
Contributor

This has been reported to Alacritty in alacritty/alacritty#2886.

It seems like currently winit does not allow to modify the DPI at runtime, which I can definitely see as desirable for some users. In Alacritty it would be possible to just change the font size, but I feel like it would still be worth it to just change one thing and the whole system properly rescales.

@frebib
Copy link

frebib commented Mar 21, 2020

Looks related to #1377

From testing with alacritty, I can't seem to invoke any ScaleFactorChanged events, presumably due to the above issue (reproduce with alacritty --print-events 2>&1 | grep -ie scale and change monitor DPI or move window to another display with different DPI).

At least in X11, I'm leveraging the xsettings behaviour built into GTK to resize at runtime. https://www.freedesktop.org/wiki/Specifications/XSettingsRegistry/
It's definitely not the most scalable solution, but it is at least one source of dpi changed events

@frebib
Copy link

frebib commented Aug 16, 2020

I spent some time digging into this. I managed to cobble together something that works, but is definitely sub-optimal. This is the first Rust I've ever "written" so even getting this to work was a challenge. It uses the existing code to reload monitors and trigger ScaleFactorChanged events which is completely overkill for the little work that is actually required. I think this needs restructuring such that monitors can update their own DPI and propagate the events down to the windows, or something like that. I didn't even want to attempt to work out the lifetime/ownership headaches around that. If anyone feels inclined, or motivated to, I'm happy for this to be adapted in a cleaner way so it can be merged. That being said, I'll be using this patch until something better comes along as it will probably work well enough for my changing-dpi needs.

frebib@74d5070

@rhelmot
Copy link

rhelmot commented Apr 17, 2022

I'm interested in working on this, but I have no familiarity with winit code. Could someone on the winit team give me a high-level explanation of what's unacceptable about the above patch so I can start hacking on it?

@frebib
Copy link

frebib commented Aug 2, 2022

Bump? Anyone able to help out with this patch? I've been using frebib@74d5070 for the last 2 years with zero issues, although it seems to stop working after c916eb6

@frebib
Copy link

frebib commented Aug 20, 2022

I rebased my patch onto v0.27.2 and reverted c916eb6 and it seems to still work.
Here is the updated commit ec4af7d

@asch
Copy link

asch commented Oct 15, 2022

Any reason why frebib's patch is not merged?

@madsmtm
Copy link
Member

madsmtm commented Oct 28, 2022

It would probably help if they (or someone else) opened a pull request with the patch, it's a bit cumbersome to discuss an implementation otherwise

frebib added a commit to frebib/winit that referenced this issue Jun 11, 2023
This change allows X11 windows to receive ScaleFactorChanged events when
using Xft.dpi via the root window PropertyChange event.

Subscribe to PropertyChange events on the root window, and reload all
available monitors when an XA_RESOURCE_MANAGER change is received. This
is a very heavy handed approach to this problem, but it was the least
intrustive way I could find to make it work with my limited skill. Load
XResources directly via XGetTextProperty on every get_xft_dpi call as
XResourceManagerString returns stale cached data and does not reload for
the lifetime of the window (?)

Fixes: rust-windowing#1228
Signed-off-by: Joe Groocock <me@frebib.net>
frebib added a commit to frebib/winit that referenced this issue Jul 18, 2023
This change allows X11 windows to receive ScaleFactorChanged events when
using Xft.dpi via the root window PropertyChange event.

Subscribe to PropertyChange events on the root window, and reload all
available monitors when an XA_RESOURCE_MANAGER change is received. This
is a very heavy handed approach to this problem, but it was the least
intrustive way I could find to make it work with my limited skill. Load
XResources directly via XGetTextProperty on every get_xft_dpi call as
XResourceManagerString returns stale cached data and does not reload for
the lifetime of the window (?)

Fixes: rust-windowing#1228
Signed-off-by: Joe Groocock <me@frebib.net>
frebib added a commit to frebib/winit that referenced this issue Jul 18, 2023
This change allows X11 windows to receive ScaleFactorChanged events when
using Xft.dpi via the root window PropertyChange event.

Subscribe to PropertyChange events on the root window, and reload all
available monitors when an XA_RESOURCE_MANAGER change is received. This
is a very heavy handed approach to this problem, but it was the least
intrustive way I could find to make it work with my limited skill. Load
XResources directly via XGetTextProperty on every get_xft_dpi call as
XResourceManagerString returns stale cached data and does not reload for
the lifetime of the window (?)

Fixes: rust-windowing#1228
Signed-off-by: Joe Groocock <me@frebib.net>
frebib added a commit to frebib/winit that referenced this issue Jul 18, 2023
This change allows X11 windows to receive ScaleFactorChanged events when
using Xft.dpi via the root window PropertyChange event.

Subscribe to PropertyChange events on the root window, and reload all
available monitors when an XA_RESOURCE_MANAGER change is received. This
is a very heavy handed approach to this problem, but it was the least
intrustive way I could find to make it work with my limited skill. Load
XResources directly via XGetTextProperty on every get_xft_dpi call as
XResourceManagerString returns stale cached data and does not reload for
the lifetime of the window (?)

Fixes: rust-windowing#1228
Signed-off-by: Joe Groocock <me@frebib.net>
frebib added a commit to frebib/winit that referenced this issue Jul 18, 2023
This change allows X11 windows to receive ScaleFactorChanged events when
using Xft.dpi via the root window PropertyChange event.

Subscribe to PropertyChange events on the root window, and reload all
available monitors when an XA_RESOURCE_MANAGER change is received. This
is a very heavy handed approach to this problem, but it was the least
intrustive way I could find to make it work with my limited skill. Load
XResources directly via XGetTextProperty on every get_xft_dpi call as
XResourceManagerString returns stale cached data and does not reload for
the lifetime of the window (?)

Fixes: rust-windowing#1228
Signed-off-by: Joe Groocock <me@frebib.net>
frebib added a commit to frebib/winit that referenced this issue Jul 18, 2023
This change allows X11 windows to receive ScaleFactorChanged events when
using Xft.dpi via the root window PropertyChange event.

Subscribe to PropertyChange events on the root window, and reload all
available monitors when an XA_RESOURCE_MANAGER change is received. This
is a very heavy handed approach to this problem, but it was the least
intrustive way I could find to make it work with my limited skill. Load
XResources directly via XGetTextProperty on every get_xft_dpi call as
XResourceManagerString returns stale cached data and does not reload for
the lifetime of the window (?)

Fixes: rust-windowing#1228
Signed-off-by: Joe Groocock <me@frebib.net>
notgull added a commit that referenced this issue Nov 12, 2023
Supersedes #2874, fixes #1228

Signed-off-by: John Nunley <dev@notgull.net>
kchibisov pushed a commit that referenced this issue Nov 24, 2023
Signed-off-by: John Nunley <dev@notgull.net>
Fixes #1228.
kchibisov pushed a commit to kchibisov/winit that referenced this issue Nov 24, 2023
Signed-off-by: John Nunley <dev@notgull.net>
Fixes rust-windowing#1228.
kchibisov pushed a commit that referenced this issue Nov 24, 2023
Signed-off-by: John Nunley <dev@notgull.net>
Fixes #1228.
@frebib
Copy link

frebib commented Dec 22, 2023

This is closed, but at least in Alacritty it doesn't work. Whilst this listens for the correct events, it doesn't actually read the new DPI value, so it still doesn't change scale

@madsmtm
Copy link
Member

madsmtm commented Dec 22, 2023

CC @notgull?

@notgull notgull reopened this Dec 22, 2023
@notgull
Copy link
Member

notgull commented Dec 23, 2023

It looks like that it's still re-reading the Xft.dpi variables and the CRTC info, so I'm not sure why it wouldn't be updating.

@frebib
Copy link

frebib commented Dec 24, 2023

In my hacky original patch, the code reread the X11 resources from X frebib@fb56303#diff-c2d9fcab6774ee66ce076daadd1d1d1a376066dfcc6ab6584e0925c9fe61ca47R55

I shamelessly stole this from dunst. I don't know anything about X11 but I doubt this is the only approach to fix this problem. I would guess the issue with the current implementation is that it doesn't read the updated xft.dpi value from xresources because the application has the xresources from when the window was opened.

@notgull
Copy link
Member

notgull commented Dec 24, 2023

Good catch! I'll file a patch to fix that

notgull added a commit that referenced this issue Dec 24, 2023
Closes #1228

Signed-off-by: John Nunley <dev@notgull.net>
notgull added a commit that referenced this issue Dec 26, 2023
kchibisov pushed a commit to kchibisov/winit that referenced this issue Dec 27, 2023
kchibisov pushed a commit that referenced this issue Dec 27, 2023
@jfly
Copy link

jfly commented Jan 21, 2024

For the record, this is still not working for me on Alacritty 0.13.1, as already described by @frebib here: #3309 (comment).

@notgull @kchibisov, can we (re)-reopen this issue?

@madsmtm madsmtm reopened this Jan 21, 2024
notgull added a commit that referenced this issue Jan 25, 2024
Apparently we are missing some DPI update because the DPI is still not
begin updated. See #1228 for details. Therefore, it's best to just
reload the DPI every time we need it.

Signed-off-by: John Nunley <dev@notgull.net>
@notgull
Copy link
Member

notgull commented Feb 4, 2024

This should be fixed as of #3423, unless Qt/KDE has a way of updating DPI that I don't know about.

@notgull
Copy link
Member

notgull commented Feb 4, 2024

Huh, seems like Qt5 uses XSETTINGS as well: https://github.com/qt/qtbase/blob/dev/src/plugins/platforms/xcb/qxcbxsettings.cpp

So I think our bases should be covered, at least for platforms that aren't super weird.

@notgull notgull closed this as completed Feb 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DS - x11 S - enhancement Wouldn't this be the coolest?
8 participants