<div dir="ltr">Hi fellow developers,<br><br>Did you know that by enabling HiDPI support in your PyQt5 application you could inadvertently be causing some Linux users to end up with an application with a completely scrambled appearance? I don't know how rare it is, but it can happen. The Qt versions were 5.12 and 5.14.2. An example:<br><br><div><img src="https://damonlynch.net/rapid/bugs/1871649/screencorruption2.png" width="541" height="304"><br></div><div><br></div><div>The window should be 
approximating

this (with some differences obviously):</div><div><br></div><div><div><img src="https://damonlynch.net/rapid/screenshots/0921/features/mainwindow.png" width="541" height="426"><br></div><div><br></div><div>The workaround I developed is to enable HiDPI scaling support only if a monitor on the machine has scaling enabled. The good news is that on Qt that's really easy to figure out, but the bad news is that it never works under a Gtk derived desktop! Therefore I wrote this:</div><div><br></div><div>
<pre class="gmail-markdown-highlight"><code class="gmail-hljs gmail-python"><span class="gmail-hljs-function"><span class="gmail-hljs-keyword">def</span> <span class="gmail-hljs-title">any_screen_scaled_gdk</span><span class="gmail-hljs-params">()</span> -> bool:</span>
    <span class="gmail-hljs-string">"""
    Detect if any of the screens on this system have scaling enabled.

    Uses GDK to do the querying.

    :return: True if found, else False
    """</span>

    <span class="gmail-hljs-keyword">try</span>:
        display = Gdk.Display.get_default()
    <span class="gmail-hljs-keyword">except</span> Exception:
        <span class="gmail-hljs-keyword">import</span> logging
        logging.exception(
            <span class="gmail-hljs-string">'An unexpected error occurred when querying the systems display parameters. Exception:'</span>
        )
        <span class="gmail-hljs-keyword">return</span> <span class="gmail-hljs-keyword">False</span>

    <span class="gmail-hljs-keyword">if</span> display:
        <span class="gmail-hljs-keyword">try</span>:
            <span class="gmail-hljs-keyword">for</span> n <span class="gmail-hljs-keyword">in</span> range(display.get_n_monitors()):
                monitor = display.get_monitor(n)
                <span class="gmail-hljs-keyword">if</span> monitor.get_scale_factor() > <span class="gmail-hljs-number">1</span>:
                    <span class="gmail-hljs-keyword">return</span> <span class="gmail-hljs-keyword">True</span>
            <span class="gmail-hljs-keyword">return</span> <span class="gmail-hljs-keyword">False</span>

        <span class="gmail-hljs-keyword">except</span> AttributeError:
            <span class="gmail-hljs-comment"># get_n_monitors() was introduced in gtk 3.22</span>
            <span class="gmail-hljs-keyword">try</span>:
                screen = display.get_default_screen()
                <span class="gmail-hljs-keyword">for</span> monitor <span class="gmail-hljs-keyword">in</span> range(screen.get_n_monitors()):
                    <span class="gmail-hljs-keyword">if</span> screen.get_monitor_scale_factor(monitor) > <span class="gmail-hljs-number">1</span>:
                        <span class="gmail-hljs-keyword">return</span> <span class="gmail-hljs-keyword">True</span>
            <span class="gmail-hljs-keyword">except</span> Exception:
                <span class="gmail-hljs-keyword">import</span> logging
                logging.exception(<span class="gmail-hljs-string">'An unexpected error occurred when querying Gdk. Exception:'</span>)

    <span class="gmail-hljs-keyword">return</span> <span class="gmail-hljs-keyword">False</span>


<span class="gmail-hljs-function"><span class="gmail-hljs-keyword">def</span> <span class="gmail-hljs-title">any_screen_scaled_qt</span><span class="gmail-hljs-params">()</span> -> bool:</span>
    <span class="gmail-hljs-string">"""
    Detect if any of the screens on this system have scaling enabled.

    Call before QApplication is initialized. Uses temporary QGuiApplication.

    :return: True if found, else False
    """</span>

    app = QGuiApplication(sys.argv)
    <span class="gmail-hljs-keyword">return</span> app.devicePixelRatio() > <span class="gmail-hljs-number">1.0</span></code></pre>

</div><div><br></div><div>The basic idea is that if no monitor has scaling enabled, then don't enable it in the application. I'm optimistic this should work (let's see).<br></div><div><br></div><div>Hopefully this might be useful to someone else. I've tested it under Gtk Wayland & X11, and Qt X11. If you have a better approach or any thoughts in general about it, please feel free to share them. I'm surely far from the first to be confronted by this problem. <br></div><div><br></div><div>Damon<br></div><div><br></div></div><div>-- <br><a href="http://www.damonlynch.net">http://www.damonlynch.net</a></div></div>