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 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 } | 308 } |
309 | 309 |
310 void AddScrollStylesToWindow(HWND window) { | 310 void AddScrollStylesToWindow(HWND window) { |
311 if (::IsWindow(window)) { | 311 if (::IsWindow(window)) { |
312 long current_style = ::GetWindowLong(window, GWL_STYLE); | 312 long current_style = ::GetWindowLong(window, GWL_STYLE); |
313 ::SetWindowLong(window, GWL_STYLE, | 313 ::SetWindowLong(window, GWL_STYLE, |
314 current_style | WS_VSCROLL | WS_HSCROLL); | 314 current_style | WS_VSCROLL | WS_HSCROLL); |
315 } | 315 } |
316 } | 316 } |
317 | 317 |
318 void HideWindowsScrollBar(HWND window) { | |
319 ShowScrollBar(window, SB_BOTH, FALSE); | |
320 base::MessageLoop::current()->PostTask( | |
sky
2014/01/15 15:41:32
Document why the post task.
ananta
2014/01/15 16:54:58
Done.
| |
321 FROM_HERE, | |
322 base::Bind(&AddScrollStylesToWindow, window)); | |
323 } | |
324 | |
318 } // namespace | 325 } // namespace |
319 | 326 |
320 // A scoping class that prevents a window from being able to redraw in response | 327 // A scoping class that prevents a window from being able to redraw in response |
321 // to invalidations that may occur within it for the lifetime of the object. | 328 // to invalidations that may occur within it for the lifetime of the object. |
322 // | 329 // |
323 // Why would we want such a thing? Well, it turns out Windows has some | 330 // Why would we want such a thing? Well, it turns out Windows has some |
324 // "unorthodox" behavior when it comes to painting its non-client areas. | 331 // "unorthodox" behavior when it comes to painting its non-client areas. |
325 // Occasionally, Windows will paint portions of the default non-client area | 332 // Occasionally, Windows will paint portions of the default non-client area |
326 // right over the top of the custom frame. This is not simply fixed by handling | 333 // right over the top of the custom frame. This is not simply fixed by handling |
327 // WM_NCPAINT/WM_PAINT, with some investigation it turns out that this | 334 // WM_NCPAINT/WM_PAINT, with some investigation it turns out that this |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
400 lock_updates_count_(0), | 407 lock_updates_count_(0), |
401 ignore_window_pos_changes_(false), | 408 ignore_window_pos_changes_(false), |
402 last_monitor_(NULL), | 409 last_monitor_(NULL), |
403 use_layered_buffer_(false), | 410 use_layered_buffer_(false), |
404 layered_alpha_(255), | 411 layered_alpha_(255), |
405 waiting_for_redraw_layered_window_contents_(false), | 412 waiting_for_redraw_layered_window_contents_(false), |
406 is_first_nccalc_(true), | 413 is_first_nccalc_(true), |
407 menu_depth_(0), | 414 menu_depth_(0), |
408 autohide_factory_(this), | 415 autohide_factory_(this), |
409 id_generator_(0), | 416 id_generator_(0), |
410 scroll_styles_set_(false) { | 417 scroll_styles_set_(false), |
418 size_move_loop_(false) { | |
411 } | 419 } |
412 | 420 |
413 HWNDMessageHandler::~HWNDMessageHandler() { | 421 HWNDMessageHandler::~HWNDMessageHandler() { |
414 delegate_ = NULL; | 422 delegate_ = NULL; |
415 // Prevent calls back into this class via WNDPROC now that we've been | 423 // Prevent calls back into this class via WNDPROC now that we've been |
416 // destroyed. | 424 // destroyed. |
417 ClearUserData(); | 425 ClearUserData(); |
418 } | 426 } |
419 | 427 |
420 void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) { | 428 void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) { |
421 TRACE_EVENT0("views", "HWNDMessageHandler::Init"); | 429 TRACE_EVENT0("views", "HWNDMessageHandler::Init"); |
422 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, | 430 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, |
423 &last_work_area_); | 431 &last_work_area_); |
424 | 432 |
425 // Create the window. | 433 // Create the window. |
426 WindowImpl::Init(parent, bounds); | 434 WindowImpl::Init(parent, bounds); |
435 | |
436 #if defined(USE_AURA) | |
437 // Certain trackpad drivers on Windows have bugs where in they don't generate | |
438 // WM_MOUSEWHEEL messages for the trackpoint and trackpad scrolling gestures | |
439 // unless there is an entry for Chrome with the class name of the Window. | |
440 // These drivers check if the window under the trackpoint has the WS_VSCROLL/ | |
441 // WS_HSCROLL style and if yes they generate the legacy WM_VSCROLL/WM_HSCROLL | |
442 // messages. We add these styles to ensure that trackpad/trackpoint scrolling | |
443 // work. | |
444 // TODO(ananta) | |
445 // Look into moving the WS_VSCROLL and WS_HSCROLL style setting logic to the | |
446 // CalculateWindowStylesFromInitParams function. Doing it there seems to | |
447 // cause some interactive tests to fail. Investigation needed. | |
448 if (IsTopLevelWindow(hwnd())) { | |
449 long current_style = ::GetWindowLong(hwnd(), GWL_STYLE); | |
450 if (!(current_style & WS_POPUP)) { | |
451 ::SetWindowLong(hwnd(), GWL_STYLE, | |
sky
2014/01/15 15:41:32
Can you use AddScrollStylesToWindow?
ananta
2014/01/15 16:54:58
Done.
| |
452 current_style | WS_VSCROLL | WS_HSCROLL); | |
453 scroll_styles_set_ = true; | |
sky
2014/01/15 15:41:32
How about naming this needs_scroll_styles_?
ananta
2014/01/15 16:54:58
Done.
| |
454 } | |
455 } | |
456 #endif | |
427 } | 457 } |
428 | 458 |
429 void HWNDMessageHandler::InitModalType(ui::ModalType modal_type) { | 459 void HWNDMessageHandler::InitModalType(ui::ModalType modal_type) { |
430 if (modal_type == ui::MODAL_TYPE_NONE) | 460 if (modal_type == ui::MODAL_TYPE_NONE) |
431 return; | 461 return; |
432 // We implement modality by crawling up the hierarchy of windows starting | 462 // 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 | 463 // at the owner, disabling all of them so that they don't receive input |
434 // messages. | 464 // messages. |
435 HWND start = ::GetWindow(hwnd(), GW_OWNER); | 465 HWND start = ::GetWindow(hwnd(), GW_OWNER); |
436 while (start) { | 466 while (start) { |
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1359 #if !defined(USE_AURA) | 1389 #if !defined(USE_AURA) |
1360 // We need to add ourselves as a message loop observer so that we can repaint | 1390 // We need to add ourselves as a message loop observer so that we can repaint |
1361 // aggressively if the contents of our window become invalid. Unfortunately | 1391 // aggressively if the contents of our window become invalid. Unfortunately |
1362 // WM_PAINT messages are starved and we get flickery redrawing when resizing | 1392 // WM_PAINT messages are starved and we get flickery redrawing when resizing |
1363 // if we do not do this. | 1393 // if we do not do this. |
1364 base::MessageLoopForUI::current()->AddObserver(this); | 1394 base::MessageLoopForUI::current()->AddObserver(this); |
1365 #endif | 1395 #endif |
1366 | 1396 |
1367 delegate_->HandleCreate(); | 1397 delegate_->HandleCreate(); |
1368 | 1398 |
1369 #if defined(USE_AURA) | |
1370 // Certain trackpad drivers on Windows have bugs where in they don't generate | |
1371 // WM_MOUSEWHEEL messages for the trackpoint and trackpad scrolling gestures | |
1372 // unless there is an entry for Chrome with the class name of the Window. | |
1373 // These drivers check if the window under the trackpoint has the WS_VSCROLL/ | |
1374 // WS_HSCROLL style and if yes they generate the legacy WM_VSCROLL/WM_HSCROLL | |
1375 // messages. We add these styles to ensure that trackpad/trackpoint scrolling | |
1376 // work. | |
1377 // TODO(ananta) | |
1378 // Look into moving the WS_VSCROLL and WS_HSCROLL style setting logic to the | |
1379 // CalculateWindowStylesFromInitParams function. Doing it there seems to | |
1380 // cause some interactive tests to fail. Investigation needed. | |
1381 if (IsTopLevelWindow(hwnd())) { | |
1382 long current_style = ::GetWindowLong(hwnd(), GWL_STYLE); | |
1383 ::SetWindowLong(hwnd(), GWL_STYLE, | |
1384 current_style | WS_VSCROLL | WS_HSCROLL); | |
1385 scroll_styles_set_ = true; | |
1386 } | |
1387 #endif | |
1388 // TODO(beng): move more of NWW::OnCreate here. | 1399 // TODO(beng): move more of NWW::OnCreate here. |
1389 return 0; | 1400 return 0; |
1390 } | 1401 } |
1391 | 1402 |
1392 void HWNDMessageHandler::OnDestroy() { | 1403 void HWNDMessageHandler::OnDestroy() { |
1393 delegate_->HandleDestroying(); | 1404 delegate_->HandleDestroying(); |
1394 } | 1405 } |
1395 | 1406 |
1396 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, | 1407 void HWNDMessageHandler::OnDisplayChange(UINT bits_per_pixel, |
1397 const CSize& screen_size) { | 1408 const CSize& screen_size) { |
(...skipping 11 matching lines...) Expand all Loading... | |
1409 FrameTypeChanged(); | 1420 FrameTypeChanged(); |
1410 return 0; | 1421 return 0; |
1411 } | 1422 } |
1412 | 1423 |
1413 void HWNDMessageHandler::OnEnterMenuLoop(BOOL from_track_popup_menu) { | 1424 void HWNDMessageHandler::OnEnterMenuLoop(BOOL from_track_popup_menu) { |
1414 if (menu_depth_++ == 0) | 1425 if (menu_depth_++ == 0) |
1415 delegate_->HandleMenuLoop(true); | 1426 delegate_->HandleMenuLoop(true); |
1416 } | 1427 } |
1417 | 1428 |
1418 void HWNDMessageHandler::OnEnterSizeMove() { | 1429 void HWNDMessageHandler::OnEnterSizeMove() { |
1430 size_move_loop_ = true; | |
1419 delegate_->HandleBeginWMSizeMove(); | 1431 delegate_->HandleBeginWMSizeMove(); |
1420 SetMsgHandled(FALSE); | 1432 SetMsgHandled(FALSE); |
1421 } | 1433 } |
1422 | 1434 |
1423 LRESULT HWNDMessageHandler::OnEraseBkgnd(HDC dc) { | 1435 LRESULT HWNDMessageHandler::OnEraseBkgnd(HDC dc) { |
1424 // Needed to prevent resize flicker. | 1436 // Needed to prevent resize flicker. |
1425 return 1; | 1437 return 1; |
1426 } | 1438 } |
1427 | 1439 |
1428 void HWNDMessageHandler::OnExitMenuLoop(BOOL is_shortcut_menu) { | 1440 void HWNDMessageHandler::OnExitMenuLoop(BOOL is_shortcut_menu) { |
1429 if (--menu_depth_ == 0) | 1441 if (--menu_depth_ == 0) |
1430 delegate_->HandleMenuLoop(false); | 1442 delegate_->HandleMenuLoop(false); |
1431 DCHECK_GE(0, menu_depth_); | 1443 DCHECK_GE(0, menu_depth_); |
1432 } | 1444 } |
1433 | 1445 |
1434 void HWNDMessageHandler::OnExitSizeMove() { | 1446 void HWNDMessageHandler::OnExitSizeMove() { |
1435 delegate_->HandleEndWMSizeMove(); | 1447 delegate_->HandleEndWMSizeMove(); |
1436 SetMsgHandled(FALSE); | 1448 SetMsgHandled(FALSE); |
1449 size_move_loop_ = false; | |
1450 // Please refer to the notes in the OnSize function for information about | |
1451 // the scrolling hack. | |
1452 if (scroll_styles_set_) | |
1453 HideWindowsScrollBar(hwnd()); | |
1437 } | 1454 } |
1438 | 1455 |
1439 void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { | 1456 void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { |
1440 gfx::Size min_window_size; | 1457 gfx::Size min_window_size; |
1441 gfx::Size max_window_size; | 1458 gfx::Size max_window_size; |
1442 delegate_->GetMinMaxSize(&min_window_size, &max_window_size); | 1459 delegate_->GetMinMaxSize(&min_window_size, &max_window_size); |
1443 | 1460 |
1444 // Add the native frame border size to the minimum and maximum size if the | 1461 // Add the native frame border size to the minimum and maximum size if the |
1445 // view reports its size as the client size. | 1462 // view reports its size as the client size. |
1446 if (delegate_->WidgetSizeIsClientSize()) { | 1463 if (delegate_->WidgetSizeIsClientSize()) { |
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2094 // invoked OnSize we ensure the RootView has been laid out. | 2111 // invoked OnSize we ensure the RootView has been laid out. |
2095 ResetWindowRegion(false, true); | 2112 ResetWindowRegion(false, true); |
2096 | 2113 |
2097 #if defined(USE_AURA) | 2114 #if defined(USE_AURA) |
2098 // We add the WS_VSCROLL and WS_HSCROLL styles to top level windows to ensure | 2115 // We add the WS_VSCROLL and WS_HSCROLL styles to top level windows to ensure |
2099 // that legacy trackpad/trackpoint drivers generate the WM_VSCROLL and | 2116 // that legacy trackpad/trackpoint drivers generate the WM_VSCROLL and |
2100 // WM_HSCROLL messages and scrolling works. | 2117 // WM_HSCROLL messages and scrolling works. |
2101 // We want the style to be present on the window. However we don't want | 2118 // We want the style to be present on the window. However we don't want |
2102 // Windows to draw the scrollbars. To achieve this we hide the scroll bars | 2119 // Windows to draw the scrollbars. To achieve this we hide the scroll bars |
2103 // and readd them to the window style in a posted task which works. | 2120 // and readd them to the window style in a posted task which works. |
2104 if (scroll_styles_set_) { | 2121 // If we are in the context of a size loop operation, we do this when the |
2105 ShowScrollBar(hwnd(), SB_BOTH, FALSE); | 2122 // sizing operation completes. |
2106 base::MessageLoop::current()->PostTask( | 2123 if (scroll_styles_set_ && !size_move_loop_) |
2107 FROM_HERE, | 2124 HideWindowsScrollBar(hwnd()); |
2108 base::Bind(&AddScrollStylesToWindow, hwnd())); | |
2109 #endif | 2125 #endif |
2110 } | |
2111 } | 2126 } |
2112 | 2127 |
2113 void HWNDMessageHandler::OnSysCommand(UINT notification_code, | 2128 void HWNDMessageHandler::OnSysCommand(UINT notification_code, |
2114 const CPoint& point) { | 2129 const CPoint& point) { |
2115 if (!delegate_->ShouldHandleSystemCommands()) | 2130 if (!delegate_->ShouldHandleSystemCommands()) |
2116 return; | 2131 return; |
2117 | 2132 |
2118 // Windows uses the 4 lower order bits of |notification_code| for type- | 2133 // Windows uses the 4 lower order bits of |notification_code| for type- |
2119 // specific information so we must exclude this when comparing. | 2134 // specific information so we must exclude this when comparing. |
2120 static const int sc_mask = 0xFFF0; | 2135 static const int sc_mask = 0xFFF0; |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2321 SetMsgHandled(FALSE); | 2336 SetMsgHandled(FALSE); |
2322 } | 2337 } |
2323 | 2338 |
2324 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) { | 2339 void HWNDMessageHandler::HandleTouchEvents(const TouchEvents& touch_events) { |
2325 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); | 2340 base::WeakPtr<HWNDMessageHandler> ref(weak_factory_.GetWeakPtr()); |
2326 for (size_t i = 0; i < touch_events.size() && ref; ++i) | 2341 for (size_t i = 0; i < touch_events.size() && ref; ++i) |
2327 delegate_->HandleTouchEvent(touch_events[i]); | 2342 delegate_->HandleTouchEvent(touch_events[i]); |
2328 } | 2343 } |
2329 | 2344 |
2330 } // namespace views | 2345 } // namespace views |
OLD | NEW |