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

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_win.cc

Issue 8341125: Forward Windows touch messages to the renderer (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "content/browser/renderer_host/render_widget_host_view_win.h" 5 #include "content/browser/renderer_host/render_widget_host_view_win.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/i18n/rtl.h" 10 #include "base/i18n/rtl.h"
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 result.windowX = result.x; 283 result.windowX = result.x;
284 result.windowY = result.y; 284 result.windowY = result.y;
285 // Note that we support diagonal scrolling. 285 // Note that we support diagonal scrolling.
286 result.deltaX = static_cast<float>(delta.x); 286 result.deltaX = static_cast<float>(delta.x);
287 result.wheelTicksX = WHEEL_DELTA; 287 result.wheelTicksX = WHEEL_DELTA;
288 result.deltaY = static_cast<float>(delta.y); 288 result.deltaY = static_cast<float>(delta.y);
289 result.wheelTicksY = WHEEL_DELTA; 289 result.wheelTicksY = WHEEL_DELTA;
290 return result; 290 return result;
291 } 291 }
292 292
293 static const int kTouchMask = 0x7;
294
295 inline int GetTouchType(const TOUCHINPUT& point) {
ananta 2011/11/10 22:31:15 These functions can be moved to the new class?
296 return point.dwFlags & kTouchMask;
297 }
298
299 inline void SetTouchType(TOUCHINPUT* point, int type) {
300 point->dwFlags = (point->dwFlags & kTouchMask) | type;
301 }
302
293 } // namespace 303 } // namespace
294 304
295 /////////////////////////////////////////////////////////////////////////////// 305 ///////////////////////////////////////////////////////////////////////////////
296 // RenderWidgetHostViewWin, public: 306 // RenderWidgetHostViewWin, public:
297 307
298 RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) 308 RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget)
299 : render_widget_host_(widget), 309 : render_widget_host_(widget),
300 compositor_host_window_(NULL), 310 compositor_host_window_(NULL),
301 hide_compositor_window_at_next_paint_(false), 311 hide_compositor_window_at_next_paint_(false),
302 track_mouse_leave_(false), 312 track_mouse_leave_(false),
303 ime_notification_(false), 313 ime_notification_(false),
304 capture_enter_key_(false), 314 capture_enter_key_(false),
305 is_hidden_(false), 315 is_hidden_(false),
306 about_to_validate_and_paint_(false), 316 about_to_validate_and_paint_(false),
307 close_on_deactivate_(false), 317 close_on_deactivate_(false),
308 being_destroyed_(false), 318 being_destroyed_(false),
309 tooltip_hwnd_(NULL), 319 tooltip_hwnd_(NULL),
310 tooltip_showing_(false), 320 tooltip_showing_(false),
311 shutdown_factory_(this), 321 shutdown_factory_(this),
312 parent_hwnd_(NULL), 322 parent_hwnd_(NULL),
313 is_loading_(false), 323 is_loading_(false),
314 overlay_color_(0), 324 overlay_color_(0),
315 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), 325 text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
316 is_fullscreen_(false), 326 is_fullscreen_(false),
317 ignore_mouse_movement_(true), 327 ignore_mouse_movement_(true),
318 composition_range_(ui::Range::InvalidRange()), 328 composition_range_(ui::Range::InvalidRange()),
319 ignore_next_lbutton_message_at_same_location(false), 329 ignore_next_lbutton_message_at_same_location(false),
320 last_pointer_down_location_(0) { 330 last_pointer_down_location_(0),
331 touch_state_(this) {
321 render_widget_host_->SetView(this); 332 render_widget_host_->SetView(this);
322 registrar_.Add(this, 333 registrar_.Add(this,
323 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 334 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
324 content::NotificationService::AllBrowserContextsAndSources()); 335 content::NotificationService::AllBrowserContextsAndSources());
325 } 336 }
326 337
327 RenderWidgetHostViewWin::~RenderWidgetHostViewWin() { 338 RenderWidgetHostViewWin::~RenderWidgetHostViewWin() {
328 UnlockMouse(); 339 UnlockMouse();
329 ResetTooltip(); 340 ResetTooltip();
330 } 341 }
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 883
873 LRESULT RenderWidgetHostViewWin::OnCreate(CREATESTRUCT* create_struct) { 884 LRESULT RenderWidgetHostViewWin::OnCreate(CREATESTRUCT* create_struct) {
874 // Call the WM_INPUTLANGCHANGE message handler to initialize the input locale 885 // Call the WM_INPUTLANGCHANGE message handler to initialize the input locale
875 // of a browser process. 886 // of a browser process.
876 OnInputLangChange(0, 0); 887 OnInputLangChange(0, 0);
877 // Marks that window as supporting mouse-wheel messages rerouting so it is 888 // Marks that window as supporting mouse-wheel messages rerouting so it is
878 // scrolled when under the mouse pointer even if inactive. 889 // scrolled when under the mouse pointer even if inactive.
879 props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(m_hWnd)); 890 props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(m_hWnd));
880 891
881 if (base::win::GetVersion() >= base::win::VERSION_WIN7) { 892 if (base::win::GetVersion() >= base::win::VERSION_WIN7) {
882 // Single finger panning is consistent with other windows applications. 893 // Use gestures if touch event switch isn't present or registration fails.
883 const DWORD gesture_allow = GC_PAN_WITH_SINGLE_FINGER_VERTICALLY | 894 if (!CommandLine::ForCurrentProcess()->HasSwitch(
884 GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; 895 switches::kEnableTouchEvents) ||
885 const DWORD gesture_block = GC_PAN_WITH_GUTTER; 896 !RegisterTouchWindow(m_hWnd, 0)) {
886 GESTURECONFIG gc[] = { 897 // Single finger panning is consistent with other windows applications.
887 { GID_ZOOM, GC_ZOOM, 0 }, 898 const DWORD gesture_allow = GC_PAN_WITH_SINGLE_FINGER_VERTICALLY |
888 { GID_PAN, gesture_allow , gesture_block}, 899 GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
889 { GID_TWOFINGERTAP, GC_TWOFINGERTAP , 0}, 900 const DWORD gesture_block = GC_PAN_WITH_GUTTER;
890 { GID_PRESSANDTAP, GC_PRESSANDTAP , 0} 901 GESTURECONFIG gc[] = {
891 }; 902 { GID_ZOOM, GC_ZOOM, 0 },
892 if (!SetGestureConfig(m_hWnd, 0, arraysize(gc), gc, sizeof(GESTURECONFIG))) 903 { GID_PAN, gesture_allow , gesture_block},
893 { 904 { GID_TWOFINGERTAP, GC_TWOFINGERTAP , 0},
894 NOTREACHED(); 905 { GID_PRESSANDTAP, GC_PRESSANDTAP , 0}
906 };
907 if (!SetGestureConfig(m_hWnd, 0, arraysize(gc), gc,
908 sizeof(GESTURECONFIG))) {
909 NOTREACHED();
910 }
895 } 911 }
896 } 912 }
897 913
898 return 0; 914 return 0;
899 } 915 }
900 916
901 void RenderWidgetHostViewWin::OnActivate(UINT action, BOOL minimized, 917 void RenderWidgetHostViewWin::OnActivate(UINT action, BOOL minimized,
902 HWND window) { 918 HWND window) {
903 // If the container is a popup, clicking elsewhere on screen should close the 919 // If the container is a popup, clicking elsewhere on screen should close the
904 // popup. 920 // popup.
(...skipping 15 matching lines...) Expand all
920 // handler for NPP_DestroyStream relies on. 936 // handler for NPP_DestroyStream relies on.
921 // 937 //
922 // The fix is to detach plugin windows from web contents when it is going 938 // The fix is to detach plugin windows from web contents when it is going
923 // away. This will prevent the plugin windows from getting destroyed 939 // away. This will prevent the plugin windows from getting destroyed
924 // automatically. The detached plugin windows will get cleaned up in proper 940 // automatically. The detached plugin windows will get cleaned up in proper
925 // sequence as part of the usual cleanup when the plugin instance goes away. 941 // sequence as part of the usual cleanup when the plugin instance goes away.
926 EnumChildWindows(m_hWnd, DetachPluginWindowsCallback, NULL); 942 EnumChildWindows(m_hWnd, DetachPluginWindowsCallback, NULL);
927 943
928 props_.reset(); 944 props_.reset();
929 945
946 if (IsTouchWindow(m_hWnd, NULL))
947 UnregisterTouchWindow(m_hWnd);
948
930 CleanupCompositorWindow(); 949 CleanupCompositorWindow();
931 950
932 ResetTooltip(); 951 ResetTooltip();
933 TrackMouseLeave(false); 952 TrackMouseLeave(false);
934 } 953 }
935 954
936 void RenderWidgetHostViewWin::OnPaint(HDC unused_dc) { 955 void RenderWidgetHostViewWin::OnPaint(HDC unused_dc) {
937 if (!render_widget_host_) 956 if (!render_widget_host_)
938 return; 957 return;
939 958
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 return 0; 1114 return 0;
1096 } 1115 }
1097 1116
1098 void RenderWidgetHostViewWin::OnSetFocus(HWND window) { 1117 void RenderWidgetHostViewWin::OnSetFocus(HWND window) {
1099 if (browser_accessibility_manager_.get()) 1118 if (browser_accessibility_manager_.get())
1100 browser_accessibility_manager_->GotFocus(); 1119 browser_accessibility_manager_->GotFocus();
1101 if (render_widget_host_) { 1120 if (render_widget_host_) {
1102 render_widget_host_->GotFocus(); 1121 render_widget_host_->GotFocus();
1103 render_widget_host_->SetActive(true); 1122 render_widget_host_->SetActive(true);
1104 } 1123 }
1124 if (touch_state_.ReleaseTouchPoints())
1125 render_widget_host_->ForwardTouchEvent(touch_state_.touch_event());
1105 } 1126 }
1106 1127
1107 void RenderWidgetHostViewWin::OnKillFocus(HWND window) { 1128 void RenderWidgetHostViewWin::OnKillFocus(HWND window) {
1108 if (render_widget_host_) { 1129 if (render_widget_host_) {
1109 render_widget_host_->SetActive(false); 1130 render_widget_host_->SetActive(false);
1110 render_widget_host_->Blur(); 1131 render_widget_host_->Blur();
1111 } 1132 }
1133 if (touch_state_.ReleaseTouchPoints())
1134 render_widget_host_->ForwardTouchEvent(touch_state_.touch_event());
1112 } 1135 }
1113 1136
1114 void RenderWidgetHostViewWin::OnCaptureChanged(HWND window) { 1137 void RenderWidgetHostViewWin::OnCaptureChanged(HWND window) {
1115 if (render_widget_host_) 1138 if (render_widget_host_)
1116 render_widget_host_->LostCapture(); 1139 render_widget_host_->LostCapture();
1117 } 1140 }
1118 1141
1119 void RenderWidgetHostViewWin::OnCancelMode() { 1142 void RenderWidgetHostViewWin::OnCancelMode() {
1120 if (render_widget_host_) 1143 if (render_widget_host_)
1121 render_widget_host_->LostCapture(); 1144 render_widget_host_->LostCapture();
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
1563 1586
1564 if (!handled_by_TabContents && render_widget_host_) { 1587 if (!handled_by_TabContents && render_widget_host_) {
1565 render_widget_host_->ForwardWheelEvent( 1588 render_widget_host_->ForwardWheelEvent(
1566 WebInputEventFactory::mouseWheelEvent(m_hWnd, message, wparam, 1589 WebInputEventFactory::mouseWheelEvent(m_hWnd, message, wparam,
1567 lparam)); 1590 lparam));
1568 } 1591 }
1569 handled = TRUE; 1592 handled = TRUE;
1570 return 0; 1593 return 0;
1571 } 1594 }
1572 1595
1596 RenderWidgetHostViewWin::WebTouchState::WebTouchState(const CWindowImpl* window)
1597 : window_(window) { }
1598
1599 size_t RenderWidgetHostViewWin::WebTouchState::UpdateTouchPoints(
1600 TOUCHINPUT* points, size_t count) {
1601 // First we reset all touch event state. This involves removing any released
1602 // touchpoints and marking the rest as stationary. After that we go through
1603 // and alter/add any touchpoints (from the touch input buffer) that we can
1604 // coalesce into a single message. The return value is the number of consumed
1605 // input message.
1606 WebKit::WebTouchPoint* point = touch_event_.touches;
1607 WebKit::WebTouchPoint* end = point + touch_event_.touchesLength;
1608 while (point < end) {
1609 if (point->state == WebKit::WebTouchPoint::StateReleased) {
1610 *point = *(--end);
1611 --touch_event_.touchesLength;
1612 } else {
1613 point->state = WebKit::WebTouchPoint::StateStationary;
1614 point++;
1615 }
1616 }
1617 touch_event_.changedTouchesLength = 0;
1618
1619 // Consume all events of the same type and add them to the changed list.
1620 int last_type = 0;
1621 for (size_t i = 0; i < count; ++i) {
1622 if (points[i].dwID == 0ul)
1623 continue;
1624
1625 WebKit::WebTouchPoint* point = NULL;
1626 for (unsigned j = 0; j < touch_event_.touchesLength; ++j) {
1627 if (static_cast<DWORD>(touch_event_.touches[j].id) == points[i].dwID) {
1628 point = &touch_event_.touches[j];
1629 break;
1630 }
1631 }
1632
1633 // Use a move instead if we see a down on a point we already have.
1634 int type = GetTouchType(points[i]);
1635 if (point && type == TOUCHEVENTF_DOWN)
1636 SetTouchType(&points[i], TOUCHEVENTF_MOVE);
1637
1638 // Stop processing when the event type changes.
1639 if (touch_event_.changedTouchesLength && type != last_type)
1640 return i;
1641
1642 last_type = type;
1643 switch (type) {
1644 case TOUCHEVENTF_DOWN: {
1645 if (!(point = AddTouchPoint(&points[i])))
1646 continue;
1647 touch_event_.type = WebKit::WebInputEvent::TouchStart;
1648 break;
1649 }
1650
1651 case TOUCHEVENTF_UP: {
1652 if (!point) // Just throw away a stray up.
1653 continue;
1654 point->state = WebKit::WebTouchPoint::StateReleased;
1655 UpdateTouchPoint(point, &points[i]);
1656 touch_event_.type = WebKit::WebInputEvent::TouchEnd;
1657 break;
1658 }
1659
1660 case TOUCHEVENTF_MOVE: {
1661 if (point) {
1662 point->state = WebKit::WebTouchPoint::StateMoved;
1663 // Don't update the message if the point didn't really move.
1664 if (UpdateTouchPoint(point, &points[i]))
1665 continue;
1666 touch_event_.type = WebKit::WebInputEvent::TouchMove;
1667 } else if (touch_event_.changedTouchesLength) {
1668 // Can't add a point if we're already handling move events.
1669 return i;
1670 } else {
1671 // Treat a move with no existing point as a down.
1672 if (!(point = AddTouchPoint(&points[i])))
1673 continue;
1674 last_type = TOUCHEVENTF_DOWN;
1675 SetTouchType(&points[i], TOUCHEVENTF_DOWN);
1676 touch_event_.type = WebKit::WebInputEvent::TouchStart;
1677 }
1678 break;
1679 }
1680
1681 default:
1682 NOTREACHED();
1683 continue;
1684 }
1685 touch_event_.changedTouches[touch_event_.changedTouchesLength++] = *point;
1686 }
1687
1688 return count;
1689 }
1690
1691 bool RenderWidgetHostViewWin::WebTouchState::ReleaseTouchPoints() {
1692 if (touch_event_.touchesLength == 0)
1693 return false;
1694 // Mark every active touchpoint as released.
1695 touch_event_.type = WebKit::WebInputEvent::TouchEnd;
1696 touch_event_.changedTouchesLength = touch_event_.touchesLength;
1697 for (unsigned int i = 0; i < touch_event_.touchesLength; ++i) {
1698 touch_event_.touches[i].state = WebKit::WebTouchPoint::StateReleased;
1699 touch_event_.changedTouches[i].state =
1700 WebKit::WebTouchPoint::StateReleased;
1701 }
1702
1703 return true;
1704 }
1705
1706 WebKit::WebTouchPoint* RenderWidgetHostViewWin::WebTouchState::AddTouchPoint(
1707 TOUCHINPUT* touch_input) {
1708 if (touch_event_.touchesLength >= WebKit::WebTouchEvent::touchesLengthCap)
1709 return NULL;
1710 WebKit::WebTouchPoint* point =
1711 &touch_event_.touches[touch_event_.touchesLength++];
1712 point->state = WebKit::WebTouchPoint::StatePressed;
1713 point->id = touch_input->dwID;
1714 UpdateTouchPoint(point, touch_input);
1715 return point;
1716 }
1717
1718 bool RenderWidgetHostViewWin::WebTouchState::UpdateTouchPoint(
1719 WebKit::WebTouchPoint* touch_point,
1720 TOUCHINPUT* touch_input) {
1721 CPoint coordinates(TOUCH_COORD_TO_PIXEL(touch_input->x),
1722 TOUCH_COORD_TO_PIXEL(touch_input->y));
1723 int radius_x = 1;
1724 int radius_y = 1;
1725 if (touch_input->dwMask & TOUCHINPUTMASKF_CONTACTAREA) {
1726 radius_x = TOUCH_COORD_TO_PIXEL(touch_input->cxContact);
1727 radius_y = TOUCH_COORD_TO_PIXEL(touch_input->cyContact);
1728 }
1729
1730 // Detect and exclude stationary moves.
1731 if (GetTouchType(*touch_input) == TOUCHEVENTF_MOVE &&
1732 touch_point->screenPosition.x == coordinates.x &&
1733 touch_point->screenPosition.y == coordinates.y &&
1734 touch_point->radiusX == radius_x &&
1735 touch_point->radiusY == radius_y) {
1736 touch_point->state = WebKit::WebTouchPoint::StateStationary;
1737 return true;
1738 }
1739
1740 touch_point->screenPosition.x = coordinates.x;
1741 touch_point->screenPosition.y = coordinates.y;
1742 window_->GetParent().ScreenToClient(&coordinates);
1743 touch_point->position.x = coordinates.x;
1744 touch_point->position.y = coordinates.y;
1745 touch_point->radiusX = radius_x;
1746 touch_point->radiusY = radius_y;
1747 touch_point->force = 0;
1748 touch_point->rotationAngle = 0;
1749 return false;
1750 }
1751
1752 LRESULT RenderWidgetHostViewWin::OnTouchEvent(UINT message, WPARAM wparam,
1753 LPARAM lparam, BOOL& handled) {
1754 // TODO(jschuh): Add support for an arbitrary number of touchpoints.
1755 size_t total = std::min(static_cast<int>(LOWORD(wparam)),
1756 static_cast<int>(WebKit::WebTouchEvent::touchesLengthCap));
1757 TOUCHINPUT points[WebKit::WebTouchEvent::touchesLengthCap];
1758
1759 if (!total || !GetTouchInputInfo((HTOUCHINPUT)lparam, total,
1760 points, sizeof(TOUCHINPUT))) {
1761 return 0;
1762 }
1763
1764 for (size_t start = 0; start < total;) {
1765 start += touch_state_.UpdateTouchPoints(points + start, total - start);
1766 if (touch_state_.is_changed())
1767 render_widget_host_->ForwardTouchEvent(touch_state_.touch_event());
1768 }
1769
1770 CloseTouchInputHandle((HTOUCHINPUT)lparam);
1771
1772 return 0;
1773 }
1774
1573 LRESULT RenderWidgetHostViewWin::OnMouseActivate(UINT message, 1775 LRESULT RenderWidgetHostViewWin::OnMouseActivate(UINT message,
1574 WPARAM wparam, 1776 WPARAM wparam,
1575 LPARAM lparam, 1777 LPARAM lparam,
1576 BOOL& handled) { 1778 BOOL& handled) {
1577 if (!render_widget_host_) 1779 if (!render_widget_host_)
1578 return MA_NOACTIVATE; 1780 return MA_NOACTIVATE;
1579 1781
1580 if (!IsActivatable()) 1782 if (!IsActivatable())
1581 return MA_NOACTIVATE; 1783 return MA_NOACTIVATE;
1582 1784
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
2225 2427
2226 size_t offset = selection_range_.GetMin() - selection_text_offset_; 2428 size_t offset = selection_range_.GetMin() - selection_text_offset_;
2227 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), 2429 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING),
2228 selection_text_.c_str() + offset, len * sizeof(WCHAR)); 2430 selection_text_.c_str() + offset, len * sizeof(WCHAR));
2229 2431
2230 // According to Microsft API document, IMR_RECONVERTSTRING and 2432 // According to Microsft API document, IMR_RECONVERTSTRING and
2231 // IMR_DOCUMENTFEED should return reconv, but some applications return 2433 // IMR_DOCUMENTFEED should return reconv, but some applications return
2232 // need_size. 2434 // need_size.
2233 return reinterpret_cast<LRESULT>(reconv); 2435 return reinterpret_cast<LRESULT>(reconv);
2234 } 2436 }
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_host_view_win.h ('k') | content/public/common/content_switches.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698