summaryrefslogtreecommitdiffstats
path: root/chrome/views
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-25 22:05:11 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-25 22:05:11 +0000
commitc9d989b20d74fcd1de89d5aad90f5ad11d11801c (patch)
tree8e0d7b90a6810033316b54ba57ba4de1417cb309 /chrome/views
parentcdd24e1db2da2fa61261ff78278ce2961a320b84 (diff)
downloadchromium_src-c9d989b20d74fcd1de89d5aad90f5ad11d11801c.zip
chromium_src-c9d989b20d74fcd1de89d5aad90f5ad11d11801c.tar.gz
chromium_src-c9d989b20d74fcd1de89d5aad90f5ad11d11801c.tar.bz2
Reverting 12498.
Review URL: http://codereview.chromium.org/53073 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12500 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/views')
-rw-r--r--chrome/views/focus/focus_manager.cc107
-rw-r--r--chrome/views/focus/focus_util_win.cc116
-rw-r--r--chrome/views/focus/focus_util_win.h26
-rw-r--r--chrome/views/views.vcproj8
-rw-r--r--chrome/views/widget/widget_win.cc21
-rw-r--r--chrome/views/widget/widget_win.h4
6 files changed, 115 insertions, 167 deletions
diff --git a/chrome/views/focus/focus_manager.cc b/chrome/views/focus/focus_manager.cc
index d8fb23f..e11d43f 100644
--- a/chrome/views/focus/focus_manager.cc
+++ b/chrome/views/focus/focus_manager.cc
@@ -43,6 +43,109 @@ static const wchar_t* const kFocusSubclassInstalled =
namespace views {
+static bool IsCompatibleWithMouseWheelRedirection(HWND window) {
+ std::wstring class_name = win_util::GetClassName(window);
+ // Mousewheel redirection to comboboxes is a surprising and
+ // undesireable user behavior.
+ return !(class_name == L"ComboBox" ||
+ class_name == L"ComboBoxEx32");
+}
+
+static bool CanRedirectMouseWheelFrom(HWND window) {
+ std::wstring class_name = win_util::GetClassName(window);
+
+ // Older Thinkpad mouse wheel drivers create a window under mouse wheel
+ // pointer. Detect if we are dealing with this window. In this case we
+ // don't need to do anything as the Thinkpad mouse driver will send
+ // mouse wheel messages to the right window.
+ if ((class_name == L"Syn Visual Class") ||
+ (class_name == L"SynTrackCursorWindowClass"))
+ return false;
+
+ return true;
+}
+
+bool IsPluginWindow(HWND window) {
+ HWND current_window = window;
+ while (GetWindowLong(current_window, GWL_STYLE) & WS_CHILD) {
+ current_window = GetParent(current_window);
+ if (!IsWindow(current_window))
+ break;
+
+ std::wstring class_name = win_util::GetClassName(current_window);
+ if (class_name == kRenderWidgetHostHWNDClass)
+ return true;
+ }
+
+ return false;
+}
+
+// Forwards mouse wheel messages to the window under it.
+// Windows sends mouse wheel messages to the currently active window.
+// This causes a window to scroll even if it is not currently under the
+// mouse wheel. The following code gives mouse wheel messages to the
+// window under the mouse wheel in order to scroll that window. This
+// is arguably a better user experience. The returns value says whether
+// the mouse wheel message was successfully redirected.
+static bool RerouteMouseWheel(HWND window, WPARAM wParam, LPARAM lParam) {
+ // Since this is called from a subclass for every window, we can get
+ // here recursively. This will happen if, for example, a control
+ // reflects wheel scroll messages to its parent. Bail out if we got
+ // here recursively.
+ static bool recursion_break = false;
+ if (recursion_break)
+ return false;
+ // Check if this window's class has a bad interaction with rerouting.
+ if (!IsCompatibleWithMouseWheelRedirection(window))
+ return false;
+
+ DWORD current_process = GetCurrentProcessId();
+ POINT wheel_location = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+ HWND window_under_wheel = WindowFromPoint(wheel_location);
+
+ if (!CanRedirectMouseWheelFrom(window_under_wheel))
+ return false;
+
+ // Find the lowest Chrome window in the hierarchy that can be the
+ // target of mouse wheel redirection.
+ while (window != window_under_wheel) {
+ // If window_under_wheel is not a valid Chrome window, then return
+ // true to suppress further processing of the message.
+ if (!::IsWindow(window_under_wheel))
+ return true;
+ DWORD wheel_window_process = 0;
+ GetWindowThreadProcessId(window_under_wheel, &wheel_window_process);
+ if (current_process != wheel_window_process) {
+ if (IsChild(window, window_under_wheel)) {
+ // If this message is reflected from a child window in a different
+ // process (happens with out of process windowed plugins) then
+ // we don't want to reroute the wheel message.
+ return false;
+ } else {
+ // The wheel is scrolling over an unrelated window. If that window
+ // is a plugin window in a different chrome then we can send it a
+ // WM_MOUSEWHEEL. Otherwise, we cannot send random WM_MOUSEWHEEL
+ // messages to arbitrary windows. So just drop the message.
+ if (!IsPluginWindow(window_under_wheel))
+ return true;
+ }
+ }
+
+ // window_under_wheel is a Chrome window. If allowed, redirect.
+ if (IsCompatibleWithMouseWheelRedirection(window_under_wheel)) {
+ recursion_break = true;
+ SendMessage(window_under_wheel, WM_MOUSEWHEEL, wParam, lParam);
+ recursion_break = false;
+ return true;
+ }
+ // If redirection is disallowed, try the parent.
+ window_under_wheel = GetAncestor(window_under_wheel, GA_PARENT);
+ }
+ // If we traversed back to the starting point, we should process
+ // this message normally; return false.
+ return false;
+}
+
// Callback installed via InstallFocusSubclass.
static LRESULT CALLBACK FocusWindowCallback(HWND window, UINT message,
WPARAM wParam, LPARAM lParam) {
@@ -84,6 +187,10 @@ static LRESULT CALLBACK FocusWindowCallback(HWND window, UINT message,
return 0;
return result;
}
+ case WM_MOUSEWHEEL:
+ if (RerouteMouseWheel(window, wParam, lParam))
+ return 0;
+ break;
case WM_IME_CHAR:
// Issue 7707: A rich-edit control may crash when it receives a
// WM_IME_CHAR message while it is processing a WM_IME_COMPOSITION
diff --git a/chrome/views/focus/focus_util_win.cc b/chrome/views/focus/focus_util_win.cc
deleted file mode 100644
index ec77519..0000000
--- a/chrome/views/focus/focus_util_win.cc
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/views/focus/focus_util_win.h"
-
-#include "base/win_util.h"
-
-namespace views {
-
-// Property used to indicate the HWND supports having mouse wheel messages
-// rerouted to it.
-static const wchar_t* const kHWNDSupportMouseWheelRerouting =
- L"__HWND_MW_REROUTE_OK";
-
-static bool WindowSupportsRerouteMouseWheel(HWND window) {
- while (GetWindowLong(window, GWL_STYLE) & WS_CHILD) {
- if (!IsWindow(window))
- break;
-
- if (reinterpret_cast<bool>(GetProp(window,
- kHWNDSupportMouseWheelRerouting))) {
- return true;
- }
- window = GetParent(window);
- }
- return false;
-}
-
-static bool IsCompatibleWithMouseWheelRedirection(HWND window) {
- std::wstring class_name = win_util::GetClassName(window);
- // Mousewheel redirection to comboboxes is a surprising and
- // undesireable user behavior.
- return !(class_name == L"ComboBox" ||
- class_name == L"ComboBoxEx32");
-}
-
-static bool CanRedirectMouseWheelFrom(HWND window) {
- std::wstring class_name = win_util::GetClassName(window);
-
- // Older Thinkpad mouse wheel drivers create a window under mouse wheel
- // pointer. Detect if we are dealing with this window. In this case we
- // don't need to do anything as the Thinkpad mouse driver will send
- // mouse wheel messages to the right window.
- if ((class_name == L"Syn Visual Class") ||
- (class_name == L"SynTrackCursorWindowClass"))
- return false;
-
- return true;
-}
-
-void SetWindowSupportsRerouteMouseWheel(HWND hwnd) {
- SetProp(hwnd, kHWNDSupportMouseWheelRerouting,
- reinterpret_cast<HANDLE>(true));
-}
-
-bool RerouteMouseWheel(HWND window, WPARAM w_param, LPARAM l_param) {
- // Since this is called from a subclass for every window, we can get
- // here recursively. This will happen if, for example, a control
- // reflects wheel scroll messages to its parent. Bail out if we got
- // here recursively.
- static bool recursion_break = false;
- if (recursion_break)
- return false;
- // Check if this window's class has a bad interaction with rerouting.
- if (!IsCompatibleWithMouseWheelRedirection(window))
- return false;
-
- DWORD current_process = GetCurrentProcessId();
- POINT wheel_location = { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) };
- HWND window_under_wheel = WindowFromPoint(wheel_location);
-
- if (!CanRedirectMouseWheelFrom(window_under_wheel))
- return false;
-
- // Find the lowest Chrome window in the hierarchy that can be the
- // target of mouse wheel redirection.
- while (window != window_under_wheel) {
- // If window_under_wheel is not a valid Chrome window, then return true to
- // suppress further processing of the message.
- if (!::IsWindow(window_under_wheel))
- return true;
- DWORD wheel_window_process = 0;
- GetWindowThreadProcessId(window_under_wheel, &wheel_window_process);
- if (current_process != wheel_window_process) {
- if (IsChild(window, window_under_wheel)) {
- // If this message is reflected from a child window in a different
- // process (happens with out of process windowed plugins) then
- // we don't want to reroute the wheel message.
- return false;
- } else {
- // The wheel is scrolling over an unrelated window. Make sure that we
- // have marked that window as supporting mouse wheel rerouting.
- // Otherwise, we cannot send random WM_MOUSEWHEEL messages to arbitrary
- // windows. So just drop the message.
- if (!WindowSupportsRerouteMouseWheel(window_under_wheel))
- return true;
- }
- }
-
- // window_under_wheel is a Chrome window. If allowed, redirect.
- if (IsCompatibleWithMouseWheelRedirection(window_under_wheel)) {
- recursion_break = true;
- SendMessage(window_under_wheel, WM_MOUSEWHEEL, w_param, l_param);
- recursion_break = false;
- return true;
- }
- // If redirection is disallowed, try the parent.
- window_under_wheel = GetAncestor(window_under_wheel, GA_PARENT);
- }
- // If we traversed back to the starting point, we should process
- // this message normally; return false.
- return false;
-}
-
-} // namespace views
diff --git a/chrome/views/focus/focus_util_win.h b/chrome/views/focus/focus_util_win.h
deleted file mode 100644
index b7a8625..0000000
--- a/chrome/views/focus/focus_util_win.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_VIEWS_FOCUS_FOCUS_UTIL_WIN_H_
-#define CHROME_VIEWS_FOCUS_FOCUS_UTIL_WIN_H_
-
-namespace views {
-
-// Marks the passed |hwnd| as supporting mouse-wheel message rerouting.
-// We reroute the mouse wheel messages to such HWND when they are under the
-// mouse pointer (but are not the active window)
-void SetWindowSupportsRerouteMouseWheel(HWND hwnd);
-
-// Forwards mouse wheel messages to the window under it.
-// Windows sends mouse wheel messages to the currently active window.
-// This causes a window to scroll even if it is not currently under the mouse
-// wheel. The following code gives mouse wheel messages to the window under the
-// mouse wheel in order to scroll that window. This is arguably a better user
-// experience. The returns value says whether the mouse wheel message was
-// successfully redirected.
-bool RerouteMouseWheel(HWND window, WPARAM w_param, LPARAM l_param);
-
-} // namespace views
-
-#endif // CHROME_VIEWS_FOCUS_FOCUS_UTIL_WIN_H_
diff --git a/chrome/views/views.vcproj b/chrome/views/views.vcproj
index 52ca5af..29cf7bd 100644
--- a/chrome/views/views.vcproj
+++ b/chrome/views/views.vcproj
@@ -431,14 +431,6 @@
>
</File>
<File
- RelativePath=".\focus\focus_util_win.cc"
- >
- </File>
- <File
- RelativePath=".\focus\focus_util_win.h"
- >
- </File>
- <File
RelativePath=".\focus\view_storage.cc"
>
</File>
diff --git a/chrome/views/widget/widget_win.cc b/chrome/views/widget/widget_win.cc
index d4397c7..2faab37 100644
--- a/chrome/views/widget/widget_win.cc
+++ b/chrome/views/widget/widget_win.cc
@@ -14,7 +14,6 @@
#include "chrome/views/accessibility/view_accessibility.h"
#include "chrome/views/controls/native_control_win.h"
#include "chrome/views/fill_layout.h"
-#include "chrome/views/focus/focus_util_win.h"
#include "chrome/views/widget/aero_tooltip_manager.h"
#include "chrome/views/widget/hwnd_notification_source.h"
#include "chrome/views/widget/root_view.h"
@@ -149,7 +148,6 @@ void WidgetWin::Init(HWND parent, const gfx::Rect& bounds,
bounds.height(), parent, NULL, NULL, this);
DCHECK(hwnd_);
TRACK_HWND_CREATION(hwnd_);
- SetWindowSupportsRerouteMouseWheel(hwnd_);
// The window procedure should have set the data for us.
DCHECK(win_util::GetWindowUserData(hwnd_) == this);
@@ -559,19 +557,12 @@ LRESULT WidgetWin::OnMouseLeave(UINT message, WPARAM w_param, LPARAM l_param) {
return 0;
}
-LRESULT WidgetWin::OnMouseWheel(UINT message, WPARAM w_param, LPARAM l_param) {
- // Reroute the mouse-wheel to the window under the mouse pointer if
- // applicable.
- if (message == WM_MOUSEWHEEL &&
- views::RerouteMouseWheel(hwnd_, w_param, l_param)) {
- return 0;
- }
-
- int flags = GET_KEYSTATE_WPARAM(w_param);
- short distance = GET_WHEEL_DELTA_WPARAM(w_param);
- int x = GET_X_LPARAM(l_param);
- int y = GET_Y_LPARAM(l_param);
- MouseWheelEvent e(distance, x, y, Event::ConvertWindowsFlags(flags));
+LRESULT WidgetWin::OnMouseWheel(UINT flags, short distance,
+ const CPoint& point) {
+ MouseWheelEvent e(distance,
+ point.x,
+ point.y,
+ Event::ConvertWindowsFlags(flags));
return root_view_->ProcessMouseWheelEvent(e) ? 0 : 1;
}
diff --git a/chrome/views/widget/widget_win.h b/chrome/views/widget/widget_win.h
index 38dc730..aa88b08 100644
--- a/chrome/views/widget/widget_win.h
+++ b/chrome/views/widget/widget_win.h
@@ -162,7 +162,6 @@ class WidgetWin : public Widget,
MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject)
MESSAGE_HANDLER_EX(WM_NCMOUSELEAVE, OnNCMouseLeave)
MESSAGE_HANDLER_EX(WM_MOUSELEAVE, OnMouseLeave)
- MESSAGE_HANDLER_EX(WM_MOUSEWHEEL, OnMouseWheel)
// This list is in _ALPHABETICAL_ order! OR I WILL HURT YOU.
MSG_WM_ACTIVATE(OnActivate)
@@ -193,6 +192,7 @@ class WidgetWin : public Widget,
MSG_WM_MBUTTONDBLCLK(OnMButtonDblClk)
MSG_WM_MOUSEACTIVATE(OnMouseActivate)
MSG_WM_MOUSEMOVE(OnMouseMove)
+ MSG_WM_MOUSEWHEEL(OnMouseWheel)
MSG_WM_MOVE(OnMove)
MSG_WM_MOVING(OnMoving)
MSG_WM_NCACTIVATE(OnNCActivate)
@@ -384,9 +384,9 @@ class WidgetWin : public Widget,
virtual LRESULT OnMouseActivate(HWND window, UINT hittest_code, UINT message);
virtual void OnMouseMove(UINT flags, const CPoint& point);
virtual LRESULT OnMouseLeave(UINT message, WPARAM w_param, LPARAM l_param);
- virtual LRESULT OnMouseWheel(UINT message, WPARAM w_param, LPARAM l_param);
virtual void OnMove(const CPoint& point) { SetMsgHandled(FALSE); }
virtual void OnMoving(UINT param, const LPRECT new_bounds) { }
+ virtual LRESULT OnMouseWheel(UINT flags, short distance, const CPoint& point);
virtual LRESULT OnMouseRange(UINT msg, WPARAM w_param, LPARAM l_param);
virtual LRESULT OnNCActivate(BOOL active) { SetMsgHandled(FALSE); return 0; }
virtual LRESULT OnNCCalcSize(BOOL w_param, LPARAM l_param) {