diff options
author | scottmg@chromium.org <scottmg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-03 18:54:09 +0000 |
---|---|---|
committer | scottmg@chromium.org <scottmg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-03 18:54:09 +0000 |
commit | fdb13bcb913707f3f7f921aace4833ec19877039 (patch) | |
tree | 9b1ff0a009e744742036d5b6a2fb359bdc595088 /content | |
parent | b2c4565776236a9c997cb5bb751ef1678b3f4a0d (diff) | |
download | chromium_src-fdb13bcb913707f3f7f921aace4833ec19877039.zip chromium_src-fdb13bcb913707f3f7f921aace4833ec19877039.tar.gz chromium_src-fdb13bcb913707f3f7f921aace4833ec19877039.tar.bz2 |
Improve switch between gestures and touch mode when kEnableTouchEvents
Mostly works, the only problem is that the first touch or gesture on switching "modes" gets lost because Windows doesn't start a touch of the "other" type when TouchRegisterWindow is called while there's a touch in progress.
TBR=cpu
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=124813
Review URL: http://codereview.chromium.org/9549020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124871 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
12 files changed, 112 insertions, 36 deletions
diff --git a/content/browser/renderer_host/render_widget_host.cc b/content/browser/renderer_host/render_widget_host.cc index ea2013e..ae6047a 100644 --- a/content/browser/renderer_host/render_widget_host.cc +++ b/content/browser/renderer_host/render_widget_host.cc @@ -1240,7 +1240,7 @@ void RenderWidgetHostImpl::OnMsgInputEventAck(WebInputEvent::Type event_type, } else if (type == WebInputEvent::MouseWheel) { ProcessWheelAck(processed); } else if (WebInputEvent::isTouchEventType(type)) { - ProcessTouchAck(processed); + ProcessTouchAck(event_type, processed); } // This is used only for testing. content::NotificationService::current()->Notify( @@ -1264,9 +1264,10 @@ void RenderWidgetHostImpl::ProcessWheelAck(bool processed) { view_->UnhandledWheelEvent(current_wheel_event_); } -void RenderWidgetHostImpl::ProcessTouchAck(bool processed) { +void RenderWidgetHostImpl::ProcessTouchAck( + WebInputEvent::Type type, bool processed) { if (view_) - view_->ProcessTouchAck(processed); + view_->ProcessTouchAck(type, processed); } void RenderWidgetHostImpl::OnMsgFocus() { diff --git a/content/browser/renderer_host/render_widget_host.h b/content/browser/renderer_host/render_widget_host.h index 7abb547..21db907 100644 --- a/content/browser/renderer_host/render_widget_host.h +++ b/content/browser/renderer_host/render_widget_host.h @@ -750,7 +750,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl : public RenderWidgetHost, // Called on OnMsgInputEventAck() to process a touch event ack message. // This can result in a gesture event being generated and sent back to the // renderer. - void ProcessTouchAck(bool processed); + void ProcessTouchAck(WebKit::WebInputEvent::Type type, bool processed); // True if renderer accessibility is enabled. This should only be set when a // screenreader is detected as it can potentially slow down Chrome. diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 435a4da..d36c2d5 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -469,7 +469,8 @@ void RenderWidgetHostViewAura::UnhandledWheelEvent( // Not needed. Mac-only. } -void RenderWidgetHostViewAura::ProcessTouchAck(bool processed) { +void RenderWidgetHostViewAura::ProcessTouchAck( + WebKit::WebInputEvent::Type type, bool processed) { // The ACKs for the touch-events arrive in the same sequence as they were // dispatched. aura::RootWindow* root_window = window_->GetRootWindow(); diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 31a60b1..f6b878c 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h @@ -106,7 +106,8 @@ class RenderWidgetHostViewAura virtual void AcceleratedSurfaceRelease(uint64 surface_id) OVERRIDE; virtual void GetScreenInfo(WebKit::WebScreenInfo* results) OVERRIDE; virtual gfx::Rect GetRootWindowBounds() OVERRIDE; - virtual void ProcessTouchAck(bool processed) OVERRIDE; + virtual void ProcessTouchAck(WebKit::WebInputEvent::Type type, + bool processed) OVERRIDE; virtual void SetHasHorizontalScrollbar( bool has_horizontal_scrollbar) OVERRIDE; virtual void SetScrollOffsetPinning( diff --git a/content/browser/renderer_host/render_widget_host_view_gtk.cc b/content/browser/renderer_host/render_widget_host_view_gtk.cc index 2724063..1f209ca 100644 --- a/content/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/content/browser/renderer_host/render_widget_host_view_gtk.cc @@ -1188,7 +1188,8 @@ void RenderWidgetHostViewGtk::UnhandledWheelEvent( const WebKit::WebMouseWheelEvent& event) { } -void RenderWidgetHostViewGtk::ProcessTouchAck(bool processed) { +void RenderWidgetHostViewGtk::ProcessTouchAck( + WebKit::WebInputEvent::Type type, bool processed) { } void RenderWidgetHostViewGtk::SetHasHorizontalScrollbar( diff --git a/content/browser/renderer_host/render_widget_host_view_gtk.h b/content/browser/renderer_host/render_widget_host_view_gtk.h index 564053e..34fce7c 100644 --- a/content/browser/renderer_host/render_widget_host_view_gtk.h +++ b/content/browser/renderer_host/render_widget_host_view_gtk.h @@ -110,7 +110,8 @@ class RenderWidgetHostViewGtk : public content::RenderWidgetHostViewBase { virtual void AcceleratedSurfaceSuspend() OVERRIDE; virtual void CreatePluginContainer(gfx::PluginWindowHandle id) OVERRIDE; virtual void DestroyPluginContainer(gfx::PluginWindowHandle id) OVERRIDE; - virtual void ProcessTouchAck(bool processed) OVERRIDE; + virtual void ProcessTouchAck(WebKit::WebInputEvent::Type type, + bool processed) OVERRIDE; virtual void SetHasHorizontalScrollbar( bool has_horizontal_scrollbar) OVERRIDE; virtual void SetScrollOffsetPinning( diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h index efcaee8..8878ade 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.h +++ b/content/browser/renderer_host/render_widget_host_view_mac.h @@ -278,7 +278,8 @@ class RenderWidgetHostViewMac : public content::RenderWidgetHostViewBase { // to be reloaded. void ForceTextureReload(); - virtual void ProcessTouchAck(bool processed) OVERRIDE; + virtual void ProcessTouchAck(WebKit::WebInputEvent::Type type, + bool processed) OVERRIDE; virtual void SetHasHorizontalScrollbar( bool has_horizontal_scrollbar) OVERRIDE; virtual void SetScrollOffsetPinning( diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index a60d6af..acff768 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm @@ -1038,7 +1038,8 @@ void RenderWidgetHostViewMac::UnhandledWheelEvent( [cocoa_view_ gotUnhandledWheelEvent]; } -void RenderWidgetHostViewMac::ProcessTouchAck(bool processed) { +void RenderWidgetHostViewMac::ProcessTouchAck( + WebKit::WebInputEvent::Type type, bool processed) { } void RenderWidgetHostViewMac::SetHasHorizontalScrollbar( diff --git a/content/browser/renderer_host/render_widget_host_view_win.cc b/content/browser/renderer_host/render_widget_host_view_win.cc index 344e11b..b4ffe3b 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.cc +++ b/content/browser/renderer_host/render_widget_host_view_win.cc @@ -329,7 +329,8 @@ RenderWidgetHostViewWin::RenderWidgetHostViewWin(RenderWidgetHost* widget) pointer_down_context_(false), focus_on_editable_field_(false), received_focus_change_after_pointer_down_(false), - transparent_region_(0) { + transparent_region_(0), + touch_events_enabled_(false) { render_widget_host_ = static_cast<RenderWidgetHostImpl*>(widget); render_widget_host_->SetView(this); registrar_.Add(this, @@ -910,7 +911,61 @@ void RenderWidgetHostViewWin::UnhandledWheelEvent( const WebKit::WebMouseWheelEvent& event) { } -void RenderWidgetHostViewWin::ProcessTouchAck(bool processed) { +void RenderWidgetHostViewWin::ProcessTouchAck( + WebKit::WebInputEvent::Type type, bool processed) { + if (type == WebKit::WebInputEvent::TouchStart) + UpdateDesiredTouchMode(processed); +} + +void RenderWidgetHostViewWin::SetToGestureMode() { + if (base::win::GetVersion() < base::win::VERSION_WIN7) + return; + UnregisterTouchWindow(m_hWnd); + // Single finger panning is consistent with other windows applications. + const DWORD gesture_allow = GC_PAN_WITH_SINGLE_FINGER_VERTICALLY | + GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; + const DWORD gesture_block = GC_PAN_WITH_GUTTER; + GESTURECONFIG gc[] = { + { GID_ZOOM, GC_ZOOM, 0 }, + { GID_PAN, gesture_allow , gesture_block}, + { GID_TWOFINGERTAP, GC_TWOFINGERTAP , 0}, + { GID_PRESSANDTAP, GC_PRESSANDTAP , 0} + }; + if (!SetGestureConfig(m_hWnd, 0, arraysize(gc), gc, + sizeof(GESTURECONFIG))) { + NOTREACHED(); + } + touch_events_enabled_ = false; +} + +bool RenderWidgetHostViewWin::SetToTouchMode() { + if (base::win::GetVersion() < base::win::VERSION_WIN7) + return false; + bool touch_mode = RegisterTouchWindow(m_hWnd, TWF_WANTPALM) == TRUE; + touch_events_enabled_ = touch_mode; + return touch_mode; +} + +void RenderWidgetHostViewWin::UpdateDesiredTouchMode(bool touch_mode) { + // Make sure that touch events even make sense. + bool touch_mode_valid = base::win::GetVersion() >= base::win::VERSION_WIN7 && + CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableTouchEvents); + touch_mode = touch_mode && touch_mode_valid; + + // Already in correct mode, nothing to do. + if ((touch_mode && touch_events_enabled_) || + (!touch_mode && !touch_events_enabled_)) + return; + + // Now we know that the window's current state doesn't match the desired + // state. If we want touch mode, then we attempt to register for touch + // events, and otherwise to unregister. + if (touch_mode) { + touch_mode = SetToTouchMode(); + } + if (!touch_mode) { + SetToGestureMode(); + } } void RenderWidgetHostViewWin::SetHasHorizontalScrollbar( @@ -932,27 +987,8 @@ LRESULT RenderWidgetHostViewWin::OnCreate(CREATESTRUCT* create_struct) { // scrolled when under the mouse pointer even if inactive. props_.push_back(ui::SetWindowSupportsRerouteMouseWheel(m_hWnd)); - if (base::win::GetVersion() >= base::win::VERSION_WIN7) { - // Use gestures if touch event switch isn't present or registration fails. - if (!CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableTouchEvents) || - !RegisterTouchWindow(m_hWnd, TWF_WANTPALM)) { - // Single finger panning is consistent with other windows applications. - const DWORD gesture_allow = GC_PAN_WITH_SINGLE_FINGER_VERTICALLY | - GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; - const DWORD gesture_block = GC_PAN_WITH_GUTTER; - GESTURECONFIG gc[] = { - { GID_ZOOM, GC_ZOOM, 0 }, - { GID_PAN, gesture_allow , gesture_block}, - { GID_TWOFINGERTAP, GC_TWOFINGERTAP , 0}, - { GID_PRESSANDTAP, GC_PRESSANDTAP , 0} - }; - if (!SetGestureConfig(m_hWnd, 0, arraysize(gc), gc, - sizeof(GESTURECONFIG))) { - NOTREACHED(); - } - } - } + SetToGestureMode(); + return 0; } @@ -1907,6 +1943,23 @@ LRESULT RenderWidgetHostViewWin::OnGestureEvent( render_widget_host_->ForwardWheelEvent( MakeFakeScrollWheelEvent(m_hWnd, start, delta)); } + } else if (gi.dwID == GID_BEGIN) { + // Send a touch event at this location; if the touch start is handled + // then we switch to touch mode, rather than gesture mode (in the ACK). + TOUCHINPUT fake_touch; + fake_touch.x = gi.ptsLocation.x * 100; + fake_touch.y = gi.ptsLocation.y * 100; + fake_touch.cxContact = 100; + fake_touch.cyContact = 100; + fake_touch.dwMask = 0; + fake_touch.dwFlags = TOUCHEVENTF_DOWN | TOUCHEVENTF_PRIMARY; + fake_touch.dwID = gi.dwInstanceID; + touch_state_.UpdateTouchPoints(&fake_touch, 1); + if (touch_state_.is_changed()) + render_widget_host_->ForwardTouchEvent(touch_state_.touch_event()); + } else if (gi.dwID == GID_END) { + if (touch_state_.ReleaseTouchPoints()) + render_widget_host_->ForwardTouchEvent(touch_state_.touch_event()); } ::CloseGestureInfoHandle(gi_handle); return 0; diff --git a/content/browser/renderer_host/render_widget_host_view_win.h b/content/browser/renderer_host/render_widget_host_view_win.h index 839fdde..736eeda 100644 --- a/content/browser/renderer_host/render_widget_host_view_win.h +++ b/content/browser/renderer_host/render_widget_host_view_win.h @@ -197,7 +197,8 @@ class RenderWidgetHostViewWin virtual void SetTooltipText(const string16& tooltip_text) OVERRIDE; virtual BackingStore* AllocBackingStore(const gfx::Size& size) OVERRIDE; virtual void OnAcceleratedCompositingStateChange() OVERRIDE; - virtual void ProcessTouchAck(bool processed) OVERRIDE; + virtual void ProcessTouchAck(WebKit::WebInputEvent::Type type, + bool processed) OVERRIDE; virtual void SetHasHorizontalScrollbar( bool has_horizontal_scrollbar) OVERRIDE; virtual void SetScrollOffsetPinning( @@ -368,6 +369,16 @@ class RenderWidgetHostViewWin // a WM_POINTERDOWN message. void ResetPointerDownContext(); + // Switches between raw-touches mode and gesture mode. Currently touch mode + // will only take effect when kEnableTouchEvents is in effect. + void UpdateDesiredTouchMode(bool touch); + + // Set window to receive gestures. + void SetToGestureMode(); + + // Set window to raw touch events. Returns whether registering was successful. + bool SetToTouchMode(); + // The associated Model. While |this| is being Destroyed, // |render_widget_host_| is NULL and the Windows message loop is run one last // time. Message handlers must check for a NULL |render_widget_host_|. @@ -546,6 +557,9 @@ class RenderWidgetHostViewWin // Region in which the view will be transparent to clicks. gfx::ScopedSkRegion transparent_region_; + // Are touch events currently enabled? + bool touch_events_enabled_; + DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewWin); }; diff --git a/content/browser/renderer_host/test_render_view_host.h b/content/browser/renderer_host/test_render_view_host.h index 029c748..c3b03d8 100644 --- a/content/browser/renderer_host/test_render_view_host.h +++ b/content/browser/renderer_host/test_render_view_host.h @@ -154,7 +154,8 @@ class TestRenderWidgetHostView : public RenderWidgetHostViewBase { virtual void GetScreenInfo(WebKit::WebScreenInfo* results) OVERRIDE {} virtual gfx::Rect GetRootWindowBounds() OVERRIDE; #endif - virtual void ProcessTouchAck(bool processed) OVERRIDE { } + virtual void ProcessTouchAck(WebKit::WebInputEvent::Type type, + bool processed) OVERRIDE { } virtual void SetHasHorizontalScrollbar( bool has_horizontal_scrollbar) OVERRIDE { } virtual void SetScrollOffsetPinning( diff --git a/content/port/browser/render_widget_host_view_port.h b/content/port/browser/render_widget_host_view_port.h index ce18440..a82fd03 100644 --- a/content/port/browser/render_widget_host_view_port.h +++ b/content/port/browser/render_widget_host_view_port.h @@ -226,7 +226,8 @@ class CONTENT_EXPORT RenderWidgetHostViewPort : public RenderWidgetHostView { // prevent-default on a dispatched touch event, the touch events are queued in // the GestureRecognizer until invocation of ProcessTouchAck releases it to be // processed (when |processed| is false) or ignored (when |processed| is true) - virtual void ProcessTouchAck(bool processed) = 0; + virtual void ProcessTouchAck(WebKit::WebInputEvent::Type type, + bool processed) = 0; virtual void SetHasHorizontalScrollbar(bool has_horizontal_scrollbar) = 0; virtual void SetScrollOffsetPinning( |