Merge pull request #8047 from electron/fix-incorrect-window-size
Fix incorrect window size after restore on Windows
This commit is contained in:
commit
e356168c9a
4 changed files with 90 additions and 13 deletions
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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_;
|
||||
|
||||
|
|
|
@ -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,20 +168,35 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
|
|||
NotifyWindowMinimize();
|
||||
break;
|
||||
case SIZE_RESTORED:
|
||||
switch (last_window_state_) {
|
||||
case ui::SHOW_STATE_MAXIMIZED:
|
||||
last_window_state_ = ui::SHOW_STATE_NORMAL;
|
||||
NotifyWindowUnmaximize();
|
||||
break;
|
||||
case ui::SHOW_STATE_MINIMIZED:
|
||||
if (IsFullscreen()) {
|
||||
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
|
||||
NotifyWindowEnterFullScreen();
|
||||
} else {
|
||||
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;
|
||||
NotifyWindowRestore();
|
||||
}
|
||||
break;
|
||||
|
||||
// Don't force out last known bounds onto the window as Windows
|
||||
// actually gets these correct
|
||||
|
||||
NotifyWindowUnmaximize();
|
||||
break;
|
||||
case ui::SHOW_STATE_MINIMIZED:
|
||||
if (IsFullscreen()) {
|
||||
last_window_state_ = ui::SHOW_STATE_FULLSCREEN;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue