Skip to content

cef.DpiAware.EnableHighDpiSupport() doesn't work well. Update pyinstaller example. Update docs. #530

@amstaff8

Description

@amstaff8

Hi

I can't get cef python to work with dpi adware.
I have cef python 66 with pywin32 224 (python 3.6.8).

I added the method cef.DpiAware.EnableHighDpiSupport() after line 28 of your example cefpython/examples/pywin32.py

But it doesn’t work (see the screenshot). I’ve tested it also with PyQt but the result is the same.

21_06_2019__12_12_02
21_06_2019__12_13_06

Activity

cztomczak

cztomczak commented on Jun 24, 2019

@cztomczak
Owner

The wxpython.py example supports High DPI by default. Does it work for you?

Please provide exact steps to reproduce your issue from the screenshot.

amstaff8

amstaff8 commented on Jun 24, 2019

@amstaff8
Author

Same result. My steps:

  1. I’ve downloaded cefpython/examples/wxpython.py
  2. I ran pip install wxpython (and it has installed wxpython-4.0.6)
  3. I ran the command: python wxpython.py

This is the output:

[wxpython.py] System DPI settings: (192, 192)
[wxpython.py] wx.GetDisplayPPI = (267, 267)
[wxpython.py] wx.GetDisplaySize = (2736, 1824)
[wxpython.py] MainFrame declared size: (900, 640)
[wxpython.py] MainFrame DPI scaled size: (1800, 1280)
[wxpython.py] MainFrame actual size: (1800, 1280)

And this is the result:

24_06_2019__16_38_34

This is my resolution:

24_06_2019__16_48_47

cztomczak

cztomczak commented on Jun 24, 2019

@cztomczak
Owner

This is DPI awareness issue. The example sets DPI awareness via a call to cef.DpiAware.EnableHighDpiSupport, but the call occurs too late in Python programs on some machines, it's a race condition. DPI awareness needs to be set for the executable before Python program executes. Same for the subprocess.exe executable that runs the Renderer subprocess. If you remove the call to EnableHighDpiSupport you will get rid of double rendering, but it will result in a different rendering issue with app appearing blurry.

It is recommended to set High DPI awareness through manifest that is attached inside or next to executable. Such manifest must be added for both main executable and subprocess executable. Sometimes it is too late to set DPI awareness during runtime, so it must be set through manifest. If you want to fix the issue on a developer machine then go find python.exe executable and set appropriate file properties. On Windows 7 select "Compatibility" tab and check "Disable display scaling on high DPI settings".

For example to set DPI awareness through manifest create two files: myapp.exe.manifest and subprocess.exe.manifest in the same directory where myapp.exe and subprocess.exe executables reside. Edit both of these manifest files, so that they contain these contents:

<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"></supportedOS> 
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS> 
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"></supportedOS> 
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"></supportedOS> 
    </application>
  </compatibility>

  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel level="asInvoker"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>

  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>true/PM</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>

</asmv1:assembly>

Some users report that this still doesn't work for them and it works only after embedding manifest inside the exe with such command:

mt.exe -nologo -manifest myapp.exe.manifest -outputresource:"myapp.exe;1"
mt.exe -nologo -manifest subprocess.exe.manifest -outputresource:"subprocess.exe;1"

When using pyinstaller you might not be able to embed manifest inside myapp.exe executable, in my case it resulted in errors. In such case you have to modify the existing manifest file that is placed next to exe, it was generated by pyinstaller. You cannot overwrite it entirely with a new file, because it contains other necessary options, so manual editing is required. Embedding manifest inside subprocess.exe executable will alway work fine.

pi-slh

pi-slh commented on Jul 31, 2019

@pi-slh

I've recently spent some time working through a similar issue in our cefpython-based app.

The app is intended to run on a Dell tablet running Windows 10 where the system Display Scale setting is very likely to be greater than 100%. It is using CEF 66, python 3.7.3 and wxPython 4.0.6.

The app was exhibiting the rendering artefact described and illustrated in this issue whereby the UI is drawn twice - once at the desired scale, and a duplicated, smaller version aligned in the top left of the screen. Touch and mouse events would go to the right place in the full-sized UI, but the updates would only be rendered in the smaller version.

Setting a chrome switch to disable GPU compositing has 'fixed' this issue.

Using any of these switches 'fixes' the issue.

--disable-gpu
--disable-gpu-compositing
--disable-gpu-driver-bug-workarounds

The solution in my situation is;

cef.Initialize(settings={}, switches={'disable-gpu-compositing': None})

I've seen this issue on Dell machines with integrated Intel GPUs and with an Nvidia card.

I haven't identified a root cause.

cztomczak

cztomczak commented on Jul 31, 2019

@cztomczak
Owner

@pi-slh Have you embedded a DPI aware manifest in your app? See my comment: #530 (comment)

pi-slh

pi-slh commented on Jul 31, 2019

@pi-slh

@cztomczak I saw the comment and tried putting a .manifest next to both the python.exe and the subprocess.exe that are the entry points for our app. I'm not sure that they are doing anything - my reading suggests the python.exe has an embedded manifest and therefore ignores the .manifest next to it. We're not building our own executable at the moment, just running python.exe scriptname.py to startup.
I've been unable to get the layout I want in the browser by setting the High DPI scaling override on the application executable, so I haven't looked into manifests any further, assuming that it wouldn't give me the result I was after.
Thanks for your attention :)

cztomczak

cztomczak commented on Jul 31, 2019

@cztomczak
Owner

@pi-slh The issue is with DPI support and fixing it by disabling GPU is not a good idea. Unless you have a different issue. What do you mean by "I've been unable to get the layout I want in the browser by setting the High DPI scaling override on the application executable"? Are you sure you've checked the right option? Have you tested with original wxpython.py example?

dfb

dfb commented on Nov 30, 2019

@dfb

For anyone stuck on this, it never worked for me using a manifest file next to the exe, but it did work if I embedded the manifest inside the exe:

mt.exe -nologo -manifest subprocess.exe.manifest -outputresource:"subprocess.exe;1"

changed the title [-]cef.DpiAware.EnableHighDpiSupport() doesn't work well[/-] [+]cef.DpiAware.EnableHighDpiSupport() doesn't work well. Update pyinstaller example to embed High DPI manifest files in exe's.[/+] on Jan 16, 2020
cztomczak

cztomczak commented on Jan 16, 2020

@cztomczak
Owner

We should update the pyinstaller example to embed the necessary High DPI manifest files in the exe's. Marking this for next release.

18 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @dfb@cztomczak@bekatd@marcelomanzo@linesight

        Issue actions

          cef.DpiAware.EnableHighDpiSupport() doesn't work well. Update pyinstaller example. Update docs. · Issue #530 · cztomczak/cefpython