fix: improve single-pixel resize handling on Windows (#44722)

* fix: improve single-pixel resize handling

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* Update spec/api-browser-window-spec.ts

Co-authored-by: Niklas Wenzel <dev@nikwen.de>

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

* Update shell/browser/native_window_views.cc

Co-authored-by: Niklas Wenzel <dev@nikwen.de>

Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>

---------

Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
This commit is contained in:
trop[bot] 2024-11-19 10:53:04 -05:00 committed by GitHub
parent 3764c4d0b3
commit ca8e1e4af6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 37 additions and 6 deletions

View file

@ -1661,18 +1661,28 @@ void NativeWindowViews::OnWidgetBoundsChanged(views::Widget* changed_widget,
if (changed_widget != widget())
return;
// |GetWindowBoundsInScreen| has a ~1 pixel margin of error, so if we check
// existing bounds directly against the new bounds without accounting for that
// we'll have constant false positives when the window is moving but the user
// hasn't changed its size at all.
auto areWithinOnePixel = [](gfx::Size old_size, gfx::Size new_size) -> bool {
#if BUILDFLAG(IS_WIN)
// OnWidgetBoundsChanged is emitted both when a window is moved and when a
// window is resized. If the window is moving, then
// WidgetObserver::OnWidgetBoundsChanged is being called from
// Widget::OnNativeWidgetMove() and not Widget::OnNativeWidgetSizeChanged.
// |GetWindowBoundsInScreen| has a ~1 pixel margin
// of error because it converts from floats to integers between calculations,
// so if we check existing bounds directly against the new bounds without
// accounting for that we'll have constant false positives when the window is
// moving but the user hasn't changed its size at all.
auto isWithinOnePixel = [](gfx::Size old_size, gfx::Size new_size) -> bool {
return base::IsApproximatelyEqual(old_size.width(), new_size.width(), 1) &&
base::IsApproximatelyEqual(old_size.height(), new_size.height(), 1);
};
if (is_moving_ && isWithinOnePixel(widget_size_, bounds.size()))
return;
#endif
// We use |GetBounds| to account for minimized windows on Windows.
const auto new_bounds = GetBounds();
if (!areWithinOnePixel(widget_size_, new_bounds.size())) {
if (widget_size_ != new_bounds.size()) {
NotifyWindowResize();
widget_size_ = new_bounds.size();
}