diff --git a/tests/cefclient/browser/osr_window_win.cc b/tests/cefclient/browser/osr_window_win.cc index 11ed5fd47..7b9571014 100644 --- a/tests/cefclient/browser/osr_window_win.cc +++ b/tests/cefclient/browser/osr_window_win.cc @@ -443,6 +443,8 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) { LONG currentTime = 0; bool cancelPreviousClick = false; + const float device_scale_factor = GetDeviceScaleFactor(); + if (message == WM_LBUTTONDOWN || message == WM_RBUTTONDOWN || message == WM_MBUTTONDOWN || message == WM_MOUSEMOVE || message == WM_MOUSELEAVE) { @@ -496,6 +498,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) { mouse_event.y = y; last_mouse_down_on_view_ = !IsOverPopupWidget(x, y); ApplyPopupOffset(mouse_event.x, mouse_event.y); + DeviceToLogical(mouse_event, device_scale_factor); mouse_event.modifiers = GetCefMouseModifiers(wParam); browser_host->SendMouseClickEvent(mouse_event, btnType, false, last_click_count_); @@ -529,6 +532,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) { break; } ApplyPopupOffset(mouse_event.x, mouse_event.y); + DeviceToLogical(mouse_event, device_scale_factor); mouse_event.modifiers = GetCefMouseModifiers(wParam); browser_host->SendMouseClickEvent(mouse_event, btnType, true, last_click_count_); @@ -566,6 +570,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) { mouse_event.x = x; mouse_event.y = y; ApplyPopupOffset(mouse_event.x, mouse_event.y); + DeviceToLogical(mouse_event, device_scale_factor); mouse_event.modifiers = GetCefMouseModifiers(wParam); browser_host->SendMouseMoveEvent(mouse_event, false); } @@ -593,6 +598,7 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) { CefMouseEvent mouse_event; mouse_event.x = p.x; mouse_event.y = p.y; + DeviceToLogical(mouse_event, device_scale_factor); mouse_event.modifiers = GetCefMouseModifiers(wParam); browser_host->SendMouseMoveEvent(mouse_event, true); } @@ -612,8 +618,8 @@ void OsrWindowWin::OnMouseEvent(UINT message, WPARAM wParam, LPARAM lParam) { mouse_event.x = screen_point.x; mouse_event.y = screen_point.y; ApplyPopupOffset(mouse_event.x, mouse_event.y); + DeviceToLogical(mouse_event, device_scale_factor); mouse_event.modifiers = GetCefMouseModifiers(wParam); - browser_host->SendMouseWheelEvent(mouse_event, IsKeyDown(VK_SHIFT) ? delta : 0, !IsKeyDown(VK_SHIFT) ? delta : 0); @@ -731,16 +737,6 @@ void OsrWindowWin::OnBeforeClose(CefRefPtr browser) { bool OsrWindowWin::GetRootScreenRect(CefRefPtr browser, CefRect& rect) { CEF_REQUIRE_UI_THREAD(); - - RECT window_rect = {0}; - HWND root_window = GetAncestor(hwnd_, GA_ROOT); - if (::GetWindowRect(root_window, &window_rect)) { - rect = CefRect(window_rect.left, - window_rect.top, - window_rect.right - window_rect.left, - window_rect.bottom - window_rect.top); - return true; - } return false; } @@ -748,9 +744,13 @@ bool OsrWindowWin::GetViewRect(CefRefPtr browser, CefRect& rect) { CEF_REQUIRE_UI_THREAD(); - rect.x = rect.y = 0; - rect.width = client_rect_.right - client_rect_.left; - rect.height = client_rect_.bottom - client_rect_.top; + const float device_scale_factor = GetDeviceScaleFactor(); + + rect.x = rect.y = 0; + rect.width = DeviceToLogical(client_rect_.right - client_rect_.left, + device_scale_factor); + rect.height = DeviceToLogical(client_rect_.bottom - client_rect_.top, + device_scale_factor); return true; } @@ -764,8 +764,13 @@ bool OsrWindowWin::GetScreenPoint(CefRefPtr browser, if (!::IsWindow(hwnd_)) return false; + const float device_scale_factor = GetDeviceScaleFactor(); + // Convert the point from view coordinates to actual screen coordinates. - POINT screen_pt = {viewX, viewY}; + POINT screen_pt = { + LogicalToDevice(viewX, device_scale_factor), + LogicalToDevice(viewY, device_scale_factor) + }; ClientToScreen(hwnd_, &screen_pt); screenX = screen_pt.x; screenY = screen_pt.y; @@ -776,7 +781,19 @@ bool OsrWindowWin::GetScreenInfo(CefRefPtr browser, CefScreenInfo& screen_info) { CEF_REQUIRE_UI_THREAD(); - return false; + if (!::IsWindow(hwnd_)) + return false; + + CefRect view_rect; + GetViewRect(browser, view_rect); + + screen_info.device_scale_factor = GetDeviceScaleFactor(); + + // The screen info rectangles are used by the renderer to create and position + // popups. Keep popups inside the view rectangle. + screen_info.rect = view_rect; + screen_info.available_rect = view_rect; + return true; } void OsrWindowWin::OnPopupShow(CefRefPtr browser, @@ -794,7 +811,7 @@ void OsrWindowWin::OnPopupSize(CefRefPtr browser, const CefRect& rect) { CEF_REQUIRE_UI_THREAD(); - renderer_.OnPopupSize(browser, rect); + renderer_.OnPopupSize(browser, LogicalToDevice(rect, GetDeviceScaleFactor())); } void OsrWindowWin::OnPaint(CefRefPtr browser, @@ -848,6 +865,7 @@ bool OsrWindowWin::StartDragging( #if defined(CEF_USE_ATL) if (!drop_target_) return false; + current_drag_op_ = DRAG_OPERATION_NONE; CefBrowserHost::DragOperationsMask result = drop_target_->StartDragging(browser, drag_data, allowed_ops, x, y); @@ -855,7 +873,13 @@ bool OsrWindowWin::StartDragging( POINT pt = {}; GetCursorPos(&pt); ScreenToClient(hwnd_, &pt); - browser->GetHost()->DragSourceEndedAt(pt.x, pt.y, result); + + const float device_scale_factor = GetDeviceScaleFactor(); + + browser->GetHost()->DragSourceEndedAt( + DeviceToLogical(pt.x, device_scale_factor), + DeviceToLogical(pt.y, device_scale_factor), + result); browser->GetHost()->DragSourceSystemDragEnded(); return true; #else @@ -881,6 +905,7 @@ OsrWindowWin::OnDragEnter(CefRefPtr drag_data, CefMouseEvent ev, CefBrowserHost::DragOperationsMask effect) { if (browser_) { + DeviceToLogical(ev, GetDeviceScaleFactor()); browser_->GetHost()->DragTargetDragEnter(drag_data, ev, effect); browser_->GetHost()->DragTargetDragOver(ev, effect); } @@ -890,8 +915,10 @@ OsrWindowWin::OnDragEnter(CefRefPtr drag_data, CefBrowserHost::DragOperationsMask OsrWindowWin::OnDragOver(CefMouseEvent ev, CefBrowserHost::DragOperationsMask effect) { - if (browser_) + if (browser_) { + DeviceToLogical(ev, GetDeviceScaleFactor()); browser_->GetHost()->DragTargetDragOver(ev, effect); + } return current_drag_op_; } @@ -904,6 +931,7 @@ CefBrowserHost::DragOperationsMask OsrWindowWin::OnDrop(CefMouseEvent ev, CefBrowserHost::DragOperationsMask effect) { if (browser_) { + DeviceToLogical(ev, GetDeviceScaleFactor()); browser_->GetHost()->DragTargetDragOver(ev, effect); browser_->GetHost()->DragTargetDrop(ev); } diff --git a/tests/cefclient/browser/root_window_win.cc b/tests/cefclient/browser/root_window_win.cc index 188ee87e4..0591d6e90 100644 --- a/tests/cefclient/browser/root_window_win.cc +++ b/tests/cefclient/browser/root_window_win.cc @@ -43,6 +43,30 @@ INT_PTR CALLBACK AboutWndProc(HWND hDlg, UINT message, return FALSE; } +int GetButtonWidth() { + static int button_width = BUTTON_WIDTH; + static bool initialized = false; + + if (!initialized) { + button_width = LogicalToDevice(BUTTON_WIDTH, GetDeviceScaleFactor()); + initialized = true; + } + + return button_width; +} + +int GetURLBarHeight() { + static int urlbar_height = URLBAR_HEIGHT; + static bool initialized = false; + + if (!initialized) { + urlbar_height = LogicalToDevice(URLBAR_HEIGHT, GetDeviceScaleFactor()); + initialized = true; + } + + return urlbar_height; +} + } // namespace RootWindowWin::RootWindowWin() @@ -54,6 +78,7 @@ RootWindowWin::RootWindowWin() initialized_(false), hwnd_(NULL), draggable_region_(NULL), + font_(NULL), back_hwnd_(NULL), forward_hwnd_(NULL), reload_hwnd_(NULL), @@ -78,6 +103,7 @@ RootWindowWin::~RootWindowWin() { REQUIRE_MAIN_THREAD(); ::DeleteObject(draggable_region_); + ::DeleteObject(font_); // The window and browser should already have been destroyed. DCHECK(window_destroyed_); @@ -254,7 +280,7 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) { RECT window_rect = start_rect_; ::AdjustWindowRectEx(&window_rect, dwStyle, with_controls_, 0); if (with_controls_) - window_rect.bottom += URLBAR_HEIGHT; + window_rect.bottom += GetURLBarHeight(); x = start_rect_.left; y = start_rect_.top; @@ -279,44 +305,61 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) { // Create the child controls. int x = 0; + static int button_width = GetButtonWidth(); + static int urlbar_height = GetURLBarHeight(); + static int font_height = LogicalToDevice(14, 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, 0, BUTTON_WIDTH, URLBAR_HEIGHT, + x, 0, button_width, urlbar_height, hwnd_, reinterpret_cast(IDC_NAV_BACK), hInstance, 0); CHECK(back_hwnd_); - x += BUTTON_WIDTH; + SendMessage(back_hwnd_, WM_SETFONT, reinterpret_cast(font_), TRUE); + x += button_width; forward_hwnd_ = CreateWindow( L"BUTTON", L"Forward", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED, - x, 0, BUTTON_WIDTH, URLBAR_HEIGHT, + x, 0, button_width, urlbar_height, hwnd_, reinterpret_cast(IDC_NAV_FORWARD), hInstance, 0); CHECK(forward_hwnd_); - x += BUTTON_WIDTH; + SendMessage(forward_hwnd_, WM_SETFONT, + reinterpret_cast(font_), TRUE); + x += button_width; reload_hwnd_ = CreateWindow( L"BUTTON", L"Reload", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON| WS_DISABLED, - x, 0, BUTTON_WIDTH, URLBAR_HEIGHT, + x, 0, button_width, urlbar_height, hwnd_, reinterpret_cast(IDC_NAV_RELOAD), hInstance, 0); CHECK(reload_hwnd_); - x += BUTTON_WIDTH; + SendMessage(reload_hwnd_, WM_SETFONT, + reinterpret_cast(font_), TRUE); + x += button_width; stop_hwnd_ = CreateWindow( L"BUTTON", L"Stop", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_DISABLED, - x, 0, BUTTON_WIDTH, URLBAR_HEIGHT, + x, 0, button_width, urlbar_height, hwnd_, reinterpret_cast(IDC_NAV_STOP), hInstance, 0); CHECK(stop_hwnd_); - x += BUTTON_WIDTH; + SendMessage(stop_hwnd_, WM_SETFONT, reinterpret_cast(font_), TRUE); + x += button_width; edit_hwnd_ = CreateWindow( L"EDIT", 0, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_LEFT | ES_AUTOVSCROLL | ES_AUTOHSCROLL| WS_DISABLED, - x, 0, rect.right - BUTTON_WIDTH * 4, URLBAR_HEIGHT, + x, 0, rect.right - button_width * 4, urlbar_height, hwnd_, 0, hInstance, 0); + SendMessage(edit_hwnd_, WM_SETFONT, reinterpret_cast(font_), TRUE); CHECK(edit_hwnd_); // Override the edit control's window procedure. @@ -325,7 +368,7 @@ void RootWindowWin::CreateRootWindow(const CefBrowserSettings& settings) { // Associate |this| with the edit window. SetUserDataPtr(edit_hwnd_, this); - rect.top += URLBAR_HEIGHT; + rect.top += urlbar_height; if (!with_osr_) { // Remove the menu items that are only used with OSR. @@ -573,23 +616,26 @@ void RootWindowWin::OnSize(bool minimized) { GetClientRect(hwnd_, &rect); if (with_controls_) { - // Resize the window and address bar to match the new frame size. - rect.top += URLBAR_HEIGHT; + static int button_width = GetButtonWidth(); + static int urlbar_height = GetURLBarHeight(); - int urloffset = rect.left + BUTTON_WIDTH * 4; + // Resize the window and address bar to match the new frame size. + rect.top += urlbar_height; + + int urloffset = rect.left + button_width * 4; if (browser_window_) { HWND browser_hwnd = browser_window_->GetWindowHandle(); HDWP hdwp = BeginDeferWindowPos(1); hdwp = DeferWindowPos(hdwp, edit_hwnd_, NULL, urloffset, - 0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER); + 0, rect.right - urloffset, urlbar_height, SWP_NOZORDER); hdwp = DeferWindowPos(hdwp, browser_hwnd, NULL, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER); EndDeferWindowPos(hdwp); } else { SetWindowPos(edit_hwnd_, NULL, urloffset, - 0, rect.right - urloffset, URLBAR_HEIGHT, SWP_NOZORDER); + 0, rect.right - urloffset, urlbar_height, SWP_NOZORDER); } } else if (browser_window_) { // Size the browser window to the whole client area. diff --git a/tests/cefclient/browser/root_window_win.h b/tests/cefclient/browser/root_window_win.h index 725708bc7..7bf114344 100644 --- a/tests/cefclient/browser/root_window_win.h +++ b/tests/cefclient/browser/root_window_win.h @@ -112,6 +112,9 @@ class RootWindowWin : public RootWindow, // Draggable region. HRGN draggable_region_; + // Font for buttons and text fields. + HFONT font_; + // Buttons. HWND back_hwnd_; HWND forward_hwnd_; diff --git a/tests/cefclient/browser/util_win.cc b/tests/cefclient/browser/util_win.cc index 8eb758d9f..fb14d4a1b 100644 --- a/tests/cefclient/browser/util_win.cc +++ b/tests/cefclient/browser/util_win.cc @@ -5,7 +5,6 @@ #include "cefclient/browser/util_win.h" #include "include/base/cef_logging.h" -#include "include/internal/cef_types.h" namespace client { @@ -140,4 +139,51 @@ bool IsKeyDown(WPARAM wparam) { return (GetKeyState(wparam) & 0x8000) != 0; } +float GetDeviceScaleFactor() { + static float scale_factor = 1.0; + static bool initialized = false; + + if (!initialized) { + // This value is safe to cache for the life time of the app since the user + // must logout to change the DPI setting. This value also applies to all + // screens. + HDC screen_dc = ::GetDC(NULL); + int dpi_x = GetDeviceCaps(screen_dc, LOGPIXELSX); + scale_factor = static_cast(dpi_x) / 96.0f; + ::ReleaseDC(NULL, screen_dc); + initialized = true; + } + + return scale_factor; +} + +int LogicalToDevice(int value, float device_scale_factor) { + float scaled_val = static_cast(value) * device_scale_factor; + return static_cast(std::floor(scaled_val)); +} + +CefRect LogicalToDevice(const CefRect& value, float device_scale_factor) { + return CefRect(LogicalToDevice(value.x, device_scale_factor), + LogicalToDevice(value.y, device_scale_factor), + LogicalToDevice(value.width, device_scale_factor), + LogicalToDevice(value.height, device_scale_factor)); +} + +int DeviceToLogical(int value, float device_scale_factor) { + float scaled_val = static_cast(value) / device_scale_factor; + return static_cast(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) { + value.x = DeviceToLogical(value.x, device_scale_factor); + value.y = DeviceToLogical(value.y, device_scale_factor); +} + } // namespace client diff --git a/tests/cefclient/browser/util_win.h b/tests/cefclient/browser/util_win.h index ad092def6..c7b37d387 100644 --- a/tests/cefclient/browser/util_win.h +++ b/tests/cefclient/browser/util_win.h @@ -9,6 +9,8 @@ #include #include +#include "include/internal/cef_types_wrappers.h" + namespace client { // Set the window's user data pointer. @@ -30,6 +32,19 @@ int GetCefMouseModifiers(WPARAM wparam); int GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam); bool IsKeyDown(WPARAM wparam); +// Returns the device scale factor. For example, 200% display scaling will +// return 2.0. +float GetDeviceScaleFactor(); + +// Convert |value| from logical coordinates to device coordinates. +int LogicalToDevice(int value, float device_scale_factor); +CefRect LogicalToDevice(const CefRect& value, float device_scale_factor); + +// Convert |value| from device coordinates to logical coordinates. +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); + } // namespace client #endif // CEF_TESTS_CEFCLIENT_BROWSER_UTIL_WIN_H_