Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: ui/views/win/hwnd_message_handler.cc

Issue 2488993002: Restore maximized window position after detaching display. (Closed)
Patch Set: New changes Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698