Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-63544

Scale factor does not match windows(buttons) and fonts for Hi-DPI (Retina) displays

    XMLWordPrintable

    Details

      Description

      When enabling 

      QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 

      the application detects screen DPI scaling factor and scale up the user interface(main window and buttuns) and fonts.

      The fonts are scaled always, but windows and buttons are scaled differently from fonts. For buttons and mainwindow used rounded fragmental scale factor - that is defenetly wrong.

      I.e if Windows's screen dpi scalefactor is set to 125% => that is mean 1.25 system scale factor, it is treated as 1.25 for fonts and 1.0 for buttons due to rounding 1.25 to 1.0.

      100% --> 1.00 -fonts
      100% --> 1.00 -buttons, main window (default)
      -----
      125% --> 1.25 -fonts
      125% --> 1.00 -buttons, main window (small)
      -----
      149% -->1.49 - fonts
      149% -->1.00 -buttons, main window (terrible small)
      -----
      150% -->1.50 - fonts
      150% -->2.00 -buttons, main window (too big)
      

      On the picture it is seen that it is hard to predict the size of the button that is needed to fit font scale on HiDPI display that would be chousen by user.

      Even it we make button wide then the text it is not enough to make button text looks good.

      So application created on normal machines looks and feel buggy and ugly on retina display with non round scales.

      It is mentioned in -----QTBUG-49195----- in late comments

      mentioned in ----QTBUG-55654---- saying that no fractional scalefactor supported, due to limitations of the styles, etc. 

      But actually fractional scalefactor does supported, due to QTBUG-52196, my test and many comments i've seen.

      I think font scale should be treated the same way as windows scale and be fractional on windows platform(i.e 1.25 both for fonts and buttons, not 1.25 for fonts and 1.00 for buttons).

      It is to be tested with different styles, etc.., and it would be nice to avoid recompiling full Qt just for removing

      qRound and replacing

       

      return qRound(logicalDpi().first / 96);

       

      to

      return (logicalDpi().first / 96.0);

      This searching, replacement and recompiling took 2 days of my time and it can be hard for a novice Qt programmer to find and face with other qt linking bugs witch can be present in qt sources(there was errors in linking Qt 5.8.0 in my case).

      So, I think, there must a environment variable, some thing like 

      qputenv("QT_FRACTIONAL_SCALE_FACTOR", "1");

      Just to avoid recompilling Qt to get tested.Then in later releases, it is to be out date and  deprecated

      To reproduce a bug make a button with a text fit the buttons size. Add this code (i use MSVS 2013 so there is prinf. Replace is for what is what is suitable for you like qDebug
       

       #include <qtwidgets\QApplication>
       #include <QtGui\QtGui>
       #include "MainForm.h"
      int main(int argc, char* argv[])
       { 
       //qputenv("QT_SCREEN_SCALE_FACTORS", "1.25");
      QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
      QApplication app(argc, argv);
      //print out screens factors
       QList<QScreen *> sk = app.screens();
       QList<QScreen*>::iterator it;
       int i = 0;
       int s = sk.size();
       for (it = sk.begin(); it != sk.end(); +it, i+)
      {
       printf("\n%d %f", i, it.operator*()->devicePixelRatio()); 
      }
      // Start mainForm
       MainForm * win = new MainForm();
       win->show();
      return app.exec();
      return 0;
       }
      

       
      it prints out windows and buttons scale factor.
      Then go to Conrol Panel -> Display -> move the slider right to one division (On Windows 8.1 this mean 125%), click Apply.

      Restart the application. It will print out new scale factor. Or not new, the same 1, due to Round of 1.25

      Uncomment

      //qputenv("QT_SCREEN_SCALE_FACTORS", "1.25");
      

      to test fractional scalefactor, compile and start the application and you will see fractional scalefactor, and what this time the text on the button fits button size.

      comment qputenv("QT_SCREEN_SCALE_FACTORS", "1.25"); once again, go to
      QT_Src\qtbase\src\plugins\platforms\windows\qwindowsscreen.cpp
      Omit qRound in QWindowsScreen::pixelDensity(), add dot zero to 96
      so it to be

      return (logicalDpi().first / 96.0);
      

      Recompile QT, replace qwindows.dll in a folder where you install qt. And you see the bug cleared.

      PS1 the difference this bug report to the others mentioned reports, is not in un supporting fract factors, but in difference between font and windows scale factors

      PS2. Actually i think the support of fractional scale factor might have present in Win Qt by default, without acting any special action exept setting QApplication::setAttribute(Qt::AA_EnableHighDpiScaling). So qRound in qwindowsscreen.cpp should be omitted and bugs in styles are to be found and fixed.

      So it better to make buttons behave like fonts.

      And i think it will be a bad idea to make fonts behave like buttons(e.i. be rounded too) and disabling fractional scalefactor at all. The second choice would be harder recovered from then the current state.

       

        Attachments

          Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            Activity

              People

              Assignee:
              laknoll Lars Knoll
              Reporter:
              alexandet sa I
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes