Windows: Add CefEnableHighDPISupport function and fix high-dpi scaling issues (issue #1674)

This commit is contained in:
Marshall Greenblatt 2015-08-07 16:04:03 -04:00
parent 2792d1bb12
commit 9e0d84d94a
9 changed files with 119 additions and 4 deletions

View File

@ -175,6 +175,13 @@ CEF_EXPORT void cef_quit_message_loop();
///
CEF_EXPORT void cef_set_osmodal_loop(int osModalLoop);
///
// Call during process startup to enable High-DPI support on Windows 7 or newer.
// Older versions of Windows should be left DPI-unaware because they do not
// support DirectWrite and GDI fonts are kerned very badly.
///
CEF_EXPORT void cef_enable_highdpi_support();
#ifdef __cplusplus
}
#endif

View File

@ -124,6 +124,14 @@ void CefQuitMessageLoop();
/*--cef()--*/
void CefSetOSModalLoop(bool osModalLoop);
///
// Call during process startup to enable High-DPI support on Windows 7 or newer.
// Older versions of Windows should be left DPI-unaware because they do not
// support DirectWrite and GDI fonts are kerned very badly.
///
/*--cef(capi_name=cef_enable_highdpi_support)--*/
void CefEnableHighDPISupport();
///
// Implement this interface to provide handler implementations. Methods will be
// called by the process and/or thread indicated.

View File

@ -37,6 +37,7 @@
#include "ui/aura/window_tree_host.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/win/shell.h"
#include "ui/gfx/screen.h"
#include "ui/gfx/win/hwnd_util.h"
#include "ui/views/widget/desktop_aura/desktop_window_tree_host_win.h"
#include "ui/views/widget/widget.h"
@ -809,11 +810,17 @@ bool CefBrowserHostImpl::PlatformCreateWindow() {
CefColorGetB(settings.background_color));
}
// Adjust for potential display scaling.
gfx::Point point = gfx::Point(cr.right, cr.bottom);
float scale = gfx::Screen::GetNativeScreen()->
GetDisplayNearestPoint(point).device_scale_factor();
point = gfx::ToFlooredPoint(gfx::ScalePoint(point, 1.0f / scale));
CefWindowDelegateView* delegate_view =
new CefWindowDelegateView(background_color);
delegate_view->Init(window_info_.window,
web_contents(),
gfx::Rect(0, 0, cr.right, cr.bottom));
gfx::Rect(0, 0, point.x(), point.y()));
window_widget_ = delegate_view->GetWidget();
window_widget_->Show();

View File

@ -8,6 +8,8 @@
#include "base/message_loop/message_loop.h"
#include "ui/aura/window.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/gfx/screen.h"
#include "ui/views/controls/menu/menu_2.h"
CefMenuCreatorRunnerWin::CefMenuCreatorRunnerWin() {
@ -46,6 +48,11 @@ bool CefMenuCreatorRunnerWin::RunContextMenu(CefMenuCreator* manager) {
const gfx::Rect& bounds_in_screen = window->GetBoundsInScreen();
screen_point = gfx::Point(bounds_in_screen.x() + manager->params().x,
bounds_in_screen.y() + manager->params().y);
// Adjust for potential display scaling.
float scale = gfx::Screen::GetScreenFor(window)->
GetDisplayNearestWindow(window).device_scale_factor();
screen_point = gfx::ToFlooredPoint(gfx::ScalePoint(screen_point, scale));
}
// Show the menu. Blocks until the menu is dismissed.

View File

@ -1,6 +1,13 @@
// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that can
// be found in the LICENSE file.
// Copyright 2014 The Chromium Embedded Framework Authors. Portions copyright
// 2011 the Chromium Authors. All rights reserved. Use of this source code is
// governed by a BSD-style license that can be found in the LICENSE file.
#include "include/base/cef_build.h"
#if defined(OS_WIN)
#include <windows.h>
#include <shellscalingapi.h>
#endif
#include "include/internal/cef_trace_event_internal.h"
#include "include/internal/cef_logging_internal.h"
@ -10,6 +17,55 @@
#include "base/threading/platform_thread.h"
#include "base/trace_event/trace_event.h"
#if defined(OS_WIN)
#include "base/win/windows_version.h"
namespace {
// Implementation from chrome/app/chrome_exe_main_win.cc.
// Win8.1 supports monitor-specific DPI scaling.
bool SetProcessDpiAwarenessWrapper(PROCESS_DPI_AWARENESS value) {
typedef HRESULT(WINAPI *SetProcessDpiAwarenessPtr)(PROCESS_DPI_AWARENESS);
SetProcessDpiAwarenessPtr set_process_dpi_awareness_func =
reinterpret_cast<SetProcessDpiAwarenessPtr>(
GetProcAddress(GetModuleHandleA("user32.dll"),
"SetProcessDpiAwarenessInternal"));
if (set_process_dpi_awareness_func) {
HRESULT hr = set_process_dpi_awareness_func(value);
if (SUCCEEDED(hr)) {
VLOG(1) << "SetProcessDpiAwareness succeeded.";
return true;
} else if (hr == E_ACCESSDENIED) {
LOG(ERROR) << "Access denied error from SetProcessDpiAwareness. "
"Function called twice, or manifest was used.";
}
}
return false;
}
// This function works for Windows Vista through Win8. Win8.1 must use
// SetProcessDpiAwareness[Wrapper].
BOOL SetProcessDPIAwareWrapper() {
typedef BOOL(WINAPI *SetProcessDPIAwarePtr)(VOID);
SetProcessDPIAwarePtr set_process_dpi_aware_func =
reinterpret_cast<SetProcessDPIAwarePtr>(
GetProcAddress(GetModuleHandleA("user32.dll"),
"SetProcessDPIAware"));
return set_process_dpi_aware_func &&
set_process_dpi_aware_func();
}
void EnableHighDPISupport() {
if (!SetProcessDpiAwarenessWrapper(PROCESS_SYSTEM_DPI_AWARE)) {
SetProcessDPIAwareWrapper();
}
}
} // namespace
#endif // defined(OS_WIN)
// The contents of this file are a compilation unit that is not called by other
// functions in the the library. Consiquently MSVS will exclude it during the
// linker stage if we don't call a stub function.
@ -343,3 +399,13 @@ CEF_EXPORT cef_platform_thread_handle_t
return base::PlatformThread::CurrentHandle().platform_handle();
#endif
}
void CefEnableHighDPISupport() {
#if defined(OS_WIN)
// We don't want to set DPI awareness on pre-Win7 because we don't support
// DirectWrite there. GDI fonts are kerned very badly, so better to leave
// DPI-unaware and at effective 1.0. See also ShouldUseDirectWrite().
if (base::win::GetVersion() >= base::win::VERSION_WIN7)
EnableHighDPISupport();
#endif
}

View File

@ -311,6 +311,13 @@ CEF_EXPORT void cef_set_osmodal_loop(int osModalLoop) {
osModalLoop?true:false);
}
CEF_EXPORT void cef_enable_highdpi_support() {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
CefEnableHighDPISupport();
}
CEF_EXPORT int cef_get_geolocation(
struct _cef_get_geolocation_callback_t* callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

View File

@ -303,6 +303,13 @@ CEF_GLOBAL void CefSetOSModalLoop(bool osModalLoop) {
osModalLoop);
}
CEF_GLOBAL void CefEnableHighDPISupport() {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Execute
cef_enable_highdpi_support();
}
CEF_GLOBAL bool CefGetGeolocation(
CefRefPtr<CefGetGeolocationCallback> callback) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING

View File

@ -32,6 +32,9 @@ namespace client {
namespace {
int RunMain(HINSTANCE hInstance, int nCmdShow) {
// Enable High-DPI support on Windows 7 or newer.
CefEnableHighDPISupport();
CefMainArgs main_args(hInstance);
void* sandbox_info = NULL;

View File

@ -29,6 +29,9 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// Enable High-DPI support on Windows 7 or newer.
CefEnableHighDPISupport();
void* sandbox_info = NULL;
#if defined(CEF_USE_SANDBOX)