Windows: Add per-monitor DPI support (issue #2313)
This commit is contained in:
parent
57fb011377
commit
57b9cf9ddd
|
@ -4,12 +4,6 @@
|
||||||
|
|
||||||
#include "include/base/cef_build.h"
|
#include "include/base/cef_build.h"
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <shellscalingapi.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "include/internal/cef_logging_internal.h"
|
#include "include/internal/cef_logging_internal.h"
|
||||||
#include "include/internal/cef_thread_internal.h"
|
#include "include/internal/cef_thread_internal.h"
|
||||||
#include "include/internal/cef_trace_event_internal.h"
|
#include "include/internal/cef_trace_event_internal.h"
|
||||||
|
@ -19,50 +13,8 @@
|
||||||
#include "base/trace_event/trace_event.h"
|
#include "base/trace_event/trace_event.h"
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
#include "base/win/windows_version.h"
|
#include "base/win/win_util.h"
|
||||||
|
#endif
|
||||||
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
|
// 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
|
// functions in the the library. Consiquently MSVS will exclude it during the
|
||||||
|
@ -399,10 +351,6 @@ cef_get_current_platform_thread_handle() {
|
||||||
|
|
||||||
void CefEnableHighDPISupport() {
|
void CefEnableHighDPISupport() {
|
||||||
#if defined(OS_WIN)
|
#if defined(OS_WIN)
|
||||||
// We don't want to set DPI awareness on pre-Win7 because we don't support
|
base::win::EnableHighDPISupport();
|
||||||
// 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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,13 @@
|
||||||
#include "tests/cefclient/browser/browser_window_osr_win.h"
|
#include "tests/cefclient/browser/browser_window_osr_win.h"
|
||||||
|
|
||||||
#include "tests/shared/browser/main_message_loop.h"
|
#include "tests/shared/browser/main_message_loop.h"
|
||||||
#include "tests/shared/browser/util_win.h"
|
|
||||||
|
|
||||||
namespace client {
|
namespace client {
|
||||||
|
|
||||||
BrowserWindowOsrWin::BrowserWindowOsrWin(BrowserWindow::Delegate* delegate,
|
BrowserWindowOsrWin::BrowserWindowOsrWin(BrowserWindow::Delegate* delegate,
|
||||||
const std::string& startup_url,
|
const std::string& startup_url,
|
||||||
const OsrRenderer::Settings& settings)
|
const OsrRenderer::Settings& settings)
|
||||||
: BrowserWindow(delegate),
|
: BrowserWindow(delegate), osr_hwnd_(NULL), device_scale_factor_(0) {
|
||||||
osr_hwnd_(NULL),
|
|
||||||
device_scale_factor_(client::GetDeviceScaleFactor()) {
|
|
||||||
osr_window_ = new OsrWindowWin(this, settings);
|
osr_window_ = new OsrWindowWin(this, settings);
|
||||||
client_handler_ = new ClientHandlerOsr(this, osr_window_.get(), startup_url);
|
client_handler_ = new ClientHandlerOsr(this, osr_window_.get(), startup_url);
|
||||||
}
|
}
|
||||||
|
@ -92,6 +89,7 @@ void BrowserWindowOsrWin::SetDeviceScaleFactor(float device_scale_factor) {
|
||||||
|
|
||||||
float BrowserWindowOsrWin::GetDeviceScaleFactor() const {
|
float BrowserWindowOsrWin::GetDeviceScaleFactor() const {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
|
DCHECK_GT(device_scale_factor_, 0);
|
||||||
return device_scale_factor_;
|
return device_scale_factor_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ OsrWindowWin::OsrWindowWin(Delegate* delegate,
|
||||||
hwnd_(NULL),
|
hwnd_(NULL),
|
||||||
hdc_(NULL),
|
hdc_(NULL),
|
||||||
hrc_(NULL),
|
hrc_(NULL),
|
||||||
device_scale_factor_(client::GetDeviceScaleFactor()),
|
device_scale_factor_(0),
|
||||||
painting_popup_(false),
|
painting_popup_(false),
|
||||||
render_task_pending_(false),
|
render_task_pending_(false),
|
||||||
hidden_(false),
|
hidden_(false),
|
||||||
|
@ -872,6 +872,7 @@ bool OsrWindowWin::GetRootScreenRect(CefRefPtr<CefBrowser> browser,
|
||||||
|
|
||||||
bool OsrWindowWin::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) {
|
bool OsrWindowWin::GetViewRect(CefRefPtr<CefBrowser> browser, CefRect& rect) {
|
||||||
CEF_REQUIRE_UI_THREAD();
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
DCHECK_GT(device_scale_factor_, 0);
|
||||||
|
|
||||||
rect.x = rect.y = 0;
|
rect.x = rect.y = 0;
|
||||||
rect.width = DeviceToLogical(client_rect_.right - client_rect_.left,
|
rect.width = DeviceToLogical(client_rect_.right - client_rect_.left,
|
||||||
|
@ -887,6 +888,7 @@ bool OsrWindowWin::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||||
int& screenX,
|
int& screenX,
|
||||||
int& screenY) {
|
int& screenY) {
|
||||||
CEF_REQUIRE_UI_THREAD();
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
DCHECK_GT(device_scale_factor_, 0);
|
||||||
|
|
||||||
if (!::IsWindow(hwnd_))
|
if (!::IsWindow(hwnd_))
|
||||||
return false;
|
return false;
|
||||||
|
@ -903,6 +905,7 @@ bool OsrWindowWin::GetScreenPoint(CefRefPtr<CefBrowser> browser,
|
||||||
bool OsrWindowWin::GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
bool OsrWindowWin::GetScreenInfo(CefRefPtr<CefBrowser> browser,
|
||||||
CefScreenInfo& screen_info) {
|
CefScreenInfo& screen_info) {
|
||||||
CEF_REQUIRE_UI_THREAD();
|
CEF_REQUIRE_UI_THREAD();
|
||||||
|
DCHECK_GT(device_scale_factor_, 0);
|
||||||
|
|
||||||
if (!::IsWindow(hwnd_))
|
if (!::IsWindow(hwnd_))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include "tests/cefclient/browser/root_window_win.h"
|
#include "tests/cefclient/browser/root_window_win.h"
|
||||||
|
|
||||||
|
#include <shellscalingapi.h>
|
||||||
|
|
||||||
#include "include/base/cef_bind.h"
|
#include "include/base/cef_bind.h"
|
||||||
#include "include/base/cef_build.h"
|
#include "include/base/cef_build.h"
|
||||||
#include "include/cef_app.h"
|
#include "include/cef_app.h"
|
||||||
|
@ -46,30 +48,55 @@ INT_PTR CALLBACK AboutWndProc(HWND hDlg,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetButtonWidth() {
|
// Returns true if the process is per monitor DPI aware.
|
||||||
static int button_width = BUTTON_WIDTH;
|
bool IsProcessPerMonitorDpiAware() {
|
||||||
static bool initialized = false;
|
enum class PerMonitorDpiAware {
|
||||||
|
UNKNOWN = 0,
|
||||||
if (!initialized) {
|
PER_MONITOR_DPI_UNAWARE,
|
||||||
button_width =
|
PER_MONITOR_DPI_AWARE,
|
||||||
LogicalToDevice(BUTTON_WIDTH, client::GetDeviceScaleFactor());
|
};
|
||||||
initialized = true;
|
static PerMonitorDpiAware per_monitor_dpi_aware = PerMonitorDpiAware::UNKNOWN;
|
||||||
|
if (per_monitor_dpi_aware == PerMonitorDpiAware::UNKNOWN) {
|
||||||
|
per_monitor_dpi_aware = PerMonitorDpiAware::PER_MONITOR_DPI_UNAWARE;
|
||||||
|
HMODULE shcore_dll = ::LoadLibrary(L"shcore.dll");
|
||||||
|
if (shcore_dll) {
|
||||||
|
typedef HRESULT(WINAPI * GetProcessDpiAwarenessPtr)(
|
||||||
|
HANDLE, PROCESS_DPI_AWARENESS*);
|
||||||
|
GetProcessDpiAwarenessPtr func_ptr =
|
||||||
|
reinterpret_cast<GetProcessDpiAwarenessPtr>(
|
||||||
|
::GetProcAddress(shcore_dll, "GetProcessDpiAwareness"));
|
||||||
|
if (func_ptr) {
|
||||||
|
PROCESS_DPI_AWARENESS awareness;
|
||||||
|
if (SUCCEEDED(func_ptr(nullptr, &awareness)) &&
|
||||||
|
awareness == PROCESS_PER_MONITOR_DPI_AWARE)
|
||||||
|
per_monitor_dpi_aware = PerMonitorDpiAware::PER_MONITOR_DPI_AWARE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return per_monitor_dpi_aware == PerMonitorDpiAware::PER_MONITOR_DPI_AWARE;
|
||||||
return button_width;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetURLBarHeight() {
|
// DPI value for 1x scale factor.
|
||||||
static int urlbar_height = URLBAR_HEIGHT;
|
#define DPI_1X 96
|
||||||
static bool initialized = false;
|
|
||||||
|
|
||||||
if (!initialized) {
|
int GetWindowScaleFactor(HWND hwnd) {
|
||||||
urlbar_height =
|
if (hwnd && IsProcessPerMonitorDpiAware()) {
|
||||||
LogicalToDevice(URLBAR_HEIGHT, client::GetDeviceScaleFactor());
|
typedef UINT(WINAPI * GetDpiForWindowPtr)(HWND);
|
||||||
initialized = true;
|
static GetDpiForWindowPtr func_ptr = reinterpret_cast<GetDpiForWindowPtr>(
|
||||||
|
GetProcAddress(GetModuleHandle(L"user32.dll"), "GetDpiForWindow"));
|
||||||
|
if (func_ptr)
|
||||||
|
return func_ptr(hwnd) / DPI_1X;
|
||||||
}
|
}
|
||||||
|
|
||||||
return urlbar_height;
|
return client::GetDeviceScaleFactor();
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetButtonWidth(HWND hwnd) {
|
||||||
|
return LogicalToDevice(BUTTON_WIDTH, GetWindowScaleFactor(hwnd));
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetURLBarHeight(HWND hwnd) {
|
||||||
|
return LogicalToDevice(URLBAR_HEIGHT, GetWindowScaleFactor(hwnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -84,6 +111,7 @@ RootWindowWin::RootWindowWin()
|
||||||
hwnd_(NULL),
|
hwnd_(NULL),
|
||||||
draggable_region_(NULL),
|
draggable_region_(NULL),
|
||||||
font_(NULL),
|
font_(NULL),
|
||||||
|
font_height_(0),
|
||||||
back_hwnd_(NULL),
|
back_hwnd_(NULL),
|
||||||
forward_hwnd_(NULL),
|
forward_hwnd_(NULL),
|
||||||
reload_hwnd_(NULL),
|
reload_hwnd_(NULL),
|
||||||
|
@ -97,7 +125,8 @@ RootWindowWin::RootWindowWin()
|
||||||
find_next_(false),
|
find_next_(false),
|
||||||
find_match_case_last_(false),
|
find_match_case_last_(false),
|
||||||
window_destroyed_(false),
|
window_destroyed_(false),
|
||||||
browser_destroyed_(false) {
|
browser_destroyed_(false),
|
||||||
|
called_enable_non_client_dpi_scaling_(false) {
|
||||||
find_buff_[0] = 0;
|
find_buff_[0] = 0;
|
||||||
|
|
||||||
// Create a HRGN representing the draggable window area.
|
// Create a HRGN representing the draggable window area.
|
||||||
|
@ -313,8 +342,6 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings,
|
||||||
// Adjust the window size to account for window frame and controls.
|
// Adjust the window size to account for window frame and controls.
|
||||||
RECT window_rect = start_rect_;
|
RECT window_rect = start_rect_;
|
||||||
::AdjustWindowRectEx(&window_rect, dwStyle, with_controls_, 0);
|
::AdjustWindowRectEx(&window_rect, dwStyle, with_controls_, 0);
|
||||||
if (with_controls_)
|
|
||||||
window_rect.bottom += GetURLBarHeight();
|
|
||||||
|
|
||||||
x = start_rect_.left;
|
x = start_rect_.left;
|
||||||
y = start_rect_.top;
|
y = start_rect_.top;
|
||||||
|
@ -322,110 +349,23 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings,
|
||||||
height = window_rect.bottom - window_rect.top;
|
height = window_rect.bottom - window_rect.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
browser_settings_ = settings;
|
||||||
|
|
||||||
// Create the main window initially hidden.
|
// Create the main window initially hidden.
|
||||||
hwnd_ = CreateWindow(window_class.c_str(), window_title.c_str(), dwStyle, x,
|
CreateWindow(window_class.c_str(), window_title.c_str(), dwStyle, x, y, width,
|
||||||
y, width, height, NULL, NULL, hInstance, NULL);
|
height, NULL, NULL, hInstance, this);
|
||||||
CHECK(hwnd_);
|
CHECK(hwnd_);
|
||||||
|
|
||||||
// Associate |this| with the main window.
|
if (!called_enable_non_client_dpi_scaling_ && IsProcessPerMonitorDpiAware()) {
|
||||||
SetUserDataPtr(hwnd_, this);
|
// This call gets Windows to scale the non-client area when WM_DPICHANGED
|
||||||
|
// is fired on Windows versions < 10.0.14393.0.
|
||||||
RECT rect;
|
// Derived signature; not available in headers.
|
||||||
GetClientRect(hwnd_, &rect);
|
typedef LRESULT(WINAPI * EnableChildWindowDpiMessagePtr)(HWND, BOOL);
|
||||||
|
static EnableChildWindowDpiMessagePtr func_ptr =
|
||||||
if (with_controls_) {
|
reinterpret_cast<EnableChildWindowDpiMessagePtr>(GetProcAddress(
|
||||||
// Create the child controls.
|
GetModuleHandle(L"user32.dll"), "EnableChildWindowDpiMessage"));
|
||||||
int x_offset = 0;
|
if (func_ptr)
|
||||||
|
func_ptr(hwnd_, TRUE);
|
||||||
const int button_width = GetButtonWidth();
|
|
||||||
const int urlbar_height = GetURLBarHeight();
|
|
||||||
const int font_height = LogicalToDevice(14, client::GetDeviceScaleFactor());
|
|
||||||
|
|
||||||
// Create a scaled font.
|
|
||||||
font_ =
|
|
||||||
::CreateFont(-font_height, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
|
|
||||||
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
|
||||||
DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Arial");
|
|
||||||
|
|
||||||
back_hwnd_ = CreateWindow(
|
|
||||||
L"BUTTON", L"Back", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
|
||||||
x_offset, 0, button_width, urlbar_height, hwnd_,
|
|
||||||
reinterpret_cast<HMENU>(IDC_NAV_BACK), hInstance, 0);
|
|
||||||
CHECK(back_hwnd_);
|
|
||||||
SendMessage(back_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_), TRUE);
|
|
||||||
x_offset += button_width;
|
|
||||||
|
|
||||||
forward_hwnd_ =
|
|
||||||
CreateWindow(L"BUTTON", L"Forward",
|
|
||||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
|
||||||
x_offset, 0, button_width, urlbar_height, hwnd_,
|
|
||||||
reinterpret_cast<HMENU>(IDC_NAV_FORWARD), hInstance, 0);
|
|
||||||
CHECK(forward_hwnd_);
|
|
||||||
SendMessage(forward_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_),
|
|
||||||
TRUE);
|
|
||||||
x_offset += button_width;
|
|
||||||
|
|
||||||
reload_hwnd_ =
|
|
||||||
CreateWindow(L"BUTTON", L"Reload",
|
|
||||||
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
|
||||||
x_offset, 0, button_width, urlbar_height, hwnd_,
|
|
||||||
reinterpret_cast<HMENU>(IDC_NAV_RELOAD), hInstance, 0);
|
|
||||||
CHECK(reload_hwnd_);
|
|
||||||
SendMessage(reload_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_),
|
|
||||||
TRUE);
|
|
||||||
x_offset += button_width;
|
|
||||||
|
|
||||||
stop_hwnd_ = CreateWindow(
|
|
||||||
L"BUTTON", L"Stop", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
|
||||||
x_offset, 0, button_width, urlbar_height, hwnd_,
|
|
||||||
reinterpret_cast<HMENU>(IDC_NAV_STOP), hInstance, 0);
|
|
||||||
CHECK(stop_hwnd_);
|
|
||||||
SendMessage(stop_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_), TRUE);
|
|
||||||
x_offset += button_width;
|
|
||||||
|
|
||||||
edit_hwnd_ = CreateWindow(L"EDIT", 0,
|
|
||||||
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT |
|
|
||||||
ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_DISABLED,
|
|
||||||
x_offset, 0, rect.right - button_width * 4,
|
|
||||||
urlbar_height, hwnd_, 0, hInstance, 0);
|
|
||||||
SendMessage(edit_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_), TRUE);
|
|
||||||
CHECK(edit_hwnd_);
|
|
||||||
|
|
||||||
// Override the edit control's window procedure.
|
|
||||||
edit_wndproc_old_ = SetWndProcPtr(edit_hwnd_, EditWndProc);
|
|
||||||
|
|
||||||
// Associate |this| with the edit window.
|
|
||||||
SetUserDataPtr(edit_hwnd_, this);
|
|
||||||
|
|
||||||
rect.top += urlbar_height;
|
|
||||||
|
|
||||||
if (!with_osr_) {
|
|
||||||
// Remove the menu items that are only used with OSR.
|
|
||||||
HMENU hMenu = ::GetMenu(hwnd_);
|
|
||||||
if (hMenu) {
|
|
||||||
HMENU hTestMenu = ::GetSubMenu(hMenu, 2);
|
|
||||||
if (hTestMenu) {
|
|
||||||
::RemoveMenu(hTestMenu, ID_TESTS_OSR_FPS, MF_BYCOMMAND);
|
|
||||||
::RemoveMenu(hTestMenu, ID_TESTS_OSR_DSF, MF_BYCOMMAND);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No controls so also remove the default menu.
|
|
||||||
::SetMenu(hwnd_, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_popup_) {
|
|
||||||
// Create the browser window.
|
|
||||||
CefRect cef_rect(rect.left, rect.top, rect.right - rect.left,
|
|
||||||
rect.bottom - rect.top);
|
|
||||||
browser_window_->CreateBrowser(hwnd_, cef_rect, settings,
|
|
||||||
delegate_->GetRequestContext(this));
|
|
||||||
} else {
|
|
||||||
// With popups we already have a browser window. Parent the browser window
|
|
||||||
// to the root window and show it in the correct location.
|
|
||||||
browser_window_->ShowPopup(hwnd_, rect.left, rect.top,
|
|
||||||
rect.right - rect.left, rect.bottom - rect.top);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!initially_hidden) {
|
if (!initially_hidden) {
|
||||||
|
@ -535,12 +475,15 @@ LRESULT CALLBACK RootWindowWin::RootWndProc(HWND hWnd,
|
||||||
LPARAM lParam) {
|
LPARAM lParam) {
|
||||||
REQUIRE_MAIN_THREAD();
|
REQUIRE_MAIN_THREAD();
|
||||||
|
|
||||||
RootWindowWin* self = GetUserDataPtr<RootWindowWin*>(hWnd);
|
RootWindowWin* self = NULL;
|
||||||
if (!self)
|
if (message != WM_NCCREATE) {
|
||||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
self = GetUserDataPtr<RootWindowWin*>(hWnd);
|
||||||
DCHECK(hWnd == self->hwnd_);
|
if (!self)
|
||||||
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||||
|
DCHECK_EQ(hWnd, self->hwnd_);
|
||||||
|
}
|
||||||
|
|
||||||
if (message == self->find_message_id_) {
|
if (self && message == self->find_message_id_) {
|
||||||
// Message targeting the find dialog.
|
// Message targeting the find dialog.
|
||||||
LPFINDREPLACE lpfr = reinterpret_cast<LPFINDREPLACE>(lParam);
|
LPFINDREPLACE lpfr = reinterpret_cast<LPFINDREPLACE>(lParam);
|
||||||
CHECK(lpfr == &self->find_state_);
|
CHECK(lpfr == &self->find_state_);
|
||||||
|
@ -589,6 +532,10 @@ LRESULT CALLBACK RootWindowWin::RootWndProc(HWND hWnd,
|
||||||
self->OnMove();
|
self->OnMove();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
case WM_DPICHANGED:
|
||||||
|
self->OnDpiChanged(wParam, lParam);
|
||||||
|
break;
|
||||||
|
|
||||||
case WM_ERASEBKGND:
|
case WM_ERASEBKGND:
|
||||||
if (self->OnEraseBkgnd())
|
if (self->OnEraseBkgnd())
|
||||||
break;
|
break;
|
||||||
|
@ -629,6 +576,21 @@ LRESULT CALLBACK RootWindowWin::RootWndProc(HWND hWnd,
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_NCCREATE: {
|
||||||
|
CREATESTRUCT* cs = reinterpret_cast<CREATESTRUCT*>(lParam);
|
||||||
|
self = reinterpret_cast<RootWindowWin*>(cs->lpCreateParams);
|
||||||
|
DCHECK(self);
|
||||||
|
// Associate |self| with the main window.
|
||||||
|
SetUserDataPtr(hWnd, self);
|
||||||
|
self->hwnd_ = hWnd;
|
||||||
|
|
||||||
|
self->OnNCCreate(cs);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case WM_CREATE:
|
||||||
|
self->OnCreate(reinterpret_cast<CREATESTRUCT*>(lParam));
|
||||||
|
break;
|
||||||
|
|
||||||
case WM_NCDESTROY:
|
case WM_NCDESTROY:
|
||||||
// Clear the reference to |self|.
|
// Clear the reference to |self|.
|
||||||
SetUserDataPtr(hWnd, NULL);
|
SetUserDataPtr(hWnd, NULL);
|
||||||
|
@ -670,37 +632,70 @@ void RootWindowWin::OnSize(bool minimized) {
|
||||||
RECT rect;
|
RECT rect;
|
||||||
GetClientRect(hwnd_, &rect);
|
GetClientRect(hwnd_, &rect);
|
||||||
|
|
||||||
if (with_controls_) {
|
if (with_controls_ && edit_hwnd_) {
|
||||||
static int button_width = GetButtonWidth();
|
const int button_width = GetButtonWidth(hwnd_);
|
||||||
static int urlbar_height = GetURLBarHeight();
|
const int urlbar_height = GetURLBarHeight(hwnd_);
|
||||||
|
const int font_height = LogicalToDevice(14, GetWindowScaleFactor(hwnd_));
|
||||||
|
|
||||||
|
if (font_height != font_height_) {
|
||||||
|
if (font_) {
|
||||||
|
DeleteObject(font_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a scaled font.
|
||||||
|
font_ =
|
||||||
|
::CreateFont(-font_height, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
|
||||||
|
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
|
||||||
|
DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Arial");
|
||||||
|
|
||||||
|
SendMessage(back_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_),
|
||||||
|
TRUE);
|
||||||
|
SendMessage(forward_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_),
|
||||||
|
TRUE);
|
||||||
|
SendMessage(reload_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_),
|
||||||
|
TRUE);
|
||||||
|
SendMessage(stop_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_),
|
||||||
|
TRUE);
|
||||||
|
SendMessage(edit_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(font_),
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
// Resize the window and address bar to match the new frame size.
|
// Resize the window and address bar to match the new frame size.
|
||||||
rect.top += urlbar_height;
|
rect.top += urlbar_height;
|
||||||
|
|
||||||
int urloffset = rect.left + button_width * 4;
|
int x_offset = rect.left;
|
||||||
|
|
||||||
// |browser_hwnd| may be NULL if the browser has not yet been created.
|
// |browser_hwnd| may be NULL if the browser has not yet been created.
|
||||||
HWND browser_hwnd = NULL;
|
HWND browser_hwnd = NULL;
|
||||||
if (browser_window_)
|
if (browser_window_)
|
||||||
browser_hwnd = browser_window_->GetWindowHandle();
|
browser_hwnd = browser_window_->GetWindowHandle();
|
||||||
|
|
||||||
|
// Resize all controls.
|
||||||
|
HDWP hdwp = BeginDeferWindowPos(browser_hwnd ? 6 : 5);
|
||||||
|
hdwp = DeferWindowPos(hdwp, back_hwnd_, NULL, x_offset, 0, button_width,
|
||||||
|
urlbar_height, SWP_NOZORDER);
|
||||||
|
x_offset += button_width;
|
||||||
|
hdwp = DeferWindowPos(hdwp, forward_hwnd_, NULL, x_offset, 0, button_width,
|
||||||
|
urlbar_height, SWP_NOZORDER);
|
||||||
|
x_offset += button_width;
|
||||||
|
hdwp = DeferWindowPos(hdwp, reload_hwnd_, NULL, x_offset, 0, button_width,
|
||||||
|
urlbar_height, SWP_NOZORDER);
|
||||||
|
x_offset += button_width;
|
||||||
|
hdwp = DeferWindowPos(hdwp, stop_hwnd_, NULL, x_offset, 0, button_width,
|
||||||
|
urlbar_height, SWP_NOZORDER);
|
||||||
|
x_offset += button_width;
|
||||||
|
hdwp = DeferWindowPos(hdwp, edit_hwnd_, NULL, x_offset, 0,
|
||||||
|
rect.right - x_offset, urlbar_height, SWP_NOZORDER);
|
||||||
|
|
||||||
if (browser_hwnd) {
|
if (browser_hwnd) {
|
||||||
// Resize both the browser and the URL edit field.
|
|
||||||
HDWP hdwp = BeginDeferWindowPos(2);
|
|
||||||
hdwp =
|
|
||||||
DeferWindowPos(hdwp, edit_hwnd_, NULL, urloffset, 0,
|
|
||||||
rect.right - urloffset, urlbar_height, SWP_NOZORDER);
|
|
||||||
hdwp = DeferWindowPos(hdwp, browser_hwnd, NULL, rect.left, rect.top,
|
hdwp = DeferWindowPos(hdwp, browser_hwnd, NULL, rect.left, rect.top,
|
||||||
rect.right - rect.left, rect.bottom - rect.top,
|
rect.right - rect.left, rect.bottom - rect.top,
|
||||||
SWP_NOZORDER);
|
SWP_NOZORDER);
|
||||||
BOOL result = EndDeferWindowPos(hdwp);
|
|
||||||
ALLOW_UNUSED_LOCAL(result);
|
|
||||||
DCHECK(result);
|
|
||||||
} else {
|
|
||||||
// Resize just the URL edit field.
|
|
||||||
SetWindowPos(edit_hwnd_, NULL, urloffset, 0, rect.right - urloffset,
|
|
||||||
urlbar_height, SWP_NOZORDER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL result = EndDeferWindowPos(hdwp);
|
||||||
|
ALLOW_UNUSED_LOCAL(result);
|
||||||
|
DCHECK(result);
|
||||||
} else if (browser_window_) {
|
} else if (browser_window_) {
|
||||||
// Size the browser window to the whole client area.
|
// Size the browser window to the whole client area.
|
||||||
browser_window_->SetBounds(0, 0, rect.right, rect.bottom);
|
browser_window_->SetBounds(0, 0, rect.right, rect.bottom);
|
||||||
|
@ -715,6 +710,32 @@ void RootWindowWin::OnMove() {
|
||||||
browser->GetHost()->NotifyMoveOrResizeStarted();
|
browser->GetHost()->NotifyMoveOrResizeStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RootWindowWin::OnDpiChanged(WPARAM wParam, LPARAM lParam) {
|
||||||
|
if (LOWORD(wParam) != HIWORD(wParam)) {
|
||||||
|
NOTIMPLEMENTED() << "Received non-square scaling factors";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (browser_window_) {
|
||||||
|
if (with_osr_) {
|
||||||
|
browser_window_->SetDeviceScaleFactor(LOWORD(wParam) / DPI_1X);
|
||||||
|
} else {
|
||||||
|
// Forward the DPI change to the browser window handle.
|
||||||
|
HWND browser_hwnd = browser_window_->GetWindowHandle();
|
||||||
|
if (browser_hwnd) {
|
||||||
|
RECT child_rect = {};
|
||||||
|
SendMessage(browser_hwnd, WM_DPICHANGED, wParam,
|
||||||
|
reinterpret_cast<LPARAM>(&child_rect));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Suggested size and position of the current window scaled for the new DPI.
|
||||||
|
const RECT* rect = reinterpret_cast<RECT*>(lParam);
|
||||||
|
SetBounds(rect->left, rect->top, rect->right - rect->left,
|
||||||
|
rect->bottom - rect->top);
|
||||||
|
}
|
||||||
|
|
||||||
bool RootWindowWin::OnEraseBkgnd() {
|
bool RootWindowWin::OnEraseBkgnd() {
|
||||||
// Erase the background when the browser does not exist.
|
// Erase the background when the browser does not exist.
|
||||||
return (GetBrowser() == NULL);
|
return (GetBrowser() == NULL);
|
||||||
|
@ -821,6 +842,113 @@ void RootWindowWin::OnAbout() {
|
||||||
AboutWndProc);
|
AboutWndProc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RootWindowWin::OnNCCreate(LPCREATESTRUCT lpCreateStruct) {
|
||||||
|
if (IsProcessPerMonitorDpiAware()) {
|
||||||
|
// This call gets Windows to scale the non-client area when WM_DPICHANGED
|
||||||
|
// is fired on Windows versions >= 10.0.14393.0.
|
||||||
|
typedef BOOL(WINAPI * EnableNonClientDpiScalingPtr)(HWND);
|
||||||
|
static EnableNonClientDpiScalingPtr func_ptr =
|
||||||
|
reinterpret_cast<EnableNonClientDpiScalingPtr>(GetProcAddress(
|
||||||
|
GetModuleHandle(L"user32.dll"), "EnableNonClientDpiScaling"));
|
||||||
|
called_enable_non_client_dpi_scaling_ = !!(func_ptr && func_ptr(hwnd_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RootWindowWin::OnCreate(LPCREATESTRUCT lpCreateStruct) {
|
||||||
|
const HINSTANCE hInstance = lpCreateStruct->hInstance;
|
||||||
|
|
||||||
|
RECT rect;
|
||||||
|
GetClientRect(hwnd_, &rect);
|
||||||
|
|
||||||
|
if (with_controls_) {
|
||||||
|
// Create the child controls.
|
||||||
|
int x_offset = 0;
|
||||||
|
|
||||||
|
const int button_width = GetButtonWidth(hwnd_);
|
||||||
|
const int urlbar_height = GetURLBarHeight(hwnd_);
|
||||||
|
|
||||||
|
back_hwnd_ = CreateWindow(
|
||||||
|
L"BUTTON", L"Back", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
||||||
|
x_offset, 0, button_width, urlbar_height, hwnd_,
|
||||||
|
reinterpret_cast<HMENU>(IDC_NAV_BACK), hInstance, 0);
|
||||||
|
CHECK(back_hwnd_);
|
||||||
|
x_offset += button_width;
|
||||||
|
|
||||||
|
forward_hwnd_ =
|
||||||
|
CreateWindow(L"BUTTON", L"Forward",
|
||||||
|
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
||||||
|
x_offset, 0, button_width, urlbar_height, hwnd_,
|
||||||
|
reinterpret_cast<HMENU>(IDC_NAV_FORWARD), hInstance, 0);
|
||||||
|
CHECK(forward_hwnd_);
|
||||||
|
x_offset += button_width;
|
||||||
|
|
||||||
|
reload_hwnd_ =
|
||||||
|
CreateWindow(L"BUTTON", L"Reload",
|
||||||
|
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
||||||
|
x_offset, 0, button_width, urlbar_height, hwnd_,
|
||||||
|
reinterpret_cast<HMENU>(IDC_NAV_RELOAD), hInstance, 0);
|
||||||
|
CHECK(reload_hwnd_);
|
||||||
|
x_offset += button_width;
|
||||||
|
|
||||||
|
stop_hwnd_ = CreateWindow(
|
||||||
|
L"BUTTON", L"Stop", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED,
|
||||||
|
x_offset, 0, button_width, urlbar_height, hwnd_,
|
||||||
|
reinterpret_cast<HMENU>(IDC_NAV_STOP), hInstance, 0);
|
||||||
|
CHECK(stop_hwnd_);
|
||||||
|
x_offset += button_width;
|
||||||
|
|
||||||
|
edit_hwnd_ = CreateWindow(L"EDIT", 0,
|
||||||
|
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT |
|
||||||
|
ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_DISABLED,
|
||||||
|
x_offset, 0, rect.right - button_width * 4,
|
||||||
|
urlbar_height, hwnd_, 0, hInstance, 0);
|
||||||
|
CHECK(edit_hwnd_);
|
||||||
|
|
||||||
|
// Override the edit control's window procedure.
|
||||||
|
edit_wndproc_old_ = SetWndProcPtr(edit_hwnd_, EditWndProc);
|
||||||
|
|
||||||
|
// Associate |this| with the edit window.
|
||||||
|
SetUserDataPtr(edit_hwnd_, this);
|
||||||
|
|
||||||
|
rect.top += urlbar_height;
|
||||||
|
|
||||||
|
if (!with_osr_) {
|
||||||
|
// Remove the menu items that are only used with OSR.
|
||||||
|
HMENU hMenu = ::GetMenu(hwnd_);
|
||||||
|
if (hMenu) {
|
||||||
|
HMENU hTestMenu = ::GetSubMenu(hMenu, 2);
|
||||||
|
if (hTestMenu) {
|
||||||
|
::RemoveMenu(hTestMenu, ID_TESTS_OSR_FPS, MF_BYCOMMAND);
|
||||||
|
::RemoveMenu(hTestMenu, ID_TESTS_OSR_DSF, MF_BYCOMMAND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No controls so also remove the default menu.
|
||||||
|
::SetMenu(hwnd_, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int device_scale_factor = GetWindowScaleFactor(hwnd_);
|
||||||
|
|
||||||
|
if (with_osr_) {
|
||||||
|
browser_window_->SetDeviceScaleFactor(device_scale_factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_popup_) {
|
||||||
|
// Create the browser window.
|
||||||
|
CefRect cef_rect(rect.left, rect.top, rect.right - rect.left,
|
||||||
|
rect.bottom - rect.top);
|
||||||
|
cef_rect = client::DeviceToLogical(cef_rect, device_scale_factor);
|
||||||
|
browser_window_->CreateBrowser(hwnd_, cef_rect, browser_settings_,
|
||||||
|
delegate_->GetRequestContext(this));
|
||||||
|
} else {
|
||||||
|
// With popups we already have a browser window. Parent the browser window
|
||||||
|
// to the root window and show it in the correct location.
|
||||||
|
browser_window_->ShowPopup(hwnd_, rect.left, rect.top,
|
||||||
|
rect.right - rect.left, rect.bottom - rect.top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool RootWindowWin::OnClose() {
|
bool RootWindowWin::OnClose() {
|
||||||
if (browser_window_ && !browser_window_->IsClosing()) {
|
if (browser_window_ && !browser_window_->IsClosing()) {
|
||||||
CefRefPtr<CefBrowser> browser = GetBrowser();
|
CefRefPtr<CefBrowser> browser = GetBrowser();
|
||||||
|
@ -915,9 +1043,9 @@ void RootWindowWin::OnAutoResize(const CefSize& new_size) {
|
||||||
if (new_width < 200)
|
if (new_width < 200)
|
||||||
new_width = 200;
|
new_width = 200;
|
||||||
|
|
||||||
RECT rect = {
|
const int device_scale_factor = GetWindowScaleFactor(hwnd_);
|
||||||
0, 0, LogicalToDevice(new_width, client::GetDeviceScaleFactor()),
|
RECT rect = {0, 0, LogicalToDevice(new_width, device_scale_factor),
|
||||||
LogicalToDevice(new_size.height, client::GetDeviceScaleFactor())};
|
LogicalToDevice(new_size.height, device_scale_factor)};
|
||||||
DWORD style = GetWindowLong(hwnd_, GWL_STYLE);
|
DWORD style = GetWindowLong(hwnd_, GWL_STYLE);
|
||||||
DWORD ex_style = GetWindowLong(hwnd_, GWL_EXSTYLE);
|
DWORD ex_style = GetWindowLong(hwnd_, GWL_EXSTYLE);
|
||||||
bool has_menu = !(style & WS_CHILD) && (GetMenu(hwnd_) != NULL);
|
bool has_menu = !(style & WS_CHILD) && (GetMenu(hwnd_) != NULL);
|
||||||
|
|
|
@ -83,11 +83,14 @@ class RootWindowWin : public RootWindow, public BrowserWindow::Delegate {
|
||||||
void OnActivate(bool active);
|
void OnActivate(bool active);
|
||||||
void OnSize(bool minimized);
|
void OnSize(bool minimized);
|
||||||
void OnMove();
|
void OnMove();
|
||||||
|
void OnDpiChanged(WPARAM wParam, LPARAM lParam);
|
||||||
bool OnEraseBkgnd();
|
bool OnEraseBkgnd();
|
||||||
bool OnCommand(UINT id);
|
bool OnCommand(UINT id);
|
||||||
void OnFind();
|
void OnFind();
|
||||||
void OnFindEvent();
|
void OnFindEvent();
|
||||||
void OnAbout();
|
void OnAbout();
|
||||||
|
void OnNCCreate(LPCREATESTRUCT lpCreateStruct);
|
||||||
|
void OnCreate(LPCREATESTRUCT lpCreateStruct);
|
||||||
bool OnClose();
|
bool OnClose();
|
||||||
void OnDestroyed();
|
void OnDestroyed();
|
||||||
|
|
||||||
|
@ -114,6 +117,7 @@ class RootWindowWin : public RootWindow, public BrowserWindow::Delegate {
|
||||||
bool is_popup_;
|
bool is_popup_;
|
||||||
RECT start_rect_;
|
RECT start_rect_;
|
||||||
scoped_ptr<BrowserWindow> browser_window_;
|
scoped_ptr<BrowserWindow> browser_window_;
|
||||||
|
CefBrowserSettings browser_settings_;
|
||||||
bool initialized_;
|
bool initialized_;
|
||||||
|
|
||||||
// Main window.
|
// Main window.
|
||||||
|
@ -124,6 +128,7 @@ class RootWindowWin : public RootWindow, public BrowserWindow::Delegate {
|
||||||
|
|
||||||
// Font for buttons and text fields.
|
// Font for buttons and text fields.
|
||||||
HFONT font_;
|
HFONT font_;
|
||||||
|
int font_height_;
|
||||||
|
|
||||||
// Buttons.
|
// Buttons.
|
||||||
HWND back_hwnd_;
|
HWND back_hwnd_;
|
||||||
|
@ -150,6 +155,8 @@ class RootWindowWin : public RootWindow, public BrowserWindow::Delegate {
|
||||||
bool window_destroyed_;
|
bool window_destroyed_;
|
||||||
bool browser_destroyed_;
|
bool browser_destroyed_;
|
||||||
|
|
||||||
|
bool called_enable_non_client_dpi_scaling_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(RootWindowWin);
|
DISALLOW_COPY_AND_ASSIGN(RootWindowWin);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,13 @@ int DeviceToLogical(int value, float device_scale_factor) {
|
||||||
return static_cast<int>(std::floor(scaled_val));
|
return static_cast<int>(std::floor(scaled_val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CefRect DeviceToLogical(const CefRect& value, float device_scale_factor) {
|
||||||
|
return CefRect(DeviceToLogical(value.x, device_scale_factor),
|
||||||
|
DeviceToLogical(value.y, device_scale_factor),
|
||||||
|
DeviceToLogical(value.width, device_scale_factor),
|
||||||
|
DeviceToLogical(value.height, device_scale_factor));
|
||||||
|
}
|
||||||
|
|
||||||
void DeviceToLogical(CefMouseEvent& value, float device_scale_factor) {
|
void DeviceToLogical(CefMouseEvent& value, float device_scale_factor) {
|
||||||
value.x = DeviceToLogical(value.x, device_scale_factor);
|
value.x = DeviceToLogical(value.x, device_scale_factor);
|
||||||
value.y = DeviceToLogical(value.y, device_scale_factor);
|
value.y = DeviceToLogical(value.y, device_scale_factor);
|
||||||
|
|
|
@ -16,6 +16,7 @@ CefRect LogicalToDevice(const CefRect& value, float device_scale_factor);
|
||||||
|
|
||||||
// Convert |value| from device coordinates to logical coordinates.
|
// Convert |value| from device coordinates to logical coordinates.
|
||||||
int DeviceToLogical(int value, float device_scale_factor);
|
int DeviceToLogical(int value, float device_scale_factor);
|
||||||
|
CefRect DeviceToLogical(const CefRect& value, float device_scale_factor);
|
||||||
void DeviceToLogical(CefMouseEvent& value, float device_scale_factor);
|
void DeviceToLogical(CefMouseEvent& value, float device_scale_factor);
|
||||||
|
|
||||||
} // namespace client
|
} // namespace client
|
||||||
|
|
Loading…
Reference in New Issue