зеркало из https://github.com/electron/electron.git
fix: improve single-pixel resize handling on Windows (#44700)
Co-authored-by: Niklas Wenzel <dev@nikwen.de>
This commit is contained in:
Родитель
2cea2282eb
Коммит
4b3d1caae4
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -1544,6 +1544,16 @@ describe('BrowserWindow module', () => {
|
|||
await expect(once(w, 'resized')).to.eventually.be.fulfilled();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not emits the resize event for move-only changes', async () => {
|
||||
const [x, y] = w.getPosition();
|
||||
|
||||
w.once('resize', () => {
|
||||
expect.fail('resize event should not be emitted');
|
||||
});
|
||||
|
||||
w.setBounds({ x: x + 10, y: y + 10 });
|
||||
});
|
||||
});
|
||||
|
||||
describe('BrowserWindow.setSize(width, height)', () => {
|
||||
|
@ -1557,6 +1567,17 @@ describe('BrowserWindow module', () => {
|
|||
expectBoundsEqual(w.getSize(), size);
|
||||
});
|
||||
|
||||
it('emits the resize event for single-pixel size changes', async () => {
|
||||
const [width, height] = w.getSize();
|
||||
const size = [width + 1, height - 1];
|
||||
|
||||
const resized = once(w, 'resize');
|
||||
w.setSize(size[0], size[1]);
|
||||
await resized;
|
||||
|
||||
expectBoundsEqual(w.getSize(), size);
|
||||
});
|
||||
|
||||
ifit(process.platform === 'darwin')('on macOS', () => {
|
||||
it('emits \'resized\' event after animating', async () => {
|
||||
const size = [300, 400];
|
||||
|
|
Загрузка…
Ссылка в новой задаче