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

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) {
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 // Reset all touch event state.
1602 WebKit::WebTouchPoint* point = touch_event_.touches;
ananta 2011/11/10 02:15:24 Can you add some comments here explaining the logi
jschuh 2011/11/10 21:29:10 Done.
1603 WebKit::WebTouchPoint* end = point + touch_event_.touchesLength;
1604 while (point < end) {
1605 if (point->state == WebKit::WebTouchPoint::StateReleased) {
1606 *point = *(--end);
1607 --touch_event_.touchesLength;
1608 } else {
1609 point->state = WebKit::WebTouchPoint::StateStationary;
1610 point++;
1611 }
1612 }
1613 touch_event_.changedTouchesLength = 0;
1614
1615 // Consume all events of the same type and add them to the changed list.
1616 int last_type = 0;
1617 for (size_t i = 0; i < count; ++i) {
1618 if (points[i].dwID == 0ul)
1619 continue;
1620
1621 WebKit::WebTouchPoint* point = NULL;
1622 for (unsigned j = 0; j < touch_event_.touchesLength; ++j) {
1623 if (static_cast<DWORD>(touch_event_.touches[j].id) == points[i].dwID) {
1624 point = &touch_event_.touches[j];
1625 break;
1626 }
1627 }
1628
1629 // Use a move instead if we see a down on a point we already have.
1630 int type = GetTouchType(points[i]);
1631 if (point && type == TOUCHEVENTF_DOWN)
1632 SetTouchType(&points[i], TOUCHEVENTF_MOVE);
1633
1634 // Stop processing when the event type changes.
1635 if (touch_event_.changedTouchesLength && type != last_type)
1636 return i;
1637
1638 last_type = type;
1639 switch (type) {
1640 case TOUCHEVENTF_DOWN: {
1641 if (!(point = AddTouchPoint(&points[i])))
1642 continue;
1643 touch_event_.type = WebKit::WebInputEvent::TouchStart;
1644 break;
1645 }
1646
1647 case TOUCHEVENTF_UP: {
1648 if (!point) // Just throw away a stray up.
1649 continue;
1650 point->state = WebKit::WebTouchPoint::StateReleased;
1651 UpdateTouchPoint(point, &points[i]);
1652 touch_event_.type = WebKit::WebInputEvent::TouchEnd;
1653 break;
1654 }
1655
1656 case TOUCHEVENTF_MOVE: {
1657 if (point) {
1658 point->state = WebKit::WebTouchPoint::StateMoved;
1659 // Don't update the message if the point didn't really move.
1660 if (UpdateTouchPoint(point, &points[i]))
1661 continue;
1662 touch_event_.type = WebKit::WebInputEvent::TouchMove;
1663 } else if (touch_event_.changedTouchesLength) {
1664 // Can't add a point if we're already handling move events.
1665 return i;
1666 } else {
1667 // Treat a move with no existing point as a down.
1668 if (!(point = AddTouchPoint(&points[i])))
1669 continue;
1670 last_type = TOUCHEVENTF_DOWN;
1671 SetTouchType(&points[i], TOUCHEVENTF_DOWN);
1672 touch_event_.type = WebKit::WebInputEvent::TouchStart;
1673 }
1674 break;
1675 }
1676
1677 default:
1678 NOTREACHED();
1679 continue;
1680 }
1681 touch_event_.changedTouches[touch_event_.changedTouchesLength++] = *point;
1682 }
1683
1684 return count;
1685 }
1686
1687 bool RenderWidgetHostViewWin::WebTouchState::ReleaseTouchPoints() {
1688 if (touch_event_.touchesLength == 0)
1689 return false;
1690 // Mark every active touchpoint as released.
1691 touch_event_.type = WebKit::WebInputEvent::TouchEnd;
1692 touch_event_.changedTouchesLength = touch_event_.touchesLength;
1693 for (unsigned int i = 0; i < touch_event_.touchesLength; ++i) {
1694 touch_event_.touches[i].state = WebKit::WebTouchPoint::StateReleased;
1695 touch_event_.changedTouches[i].state =
1696 WebKit::WebTouchPoint::StateReleased;
1697 }
1698
1699 return true;
1700 }
1701
1702 WebKit::WebTouchPoint* RenderWidgetHostViewWin::WebTouchState::AddTouchPoint(
1703 TOUCHINPUT* touch_input) {
1704 if (touch_event_.touchesLength >= WebKit::WebTouchEvent::touchesLengthCap)
1705 return NULL;
1706 WebKit::WebTouchPoint* point =
1707 &touch_event_.touches[touch_event_.touchesLength++];
1708 point->state = WebKit::WebTouchPoint::StatePressed;
1709 point->id = touch_input->dwID;
1710 UpdateTouchPoint(point, touch_input);
1711 return point;
1712 }
1713
1714 bool RenderWidgetHostViewWin::WebTouchState::UpdateTouchPoint(
1715 WebKit::WebTouchPoint* touch_point,
1716 TOUCHINPUT* touch_input) {
1717 CPoint coordinates(TOUCH_COORD_TO_PIXEL(touch_input->x),
1718 TOUCH_COORD_TO_PIXEL(touch_input->y));
1719 int radius_x = 1;
1720 int radius_y = 1;
1721 if (touch_input->dwMask & TOUCHINPUTMASKF_CONTACTAREA) {
1722 radius_x = TOUCH_COORD_TO_PIXEL(touch_input->cxContact);
1723 radius_y = TOUCH_COORD_TO_PIXEL(touch_input->cyContact);
1724 }
1725
1726 // Detect and exclude stationary moves.
1727 if (GetTouchType(*touch_input) == TOUCHEVENTF_MOVE &&
1728 touch_point->screenPosition.x == coordinates.x &&
1729 touch_point->screenPosition.y == coordinates.y &&
1730 touch_point->radiusX == radius_x &&
1731 touch_point->radiusY == radius_y) {
1732 touch_point->state = WebKit::WebTouchPoint::StateStationary;
1733 return true;
1734 }
1735
1736 touch_point->screenPosition.x = coordinates.x;
1737 touch_point->screenPosition.y = coordinates.y;
1738 window_->GetParent().ScreenToClient(&coordinates);
1739 touch_point->position.x = coordinates.x;
1740 touch_point->position.y = coordinates.y;
1741 touch_point->radiusX = radius_x;
1742 touch_point->radiusY = radius_y;
1743 touch_point->force = 0;
1744 touch_point->rotationAngle = 0;
1745 return false;
1746 }
1747
1748 LRESULT RenderWidgetHostViewWin::OnTouchEvent(UINT message, WPARAM wparam,
1749 LPARAM lparam, BOOL& handled) {
1750 // TODO(jschuh): Add support for an arbitrary number of touchpoints.
1751 size_t total = std::min(static_cast<int>(LOWORD(wparam)),
1752 static_cast<int>(WebKit::WebTouchEvent::touchesLengthCap));
1753 TOUCHINPUT points[WebKit::WebTouchEvent::touchesLengthCap];
1754
1755 if (!total || !GetTouchInputInfo((HTOUCHINPUT)lparam, total,
1756 points, sizeof(TOUCHINPUT))) {
1757 return 0;
1758 }
1759
1760 for (size_t start = 0; start < total;) {
1761 start += touch_state_.UpdateTouchPoints(points + start, total - start);
1762 if (touch_state_.is_changed())
1763 render_widget_host_->ForwardTouchEvent(touch_state_.touch_event());
1764 }
1765
1766 CloseTouchInputHandle((HTOUCHINPUT)lparam);
1767
1768 return 0;
1769 }
1770
1573 LRESULT RenderWidgetHostViewWin::OnMouseActivate(UINT message, 1771 LRESULT RenderWidgetHostViewWin::OnMouseActivate(UINT message,
1574 WPARAM wparam, 1772 WPARAM wparam,
1575 LPARAM lparam, 1773 LPARAM lparam,
1576 BOOL& handled) { 1774 BOOL& handled) {
1577 if (!render_widget_host_) 1775 if (!render_widget_host_)
1578 return MA_NOACTIVATE; 1776 return MA_NOACTIVATE;
1579 1777
1580 if (!IsActivatable()) 1778 if (!IsActivatable())
1581 return MA_NOACTIVATE; 1779 return MA_NOACTIVATE;
1582 1780
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
2225 2423
2226 size_t offset = selection_range_.GetMin() - selection_text_offset_; 2424 size_t offset = selection_range_.GetMin() - selection_text_offset_;
2227 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), 2425 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING),
2228 selection_text_.c_str() + offset, len * sizeof(WCHAR)); 2426 selection_text_.c_str() + offset, len * sizeof(WCHAR));
2229 2427
2230 // According to Microsft API document, IMR_RECONVERTSTRING and 2428 // According to Microsft API document, IMR_RECONVERTSTRING and
2231 // IMR_DOCUMENTFEED should return reconv, but some applications return 2429 // IMR_DOCUMENTFEED should return reconv, but some applications return
2232 // need_size. 2430 // need_size.
2233 return reinterpret_cast<LRESULT>(reconv); 2431 return reinterpret_cast<LRESULT>(reconv);
2234 } 2432 }
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