Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Wayland and fractional screen scaling reported as integer by wayland-info and (Q)Screen
Forum Updated to NodeBB v4.3 + New Features

Wayland and fractional screen scaling reported as integer by wayland-info and (Q)Screen

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 3 Posters 551 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    aran
    wrote on last edited by
    #1

    Hello all,

    I'm running an up-to-date Arch system (Qt 6.8.1) with Plasma 6.2.4 with Wayland and everything works just great. I have my screen scale factor set to 2 and that also is not causing any problems. However, I received a bug report for an Qt/QML application I'm developing that was related to fractional scaling, and digging a little deeper I noticed the following issue:

    When the scale factor in the Plasma display settings is set to anything 101% to 200%, then wayland-info simply reports an integer scale factor of 2 and I get that very same value from Qt's QScreen::devicePixelRatio() (and similarly QML's Screen.devicePixelRatio). This means that when the scale factor is set to, for instance, 150%, the wrong value is reported by both wayland-info and (Q)Screen. Note that this does in no way affect the display of the application, everything works just fine there. However, in my application I need to react to the scale factor inside of my application and thus this is causing some issues there.

    I found that GwenView is able to get the right value , and since it is based on Qt I dug into its source code a little to find out how they do it. Turns out, they use QGraphicsScene::devicePixelRatio() which I don't have with QML, however, that method does indeed return the correct scaling factor of 1.5. Thus, Qt knows about the right value but it seems to not report the right one through (Q)Screen for some reason.

    I recall there being quite a bit of talk around wayland and (fractional) scaling of screens in the past, however, it seemed to pretty much work as expected by now. Except for this I guess. Did anybody run into this before? Any suggestions as to how to solve this? Is this a Qt bug (not sure about that since wayland-info also reports the wrong factor)?

    Thanks,

    aran

    1 Reply Last reply
    0
    • A Offline
      A Offline
      aran
      wrote on last edited by
      #2

      When using a single screen only I am now parsing the output of wayland-info -i output as a workaround:

      QProcess proc;
      proc.start("wayland-info", {"-i", "output"});
      proc.waitForFinished(1000);
      const QString out = proc.readAll();
      const int ret = proc.exitCode();
      
      if(ret == 0) {
      
          int logicalW = 0, logicalH = 0;
          int physicalW = 0, physicalH = 0;
      
          const QStringList parts = out.split("\n");
          for(const QString &line : parts) {
      
              if(line.contains("logical_width:") && line.contains("logical_height:")) {
                  logicalW = line.split("logical_width: ")[1].split(",")[0].toInt();
                  logicalH = line.split("logical_height: ")[1].split("\n")[0].toInt();
              }
      
              if(!line.contains("logical_width:") && !line.contains("logical_height:") && line.contains("width:") && line.contains("height:")) {
                  physicalW = line.split("width: ")[1].split(" ")[0].toInt();
                  physicalH = line.split("height: ")[1].split(" ")[0].toInt();
              }
      
          }
      
          if(physicalW > 0 && physicalH > 0 && logicalW > 0 && logicalH > 0) {
      
              const double fac1 = static_cast<double>(physicalW)/static_cast<double>(logicalW);
              const double fac2 = static_cast<double>(physicalH)/static_cast<double>(logicalH);
      
              if(fabs(fac1-fac2) < 1e-6 && fac1 > 0.5 && fac1 < 5)
                  return fac1;
      
          }
      
      }
      

      This seems to work quite well based on the limited testing I was able to do, but of course I would prefer a proper solution if anybody has one.

      JonBJ 1 Reply Last reply
      0
      • A aran

        When using a single screen only I am now parsing the output of wayland-info -i output as a workaround:

        QProcess proc;
        proc.start("wayland-info", {"-i", "output"});
        proc.waitForFinished(1000);
        const QString out = proc.readAll();
        const int ret = proc.exitCode();
        
        if(ret == 0) {
        
            int logicalW = 0, logicalH = 0;
            int physicalW = 0, physicalH = 0;
        
            const QStringList parts = out.split("\n");
            for(const QString &line : parts) {
        
                if(line.contains("logical_width:") && line.contains("logical_height:")) {
                    logicalW = line.split("logical_width: ")[1].split(",")[0].toInt();
                    logicalH = line.split("logical_height: ")[1].split("\n")[0].toInt();
                }
        
                if(!line.contains("logical_width:") && !line.contains("logical_height:") && line.contains("width:") && line.contains("height:")) {
                    physicalW = line.split("width: ")[1].split(" ")[0].toInt();
                    physicalH = line.split("height: ")[1].split(" ")[0].toInt();
                }
        
            }
        
            if(physicalW > 0 && physicalH > 0 && logicalW > 0 && logicalH > 0) {
        
                const double fac1 = static_cast<double>(physicalW)/static_cast<double>(logicalW);
                const double fac2 = static_cast<double>(physicalH)/static_cast<double>(logicalH);
        
                if(fabs(fac1-fac2) < 1e-6 && fac1 > 0.5 && fac1 < 5)
                    return fac1;
        
            }
        
        }
        

        This seems to work quite well based on the limited testing I was able to do, but of course I would prefer a proper solution if anybody has one.

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #3

        @aran
        I know nothing about this, but if you want to replace calling that command its source is at https://gitlab.freedesktop.org/wayland/wayland-utils/-/tree/main/wayland-info?ref_type=heads, so you could borrow the bits you need?

        1 Reply Last reply
        0
        • C ccatterina referenced this topic on
        • C Offline
          C Offline
          ccatterina
          wrote on last edited by
          #4

          hi @aran , I have the same problem, have you found a solution? thank you!

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved