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" |
11 #include "base/logging.h" | |
11 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
12 #include "base/process_util.h" | 13 #include "base/process_util.h" |
13 #include "base/threading/thread.h" | 14 #include "base/threading/thread.h" |
14 #include "base/win/scoped_comptr.h" | 15 #include "base/win/scoped_comptr.h" |
15 #include "base/win/scoped_gdi_object.h" | 16 #include "base/win/scoped_gdi_object.h" |
17 #include "base/win/windows_version.h" | |
16 #include "base/win/win_util.h" | 18 #include "base/win/win_util.h" |
17 #include "base/win/windows_version.h" | 19 #include "base/win/windows_version.h" |
18 #include "base/win/wrapped_window_proc.h" | 20 #include "base/win/wrapped_window_proc.h" |
19 #include "content/browser/accessibility/browser_accessibility_manager.h" | 21 #include "content/browser/accessibility/browser_accessibility_manager.h" |
20 #include "content/browser/accessibility/browser_accessibility_state.h" | 22 #include "content/browser/accessibility/browser_accessibility_state.h" |
21 #include "content/browser/accessibility/browser_accessibility_win.h" | 23 #include "content/browser/accessibility/browser_accessibility_win.h" |
22 #include "content/browser/plugin_process_host.h" | 24 #include "content/browser/plugin_process_host.h" |
23 #include "content/browser/renderer_host/backing_store.h" | 25 #include "content/browser/renderer_host/backing_store.h" |
24 #include "content/browser/renderer_host/backing_store_win.h" | 26 #include "content/browser/renderer_host/backing_store_win.h" |
25 #include "content/browser/renderer_host/render_process_host.h" | 27 #include "content/browser/renderer_host/render_process_host.h" |
(...skipping 846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
872 | 874 |
873 LRESULT RenderWidgetHostViewWin::OnCreate(CREATESTRUCT* create_struct) { | 875 LRESULT RenderWidgetHostViewWin::OnCreate(CREATESTRUCT* create_struct) { |
874 // Call the WM_INPUTLANGCHANGE message handler to initialize the input locale | 876 // Call the WM_INPUTLANGCHANGE message handler to initialize the input locale |
875 // of a browser process. | 877 // of a browser process. |
876 OnInputLangChange(0, 0); | 878 OnInputLangChange(0, 0); |
877 // Marks that window as supporting mouse-wheel messages rerouting so it is | 879 // Marks that window as supporting mouse-wheel messages rerouting so it is |
878 // scrolled when under the mouse pointer even if inactive. | 880 // scrolled when under the mouse pointer even if inactive. |
879 props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(m_hWnd)); | 881 props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(m_hWnd)); |
880 | 882 |
881 if (base::win::GetVersion() >= base::win::VERSION_WIN7) { | 883 if (base::win::GetVersion() >= base::win::VERSION_WIN7) { |
882 // Single finger panning is consistent with other windows applications. | 884 if (CommandLine::ForCurrentProcess()->HasSwitch( |
883 const DWORD gesture_allow = GC_PAN_WITH_SINGLE_FINGER_VERTICALLY | | 885 switches::kEnableTouchEvents)) { |
884 GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; | 886 // Enable touch events rather than gestures. |
885 const DWORD gesture_block = GC_PAN_WITH_GUTTER; | 887 DCHECK(RegisterTouchWindow(m_hWnd, 0)); |
886 GESTURECONFIG gc[] = { | 888 } else { |
887 { GID_ZOOM, GC_ZOOM, 0 }, | 889 // Single finger panning is consistent with other windows applications. |
888 { GID_PAN, gesture_allow , gesture_block}, | 890 const DWORD gesture_allow = GC_PAN_WITH_SINGLE_FINGER_VERTICALLY | |
889 { GID_TWOFINGERTAP, GC_TWOFINGERTAP , 0}, | 891 GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; |
890 { GID_PRESSANDTAP, GC_PRESSANDTAP , 0} | 892 const DWORD gesture_block = GC_PAN_WITH_GUTTER; |
891 }; | 893 GESTURECONFIG gc[] = { |
892 if (!SetGestureConfig(m_hWnd, 0, arraysize(gc), gc, sizeof(GESTURECONFIG))) | 894 { GID_ZOOM, GC_ZOOM, 0 }, |
893 { | 895 { GID_PAN, gesture_allow , gesture_block}, |
894 NOTREACHED(); | 896 { GID_TWOFINGERTAP, GC_TWOFINGERTAP , 0}, |
897 { GID_PRESSANDTAP, GC_PRESSANDTAP , 0} | |
898 }; | |
899 if (!SetGestureConfig(m_hWnd, 0, arraysize(gc), gc, | |
900 sizeof(GESTURECONFIG))) { | |
901 NOTREACHED(); | |
902 } | |
895 } | 903 } |
896 } | 904 } |
897 | 905 |
898 return 0; | 906 return 0; |
899 } | 907 } |
900 | 908 |
901 void RenderWidgetHostViewWin::OnActivate(UINT action, BOOL minimized, | 909 void RenderWidgetHostViewWin::OnActivate(UINT action, BOOL minimized, |
902 HWND window) { | 910 HWND window) { |
903 // If the container is a popup, clicking elsewhere on screen should close the | 911 // If the container is a popup, clicking elsewhere on screen should close the |
904 // popup. | 912 // popup. |
(...skipping 15 matching lines...) Expand all Loading... | |
920 // handler for NPP_DestroyStream relies on. | 928 // handler for NPP_DestroyStream relies on. |
921 // | 929 // |
922 // The fix is to detach plugin windows from web contents when it is going | 930 // 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 | 931 // away. This will prevent the plugin windows from getting destroyed |
924 // automatically. The detached plugin windows will get cleaned up in proper | 932 // 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. | 933 // sequence as part of the usual cleanup when the plugin instance goes away. |
926 EnumChildWindows(m_hWnd, DetachPluginWindowsCallback, NULL); | 934 EnumChildWindows(m_hWnd, DetachPluginWindowsCallback, NULL); |
927 | 935 |
928 props_.reset(); | 936 props_.reset(); |
929 | 937 |
938 UnregisterTouchWindow(m_hWnd); | |
939 | |
930 CleanupCompositorWindow(); | 940 CleanupCompositorWindow(); |
931 | 941 |
932 ResetTooltip(); | 942 ResetTooltip(); |
933 TrackMouseLeave(false); | 943 TrackMouseLeave(false); |
934 } | 944 } |
935 | 945 |
936 void RenderWidgetHostViewWin::OnPaint(HDC unused_dc) { | 946 void RenderWidgetHostViewWin::OnPaint(HDC unused_dc) { |
937 if (!render_widget_host_) | 947 if (!render_widget_host_) |
938 return; | 948 return; |
939 | 949 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1095 return 0; | 1105 return 0; |
1096 } | 1106 } |
1097 | 1107 |
1098 void RenderWidgetHostViewWin::OnSetFocus(HWND window) { | 1108 void RenderWidgetHostViewWin::OnSetFocus(HWND window) { |
1099 if (browser_accessibility_manager_.get()) | 1109 if (browser_accessibility_manager_.get()) |
1100 browser_accessibility_manager_->GotFocus(); | 1110 browser_accessibility_manager_->GotFocus(); |
1101 if (render_widget_host_) { | 1111 if (render_widget_host_) { |
1102 render_widget_host_->GotFocus(); | 1112 render_widget_host_->GotFocus(); |
1103 render_widget_host_->SetActive(true); | 1113 render_widget_host_->SetActive(true); |
1104 } | 1114 } |
1115 FinishTouchEvent(); | |
1105 } | 1116 } |
1106 | 1117 |
1107 void RenderWidgetHostViewWin::OnKillFocus(HWND window) { | 1118 void RenderWidgetHostViewWin::OnKillFocus(HWND window) { |
1108 if (render_widget_host_) { | 1119 if (render_widget_host_) { |
1109 render_widget_host_->SetActive(false); | 1120 render_widget_host_->SetActive(false); |
1110 render_widget_host_->Blur(); | 1121 render_widget_host_->Blur(); |
1111 } | 1122 } |
1123 FinishTouchEvent(); | |
1112 } | 1124 } |
1113 | 1125 |
1114 void RenderWidgetHostViewWin::OnCaptureChanged(HWND window) { | 1126 void RenderWidgetHostViewWin::OnCaptureChanged(HWND window) { |
1115 if (render_widget_host_) | 1127 if (render_widget_host_) |
1116 render_widget_host_->LostCapture(); | 1128 render_widget_host_->LostCapture(); |
1117 } | 1129 } |
1118 | 1130 |
1119 void RenderWidgetHostViewWin::OnCancelMode() { | 1131 void RenderWidgetHostViewWin::OnCancelMode() { |
1120 if (render_widget_host_) | 1132 if (render_widget_host_) |
1121 render_widget_host_->LostCapture(); | 1133 render_widget_host_->LostCapture(); |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1563 | 1575 |
1564 if (!handled_by_TabContents && render_widget_host_) { | 1576 if (!handled_by_TabContents && render_widget_host_) { |
1565 render_widget_host_->ForwardWheelEvent( | 1577 render_widget_host_->ForwardWheelEvent( |
1566 WebInputEventFactory::mouseWheelEvent(m_hWnd, message, wparam, | 1578 WebInputEventFactory::mouseWheelEvent(m_hWnd, message, wparam, |
1567 lparam)); | 1579 lparam)); |
1568 } | 1580 } |
1569 handled = TRUE; | 1581 handled = TRUE; |
1570 return 0; | 1582 return 0; |
1571 } | 1583 } |
1572 | 1584 |
1585 void RenderWidgetHostViewWin::FinishTouchEvent() { | |
ananta
2011/11/08 20:00:25
+1 for moving this inside a class and into a separ
| |
1586 if (touch_event_.touchesLength == 0) | |
1587 return; | |
1588 | |
1589 // Release all active touchpoints. | |
1590 for (unsigned int i = 0; i < touch_event_.touchesLength; ++i) { | |
1591 touch_event_.touches[i].state = WebKit::WebTouchPoint::StateReleased; | |
1592 touch_event_.changedTouches[i].state = | |
1593 WebKit::WebTouchPoint::StateReleased; | |
1594 } | |
1595 touch_event_.changedTouchesLength = touch_event_.touchesLength = 0; | |
1596 touch_event_.type = WebKit::WebInputEvent::TouchEnd; | |
1597 render_widget_host_->ForwardTouchEvent(touch_event_); | |
1598 touch_event_.touchesLength = 0; | |
1599 } | |
1600 | |
1601 WebKit::WebTouchPoint* RenderWidgetHostViewWin::AddTouchPoint( | |
1602 TOUCHINPUT* touch_input) { | |
1603 if (touch_event_.touchesLength >= WebKit::WebTouchEvent::touchesLengthCap) | |
1604 return NULL; | |
1605 WebKit::WebTouchPoint* point = | |
1606 &touch_event_.touches[touch_event_.touchesLength++]; | |
1607 point->state = WebKit::WebTouchPoint::StatePressed; | |
1608 point->id = touch_input->dwID; | |
1609 UpdateTouchPoint(point, touch_input); | |
1610 return point; | |
1611 } | |
1612 | |
1613 bool RenderWidgetHostViewWin::UpdateTouchPoint( | |
1614 WebKit::WebTouchPoint* touch_point, | |
1615 TOUCHINPUT* touch_input) { | |
1616 CPoint coordinates(TOUCH_COORD_TO_PIXEL(touch_input->x), | |
1617 TOUCH_COORD_TO_PIXEL(touch_input->y)); | |
1618 int radius_x = 0; | |
1619 int radius_y = 0; | |
1620 if (touch_input->dwMask & TOUCHINPUTMASKF_CONTACTAREA) { | |
1621 radius_x = TOUCH_COORD_TO_PIXEL(touch_input->cxContact); | |
1622 radius_y = TOUCH_COORD_TO_PIXEL(touch_input->cyContact); | |
1623 } | |
1624 | |
1625 // Detect and exclude stationary moves. | |
1626 if (touch_point->state == WebKit::WebTouchPoint::StateMoved && | |
1627 touch_point->screenPosition.x == coordinates.x && | |
1628 touch_point->screenPosition.y == coordinates.y && | |
1629 touch_point->radiusX == radius_x && | |
1630 touch_point->radiusY == radius_y) { | |
1631 touch_point->state = WebKit::WebTouchPoint::StateStationary; | |
1632 return true; | |
1633 } | |
1634 | |
1635 touch_point->screenPosition.x = coordinates.x; | |
1636 touch_point->screenPosition.y = coordinates.y; | |
1637 GetParent().ScreenToClient(&coordinates); | |
1638 touch_point->position.x = coordinates.x; | |
1639 touch_point->position.y = coordinates.y; | |
1640 touch_point->radiusX = radius_x; | |
1641 touch_point->radiusY = radius_y; | |
1642 touch_point->force = 1.0; | |
1643 touch_point->rotationAngle = 0; | |
1644 return false; | |
1645 } | |
1646 | |
1647 LRESULT RenderWidgetHostViewWin::OnTouchEvent(UINT message, WPARAM wparam, | |
1648 LPARAM lparam, BOOL& handled) { | |
1649 unsigned int touches_down = 0; | |
1650 unsigned int touches_up = 0; | |
1651 unsigned int touches_moved = 0; | |
1652 // TODO(jschuh): Add support for an arbitrary number of touchpoints. | |
1653 size_t points_count = std::min(static_cast<int>(LOWORD(wparam)), | |
1654 static_cast<int>(WebKit::WebTouchEvent::touchesLengthCap)); | |
1655 TOUCHINPUT points[WebKit::WebTouchEvent::touchesLengthCap]; | |
1656 | |
1657 if (points_count > WebKit::WebTouchEvent::touchesLengthCap) | |
ananta
2011/11/08 20:00:25
The std::min statement above should ensure that th
| |
1658 points_count = WebKit::WebTouchEvent::touchesLengthCap; | |
1659 if (!points_count || !GetTouchInputInfo((HTOUCHINPUT)lparam, points_count, | |
1660 points, sizeof(TOUCHINPUT))) { | |
1661 return 0; | |
1662 } | |
1663 touch_event_.changedTouchesLength = 0; | |
1664 | |
1665 for (size_t i = 0; i < points_count; i++) { | |
1666 if (points[i].dwID == 0ul) | |
1667 continue; | |
1668 | |
1669 WebKit::WebTouchPoint* point = NULL; | |
1670 for (unsigned j = 0; j < touch_event_.touchesLength; ++j) { | |
1671 if (static_cast<DWORD>(touch_event_.touches[j].id) == points[i].dwID) { | |
1672 point = &touch_event_.touches[j]; | |
1673 break; | |
1674 } | |
1675 } | |
1676 | |
1677 // Use a move instead if we see a down on a point we already have. | |
1678 if (point && (points[i].dwFlags & 0x7) == TOUCHEVENTF_DOWN) | |
ananta
2011/11/08 20:00:25
Can you add a define for the 0x7 mask?
| |
1679 points[i].dwFlags = (points[i].dwFlags & ~0x7) | TOUCHEVENTF_MOVE; | |
1680 | |
1681 switch (points[i].dwFlags & 0x7) { | |
1682 case TOUCHEVENTF_DOWN: { | |
1683 if (!(point = AddTouchPoint(&points[i]))) | |
1684 continue; | |
1685 ++touches_down; | |
1686 break; | |
1687 } | |
1688 | |
1689 case TOUCHEVENTF_UP: { | |
1690 if (!point) | |
1691 continue; | |
1692 point->state = WebKit::WebTouchPoint::StateReleased; | |
1693 UpdateTouchPoint(point, &points[i]); | |
1694 ++touches_up; | |
1695 break; | |
1696 } | |
1697 | |
1698 case TOUCHEVENTF_MOVE: { | |
1699 if (point) { | |
1700 point->state = WebKit::WebTouchPoint::StateMoved; | |
1701 // Don't update the message if the point didn't really move. | |
1702 if (UpdateTouchPoint(point, &points[i])) | |
1703 continue; | |
1704 ++touches_moved; | |
1705 } else { // Add a new point if we missed the TOUCHEVENTF_DOWN | |
1706 if (!(point = AddTouchPoint(&points[i]))) | |
1707 continue; | |
1708 ++touches_down; | |
1709 } | |
1710 break; | |
1711 } | |
1712 | |
1713 default: | |
1714 NOTREACHED(); | |
1715 continue; | |
1716 } | |
1717 touch_event_.changedTouches[touch_event_.changedTouchesLength++] = *point; | |
1718 } | |
1719 | |
1720 CloseTouchInputHandle((HTOUCHINPUT)lparam); | |
1721 | |
1722 // Set the event type based on what we've received. | |
1723 if (touches_down) | |
1724 touch_event_.type = WebKit::WebInputEvent::TouchStart; | |
1725 else if (touches_up) | |
1726 touch_event_.type = WebKit::WebInputEvent::TouchEnd; | |
1727 else if (touches_moved) | |
1728 touch_event_.type = WebKit::WebInputEvent::TouchMove; | |
1729 else | |
1730 touch_event_.type = WebKit::WebInputEvent::Undefined; | |
1731 | |
1732 // Forward the event only when there's a legitimate change. | |
1733 if (touch_event_.changedTouchesLength) | |
1734 render_widget_host_->ForwardTouchEvent(touch_event_); | |
1735 | |
1736 // Clean up released touches and reset everything else to staitonary. | |
1737 WebKit::WebTouchPoint* point = touch_event_.touches; | |
1738 WebKit::WebTouchPoint* end = | |
1739 &touch_event_.touches[touch_event_.touchesLength]; | |
1740 while (point < end) { | |
1741 if (point->state == WebKit::WebTouchPoint::StateReleased) { | |
1742 *point = *(--end); | |
1743 --touch_event_.touchesLength; | |
1744 } else { | |
1745 point->state = WebKit::WebTouchPoint::StateStationary; | |
1746 point++; | |
1747 } | |
1748 } | |
1749 | |
1750 return 0; | |
1751 } | |
1752 | |
1573 LRESULT RenderWidgetHostViewWin::OnMouseActivate(UINT message, | 1753 LRESULT RenderWidgetHostViewWin::OnMouseActivate(UINT message, |
1574 WPARAM wparam, | 1754 WPARAM wparam, |
1575 LPARAM lparam, | 1755 LPARAM lparam, |
1576 BOOL& handled) { | 1756 BOOL& handled) { |
1577 if (!render_widget_host_) | 1757 if (!render_widget_host_) |
1578 return MA_NOACTIVATE; | 1758 return MA_NOACTIVATE; |
1579 | 1759 |
1580 if (!IsActivatable()) | 1760 if (!IsActivatable()) |
1581 return MA_NOACTIVATE; | 1761 return MA_NOACTIVATE; |
1582 | 1762 |
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2225 | 2405 |
2226 size_t offset = selection_range_.GetMin() - selection_text_offset_; | 2406 size_t offset = selection_range_.GetMin() - selection_text_offset_; |
2227 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), | 2407 memcpy(reinterpret_cast<char*>(reconv) + sizeof(RECONVERTSTRING), |
2228 selection_text_.c_str() + offset, len * sizeof(WCHAR)); | 2408 selection_text_.c_str() + offset, len * sizeof(WCHAR)); |
2229 | 2409 |
2230 // According to Microsft API document, IMR_RECONVERTSTRING and | 2410 // According to Microsft API document, IMR_RECONVERTSTRING and |
2231 // IMR_DOCUMENTFEED should return reconv, but some applications return | 2411 // IMR_DOCUMENTFEED should return reconv, but some applications return |
2232 // need_size. | 2412 // need_size. |
2233 return reinterpret_cast<LRESULT>(reconv); | 2413 return reinterpret_cast<LRESULT>(reconv); |
2234 } | 2414 } |
OLD | NEW |