summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>2013-05-27 12:33:03 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-06-04 20:34:15 +0200
commit0376f73239d78abcd99fcb2dec82e8d1b5132296 (patch)
tree5818d4b98d4b1c9f0b843edc9ff8c0a08f37b2db
parentac00a345b23686aa458539dde0cb3711bed84de3 (diff)
downloadqtwebkit-0376f73239d78abcd99fcb2dec82e8d1b5132296.tar.gz
[Qt][Win] Input events aren't mapped properly with windowless plugins.
https://bugs.webkit.org/show_bug.cgi?id=116094 Reviewed by Tor Arne Vestbø. Source/WebCore: The events are first sent properly but Flash then immediately repaints and this causes flickering painting. The issue is that Flash seems to be doing some input event tracking of its own internally, using the HWND returned through NPN_GetValue(NPNVnetscapeWindow). We are currently using two coordinate systems for windowless plugins on Windows with Qt: - FrameView coordinates: Used for input events and ajusted with the WM_WINDOWPOSCHANGED message - Drawable coordinates: Used by WM_PAINT and adjusted with NPP_SetWindow This patch fixes the bug by mapping input events to the native window returned as NPNVnetscapeWindow instead of the FrameView to ensure that those coordinates will match the ones used by Flash internally. With this we shouldn't be using FrameView coordinates anywhere for windowless plugins on Windows with Qt. * platform/qt/QWebPageClient.h: (QWebPageClient): Added mapToOwnerWindow to the interface, mapping from the FrameView up to the wrapping nativeParentWidget. * plugins/win/PluginViewWin.cpp: (WebCore::contentsToNativeWindow): (WebCore::PluginView::paintIntoTransformedContext): (WebCore::PluginView::handleMouseEvent): Source/WebKit/qt: * WidgetSupport/PageClientQt.cpp: (WebCore::PageClientQWidget::mapToOwnerWindow): (WebCore::PageClientQGraphicsWidget::makeOpenGLContextCurrentIfAvailable): (WebCore::PageClientQGraphicsWidget::screenNumber): (WebCore::PageClientQGraphicsWidget::geometryRelativeToOwnerWidget): (WebCore::PageClientQGraphicsWidget::mapToOwnerWindow): (WebCore::PageClientQGraphicsWidget::graphicsItemVisibleRect): (WebCore::PageClientQGraphicsWidget::firstGraphicsView): Extracted this common logic from makeOpenGLContextCurrentIfAvailable, screenNumber, geometryRelativeToOwnerWidget and graphicsItemVisibleRect to be able to use it in mapToOwnerWindow. * WidgetSupport/PageClientQt.h: (PageClientQWidget): (PageClientQGraphicsWidget): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@150749 268f45cc-cd09-0410-ab3c-d52691b4dbfc Conflicts: Source/WebCore/plugins/win/PluginViewWin.cpp Change-Id: I11ec6b6a9377c3e09b775d24fffb8572decbd0a5 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
-rw-r--r--Source/WebCore/platform/qt/QWebPageClient.h1
-rw-r--r--Source/WebCore/plugins/win/PluginViewWin.cpp27
-rw-r--r--Source/WebKit/qt/WidgetSupport/PageClientQt.cpp54
-rw-r--r--Source/WebKit/qt/WidgetSupport/PageClientQt.h4
4 files changed, 62 insertions, 24 deletions
diff --git a/Source/WebCore/platform/qt/QWebPageClient.h b/Source/WebCore/platform/qt/QWebPageClient.h
index 1526e9d20..da9ef05de 100644
--- a/Source/WebCore/platform/qt/QWebPageClient.h
+++ b/Source/WebCore/platform/qt/QWebPageClient.h
@@ -86,6 +86,7 @@ public:
virtual int screenNumber() const = 0;
virtual QObject* ownerWidget() const = 0;
virtual QRect geometryRelativeToOwnerWidget() const = 0;
+ virtual QPoint mapToOwnerWindow(const QPoint&) const = 0;
virtual QObject* pluginParent() const = 0;
diff --git a/Source/WebCore/plugins/win/PluginViewWin.cpp b/Source/WebCore/plugins/win/PluginViewWin.cpp
index bd14cd948..7160d8a99 100644
--- a/Source/WebCore/plugins/win/PluginViewWin.cpp
+++ b/Source/WebCore/plugins/win/PluginViewWin.cpp
@@ -357,6 +357,29 @@ static bool isWindowsMessageUserGesture(UINT message)
}
}
+static inline IntPoint contentsToNativeWindow(FrameView* view, const IntPoint& point)
+{
+#if PLATFORM(QT)
+ // Our web view's QWidget isn't necessarily a native window itself. Map the position
+ // all the way up to the QWidget associated with the HWND returned as NPNVnetscapeWindow.
+ PlatformPageClient client = view->hostWindow()->platformPageClient();
+ return client->mapToOwnerWindow(view->contentsToWindow(point));
+#else
+ return view->contentsToWindow(point);
+#endif
+}
+
+static inline IntRect contentsToNativeWindow(FrameView* view, const IntRect& rect)
+{
+#if PLATFORM(QT)
+ // This only handles translation of the rect.
+ ASSERT(view->contentsToWindow(rect).size() == rect.size());
+ return IntRect(contentsToNativeWindow(view, rect.location()), rect.size());
+#else
+ return view->contentsToWindow(rect);
+#endif
+}
+
LRESULT
PluginView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
@@ -553,7 +576,7 @@ void PluginView::paintIntoTransformedContext(HDC hdc)
WINDOWPOS windowpos = { 0, 0, 0, 0, 0, 0, 0 };
- IntRect r = static_cast<FrameView*>(parent())->contentsToWindow(frameRect());
+ IntRect r = contentsToNativeWindow(static_cast<FrameView*>(parent()), frameRect());
windowpos.x = r.x();
windowpos.y = r.y();
@@ -702,7 +725,7 @@ void PluginView::handleMouseEvent(MouseEvent* event)
NPEvent npEvent;
- IntPoint p = static_cast<FrameView*>(parent())->contentsToWindow(IntPoint(event->pageX(), event->pageY()));
+ IntPoint p = contentsToNativeWindow(static_cast<FrameView*>(parent()), IntPoint(event->pageX(), event->pageY()));
npEvent.lParam = MAKELPARAM(p.x(), p.y());
npEvent.wParam = 0;
diff --git a/Source/WebKit/qt/WidgetSupport/PageClientQt.cpp b/Source/WebKit/qt/WidgetSupport/PageClientQt.cpp
index 095f9e582..8f486d594 100644
--- a/Source/WebKit/qt/WidgetSupport/PageClientQt.cpp
+++ b/Source/WebKit/qt/WidgetSupport/PageClientQt.cpp
@@ -120,6 +120,16 @@ QRect PageClientQWidget::geometryRelativeToOwnerWidget() const
return view->geometry();
}
+QPoint PageClientQWidget::mapToOwnerWindow(const QPoint& point) const
+{
+ QWidget* widget = qobject_cast<QWidget*>(ownerWidget());
+ // Can be false both if ownerWidget() is native or if it doesn't have any native parent.
+ if (const QWidget *nativeParent = widget->nativeParentWidget())
+ return widget->mapTo(nativeParent, point);
+
+ return point;
+}
+
QObject* PageClientQWidget::pluginParent() const
{
return view;
@@ -170,7 +180,7 @@ void PageClientQGraphicsWidget::repaintViewport()
bool PageClientQGraphicsWidget::makeOpenGLContextCurrentIfAvailable()
{
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER_GL) && defined(QT_OPENGL_LIB)
- QGraphicsView* graphicsView = view->scene()->views()[0];
+ QGraphicsView* graphicsView = firstGraphicsView();
if (graphicsView && graphicsView->viewport()) {
QGLWidget* glWidget = qobject_cast<QGLWidget*>(graphicsView->viewport());
if (glWidget) {
@@ -218,14 +228,9 @@ QPalette PageClientQGraphicsWidget::palette() const
int PageClientQGraphicsWidget::screenNumber() const
{
#if defined(Q_WS_X11)
- if (QGraphicsScene* scene = view->scene()) {
- const QList<QGraphicsView*> views = scene->views();
-
- if (!views.isEmpty())
- return views.at(0)->x11Info().screen();
- }
+ if (QGraphicsView* graphicsView = firstGraphicsView())
+ return graphicsView->x11Info().screen();
#endif
-
return 0;
}
@@ -240,28 +245,26 @@ QObject* PageClientQGraphicsWidget::ownerWidget() const
QRect PageClientQGraphicsWidget::geometryRelativeToOwnerWidget() const
{
- if (!view->scene())
- return QRect();
-
- QList<QGraphicsView*> views = view->scene()->views();
- if (views.isEmpty())
- return QRect();
+ if (QGraphicsView* graphicsView = firstGraphicsView())
+ return graphicsView->mapFromScene(view->boundingRect()).boundingRect();
+ return QRect();
+}
- QGraphicsView* graphicsView = views.at(0);
- return graphicsView->mapFromScene(view->boundingRect()).boundingRect();
+QPoint PageClientQGraphicsWidget::mapToOwnerWindow(const QPoint& point) const
+{
+ if (const QGraphicsView* graphicsView = firstGraphicsView())
+ if (const QWidget *nativeParent = graphicsView->nativeParentWidget())
+ return graphicsView->mapTo(nativeParent, graphicsView->mapFromScene(view->mapToScene(point)));
+ return point;
}
#if USE(TILED_BACKING_STORE)
QRectF PageClientQGraphicsWidget::graphicsItemVisibleRect() const
{
- if (!view->scene())
+ QGraphicsView* graphicsView = firstGraphicsView();
+ if (!graphicsView)
return QRectF();
- QList<QGraphicsView*> views = view->scene()->views();
- if (views.isEmpty())
- return QRectF();
-
- QGraphicsView* graphicsView = views.at(0);
int xOffset = graphicsView->horizontalScrollBar()->value();
int yOffset = graphicsView->verticalScrollBar()->value();
return view->mapRectFromScene(QRectF(QPointF(xOffset, yOffset), graphicsView->viewport()->size()));
@@ -291,6 +294,13 @@ QRectF PageClientQGraphicsWidget::windowRect() const
// The sceneRect is a good approximation of the size of the application, independent of the view.
return view->scene()->sceneRect();
}
+
+QGraphicsView* PageClientQGraphicsWidget::firstGraphicsView() const
+{
+ if (view->scene() && !view->scene()->views().isEmpty())
+ return view->scene()->views().first();
+ return 0;
+}
#endif // QT_NO_GRAPHICSVIEW
} // namespace WebCore
diff --git a/Source/WebKit/qt/WidgetSupport/PageClientQt.h b/Source/WebKit/qt/WidgetSupport/PageClientQt.h
index 63a80ad03..e9da360bc 100644
--- a/Source/WebKit/qt/WidgetSupport/PageClientQt.h
+++ b/Source/WebKit/qt/WidgetSupport/PageClientQt.h
@@ -72,6 +72,7 @@ public:
virtual int screenNumber() const;
virtual QObject* ownerWidget() const;
virtual QRect geometryRelativeToOwnerWidget() const;
+ virtual QPoint mapToOwnerWindow(const QPoint&) const;
virtual QObject* pluginParent() const;
@@ -158,6 +159,7 @@ public:
virtual int screenNumber() const;
virtual QObject* ownerWidget() const;
virtual QRect geometryRelativeToOwnerWidget() const;
+ virtual QPoint mapToOwnerWindow(const QPoint&) const;
virtual QObject* pluginParent() const;
@@ -175,6 +177,8 @@ public:
virtual QRectF windowRect() const;
+ QGraphicsView* firstGraphicsView() const;
+
QGraphicsWebView* view;
QWebPage* page;
bool viewResizesToContents;