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

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

Issue 2172843002: Fix touchpad zoom on touchscreen Windows devices. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove the AddScrollStylesToWindow function Created 4 years, 5 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 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 const int kAutoHideTaskbarThicknessPx = 2; 214 const int kAutoHideTaskbarThicknessPx = 2;
215 215
216 bool IsTopLevelWindow(HWND window) { 216 bool IsTopLevelWindow(HWND window) {
217 long style = ::GetWindowLong(window, GWL_STYLE); 217 long style = ::GetWindowLong(window, GWL_STYLE);
218 if (!(style & WS_CHILD)) 218 if (!(style & WS_CHILD))
219 return true; 219 return true;
220 HWND parent = ::GetParent(window); 220 HWND parent = ::GetParent(window);
221 return !parent || (parent == ::GetDesktopWindow()); 221 return !parent || (parent == ::GetDesktopWindow());
222 } 222 }
223 223
224 void AddScrollStylesToWindow(HWND window) {
225 if (::IsWindow(window)) {
226 long current_style = ::GetWindowLong(window, GWL_STYLE);
227 ::SetWindowLong(window, GWL_STYLE,
228 current_style | WS_VSCROLL | WS_HSCROLL);
229 }
230 }
231
232 const int kTouchDownContextResetTimeout = 500; 224 const int kTouchDownContextResetTimeout = 500;
233 225
234 // Windows does not flag synthesized mouse messages from touch in all cases. 226 // Windows does not flag synthesized mouse messages from touch in all cases.
235 // This causes us grief as we don't want to process touch and mouse messages 227 // This causes us grief as we don't want to process touch and mouse messages
236 // concurrently. Hack as per msdn is to check if the time difference between 228 // concurrently. Hack as per msdn is to check if the time difference between
237 // the touch message and the mouse move is within 500 ms and at the same 229 // the touch message and the mouse move is within 500 ms and at the same
238 // location as the cursor. 230 // location as the cursor.
239 const int kSynthesizedMouseTouchMessagesTimeDifference = 500; 231 const int kSynthesizedMouseTouchMessagesTimeDifference = 500;
240 232
241 } // namespace 233 } // namespace
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 current_cursor_(NULL), 315 current_cursor_(NULL),
324 previous_cursor_(NULL), 316 previous_cursor_(NULL),
325 active_mouse_tracking_flags_(0), 317 active_mouse_tracking_flags_(0),
326 is_right_mouse_pressed_on_caption_(false), 318 is_right_mouse_pressed_on_caption_(false),
327 lock_updates_count_(0), 319 lock_updates_count_(0),
328 ignore_window_pos_changes_(false), 320 ignore_window_pos_changes_(false),
329 last_monitor_(NULL), 321 last_monitor_(NULL),
330 is_first_nccalc_(true), 322 is_first_nccalc_(true),
331 menu_depth_(0), 323 menu_depth_(0),
332 id_generator_(0), 324 id_generator_(0),
333 needs_scroll_styles_(false),
334 in_size_loop_(false), 325 in_size_loop_(false),
335 touch_down_contexts_(0), 326 touch_down_contexts_(0),
336 last_mouse_hwheel_time_(0), 327 last_mouse_hwheel_time_(0),
337 dwm_transition_desired_(false), 328 dwm_transition_desired_(false),
338 sent_window_size_changing_(false), 329 sent_window_size_changing_(false),
339 left_button_down_on_caption_(false), 330 left_button_down_on_caption_(false),
340 background_fullscreen_hack_(false), 331 background_fullscreen_hack_(false),
341 autohide_factory_(this), 332 autohide_factory_(this),
342 weak_factory_(this) {} 333 weak_factory_(this) {}
343 334
344 HWNDMessageHandler::~HWNDMessageHandler() { 335 HWNDMessageHandler::~HWNDMessageHandler() {
345 delegate_ = NULL; 336 delegate_ = NULL;
346 // Prevent calls back into this class via WNDPROC now that we've been 337 // Prevent calls back into this class via WNDPROC now that we've been
347 // destroyed. 338 // destroyed.
348 ClearUserData(); 339 ClearUserData();
349 } 340 }
350 341
351 void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) { 342 void HWNDMessageHandler::Init(HWND parent, const gfx::Rect& bounds) {
352 TRACE_EVENT0("views", "HWNDMessageHandler::Init"); 343 TRACE_EVENT0("views", "HWNDMessageHandler::Init");
353 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_, 344 GetMonitorAndRects(bounds.ToRECT(), &last_monitor_, &last_monitor_rect_,
354 &last_work_area_); 345 &last_work_area_);
355 346
356 // Create the window. 347 // Create the window.
357 WindowImpl::Init(parent, bounds); 348 WindowImpl::Init(parent, bounds);
358 // TODO(ananta)
359 // Remove the scrolling hack code once we have scrolling working well.
360 #if defined(ENABLE_SCROLL_HACK)
361 // Certain trackpad drivers on Windows have bugs where in they don't generate
362 // WM_MOUSEWHEEL messages for the trackpoint and trackpad scrolling gestures
363 // unless there is an entry for Chrome with the class name of the Window.
364 // These drivers check if the window under the trackpoint has the WS_VSCROLL/
365 // WS_HSCROLL style and if yes they generate the legacy WM_VSCROLL/WM_HSCROLL
366 // messages. We add these styles to ensure that trackpad/trackpoint scrolling
367 // work.
368 // TODO(ananta)
369 // Look into moving the WS_VSCROLL and WS_HSCROLL style setting logic to the
370 // CalculateWindowStylesFromInitParams function. Doing it there seems to
371 // cause some interactive tests to fail. Investigation needed.
372 if (IsTopLevelWindow(hwnd())) {
373 long current_style = ::GetWindowLong(hwnd(), GWL_STYLE);
374 if (!(current_style & WS_POPUP)) {
375 AddScrollStylesToWindow(hwnd());
376 needs_scroll_styles_ = true;
377 }
378 }
379 #endif
380 349
381 prop_window_target_.reset(new ui::ViewProp(hwnd(), 350 prop_window_target_.reset(new ui::ViewProp(hwnd(),
382 ui::WindowEventTarget::kWin32InputEventTarget, 351 ui::WindowEventTarget::kWin32InputEventTarget,
383 static_cast<ui::WindowEventTarget*>(this))); 352 static_cast<ui::WindowEventTarget*>(this)));
384 353
385 // Direct Manipulation is enabled on Windows 10+. The CreateInstance function 354 // Direct Manipulation is enabled on Windows 10+. The CreateInstance function
386 // returns NULL if Direct Manipulation is not available. 355 // returns NULL if Direct Manipulation is not available.
387 direct_manipulation_helper_ = 356 direct_manipulation_helper_ =
388 gfx::win::DirectManipulationHelper::CreateInstance(); 357 gfx::win::DirectManipulationHelper::CreateInstance();
389 if (direct_manipulation_helper_) 358 if (direct_manipulation_helper_)
(...skipping 1027 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 display::win::GetScalingFactorFromDPI(LOWORD(w_param))); 1386 display::win::GetScalingFactorFromDPI(LOWORD(w_param)));
1418 return 0; 1387 return 0;
1419 } 1388 }
1420 1389
1421 void HWNDMessageHandler::OnEnterMenuLoop(BOOL from_track_popup_menu) { 1390 void HWNDMessageHandler::OnEnterMenuLoop(BOOL from_track_popup_menu) {
1422 if (menu_depth_++ == 0) 1391 if (menu_depth_++ == 0)
1423 delegate_->HandleMenuLoop(true); 1392 delegate_->HandleMenuLoop(true);
1424 } 1393 }
1425 1394
1426 void HWNDMessageHandler::OnEnterSizeMove() { 1395 void HWNDMessageHandler::OnEnterSizeMove() {
1427 // Please refer to the comments in the OnSize function about the scrollbar
1428 // hack.
1429 // Hide the Windows scrollbar if the scroll styles are present to ensure
1430 // that a paint flicker does not occur while sizing.
1431 if (in_size_loop_ && needs_scroll_styles_)
1432 ShowScrollBar(hwnd(), SB_BOTH, FALSE);
1433
1434 delegate_->HandleBeginWMSizeMove(); 1396 delegate_->HandleBeginWMSizeMove();
1435 SetMsgHandled(FALSE); 1397 SetMsgHandled(FALSE);
1436 } 1398 }
1437 1399
1438 LRESULT HWNDMessageHandler::OnEraseBkgnd(HDC dc) { 1400 LRESULT HWNDMessageHandler::OnEraseBkgnd(HDC dc) {
1439 // Needed to prevent resize flicker. 1401 // Needed to prevent resize flicker.
1440 return 1; 1402 return 1;
1441 } 1403 }
1442 1404
1443 void HWNDMessageHandler::OnExitMenuLoop(BOOL is_shortcut_menu) { 1405 void HWNDMessageHandler::OnExitMenuLoop(BOOL is_shortcut_menu) {
1444 if (--menu_depth_ == 0) 1406 if (--menu_depth_ == 0)
1445 delegate_->HandleMenuLoop(false); 1407 delegate_->HandleMenuLoop(false);
1446 DCHECK_GE(0, menu_depth_); 1408 DCHECK_GE(0, menu_depth_);
1447 } 1409 }
1448 1410
1449 void HWNDMessageHandler::OnExitSizeMove() { 1411 void HWNDMessageHandler::OnExitSizeMove() {
1450 delegate_->HandleEndWMSizeMove(); 1412 delegate_->HandleEndWMSizeMove();
1451 SetMsgHandled(FALSE); 1413 SetMsgHandled(FALSE);
1452 // Please refer to the notes in the OnSize function for information about
1453 // the scrolling hack.
1454 // We hide the Windows scrollbar in the OnEnterSizeMove function. We need
1455 // to add the scroll styles back to ensure that scrolling works in legacy
1456 // trackpoint drivers.
1457 if (in_size_loop_ && needs_scroll_styles_)
1458 AddScrollStylesToWindow(hwnd());
1459 // If the window was moved to a monitor which has a fullscreen window active, 1414 // If the window was moved to a monitor which has a fullscreen window active,
1460 // we need to reduce the size of the fullscreen window by 1px. 1415 // we need to reduce the size of the fullscreen window by 1px.
1461 CheckAndHandleBackgroundFullscreenOnMonitor(hwnd()); 1416 CheckAndHandleBackgroundFullscreenOnMonitor(hwnd());
1462 } 1417 }
1463 1418
1464 void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) { 1419 void HWNDMessageHandler::OnGetMinMaxInfo(MINMAXINFO* minmax_info) {
1465 gfx::Size min_window_size; 1420 gfx::Size min_window_size;
1466 gfx::Size max_window_size; 1421 gfx::Size max_window_size;
1467 delegate_->GetMinMaxSize(&min_window_size, &max_window_size); 1422 delegate_->GetMinMaxSize(&min_window_size, &max_window_size);
1468 min_window_size = delegate_->DIPToScreenSize(min_window_size); 1423 min_window_size = delegate_->DIPToScreenSize(min_window_size);
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 } 1787 }
1833 1788
1834 // If the point is specified as custom or system nonclient item, return it. 1789 // If the point is specified as custom or system nonclient item, return it.
1835 if (component != HTNOWHERE) 1790 if (component != HTNOWHERE)
1836 return component; 1791 return component;
1837 1792
1838 // Otherwise, we let Windows do all the native frame non-client handling for 1793 // Otherwise, we let Windows do all the native frame non-client handling for
1839 // us. 1794 // us.
1840 LRESULT hit_test_code = DefWindowProc(hwnd(), WM_NCHITTEST, 0, 1795 LRESULT hit_test_code = DefWindowProc(hwnd(), WM_NCHITTEST, 0,
1841 MAKELPARAM(point.x(), point.y())); 1796 MAKELPARAM(point.x(), point.y()));
1842 if (needs_scroll_styles_) {
1843 switch (hit_test_code) {
1844 // If we faked the WS_VSCROLL and WS_HSCROLL styles for this window, then
1845 // Windows returns the HTVSCROLL or HTHSCROLL hit test codes if we hover
1846 // or click on the non client portions of the window where the OS
1847 // scrollbars would be drawn. These hittest codes are returned even when
1848 // the scrollbars are hidden, which is the case in Aura. We fake the
1849 // hittest code as HTCLIENT in this case to ensure that we receive client
1850 // mouse messages as opposed to non client mouse messages.
1851 case HTVSCROLL:
1852 case HTHSCROLL:
1853 hit_test_code = HTCLIENT;
1854 break;
1855
1856 case HTBOTTOMRIGHT: {
1857 // Normally the HTBOTTOMRIGHT hittest code is received when we hover
1858 // near the bottom right of the window. However due to our fake scroll
1859 // styles, we get this code even when we hover around the area where
1860 // the vertical scrollar down arrow would be drawn.
1861 // We check if the hittest coordinates lie in this region and if yes
1862 // we return HTCLIENT.
1863 int border_width = ::GetSystemMetrics(SM_CXSIZEFRAME);
1864 int border_height = ::GetSystemMetrics(SM_CYSIZEFRAME);
1865 int scroll_width = ::GetSystemMetrics(SM_CXVSCROLL);
1866 int scroll_height = ::GetSystemMetrics(SM_CYVSCROLL);
1867 RECT window_rect;
1868 ::GetWindowRect(hwnd(), &window_rect);
1869 window_rect.bottom -= border_height;
1870 window_rect.right -= border_width;
1871 window_rect.left = window_rect.right - scroll_width;
1872 window_rect.top = window_rect.bottom - scroll_height;
1873 POINT pt;
1874 pt.x = point.x();
1875 pt.y = point.y();
1876 if (::PtInRect(&window_rect, pt))
1877 hit_test_code = HTCLIENT;
1878 break;
1879 }
1880
1881 default:
1882 break;
1883 }
1884 }
1885 return hit_test_code; 1797 return hit_test_code;
1886 } 1798 }
1887 1799
1888 void HWNDMessageHandler::OnNCPaint(HRGN rgn) { 1800 void HWNDMessageHandler::OnNCPaint(HRGN rgn) {
1889 RECT window_rect; 1801 RECT window_rect;
1890 GetWindowRect(hwnd(), &window_rect); 1802 GetWindowRect(hwnd(), &window_rect);
1891 RECT dirty_region; 1803 RECT dirty_region;
1892 // A value of 1 indicates paint all. 1804 // A value of 1 indicates paint all.
1893 if (!rgn || rgn == reinterpret_cast<HRGN>(1)) { 1805 if (!rgn || rgn == reinterpret_cast<HRGN>(1)) {
1894 dirty_region.left = 0; 1806 dirty_region.left = 0;
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
2122 // this correctly. 2034 // this correctly.
2123 if (flags == SPI_SETWORKAREA) 2035 if (flags == SPI_SETWORKAREA)
2124 SendFrameChanged(); 2036 SendFrameChanged();
2125 } 2037 }
2126 2038
2127 void HWNDMessageHandler::OnSize(UINT param, const gfx::Size& size) { 2039 void HWNDMessageHandler::OnSize(UINT param, const gfx::Size& size) {
2128 RedrawWindow(hwnd(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN); 2040 RedrawWindow(hwnd(), NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
2129 // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've 2041 // ResetWindowRegion is going to trigger WM_NCPAINT. By doing it after we've
2130 // invoked OnSize we ensure the RootView has been laid out. 2042 // invoked OnSize we ensure the RootView has been laid out.
2131 ResetWindowRegion(false, true); 2043 ResetWindowRegion(false, true);
2132
2133 // We add the WS_VSCROLL and WS_HSCROLL styles to top level windows to ensure
2134 // that legacy trackpad/trackpoint drivers generate the WM_VSCROLL and
2135 // WM_HSCROLL messages and scrolling works.
2136 // We want the scroll styles to be present on the window. However we don't
2137 // want Windows to draw the scrollbars. To achieve this we hide the scroll
2138 // bars and readd them to the window style in a posted task to ensure that we
2139 // don't get nested WM_SIZE messages.
2140 if (needs_scroll_styles_ && !in_size_loop_) {
2141 ShowScrollBar(hwnd(), SB_BOTH, FALSE);
2142 base::ThreadTaskRunnerHandle::Get()->PostTask(
2143 FROM_HERE, base::Bind(&AddScrollStylesToWindow, hwnd()));
2144 }
2145 } 2044 }
2146 2045
2147 void HWNDMessageHandler::OnSysCommand(UINT notification_code, 2046 void HWNDMessageHandler::OnSysCommand(UINT notification_code,
2148 const gfx::Point& point) { 2047 const gfx::Point& point) {
2149 if (!delegate_->ShouldHandleSystemCommands()) 2048 if (!delegate_->ShouldHandleSystemCommands())
2150 return; 2049 return;
2151 2050
2152 // Windows uses the 4 lower order bits of |notification_code| for type- 2051 // Windows uses the 4 lower order bits of |notification_code| for type-
2153 // specific information so we must exclude this when comparing. 2052 // specific information so we must exclude this when comparing.
2154 static const int sc_mask = 0xFFF0; 2053 static const int sc_mask = 0xFFF0;
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
2423 LPARAM l_param, 2322 LPARAM l_param,
2424 bool track_mouse) { 2323 bool track_mouse) {
2425 // We handle touch events on Windows Aura. Windows generates synthesized 2324 // We handle touch events on Windows Aura. Windows generates synthesized
2426 // mouse messages in response to touch which we should ignore. However touch 2325 // mouse messages in response to touch which we should ignore. However touch
2427 // messages are only received for the client area. We need to ignore the 2326 // messages are only received for the client area. We need to ignore the
2428 // synthesized mouse messages for all points in the client area and places 2327 // synthesized mouse messages for all points in the client area and places
2429 // which return HTNOWHERE. 2328 // which return HTNOWHERE.
2430 // TODO(ananta) 2329 // TODO(ananta)
2431 // Windows does not reliably set the touch flag on mouse messages. Look into 2330 // Windows does not reliably set the touch flag on mouse messages. Look into
2432 // a better way of identifying mouse messages originating from touch. 2331 // a better way of identifying mouse messages originating from touch.
2433 if (ui::IsMouseEventFromTouch(message)) { 2332 if ((message != WM_MOUSEWHEEL && message != WM_MOUSEHWHEEL) &&
2333 (ui::IsMouseEventFromTouch(message))) {
2434 LPARAM l_param_ht = l_param; 2334 LPARAM l_param_ht = l_param;
2435 // For mouse events (except wheel events), location is in window coordinates 2335 // For mouse events (except wheel events), location is in window coordinates
2436 // and should be converted to screen coordinates for WM_NCHITTEST. 2336 // and should be converted to screen coordinates for WM_NCHITTEST.
2437 if (message != WM_MOUSEWHEEL && message != WM_MOUSEHWHEEL) { 2337 POINT screen_point = CR_POINT_INITIALIZER_FROM_LPARAM(l_param_ht);
2438 POINT screen_point = CR_POINT_INITIALIZER_FROM_LPARAM(l_param_ht); 2338 MapWindowPoints(hwnd(), HWND_DESKTOP, &screen_point, 1);
2439 MapWindowPoints(hwnd(), HWND_DESKTOP, &screen_point, 1); 2339 l_param_ht = MAKELPARAM(screen_point.x, screen_point.y);
2440 l_param_ht = MAKELPARAM(screen_point.x, screen_point.y); 2340
2441 }
2442 LRESULT hittest = SendMessage(hwnd(), WM_NCHITTEST, 0, l_param_ht); 2341 LRESULT hittest = SendMessage(hwnd(), WM_NCHITTEST, 0, l_param_ht);
2443 if (hittest == HTCLIENT || hittest == HTNOWHERE) 2342 if (hittest == HTCLIENT || hittest == HTNOWHERE)
2444 return 0; 2343 return 0;
2445 } 2344 }
2446 2345
2447 // Certain logitech drivers send the WM_MOUSEHWHEEL message to the parent 2346 // Certain logitech drivers send the WM_MOUSEHWHEEL message to the parent
2448 // followed by WM_MOUSEWHEEL messages to the child window causing a vertical 2347 // followed by WM_MOUSEWHEEL messages to the child window causing a vertical
2449 // scroll. We treat these WM_MOUSEWHEEL messages as WM_MOUSEHWHEEL 2348 // scroll. We treat these WM_MOUSEWHEEL messages as WM_MOUSEHWHEEL
2450 // messages. 2349 // messages.
2451 if (message == WM_MOUSEHWHEEL) 2350 if (message == WM_MOUSEHWHEEL)
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after
2758 MONITORINFO monitor_info = {sizeof(monitor_info)}; 2657 MONITORINFO monitor_info = {sizeof(monitor_info)};
2759 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY), 2658 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTOPRIMARY),
2760 &monitor_info); 2659 &monitor_info);
2761 gfx::Rect shrunk_rect(monitor_info.rcMonitor); 2660 gfx::Rect shrunk_rect(monitor_info.rcMonitor);
2762 shrunk_rect.set_height(shrunk_rect.height() - 1); 2661 shrunk_rect.set_height(shrunk_rect.height() - 1);
2763 background_fullscreen_hack_ = true; 2662 background_fullscreen_hack_ = true;
2764 SetBoundsInternal(shrunk_rect, false); 2663 SetBoundsInternal(shrunk_rect, false);
2765 } 2664 }
2766 2665
2767 } // namespace views 2666 } // 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