From d518b6abc887787ac169270cbcf71c4626e2caaf Mon Sep 17 00:00:00 2001 From: Samuel Maddock Date: Tue, 18 May 2021 21:34:40 -0400 Subject: [PATCH] fix: window bounds not scaled from screen coordinates (#29162) --- shell/browser/native_window_views.cc | 28 ++++++++++++++---------- shell/browser/native_window_views.h | 4 ++++ shell/browser/native_window_views_win.cc | 18 ++++++++------- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/shell/browser/native_window_views.cc b/shell/browser/native_window_views.cc index 79eb4d20752d..1a855d106792 100644 --- a/shell/browser/native_window_views.cc +++ b/shell/browser/native_window_views.cc @@ -82,6 +82,22 @@ namespace electron { +#if defined(OS_WIN) + +// Similar to the ones in display::win::ScreenWin, but with rounded values +// These help to avoid problems that arise from unresizable windows where the +// original ceil()-ed values can cause calculation errors, since converting +// both ways goes through a ceil() call. Related issue: #15816 +gfx::Rect ScreenToDIPRect(HWND hwnd, const gfx::Rect& pixel_bounds) { + float scale_factor = display::win::ScreenWin::GetScaleFactorForHWND(hwnd); + gfx::Rect dip_rect = ScaleToRoundedRect(pixel_bounds, 1.0f / scale_factor); + dip_rect.set_origin( + display::win::ScreenWin::ScreenToDIPRect(hwnd, pixel_bounds).origin()); + return dip_rect; +} + +#endif + namespace { #if defined(OS_WIN) @@ -96,18 +112,6 @@ void FlipWindowStyle(HWND handle, bool on, DWORD flag) { ::SetWindowLong(handle, GWL_STYLE, style); } -// Similar to the ones in display::win::ScreenWin, but with rounded values -// These help to avoid problems that arise from unresizable windows where the -// original ceil()-ed values can cause calculation errors, since converting -// both ways goes through a ceil() call. Related issue: #15816 -gfx::Rect ScreenToDIPRect(HWND hwnd, const gfx::Rect& pixel_bounds) { - float scale_factor = display::win::ScreenWin::GetScaleFactorForHWND(hwnd); - gfx::Rect dip_rect = ScaleToRoundedRect(pixel_bounds, 1.0f / scale_factor); - dip_rect.set_origin( - display::win::ScreenWin::ScreenToDIPRect(hwnd, pixel_bounds).origin()); - return dip_rect; -} - gfx::Rect DIPToScreenRect(HWND hwnd, const gfx::Rect& pixel_bounds) { float scale_factor = display::win::ScreenWin::GetScaleFactorForHWND(hwnd); gfx::Rect screen_rect = ScaleToRoundedRect(pixel_bounds, scale_factor); diff --git a/shell/browser/native_window_views.h b/shell/browser/native_window_views.h index 9f62ac1ba20b..52ca6f024531 100644 --- a/shell/browser/native_window_views.h +++ b/shell/browser/native_window_views.h @@ -35,6 +35,10 @@ class WindowStateWatcher; class EventDisabler; #endif +#if defined(OS_WIN) +gfx::Rect ScreenToDIPRect(HWND hwnd, const gfx::Rect& pixel_bounds); +#endif + class NativeWindowViews : public NativeWindow, public views::WidgetObserver, public ui::EventHandler { diff --git a/shell/browser/native_window_views_win.cc b/shell/browser/native_window_views_win.cc index 0ff2b7ad14af..13e369c716c2 100644 --- a/shell/browser/native_window_views_win.cc +++ b/shell/browser/native_window_views_win.cc @@ -260,11 +260,12 @@ bool NativeWindowViews::PreHandleMSG(UINT message, case WM_SIZING: { is_resizing_ = true; bool prevent_default = false; - NotifyWindowWillResize(gfx::Rect(*reinterpret_cast(l_param)), - &prevent_default); + gfx::Rect bounds = gfx::Rect(*reinterpret_cast(l_param)); + HWND hwnd = GetAcceleratedWidget(); + gfx::Rect dpi_bounds = ScreenToDIPRect(hwnd, bounds); + NotifyWindowWillResize(dpi_bounds, &prevent_default); if (prevent_default) { - ::GetWindowRect(GetAcceleratedWidget(), - reinterpret_cast(l_param)); + ::GetWindowRect(hwnd, reinterpret_cast(l_param)); return true; // Tells Windows that the Sizing is handled. } return false; @@ -288,11 +289,12 @@ bool NativeWindowViews::PreHandleMSG(UINT message, case WM_MOVING: { is_moving_ = true; bool prevent_default = false; - NotifyWindowWillMove(gfx::Rect(*reinterpret_cast(l_param)), - &prevent_default); + gfx::Rect bounds = gfx::Rect(*reinterpret_cast(l_param)); + HWND hwnd = GetAcceleratedWidget(); + gfx::Rect dpi_bounds = ScreenToDIPRect(hwnd, bounds); + NotifyWindowWillMove(dpi_bounds, &prevent_default); if (!movable_ || prevent_default) { - ::GetWindowRect(GetAcceleratedWidget(), - reinterpret_cast(l_param)); + ::GetWindowRect(hwnd, reinterpret_cast(l_param)); return true; // Tells Windows that the Move is handled. If not true, // frameless windows can be moved using // -webkit-app-region: drag elements.