Merge pull request #8047 from electron/fix-incorrect-window-size

Fix incorrect window size after restore on Windows
This commit is contained in:
Kevin Sawicki 2016-11-22 14:01:50 -08:00 committed by GitHub
commit e356168c9a
4 changed files with 90 additions and 13 deletions

View file

@ -327,6 +327,7 @@ NativeWindowViews::NativeWindowViews(
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
else
last_window_state_ = ui::SHOW_STATE_NORMAL;
last_normal_bounds_ = GetBounds();
#endif
}

View file

@ -211,6 +211,23 @@ class NativeWindowViews : public NativeWindow,
ui::WindowShowState last_window_state_;
// There's an issue with restore on Windows, that sometimes causes the Window
// to receive the wrong size (#2498). To circumvent that, we keep tabs on the
// size of the window while in the normal state (not maximized, minimized or
// fullscreen), so we restore it correctly.
gfx::Rect last_normal_bounds_;
gfx::Rect last_normal_bounds_before_move_;
// last_normal_bounds_ may or may not require update on WM_MOVE. When a
// window is maximized, it is moved (WM_MOVE) to maximum size first and then
// sized (WM_SIZE). In this case, last_normal_bounds_ should not update. We
// keep last_normal_bounds_candidate_ as a candidate which will become valid
// last_normal_bounds_ if the moves are consecutive with no WM_SIZE event in
// between.
gfx::Rect last_normal_bounds_candidate_;
bool consecutive_moves_;
// In charge of running taskbar related APIs.
TaskbarHost taskbar_host_;

View file

@ -127,6 +127,10 @@ bool NativeWindowViews::PreHandleMSG(
case WM_SIZE: {
// Handle window state change.
HandleSizeEvent(w_param, l_param);
consecutive_moves_ = false;
last_normal_bounds_before_move_ = last_normal_bounds_;
return false;
}
case WM_MOVING: {
@ -134,6 +138,15 @@ bool NativeWindowViews::PreHandleMSG(
::GetWindowRect(GetAcceleratedWidget(), (LPRECT)l_param);
return false;
}
case WM_MOVE: {
if (last_window_state_ == ui::SHOW_STATE_NORMAL) {
if (consecutive_moves_)
last_normal_bounds_ = last_normal_bounds_candidate_;
last_normal_bounds_candidate_ = GetBounds();
consecutive_moves_ = true;
}
return false;
}
default:
return false;
}
@ -145,6 +158,9 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
switch (w_param) {
case SIZE_MAXIMIZED:
last_window_state_ = ui::SHOW_STATE_MAXIMIZED;
if (consecutive_moves_) {
last_normal_bounds_ = last_normal_bounds_before_move_;
}
NotifyWindowMaximize();
break;
case SIZE_MINIMIZED:
@ -152,9 +168,18 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
NotifyWindowMinimize();
break;
case SIZE_RESTORED:
if (last_window_state_ == ui::SHOW_STATE_NORMAL) {
// Window was resized so we save it's new size.
last_normal_bounds_ = GetBounds();
last_normal_bounds_before_move_ = last_normal_bounds_;
} else {
switch (last_window_state_) {
case ui::SHOW_STATE_MAXIMIZED:
last_window_state_ = ui::SHOW_STATE_NORMAL;
// Don't force out last known bounds onto the window as Windows
// actually gets these correct
NotifyWindowUnmaximize();
break;
case ui::SHOW_STATE_MINIMIZED:
@ -163,10 +188,16 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
NotifyWindowEnterFullScreen();
} else {
last_window_state_ = ui::SHOW_STATE_NORMAL;
// When the window is restored we resize it to the previous known
// normal size.
SetBounds(last_normal_bounds_, false);
NotifyWindowRestore();
}
break;
}
}
break;
}
}

View file

@ -1320,6 +1320,34 @@ describe('browser-window module', function () {
})
})
describe('BrowserWindow.restore()', function () {
it('should restore the previous window size', function () {
if (w != null) w.destroy()
w = new BrowserWindow({
minWidth: 800,
width: 800
})
const initialSize = w.getSize()
w.minimize()
w.restore()
assertBoundsEqual(w.getSize(), initialSize)
})
})
describe('BrowserWindow.unmaximize()', function () {
it('should restore the previous window position', function () {
if (w != null) w.destroy()
w = new BrowserWindow()
const initialPosition = w.getPosition()
w.maximize()
w.unmaximize()
assertBoundsEqual(w.getPosition(), initialPosition)
})
})
describe('parent window', function () {
let c = null