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 <shellapi.h> | 8 #include <shellapi.h> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 lock_updates_count_(0), | 400 lock_updates_count_(0), |
401 ignore_window_pos_changes_(false), | 401 ignore_window_pos_changes_(false), |
402 last_monitor_(NULL), | 402 last_monitor_(NULL), |
403 use_layered_buffer_(false), | 403 use_layered_buffer_(false), |
404 layered_alpha_(255), | 404 layered_alpha_(255), |
405 waiting_for_redraw_layered_window_contents_(false), | 405 waiting_for_redraw_layered_window_contents_(false), |
406 is_first_nccalc_(true), | 406 is_first_nccalc_(true), |
407 menu_depth_(0), | 407 menu_depth_(0), |
408 autohide_factory_(this), | 408 autohide_factory_(this), |
409 id_generator_(0), | 409 id_generator_(0), |
410 scroll_styles_set_(false) { | 410 needs_scroll_styles_(false), |
| 411 in_size_move_loop_(false) { |
411 } | 412 } |
412 | 413 |
413 HWNDMessageHandler::~HWNDMessageHandler() { | 414 HWNDMessageHandler::~HWNDMessageHandler() { |
414 delegate_ = NULL; | 415 delegate_ = NULL; |
415 // Prevent calls back into this class via WNDPROC now that we've been | 416 // Prevent calls back into this class via WNDPROC now that we've been |
416 // destroyed. | 417 // destroyed. |
417 ClearUserData(); | 418 ClearUserData(); |
418 } | 419 } |
419 | 420 |
420 void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) { | 421 void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) { |
421 TRACE_EVENT0("views", "HWNDMessageHandler::Init"); | 422 TRACE_EVENT0("views", "HWNDMessageHandler::Init"); |
422 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, | 423 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, |
423 &last_work_area_); | 424 &last_work_area_); |
424 | 425 |
425 // Create the window. | 426 // Create the window. |
426 WindowImpl::Init(parent, bounds); | 427 WindowImpl::Init(parent, bounds); |
| 428 |
| 429 #if defined(USE_AURA) |
| 430 // Certain trackpad drivers on Windows have bugs where in they don't generate |
| 431 // WM_MOUSEWHEEL messages for the trackpoint and trackpad scrolling gestures |
| 432 // unless there is an entry for Chrome with the class name of the Window. |
| 433 // These drivers check if the window under the trackpoint has the WS_VSCROLL/ |
| 434 // WS_HSCROLL style and if yes they generate the legacy WM_VSCROLL/WM_HSCROLL |
| 435 // messages. We add these styles to ensure that trackpad/trackpoint scrolling |
| 436 // work. |
| 437 // TODO(ananta) |
| 438 // Look into moving the WS_VSCROLL and WS_HSCROLL style setting logic to the |
| 439 // CalculateWindowStylesFromInitParams function. Doing it there seems to |
| 440 // cause some interactive tests to fail. Investigation needed. |
| 441 if (IsTopLevelWindow(hwnd())) { |
| 442 long current_style = ::GetWindowLong(hwnd(), GWL_STYLE); |
| 443 if (!(current_style & WS_POPUP)) { |
| 444 AddScrollStylesToWindow(hwnd()); |
| 445 needs_scroll_styles_ = true; |
| 446 } |
| 447 } |
| 448 #endif |
427 } | 449 } |
428 | 450 |
429 void HWNDMessageHandler::InitModalType(ui::ModalType modal_type) { | 451 void HWNDMessageHandler::InitModalType(ui::ModalType modal_type) { |
430 if (modal_type == ui::MODAL_TYPE_NONE) | 452 if (modal_type == ui::MODAL_TYPE_NONE) |
431 return; | 453 return; |
432 // We implement modality by crawling up the hierarchy of windows starting | 454 // We implement modality by crawling up the hierarchy of windows starting |
433 // at the owner, disabling all of them so that they don't receive input | 455 // at the owner, disabling all of them so that they don't receive input |
434 // messages. | 456 // messages. |
435 HWND start = ::GetWindow(hwnd(), GW_OWNER); | 457 HWND start = ::GetWindow(hwnd(), GW_OWNER); |
436 while (start) { | 458 while (start) { |
(...skipping 920 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 #if !defined(USE_AURA) | 1379 #if !defined(USE_AURA) |
1358 // We need to add ourselves as a message loop observer so that we can repaint | 1380 // We need to add ourselves as a message loop observer so that we can repaint |
1359 // aggressively if the contents of our window become invalid. Unfortunately | 1381 // aggressively if the contents of our window become invalid. Unfortunately |
1360 // WM_PAINT messages are starved and we get flickery redrawing when resizing | 1382 // WM_PAINT messages are starved and we get flickery redrawing when resizing |
1361 // if we do not do this. | 1383 // if we do not do this. |
1362 base::MessageLoopForUI::current()->AddObserver(this); | 1384 base::MessageLoopForUI::current()->AddObserver(this); |
1363 #endif | 1385 #endif |
1364 | 1386 |
1365 delegate_->HandleCreate(); | 1387 delegate_->HandleCreate(); |
1366 | 1388 |
1367 #if defined(USE_AURA) | |
1368 // Certain trackpad drivers on Windows have bugs where in they don't generate | |
1369 // WM_MOUSEWHEEL messages for the trackpoint and trackpad scrolling gestures | |
1370 // unless there is an entry for Chrome with the class name of the Window. | |
1371 // These drivers check if the window under the trackpoint has the WS_VSCROLL/ | |
1372 // WS_HSCROLL style and if yes they generate the legacy WM_VSCROLL/WM_HSCROLL | |
1373 // messages. We add these styles to ensure that trackpad/trackpoint scrolling | |
1374 // work. | |
1375 // TODO(ananta) | |
1376 // Look into moving the WS_VSCROLL and WS_HSCROLL style setting logic to the | |
1377 // CalculateWindowStylesFromInitParams function. Doing it there seems to | |
1378 // cause some interactive tests to fail. Investigation needed. | |
1379 if (IsTopLevelWindow(hwnd())) { | |
1380 long current_style = ::GetWindowLong(hwnd(), GWL_STYLE); | |
1381 ::SetWindowLong(hwnd(), GWL_STYLE, | |
1382 current_style | WS_VSCROLL | WS_HSCROLL); | |
1383 scroll_styles_set_ = true; | |
1384 } | |
1385 #endif | |
1386 // TODO(beng): move more of NWW::OnCreate here. | 1389 // TODO(beng): move more of NWW::OnCreate here. |
1387 return 0; | 1390 return 0; |
1388 } | 1391 } |
1389 | 1392 |
1390 void HWNDMessageHandler::OnDestroy() { | 1393 void HWNDMessageHandler::OnDestroy() { |
1391 delegate_->HandleDestroying(); | 1394 delegate_->HandleDestroying(); |
1392 } | 1395 } |
1393 | 1396 |
1394 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, | 1397 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, |
1395 const CSize& screen_size) { | 1398 const CSize& screen_size) { |
(...skipping 11 matching lines...) Expand all Loading... |
1407 FrameTypeChanged(); | 1410 FrameTypeChanged(); |
1408 return 0; | 1411 return 0; |
1409 } | 1412 } |
1410 | 1413 |
1411 void HWNDMessageHandler::OnEnterMenuLoop(BOOL from_track_popup_menu) { | 1414 void HWNDMessageHandler::OnEnterMenuLoop(BOOL from_track_popup_menu) { |
1412 if (menu_depth_++ == 0) | 1415 if (menu_depth_++ == 0) |
1413 delegate_->HandleMenuLoop(true); | 1416 delegate_->HandleMenuLoop(true); |
1414 } | 1417 } |
1415 | 1418 |
1416 void HWNDMessageHandler::OnEnterSizeMove() { | 1419 void HWNDMessageHandler::OnEnterSizeMove() { |
| 1420 in_size_move_loop_ = true; |
| 1421 |
| 1422 // Please refer to the comments in the OnSize function about the scrollbar |
| 1423 // hack. |
| 1424 // Hide the Windows scrollbar if the scroll styles are present to ensure |
| 1425 // that a paint flicker does not occur while sizing. |
| 1426 if (needs_scroll_styles_) |
| 1427 ShowScrollBar(hwnd(), SB_BOTH, FALSE); |
| 1428 |
1417 delegate_->HandleBeginWMSizeMove(); | 1429 delegate_->HandleBeginWMSizeMove(); |
1418 SetMsgHandled(FALSE); | 1430 SetMsgHandled(FALSE); |
1419 } | 1431 } |
1420 | 1432 |
1421 LRESULT HWNDMessageHandler::OnEraseBkgnd(HDC dc) { | 1433 LRESULT HWNDMessageHandler::OnEraseBkgnd(HDC dc) { |
1422 // Needed to prevent resize flicker. | 1434 // Needed to prevent resize flicker. |
1423 return 1; | 1435 return 1; |
1424 } | 1436 } |
1425 | 1437 |
1426 void HWNDMessageHandler::OnExitMenuLoop(BOOL is_shortcut_menu) { | 1438 void HWNDMessageHandler::OnExitMenuLoop(BOOL is_shortcut_menu) { |
1427 if (--menu_depth_ == 0) | 1439 if (--menu_depth_ == 0) |
1428 delegate_->HandleMenuLoop(false); | 1440 delegate_->HandleMenuLoop(false); |
1429 DCHECK_GE(0, menu_depth_); | 1441 DCHECK_GE(0, menu_depth_); |
1430 } | 1442 } |
1431 | 1443 |
1432 void HWNDMessageHandler::OnExitSizeMove() { | 1444 void HWNDMessageHandler::OnExitSizeMove() { |
1433 delegate_->HandleEndWMSizeMove(); | 1445 delegate_->HandleEndWMSizeMove(); |
1434 SetMsgHandled(FALSE); | 1446 SetMsgHandled(FALSE); |
| 1447 in_size_move_loop_ = false; |
| 1448 // Please refer to the notes in the OnSize function for information about |
| 1449 // the scrolling hack. |
| 1450 // We hide the Windows scrollbar in the OnEnterSizeMove function. We need |
| 1451 // to add the scroll styles back to ensure that scrolling works in legacy |
| 1452 // trackpoint drivers. |
| 1453 if (needs_scroll_styles_) |
| 1454 AddScrollStylesToWindow(hwnd()); |
1435 } | 1455 } |
1436 | 1456 |
1437 void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { | 1457 void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { |
1438 gfx::Size min_window_size; | 1458 gfx::Size min_window_size; |
1439 gfx::Size max_window_size; | 1459 gfx::Size max_window_size; |
1440 delegate_->GetMinMaxSize(&min_window_size, &max_window_size); | 1460 delegate_->GetMinMaxSize(&min_window_size, &max_window_size); |
1441 | 1461 |
1442 // Add the native frame border size to the minimum and maximum size if the | 1462 // Add the native frame border size to the minimum and maximum size if the |
1443 // view reports its size as the client size. | 1463 // view reports its size as the client size. |
1444 if (delegate_->WidgetSizeIsClientSize()) { | 1464 if (delegate_->WidgetSizeIsClientSize()) { |
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2092 void HWNDMessageHandler::OnSize(UINT param, const CSize& size) { | 2112 void HWNDMessageHandler::OnSize(UINT param, const CSize& size) { |
2093 RedrawWindow(hwnd(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); | 2113 RedrawWindow(hwnd(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); |
2094 // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've | 2114 // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've |
2095 // invoked OnSize we ensure the RootView has been laid out. | 2115 // invoked OnSize we ensure the RootView has been laid out. |
2096 ResetWindowRegion(false, true); | 2116 ResetWindowRegion(false, true); |
2097 | 2117 |
2098 #if defined(USE_AURA) | 2118 #if defined(USE_AURA) |
2099 // We add the WS_VSCROLL and WS_HSCROLL styles to top level windows to ensure | 2119 // We add the WS_VSCROLL and WS_HSCROLL styles to top level windows to ensure |
2100 // that legacy trackpad/trackpoint drivers generate the WM_VSCROLL and | 2120 // that legacy trackpad/trackpoint drivers generate the WM_VSCROLL and |
2101 // WM_HSCROLL messages and scrolling works. | 2121 // WM_HSCROLL messages and scrolling works. |
2102 // We want the style to be present on the window. However we don't want | 2122 // We want the scroll styles to be present on the window. However we don't |
2103 // Windows to draw the scrollbars. To achieve this we hide the scroll bars | 2123 // want Windows to draw the scrollbars. To achieve this we hide the scroll |
2104 // and readd them to the window style in a posted task which works. | 2124 // bars and readd them to the window style in a posted task to ensure that we |
2105 if (scroll_styles_set_) { | 2125 // don't get nested WM_SIZE messages. |
| 2126 if (needs_scroll_styles_ && !in_size_move_loop_) { |
2106 ShowScrollBar(hwnd(), SB_BOTH, FALSE); | 2127 ShowScrollBar(hwnd(), SB_BOTH, FALSE); |
2107 base::MessageLoop::current()->PostTask( | 2128 base::MessageLoop::current()->PostTask( |
2108 FROM_HERE, | 2129 FROM_HERE, base::Bind(&AddScrollStylesToWindow, hwnd())); |
2109 base::Bind(&AddScrollStylesToWindow, hwnd())); | 2130 } |
2110 #endif | 2131 #endif |
2111 } | |
2112 } | 2132 } |
2113 | 2133 |
2114 void HWNDMessageHandler::OnSysCommand(UINT notification_code, | 2134 void HWNDMessageHandler::OnSysCommand(UINT notification_code, |
2115 const CPoint& point) { | 2135 const CPoint& point) { |
2116 if (!delegate_->ShouldHandleSystemCommands()) | 2136 if (!delegate_->ShouldHandleSystemCommands()) |
2117 return; | 2137 return; |
2118 | 2138 |
2119 // Windows uses the 4 lower order bits of |notification_code| for type- | 2139 // Windows uses the 4 lower order bits of |notification_code| for type- |
2120 // specific information so we must exclude this when comparing. | 2140 // specific information so we must exclude this when comparing. |
2121 static const int sc_mask = 0xFFF0; | 2141 static const int sc_mask = 0xFFF0; |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2322 SetMsgHandled(FALSE); | 2342 SetMsgHandled(FALSE); |
2323 } | 2343 } |
2324 | 2344 |
2325 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) { | 2345 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) { |
2326 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); | 2346 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); |
2327 for (size_t i = 0; i < touch_events.size() && ref; ++i) | 2347 for (size_t i = 0; i < touch_events.size() && ref; ++i) |
2328 delegate_->HandleTouchEvent(touch_events[i]); | 2348 delegate_->HandleTouchEvent(touch_events[i]); |
2329 } | 2349 } |
2330 | 2350 |
2331 } // namespace views | 2351 } // namespace views |
OLD | NEW |