[Development] High-DPI on Win

Sorvig Morten Morten.Sorvig at theqtcompany.com
Tue Dec 29 11:47:05 CET 2015


Hello!


> On 28 Dec 2015, at 21:50, Die Waldmanns <waldmanns at gmx.de> wrote:
> 
> (1) Support of fractional scaling (devicePixelRatio).
> This ratio is qreal, but in QT5.5 it nevertheless seems not be possible to set it to fractional values (I could get it only to 1.0,2.0,3.0 etc). In 5.6-beta1 the new environment SCALE mechanisms seem to allow setting it to real values, but the examples in the docu are mentioning only devicePixelRatios of 1 and 2, which makes me wonder. If in QT5.6 it's now possible to acieve devicePixelRatios of 1.0, 1.25, 1.5, 2.0, and 2.5, then this point is obsolete; if not I think this neeeds to be enabled.

(talking about 5.6 here)

We use qreal in the API, and using QT_SCALE_FACTOR it is indeed possible to set a fractional scale factor.

The Windows and Xcb platform plugins rounds the scale factor returned by pixelDensity() and returns integer values only. You could patch out the qRound() calls and test how this works.

Note that we don’t support or guarantee glitch free graphics at fractional scale factors (hence the qRound calls in pixelDensity()). There is a possibility that a solution like codereview.qt-project.org/#/c/143819 may be available in the future, but not for 5.6.

>  
> (2) Allow setting the devicePixelRatio programatically.  
> The current method via an environment variable might not be considered acceptable, or a programmer might want to modify the built-in method of how it is determined automatically. Im not sure if this could be achieved now by e.g. calling QHighDpiScaling::setGlobalFactor(). Anyway, I think the mechanism should be part of the API, i.e. be simple, official, and documented (e.g. a virtual method which can be overloaded). It would avoid clumpsy work-arounds such as calling os.environ['QT_DEVICE_PIXEL_RATIO'] = str( int(winScale) ) from within the code.
>  
> Ideally the mechanism would allow one to set devicePixelRatio at a point in time where the fonts are already accessible (app.font(),QFontInfo()). (not sure if that's possible, but the current mechanism seems to set the pixel ratio in two steps, so I recon it might be)

Closest thing I've considered for public API is QWindow::setScaleFactor, which might have sufficiently strong use cases (simulation etc).

We really want the platform plugin to do the right thing though, optionally with user input if correct display metrics are not available.

>  
> (3) Don't calculate the scale from the display resolution (QPlatformScreen::pixelDensity()).
> In QT5.5 the devicePixelRatio is obviously set to either 1.0 or 2.0 depending on the resolution of the display. I'm not sure for Qt5.6, but it seems to be alike here. However, in Win the user can set a scaling such as 100%, 125%, 150%, 200%, and 250%, and the user can do so - and may want to do so - for whatever display she/he is using (anyone with ailing eyes is happy to use 125% on regular screens, or 250% on HDPI screens ;)). So - IMHO - the devicePixelRatio should actually be set to exactly this value, independent on any display resolution.

As far as I can see the Windows platform plugin uses GetDpiForMonitor() for both the font DPI and pixelDensity(). Then as noted above the DPI value is rounded by pixelDensity().

See also QTBUG-50120 for a summary of native API use.

Morten




More information about the Development mailing list