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

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

Issue 1976923004: Reduce the size of the fullscreen window on activation loss only if the window being activated is … (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix include order Created 4 years, 7 months 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 | « ui/views/win/hwnd_message_handler.h ('k') | 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 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 // Records the HWND visibility at the time of creation. 293 // Records the HWND visibility at the time of creation.
294 bool was_visible_; 294 bool was_visible_;
295 // A flag indicating that the unlock operation was canceled. 295 // A flag indicating that the unlock operation was canceled.
296 bool cancel_unlock_; 296 bool cancel_unlock_;
297 // If true, perform the redraw lock regardless of Aero state. 297 // If true, perform the redraw lock regardless of Aero state.
298 bool force_; 298 bool force_;
299 299
300 DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock); 300 DISALLOW_COPY_AND_ASSIGN(ScopedRedrawLock);
301 }; 301 };
302 302
303
304 // static HWNDMessageHandler member initialization.
305 HWNDMessageHandler::FullscreenWindowMonitorMap*
sky 2016/05/13 23:32:36 Use LazyInstance, it's less error prone than what
ananta 2016/05/16 19:56:43 Done.
306 HWNDMessageHandler::fullscreen_monitor_map_ = nullptr;
307 int32_t HWNDMessageHandler::instance_count_ = 0;
308
303 //////////////////////////////////////////////////////////////////////////////// 309 ////////////////////////////////////////////////////////////////////////////////
304 // HWNDMessageHandler, public: 310 // HWNDMessageHandler, public:
305 311
306 long HWNDMessageHandler::last_touch_message_time_ = 0; 312 long HWNDMessageHandler::last_touch_message_time_ = 0;
307 313
308 HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate) 314 HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate)
309 : msg_handled_(FALSE), 315 : msg_handled_(FALSE),
310 delegate_(delegate), 316 delegate_(delegate),
311 fullscreen_handler_(new FullscreenHandler), 317 fullscreen_handler_(new FullscreenHandler),
312 waiting_for_close_now_(false), 318 waiting_for_close_now_(false),
(...skipping 18 matching lines...) Expand all
331 left_button_down_on_caption_(false), 337 left_button_down_on_caption_(false),
332 background_fullscreen_hack_(false), 338 background_fullscreen_hack_(false),
333 autohide_factory_(this), 339 autohide_factory_(this),
334 weak_factory_(this) {} 340 weak_factory_(this) {}
335 341
336 HWNDMessageHandler::~HWNDMessageHandler() { 342 HWNDMessageHandler::~HWNDMessageHandler() {
337 delegate_ = NULL; 343 delegate_ = NULL;
338 // Prevent calls back into this class via WNDPROC now that we've been 344 // Prevent calls back into this class via WNDPROC now that we've been
339 // destroyed. 345 // destroyed.
340 ClearUserData(); 346 ClearUserData();
347 instance_count_--;
348 if (!instance_count_) {
349 delete fullscreen_monitor_map_;
350 }
341 } 351 }
342 352
343 void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) { 353 void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) {
344 TRACE_EVENT0("views", "HWNDMessageHandler::Init"); 354 TRACE_EVENT0("views", "HWNDMessageHandler::Init");
345 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, 355 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_,
346 &last_work_area_); 356 &last_work_area_);
347 357
348 // Create the window. 358 // Create the window.
349 WindowImpl::Init(parent, bounds); 359 WindowImpl::Init(parent, bounds);
350 // TODO(ananta) 360 // TODO(ananta)
(...skipping 25 matching lines...) Expand all
376 386
377 // Direct Manipulation is enabled on Windows 10+. The CreateInstance function 387 // Direct Manipulation is enabled on Windows 10+. The CreateInstance function
378 // returns NULL if Direct Manipulation is not available. 388 // returns NULL if Direct Manipulation is not available.
379 direct_manipulation_helper_ = 389 direct_manipulation_helper_ =
380 gfx::win::DirectManipulationHelper::CreateInstance(); 390 gfx::win::DirectManipulationHelper::CreateInstance();
381 if (direct_manipulation_helper_) 391 if (direct_manipulation_helper_)
382 direct_manipulation_helper_->Initialize(hwnd()); 392 direct_manipulation_helper_->Initialize(hwnd());
383 393
384 // Disable pen flicks (http://crbug.com/506977) 394 // Disable pen flicks (http://crbug.com/506977)
385 base::win::DisableFlicks(hwnd()); 395 base::win::DisableFlicks(hwnd());
396
397 instance_count_++;
398 if (!fullscreen_monitor_map_)
399 fullscreen_monitor_map_ = new FullscreenWindowMonitorMap;
386 } 400 }
387 401
388 void HWNDMessageHandler::InitModalType(ui::ModalType modal_type) { 402 void HWNDMessageHandler::InitModalType(ui::ModalType modal_type) {
389 if (modal_type == ui::MODAL_TYPE_NONE) 403 if (modal_type == ui::MODAL_TYPE_NONE)
390 return; 404 return;
391 // We implement modality by crawling up the hierarchy of windows starting 405 // We implement modality by crawling up the hierarchy of windows starting
392 // at the owner, disabling all of them so that they don't receive input 406 // at the owner, disabling all of them so that they don't receive input
393 // messages. 407 // messages.
394 HWND start = ::GetWindow(hwnd(), GW_OWNER); 408 HWND start = ::GetWindow(hwnd(), GW_OWNER);
395 while (start) { 409 while (start) {
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
806 } 820 }
807 } 821 }
808 822
809 void HWNDMessageHandler::SetFullscreen(bool fullscreen) { 823 void HWNDMessageHandler::SetFullscreen(bool fullscreen) {
810 background_fullscreen_hack_ = false; 824 background_fullscreen_hack_ = false;
811 fullscreen_handler()->SetFullscreen(fullscreen); 825 fullscreen_handler()->SetFullscreen(fullscreen);
812 // If we are out of fullscreen and there was a pending DWM transition for the 826 // If we are out of fullscreen and there was a pending DWM transition for the
813 // window, then go ahead and do it now. 827 // window, then go ahead and do it now.
814 if (!fullscreen && dwm_transition_desired_) 828 if (!fullscreen && dwm_transition_desired_)
815 PerformDwmTransition(); 829 PerformDwmTransition();
830
831 // Add the fullscreen window to the fullscreen window map which is used to
832 // handle window activations.
833 HMONITOR monitor = MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY);
834 DCHECK(fullscreen_monitor_map_);
835 if (fullscreen) {
836 (*fullscreen_monitor_map_)[monitor] = hwnd();
837 } else {
838 fullscreen_monitor_map_->erase(fullscreen_monitor_map_->find(monitor));
839 }
816 } 840 }
817 841
818 void HWNDMessageHandler::SizeConstraintsChanged() { 842 void HWNDMessageHandler::SizeConstraintsChanged() {
819 LONG style = GetWindowLong(hwnd(), GWL_STYLE); 843 LONG style = GetWindowLong(hwnd(), GWL_STYLE);
820 // Ignore if this is not a standard window. 844 // Ignore if this is not a standard window.
821 if (style & (WS_POPUP | WS_CHILD)) 845 if (style & (WS_POPUP | WS_CHILD))
822 return; 846 return;
823 847
824 LONG exstyle = GetWindowLong(hwnd(), GWL_EXSTYLE); 848 LONG exstyle = GetWindowLong(hwnd(), GWL_EXSTYLE);
825 // Windows cannot have WS_THICKFRAME set if WS_EX_COMPOSITED is set. 849 // Windows cannot have WS_THICKFRAME set if WS_EX_COMPOSITED is set.
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 // If the window losing activation is a fullscreen window, we reduce the size 1038 // If the window losing activation is a fullscreen window, we reduce the size
1015 // of the window by 1px. i.e. Not fullscreen. This is to work around an 1039 // of the window by 1px. i.e. Not fullscreen. This is to work around an
1016 // apparent bug in the Windows taskbar where in it tracks fullscreen state on 1040 // apparent bug in the Windows taskbar where in it tracks fullscreen state on
1017 // a per thread basis. This causes it not be a topmost window when any 1041 // a per thread basis. This causes it not be a topmost window when any
1018 // maximized window on a thread which has a fullscreen window is active. This 1042 // maximized window on a thread which has a fullscreen window is active. This
1019 // affects the way these windows interact with the taskbar, they obscure it 1043 // affects the way these windows interact with the taskbar, they obscure it
1020 // when maximized, autohide does not work correctly, etc. 1044 // when maximized, autohide does not work correctly, etc.
1021 // By reducing the size of the fullscreen window by 1px, we ensure that the 1045 // By reducing the size of the fullscreen window by 1px, we ensure that the
1022 // taskbar no longer treats the window and in turn the thread as a fullscreen 1046 // taskbar no longer treats the window and in turn the thread as a fullscreen
1023 // thread. This in turn ensures that maximized windows on the same thread 1047 // thread. This in turn ensures that maximized windows on the same thread
1024 /// don't obscure the taskbar, etc. 1048 // don't obscure the taskbar, etc.
1049 // Please note that this taskbar behavior only occurs if the window becoming
1050 // active is on the same monitor as the fullscreen window.
1025 if (!active) { 1051 if (!active) {
1026 if (IsFullscreen() && ::IsWindow(window_gaining_or_losing_activation)) { 1052 if (IsFullscreen() && ::IsWindow(window_gaining_or_losing_activation)) {
1027 // Reduce the bounds of the window by 1px to ensure that Windows does 1053 HMONITOR active_window_monitor = MonitorFromWindow(
1028 // not treat this like a fullscreen window. 1054 window_gaining_or_losing_activation, MONITOR_DEFAULTTOPRIMARY);
1029 MONITORINFO monitor_info = {sizeof(monitor_info)}; 1055 HMONITOR fullscreen_window_monitor = MonitorFromWindow(
1030 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), 1056 hwnd(), MONITOR_DEFAULTTOPRIMARY);
1031 &monitor_info); 1057
1032 gfx::Rect shrunk_rect(monitor_info.rcMonitor); 1058 if (active_window_monitor == fullscreen_window_monitor)
1033 shrunk_rect.set_height(shrunk_rect.height() - 1); 1059 OnBackgroundFullscreen(0, 0, 0);
1034 background_fullscreen_hack_ = true;
1035 SetBoundsInternal(shrunk_rect, false);
1036 } 1060 }
1037 } else if (background_fullscreen_hack_) { 1061 } else if (background_fullscreen_hack_) {
1038 // Restore the bounds of the window to fullscreen. 1062 // Restore the bounds of the window to fullscreen.
1039 DCHECK(IsFullscreen()); 1063 DCHECK(IsFullscreen());
1040 MONITORINFO monitor_info = {sizeof(monitor_info)}; 1064 MONITORINFO monitor_info = {sizeof(monitor_info)};
1041 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), 1065 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY),
1042 &monitor_info); 1066 &monitor_info);
1043 SetBoundsInternal(gfx::Rect(monitor_info.rcMonitor), false); 1067 SetBoundsInternal(gfx::Rect(monitor_info.rcMonitor), false);
1044 background_fullscreen_hack_ = false; 1068 background_fullscreen_hack_ = false;
1069 } else {
1070 // If the window becoming active has a fullscreen window on the same
1071 // monitor then we need to reduce the size of the fullscreen window by
1072 // 1 px. Please refer to the comments above for the reasoning behind
1073 // this.
1074 CheckAndHandleBackgroundFullscreenOnMonitor(
1075 window_gaining_or_losing_activation);
1045 } 1076 }
1046 } 1077 }
1047 1078
1048 void HWNDMessageHandler::RestoreEnabledIfNecessary() { 1079 void HWNDMessageHandler::RestoreEnabledIfNecessary() {
1049 if (delegate_->IsModal() && !restored_enabled_) { 1080 if (delegate_->IsModal() && !restored_enabled_) {
1050 restored_enabled_ = true; 1081 restored_enabled_ = true;
1051 // If we were run modally, we need to undo the disabled-ness we inflicted on 1082 // If we were run modally, we need to undo the disabled-ness we inflicted on
1052 // the owner's parent hierarchy. 1083 // the owner's parent hierarchy.
1053 HWND start = ::GetWindow(hwnd(), GW_OWNER); 1084 HWND start = ::GetWindow(hwnd(), GW_OWNER);
1054 while (start) { 1085 while (start) {
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 base::Bind(&HWNDMessageHandler::OnSessionChange, 1361 base::Bind(&HWNDMessageHandler::OnSessionChange,
1331 base::Unretained(this)))); 1362 base::Unretained(this))));
1332 1363
1333 // TODO(beng): move more of NWW::OnCreate here. 1364 // TODO(beng): move more of NWW::OnCreate here.
1334 return 0; 1365 return 0;
1335 } 1366 }
1336 1367
1337 void HWNDMessageHandler::OnDestroy() { 1368 void HWNDMessageHandler::OnDestroy() {
1338 windows_session_change_observer_.reset(nullptr); 1369 windows_session_change_observer_.reset(nullptr);
1339 delegate_->HandleDestroying(); 1370 delegate_->HandleDestroying();
1371 // If the window going away is a fullscreen window then remove its references
1372 // from the full screen window map.
1373 FullscreenWindowMonitorMap::iterator index;
1374 DCHECK(fullscreen_monitor_map_);
1375 for (index = fullscreen_monitor_map_->begin();
1376 index != fullscreen_monitor_map_->end();
1377 index++) {
1378 if (index->second == hwnd()) {
1379 fullscreen_monitor_map_->erase(index);
1380 break;
1381 }
1382 }
1340 } 1383 }
1341 1384
1342 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, 1385 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel,
1343 const gfx::Size& screen_size) { 1386 const gfx::Size& screen_size) {
1344 delegate_->HandleDisplayChange(); 1387 delegate_->HandleDisplayChange();
1345 // Force a WM_NCCALCSIZE to occur to ensure that we handle auto hide 1388 // Force a WM_NCCALCSIZE to occur to ensure that we handle auto hide
1346 // taskbars correctly. 1389 // taskbars correctly.
1347 SendFrameChanged(); 1390 SendFrameChanged();
1348 } 1391 }
1349 1392
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1390 void HWNDMessageHandler::OnExitSizeMove() { 1433 void HWNDMessageHandler::OnExitSizeMove() {
1391 delegate_->HandleEndWMSizeMove(); 1434 delegate_->HandleEndWMSizeMove();
1392 SetMsgHandled(FALSE); 1435 SetMsgHandled(FALSE);
1393 // Please refer to the notes in the OnSize function for information about 1436 // Please refer to the notes in the OnSize function for information about
1394 // the scrolling hack. 1437 // the scrolling hack.
1395 // We hide the Windows scrollbar in the OnEnterSizeMove function. We need 1438 // We hide the Windows scrollbar in the OnEnterSizeMove function. We need
1396 // to add the scroll styles back to ensure that scrolling works in legacy 1439 // to add the scroll styles back to ensure that scrolling works in legacy
1397 // trackpoint drivers. 1440 // trackpoint drivers.
1398 if (in_size_loop_ && needs_scroll_styles_) 1441 if (in_size_loop_ && needs_scroll_styles_)
1399 AddScrollStylesToWindow(hwnd()); 1442 AddScrollStylesToWindow(hwnd());
1443 // If the window was moved to a monitor which has a fullscreen window active,
1444 // we need to reduce the size of the fullscreen window by 1px.
1445 CheckAndHandleBackgroundFullscreenOnMonitor(hwnd());
1400 } 1446 }
1401 1447
1402 void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { 1448 void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) {
1403 gfx::Size min_window_size; 1449 gfx::Size min_window_size;
1404 gfx::Size max_window_size; 1450 gfx::Size max_window_size;
1405 delegate_->GetMinMaxSize(&min_window_size, &max_window_size); 1451 delegate_->GetMinMaxSize(&min_window_size, &max_window_size);
1406 min_window_size = delegate_->DIPToScreenSize(min_window_size); 1452 min_window_size = delegate_->DIPToScreenSize(min_window_size);
1407 max_window_size = delegate_->DIPToScreenSize(max_window_size); 1453 max_window_size = delegate_->DIPToScreenSize(max_window_size);
1408 1454
1409 1455
(...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after
2337 if (direct_manipulation_helper_) 2383 if (direct_manipulation_helper_)
2338 direct_manipulation_helper_->Deactivate(hwnd()); 2384 direct_manipulation_helper_->Deactivate(hwnd());
2339 } 2385 }
2340 if (sent_window_size_changing_) { 2386 if (sent_window_size_changing_) {
2341 sent_window_size_changing_ = false; 2387 sent_window_size_changing_ = false;
2342 delegate_->HandleWindowSizeChanged(); 2388 delegate_->HandleWindowSizeChanged();
2343 } 2389 }
2344 SetMsgHandled(FALSE); 2390 SetMsgHandled(FALSE);
2345 } 2391 }
2346 2392
2393 LRESULT HWNDMessageHandler::OnBackgroundFullscreen(UINT message,
2394 WPARAM w_param,
2395 LPARAM l_param) {
2396 // Reduce the bounds of the window by 1px to ensure that Windows does
2397 // not treat this like a fullscreen window.
2398 MONITORINFO monitor_info = { sizeof(monitor_info) };
2399 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY),
2400 &monitor_info);
2401 gfx::Rect shrunk_rect(monitor_info.rcMonitor);
2402 shrunk_rect.set_height(shrunk_rect.height() - 1);
2403 background_fullscreen_hack_ = true;
2404 SetBoundsInternal(shrunk_rect, false);
2405 return 0;
2406 }
2407
2347 void HWNDMessageHandler::OnSessionChange(WPARAM status_code) { 2408 void HWNDMessageHandler::OnSessionChange(WPARAM status_code) {
2348 // Direct3D presents are ignored while the screen is locked, so force the 2409 // Direct3D presents are ignored while the screen is locked, so force the
2349 // window to be redrawn on unlock. 2410 // window to be redrawn on unlock.
2350 if (status_code == WTS_SESSION_UNLOCK) 2411 if (status_code == WTS_SESSION_UNLOCK)
2351 ForceRedrawWindow(10); 2412 ForceRedrawWindow(10);
2352 } 2413 }
2353 2414
2354 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) { 2415 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) {
2355 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); 2416 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr());
2356 for (size_t i = 0; i < touch_events.size() && ref; ++i) 2417 for (size_t i = 0; i < touch_events.size() && ref; ++i)
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
2676 if (old_size == bounds_in_pixels.size() && force_size_changed && 2737 if (old_size == bounds_in_pixels.size() && force_size_changed &&
2677 !background_fullscreen_hack_) { 2738 !background_fullscreen_hack_) {
2678 delegate_->HandleClientSizeChanged(GetClientAreaBounds().size()); 2739 delegate_->HandleClientSizeChanged(GetClientAreaBounds().size());
2679 ResetWindowRegion(false, true); 2740 ResetWindowRegion(false, true);
2680 } 2741 }
2681 2742
2682 if (direct_manipulation_helper_) 2743 if (direct_manipulation_helper_)
2683 direct_manipulation_helper_->SetBounds(bounds_in_pixels); 2744 direct_manipulation_helper_->SetBounds(bounds_in_pixels);
2684 } 2745 }
2685 2746
2747 void HWNDMessageHandler::CheckAndHandleBackgroundFullscreenOnMonitor(
2748 HWND window) {
2749 HMONITOR monitor = MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY);
2750
2751 DCHECK(fullscreen_monitor_map_);
2752 FullscreenWindowMonitorMap::iterator index = fullscreen_monitor_map_->find(
2753 monitor);
2754 if (index != fullscreen_monitor_map_->end() && window != index->second) {
2755 PostMessage(index->second,
sky 2016/05/13 23:32:36 Why bother with the PostMessage? Why not call the
ananta 2016/05/16 19:56:43 The fullscreen window could be a different instanc
ananta 2016/05/16 21:35:42 yeah. done.
2756 WM_CUSTOM_MESSAGE_HANDLE_BACKGROUND_FULLSCREEN,
2757 0,
2758 0);
2759 }
2760 }
2686 2761
2687 } // namespace views 2762 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/win/hwnd_message_handler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698