- 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.dpi
X 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.dpi
X resource based on whatxrandr
tells us) is the raw scale factor:factor = qreal(platformLogicalDpi.first) / qreal(platformBaseDpi.first);
e.g.
144 / 96 = 1.5
which 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.
Overriding the Monitor Size in mm and Script Debug Mode
With that PR, this is now also debuggable, and a user can override the monitor width in mm from the kernel command line of the installation media:
Boot with
(replace "200" with the real value, of course)
or start the script in debug mode with
Then it will only calculate the DPI and the scale factor, show them on stdout and then exit. Remember to also check
/var/log/YaST2/y2start.log
.