Windows: Add per monitor DPI support

Issue #2313 resolved
wu yong created an issue

Cef3 currently only support PROCESS_SYSTEM_DPI_AWARE, which has one issue in my current project, if I set my PROCESS_SYSTEM_DPI_AWARE in the application manually with windows API , instead of CefEnableHighDPISupport (PROCESS_SYSTEM_DPI_AWARE), then the right click context menu is always far away from the mouse pointer, eg. menu shows on the first monitor

int RunMain(HINSTANCE hInstance, int nCmdShow) { // Enable High-DPI support on Windows 7 or newer. //CefEnableHighDPISupport();

typedef HRESULT(__stdcall *SetProcessDPIAwareFunc)(PROCESS_DPI_AWARENESS);
HMODULE hUser32 = LoadLibrary(L"Shcore.dll");

if (hUser32)
    SetProcessDPIAwareFunc setDPIAware = (SetProcessDPIAwareFunc)GetProcAddress(hUser32, "SetProcessDpiAwareness");


CefMainArgs main_args(hInstance);

Comments (14)

  1. wu yong reporter

    Comment 101 by, Nov 30 (3 days ago) ⚐ Labels: Restrict-AddIssueComment-EditIssue Hello everyone! Thanks for your feedback.

    Chrome has been per-monitor DPI aware since

    Implementing per-monitor DPI is very tricky, and it's not surprising that there may be some issues floating around within Chrome or third-party extensions.

    If you do encounter issues, please create a new issue for that. This issue is intended to track the overall progress of per-monitor DPI awareness.

  2. Marshall Greenblatt
    • changed status to open

    Re-opening this issue because per-monitor is now supported by Chromium.

    Someone will need to examine the Chromium implementation in detail and propose the correct way to implement support in CEF.

  3. Marshall Greenblatt

    Per-monitor dpi support has been added in master revision 57b9cf9, 3325 branch revision 2e7b0e4 and 3282 branch revision 8f26fe0.

    Per-monitor dpi support will be enabled automatically when you call the CefEnableHighDPISupport() function if your Windows version supports it. When using the Views framework all controls will be scaled correctly without additional code changes. When embedding a CEF browser window (HWND) in another application you must:

    • Test if per-monitor dpi is supported by calling the GetProcessDpiAwareness function if it exists.
    • If your top-level HWND has a frame then call the EnableChildWindowDpiMessage or EnableNonClientDpiScaling function if they exist. This causes Windows to automatically scale the non-client area of the top-level HWND when the WM_DPICHANGED message is received.
    • Resize child controls when the WM_DPICHANGED message is received by the top-level HWND.
    • If using OSR, call NotifyScreenInfoChanged from WM_DPICHANGED and return the new scale factor from GetScreenInfo.

    See the changes to cefclient for example usage.

    There are some known issues with per-monitor dpi when the primary display is high-dpi and the application is launched on an external low-dpi monitor:

  4. Marshall Greenblatt

    Fix per-monitor DPI scaling of top-level browser windows and placement of context menus in master revision a5a5e7f, 3325 branch revision 503b117 and 3282 branch revision 1e5b631.

    I tried various ways of fixing the dialog DPI scaling but so far no luck.

  5. Ilya Melamed

    Seems that this part covers the "resize child controls when WM_DPICHANGED message is received by top-level HWND":

    cef_window_handle_t hWnd = m_cef_browser->GetHost()->GetWindowHandle();

    #ifdef WIN32 ::SendMessage(hWnd, WM_SIZE, 0, MAKELPARAM(width(), height())); #endif

  6. Marshall Greenblatt

    I believe everything is working as expected with currently supported CEF versions. If anyone is aware of an existing problem with those versions we can re-open this issue.

  7. Log in to comment