| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/views/win/hwnd_message_handler.h" | 5 #include "ui/views/win/hwnd_message_handler.h" |
| 6 | 6 |
| 7 #include <dwmapi.h> | 7 #include <dwmapi.h> |
| 8 #include <oleacc.h> | 8 #include <oleacc.h> |
| 9 #include <shellapi.h> | 9 #include <shellapi.h> |
| 10 #include <tchar.h> | 10 #include <tchar.h> |
| (...skipping 2209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2220 // change our Z-order, or activate us, we should probably let it go through. | 2220 // change our Z-order, or activate us, we should probably let it go through. |
| 2221 if (!(window_pos->flags & ((IsVisible() ? SWP_HIDEWINDOW : SWP_SHOWWINDOW) | | 2221 if (!(window_pos->flags & ((IsVisible() ? SWP_HIDEWINDOW : SWP_SHOWWINDOW) | |
| 2222 SWP_FRAMECHANGED)) && | 2222 SWP_FRAMECHANGED)) && |
| 2223 (window_pos->flags & (SWP_NOZORDER | SWP_NOACTIVATE))) { | 2223 (window_pos->flags & (SWP_NOZORDER | SWP_NOACTIVATE))) { |
| 2224 // Just sizing/moving the window; ignore. | 2224 // Just sizing/moving the window; ignore. |
| 2225 window_pos->flags |= SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW; | 2225 window_pos->flags |= SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW; |
| 2226 window_pos->flags &= ~(SWP_SHOWWINDOW | SWP_HIDEWINDOW); | 2226 window_pos->flags &= ~(SWP_SHOWWINDOW | SWP_HIDEWINDOW); |
| 2227 } | 2227 } |
| 2228 } else if (!GetParent(hwnd())) { | 2228 } else if (!GetParent(hwnd())) { |
| 2229 RECT window_rect; | 2229 RECT window_rect; |
| 2230 const bool have_new_window_rect = |
| 2231 !(window_pos->flags & SWP_NOMOVE) && !(window_pos->flags & SWP_NOSIZE); |
| 2232 if (have_new_window_rect) { |
| 2233 // We should use new window rect for detecting monitor and it's |
| 2234 // parameters, if it is available. If we use |GetWindowRect()| instead, |
| 2235 // we can break our same monitor detection logic (see |same_monitor| |
| 2236 // below) and consequently Windows "Move to other monitor" shortcuts |
| 2237 // (Win+Shift+Arrows). See crbug.com/656001. |
| 2238 window_rect.left = window_pos->x; |
| 2239 window_rect.top = window_pos->y; |
| 2240 window_rect.right = window_pos->x + window_pos->cx - 1; |
| 2241 window_rect.bottom = window_pos->y + window_pos->cy - 1; |
| 2242 } |
| 2243 |
| 2230 HMONITOR monitor; | 2244 HMONITOR monitor; |
| 2231 gfx::Rect monitor_rect, work_area; | 2245 gfx::Rect monitor_rect, work_area; |
| 2232 if (GetWindowRect(hwnd(), &window_rect) && | 2246 if ((have_new_window_rect || GetWindowRect(hwnd(), &window_rect)) && |
| 2233 GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { | 2247 GetMonitorAndRects(window_rect, &monitor, &monitor_rect, &work_area)) { |
| 2234 bool work_area_changed = (monitor_rect == last_monitor_rect_) && | 2248 bool work_area_changed = (monitor_rect == last_monitor_rect_) && |
| 2235 (work_area != last_work_area_); | 2249 (work_area != last_work_area_); |
| 2250 const bool same_monitor = monitor && (monitor == last_monitor_); |
| 2251 |
| 2252 gfx::Rect expected_maximized_bounds = work_area; |
| 2253 if (IsMaximized()) { |
| 2254 // Windows automatically adds a standard width border to all sides when |
| 2255 // window is maximized. We should take this into account. |
| 2256 gfx::Insets client_area_insets; |
| 2257 if (GetClientAreaInsets(&client_area_insets)) |
| 2258 expected_maximized_bounds.Inset(client_area_insets.Scale(-1)); |
| 2259 } |
| 2260 // Sometimes Windows incorrectly changes bounds of maximized windows after |
| 2261 // attaching or detaching additional displays. In this case user can see |
| 2262 // non-client area of the window (that should be hidden in normal case). |
| 2263 // We should restore window position if problem occurs. |
| 2264 const bool incorrect_maximized_bounds = |
| 2265 IsMaximized() && have_new_window_rect && |
| 2266 (expected_maximized_bounds.x() != window_pos->x || |
| 2267 expected_maximized_bounds.y() != window_pos->y || |
| 2268 expected_maximized_bounds.width() != window_pos->cx || |
| 2269 expected_maximized_bounds.height() != window_pos->cy); |
| 2270 |
| 2236 // If the size of a background fullscreen window changes again, then we | 2271 // If the size of a background fullscreen window changes again, then we |
| 2237 // should reset the |background_fullscreen_hack_| flag. | 2272 // should reset the |background_fullscreen_hack_| flag. |
| 2238 if (background_fullscreen_hack_ && | 2273 if (background_fullscreen_hack_ && |
| 2239 (!(window_pos->flags & SWP_NOSIZE) && | 2274 (!(window_pos->flags & SWP_NOSIZE) && |
| 2240 (monitor_rect.height() - window_pos->cy != 1))) { | 2275 (monitor_rect.height() - window_pos->cy != 1))) { |
| 2241 background_fullscreen_hack_ = false; | 2276 background_fullscreen_hack_ = false; |
| 2242 } | 2277 } |
| 2243 if (monitor && (monitor == last_monitor_) && | 2278 const bool fullscreen_without_hack = |
| 2244 ((IsFullscreen() && !background_fullscreen_hack_) || | 2279 IsFullscreen() && !background_fullscreen_hack_; |
| 2280 |
| 2281 if (same_monitor && |
| 2282 (incorrect_maximized_bounds || fullscreen_without_hack || |
| 2245 work_area_changed)) { | 2283 work_area_changed)) { |
| 2246 // A rect for the monitor we're on changed. Normally Windows notifies | 2284 // A rect for the monitor we're on changed. Normally Windows notifies |
| 2247 // us about this (and thus we're reaching here due to the SetWindowPos() | 2285 // us about this (and thus we're reaching here due to the SetWindowPos() |
| 2248 // call in OnSettingChange() above), but with some software (e.g. | 2286 // call in OnSettingChange() above), but with some software (e.g. |
| 2249 // nVidia's nView desktop manager) the work area can change asynchronous | 2287 // nVidia's nView desktop manager) the work area can change asynchronous |
| 2250 // to any notification, and we're just sent a SetWindowPos() call with a | 2288 // to any notification, and we're just sent a SetWindowPos() call with a |
| 2251 // new (frequently incorrect) position/size. In either case, the best | 2289 // new (frequently incorrect) position/size. In either case, the best |
| 2252 // response is to throw away the existing position/size information in | 2290 // response is to throw away the existing position/size information in |
| 2253 // |window_pos| and recalculate it based on the new work rect. | 2291 // |window_pos| and recalculate it based on the new work rect. |
| 2254 gfx::Rect new_window_rect; | 2292 gfx::Rect new_window_rect; |
| 2255 if (IsFullscreen()) { | 2293 if (IsFullscreen()) { |
| 2256 new_window_rect = monitor_rect; | 2294 new_window_rect = monitor_rect; |
| 2257 } else if (IsMaximized()) { | 2295 } else if (IsMaximized()) { |
| 2258 new_window_rect = work_area; | 2296 new_window_rect = expected_maximized_bounds; |
| 2259 int border_thickness = GetSystemMetrics(SM_CXSIZEFRAME); | |
| 2260 new_window_rect.Inset(-border_thickness, -border_thickness); | |
| 2261 } else { | 2297 } else { |
| 2262 new_window_rect = gfx::Rect(window_rect); | 2298 new_window_rect = gfx::Rect(window_rect); |
| 2263 new_window_rect.AdjustToFit(work_area); | 2299 new_window_rect.AdjustToFit(work_area); |
| 2264 } | 2300 } |
| 2265 window_pos->x = new_window_rect.x(); | 2301 window_pos->x = new_window_rect.x(); |
| 2266 window_pos->y = new_window_rect.y(); | 2302 window_pos->y = new_window_rect.y(); |
| 2267 window_pos->cx = new_window_rect.width(); | 2303 window_pos->cx = new_window_rect.width(); |
| 2268 window_pos->cy = new_window_rect.height(); | 2304 window_pos->cy = new_window_rect.height(); |
| 2269 // WARNING! Don't set SWP_FRAMECHANGED here, it breaks moving the child | 2305 // WARNING! Don't set SWP_FRAMECHANGED here, it breaks moving the child |
| 2270 // HWNDs for some reason. | 2306 // HWNDs for some reason. |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2713 MONITORINFO monitor_info = {sizeof(monitor_info)}; | 2749 MONITORINFO monitor_info = {sizeof(monitor_info)}; |
| 2714 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), | 2750 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), |
| 2715 &monitor_info); | 2751 &monitor_info); |
| 2716 gfx::Rect shrunk_rect(monitor_info.rcMonitor); | 2752 gfx::Rect shrunk_rect(monitor_info.rcMonitor); |
| 2717 shrunk_rect.set_height(shrunk_rect.height() - 1); | 2753 shrunk_rect.set_height(shrunk_rect.height() - 1); |
| 2718 background_fullscreen_hack_ = true; | 2754 background_fullscreen_hack_ = true; |
| 2719 SetBoundsInternal(shrunk_rect, false); | 2755 SetBoundsInternal(shrunk_rect, false); |
| 2720 } | 2756 } |
| 2721 | 2757 |
| 2722 } // namespace views | 2758 } // namespace views |
| OLD | NEW |