| Index: ui/views/win/hwnd_message_handler.cc
|
| diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
|
| index 020d0a1f9e06a46b1e80c081bb01d338c22a004e..6f80d3e568e2ca1dc1471d563356f850ec2bdc39 100644
|
| --- a/ui/views/win/hwnd_message_handler.cc
|
| +++ b/ui/views/win/hwnd_message_handler.cc
|
| @@ -2227,12 +2227,47 @@ void HWNDMessageHandler::OnWindowPosChanging(WINDOWPOS* window_pos) {
|
| }
|
| } else if (!GetParent(hwnd())) {
|
| RECT window_rect;
|
| + const bool have_new_window_rect =
|
| + !(window_pos->flags & SWP_NOMOVE) && !(window_pos->flags & SWP_NOSIZE);
|
| + if (have_new_window_rect) {
|
| + // We should use new window rect for detecting monitor and it's
|
| + // parameters, if it is available. If we use |GetWindowRect()| instead,
|
| + // we can break our same monitor detection logic (see |same_monitor|
|
| + // below) and consequently Windows "Move to other monitor" shortcuts
|
| + // (Win+Shift+Arrows). See crbug.com/656001.
|
| + window_rect.left = window_pos->x;
|
| + window_rect.top = window_pos->y;
|
| + window_rect.right = window_pos->x + window_pos->cx - 1;
|
| + window_rect.bottom = window_pos->y + window_pos->cy - 1;
|
| + }
|
| +
|
| HMONITOR monitor;
|
| gfx::Rect monitor_rect, work_area;
|
| - if (GetWindowRect(hwnd(), &window_rect) &&
|
| + if ((have_new_window_rect || GetWindowRect(hwnd(), &window_rect)) &&
|
| GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) {
|
| bool work_area_changed = (monitor_rect == last_monitor_rect_) &&
|
| (work_area != last_work_area_);
|
| + const bool same_monitor = monitor && (monitor == last_monitor_);
|
| +
|
| + gfx::Rect expected_maximized_bounds = work_area;
|
| + if (IsMaximized()) {
|
| + // Windows automatically adds a standard width border to all sides when
|
| + // window is maximized. We should take this into account.
|
| + gfx::Insets client_area_insets;
|
| + if (GetClientAreaInsets(&client_area_insets))
|
| + expected_maximized_bounds.Inset(client_area_insets.Scale(-1));
|
| + }
|
| + // Sometimes Windows incorrectly changes bounds of maximized windows after
|
| + // attaching or detaching additional displays. In this case user can see
|
| + // non-client area of the window (that should be hidden in normal case).
|
| + // We should restore window position if problem occurs.
|
| + const bool incorrect_maximized_bounds =
|
| + IsMaximized() && have_new_window_rect &&
|
| + (expected_maximized_bounds.x() != window_pos->x ||
|
| + expected_maximized_bounds.y() != window_pos->y ||
|
| + expected_maximized_bounds.width() != window_pos->cx ||
|
| + expected_maximized_bounds.height() != window_pos->cy);
|
| +
|
| // If the size of a background fullscreen window changes again, then we
|
| // should reset the |background_fullscreen_hack_| flag.
|
| if (background_fullscreen_hack_ &&
|
| @@ -2240,8 +2275,11 @@ void HWNDMessageHandler::OnWindowPosChanging(WINDOWPOS* window_pos) {
|
| (monitor_rect.height() - window_pos->cy != 1))) {
|
| background_fullscreen_hack_ = false;
|
| }
|
| - if (monitor && (monitor == last_monitor_) &&
|
| - ((IsFullscreen() && !background_fullscreen_hack_) ||
|
| + const bool fullscreen_without_hack =
|
| + IsFullscreen() && !background_fullscreen_hack_;
|
| +
|
| + if (same_monitor &&
|
| + (incorrect_maximized_bounds || fullscreen_without_hack ||
|
| work_area_changed)) {
|
| // A rect for the monitor we're on changed. Normally Windows notifies
|
| // us about this (and thus we're reaching here due to the SetWindowPos()
|
| @@ -2255,9 +2293,7 @@ void HWNDMessageHandler::OnWindowPosChanging(WINDOWPOS* window_pos) {
|
| if (IsFullscreen()) {
|
| new_window_rect = monitor_rect;
|
| } else if (IsMaximized()) {
|
| - new_window_rect = work_area;
|
| - int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME);
|
| - new_window_rect.Inset(-border_thickness, -border_thickness);
|
| + new_window_rect = expected_maximized_bounds;
|
| } else {
|
| new_window_rect = gfx::Rect(window_rect);
|
| new_window_rect.AdjustToFit(work_area);
|
|
|