From 0376f73239d78abcd99fcb2dec82e8d1b5132296 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Mon, 27 May 2013 12:33:03 +0000 Subject: [Qt][Win] Input events aren't mapped properly with windowless plugins. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- Source/WebCore/platform/qt/QWebPageClient.h | 1 + Source/WebCore/plugins/win/PluginViewWin.cpp | 27 ++++++++++++- Source/WebKit/qt/WidgetSupport/PageClientQt.cpp | 54 +++++++++++++++---------- 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(parent())->contentsToWindow(frameRect()); + IntRect r = contentsToNativeWindow(static_cast(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(parent())->contentsToWindow(IntPoint(event->pageX(), event->pageY())); + IntPoint p = contentsToNativeWindow(static_cast(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(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(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 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 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 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; -- cgit v1.2.1 From 43d40815e5ed44a3dbc89380ae4b8975c4f86cb7 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Tue, 4 Jun 2013 14:41:32 +0000 Subject: [Qt] Fix a crash in QtPixmapRuntime. https://bugs.webkit.org/show_bug.cgi?id=117193 Reviewed by Allan Sandfeld Jensen. The crash could only be reproduced in release builds on Windows. JSClassCreate calculates the size of JSClassDefinition.staticValues and staticFunctions by iterating until an entry with a null name is found. * bridge/qt/qt_pixmapruntime.cpp: (JSC::Bindings::QtPixmapRuntime::getClassRef): Task-number: QTBUG-30736 Change-Id: I443c69fd6772b78edbdadb6270c30229b30d992d git-svn-id: http://svn.webkit.org/repository/webkit/trunk@151170 268f45cc-cd09-0410-ab3c-d52691b4dbfc Reviewed-by: Allan Sandfeld Jensen --- Source/WebCore/bridge/qt/qt_pixmapruntime.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp b/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp index f50465979..1ddf4fdf3 100644 --- a/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp +++ b/Source/WebCore/bridge/qt/qt_pixmapruntime.cpp @@ -249,14 +249,16 @@ JSClassRef QtPixmapRuntime::getClassRef() { static const JSStaticValue staticValues[] = { { "width", getPixmapWidth, 0, 0 }, - { "height", getPixmapHeight, 0, 0 } + { "height", getPixmapHeight, 0, 0 }, + { 0, 0, 0, 0} }; static const JSStaticFunction staticFunctions[] = { { "assignToHTMLImageElement", assignToHTMLImageElement, 0 }, { "toDataUrl", pixmapToDataUrl, 0 }, { "toImageData", pixmapToImageData, 0 }, - { "toString", pixmapToString, 0 } + { "toString", pixmapToString, 0 }, + { 0, 0, 0 } }; static const JSClassDefinition classDefinition = { -- cgit v1.2.1 From 9769275688aec7a53b55b66bde961b18c32c6d51 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 5 Jun 2013 18:43:34 +0200 Subject: Make PNGImageDecoder::rowAvailable auto-vectorizable https://bugs.webkit.org/show_bug.cgi?id=116151 Reviewed by Benjamin Poulain. Changed the main loops under PNGImageDecoder::rowAvailable so that they avoid branches and non-sequential table look ups. Together with automatic vectorization by the compiler this provides around 4x speed-up with AVX or 2x speed-up on generic x64. Shaving off 12-40% on PNG decoding in general. * platform/graphics/Color.cpp: (WebCore::premultipliedARGBFromColor): * platform/graphics/Color.h: (WebCore::fastDivideBy255): * platform/graphics/filters/FEBlend.cpp: * platform/image-decoders/png/PNGImageDecoder.cpp: (WebCore::setPixelRGB): (WebCore::setPixelRGBA): (WebCore::setPixelRGBA_Premultiplied): (WebCore::PNGImageDecoder::rowAvailable): Change-Id: Ic3d6cefda505ebceb37165d0a7aeb3cd2fe3e2c9 git-svn-id: http://svn.webkit.org/repository/webkit/trunk@150252 268f45cc-cd09-0410-ab3c-d52691b4dbfc Reviewed-by: Jocelyn Turcotte --- Source/WebCore/platform/graphics/Color.cpp | 6 +- Source/WebCore/platform/graphics/Color.h | 8 +++ .../WebCore/platform/graphics/filters/FEBlend.cpp | 8 --- .../image-decoders/png/PNGImageDecoder.cpp | 68 ++++++++++++++++------ 4 files changed, 62 insertions(+), 28 deletions(-) diff --git a/Source/WebCore/platform/graphics/Color.cpp b/Source/WebCore/platform/graphics/Color.cpp index 04dc73ea6..51c710007 100644 --- a/Source/WebCore/platform/graphics/Color.cpp +++ b/Source/WebCore/platform/graphics/Color.cpp @@ -434,9 +434,9 @@ RGBA32 premultipliedARGBFromColor(const Color& color) unsigned alpha = color.alpha(); if (alpha < 255) { pixelColor = Color::createUnchecked( - (color.red() * alpha + 254) / 255, - (color.green() * alpha + 254) / 255, - (color.blue() * alpha + 254) / 255, + fastDivideBy255(color.red() * alpha + 254), + fastDivideBy255(color.green() * alpha + 254), + fastDivideBy255(color.blue() * alpha + 254), alpha).rgb(); } else pixelColor = color.rgb(); diff --git a/Source/WebCore/platform/graphics/Color.h b/Source/WebCore/platform/graphics/Color.h index 87ca23375..9e4ce8c11 100644 --- a/Source/WebCore/platform/graphics/Color.h +++ b/Source/WebCore/platform/graphics/Color.h @@ -211,6 +211,14 @@ inline Color blend(const Color& from, const Color& to, double progress, bool ble blend(from.alpha(), to.alpha(), progress)); } +inline uint16_t fastDivideBy255(uint16_t value) +{ + // This is an approximate algorithm for division by 255, but it gives accurate results for 16bit values. + uint16_t approximation = value >> 8; + uint16_t remainder = value - (approximation * 255) + 1; + return approximation + (remainder >> 8); +} + #if USE(CG) CGColorRef cachedCGColor(const Color&, ColorSpace); #endif diff --git a/Source/WebCore/platform/graphics/filters/FEBlend.cpp b/Source/WebCore/platform/graphics/filters/FEBlend.cpp index d5897c392..bf527ff53 100644 --- a/Source/WebCore/platform/graphics/filters/FEBlend.cpp +++ b/Source/WebCore/platform/graphics/filters/FEBlend.cpp @@ -63,14 +63,6 @@ bool FEBlend::setBlendMode(BlendModeType mode) return true; } -static inline unsigned char fastDivideBy255(uint16_t value) -{ - // This is an approximate algorithm for division by 255, but it gives accurate results for 16bit values. - uint16_t quotient = value >> 8; - uint16_t remainder = value - (quotient * 255) + 1; - return quotient + (remainder >> 8); -} - inline unsigned char feBlendNormal(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char) { return fastDivideBy255((255 - alphaA) * colorB + colorA * 255); diff --git a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp index 7984c9ae8..776acce2b 100644 --- a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp +++ b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp @@ -40,6 +40,7 @@ #include "config.h" #include "PNGImageDecoder.h" +#include "Color.h" #include "PlatformInstrumentation.h" #include "png.h" #include @@ -402,6 +403,29 @@ void PNGImageDecoder::headerAvailable() } } +static inline void setPixelRGB(ImageFrame::PixelData* dest, png_bytep pixel) +{ + *dest = 0xFF000000U | pixel[0] << 16 | pixel[1] << 8 | pixel[2]; +} + +static inline void setPixelRGBA(ImageFrame::PixelData* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask) +{ + unsigned char a = pixel[3]; + *dest = a << 24 | pixel[0] << 16 | pixel[1] << 8 | pixel[2]; + nonTrivialAlphaMask |= (255 - a); +} + +static inline void setPixelPremultipliedRGBA(ImageFrame::PixelData* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask) +{ + unsigned char a = pixel[3]; + unsigned char r = fastDivideBy255(pixel[0] * a); + unsigned char g = fastDivideBy255(pixel[1] * a); + unsigned char b = fastDivideBy255(pixel[2] * a); + + *dest = a << 24 | r << 16 | g << 8 | b; + nonTrivialAlphaMask |= (255 - a); +} + void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, int) { if (m_frameBufferCache.isEmpty()) @@ -501,27 +525,37 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, // Write the decoded row pixels to the frame buffer. ImageFrame::PixelData* address = buffer.getAddr(0, y); int width = scaledSize().width(); - bool nonTrivialAlpha = false; + unsigned char nonTrivialAlphaMask = 0; #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) - for (int x = 0; x < width; ++x) { - png_bytep pixel = row + (m_scaled ? m_scaledColumns[x] : x) * colorChannels; - unsigned alpha = hasAlpha ? pixel[3] : 255; - buffer.setRGBA(address++, pixel[0], pixel[1], pixel[2], alpha); - nonTrivialAlpha |= alpha < 255; - } -#else - ASSERT(!m_scaled); - png_bytep pixel = row; - for (int x = 0; x < width; ++x, pixel += colorChannels) { - unsigned alpha = hasAlpha ? pixel[3] : 255; - buffer.setRGBA(address++, pixel[0], pixel[1], pixel[2], alpha); - nonTrivialAlpha |= alpha < 255; - } + if (m_scaled) { + for (int x = 0; x < width; ++x) { + png_bytep pixel = row + m_scaledColumns[x] * colorChannels; + unsigned alpha = hasAlpha ? pixel[3] : 255; + buffer.setRGBA(address++, pixel[0], pixel[1], pixel[2], alpha); + nonTrivialAlphaMask |= (255 - alpha); + } + } else #endif + { + png_bytep pixel = row; + if (hasAlpha) { + if (buffer.premultiplyAlpha()) { + for (int x = 0; x < width; ++x, pixel += 4) + setPixelPremultipliedRGBA(address++, pixel, nonTrivialAlphaMask); + } else { + for (int x = 0; x < width; ++x, pixel += 4) + setPixelRGBA(address++, pixel, nonTrivialAlphaMask); + } + } else { + for (int x = 0; x < width; ++x, pixel += 3) + setPixelRGB(address++, pixel); + } + } + - if (nonTrivialAlpha && !buffer.hasAlpha()) - buffer.setHasAlpha(nonTrivialAlpha); + if (nonTrivialAlphaMask && !buffer.hasAlpha()) + buffer.setHasAlpha(true); } void PNGImageDecoder::pngComplete() -- cgit v1.2.1 From 50ccde81258f6d9f9147b8b1c52adb90db22cd3e Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 5 Jun 2013 18:46:07 +0200 Subject: Crash when loading link to audio file https://bugs.webkit.org/show_bug.cgi?id=115794 Reviewed by Jocelyn Turcotte. Do not access a null pointer frame. * loader/appcache/ApplicationCacheHost.cpp: (WebCore::ApplicationCacheHost::isApplicationCacheEnabled): Change-Id: I1c7c8ea84394f669e565634f71720ae504ceded4 git-svn-id: http://svn.webkit.org/repository/webkit/trunk@149733 268f45cc-cd09-0410-ab3c-d52691b4dbfc Reviewed-by: Jocelyn Turcotte --- Source/WebCore/loader/appcache/ApplicationCacheHost.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp b/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp index fe9f010a0..c4e743065 100644 --- a/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp +++ b/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp @@ -473,7 +473,7 @@ void ApplicationCacheHost::abort() bool ApplicationCacheHost::isApplicationCacheEnabled() { - return m_documentLoader->frame()->settings() + return m_documentLoader->frame() && m_documentLoader->frame()->settings() && m_documentLoader->frame()->settings()->offlineWebApplicationCacheEnabled(); } -- cgit v1.2.1 From 57626c5f3624b3b55d3b5a49118bca8a5baad8b3 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Mon, 3 Jun 2013 13:12:31 +0000 Subject: [Qt][Mac] Remove Carbon and QuickDraw support for plugins. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugs.webkit.org/show_bug.cgi?id=116619 Reviewed by Tor Arne Vestbø. They are only enabled for 32bit builds of QtWebKit and are rarely tested. Other browsers support them through a 32bit host process. PluginViewMac.mm is only used by Qt since the Wx port was removed. - Only support the Cocoa event model - Only support the CoreGraphics drawing model - Remove all NP_NO_CARBON and NP_NO_QUICKDRAW blocks in PluginViewMac.mm * plugins/PluginView.cpp: (WebCore::PluginView::setValue): (WebCore::PluginView::PluginView): * plugins/PluginView.h: * plugins/mac/PluginViewMac.mm: (WebCore::PluginView::platformStart): (WebCore::PluginView::platformDestroy): (WebCore::PluginView::platformGetValueStatic): (WebCore::PluginView::setFocus): (WebCore::PluginView::setNPWindowIfNeeded): (WebCore::PluginView::paint): (WebCore::PluginView::handleWheelEvent): (WebCore::PluginView::handleMouseEvent): (WebCore::PluginView::handleKeyboardEvent): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@151106 268f45cc-cd09-0410-ab3c-d52691b4dbfc Conflicts: Source/WebCore/plugins/mac/PluginViewMac.mm Change-Id: Id4939dfe00a306299ab54c28b03f949ce4beb4d8 Reviewed-by: Allan Sandfeld Jensen --- Source/WebCore/plugins/PluginView.cpp | 12 - Source/WebCore/plugins/PluginView.h | 10 - Source/WebCore/plugins/mac/PluginViewMac.mm | 647 +++++++--------------------- 3 files changed, 154 insertions(+), 515 deletions(-) diff --git a/Source/WebCore/plugins/PluginView.cpp b/Source/WebCore/plugins/PluginView.cpp index 8a31103af..861372f9d 100644 --- a/Source/WebCore/plugins/PluginView.cpp +++ b/Source/WebCore/plugins/PluginView.cpp @@ -646,11 +646,7 @@ NPError PluginView::setValue(NPPVariable variable, void* value) NPDrawingModel newDrawingModel = NPDrawingModel(uintptr_t(value)); switch (newDrawingModel) { case NPDrawingModelCoreGraphics: - m_drawingModel = newDrawingModel; return NPERR_NO_ERROR; -#ifndef NP_NO_QUICKDRAW - case NPDrawingModelQuickDraw: -#endif case NPDrawingModelCoreAnimation: default: LOG(Plugins, "Plugin asked for unsupported drawing model: %s", @@ -666,13 +662,8 @@ NPError PluginView::setValue(NPPVariable variable, void* value) NPEventModel newEventModel = NPEventModel(uintptr_t(value)); switch (newEventModel) { -#ifndef NP_NO_CARBON - case NPEventModelCarbon: -#endif case NPEventModelCocoa: - m_eventModel = newEventModel; return NPERR_NO_ERROR; - default: LOG(Plugins, "Plugin asked for unsupported event model: %s", prettyNameForEventModel(newEventModel)); @@ -860,10 +851,7 @@ PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* p , m_window(0) #endif #if defined(XP_MACOSX) - , m_drawingModel(NPDrawingModel(-1)) - , m_eventModel(NPEventModel(-1)) , m_contextRef(0) - , m_fakeWindow(0) #endif #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) , m_hasPendingGeometryChange(true) diff --git a/Source/WebCore/plugins/PluginView.h b/Source/WebCore/plugins/PluginView.h index 84e62d8ae..821c16161 100644 --- a/Source/WebCore/plugins/PluginView.h +++ b/Source/WebCore/plugins/PluginView.h @@ -323,10 +323,8 @@ namespace WebCore { void lifeSupportTimerFired(Timer*); Timer m_lifeSupportTimer; -#ifndef NP_NO_CARBON #if ENABLE(NETSCAPE_PLUGIN_API) bool dispatchNPEvent(NPEvent&); -#endif // ENABLE(NETSCAPE_PLUGIN_API) #endif #if defined(XP_MACOSX) && ENABLE(NETSCAPE_PLUGIN_API) int16_t dispatchNPCocoaEvent(NPCocoaEvent&); @@ -411,20 +409,12 @@ private: void setNPWindowIfNeeded(); #elif defined(XP_MACOSX) NP_CGContext m_npCgContext; - OwnPtr > m_nullEventTimer; - NPDrawingModel m_drawingModel; - NPEventModel m_eventModel; CGContextRef m_contextRef; - WindowRef m_fakeWindow; #if PLATFORM(QT) QPixmap m_pixmap; #endif - Point m_lastMousePos; void setNPWindowIfNeeded(); - void nullEventTimerFired(Timer*); - Point globalMousePosForPlugin() const; - Point mousePosForPlugin(MouseEvent* event = 0) const; #endif #if defined(XP_UNIX) && ENABLE(NETSCAPE_PLUGIN_API) diff --git a/Source/WebCore/plugins/mac/PluginViewMac.mm b/Source/WebCore/plugins/mac/PluginViewMac.mm index 849a57fdf..e70d5eee6 100644 --- a/Source/WebCore/plugins/mac/PluginViewMac.mm +++ b/Source/WebCore/plugins/mac/PluginViewMac.mm @@ -90,18 +90,12 @@ QT_END_NAMESPACE #include #endif -using std::min; - using namespace WTF; namespace WebCore { using namespace HTMLNames; -#ifndef NP_NO_CARBON -static int modifiersForEvent(UIEventWithKeyState *event); -#endif - static inline WindowRef nativeWindowFor(PlatformWidget widget) { #if PLATFORM(QT) @@ -174,66 +168,16 @@ bool PluginView::platformStart() ASSERT(m_isStarted); ASSERT(m_status == PluginStatusLoadedSuccessfully); - if (m_drawingModel == NPDrawingModel(-1)) { - // We default to QuickDraw, even though we don't support it, - // since that's what Safari does, and some plugins expect this - // behavior and never set the drawing model explicitly. -#ifndef NP_NO_QUICKDRAW - m_drawingModel = NPDrawingModelQuickDraw; -#else - // QuickDraw not available, so we have to default to CoreGraphics - m_drawingModel = NPDrawingModelCoreGraphics; -#endif - } - - if (m_eventModel == NPEventModel(-1)) { - // If the plug-in did not specify an event model - // we default to Carbon, when it is available. -#ifndef NP_NO_CARBON - m_eventModel = NPEventModelCarbon; -#else - m_eventModel = NPEventModelCocoa; -#endif - } - // Gracefully handle unsupported drawing or event models. We can do this // now since the drawing and event model can only be set during NPP_New. -#ifndef NP_NO_CARBON NPBool eventModelSupported; - if (getValueStatic(NPNVariable(NPNVsupportsCarbonBool + m_eventModel), &eventModelSupported) != NPERR_NO_ERROR + if (getValueStatic(NPNVariable(NPNVsupportsCocoaBool), &eventModelSupported) != NPERR_NO_ERROR || !eventModelSupported) { -#else - NPBool eventModelSupported; - if (getValueStatic(NPNVariable(NPNVsupportsCocoaBool/* + m_eventModel*/), &eventModelSupported) != NPERR_NO_ERROR - || !eventModelSupported) { -#endif m_status = PluginStatusCanNotLoadPlugin; LOG(Plugins, "Plug-in '%s' uses unsupported event model %s", - m_plugin->name().utf8().data(), prettyNameForEventModel(m_eventModel)); - return false; - } - -#ifndef NP_NO_QUICKDRAW - NPBool drawingModelSupported; - if (getValueStatic(NPNVariable(NPNVsupportsQuickDrawBool + m_drawingModel), &drawingModelSupported) != NPERR_NO_ERROR - || !drawingModelSupported) { - m_status = PluginStatusCanNotLoadPlugin; - LOG(Plugins, "Plug-in '%s' uses unsupported drawing model %s", - m_plugin->name().utf8().data(), prettyNameForDrawingModel(m_drawingModel)); - return false; - } -#endif - -#ifdef NP_NO_QUICKDRAW - NPBool drawingModelSupported; - if (getValueStatic(NPNVariable(NPNVsupportsCoreGraphicsBool/* + m_drawingModel*/), &drawingModelSupported) != NPERR_NO_ERROR - || !drawingModelSupported) { - m_status = PluginStatusCanNotLoadPlugin; - LOG(Plugins, "Plug-in '%s' uses unsupported drawing model %s", - m_plugin->name().utf8().data(), prettyNameForDrawingModel(m_drawingModel)); + m_plugin->name().utf8().data(), prettyNameForEventModel(NPEventModelCocoa)); return false; } -#endif #if PLATFORM(QT) @@ -249,31 +193,11 @@ bool PluginView::platformStart() setPlatformPluginWidget(widget); #endif - // Create a fake window relative to which all events will be sent when using offscreen rendering -#ifndef NP_NO_CARBON - if (!platformPluginWidget()) { - // Make the default size really big. It is unclear why this is required but with a smaller size, mouse move - // events don't get processed. Resizing the fake window to flash's size doesn't help. - ::Rect windowBounds = { 0, 0, 1000, 1000 }; - CreateNewWindow(kDocumentWindowClass, kWindowStandardDocumentAttributes, &windowBounds, &m_fakeWindow); - // Flash requires the window to be hilited to process mouse move events. - HiliteWindow(m_fakeWindow, true); - } -#endif - updatePluginWidget(); if (!m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall)) setNPWindowIfNeeded(); -#ifndef NP_NO_CARBON - // TODO: Implement null timer throttling depending on plugin activation - m_nullEventTimer = adoptPtr(new Timer(this, &PluginView::nullEventTimerFired)); - m_nullEventTimer->startRepeating(0.02); - - m_lastMousePos.h = m_lastMousePos.v = 0; -#endif // NP_NO_CARBON - return true; } @@ -283,10 +207,6 @@ void PluginView::platformDestroy() setPlatformPluginWidget(0); else { CGContextRelease(m_contextRef); -#ifndef NP_NO_CARBON - if (m_fakeWindow) - DisposeWindow(m_fakeWindow); -#endif } } @@ -305,13 +225,6 @@ bool PluginView::platformGetValueStatic(NPNVariable variable, void* value, NPErr *result = NPERR_NO_ERROR; return true; -#ifndef NP_NO_CARBON - case NPNVsupportsCarbonBool: - *static_cast(value) = true; - *result = NPERR_NO_ERROR; - return true; - -#endif case NPNVsupportsCocoaBool: *static_cast(value) = true; *result = NPERR_NO_ERROR; @@ -328,10 +241,6 @@ bool PluginView::platformGetValueStatic(NPNVariable variable, void* value, NPErr *result = NPERR_NO_ERROR; return true; -#ifndef NP_NO_QUICKDRAW - // QuickDraw is deprecated in 10.5 and not supported on 64-bit - case NPNVsupportsQuickDrawBool: -#endif case NPNVsupportsOpenGLBool: case NPNVsupportsCoreAnimationBool: *static_cast(value) = false; @@ -396,11 +305,8 @@ void PluginView::hide() void PluginView::setFocus(bool focused) { LOG(Plugins, "PluginView::setFocus(%d)", focused); - if (!focused) { + if (!focused) Widget::setFocus(focused); - if (m_eventModel != NPEventModelCocoa) - return; - } if (platformPluginWidget()) #if PLATFORM(QT) @@ -412,28 +318,14 @@ void PluginView::setFocus(bool focused) Widget::setFocus(focused); -#ifndef NP_NO_CARBON - // TODO: Also handle and pass on blur events (focus lost) - EventRecord record; - record.what = NPEventType_GetFocusEvent; - record.message = 0; - record.when = TickCount(); - record.where = globalMousePosForPlugin(); - record.modifiers = GetCurrentKeyModifiers(); + NPCocoaEvent cocoaEvent; + initializeNPCocoaEvent(&cocoaEvent); + cocoaEvent.type = NPCocoaEventFocusChanged; + NPBool focus = focused; + cocoaEvent.data.focus.hasFocus = focus; - if (!dispatchNPEvent(record)) - LOG(Events, "PluginView::setFocus(%d): Focus event not accepted", focused); -#endif - { - NPCocoaEvent cocoaEvent; - initializeNPCocoaEvent(&cocoaEvent); - cocoaEvent.type = NPCocoaEventFocusChanged; - NPBool focus = focused; - cocoaEvent.data.focus.hasFocus = focus; - - if(!dispatchNPCocoaEvent(cocoaEvent)) { - LOG(Events, "PluginView::setFocus(): Focus event %d not accepted", cocoaEvent.type); - } + if(!dispatchNPCocoaEvent(cocoaEvent)) { + LOG(Events, "PluginView::setFocus(): Focus event %d not accepted", cocoaEvent.type); } } @@ -456,26 +348,20 @@ void PluginView::setNPWindowIfNeeded() return; CGContextRef newContextRef = 0; - WindowRef newWindowRef = 0; if (platformPluginWidget()) { newContextRef = cgHandleFor(platformPluginWidget()); - newWindowRef = nativeWindowFor(platformPluginWidget()); m_npWindow.type = NPWindowTypeWindow; } else { newContextRef = m_contextRef; - newWindowRef = m_fakeWindow; m_npWindow.type = NPWindowTypeDrawable; } - if (!newContextRef || !newWindowRef) { + if (!newContextRef) { if (!m_usePixmap) return; } m_npWindow.window = (void*)&m_npCgContext; -#ifndef NP_NO_CARBON - m_npCgContext.window = newWindowRef; -#endif m_npCgContext.context = newContextRef; m_npWindow.x = m_windowRect.x(); @@ -489,9 +375,9 @@ void PluginView::setNPWindowIfNeeded() m_npWindow.clipRect.right = m_windowRect.x() + m_windowRect.width(); m_npWindow.clipRect.bottom = m_windowRect.y() + m_windowRect.height(); - LOG(Plugins, "PluginView::setNPWindowIfNeeded(): window=%p, context=%p," + LOG(Plugins, "PluginView::setNPWindowIfNeeded(): context=%p," " window.x:%d window.y:%d window.width:%d window.height:%d window.clipRect size:%dx%d", - newWindowRef, newContextRef, m_npWindow.x, m_npWindow.y, m_npWindow.width, m_npWindow.height, + newContextRef, m_npWindow.x, m_npWindow.y, m_npWindow.width, m_npWindow.height, m_npWindow.clipRect.right - m_npWindow.clipRect.left, m_npWindow.clipRect.bottom - m_npWindow.clipRect.top); PluginView::setCurrentPluginView(this); @@ -596,33 +482,17 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) #endif } -#ifndef NP_NO_CARBON - if (m_eventModel != NPEventModelCocoa) { - EventRecord event; - event.what = updateEvt; - event.message = (long unsigned int)m_npCgContext.window; - event.when = TickCount(); - event.where.h = 0; - event.where.v = 0; - event.modifiers = GetCurrentKeyModifiers(); - - if (!dispatchNPEvent(event)) - LOG(Events, "PluginView::paint(): Paint event not accepted"); - } else -#endif - { - NPCocoaEvent cocoaEvent; - initializeNPCocoaEvent(&cocoaEvent); - cocoaEvent.type = NPCocoaEventDrawRect; - cocoaEvent.data.draw.x = m_usePixmap ? 0 : r.origin.x; - cocoaEvent.data.draw.y = m_usePixmap ? 0 : r.origin.y; - cocoaEvent.data.draw.width = m_usePixmap ? m_pixmap.width() : r.size.width; - cocoaEvent.data.draw.height = m_usePixmap ? m_pixmap.height() : r.size.height; - cocoaEvent.data.draw.context = cgContext; - - if(!dispatchNPCocoaEvent(cocoaEvent)) - LOG(Events, "PluginView::paint(): Paint event type %d not accepted", cocoaEvent.type); - } + NPCocoaEvent cocoaEvent; + initializeNPCocoaEvent(&cocoaEvent); + cocoaEvent.type = NPCocoaEventDrawRect; + cocoaEvent.data.draw.x = m_usePixmap ? 0 : r.origin.x; + cocoaEvent.data.draw.y = m_usePixmap ? 0 : r.origin.y; + cocoaEvent.data.draw.width = m_usePixmap ? m_pixmap.width() : r.size.width; + cocoaEvent.data.draw.height = m_usePixmap ? m_pixmap.height() : r.size.height; + cocoaEvent.data.draw.context = cgContext; + + if(!dispatchNPCocoaEvent(cocoaEvent)) + LOG(Events, "PluginView::paint(): Paint event type %d not accepted", cocoaEvent.type); if (!platformPluginWidget() || m_isTransparent) { #if PLATFORM(QT) @@ -684,7 +554,7 @@ void PluginView::forceRedraw() // ----------------- Event handling -------------------- void PluginView::handleWheelEvent(WheelEvent *event) { - if (!m_isStarted || m_eventModel != NPEventModelCocoa) + if (!m_isStarted) return; NPCocoaEvent cocoaEvent; @@ -702,8 +572,8 @@ void PluginView::handleWheelEvent(WheelEvent *event) cocoaEvent.data.mouse.modifierFlags = getModifiers(event); if(!dispatchNPCocoaEvent(cocoaEvent)) { - LOG(Events, "PluginView::handleMouseEvent(): Wheel event type %d at %d,%d not accepted", cocoaEvent.type - cocoaEvent.data.mouse.x, cocoaEvent.data.mouse.y); + LOG(Events, "PluginView::handleMouseEvent(): Wheel event type %d at %d,%d not accepted", cocoaEvent.type, + cocoaEvent.data.mouse.pluginX, cocoaEvent.data.mouse.pluginY); } event->setDefaultHandled(); } @@ -713,125 +583,80 @@ void PluginView::handleMouseEvent(MouseEvent* event) if (!m_isStarted) return; -#ifndef NP_NO_CARBON - if (m_eventModel != NPEventModelCocoa) { - EventRecord record; - - if (event->type() == eventNames().mousemoveEvent) { - // Mouse movement is handled by null timer events - m_lastMousePos = mousePosForPlugin(event); - return; - } else if (event->type() == eventNames().mouseoverEvent) { - record.what = NPEventType_AdjustCursorEvent; - } else if (event->type() == eventNames().mouseoutEvent) { - record.what = NPEventType_AdjustCursorEvent; - } else if (event->type() == eventNames().mousedownEvent) { - record.what = mouseDown; + NPCocoaEventType eventType; + int32_t buttonNumber = 0; + int32_t clickCount = 0; + NSEvent *currentEvent = [NSApp currentEvent]; + + NSEventType type = [currentEvent type]; + + switch (type) { + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + buttonNumber = [currentEvent buttonNumber]; + clickCount = [currentEvent clickCount]; + eventType = NPCocoaEventMouseDown; // The plugin needs focus to receive keyboard events if (Page* page = m_parentFrame->page()) page->focusController()->setFocusedFrame(m_parentFrame); m_parentFrame->document()->setFocusedNode(m_element); - } else if (event->type() == eventNames().mouseupEvent) { - record.what = mouseUp; - } else { + break; + + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + buttonNumber = [currentEvent buttonNumber]; + clickCount = [currentEvent clickCount]; + eventType = NPCocoaEventMouseUp; + break; + + case NSMouseMoved: + eventType = NPCocoaEventMouseMoved; + break; + + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + buttonNumber = [currentEvent buttonNumber]; + eventType = NPCocoaEventMouseDragged; + break; + + case NSMouseEntered: + eventType = NPCocoaEventMouseEntered; + break; + + case NSMouseExited: + eventType = NPCocoaEventMouseExited; + default: return; - } - record.where = mousePosForPlugin(event); - record.modifiers = modifiersForEvent(event); - - if (!event->buttonDown()) - record.modifiers |= btnState; - - if (event->button() == 2) - record.modifiers |= controlKey; - - if (!dispatchNPEvent(record)) { - if (record.what == NPEventType_AdjustCursorEvent) - return; // Signals that the plugin wants a normal cursor - - LOG(Events, "PluginView::handleMouseEvent(): Mouse event type %d at %d,%d not accepted", - record.what, record.where.h, record.where.v); - } else { - event->setDefaultHandled(); - } - } else -#endif - { - NPCocoaEventType eventType; - int32_t buttonNumber = 0; - int32_t clickCount = 0; - NSEvent *currentEvent = [NSApp currentEvent]; - - NSEventType type = [currentEvent type]; - - switch (type) { - case NSLeftMouseDown: - case NSRightMouseDown: - case NSOtherMouseDown: - buttonNumber = [currentEvent buttonNumber]; - clickCount = [currentEvent clickCount]; - eventType = NPCocoaEventMouseDown; - // The plugin needs focus to receive keyboard events - if (Page* page = m_parentFrame->page()) - page->focusController()->setFocusedFrame(m_parentFrame); - m_parentFrame->document()->setFocusedNode(m_element); - break; - - case NSLeftMouseUp: - case NSRightMouseUp: - case NSOtherMouseUp: - buttonNumber = [currentEvent buttonNumber]; - clickCount = [currentEvent clickCount]; - eventType = NPCocoaEventMouseUp; - break; - - case NSMouseMoved: - eventType = NPCocoaEventMouseMoved; - break; - - case NSLeftMouseDragged: - case NSRightMouseDragged: - case NSOtherMouseDragged: - buttonNumber = [currentEvent buttonNumber]; - eventType = NPCocoaEventMouseDragged; - break; - - case NSMouseEntered: - eventType = NPCocoaEventMouseEntered; - break; - - case NSMouseExited: - eventType = NPCocoaEventMouseExited; - default: - return; - } - - NPCocoaEvent cocoaEvent; - initializeNPCocoaEvent(&cocoaEvent); - - cocoaEvent.type = eventType; - if (!(NPCocoaEventMouseEntered == eventType || NPCocoaEventMouseExited == eventType)) { - cocoaEvent.data.mouse.buttonNumber = buttonNumber; - cocoaEvent.data.mouse.clickCount = clickCount; - } - - cocoaEvent.data.mouse.pluginX = event->layerX() - m_npWindow.x + m_windowRect.x() - m_element->offsetLeft(); - cocoaEvent.data.mouse.pluginY = event->layerY() - m_npWindow.y + m_windowRect.y() - m_element->offsetTop(); - cocoaEvent.data.mouse.deltaX = [currentEvent deltaX]; - cocoaEvent.data.mouse.deltaY = [currentEvent deltaY]; - cocoaEvent.data.mouse.deltaZ = [currentEvent deltaZ]; - cocoaEvent.data.mouse.modifierFlags = getModifiers(event); - - int16_t response = dispatchNPCocoaEvent(cocoaEvent); - if(response = kNPEventNotHandled) { - LOG(Events, "PluginView::handleMouseEvent(): Mouse event type %d at %d,%d not accepted", cocoaEvent.type - cocoaEvent.data.mouse.x, cocoaEvent.data.mouse.y); - } - - // Safari policy is to return true for all mouse events, because some plugins - // return false even if they have handled the event. - event->setDefaultHandled(); } + + NPCocoaEvent cocoaEvent; + initializeNPCocoaEvent(&cocoaEvent); + + cocoaEvent.type = eventType; + if (!(NPCocoaEventMouseEntered == eventType || NPCocoaEventMouseExited == eventType)) { + cocoaEvent.data.mouse.buttonNumber = buttonNumber; + cocoaEvent.data.mouse.clickCount = clickCount; + } + + cocoaEvent.data.mouse.pluginX = event->layerX() - m_npWindow.x + m_windowRect.x() - m_element->offsetLeft(); + cocoaEvent.data.mouse.pluginY = event->layerY() - m_npWindow.y + m_windowRect.y() - m_element->offsetTop(); + cocoaEvent.data.mouse.deltaX = [currentEvent deltaX]; + cocoaEvent.data.mouse.deltaY = [currentEvent deltaY]; + cocoaEvent.data.mouse.deltaZ = [currentEvent deltaZ]; + cocoaEvent.data.mouse.modifierFlags = getModifiers(event); + + int16_t response = dispatchNPCocoaEvent(cocoaEvent); + if(response == kNPEventNotHandled) { + LOG(Events, "PluginView::handleMouseEvent(): Mouse event type %d at %d,%d not accepted", cocoaEvent.type, + cocoaEvent.data.mouse.pluginX, cocoaEvent.data.mouse.pluginY); + } + + // Safari policy is to return true for all mouse events, because some plugins + // return false even if they have handled the event. + event->setDefaultHandled(); } void PluginView::handleKeyboardEvent(KeyboardEvent* event) @@ -839,238 +664,74 @@ void PluginView::handleKeyboardEvent(KeyboardEvent* event) if (!m_isStarted) return; LOG(Plugins, "PluginView::handleKeyboardEvent() ----------------- "); - + LOG(Plugins, "PV::hKE(): KE.keyCode: 0x%02X, KE.charCode: %d", event->keyCode(), event->charCode()); - -#ifndef NP_NO_CARBON - if (m_eventModel != NPEventModelCocoa) { - EventRecord record; - if (event->type() == eventNames().keydownEvent) { - // This event is the result of a PlatformKeyboardEvent::KeyDown which - // was disambiguated into a PlatformKeyboardEvent::RawKeyDown. Since - // we don't have access to the text here, we return, and wait for the - // corresponding event based on PlatformKeyboardEvent::Char. - return; - } else if (event->type() == eventNames().keypressEvent) { - // Which would be this one. This event was disambiguated from the same - // PlatformKeyboardEvent::KeyDown, but to a PlatformKeyboardEvent::Char, - // which retains the text from the original event. So, we can safely pass - // on the event as a key-down event to the plugin. - record.what = keyDown; - } else if (event->type() == eventNames().keyupEvent) { - // PlatformKeyboardEvent::KeyUp events always have the text, so nothing - // fancy here. - record.what = keyUp; - } else { - return; - } - - const PlatformKeyboardEvent* platformEvent = event->keyEvent(); - int keyCode = platformEvent->nativeVirtualKeyCode(); - - const String text = platformEvent->text(); - if (text.length() < 1) { - event->setDefaultHandled(); - return; - } - - WTF::RetainPtr cfText(WTF::AdoptCF, text.createCFString()); - - LOG(Plugins, "PV::hKE(): PKE.text: %s, PKE.unmodifiedText: %s, PKE.keyIdentifier: %s", - text.ascii().data(), platformEvent->unmodifiedText().ascii().data(), - platformEvent->keyIdentifier().ascii().data()); - - char charCodes[2] = { 0, 0 }; - if (!CFStringGetCString(cfText.get(), charCodes, 2, CFStringGetSystemEncoding())) { - LOG_ERROR("Could not resolve character code using system encoding."); - event->setDefaultHandled(); - return; - } - - record.where = globalMousePosForPlugin(); - record.modifiers = modifiersForEvent(event); - record.message = ((keyCode & 0xFF) << 8) | (charCodes[0] & 0xFF); - record.when = TickCount(); - - LOG(Plugins, "PV::hKE(): record.modifiers: %d", record.modifiers); - -#if PLATFORM(QT) - LOG(Plugins, "PV::hKE(): PKE.qtEvent()->nativeVirtualKey: 0x%02X, charCode: %d", - keyCode, int(uchar(charCodes[0]))); -#endif - - if (!dispatchNPEvent(record)) - LOG(Events, "PluginView::handleKeyboardEvent(): Keyboard event type %d not accepted", record.what); - else - event->setDefaultHandled(); - } else -#endif - { - NSEvent *currentEvent = [NSApp currentEvent]; - NPCocoaEventType eventType; - NSEventType type = [currentEvent type]; - - switch (type) { - case NSKeyDown: - eventType = NPCocoaEventKeyDown; - m_keyDownSent = true; - break; - case NSKeyUp: - if (m_disregardKeyUpCounter > 0) { - m_disregardKeyUpCounter--; - event->setDefaultHandled(); - return; - } - eventType = NPCocoaEventKeyUp; - break; - case NSFlagsChanged: - eventType = NPCocoaEventFlagsChanged; - break; - default: - return; - } - - NPCocoaEvent cocoaEvent; - initializeNPCocoaEvent(&cocoaEvent); - cocoaEvent.type = eventType; - if (eventType != NPCocoaEventFlagsChanged) { - NSString *characters = [currentEvent characters]; - NSString *charactersIgnoringModifiers = [currentEvent charactersIgnoringModifiers]; - cocoaEvent.data.key.characters = reinterpret_cast(characters); - cocoaEvent.data.key.charactersIgnoringModifiers = reinterpret_cast(charactersIgnoringModifiers); - cocoaEvent.data.key.isARepeat = [currentEvent isARepeat]; - cocoaEvent.data.key.keyCode = [currentEvent keyCode]; - cocoaEvent.data.key.modifierFlags = getModifiers(event); - } - - int16_t response = dispatchNPCocoaEvent(cocoaEvent); - if(response == kNPEventNotHandled) { - LOG(Events, "PluginView::handleKeyboardEvent(): Keyboard event type %d not accepted", cocoaEvent.type); - } else if (response == kNPEventStartIME) { - // increment counter and resend as a text input - m_disregardKeyUpCounter++; - NPCocoaEvent textEvent; - initializeNPCocoaEvent(&textEvent); - textEvent.type = NPCocoaEventTextInput; - textEvent.data.text.text = reinterpret_cast([currentEvent characters]); - response = dispatchNPCocoaEvent(textEvent); - if(response == kNPEventNotHandled) - LOG(Events, "PluginView::handleKeyboardEvent(): Keyboard event type %d not accepted", cocoaEvent.type); - } - - // All keyboard events need to be handled to prevent them falling - // through to the page, unless they are Meta key events, in which - // case they are, unless they are Cmd+a. From WebKit2, possibly - // not the most elegant piece of key handling code..... - if (event->metaKey()) { - if (cocoaEvent.data.key.keyCode == 0) + + NSEvent *currentEvent = [NSApp currentEvent]; + NPCocoaEventType eventType; + NSEventType type = [currentEvent type]; + + switch (type) { + case NSKeyDown: + eventType = NPCocoaEventKeyDown; + m_keyDownSent = true; + break; + case NSKeyUp: + if (m_disregardKeyUpCounter > 0) { + m_disregardKeyUpCounter--; event->setDefaultHandled(); - } else { - // else ignore, it's a Meta Key event for the browser. - event->setDefaultHandled(); - } + return; + } + eventType = NPCocoaEventKeyUp; + break; + case NSFlagsChanged: + eventType = NPCocoaEventFlagsChanged; + break; + default: + return; } -} - -#ifndef NP_NO_CARBON -void PluginView::nullEventTimerFired(Timer*) -{ - EventRecord record; - - record.what = nullEvent; - record.message = 0; - record.when = TickCount(); - record.where = m_lastMousePos; - record.modifiers = GetCurrentKeyModifiers(); - if (!Button()) - record.modifiers |= btnState; - - if (!dispatchNPEvent(record)) - LOG(Events, "PluginView::nullEventTimerFired(): Null event not accepted"); -} -#endif - -#ifndef NP_NO_CARBON -static int modifiersForEvent(UIEventWithKeyState* event) -{ - int modifiers = 0; - - if (event->ctrlKey()) - modifiers |= controlKey; - if (event->altKey()) - modifiers |= optionKey; - - if (event->metaKey()) - modifiers |= cmdKey; - - if (event->shiftKey()) - modifiers |= shiftKey; - - return modifiers; -} -#endif - -#ifndef NP_NO_CARBON -Point PluginView::globalMousePosForPlugin() const -{ - Point pos; - GetGlobalMouse(&pos); - -#if PLATFORM(WX) - // make sure the titlebar/toolbar size is included - WindowRef windowRef = nativeWindowFor(platformPluginWidget()); - ::Rect content, structure; - - GetWindowBounds(windowRef, kWindowStructureRgn, &structure); - GetWindowBounds(windowRef, kWindowContentRgn, &content); - - int top = content.top - structure.top; - pos.v -= top; -#endif - - return pos; -} -#endif - -#ifndef NP_NO_CARBON -Point PluginView::mousePosForPlugin(MouseEvent* event) const -{ - ASSERT(event); - if (platformPluginWidget()) - return globalMousePosForPlugin(); - - if (event->button() == 2) { - // always pass the global position for right-click since Flash uses it to position the context menu - return globalMousePosForPlugin(); + NPCocoaEvent cocoaEvent; + initializeNPCocoaEvent(&cocoaEvent); + cocoaEvent.type = eventType; + if (eventType != NPCocoaEventFlagsChanged) { + NSString *characters = [currentEvent characters]; + NSString *charactersIgnoringModifiers = [currentEvent charactersIgnoringModifiers]; + cocoaEvent.data.key.characters = reinterpret_cast(characters); + cocoaEvent.data.key.charactersIgnoringModifiers = reinterpret_cast(charactersIgnoringModifiers); + cocoaEvent.data.key.isARepeat = [currentEvent isARepeat]; + cocoaEvent.data.key.keyCode = [currentEvent keyCode]; + cocoaEvent.data.key.modifierFlags = getModifiers(event); } - Point pos; - IntPoint postZoomPos = roundedIntPoint(m_element->renderer()->absoluteToLocal(event->absoluteLocation())); - pos.h = postZoomPos.x() + m_windowRect.x(); - // The number 22 is the height of the title bar. As to why it figures in the calculation below - // is left as an exercise to the reader :-) - pos.v = postZoomPos.y() + m_windowRect.y() - 22; - return pos; -} -#endif - -#ifndef NP_NO_CARBON -bool PluginView::dispatchNPEvent(NPEvent& event) -{ - PluginView::setCurrentPluginView(this); - JSC::JSLock::DropAllLocks dropAllLocks(JSDOMWindowBase::commonJSGlobalData()); - setCallingPlugin(true); - - bool accepted = m_plugin->pluginFuncs()->event(m_instance, &event); + int16_t response = dispatchNPCocoaEvent(cocoaEvent); + if(response == kNPEventNotHandled) { + LOG(Events, "PluginView::handleKeyboardEvent(): Keyboard event type %d not accepted", cocoaEvent.type); + } else if (response == kNPEventStartIME) { + // increment counter and resend as a text input + m_disregardKeyUpCounter++; + NPCocoaEvent textEvent; + initializeNPCocoaEvent(&textEvent); + textEvent.type = NPCocoaEventTextInput; + textEvent.data.text.text = reinterpret_cast([currentEvent characters]); + response = dispatchNPCocoaEvent(textEvent); + if(response == kNPEventNotHandled) + LOG(Events, "PluginView::handleKeyboardEvent(): Keyboard event type %d not accepted", cocoaEvent.type); + } - setCallingPlugin(false); - PluginView::setCurrentPluginView(0); - return accepted; + // All keyboard events need to be handled to prevent them falling + // through to the page, unless they are Meta key events, in which + // case they are, unless they are Cmd+a. From WebKit2, possibly + // not the most elegant piece of key handling code..... + if (event->metaKey()) { + if (cocoaEvent.data.key.keyCode == 0) + event->setDefaultHandled(); + } else { + // else ignore, it's a Meta Key event for the browser. + event->setDefaultHandled(); + } } -#endif - int16_t PluginView::dispatchNPCocoaEvent(NPCocoaEvent& cocoaEvent) { -- cgit v1.2.1 From f64d11fc6fd0798fae2a1ecc7565b9d2efd385bc Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Mon, 3 Jun 2013 13:12:48 +0000 Subject: [Qt][Mac] Allow drawing plugins with QWindow by always using an intermediate bitmap. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugs.webkit.org/show_bug.cgi?id=116620 Reviewed by Tor Arne Vestbø. The isolation of QWidget along with QPA in Qt5 is abstracting away the native CGContext of a QWidget and we would need to create a non-public API to be able to achieve it. Instead of adding complexity to this rarely touched code, always draw into an intermediate bitmap that we then paint into our QPainter afterward. - Use CGBitmapContextCreate to allocate a buffer directly instead of creating a QPixmap and extract an CGContextRef out of it. - Get rid of the "if (platformPluginWidget())" code path since we don't paint directly into the QWidget's backing store anymore. - Always use m_contextRef to draw the plugin instead of alternating between direct and indirect drawing. * plugins/PluginView.cpp: (WebCore::PluginView::PluginView): * plugins/PluginView.h: * plugins/mac/PluginViewMac.mm: (WebCore::createBitmapContext): (WebCore::PluginView::platformStart): (WebCore::PluginView::platformDestroy): (WebCore::PluginView::setFocus): (WebCore::PluginView::setNPWindowIfNeeded): (WebCore::PluginView::updatePluginWidget): (WebCore::PluginView::paint): (WebCore::PluginView::invalidateRect): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@151107 268f45cc-cd09-0410-ab3c-d52691b4dbfc Conflicts: Source/WebCore/plugins/PluginView.h Source/WebCore/plugins/mac/PluginViewMac.mm Change-Id: I1006dcf3c08c14ca0d144532372de33f815fbc23 Reviewed-by: Allan Sandfeld Jensen --- Source/WebCore/plugins/PluginView.cpp | 2 +- Source/WebCore/plugins/PluginView.h | 9 +- Source/WebCore/plugins/mac/PluginViewMac.mm | 228 ++++++---------------------- 3 files changed, 51 insertions(+), 188 deletions(-) diff --git a/Source/WebCore/plugins/PluginView.cpp b/Source/WebCore/plugins/PluginView.cpp index 861372f9d..cdf8a78bb 100644 --- a/Source/WebCore/plugins/PluginView.cpp +++ b/Source/WebCore/plugins/PluginView.cpp @@ -847,7 +847,7 @@ PluginView::PluginView(Frame* parentFrame, const IntSize& size, PluginPackage* p , m_wmPrintHDC(0) , m_haveUpdatedPluginWidget(false) #endif -#if (PLATFORM(QT) && OS(WINDOWS)) || defined(XP_MACOSX) || PLATFORM(EFL) +#if (PLATFORM(QT) && OS(WINDOWS)) || PLATFORM(EFL) , m_window(0) #endif #if defined(XP_MACOSX) diff --git a/Source/WebCore/plugins/PluginView.h b/Source/WebCore/plugins/PluginView.h index 821c16161..361c286db 100644 --- a/Source/WebCore/plugins/PluginView.h +++ b/Source/WebCore/plugins/PluginView.h @@ -52,9 +52,6 @@ typedef struct HWND__* HWND; typedef HWND PlatformPluginWidget; #else typedef PlatformWidget PlatformPluginWidget; -#if defined(XP_MACOSX) && PLATFORM(QT) -#include -#endif #endif #if PLATFORM(QT) #if USE(TEXTURE_MAPPER) @@ -330,7 +327,6 @@ namespace WebCore { int16_t dispatchNPCocoaEvent(NPCocoaEvent&); bool m_updatedCocoaTextInputRequested; bool m_keyDownSent; - bool m_usePixmap; uint16_t m_disregardKeyUpCounter; #endif @@ -390,7 +386,7 @@ namespace WebCore { bool m_haveUpdatedPluginWidget; #endif -#if ((PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(WX)) && OS(WINDOWS)) || defined(XP_MACOSX) || PLATFORM(EFL) +#if ((PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(WX)) && OS(WINDOWS)) || PLATFORM(EFL) // On Mac OSX and Qt/Windows the plugin does not have its own native widget, // but is using the containing window as its reference for positioning/painting. PlatformPluginWidget m_window; @@ -410,9 +406,6 @@ private: #elif defined(XP_MACOSX) NP_CGContext m_npCgContext; CGContextRef m_contextRef; -#if PLATFORM(QT) - QPixmap m_pixmap; -#endif void setNPWindowIfNeeded(); #endif diff --git a/Source/WebCore/plugins/mac/PluginViewMac.mm b/Source/WebCore/plugins/mac/PluginViewMac.mm index e70d5eee6..d1582d837 100644 --- a/Source/WebCore/plugins/mac/PluginViewMac.mm +++ b/Source/WebCore/plugins/mac/PluginViewMac.mm @@ -73,16 +73,7 @@ using JSC::JSObject; using JSC::JSValue; #if PLATFORM(QT) -#include -#include #include -#include -#include -#include "QWebPageClient.h" -QT_BEGIN_NAMESPACE -extern Q_GUI_EXPORT OSWindowRef qt_mac_window_for(const QWidget* w); -extern Q_GUI_EXPORT CGContextRef qt_mac_cg_context(const QPaintDevice *pdev); //qpaintdevice_mac.cpp -QT_END_NAMESPACE #endif #if PLATFORM(WX) @@ -96,52 +87,6 @@ namespace WebCore { using namespace HTMLNames; -static inline WindowRef nativeWindowFor(PlatformWidget widget) -{ -#if PLATFORM(QT) - if (widget) -#if QT_MAC_USE_COCOA - return static_cast([qt_mac_window_for(static_cast(widget)) windowRef]); -#else - return static_cast(qt_mac_window_for(widget)); -#endif -#elif PLATFORM(WX) - if (widget) - return (WindowRef)widget->MacGetTopLevelWindowRef(); -#endif - return 0; -} - -static inline CGContextRef cgHandleFor(PlatformWidget widget) -{ -#if PLATFORM(QT) - if (widget) - return (CGContextRef)static_cast(widget)->macCGHandle(); -#endif -#if PLATFORM(WX) - if (widget) - return (CGContextRef)widget->MacGetCGContextRef(); -#endif - return 0; -} - -static inline IntPoint topLevelOffsetFor(PlatformWidget widget) -{ -#if PLATFORM(QT) - if (widget) { - QWidget* topLevel = static_cast(widget)->window(); - return static_cast(widget)->mapTo(topLevel, QPoint(0, 0)) + topLevel->geometry().topLeft() - topLevel->pos(); - } -#endif -#if PLATFORM(WX) - if (widget) { - PlatformWidget toplevel = wxGetTopLevelParent(widget); - return toplevel->ScreenToClient(widget->GetScreenPosition()); - } -#endif - return IntPoint(); -} - // --------- Cocoa specific utility functions ---------- static void initializeNPCocoaEvent(NPCocoaEvent* event) @@ -161,6 +106,19 @@ static int32_t getModifiers(UIEventWithKeyState *event) return modifiers; } +static CGContextRef createBitmapContext(const IntSize& size) +{ + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + uint flags = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; + CGContextRef context = CGBitmapContextCreate(0, size.width(), size.height(), + 8, 4 * size.width(), colorspace, flags); + + CGContextTranslateCTM(context, 0, size.height()); + CGContextScaleCTM(context, 1, -1); + CGColorSpaceRelease(colorspace); + return context; +} + // --------------- Lifetime management ----------------- bool PluginView::platformStart() @@ -179,20 +137,6 @@ bool PluginView::platformStart() return false; } - -#if PLATFORM(QT) - // Set the platformPluginWidget only in the case of QWebView so that the context menu appears in the right place. - // In all other cases, we use off-screen rendering - if (QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient()) { - if (QWidget* widget = qobject_cast(client->pluginParent())) - setPlatformPluginWidget(widget); - } -#endif -#if PLATFORM(WX) - if (wxWindow* widget = m_parentFrame->view()->hostWindow()->platformPageClient()) - setPlatformPluginWidget(widget); -#endif - updatePluginWidget(); if (!m_plugin->quirks().contains(PluginQuirkDeferFirstSetWindowCall)) @@ -203,11 +147,7 @@ bool PluginView::platformStart() void PluginView::platformDestroy() { - if (platformPluginWidget()) - setPlatformPluginWidget(0); - else { - CGContextRelease(m_contextRef); - } + CGContextRelease(m_contextRef); } // Used before the plugin view has been initialized properly, and as a @@ -308,15 +248,7 @@ void PluginView::setFocus(bool focused) if (!focused) Widget::setFocus(focused); - if (platformPluginWidget()) -#if PLATFORM(QT) - static_cast(platformPluginWidget())->setFocus(Qt::OtherFocusReason); -#else - platformPluginWidget()->SetFocus(); -#endif - else - Widget::setFocus(focused); - + Widget::setFocus(focused); NPCocoaEvent cocoaEvent; initializeNPCocoaEvent(&cocoaEvent); @@ -344,32 +276,19 @@ void PluginView::setNPWindowRect(const IntRect&) void PluginView::setNPWindowIfNeeded() { - if (!m_isStarted || !parent() || !m_plugin->pluginFuncs()->setwindow) + if (!m_isStarted || !parent() || !m_plugin->pluginFuncs()->setwindow || !m_contextRef) return; - CGContextRef newContextRef = 0; - if (platformPluginWidget()) { - newContextRef = cgHandleFor(platformPluginWidget()); - m_npWindow.type = NPWindowTypeWindow; - } else { - newContextRef = m_contextRef; - m_npWindow.type = NPWindowTypeDrawable; - } - - if (!newContextRef) { - if (!m_usePixmap) - return; - } - + // The context is set through the draw event. + ASSERT(!m_npCgContext.context && !m_npCgContext.window); m_npWindow.window = (void*)&m_npCgContext; - m_npCgContext.context = newContextRef; + m_npWindow.type = NPWindowTypeDrawable; m_npWindow.x = m_windowRect.x(); m_npWindow.y = m_windowRect.y(); m_npWindow.width = m_windowRect.width(); m_npWindow.height = m_windowRect.height(); - // TODO: (also clip against scrollbars, etc.) m_npWindow.clipRect.left = max(0, m_windowRect.x()); m_npWindow.clipRect.top = max(0, m_windowRect.y()); m_npWindow.clipRect.right = m_windowRect.x() + m_windowRect.width(); @@ -377,7 +296,7 @@ void PluginView::setNPWindowIfNeeded() LOG(Plugins, "PluginView::setNPWindowIfNeeded(): context=%p," " window.x:%d window.y:%d window.width:%d window.height:%d window.clipRect size:%dx%d", - newContextRef, m_npWindow.x, m_npWindow.y, m_npWindow.width, m_npWindow.height, + m_contextRef, m_npWindow.x, m_npWindow.y, m_npWindow.width, m_npWindow.height, m_npWindow.clipRect.right - m_npWindow.clipRect.left, m_npWindow.clipRect.bottom - m_npWindow.clipRect.top); PluginView::setCurrentPluginView(this); @@ -397,27 +316,15 @@ void PluginView::updatePluginWidget() FrameView* frameView = static_cast(parent()); IntRect oldWindowRect = m_windowRect; - IntRect oldClipRect = m_clipRect; - m_windowRect = frameView->contentsToWindow(frameRect()); - IntPoint offset = topLevelOffsetFor(platformPluginWidget()); - m_windowRect.move(offset.x(), offset.y()); - if (!platformPluginWidget()) { - if (m_windowRect.size() != oldWindowRect.size()) { - CGContextRelease(m_contextRef); -#if PLATFORM(QT) - m_pixmap = QPixmap(m_windowRect.size()); - m_pixmap.fill(Qt::transparent); - m_contextRef = m_pixmap.isNull() ? 0 : qt_mac_cg_context(&m_pixmap); -#endif - } + if (m_windowRect.size() != oldWindowRect.size()) { + CGContextRelease(m_contextRef); + m_contextRef = createBitmapContext(m_windowRect.size()); + CGContextClearRect(m_contextRef, CGRectMake(0, 0, m_windowRect.width(), m_windowRect.height())); } - m_clipRect = windowClipRect(); - m_clipRect.move(-m_windowRect.x(), -m_windowRect.y()); - - if (platformPluginWidget() && (m_windowRect != oldWindowRect || m_clipRect != oldClipRect)) + if (m_windowRect != oldWindowRect) setNPWindowIfNeeded(); } @@ -428,41 +335,10 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) return; } - if (context->paintingDisabled()) + if (context->paintingDisabled() || !m_contextRef) return; -#if PLATFORM(QT) - QPainter* p = context->platformContext(); - CGContextRef cgContext = qt_mac_cg_context(p->device()); -#else - CGContextRef cgContext = m_npCgContext.context; -#endif - setNPWindowIfNeeded(); - if (!cgContext) { - cgContext = m_contextRef; - if (!cgContext) - return; - else { - m_usePixmap = true; - setNPWindowIfNeeded(); - } - } else - m_usePixmap = false; - - bool oldUsePixmap = m_usePixmap; - if (m_isTransparent && !m_usePixmap) { - if (m_pixmap.isNull()) - m_pixmap = QPixmap(frameRect().size()); - m_usePixmap = true; - setNPWindowIfNeeded(); - cgContext = qt_mac_cg_context(&m_pixmap); - } - - CGContextSaveGState(cgContext); - if (platformPluginWidget()) { - IntPoint offset = frameRect().location(); - CGContextTranslateCTM(cgContext, offset.x(), offset.y()); - } + CGContextSaveGState(m_contextRef); IntRect targetRect(frameRect()); targetRect.intersects(rect); @@ -472,40 +348,40 @@ void PluginView::paint(GraphicsContext* context, const IntRect& rect) r.origin.y = targetRect.y() - frameRect().y(); r.size.width = targetRect.width(); r.size.height = targetRect.height(); - CGContextClipToRect(cgContext, r); + CGContextClipToRect(m_contextRef, r); - if (!platformPluginWidget() || m_isTransparent) { // clean the pixmap in transparent mode -#if PLATFORM(QT) - QPainter painter(&m_pixmap); - painter.setCompositionMode(QPainter::CompositionMode_Clear); - painter.fillRect(QRectF(r.origin.x, r.origin.y, r.size.width, r.size.height), Qt::transparent); -#endif + if (m_isTransparent) { + // Clean the pixmap in transparent mode. + CGContextClearRect(m_contextRef, CGRectMake(r.origin.x, r.origin.y, r.size.width, r.size.height)); } NPCocoaEvent cocoaEvent; initializeNPCocoaEvent(&cocoaEvent); cocoaEvent.type = NPCocoaEventDrawRect; - cocoaEvent.data.draw.x = m_usePixmap ? 0 : r.origin.x; - cocoaEvent.data.draw.y = m_usePixmap ? 0 : r.origin.y; - cocoaEvent.data.draw.width = m_usePixmap ? m_pixmap.width() : r.size.width; - cocoaEvent.data.draw.height = m_usePixmap ? m_pixmap.height() : r.size.height; - cocoaEvent.data.draw.context = cgContext; + cocoaEvent.data.draw.x = 0; + cocoaEvent.data.draw.y = 0; + cocoaEvent.data.draw.width = CGBitmapContextGetWidth(m_contextRef); + cocoaEvent.data.draw.height = CGBitmapContextGetHeight(m_contextRef); + cocoaEvent.data.draw.context = m_contextRef; if(!dispatchNPCocoaEvent(cocoaEvent)) LOG(Events, "PluginView::paint(): Paint event type %d not accepted", cocoaEvent.type); - if (!platformPluginWidget() || m_isTransparent) { #if PLATFORM(QT) - QPainter* painter = context->platformContext(); - painter->drawPixmap(targetRect.x(), targetRect.y(), m_pixmap, - targetRect.x() - frameRect().x(), targetRect.y() - frameRect().y(), targetRect.width(), targetRect.height()); + // Paint the intermediate bitmap into our graphics context. + ASSERT(CGBitmapContextGetBitmapInfo(m_contextRef) & (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); + ASSERT(CGBitmapContextGetBitsPerPixel(m_contextRef) == 32); + const uint8_t* data = reinterpret_cast(CGBitmapContextGetData(m_contextRef)); + size_t width = CGBitmapContextGetWidth(m_contextRef); + size_t height = CGBitmapContextGetHeight(m_contextRef); + const QImage imageFromBitmap(data, width, height, QImage::Format_ARGB32_Premultiplied); + + QPainter* painter = context->platformContext(); + painter->drawImage(targetRect.x(), targetRect.y(), imageFromBitmap, + targetRect.x() - frameRect().x(), targetRect.y() - frameRect().y(), targetRect.width(), targetRect.height()); #endif - } - CGContextRestoreGState(cgContext); - if (oldUsePixmap != m_usePixmap) { - m_usePixmap = oldUsePixmap; - m_pixmap = QPixmap(); - } + + CGContextRestoreGState(m_contextRef); } bool PluginView::popUpContextMenu(NPMenu *menu) @@ -524,12 +400,6 @@ bool PluginView::popUpContextMenu(NPMenu *menu) void PluginView::invalidateRect(const IntRect& rect) { - if (platformPluginWidget() && m_isTransparent) -#if PLATFORM(QT) - static_cast(platformPluginWidget())->update(convertToContainingWindow(rect)); -#else - platformPluginWidget()->RefreshRect(convertToContainingWindow(rect)); -#endif invalidateWindowlessPluginRect(rect); } -- cgit v1.2.1 From 0c06c599cfa5a3235922494992712860c34dfcd3 Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Mon, 3 Jun 2013 13:13:26 +0000 Subject: [Qt] Re-enable plugins on Mac. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugs.webkit.org/show_bug.cgi?id=116622 Reviewed by Tor Arne Vestbø. Source/WebCore: * platform/FileSystem.h: * platform/qt/FileSystemQt.cpp: (WebCore::unloadModule): - Q_WS_* aren't defined since Qt5, use Q_OS_MACX instead. * plugins/mac/PluginPackageMac.cpp: (WebCore::PluginPackage::fetchInfo): (WebCore::PluginPackage::load): - createCFString now does the adoption itself. * plugins/mac/PluginViewMac.mm: - Add missing include. Source/WebKit/qt: * WebCoreSupport/ChromeClientQt.cpp: (WebCore::ChromeClientQt::windowResizerRect): - Add missing parenthese. Tools: Plugins on Mac were only enabled if !embedded but the later was set if QPA is enabled, which is the default since Qt 5.0. Remove references to 'embedded' and fix various build issues, PluginViewMac.mm and PluginPackageMac.cpp haven't been compiled since a few months. * DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro: * qmake/mkspecs/features/features.prf: * qmake/mkspecs/features/unix/default_pre.prf: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@151109 268f45cc-cd09-0410-ab3c-d52691b4dbfc Conflicts: Source/WebCore/platform/FileSystem.h Source/WebCore/plugins/mac/PluginPackageMac.cpp Change-Id: I38dc6170ca868b54f8092aa6b271ace4911a2390 Reviewed-by: Allan Sandfeld Jensen --- Source/WebCore/platform/FileSystem.h | 4 ++-- Source/WebCore/platform/qt/FileSystemQt.cpp | 2 +- Source/WebCore/plugins/mac/PluginPackageMac.cpp | 4 ++-- Source/WebCore/plugins/mac/PluginViewMac.mm | 3 +++ Source/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp | 2 +- Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro | 2 +- Tools/qmake/mkspecs/features/features.prf | 2 +- Tools/qmake/mkspecs/features/unix/default_pre.prf | 4 ---- 8 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Source/WebCore/platform/FileSystem.h b/Source/WebCore/platform/FileSystem.h index 943cc7b60..642d07edf 100644 --- a/Source/WebCore/platform/FileSystem.h +++ b/Source/WebCore/platform/FileSystem.h @@ -53,7 +53,7 @@ #include #endif -#if USE(CF) || (PLATFORM(QT) && defined(Q_WS_MAC)) +#if USE(CF) || (PLATFORM(QT) && defined(Q_OS_MACX)) typedef struct __CFBundle* CFBundleRef; typedef const struct __CFData* CFDataRef; #endif @@ -85,7 +85,7 @@ typedef GModule* PlatformModule; #elif PLATFORM(EFL) typedef Eina_Module* PlatformModule; #elif PLATFORM(QT) -#if defined(Q_WS_MAC) +#if defined(Q_OS_MACX) typedef CFBundleRef PlatformModule; #elif !defined(QT_NO_LIBRARY) typedef QLibrary* PlatformModule; diff --git a/Source/WebCore/platform/qt/FileSystemQt.cpp b/Source/WebCore/platform/qt/FileSystemQt.cpp index 16f4d7420..9744790d3 100644 --- a/Source/WebCore/platform/qt/FileSystemQt.cpp +++ b/Source/WebCore/platform/qt/FileSystemQt.cpp @@ -234,7 +234,7 @@ int writeToFile(PlatformFileHandle handle, const char* data, int length) bool unloadModule(PlatformModule module) { -#if defined(Q_WS_MAC) +#if defined(Q_OS_MACX) CFRelease(module); return true; diff --git a/Source/WebCore/plugins/mac/PluginPackageMac.cpp b/Source/WebCore/plugins/mac/PluginPackageMac.cpp index fead89bc3..23a5e231b 100644 --- a/Source/WebCore/plugins/mac/PluginPackageMac.cpp +++ b/Source/WebCore/plugins/mac/PluginPackageMac.cpp @@ -138,7 +138,7 @@ bool PluginPackage::fetchInfo() if (mimeTypesFileName && CFGetTypeID(mimeTypesFileName.get()) == CFStringGetTypeID()) { WTF::RetainPtr fileName = (CFStringRef)mimeTypesFileName.get(); - WTF::RetainPtr homeDir = adoptCF(homeDirectoryPath().createCFString()); + WTF::RetainPtr homeDir = homeDirectoryPath().createCFString(); WTF::RetainPtr path(AdoptCF, CFStringCreateWithFormat(0, 0, CFSTR("%@/Library/Preferences/%@"), homeDir.get(), fileName.get())); WTF::RetainPtr plist = readPListFile(path.get(), /*createFile*/ false, m_module); @@ -255,7 +255,7 @@ bool PluginPackage::load() return true; } - WTF::RetainPtr path(AdoptCF, m_path.createCFString()); + WTF::RetainPtr path = m_path.createCFString(); WTF::RetainPtr url(AdoptCF, CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path.get(), kCFURLPOSIXPathStyle, false)); m_module = CFBundleCreate(NULL, url.get()); diff --git a/Source/WebCore/plugins/mac/PluginViewMac.mm b/Source/WebCore/plugins/mac/PluginViewMac.mm index d1582d837..c163b5f3b 100644 --- a/Source/WebCore/plugins/mac/PluginViewMac.mm +++ b/Source/WebCore/plugins/mac/PluginViewMac.mm @@ -61,6 +61,9 @@ #include "WheelEvent.h" #include "npruntime_impl.h" #include "runtime_root.h" +#include +#include +#include #include #include #include diff --git a/Source/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/Source/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp index 58dad5b76..ae3fef43e 100644 --- a/Source/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp +++ b/Source/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp @@ -405,7 +405,7 @@ IntRect ChromeClientQt::windowResizerRect() const // always draw scrollbars on the right hand side, so we assume this to be the // location when computing the resize rect to reserve for WebKit. QPoint resizeCornerTopLeft = QPoint(topLevelGeometry.width(), topLevelGeometry.height()) - - QPoint(scollbarThickness, scollbarThickness)) + - QPoint(scollbarThickness, scollbarThickness) - m_webPage->viewRectRelativeToWindow().topLeft(); QRect resizeCornerRect = QRect(resizeCornerTopLeft, QSize(scollbarThickness, scollbarThickness)); diff --git a/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro b/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro index f962ee18b..ae45c0331 100644 --- a/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro +++ b/Tools/DumpRenderTree/qt/TestNetscapePlugin/TestNetscapePlugin.pro @@ -55,7 +55,7 @@ mac { LIBS += -framework Carbon -framework Cocoa -framework QuartzCore } -!win32:!embedded:!mac { +!win32:!mac { LIBS += -lX11 DEFINES += XP_UNIX } diff --git a/Tools/qmake/mkspecs/features/features.prf b/Tools/qmake/mkspecs/features/features.prf index cf6dc7fac..3a17133a6 100644 --- a/Tools/qmake/mkspecs/features/features.prf +++ b/Tools/qmake/mkspecs/features/features.prf @@ -71,7 +71,7 @@ defineTest(detectFeatures) { plugin_architecture_x11 \ plugin_process - } else: unix|win32-*:!embedded:!wince* { + } else: mac|win32 { WEBKIT_CONFIG += netscape_plugin_api # WebKit2 WEBKIT_CONFIG += plugin_architecture_unsupported diff --git a/Tools/qmake/mkspecs/features/unix/default_pre.prf b/Tools/qmake/mkspecs/features/unix/default_pre.prf index aafc48ceb..60de13338 100644 --- a/Tools/qmake/mkspecs/features/unix/default_pre.prf +++ b/Tools/qmake/mkspecs/features/unix/default_pre.prf @@ -12,10 +12,6 @@ CONFIG += object_parallel_to_source SBOX_CHECK = $$(_SBOX_DIR) !isEmpty(SBOX_CHECK): CONFIG += scratchbox -# If Qt is configured with embedded or QPA we set a convenience config -# flag that can be used to test for either of these situations. -contains(QT_CONFIG, qpa)|contains(QT_CONFIG, embedded): CONFIG += embedded - # Reduce linking memory pressure on 32-bit debug builds on Linux linux-g++*:CONFIG(debug, debug|release):isEqual(QT_ARCH,i386): CONFIG += use_all_in_one_files -- cgit v1.2.1 From b3923742ae3271ec1e273a5ffbc5555f3ee089ae Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Tue, 14 May 2013 08:31:16 +0000 Subject: [Qt] Fix a crash under ~PingLoader when the QNAM on the page has been destroyed. https://bugs.webkit.org/show_bug.cgi?id=116035 Reviewed by Simon Hausmann. Source/WebCore: Reproduced with arora which does destroy the QNetworkAccessManager in some situations. The problem is that PingLoader can still be pending meanwhile, holding a ResourceHandle with a dangling pointer to a QNetworkReply destroyed with the QNetworkAccessManager. * platform/network/qt/QNetworkReplyHandler.cpp: (WebCore::QNetworkReplyWrapper::QNetworkReplyWrapper): Set the parent to 0 like we did before the introduction of QNetworkReplyWrapper. (WebCore::QNetworkReplyWrapper::release): Source/WebKit/qt: * tests/qwebpage/tst_qwebpage.cpp: (tst_QWebPage::networkReplyParentChanged): Change-Id: Id53db216a6252f8471d6fa97093312843213e48d git-svn-id: http://svn.webkit.org/repository/webkit/trunk@150057 268f45cc-cd09-0410-ab3c-d52691b4dbfc Reviewed-by: Allan Sandfeld Jensen --- .../WebCore/platform/network/qt/QNetworkReplyHandler.cpp | 4 +++- Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index 904e85983..b763cc28f 100644 --- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -268,6 +268,9 @@ QNetworkReplyWrapper::QNetworkReplyWrapper(QNetworkReplyHandlerCallQueue* queue, { Q_ASSERT(m_reply); + // Allow the QNetworkReply to outlive its parent QNetworkAccessManager in case the later gets destroyed before our ResourceHandle is done with it. + m_reply->setParent(0); + // setFinished() must be the first that we connect, so isFinished() is updated when running other slots. connect(m_reply, SIGNAL(finished()), this, SLOT(setFinished())); connect(m_reply, SIGNAL(finished()), this, SLOT(receiveMetaData())); @@ -291,7 +294,6 @@ QNetworkReply* QNetworkReplyWrapper::release() m_reply = 0; m_sniffer = nullptr; - reply->setParent(0); return reply; } diff --git a/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index fbba56d6c..4f7b36c21 100644 --- a/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -173,6 +174,7 @@ private Q_SLOTS: #endif void originatingObjectInNetworkRequests(); + void networkReplyParentChanged(); void testJSPrompt(); void showModalDialog(); void testStopScheduledPageRefresh(); @@ -2846,6 +2848,19 @@ void tst_QWebPage::originatingObjectInNetworkRequests() QVERIFY(qobject_cast(networkManager->requests.at(i).originatingObject()) == childFrames.at(i)); } +void tst_QWebPage::networkReplyParentChanged() +{ + TestNetworkManager* networkManager = new TestNetworkManager(m_page); + m_page->setNetworkAccessManager(networkManager); + networkManager->requests.clear(); + + // Trigger a load and check if pending QNetworkReplies have been reparented before returning to the event loop. + m_view->load(QUrl("qrc:///resources/content.html")); + + QVERIFY(networkManager->requests.count() > 0); + QVERIFY(networkManager->findChildren().isEmpty()); +} + /** * Test fixups for https://bugs.webkit.org/show_bug.cgi?id=30914 * -- cgit v1.2.1 From b3b8ed036fb802f638cac9c637065363fba8b4fa Mon Sep 17 00:00:00 2001 From: Jocelyn Turcotte Date: Wed, 15 May 2013 16:31:13 +0000 Subject: [Qt] Fix a crash under ~PingLoader when the QNAM on the page has been destroyed. https://bugs.webkit.org/show_bug.cgi?id=116035 Reviewed by Allan Sandfeld Jensen. Source/WebCore: The previous fix only moved the crash location from WebKit down to QNetworkReplyHttpImpl which expects its QNetworkAccessManager to still be alive. Fix it by watching the QNetworkReply's destroyed() signal and avoid the dangling pointer instead. The QNetworkReply doesn't need to be aborted in this case anyway. * platform/network/qt/QNetworkReplyHandler.cpp: (WebCore::QNetworkReplyWrapper::QNetworkReplyWrapper): (WebCore::QNetworkReplyWrapper::release): (WebCore::QNetworkReplyWrapper::stopForwarding): Rename resetConnections to stopForwarding since not all connections are related to data forwarding to the client anymore. (WebCore::QNetworkReplyWrapper::receiveMetaData): (WebCore::QNetworkReplyWrapper::replyDestroyed): (WebCore::QNetworkReplyWrapper::didReceiveFinished): * platform/network/qt/QNetworkReplyHandler.h: (QNetworkReplyWrapper): Source/WebKit/qt: * tests/qwebpage/tst_qwebpage.cpp: (tst_QWebPage::networkReplyParentDidntChange): Change test to match the new expectation. (tst_QWebPage::destroyQNAMBeforeAbortDoesntCrash): Change-Id: I5e82b8ccc8fccf496669af8de76888e367480f67 git-svn-id: http://svn.webkit.org/repository/webkit/trunk@150120 268f45cc-cd09-0410-ab3c-d52691b4dbfc Reviewed-by: Allan Sandfeld Jensen --- .../platform/network/qt/QNetworkReplyHandler.cpp | 21 ++++++++++++--------- .../platform/network/qt/QNetworkReplyHandler.h | 3 ++- Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 22 ++++++++++++++++++---- 3 files changed, 32 insertions(+), 14 deletions(-) diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp index b763cc28f..d4bc9bcb8 100644 --- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp +++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.cpp @@ -268,13 +268,11 @@ QNetworkReplyWrapper::QNetworkReplyWrapper(QNetworkReplyHandlerCallQueue* queue, { Q_ASSERT(m_reply); - // Allow the QNetworkReply to outlive its parent QNetworkAccessManager in case the later gets destroyed before our ResourceHandle is done with it. - m_reply->setParent(0); - // setFinished() must be the first that we connect, so isFinished() is updated when running other slots. connect(m_reply, SIGNAL(finished()), this, SLOT(setFinished())); connect(m_reply, SIGNAL(finished()), this, SLOT(receiveMetaData())); connect(m_reply, SIGNAL(readyRead()), this, SLOT(receiveMetaData())); + connect(m_reply, SIGNAL(destroyed()), this, SLOT(replyDestroyed())); } QNetworkReplyWrapper::~QNetworkReplyWrapper() @@ -289,7 +287,7 @@ QNetworkReply* QNetworkReplyWrapper::release() if (!m_reply) return 0; - resetConnections(); + m_reply->disconnect(this); QNetworkReply* reply = m_reply; m_reply = 0; m_sniffer = nullptr; @@ -303,10 +301,10 @@ void QNetworkReplyWrapper::synchronousLoad() receiveMetaData(); } -void QNetworkReplyWrapper::resetConnections() +void QNetworkReplyWrapper::stopForwarding() { if (m_reply) { - // Disconnect all connections except the one to setFinished() slot. + // Disconnect all connections that might affect the ResourceHandleClient. m_reply->disconnect(this, SLOT(receiveMetaData())); m_reply->disconnect(this, SLOT(didReceiveFinished())); m_reply->disconnect(this, SLOT(didReceiveReadyRead())); @@ -317,8 +315,7 @@ void QNetworkReplyWrapper::resetConnections() void QNetworkReplyWrapper::receiveMetaData() { // This slot is only used to receive the first signal from the QNetworkReply object. - resetConnections(); - + stopForwarding(); WTF::String contentType = m_reply->header(QNetworkRequest::ContentTypeHeader).toString(); m_encoding = extractCharsetFromMediaType(contentType); @@ -371,6 +368,12 @@ void QNetworkReplyWrapper::setFinished() m_reply->setProperty("_q_isFinished", true); } +void QNetworkReplyWrapper::replyDestroyed() +{ + m_reply = 0; + m_sniffer = nullptr; +} + void QNetworkReplyWrapper::emitMetaDataChanged() { QueueLocker lock(m_queue); @@ -401,7 +404,7 @@ void QNetworkReplyWrapper::didReceiveReadyRead() void QNetworkReplyWrapper::didReceiveFinished() { // Disconnecting will make sure that nothing will happen after emitting the finished signal. - resetConnections(); + stopForwarding(); m_queue->push(&QNetworkReplyHandler::finish); } diff --git a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h index a68904147..6bc35cc12 100644 --- a/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h +++ b/Source/WebCore/platform/network/qt/QNetworkReplyHandler.h @@ -94,9 +94,10 @@ private Q_SLOTS: void didReceiveReadyRead(); void receiveSniffedMIMEType(); void setFinished(); + void replyDestroyed(); private: - void resetConnections(); + void stopForwarding(); void emitMetaDataChanged(); QNetworkReply* m_reply; diff --git a/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 4f7b36c21..e5abf6b79 100644 --- a/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/Source/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -174,7 +174,8 @@ private Q_SLOTS: #endif void originatingObjectInNetworkRequests(); - void networkReplyParentChanged(); + void networkReplyParentDidntChange(); + void destroyQNAMBeforeAbortDoesntCrash(); void testJSPrompt(); void showModalDialog(); void testStopScheduledPageRefresh(); @@ -2848,17 +2849,30 @@ void tst_QWebPage::originatingObjectInNetworkRequests() QVERIFY(qobject_cast(networkManager->requests.at(i).originatingObject()) == childFrames.at(i)); } -void tst_QWebPage::networkReplyParentChanged() +void tst_QWebPage::networkReplyParentDidntChange() { TestNetworkManager* networkManager = new TestNetworkManager(m_page); m_page->setNetworkAccessManager(networkManager); networkManager->requests.clear(); - // Trigger a load and check if pending QNetworkReplies have been reparented before returning to the event loop. + // Trigger a load and check that pending QNetworkReplies haven't been reparented before returning to the event loop. m_view->load(QUrl("qrc:///resources/content.html")); QVERIFY(networkManager->requests.count() > 0); - QVERIFY(networkManager->findChildren().isEmpty()); + QVERIFY(networkManager->findChildren().size() > 0); +} + +void tst_QWebPage::destroyQNAMBeforeAbortDoesntCrash() +{ + QNetworkAccessManager* networkManager = new QNetworkAccessManager; + m_page->setNetworkAccessManager(networkManager); + + m_view->load(QUrl("qrc:///resources/content.html")); + delete networkManager; + // This simulates what PingLoader does with its QNetworkReply when it times out. + // PingLoader isn't attached to a QWebPage and can be kept alive + // for 60000 seconds (~16.7 hours) to then cancel its ResourceHandle. + m_view->stop(); } /** -- cgit v1.2.1 From 1810e3848d15ffbe9529f53866fc0ede8d947fef Mon Sep 17 00:00:00 2001 From: "graouts@apple.com" Date: Tue, 11 Jun 2013 11:50:21 +0200 Subject: Glyphs may fail to render when using SVG font MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugs.webkit.org/show_bug.cgi?id=115193 Reviewed by Simon Fraser. Calling SimpleFontData::applyTransforms() when the font used is an SVG font makes little sense since Core Text doesn’t know or understand SVG fonts and would be passed some other, unrelated platform font. * platform/graphics/SimpleFontData.h: (WebCore::SimpleFontData::applyTransforms): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@149144 268f45cc-cd09-0410-ab3c-d52691b4dbfc Task-number: QTBUG-31663 Change-Id: Ic631da7c64e477c4f6199053584d36827bd3a5b1 Reviewed-by: Pierre Rossi Reviewed-by: Robert Loehning --- Source/WebCore/platform/graphics/SimpleFontData.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/WebCore/platform/graphics/SimpleFontData.h b/Source/WebCore/platform/graphics/SimpleFontData.h index 8621ca596..a99482404 100644 --- a/Source/WebCore/platform/graphics/SimpleFontData.h +++ b/Source/WebCore/platform/graphics/SimpleFontData.h @@ -200,6 +200,8 @@ public: bool applyTransforms(GlyphBufferGlyph* glyphs, GlyphBufferAdvance* advances, size_t glyphCount, TypesettingFeatures typesettingFeatures) const { + if (isSVGFont()) + return false; #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED > 1080 wkCTFontTransformOptions options = (typesettingFeatures & Kerning ? wkCTFontTransformApplyPositioning : 0) | (typesettingFeatures & Ligatures ? wkCTFontTransformApplyShaping : 0); return wkCTFontTransformGlyphs(m_platformData.ctFont(), glyphs, reinterpret_cast(advances), glyphCount, options); -- cgit v1.2.1 From c4e25a8d5fc2d840c78fbddea06d32bf34b89083 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 18 Jun 2013 16:23:52 +0200 Subject: [Qt] Set windows key-code for multimedia keys https://bugs.webkit.org/show_bug.cgi?id=117535 Reviewed by Jocelyn Turcotte. Map Qt Key-events to their defined windows keycode values. * platform/qt/PlatformKeyboardEventQt.cpp: (WebCore::windowsKeyCodeForKeyEvent): Change-Id: If7dbf14afbcd60d0454334c9bd0a487d3b74b08c git-svn-id: http://svn.webkit.org/repository/webkit/trunk@151494 268f45cc-cd09-0410-ab3c-d52691b4dbfc Reviewed-by: Jocelyn Turcotte --- .../platform/qt/PlatformKeyboardEventQt.cpp | 23 +++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp b/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp index 5123a8d8c..c2ebcd02e 100644 --- a/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp +++ b/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp @@ -433,13 +433,22 @@ int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad) // VK_BROWSER_SEARCH (AA) Windows 2000/XP: Browser Search key // VK_BROWSER_FAVORITES (AB) Windows 2000/XP: Browser Favorites key // VK_BROWSER_HOME (AC) Windows 2000/XP: Browser Start and Home key - // VK_VOLUME_MUTE (AD) Windows 2000/XP: Volume Mute key - // VK_VOLUME_DOWN (AE) Windows 2000/XP: Volume Down key - // VK_VOLUME_UP (AF) Windows 2000/XP: Volume Up key - // VK_MEDIA_NEXT_TRACK (B0) Windows 2000/XP: Next Track key - // VK_MEDIA_PREV_TRACK (B1) Windows 2000/XP: Previous Track key - // VK_MEDIA_STOP (B2) Windows 2000/XP: Stop Media key - // VK_MEDIA_PLAY_PAUSE (B3) Windows 2000/XP: Play/Pause Media key + + case Qt::Key_VolumeMute: + return VK_VOLUME_MUTE; // (AD) Windows 2000/XP: Volume Mute key + case Qt::Key_VolumeDown: + return VK_VOLUME_DOWN; // (AE) Windows 2000/XP: Volume Down key + case Qt::Key_VolumeUp: + return VK_VOLUME_UP; // (AF) Windows 2000/XP: Volume Up key + case Qt::Key_MediaNext: + return VK_MEDIA_NEXT_TRACK; // (B0) Windows 2000/XP: Next Track key + case Qt::Key_MediaPrevious: + return VK_MEDIA_PREV_TRACK; // (B1) Windows 2000/XP: Previous Track key + case Qt::Key_MediaStop: + return VK_MEDIA_STOP; // (B2) Windows 2000/XP: Stop Media key + case Qt::Key_MediaTogglePlayPause: + return VK_MEDIA_PLAY_PAUSE; // (B3) Windows 2000/XP: Play/Pause Media key + // VK_LAUNCH_MAIL (B4) Windows 2000/XP: Start Mail key // VK_LAUNCH_MEDIA_SELECT (B5) Windows 2000/XP: Select Media key // VK_LAUNCH_APP1 (B6) Windows 2000/XP: Start Application 1 key -- cgit v1.2.1 From 3b25694b613fe8b855a9aa7519645ed419e8e549 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 18 Jun 2013 16:24:34 +0200 Subject: [Qt] Map rewind and fast forward keys to match GoogleTV https://bugs.webkit.org/show_bug.cgi?id=117634 Reviewed by Jocelyn Turcotte. Set the same keycode for media keys rewind and fast-forward as GoogleTV does. * platform/qt/PlatformKeyboardEventQt.cpp: (WebCore::windowsKeyCodeForKeyEvent): Change-Id: I6bad920686b3e2f07e045b3a22e36eb8d0eb6400 git-svn-id: http://svn.webkit.org/repository/webkit/trunk@151588 268f45cc-cd09-0410-ab3c-d52691b4dbfc Reviewed-by: Jocelyn Turcotte --- Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp b/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp index c2ebcd02e..470612c63 100644 --- a/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp +++ b/Source/WebCore/platform/qt/PlatformKeyboardEventQt.cpp @@ -499,6 +499,12 @@ int windowsKeyCodeForKeyEvent(unsigned int keycode, bool isKeypad) return VK_OEM_7; // case '\'': case '"': return 0xDE; // VK_OEM_8 (DF) Used for miscellaneous characters; it can vary by keyboard. // VK_OEM_102 (E2) Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard + + case Qt::Key_AudioRewind: + return 0xE3; // (E3) Android/GoogleTV: Rewind media key (Windows: VK_ICO_HELP Help key on 1984 Olivetti M24 deluxe keyboard) + case Qt::Key_AudioForward: + return 0xE4; // (E4) Android/GoogleTV: Fast forward media key (Windows: VK_ICO_00 '00' key on 1984 Olivetti M24 deluxe keyboard) + // VK_PROCESSKEY (E5) Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key // VK_PACKET (E7) Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT,SendInput, WM_KEYDOWN, and WM_KEYUP // VK_ATTN (F6) Attn key -- cgit v1.2.1