cefsharp / CefSharp

.NET (WPF and Windows Forms) bindings for the Chromium Embedded Framework
http://cefsharp.github.io/
Other
9.89k stars 2.92k forks source link

Doc - High-DPI support is now enabled by default in Chromium #4410

Open amaitland opened 1 year ago

amaitland commented 1 year ago

Starting in M108 High-DPI support is now enabled by default in Chromium.

Additionally, as a refactor to move responsibility out of the embedder this change moves the existing EnableHighDPISupport calls in chrome_exe_main_win.cc into the respective GpuMain & BrowserMainRunnerImpl for the GPU & Browser processes.

https://github.com/chromiumembedded/cef/issues/3452

amaitland commented 1 year ago

For WPF the default would appear to be still System aware, WPF must be setting that somewhere internally (which makes sense as that's the default that WPF uses). So setting via the app.manifest is still required.

amaitland commented 1 year ago

M111 will be the first version to rely on the Chromium default. The BrowserSubProcess no longer has app.manifest entries for DPI Awareness. Setting the DPI Awareness programmatically looks like it also influences the GPU process. See https://github.com/cefsharp/CefSharp/issues/2927#issuecomment-1457456272

UweKeim commented 1 year ago

I want to continue using CefSharp in a WinForms app that is currently not yet capable of running in High-DPI mode.

Is there still a way to fall back to non-High-DPI mode?


Update 1

It seems that disabling High-DPI through the application manifest did not help.

Instead, I removed all High-DPI related stuff from the manifest and instead did call the following right at the beginning of my application:

SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);

So far, it seems that this works.

(Context: I'm using CefSharp as "self-hosted" in a .NET 7 WinForms application, 64-bit)

Yokomoko commented 1 year ago

I cannot seem to find this SetProcessDpiAwarenessContext method, do you know where this is? As I also need this.

UweKeim commented 1 year ago

@Yokomoko Sure, it is P/Invoke:

[DllImport(@"user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetProcessDpiAwarenessContext(IntPtr dpiAWarenessContext);

private const int DPI_AWARENESS_CONTEXT_UNAWARE = -1;
private const int DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED = -5;

My call then looks like:

var r = SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE);
if (!r)
{
    var error = Marshal.GetLastWin32Error();
    Trace.TraceWarning($@"Error settings DPI awareness: {error}.");
}
jquerijero commented 6 months ago

There is a bitmap scaling that is used by Terminal Server and newer Windows versions for non-DPI aware (manifest not modified) application. Chromium instance is overriding that function by re-rendering the application (including windows that doesn't contain an embedded browser) causing it to resize and remove bitmap scaling.

amaitland commented 6 months ago

Chromium instance is overriding that function by re-rendering the application

Chromium uses Per Monitor V2 by default.

You can override this behaviour as

Setting the DPI Awareness programmatically looks like it also influences the GPU process. See #2927 (comment)

There are some additional examples of setting DPI awareness programmatically.

amaitland commented 5 months ago

In the context of WinForms. Setting DPI Awareness via app.manifest is no longer recommended when using .Net 4.8 or greater (this includes newer versions including .Net 8.0).

See https://learn.microsoft.com/en-us/dotnet/desktop/winforms/wfdev-diagnostics/wfac010?view=netdesktop-8.0 for Microsoft guidance regarding the compiler warning that will be raised.

Starting in .Net Core 3.0 you can use the WinForms specific API. Some examples (refer to the Microsoft documentation for more details)

Application.SetHighDpiMode(HighDpiMode.DpiUnaware);
Application.SetHighDpiMode(HighDpiMode.DpiUnawareGdiScaled);
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.SetHighDpiMode(HighDpiMode.PerMonitor);
Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);

https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.application.sethighdpimode?view=windowsdesktop-8.0