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 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 is_right_mouse_pressed_on_caption_(false), | 399 is_right_mouse_pressed_on_caption_(false), |
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 autohide_factory_(this), | 407 autohide_factory_(this), |
408 id_generator_(0), | 408 id_generator_(0), |
409 scroll_styles_set_(false) { | 409 needs_scroll_styles_(false), |
| 410 in_size_move_loop_(false) { |
410 } | 411 } |
411 | 412 |
412 HWNDMessageHandler::~HWNDMessageHandler() { | 413 HWNDMessageHandler::~HWNDMessageHandler() { |
413 delegate_ = NULL; | 414 delegate_ = NULL; |
414 // Prevent calls back into this class via WNDPROC now that we've been | 415 // Prevent calls back into this class via WNDPROC now that we've been |
415 // destroyed. | 416 // destroyed. |
416 ClearUserData(); | 417 ClearUserData(); |
417 } | 418 } |
418 | 419 |
419 void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) { | 420 void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) { |
420 TRACE_EVENT0("views", "HWNDMessageHandler::Init"); | 421 TRACE_EVENT0("views", "HWNDMessageHandler::Init"); |
421 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, | 422 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, |
422 &last_work_area_); | 423 &last_work_area_); |
423 | 424 |
424 // Create the window. | 425 // Create the window. |
425 WindowImpl::Init(parent, bounds); | 426 WindowImpl::Init(parent, bounds); |
| 427 |
| 428 #if defined(USE_AURA) |
| 429 // Certain trackpad drivers on Windows have bugs where in they don't generate |
| 430 // WM_MOUSEWHEEL messages for the trackpoint and trackpad scrolling gestures |
| 431 // unless there is an entry for Chrome with the class name of the Window. |
| 432 // These drivers check if the window under the trackpoint has the WS_VSCROLL/ |
| 433 // WS_HSCROLL style and if yes they generate the legacy WM_VSCROLL/WM_HSCROLL |
| 434 // messages. We add these styles to ensure that trackpad/trackpoint scrolling |
| 435 // work. |
| 436 // TODO(ananta) |
| 437 // Look into moving the WS_VSCROLL and WS_HSCROLL style setting logic to the |
| 438 // CalculateWindowStylesFromInitParams function. Doing it there seems to |
| 439 // cause some interactive tests to fail. Investigation needed. |
| 440 if (IsTopLevelWindow(hwnd())) { |
| 441 long current_style = ::GetWindowLong(hwnd(), GWL_STYLE); |
| 442 if (!(current_style & WS_POPUP)) { |
| 443 AddScrollStylesToWindow(hwnd()); |
| 444 needs_scroll_styles_ = true; |
| 445 } |
| 446 } |
| 447 #endif |
426 } | 448 } |
427 | 449 |
428 void HWNDMessageHandler::InitModalType(ui::ModalType modal_type) { | 450 void HWNDMessageHandler::InitModalType(ui::ModalType modal_type) { |
429 if (modal_type == ui::MODAL_TYPE_NONE) | 451 if (modal_type == ui::MODAL_TYPE_NONE) |
430 return; | 452 return; |
431 // We implement modality by crawling up the hierarchy of windows starting | 453 // We implement modality by crawling up the hierarchy of windows starting |
432 // at the owner, disabling all of them so that they don't receive input | 454 // at the owner, disabling all of them so that they don't receive input |
433 // messages. | 455 // messages. |
434 HWND start = ::GetWindow(hwnd(), GW_OWNER); | 456 HWND start = ::GetWindow(hwnd(), GW_OWNER); |
435 while (start) { | 457 while (start) { |
(...skipping 914 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1350 #if !defined(USE_AURA) | 1372 #if !defined(USE_AURA) |
1351 // We need to add ourselves as a message loop observer so that we can repaint | 1373 // We need to add ourselves as a message loop observer so that we can repaint |
1352 // aggressively if the contents of our window become invalid. Unfortunately | 1374 // aggressively if the contents of our window become invalid. Unfortunately |
1353 // WM_PAINT messages are starved and we get flickery redrawing when resizing | 1375 // WM_PAINT messages are starved and we get flickery redrawing when resizing |
1354 // if we do not do this. | 1376 // if we do not do this. |
1355 base::MessageLoopForUI::current()->AddObserver(this); | 1377 base::MessageLoopForUI::current()->AddObserver(this); |
1356 #endif | 1378 #endif |
1357 | 1379 |
1358 delegate_->HandleCreate(); | 1380 delegate_->HandleCreate(); |
1359 | 1381 |
1360 #if defined(USE_AURA) | |
1361 // Certain trackpad drivers on Windows have bugs where in they don't generate | |
1362 // WM_MOUSEWHEEL messages for the trackpoint and trackpad scrolling gestures | |
1363 // unless there is an entry for Chrome with the class name of the Window. | |
1364 // These drivers check if the window under the trackpoint has the WS_VSCROLL/ | |
1365 // WS_HSCROLL style and if yes they generate the legacy WM_VSCROLL/WM_HSCROLL | |
1366 // messages. We add these styles to ensure that trackpad/trackpoint scrolling | |
1367 // work. | |
1368 // TODO(ananta) | |
1369 // Look into moving the WS_VSCROLL and WS_HSCROLL style setting logic to the | |
1370 // CalculateWindowStylesFromInitParams function. Doing it there seems to | |
1371 // cause some interactive tests to fail. Investigation needed. | |
1372 if (IsTopLevelWindow(hwnd())) { | |
1373 long current_style = ::GetWindowLong(hwnd(), GWL_STYLE); | |
1374 ::SetWindowLong(hwnd(), GWL_STYLE, | |
1375 current_style | WS_VSCROLL | WS_HSCROLL); | |
1376 scroll_styles_set_ = true; | |
1377 } | |
1378 #endif | |
1379 // TODO(beng): move more of NWW::OnCreate here. | 1382 // TODO(beng): move more of NWW::OnCreate here. |
1380 return 0; | 1383 return 0; |
1381 } | 1384 } |
1382 | 1385 |
1383 void HWNDMessageHandler::OnDestroy() { | 1386 void HWNDMessageHandler::OnDestroy() { |
1384 delegate_->HandleDestroying(); | 1387 delegate_->HandleDestroying(); |
1385 } | 1388 } |
1386 | 1389 |
1387 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, | 1390 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, |
1388 const CSize& screen_size) { | 1391 const CSize& screen_size) { |
1389 delegate_->HandleDisplayChange(); | 1392 delegate_->HandleDisplayChange(); |
1390 } | 1393 } |
1391 | 1394 |
1392 LRESULT HWNDMessageHandler::OnDwmCompositionChanged(UINT msg, | 1395 LRESULT HWNDMessageHandler::OnDwmCompositionChanged(UINT msg, |
1393 WPARAM w_param, | 1396 WPARAM w_param, |
1394 LPARAM l_param) { | 1397 LPARAM l_param) { |
1395 if (!delegate_->IsWidgetWindow()) { | 1398 if (!delegate_->IsWidgetWindow()) { |
1396 SetMsgHandled(FALSE); | 1399 SetMsgHandled(FALSE); |
1397 return 0; | 1400 return 0; |
1398 } | 1401 } |
1399 | 1402 |
1400 FrameTypeChanged(); | 1403 FrameTypeChanged(); |
1401 return 0; | 1404 return 0; |
1402 } | 1405 } |
1403 | 1406 |
1404 void HWNDMessageHandler::OnEnterSizeMove() { | 1407 void HWNDMessageHandler::OnEnterSizeMove() { |
| 1408 in_size_move_loop_ = true; |
| 1409 |
| 1410 // Please refer to the comments in the OnSize function about the scrollbar |
| 1411 // hack. |
| 1412 // Hide the Windows scrollbar if the scroll styles are present to ensure |
| 1413 // that a paint flicker does not occur while sizing. |
| 1414 if (needs_scroll_styles_) |
| 1415 ShowScrollBar(hwnd(), SB_BOTH, FALSE); |
| 1416 |
1405 delegate_->HandleBeginWMSizeMove(); | 1417 delegate_->HandleBeginWMSizeMove(); |
1406 SetMsgHandled(FALSE); | 1418 SetMsgHandled(FALSE); |
1407 } | 1419 } |
1408 | 1420 |
1409 LRESULT HWNDMessageHandler::OnEraseBkgnd(HDC dc) { | 1421 LRESULT HWNDMessageHandler::OnEraseBkgnd(HDC dc) { |
1410 // Needed to prevent resize flicker. | 1422 // Needed to prevent resize flicker. |
1411 return 1; | 1423 return 1; |
1412 } | 1424 } |
1413 | 1425 |
1414 void HWNDMessageHandler::OnExitSizeMove() { | 1426 void HWNDMessageHandler::OnExitSizeMove() { |
1415 delegate_->HandleEndWMSizeMove(); | 1427 delegate_->HandleEndWMSizeMove(); |
1416 SetMsgHandled(FALSE); | 1428 SetMsgHandled(FALSE); |
| 1429 in_size_move_loop_ = false; |
| 1430 // Please refer to the notes in the OnSize function for information about |
| 1431 // the scrolling hack. |
| 1432 // We hide the Windows scrollbar in the OnEnterSizeMove function. We need |
| 1433 // to add the scroll styles back to ensure that scrolling works in legacy |
| 1434 // trackpoint drivers. |
| 1435 if (needs_scroll_styles_) |
| 1436 AddScrollStylesToWindow(hwnd()); |
1417 } | 1437 } |
1418 | 1438 |
1419 void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { | 1439 void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { |
1420 gfx::Size min_window_size; | 1440 gfx::Size min_window_size; |
1421 gfx::Size max_window_size; | 1441 gfx::Size max_window_size; |
1422 delegate_->GetMinMaxSize(&min_window_size, &max_window_size); | 1442 delegate_->GetMinMaxSize(&min_window_size, &max_window_size); |
1423 | 1443 |
1424 // Add the native frame border size to the minimum and maximum size if the | 1444 // Add the native frame border size to the minimum and maximum size if the |
1425 // view reports its size as the client size. | 1445 // view reports its size as the client size. |
1426 if (delegate_->WidgetSizeIsClientSize()) { | 1446 if (delegate_->WidgetSizeIsClientSize()) { |
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2069 void HWNDMessageHandler::OnSize(UINT param, const CSize& size) { | 2089 void HWNDMessageHandler::OnSize(UINT param, const CSize& size) { |
2070 RedrawWindow(hwnd(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); | 2090 RedrawWindow(hwnd(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); |
2071 // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've | 2091 // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've |
2072 // invoked OnSize we ensure the RootView has been laid out. | 2092 // invoked OnSize we ensure the RootView has been laid out. |
2073 ResetWindowRegion(false, true); | 2093 ResetWindowRegion(false, true); |
2074 | 2094 |
2075 #if defined(USE_AURA) | 2095 #if defined(USE_AURA) |
2076 // We add the WS_VSCROLL and WS_HSCROLL styles to top level windows to ensure | 2096 // We add the WS_VSCROLL and WS_HSCROLL styles to top level windows to ensure |
2077 // that legacy trackpad/trackpoint drivers generate the WM_VSCROLL and | 2097 // that legacy trackpad/trackpoint drivers generate the WM_VSCROLL and |
2078 // WM_HSCROLL messages and scrolling works. | 2098 // WM_HSCROLL messages and scrolling works. |
2079 // We want the style to be present on the window. However we don't want | 2099 // We want the scroll styles to be present on the window. However we don't |
2080 // Windows to draw the scrollbars. To achieve this we hide the scroll bars | 2100 // want Windows to draw the scrollbars. To achieve this we hide the scroll |
2081 // and readd them to the window style in a posted task which works. | 2101 // bars and readd them to the window style in a posted task to ensure that we |
2082 if (scroll_styles_set_) { | 2102 // don't get nested WM_SIZE messages. |
| 2103 if (needs_scroll_styles_ && !in_size_move_loop_) { |
2083 ShowScrollBar(hwnd(), SB_BOTH, FALSE); | 2104 ShowScrollBar(hwnd(), SB_BOTH, FALSE); |
2084 base::MessageLoop::current()->PostTask( | 2105 base::MessageLoop::current()->PostTask( |
2085 FROM_HERE, | 2106 FROM_HERE, base::Bind(&AddScrollStylesToWindow, hwnd())); |
2086 base::Bind(&AddScrollStylesToWindow, hwnd())); | 2107 } |
2087 #endif | 2108 #endif |
2088 } | |
2089 } | 2109 } |
2090 | 2110 |
2091 void HWNDMessageHandler::OnSysCommand(UINT notification_code, | 2111 void HWNDMessageHandler::OnSysCommand(UINT notification_code, |
2092 const CPoint& point) { | 2112 const CPoint& point) { |
2093 if (!delegate_->ShouldHandleSystemCommands()) | 2113 if (!delegate_->ShouldHandleSystemCommands()) |
2094 return; | 2114 return; |
2095 | 2115 |
2096 // Windows uses the 4 lower order bits of |notification_code| for type- | 2116 // Windows uses the 4 lower order bits of |notification_code| for type- |
2097 // specific information so we must exclude this when comparing. | 2117 // specific information so we must exclude this when comparing. |
2098 static const int sc_mask = 0xFFF0; | 2118 static const int sc_mask = 0xFFF0; |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2299 SetMsgHandled(FALSE); | 2319 SetMsgHandled(FALSE); |
2300 } | 2320 } |
2301 | 2321 |
2302 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) { | 2322 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) { |
2303 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); | 2323 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); |
2304 for (size_t i = 0; i < touch_events.size() && ref; ++i) | 2324 for (size_t i = 0; i < touch_events.size() && ref; ++i) |
2305 delegate_->HandleTouchEvent(touch_events[i]); | 2325 delegate_->HandleTouchEvent(touch_events[i]); |
2306 } | 2326 } |
2307 | 2327 |
2308 } // namespace views | 2328 } // namespace views |
OLD | NEW |