Chromium Code Reviews| 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 |