Windows: cefclient: Improve high-dpi display (issue #1674).
- Add high-dpi support to the OSR example. - Apply DPI scaling to the buttons and URL bar.
This commit is contained in:
parent
9e0d84d94a
commit
41669141eb
|
@ -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<CefBrowser> browser) {
|
|||
bool OsrWindowWin::GetRootScreenRect(CefRefPtr<CefBrowser> 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<CefBrowser> 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<CefBrowser> 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<CefBrowser> 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<CefBrowser> browser,
|
||||
|
@ -794,7 +811,7 @@ void OsrWindowWin::OnPopupSize(CefRefPtr<CefBrowser> browser,
|
|||
const CefRect& rect) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
|
||||
renderer_.OnPopupSize(browser, rect);
|
||||
renderer_.OnPopupSize(browser, LogicalToDevice(rect, GetDeviceScaleFactor()));
|
||||
}
|
||||
|
||||
void OsrWindowWin::OnPaint(CefRefPtr<CefBrowser> 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<CefDragData> 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<CefDragData> 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);
|
||||
}
|
||||
|
|
|
@ -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<HMENU>(IDC_NAV_BACK), hInstance, 0);
|
||||
CHECK(back_hwnd_);
|
||||
x += BUTTON_WIDTH;
|
||||
SendMessage(back_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(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<HMENU>(IDC_NAV_FORWARD), hInstance, 0);
|
||||
CHECK(forward_hwnd_);
|
||||
x += BUTTON_WIDTH;
|
||||
SendMessage(forward_hwnd_, WM_SETFONT,
|
||||
reinterpret_cast<WPARAM>(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<HMENU>(IDC_NAV_RELOAD), hInstance, 0);
|
||||
CHECK(reload_hwnd_);
|
||||
x += BUTTON_WIDTH;
|
||||
SendMessage(reload_hwnd_, WM_SETFONT,
|
||||
reinterpret_cast<WPARAM>(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<HMENU>(IDC_NAV_STOP), hInstance, 0);
|
||||
CHECK(stop_hwnd_);
|
||||
x += BUTTON_WIDTH;
|
||||
SendMessage(stop_hwnd_, WM_SETFONT, reinterpret_cast<WPARAM>(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<WPARAM>(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.
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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<float>(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<float>(value) * device_scale_factor;
|
||||
return static_cast<int>(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<float>(value) / device_scale_factor;
|
||||
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) {
|
||||
value.x = DeviceToLogical(value.x, device_scale_factor);
|
||||
value.y = DeviceToLogical(value.y, device_scale_factor);
|
||||
}
|
||||
|
||||
} // namespace client
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
#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_
|
||||
|
|
Loading…
Reference in New Issue