Changeset 150749 in webkit


Ignore:
Timestamp:
May 27, 2013 5:33:03 AM (11 years ago)
Author:
jocelyn.turcotte@digia.com
Message:

[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):

Location:
trunk/Source
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r150747 r150749  
     12013-05-27  Jocelyn Turcotte  <jocelyn.turcotte@digia.com>
     2
     3        [Qt][Win] Input events aren't mapped properly with windowless plugins.
     4        https://bugs.webkit.org/show_bug.cgi?id=116094
     5
     6        Reviewed by Tor Arne Vestbø.
     7
     8        The events are first sent properly but Flash then immediately repaints
     9        and this causes flickering painting.
     10        The issue is that Flash seems to be doing some input event tracking of
     11        its own internally, using the HWND returned through NPN_GetValue(NPNVnetscapeWindow).
     12
     13        We are currently using two coordinate systems for windowless plugins on Windows with Qt:
     14        - FrameView coordinates: Used for input events and ajusted with the WM_WINDOWPOSCHANGED message
     15        - Drawable coordinates: Used by WM_PAINT and adjusted with NPP_SetWindow
     16
     17        This patch fixes the bug by mapping input events to the native window returned
     18        as NPNVnetscapeWindow instead of the FrameView to ensure that those coordinates will match
     19        the ones used by Flash internally.
     20        With this we shouldn't be using FrameView coordinates anywhere for windowless plugins
     21        on Windows with Qt.
     22
     23        * platform/qt/QWebPageClient.h:
     24        (QWebPageClient):
     25          Added mapToOwnerWindow to the interface, mapping from the FrameView up to the wrapping nativeParentWidget.
     26        * plugins/win/PluginViewWin.cpp:
     27        (WebCore::contentsToNativeWindow):
     28        (WebCore::PluginView::paintIntoTransformedContext):
     29        (WebCore::PluginView::handleMouseEvent):
     30
    1312013-05-27  Antti Koivisto  <antti@apple.com>
    232
  • trunk/Source/WebCore/platform/qt/QWebPageClient.h

    r136235 r150749  
    8787    virtual QObject* ownerWidget() const = 0;
    8888    virtual QRect geometryRelativeToOwnerWidget() const = 0;
     89    virtual QPoint mapToOwnerWindow(const QPoint&) const = 0;
    8990
    9091    virtual QObject* pluginParent() const = 0;
  • trunk/Source/WebCore/plugins/win/PluginViewWin.cpp

    r150214 r150749  
    346346}
    347347
     348static inline IntPoint contentsToNativeWindow(FrameView* view, const IntPoint& point)
     349{
     350#if PLATFORM(QT)
     351    // Our web view's QWidget isn't necessarily a native window itself. Map the position
     352    // all the way up to the QWidget associated with the HWND returned as NPNVnetscapeWindow.
     353    PlatformPageClient client = view->hostWindow()->platformPageClient();
     354    return client->mapToOwnerWindow(view->contentsToWindow(point));
     355#else
     356    return view->contentsToWindow(point);
     357#endif
     358}
     359
     360static inline IntRect contentsToNativeWindow(FrameView* view, const IntRect& rect)
     361{
     362#if PLATFORM(QT)
     363    // This only handles translation of the rect.
     364    ASSERT(view->contentsToWindow(rect).size() == rect.size());
     365    return IntRect(contentsToNativeWindow(view, rect.location()), rect.size());
     366#else
     367    return view->contentsToWindow(rect);
     368#endif
     369}
     370
    348371LRESULT
    349372PluginView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
     
    542565    WINDOWPOS windowpos = { 0, 0, 0, 0, 0, 0, 0 };
    543566
    544     IntRect r = toFrameView(parent())->contentsToWindow(frameRect());
     567    IntRect r = contentsToNativeWindow(toFrameView(parent()), frameRect());
    545568
    546569    windowpos.x = r.x();
     
    691714    NPEvent npEvent;
    692715
    693     IntPoint p = toFrameView(parent())->contentsToWindow(IntPoint(event->pageX(), event->pageY()));
     716    IntPoint p = contentsToNativeWindow(toFrameView(parent()), IntPoint(event->pageX(), event->pageY()));
    694717
    695718    npEvent.lParam = MAKELPARAM(p.x(), p.y());
  • trunk/Source/WebKit/qt/ChangeLog

    r150663 r150749  
     12013-05-27  Jocelyn Turcotte  <jocelyn.turcotte@digia.com>
     2
     3        [Qt][Win] Input events aren't mapped properly with windowless plugins.
     4        https://bugs.webkit.org/show_bug.cgi?id=116094
     5
     6        Reviewed by Tor Arne Vestbø.
     7
     8        * WidgetSupport/PageClientQt.cpp:
     9        (WebCore::PageClientQWidget::mapToOwnerWindow):
     10        (WebCore::PageClientQGraphicsWidget::makeOpenGLContextCurrentIfAvailable):
     11        (WebCore::PageClientQGraphicsWidget::screenNumber):
     12        (WebCore::PageClientQGraphicsWidget::geometryRelativeToOwnerWidget):
     13        (WebCore::PageClientQGraphicsWidget::mapToOwnerWindow):
     14        (WebCore::PageClientQGraphicsWidget::graphicsItemVisibleRect):
     15        (WebCore::PageClientQGraphicsWidget::firstGraphicsView):
     16          Extracted this common logic from makeOpenGLContextCurrentIfAvailable,
     17          screenNumber, geometryRelativeToOwnerWidget and graphicsItemVisibleRect
     18          to be able to use it in mapToOwnerWindow.
     19        * WidgetSupport/PageClientQt.h:
     20        (PageClientQWidget):
     21        (PageClientQGraphicsWidget):
     22
    1232013-05-24  Christophe Dumez  <ch.dumez@sisa.samsung.com>
    224
  • trunk/Source/WebKit/qt/WidgetSupport/PageClientQt.cpp

    r136235 r150749  
    121121}
    122122
     123QPoint PageClientQWidget::mapToOwnerWindow(const QPoint& point) const
     124{
     125    QWidget* widget = qobject_cast<QWidget*>(ownerWidget());
     126    // Can be false both if ownerWidget() is native or if it doesn't have any native parent.
     127    if (const QWidget *nativeParent = widget->nativeParentWidget())
     128        return widget->mapTo(nativeParent, point);
     129
     130    return point;
     131}
     132
    123133QObject* PageClientQWidget::pluginParent() const
    124134{
     
    171181{
    172182#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER_GL) && defined(QT_OPENGL_LIB)
    173     QGraphicsView* graphicsView = view->scene()->views()[0];
     183    QGraphicsView* graphicsView = firstGraphicsView();
    174184    if (graphicsView && graphicsView->viewport()) {
    175185        QGLWidget* glWidget = qobject_cast<QGLWidget*>(graphicsView->viewport());
     
    219229{
    220230#if defined(Q_WS_X11)
    221     if (QGraphicsScene* scene = view->scene()) {
    222         const QList<QGraphicsView*> views = scene->views();
    223 
    224         if (!views.isEmpty())
    225             return views.at(0)->x11Info().screen();
    226     }
    227 #endif
    228 
     231    if (QGraphicsView* graphicsView = firstGraphicsView())
     232        return graphicsView->x11Info().screen();
     233#endif
    229234    return 0;
    230235}
     
    241246QRect PageClientQGraphicsWidget::geometryRelativeToOwnerWidget() const
    242247{
    243     if (!view->scene())
    244         return QRect();
    245 
    246     QList<QGraphicsView*> views = view->scene()->views();
    247     if (views.isEmpty())
    248         return QRect();
    249 
    250     QGraphicsView* graphicsView = views.at(0);
    251     return graphicsView->mapFromScene(view->boundingRect()).boundingRect();
     248    if (QGraphicsView* graphicsView = firstGraphicsView())
     249        return graphicsView->mapFromScene(view->boundingRect()).boundingRect();
     250    return QRect();
     251}
     252
     253QPoint PageClientQGraphicsWidget::mapToOwnerWindow(const QPoint& point) const
     254{
     255    if (const QGraphicsView* graphicsView = firstGraphicsView())
     256        if (const QWidget *nativeParent = graphicsView->nativeParentWidget())
     257            return graphicsView->mapTo(nativeParent, graphicsView->mapFromScene(view->mapToScene(point)));
     258    return point;
    252259}
    253260
     
    255262QRectF PageClientQGraphicsWidget::graphicsItemVisibleRect() const
    256263{
    257     if (!view->scene())
     264    QGraphicsView* graphicsView = firstGraphicsView();
     265    if (!graphicsView)
    258266        return QRectF();
    259267
    260     QList<QGraphicsView*> views = view->scene()->views();
    261     if (views.isEmpty())
    262         return QRectF();
    263 
    264     QGraphicsView* graphicsView = views.at(0);
    265268    int xOffset = graphicsView->horizontalScrollBar()->value();
    266269    int yOffset = graphicsView->verticalScrollBar()->value();
     
    292295    return view->scene()->sceneRect();
    293296}
     297
     298QGraphicsView* PageClientQGraphicsWidget::firstGraphicsView() const
     299{
     300    if (view->scene() && !view->scene()->views().isEmpty())
     301        return view->scene()->views().first();
     302    return 0;
     303}
    294304#endif // QT_NO_GRAPHICSVIEW
    295305
  • trunk/Source/WebKit/qt/WidgetSupport/PageClientQt.h

    r136235 r150749  
    7373    virtual QObject* ownerWidget() const;
    7474    virtual QRect geometryRelativeToOwnerWidget() const;
     75    virtual QPoint mapToOwnerWindow(const QPoint&) const;
    7576
    7677    virtual QObject* pluginParent() const;
     
    159160    virtual QObject* ownerWidget() const;
    160161    virtual QRect geometryRelativeToOwnerWidget() const;
     162    virtual QPoint mapToOwnerWindow(const QPoint&) const;
    161163
    162164    virtual QObject* pluginParent() const;
     
    176178    virtual QRectF windowRect() const;
    177179
     180    QGraphicsView* firstGraphicsView() const;
     181
    178182    QGraphicsWebView* view;
    179183    QWebPage* page;
Note: See TracChangeset for help on using the changeset viewer.