OLD | NEW |
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 Loading... |
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 | |
303 } // namespace | 293 } // namespace |
304 | 294 |
305 /////////////////////////////////////////////////////////////////////////////// | 295 /////////////////////////////////////////////////////////////////////////////// |
306 // RenderWidgetHostViewWin, public: | 296 // RenderWidgetHostViewWin, public: |
307 | 297 |
308 RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) | 298 RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) |
309 : render_widget_host_(widget), | 299 : render_widget_host_(widget), |
310 compositor_host_window_(NULL), | 300 compositor_host_window_(NULL), |
311 hide_compositor_window_at_next_paint_(false), | 301 hide_compositor_window_at_next_paint_(false), |
312 track_mouse_leave_(false), | 302 track_mouse_leave_(false), |
313 ime_notification_(false), | 303 ime_notification_(false), |
314 capture_enter_key_(false), | 304 capture_enter_key_(false), |
315 is_hidden_(false), | 305 is_hidden_(false), |
316 about_to_validate_and_paint_(false), | 306 about_to_validate_and_paint_(false), |
317 close_on_deactivate_(false), | 307 close_on_deactivate_(false), |
318 being_destroyed_(false), | 308 being_destroyed_(false), |
319 tooltip_hwnd_(NULL), | 309 tooltip_hwnd_(NULL), |
320 tooltip_showing_(false), | 310 tooltip_showing_(false), |
321 shutdown_factory_(this), | 311 shutdown_factory_(this), |
322 parent_hwnd_(NULL), | 312 parent_hwnd_(NULL), |
323 is_loading_(false), | 313 is_loading_(false), |
324 overlay_color_(0), | 314 overlay_color_(0), |
325 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), | 315 text_input_type_(ui::TEXT_INPUT_TYPE_NONE), |
326 is_fullscreen_(false), | 316 is_fullscreen_(false), |
327 ignore_mouse_movement_(true), | 317 ignore_mouse_movement_(true), |
328 composition_range_(ui::Range::InvalidRange()), | 318 composition_range_(ui::Range::InvalidRange()), |
329 ignore_next_lbutton_message_at_same_location(false), | 319 ignore_next_lbutton_message_at_same_location(false), |
330 last_pointer_down_location_(0), | 320 last_pointer_down_location_(0) { |
331 touch_state_(this) { | |
332 render_widget_host_->SetView(this); | 321 render_widget_host_->SetView(this); |
333 registrar_.Add(this, | 322 registrar_.Add(this, |
334 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 323 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
335 content::NotificationService::AllBrowserContextsAndSources()); | 324 content::NotificationService::AllBrowserContextsAndSources()); |
336 } | 325 } |
337 | 326 |
338 RenderWidgetHostViewWin::~RenderWidgetHostViewWin() { | 327 RenderWidgetHostViewWin::~RenderWidgetHostViewWin() { |
339 UnlockMouse(); | 328 UnlockMouse(); |
340 ResetTooltip(); | 329 ResetTooltip(); |
341 } | 330 } |
(...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 | 872 |
884 LRESULT RenderWidgetHostViewWin::OnCreate(CREATESTRUCT* create_struct) { | 873 LRESULT RenderWidgetHostViewWin::OnCreate(CREATESTRUCT* create_struct) { |
885 // Call the WM_INPUTLANGCHANGE message handler to initialize the input locale | 874 // Call the WM_INPUTLANGCHANGE message handler to initialize the input locale |
886 // of a browser process. | 875 // of a browser process. |
887 OnInputLangChange(0, 0); | 876 OnInputLangChange(0, 0); |
888 // Marks that window as supporting mouse-wheel messages rerouting so it is | 877 // Marks that window as supporting mouse-wheel messages rerouting so it is |
889 // scrolled when under the mouse pointer even if inactive. | 878 // scrolled when under the mouse pointer even if inactive. |
890 props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(m_hWnd)); | 879 props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(m_hWnd)); |
891 | 880 |
892 if (base::win::GetVersion() >= base::win::VERSION_WIN7) { | 881 if (base::win::GetVersion() >= base::win::VERSION_WIN7) { |
893 // Use gestures if touch event switch isn't present or registration fails. | 882 // Single finger panning is consistent with other windows applications. |
894 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 883 const DWORD gesture_allow = GC_PAN_WITH_SINGLE_FINGER_VERTICALLY | |
895 switches::kEnableTouchEvents) || | 884 GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; |
896 !RegisterTouchWindow(m_hWnd, 0)) { | 885 const DWORD gesture_block = GC_PAN_WITH_GUTTER; |
897 // Single finger panning is consistent with other windows applications. | 886 GESTURECONFIG gc[] = { |
898 const DWORD gesture_allow = GC_PAN_WITH_SINGLE_FINGER_VERTICALLY | | 887 { GID_ZOOM, GC_ZOOM, 0 }, |
899 GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; | 888 { GID_PAN, gesture_allow , gesture_block}, |
900 const DWORD gesture_block = GC_PAN_WITH_GUTTER; | 889 { GID_TWOFINGERTAP, GC_TWOFINGERTAP , 0}, |
901 GESTURECONFIG gc[] = { | 890 { GID_PRESSANDTAP, GC_PRESSANDTAP , 0} |
902 { GID_ZOOM, GC_ZOOM, 0 }, | 891 }; |
903 { GID_PAN, gesture_allow , gesture_block}, | 892 if (!SetGestureConfig(m_hWnd, 0, arraysize(gc), gc, sizeof(GESTURECONFIG))) |
904 { GID_TWOFINGERTAP, GC_TWOFINGERTAP , 0}, | 893 { |
905 { GID_PRESSANDTAP, GC_PRESSANDTAP , 0} | 894 NOTREACHED(); |
906 }; | |
907 if (!SetGestureConfig(m_hWnd, 0, arraysize(gc), gc, | |
908 sizeof(GESTURECONFIG))) { | |
909 NOTREACHED(); | |
910 } | |
911 } | 895 } |
912 } | 896 } |
913 | 897 |
914 return 0; | 898 return 0; |
915 } | 899 } |
916 | 900 |
917 void RenderWidgetHostViewWin::OnActivate(UINT action, BOOL minimized, | 901 void RenderWidgetHostViewWin::OnActivate(UINT action, BOOL minimized, |
918 HWND window) { | 902 HWND window) { |
919 // If the container is a popup, clicking elsewhere on screen should close the | 903 // If the container is a popup, clicking elsewhere on screen should close the |
920 // popup. | 904 // popup. |
(...skipping 15 matching lines...) Expand all Loading... |
936 // handler for NPP_DestroyStream relies on. | 920 // handler for NPP_DestroyStream relies on. |
937 // | 921 // |
938 // The fix is to detach plugin windows from web contents when it is going | 922 // The fix is to detach plugin windows from web contents when it is going |
939 // away. This will prevent the plugin windows from getting destroyed | 923 // away. This will prevent the plugin windows from getting destroyed |
940 // automatically. The detached plugin windows will get cleaned up in proper | 924 // automatically. The detached plugin windows will get cleaned up in proper |
941 // sequence as part of the usual cleanup when the plugin instance goes away. | 925 // sequence as part of the usual cleanup when the plugin instance goes away. |
942 EnumChildWindows(m_hWnd, DetachPluginWindowsCallback, NULL); | 926 EnumChildWindows(m_hWnd, DetachPluginWindowsCallback, NULL); |
943 | 927 |
944 props_.reset(); | 928 props_.reset(); |
945 | 929 |
946 if (IsTouchWindow(m_hWnd, NULL)) | |
947 UnregisterTouchWindow(m_hWnd); | |
948 | |
949 CleanupCompositorWindow(); | 930 CleanupCompositorWindow(); |
950 | 931 |
951 ResetTooltip(); | 932 ResetTooltip(); |
952 TrackMouseLeave(false); | 933 TrackMouseLeave(false); |
953 } | 934 } |
954 | 935 |
955 void RenderWidgetHostViewWin::OnPaint(HDC unused_dc) { | 936 void RenderWidgetHostViewWin::OnPaint(HDC unused_dc) { |
956 if (!render_widget_host_) | 937 if (!render_widget_host_) |
957 return; | 938 return; |
958 | 939 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1114 return 0; | 1095 return 0; |
1115 } | 1096 } |
1116 | 1097 |
1117 void RenderWidgetHostViewWin::OnSetFocus(HWND window) { | 1098 void RenderWidgetHostViewWin::OnSetFocus(HWND window) { |
1118 if (browser_accessibility_manager_.get()) | 1099 if (browser_accessibility_manager_.get()) |
1119 browser_accessibility_manager_->GotFocus(); | 1100 browser_accessibility_manager_->GotFocus(); |
1120 if (render_widget_host_) { | 1101 if (render_widget_host_) { |
1121 render_widget_host_->GotFocus(); | 1102 render_widget_host_->GotFocus(); |
1122 render_widget_host_->SetActive(true); | 1103 render_widget_host_->SetActive(true); |
1123 } | 1104 } |
1124 if (touch_state_.ReleaseTouchPoints()) | |
1125 render_widget_host_->ForwardTouchEvent(touch_state_.touch_event()); | |
1126 } | 1105 } |
1127 | 1106 |
1128 void RenderWidgetHostViewWin::OnKillFocus(HWND window) { | 1107 void RenderWidgetHostViewWin::OnKillFocus(HWND window) { |
1129 if (render_widget_host_) { | 1108 if (render_widget_host_) { |
1130 render_widget_host_->SetActive(false); | 1109 render_widget_host_->SetActive(false); |
1131 render_widget_host_->Blur(); | 1110 render_widget_host_->Blur(); |
1132 } | 1111 } |
1133 if (touch_state_.ReleaseTouchPoints()) | |
1134 render_widget_host_->ForwardTouchEvent(touch_state_.touch_event()); | |
1135 } | 1112 } |
1136 | 1113 |
1137 void RenderWidgetHostViewWin::OnCaptureChanged(HWND window) { | 1114 void RenderWidgetHostViewWin::OnCaptureChanged(HWND window) { |
1138 if (render_widget_host_) | 1115 if (render_widget_host_) |
1139 render_widget_host_->LostCapture(); | 1116 render_widget_host_->LostCapture(); |
1140 } | 1117 } |
1141 | 1118 |
1142 void RenderWidgetHostViewWin::OnCancelMode() { | 1119 void RenderWidgetHostViewWin::OnCancelMode() { |
1143 if (render_widget_host_) | 1120 if (render_widget_host_) |
1144 render_widget_host_->LostCapture(); | 1121 render_widget_host_->LostCapture(); |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1586 | 1563 |
1587 if (!handled_by_TabContents && render_widget_host_) { | 1564 if (!handled_by_TabContents && render_widget_host_) { |
1588 render_widget_host_->ForwardWheelEvent( | 1565 render_widget_host_->ForwardWheelEvent( |
1589 WebInputEventFactory::mouseWheelEvent(m_hWnd, message, wparam, | 1566 WebInputEventFactory::mouseWheelEvent(m_hWnd, message, wparam, |
1590 lparam)); | 1567 lparam)); |
1591 } | 1568 } |
1592 handled = TRUE; | 1569 handled = TRUE; |
1593 return 0; | 1570 return 0; |
1594 } | 1571 } |
1595 | 1572 |
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 | |
1775 LRESULT RenderWidgetHostViewWin::OnMouseActivate(UINT message, | 1573 LRESULT RenderWidgetHostViewWin::OnMouseActivate(UINT message, |
1776 WPARAM wparam, | 1574 WPARAM wparam, |
1777 LPARAM lparam, | 1575 LPARAM lparam, |
1778 BOOL& handled) { | 1576 BOOL& handled) { |
1779 if (!render_widget_host_) | 1577 if (!render_widget_host_) |
1780 return MA_NOACTIVATE; | 1578 return MA_NOACTIVATE; |
1781 | 1579 |
1782 if (!IsActivatable()) | 1580 if (!IsActivatable()) |
1783 return MA_NOACTIVATE; | 1581 return MA_NOACTIVATE; |
1784 | 1582 |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2428 | 2226 |
2429 size_t offset = selection_range_.GetMin() - selection_text_offset_; | 2227 size_t offset = selection_range_.GetMin() - selection_text_offset_; |
2430 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), | 2228 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), |
2431 selection_text_.c_str() + offset, len * sizeof(WCHAR)); | 2229 selection_text_.c_str() + offset, len * sizeof(WCHAR)); |
2432 | 2230 |
2433 // According to Microsft API document, IMR_RECONVERTSTRING and | 2231 // According to Microsft API document, IMR_RECONVERTSTRING and |
2434 // IMR_DOCUMENTFEED should return reconv, but some applications return | 2232 // IMR_DOCUMENTFEED should return reconv, but some applications return |
2435 // need_size. | 2233 // need_size. |
2436 return reinterpret_cast<LRESULT>(reconv); | 2234 return reinterpret_cast<LRESULT>(reconv); |
2437 } | 2235 } |
OLD | NEW |