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

Side by Side Diff: views/focus/focus_util_win.cc

Issue 7753025: Move the mouse wheel utils from views to ui\base\win, to get rid of some views dependencies in co... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 9 years, 3 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 | Annotate | Revision Log
« no previous file with comments | « views/focus/focus_util_win.h ('k') | views/views.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "views/focus/focus_util_win.h"
6
7 #include <windowsx.h>
8
9 #include "base/auto_reset.h"
10 #include "ui/base/view_prop.h"
11 #include "ui/base/win/hwnd_util.h"
12
13 using ui::ViewProp;
14
15 namespace views {
16
17 // Property used to indicate the HWND supports having mouse wheel messages
18 // rerouted to it.
19 static const char* const kHWNDSupportMouseWheelRerouting =
20 "__HWND_MW_REROUTE_OK";
21
22 static bool WindowSupportsRerouteMouseWheel(HWND window) {
23 while (GetWindowLong(window, GWL_STYLE) & WS_CHILD) {
24 if (!IsWindow(window))
25 break;
26
27 if (reinterpret_cast<bool>(
28 ViewProp::GetValue(window, kHWNDSupportMouseWheelRerouting))) {
29 return true;
30 }
31 window = GetParent(window);
32 }
33 return false;
34 }
35
36 static bool IsCompatibleWithMouseWheelRedirection(HWND window) {
37 std::wstring class_name = ui::GetClassName(window);
38 // Mousewheel redirection to comboboxes is a surprising and
39 // undesireable user behavior.
40 return !(class_name == L"ComboBox" ||
41 class_name == L"ComboBoxEx32");
42 }
43
44 static bool CanRedirectMouseWheelFrom(HWND window) {
45 std::wstring class_name = ui::GetClassName(window);
46
47 // Older Thinkpad mouse wheel drivers create a window under mouse wheel
48 // pointer. Detect if we are dealing with this window. In this case we
49 // don't need to do anything as the Thinkpad mouse driver will send
50 // mouse wheel messages to the right window.
51 if ((class_name == L"Syn Visual Class") ||
52 (class_name == L"SynTrackCursorWindowClass"))
53 return false;
54
55 return true;
56 }
57
58 ViewProp* SetWindowSupportsRerouteMouseWheel(HWND hwnd) {
59 return new ViewProp(hwnd, kHWNDSupportMouseWheelRerouting,
60 reinterpret_cast<HANDLE>(true));
61 }
62
63 bool RerouteMouseWheel(HWND window, WPARAM w_param, LPARAM l_param) {
64 // Since this is called from a subclass for every window, we can get
65 // here recursively. This will happen if, for example, a control
66 // reflects wheel scroll messages to its parent. Bail out if we got
67 // here recursively.
68 static bool recursion_break = false;
69 if (recursion_break)
70 return false;
71 // Check if this window's class has a bad interaction with rerouting.
72 if (!IsCompatibleWithMouseWheelRedirection(window))
73 return false;
74
75 DWORD current_process = GetCurrentProcessId();
76 POINT wheel_location = { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) };
77 HWND window_under_wheel = WindowFromPoint(wheel_location);
78
79 if (!CanRedirectMouseWheelFrom(window_under_wheel))
80 return false;
81
82 // Find the lowest Chrome window in the hierarchy that can be the
83 // target of mouse wheel redirection.
84 while (window != window_under_wheel) {
85 // If window_under_wheel is not a valid Chrome window, then return true to
86 // suppress further processing of the message.
87 if (!::IsWindow(window_under_wheel))
88 return true;
89 DWORD wheel_window_process = 0;
90 GetWindowThreadProcessId(window_under_wheel, &wheel_window_process);
91 if (current_process != wheel_window_process) {
92 if (IsChild(window, window_under_wheel)) {
93 // If this message is reflected from a child window in a different
94 // process (happens with out of process windowed plugins) then
95 // we don't want to reroute the wheel message.
96 return false;
97 } else {
98 // The wheel is scrolling over an unrelated window. Make sure that we
99 // have marked that window as supporting mouse wheel rerouting.
100 // Otherwise, we cannot send random WM_MOUSEWHEEL messages to arbitrary
101 // windows. So just drop the message.
102 if (!WindowSupportsRerouteMouseWheel(window_under_wheel))
103 return true;
104 }
105 }
106
107 // window_under_wheel is a Chrome window. If allowed, redirect.
108 if (IsCompatibleWithMouseWheelRedirection(window_under_wheel)) {
109 AutoReset<bool> auto_reset_recursion_break(&recursion_break, true);
110 SendMessage(window_under_wheel, WM_MOUSEWHEEL, w_param, l_param);
111 return true;
112 }
113 // If redirection is disallowed, try the parent.
114 window_under_wheel = GetAncestor(window_under_wheel, GA_PARENT);
115 }
116 // If we traversed back to the starting point, we should process
117 // this message normally; return false.
118 return false;
119 }
120
121 } // namespace views
OLDNEW
« no previous file with comments | « views/focus/focus_util_win.h ('k') | views/views.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698