summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2013-07-31 14:04:38 +0200
committerJocelyn Turcotte <jocelyn.turcotte@digia.com>2013-08-01 12:20:45 +0200
commita3cc1b314270041b0746edb3359756188ff1487c (patch)
tree0fde0c56135c3d1eaf15327b687236c0463373ae /lib
parentf3db445d66924153905997c91f6aa4b36e787ea7 (diff)
Use ui::GestureRecognizer to enable viewport gestures.
This enables panning and zooming using touch events. Also map touch IDs given by Qt to 0-based IDs since the gesture recognizer expects it. It currently needs the following command line switches to be enabled: --force-compositing-mode --enable-threaded-compositing --enable-pinch Change-Id: I34db3203529470aef5426ddfaa65af7d67e4b017 Reviewed-by: Andras Becsi <andras.becsi@digia.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/render_widget_host_view_qt.cpp78
-rw-r--r--lib/render_widget_host_view_qt.h17
2 files changed, 93 insertions, 2 deletions
diff --git a/lib/render_widget_host_view_qt.cpp b/lib/render_widget_host_view_qt.cpp
index 5ee1ff359..ad6544afa 100644
--- a/lib/render_widget_host_view_qt.cpp
+++ b/lib/render_widget_host_view_qt.cpp
@@ -95,6 +95,7 @@ static void UpdateWebTouchEventAfterDispatch(WebKit::WebTouchEvent* event, WebKi
RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget)
: m_host(content::RenderWidgetHostImpl::From(widget))
+ , m_gestureRecognizer(ui::GestureRecognizer::Create(this))
{
m_host->SetView(this);
}
@@ -475,12 +476,80 @@ void RenderWidgetHostViewQt::OnAccessibilityNotifications(const std::vector<Acce
QT_NOT_USED
}
+bool RenderWidgetHostViewQt::DispatchLongPressGestureEvent(ui::GestureEvent *)
+{
+ return false;
+}
+
+bool RenderWidgetHostViewQt::DispatchCancelTouchEvent(ui::TouchEvent *)
+{
+ return false;
+}
+
+void RenderWidgetHostViewQt::ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) {
+ ScopedVector<ui::TouchEvent> events;
+ if (!content::MakeUITouchEventsFromWebTouchEvents(touch, &events, content::LOCAL_COORDINATES))
+ return;
+
+ ui::EventResult result = (ack_result == content::INPUT_EVENT_ACK_STATE_CONSUMED) ? ui::ER_HANDLED : ui::ER_UNHANDLED;
+ for (ScopedVector<ui::TouchEvent>::iterator iter = events.begin(), end = events.end(); iter != end; ++iter) {
+ (*iter)->latency()->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACKED_COMPONENT, static_cast<int64>(ack_result), 0);
+ scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
+ gestures.reset(m_gestureRecognizer->ProcessTouchEventForGesture(*(*iter), result, this));
+ ProcessGestures(gestures.get());
+ }
+}
+
void RenderWidgetHostViewQt::Paint(const gfx::Rect& damage_rect)
{
QRect r(damage_rect.x(), damage_rect.y(), damage_rect.width(), damage_rect.height());
m_delegate->update(r);
}
+
+void RenderWidgetHostViewQt::ProcessGestures(ui::GestureRecognizer::Gestures *gestures)
+{
+ if (!gestures || gestures->empty())
+ return;
+ for (ui::GestureRecognizer::Gestures::iterator g_it = gestures->begin(); g_it != gestures->end(); ++g_it) {
+ const ui::GestureEvent &uiGestureEvent = **g_it;
+ WebKit::WebGestureEvent webGestureEvent = content::MakeWebGestureEventFromUIEvent(uiGestureEvent);
+ if (webGestureEvent.type != WebKit::WebInputEvent::Undefined) {
+ webGestureEvent.x = uiGestureEvent.x();
+ webGestureEvent.y = uiGestureEvent.y();
+ m_host->ForwardGestureEvent(webGestureEvent);
+ }
+ }
+}
+
+// Find (or create) a mapping to a 0-based ID.
+int RenderWidgetHostViewQt::GetMappedTouch(int qtTouchId)
+{
+ QMap<int, int>::const_iterator it = m_touchIdMapping.find(qtTouchId);
+ if (it != m_touchIdMapping.end())
+ return it.value();
+ int nextValue = 0;
+ for (it = m_touchIdMapping.begin(); it != m_touchIdMapping.end(); ++it)
+ nextValue = std::max(nextValue, it.value() + 1);
+ m_touchIdMapping[qtTouchId] = nextValue;
+ return nextValue;
+}
+
+void RenderWidgetHostViewQt::RemoveExpiredMappings(QTouchEvent *ev)
+{
+ QMap<int, int> newMap;
+ for (QMap<int, int>::const_iterator it = m_touchIdMapping.begin(); it != m_touchIdMapping.end(); ++it) {
+ Q_FOREACH (const QTouchEvent::TouchPoint& touchPoint, ev->touchPoints()) {
+ if ((touchPoint.id() == it.key()) &&
+ (touchPoint.state() != Qt::TouchPointReleased)) {
+ newMap.insert(it.key(), it.value());
+ break;
+ }
+ }
+ }
+ m_touchIdMapping.swap(newMap);
+}
+
bool RenderWidgetHostViewQt::IsPopup() const
{
return popup_type_ != WebKit::WebPopupTypeNone;
@@ -518,7 +587,7 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
toUIEventType(touchPoint.state()),
toGfxPoint(touchPoint.pos().toPoint()),
0, // flags
- touchPoint.id(),
+ GetMappedTouch(touchPoint.id()),
timestamp,
0, 0, // radius
0, // angle
@@ -527,10 +596,17 @@ void RenderWidgetHostViewQt::handleTouchEvent(QTouchEvent *ev)
WebKit::WebTouchPoint *point = content::UpdateWebTouchEventFromUIEvent(uiEvent, &m_accumTouchEvent);
if (point) {
if (m_host->ShouldForwardTouchEvent())
+ // This will come back through ProcessAckedTouchEvent if the page didn't want it.
m_host->ForwardTouchEventWithLatencyInfo(m_accumTouchEvent, ui::LatencyInfo());
+ else {
+ scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
+ gestures.reset(m_gestureRecognizer->ProcessTouchEventForGesture(uiEvent, ui::ER_UNHANDLED, this));
+ ProcessGestures(gestures.get());
+ }
UpdateWebTouchEventAfterDispatch(&m_accumTouchEvent, point);
}
}
+ RemoveExpiredMappings(ev);
}
void RenderWidgetHostViewQt::handleFocusEvent(QFocusEvent *ev)
diff --git a/lib/render_widget_host_view_qt.h b/lib/render_widget_host_view_qt.h
index 542448424..22fe22512 100644
--- a/lib/render_widget_host_view_qt.h
+++ b/lib/render_widget_host_view_qt.h
@@ -46,7 +46,10 @@
#include "base/memory/scoped_ptr.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
-#include <qglobal.h>
+#include "ui/base/gestures/gesture_recognizer.h"
+#include "ui/base/gestures/gesture_types.h"
+#include <QMap>
+#include <QtGlobal>
class BackingStoreQt;
class QEvent;
@@ -59,6 +62,8 @@ class RenderWidgetHostViewQtDelegate;
class RenderWidgetHostViewQt
: public content::RenderWidgetHostViewBase
+ , public ui::GestureConsumer
+ , public ui::GestureEventHelper
{
public:
RenderWidgetHostViewQt(content::RenderWidgetHost* widget);
@@ -124,6 +129,11 @@ public:
virtual void SetHasHorizontalScrollbar(bool);
virtual void SetScrollOffsetPinning(bool, bool);
virtual void OnAccessibilityNotifications(const std::vector<AccessibilityHostMsg_NotificationParams>&);
+ virtual void ProcessAckedTouchEvent(const content::TouchEventWithLatencyInfo &touch, content::InputEventAckState ack_result) Q_DECL_OVERRIDE;
+
+ // Overridden from ui::GestureEventHelper.
+ virtual bool DispatchLongPressGestureEvent(ui::GestureEvent *event) Q_DECL_OVERRIDE;
+ virtual bool DispatchCancelTouchEvent(ui::TouchEvent *event) Q_DECL_OVERRIDE;
void handleMouseEvent(QMouseEvent*);
void handleKeyEvent(QKeyEvent*);
@@ -147,10 +157,15 @@ public:
private:
void Paint(const gfx::Rect& damage_rect);
+ void ProcessGestures(ui::GestureRecognizer::Gestures *gestures);
+ int GetMappedTouch(int qtTouchId);
+ void RemoveExpiredMappings(QTouchEvent *ev);
bool IsPopup() const;
content::RenderWidgetHostImpl *m_host;
+ scoped_ptr<ui::GestureRecognizer> m_gestureRecognizer;
+ QMap<int, int> m_touchIdMapping;
WebKit::WebTouchEvent m_accumTouchEvent;
scoped_ptr<RenderWidgetHostViewQtDelegate> m_delegate;
gfx::Size m_requestedSize;