diff options
author | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2013-05-27 12:33:03 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-06-04 20:34:15 +0200 |
commit | 0376f73239d78abcd99fcb2dec82e8d1b5132296 (patch) | |
tree | 5818d4b98d4b1c9f0b843edc9ff8c0a08f37b2db | |
parent | ac00a345b23686aa458539dde0cb3711bed84de3 (diff) | |
download | qtwebkit-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.h | 1 | ||||
-rw-r--r-- | Source/WebCore/plugins/win/PluginViewWin.cpp | 27 | ||||
-rw-r--r-- | Source/WebKit/qt/WidgetSupport/PageClientQt.cpp | 54 | ||||
-rw-r--r-- | Source/WebKit/qt/WidgetSupport/PageClientQt.h | 4 |
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; |