Index: views/events/event_win.cc |
diff --git a/views/events/event_win.cc b/views/events/event_win.cc |
index b79f83907d5cc67123bb39c6ecc6fdbf0d9058ef..11f63ec3e2affa91ec125e6a85fd27527d598674 100644 |
--- a/views/events/event_win.cc |
+++ b/views/events/event_win.cc |
@@ -18,12 +18,9 @@ namespace { |
// as with mouse messages, so we need to explicitly ask for these states. |
int GetKeyStateFlags() { |
int flags = 0; |
- if (GetKeyState(VK_MENU) & 0x80) |
- flags |= ui::EF_ALT_DOWN; |
- if (GetKeyState(VK_SHIFT) & 0x80) |
- flags |= ui::EF_SHIFT_DOWN; |
- if (GetKeyState(VK_CONTROL) & 0x80) |
- flags |= ui::EF_CONTROL_DOWN; |
+ flags |= (GetKeyState(VK_MENU) & 0x80)? ui::EF_ALT_DOWN : 0; |
+ flags |= (GetKeyState(VK_SHIFT) & 0x80)? ui::EF_SHIFT_DOWN : 0; |
+ flags |= (GetKeyState(VK_CONTROL) & 0x80)? ui::EF_CONTROL_DOWN : 0; |
return flags; |
} |
@@ -71,10 +68,81 @@ ui::EventType EventTypeFromNative(NativeEvent native_event) { |
return ui::ET_UNKNOWN; |
} |
-int GetFlagsFromNative(NativeEvent native_event) { |
- // Allow other applicable messages as necessary. |
- DCHECK(native_event.message == WM_MOUSEWHEEL); |
- return Event::ConvertWindowsFlags(GET_KEYSTATE_WPARAM(native_event.wParam)); |
+bool IsClientMouseEvent(NativeEvent native_event) { |
+ return native_event.message == WM_MOUSELEAVE || |
+ native_event.message == WM_MOUSEHOVER || |
+ (native_event.message >= WM_MOUSEFIRST && |
+ native_event.message <= WM_MOUSELAST); |
+} |
+ |
+bool IsNonClientMouseEvent(NativeEvent native_event) { |
+ return native_event.message == WM_NCMOUSELEAVE || |
+ native_event.message == WM_NCMOUSEHOVER || |
+ (native_event.message >= WM_NCMOUSEMOVE && |
+ native_event.message <= WM_NCXBUTTONDBLCLK); |
+} |
+ |
+// Get views::Event flags from a native Windows message |
+int EventFlagsFromNative(NativeEvent native_event) { |
+ int flags = 0; |
+ |
+ // TODO(msw): ORing the pressed/released button into the flags is _wrong_. |
+ // It makes it impossible to tell which button was modified when multiple |
+ // buttons are/were held down. We need to instead put the modified button into |
+ // a separate member on the MouseEvent, then audit all consumers of |
+ // MouseEvents to fix them to use the resulting values correctly. |
+ switch (native_event.message) { |
+ case WM_LBUTTONDBLCLK: |
+ case WM_LBUTTONDOWN: |
+ case WM_LBUTTONUP: |
+ case WM_NCLBUTTONDBLCLK: |
+ case WM_NCLBUTTONDOWN: |
+ case WM_NCLBUTTONUP: |
+ native_event.wParam |= MK_LBUTTON; |
+ break; |
+ case WM_MBUTTONDBLCLK: |
+ case WM_MBUTTONDOWN: |
+ case WM_MBUTTONUP: |
+ case WM_NCMBUTTONDBLCLK: |
+ case WM_NCMBUTTONDOWN: |
+ case WM_NCMBUTTONUP: |
+ native_event.wParam |= MK_MBUTTON; |
+ break; |
+ case WM_RBUTTONDBLCLK: |
+ case WM_RBUTTONDOWN: |
+ case WM_RBUTTONUP: |
+ case WM_NCRBUTTONDBLCLK: |
+ case WM_NCRBUTTONDOWN: |
+ case WM_NCRBUTTONUP: |
+ native_event.wParam |= MK_RBUTTON; |
+ break; |
+ } |
+ |
+ // Check if the event occurred in the non-client area. |
+ if (IsNonClientMouseEvent(native_event)) |
+ flags |= ui::EF_IS_NON_CLIENT; |
+ |
+ // Check for double click events. |
+ switch (native_event.message) { |
+ case WM_NCLBUTTONDBLCLK: |
+ case WM_NCMBUTTONDBLCLK: |
+ case WM_NCRBUTTONDBLCLK: |
+ case WM_LBUTTONDBLCLK: |
+ case WM_MBUTTONDBLCLK: |
+ case WM_RBUTTONDBLCLK: |
+ flags |= ui::EF_IS_DOUBLE_CLICK; |
+ break; |
+ } |
+ |
+ UINT win_flags = GET_KEYSTATE_WPARAM(native_event.wParam); |
+ flags |= (win_flags & MK_CONTROL) ? ui::EF_CONTROL_DOWN : 0; |
+ flags |= (win_flags & MK_SHIFT) ? ui::EF_SHIFT_DOWN : 0; |
+ flags |= (GetKeyState(VK_MENU) < 0) ? ui::EF_ALT_DOWN : 0; |
+ flags |= (win_flags & MK_LBUTTON) ? ui::EF_LEFT_BUTTON_DOWN : 0; |
+ flags |= (win_flags & MK_MBUTTON) ? ui::EF_MIDDLE_BUTTON_DOWN : 0; |
+ flags |= (win_flags & MK_RBUTTON) ? ui::EF_RIGHT_BUTTON_DOWN : 0; |
+ |
+ return flags; |
} |
} // namespace |
@@ -93,24 +161,6 @@ int Event::GetWindowsFlags() const { |
return result; |
} |
-//static |
-int Event::ConvertWindowsFlags(UINT win_flags) { |
- int r = 0; |
- if (win_flags & MK_CONTROL) |
- r |= ui::EF_CONTROL_DOWN; |
- if (win_flags & MK_SHIFT) |
- r |= ui::EF_SHIFT_DOWN; |
- if (GetKeyState(VK_MENU) < 0) |
- r |= ui::EF_ALT_DOWN; |
- if (win_flags & MK_LBUTTON) |
- r |= ui::EF_LEFT_BUTTON_DOWN; |
- if (win_flags & MK_MBUTTON) |
- r |= ui::EF_MIDDLE_BUTTON_DOWN; |
- if (win_flags & MK_RBUTTON) |
- r |= ui::EF_RIGHT_BUTTON_DOWN; |
- return r; |
-} |
- |
//////////////////////////////////////////////////////////////////////////////// |
// Event, private: |
@@ -138,7 +188,7 @@ void Event::InitWithNativeEvent2(NativeEvent2 native_event_2, |
LocatedEvent::LocatedEvent(NativeEvent native_event) |
: Event(native_event, EventTypeFromNative(native_event), |
- GetFlagsFromNative(native_event)), |
+ EventFlagsFromNative(native_event)), |
location_(native_event.pt.x, native_event.pt.y) { |
} |
@@ -168,16 +218,38 @@ KeyEvent::KeyEvent(NativeEvent2 native_event_2, FromNativeEvent2 from_native) |
} |
//////////////////////////////////////////////////////////////////////////////// |
+// MouseEvent, public: |
+ |
+MouseEvent::MouseEvent(NativeEvent native_event) |
+ : LocatedEvent(native_event) { |
+ if (IsNonClientMouseEvent(native_event)) { |
+ // Non-client message. The position is contained in a POINTS structure in |
+ // LPARAM, and is in screen coordinates so we have to convert to client. |
+ POINT native_point = location_.ToPOINT(); |
+ ScreenToClient(native_event.hwnd, &native_point); |
+ location_ = gfx::Point(native_point); |
+ } |
+} |
+ |
+MouseEvent::MouseEvent(NativeEvent2 native_event_2, |
+ FromNativeEvent2 from_native) |
+ : LocatedEvent(native_event_2, from_native) { |
+ // No one should ever call this on Windows. |
+ // TODO(msw): remove once we rid views of Gtk/Gdk. |
+ NOTREACHED(); |
+} |
+ |
+//////////////////////////////////////////////////////////////////////////////// |
// MouseWheelEvent, public: |
MouseWheelEvent::MouseWheelEvent(NativeEvent native_event) |
- : LocatedEvent(native_event), |
+ : MouseEvent(native_event), |
offset_(GET_WHEEL_DELTA_WPARAM(native_event.wParam)) { |
} |
MouseWheelEvent::MouseWheelEvent(NativeEvent2 native_event_2, |
FromNativeEvent2 from_native) |
- : LocatedEvent(native_event_2, from_native) { |
+ : MouseEvent(native_event_2, from_native) { |
// No one should ever call this on Windows. |
// TODO(msw): remove once we rid views of Gtk/Gdk. |
NOTREACHED(); |