- Qt ref doc about HiDPI: https://doc-snapshots.qt.io/qt5-5.15/highdpi.html
We are now setting those environment variables directly:
QT_SCALE_FACTOR=1.75
(for 168 dpi)
QT_SCALE_FACTOR_ROUNDING_POLICY="PassThrough"
(to avoid rounding)
We are no longer setting the Xft.dpi X resource.
If the monitor reports no reasonable EDID, boot the installation ISO with your real monitor width in millimeters (use an old-fashioned ruler to measure it):
YAST_MON_WIDTH_MM=260
More details: yast/yast-installation#1057
-
yast2 start scripts:
-
yast-x11 tools:
-
xftdpi.c: https://github.com/yast/yast-x11/blob/master/src/tools/xftdpi.c
(lightweight way to set Xft.dpi instead of full-blown
xrdb)
-
-
libyui-qt
- YQUI.cc: https://github.com/libyui/libyui/blob/master/libyui-qt/src/YQUI.cc
- YQUI::calcDefaultSize()
- YQUI: Setting Qt HiDPI mode: https://github.com/libyui/libyui/blob/master/libyui-qt/src/YQUI.cc#L159
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
- YQApplication.cc
- YQUI.cc: https://github.com/libyui/libyui/blob/master/libyui-qt/src/YQUI.cc
-
Qt
- class QHighDpiScaling in src/gui/kernel/:
- Handling the
Xft.dpiX resource:- Reading the X resource: QXcbVirtualDesktop::readXResources()
- QXcbScreen::forcedDpi()
- QXcbScreen::logicalDpi()
- QGuiApplication initializes its highDpiScaleFactorRoundingPolicy to Qt::HighDpiScaleFactorRoundingPolicy::Round, so the scale factor will always be 1.0 or 2.0, never something like 1.5.
-
linuxrc
- PR: Add EDID boot option: openSUSE/linuxrc#297
- QT_SCALE_FACTOR
- QT_SCALE_FACTOR_ROUNDING_POLICY
- Round
- Ceil
- Floor
- RoundPreferFloor
- PassThrough
- QT_SCREEN_SCALE_FACTORS
- QT_USE_PHYSICAL_DPI
- QT_FONT_DPI
- QT_DPI_ADJUSTMENT_POLICY
- QT_ENABLE_HIGHDPI_SCALING
- QT_AUTO_SCREEN_SCALE_FACTOR (X11 only, deprecated on all other platforms)
- QT_DEVICE_PIXEL_RATIO (deprecated)
- 2560x1080 UW-UXGA
- 2560x1440 WQHD, 1440p
- 2560x1600 WQXGA
- 3200x1600 QHD+
- 3440x1440 UW-QHD
- 3840x1600 UW-QHD+
- 3840x2160 QFHD, 4K, UltraHD, UHD-1
- 3840x2400 WQUXGA
- 4096x2160 DCI 4K
- 5120x2880 5K
All multiples of 48
- 96 (min for YaST)
- 144
- 192
- 240
- 288 (max for YaST)
- 336
- 384
-
We set Qt::AA_DisableHighDpiScaling, so in gui/kernel/qhighdpiscaling.cpp
- QHighDpiScaling::m_usePixelDensity is true,
- usePixelDensity() returns true
- QHighDpiScaling::m_pixelDensityScalingActive is true,
- QHighDpiScaling::m_active is true
-
By default, Qt rounds the scale factor to an integer; so in practice, it's either 1.0 or 2.0.
-
We set the Xft.dpi X resource, so in plugins/platforms/xcb/qxcbscreen.cpp the value is picked up in QXcbVirtualDesktop::readXResources(), so it is returned by
- QXcbVirtualDesktop::m_forcedDpi
- QXcbVirtualDesktop::forcedDpi()
- QXcbScreen::forcedDpi()
- QXcbScreen::logicalDpi()
and QWindowSystemInterface::handleScreenLogicalDotsPerInchChange() is called with that value.
-
logicalBaseDpi() has a default implementation in gui/kernel/qplatformscreen.h as QDpi( 96, 96 ), and the xcb platform (X11) overrides it with the same value in platforms/xcb/qxcbscreen.h.
-
The ratio between that logicalBaseDpi (a default value of 96 dpi) and the logicalDpi() value (i.e. what we set in the
Xft.dpiX resource based on whatxrandrtells us) is the raw scale factor:factor = qreal(platformLogicalDpi.first) / qreal(platformBaseDpi.first);
e.g.
144 / 96 = 1.5which is then rounded to the next integer value, i.e. 2 in this case.
[ 82.995] (II) modeset(0): clock: 152.8 MHz Image Size: 344 x 193 mm
[ 82.995] (II) modeset(0): h_active: 1920 h_sync: 2000 h_sync_end 2054 h_blank_end 2250 h_border: 0
[ 82.995] (II) modeset(0): v_active: 1080 v_sync: 1086 v_sync_end 1094 v_blanking: 1132 v_border: 0
Stage [call]: Monitor size: eDP-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 344mm x 193mm
Stage [call]: Monitor width mm: 344
Stage [call]: Monitor width px: 1920
Stage [call]: Monitor dpi: 144
Stage [call]: Xft.dpi set to: 144
2022-04-29 14:43:46 <1> install(4700) [qt-ui]
YQUI.cc(calcDefaultSize):370 -fullscreen: using 960 x 540 for `opt(`defaultsize)
YQUI.cc(calcDefaultSize):404 Default size: 960 x 540
YQApplication.cc(pickAutoFonts):471 Selecting auto fonts - normal: 10, heading: 12 (bold)
YQApplication.cc(currentFont):339 Loaded 10 pixel font: Sans Serif,-1,10,5,50,0,0,0,0,0
YQUI.cc(calcDefaultSize):370 -fullscreen: using 960 x 540 for `opt(`defaultsize)
?!? Why does it use 960 x 540 for fullscreen?
https://github.com/libyui/libyui/blob/master/libyui-qt/src/YQUI.cc#L370
QSize availableSize = screen->availableSize();So Qt thinks we are in HiDPI mode, scaling everything? It's using half the resolution values of 1920 x 1080 in both dimensions.
And we also requested only a moderate font size: 10 px for normal text, 12 px for headings.
We (@joseivanlopez and I) just did some experiments with his real hardware, that Dell XPS 13 9310 with a real HiDPI display with 3840x2400 on a 290mm x 180mm screen, i.e. 336 dpi. We used the latest TW NET ISO from opensuse.org.
By default, the fonts were way too small; Qt did not consider that a HiDPI setup and left everything as it was, i.e. the Qt UI got a
screen->availableSize()of 3840x2400 (which it then reported as opt(defaultsize), as expected). There was no scaling done by Qt, even though the y2start.log reported a calculated 336 dpi, capped at 288 dpi (as expected); which should have resulted in a Qt scale factor of 288 / 96 = 3. But it used a scale factor of 1.Then we tried passing some kernel parameters that, as we were told, would end up in the environment:
QT_SCALE_FACTOR_ROUNDING_POLICY=PassThrough
which changed nothing at all;
QT_SCREEN_SCALE_FACTORS=4
which did have an effect; the fonts now were quite large (a bit too large), and opt(defaultsize) now was 1/4 of the physical resolution, as expected (3840 / 4 = 960 and 2400 / 4 = 600).
Maybe we should ditch that indirect
Xft.dpimumbo-jumbo and simply setQT_SCREEN_SCALE_FACTORSdirectly from the yast2 start script; maybe with also settingQT_SCALE_FACTOR_ROUNDING_POLICY=PassThrough.