Log Message
[Qt] X11 plugins need to be reworked for Qt5+WK1 https://bugs.webkit.org/show_bug.cgi?id=80691
Reviewed by Simon Hausmann. .: Implement basic windowless plugin support with Qt5. * Source/api.pri: Need private API's to be able to use QApplicationPrivate::windowForWidget. Source/WebCore: Implement basic windowless plugin support with Qt5. The solution is the same that has been chosen for WebKit2. We get the content drawed by the plugin from the X server as an image, create a QImage from it and paint it to the window surface with QPainter. Performance is sufficient for basic video playback. No new tests, covered by existing plugin tests. * Target.pri: * WebCore.pri: * platform/qt/QWebPageClient.h: (QWebPageClient): * plugins/PluginView.h: (PluginView): * plugins/qt/PluginPackageQt.cpp: (WebCore::PluginPackage::isPluginBlacklisted): Blacklist plugins that are incompatible with Qt5. The only one I know about currently is skypebuttons but the list can be extended in the future. (WebCore): (WebCore::PluginPackage::load): * plugins/qt/PluginViewQt.cpp: (X11Environment): (WebCore): (WebCore::x11Display): (WebCore::x11Screen): (WebCore::rootWindowID): (WebCore::displayDepth): (WebCore::syncX): (WebCore::PluginView::platformPageClient): Added a safe convenience getter for the QWebpageClient. (WebCore::PluginView::updatePluginWidget): (WebCore::PluginView::setFocus): (WebCore::setupGraphicsExposeEvent): (WebCore::PluginView::paintUsingXPixmap): (WebCore::setSharedXEventFields): (WebCore::PluginView::initXEvent): (WebCore::PluginView::setXKeyEventSpecificFields): (WebCore::setXButtonEventSpecificFields): (WebCore::setXMotionEventSpecificFields): (WebCore::setXCrossingEventSpecificFields): (WebCore::PluginView::setNPWindowIfNeeded): (WebCore::PluginView::setParentVisible): (WebCore::PluginView::platformGetValue): (WebCore::PluginView::invalidateRect): (WebCore::getVisualAndColormap): Refactored this function to make it more clear what does it actually do. (WebCore::PluginView::platformStart): (WebCore::PluginView::platformDestroy): Source/WebKit/qt: * Api/qwebsettings.cpp: (QWebSettings::enablePersistentStorage): Build fix for Qt5. * WebCoreSupport/FrameLoaderClientQt.cpp: (WebCore::FrameLoaderClientQt::createPlugin): Inject the wmode parameter for flash so it will work in windowless, non-transparent mode which is the only one we support currently. * WebCoreSupport/PageClientQt.cpp: (WebCore): (WebCore::QWebPageClient::ownerWindow): Added a getter for the top level window so the PluginView can get it without calling into QtWidgets code. Tools: Implement basic windowless plugin support with Qt5. * qmake/mkspecs/features/features.prf: Enable NPAPI plugins if X11 libraries are available. * qmake/mkspecs/features/functions.prf: Added a convenience function to determine availability of X11 libraries.
Modified Paths
- trunk/ChangeLog
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/Target.pri
- trunk/Source/WebCore/WebCore.pri
- trunk/Source/WebCore/platform/qt/QWebPageClient.h
- trunk/Source/WebCore/plugins/PluginView.h
- trunk/Source/WebCore/plugins/qt/PluginPackageQt.cpp
- trunk/Source/WebCore/plugins/qt/PluginViewQt.cpp
- trunk/Source/WebKit/qt/Api/qwebsettings.cpp
- trunk/Source/WebKit/qt/ChangeLog
- trunk/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp
- trunk/Source/WebKit/qt/WebCoreSupport/PageClientQt.cpp
- trunk/Tools/ChangeLog
- trunk/Tools/qmake/mkspecs/features/features.prf
- trunk/Tools/qmake/mkspecs/features/functions.prf
Diff
Modified: trunk/ChangeLog (116402 => 116403)
--- trunk/ChangeLog 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/ChangeLog 2012-05-08 08:42:37 UTC (rev 116403)
@@ -1,3 +1,15 @@
+2012-05-08 Balazs Kelemen <[email protected]>
+
+ [Qt] X11 plugins need to be reworked for Qt5+WK1
+ https://bugs.webkit.org/show_bug.cgi?id=80691
+
+ Reviewed by Simon Hausmann.
+
+ Implement basic windowless plugin support with Qt5.
+
+ * Source/api.pri: Need private API's to be able
+ to use QApplicationPrivate::windowForWidget.
+
2012-05-07 Dave Tu <[email protected]>
Adjust flakiness dashboard gpu_tests image diff URLs.
Modified: trunk/Source/WebCore/ChangeLog (116402 => 116403)
--- trunk/Source/WebCore/ChangeLog 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Source/WebCore/ChangeLog 2012-05-08 08:42:37 UTC (rev 116403)
@@ -1,3 +1,62 @@
+2012-05-08 Balazs Kelemen <[email protected]>
+
+ [Qt] X11 plugins need to be reworked for Qt5+WK1
+ https://bugs.webkit.org/show_bug.cgi?id=80691
+
+ Reviewed by Simon Hausmann.
+
+ Implement basic windowless plugin support with Qt5.
+ The solution is the same that has been chosen for
+ WebKit2. We get the content drawed by the plugin
+ from the X server as an image, create a QImage
+ from it and paint it to the window surface with QPainter.
+ Performance is sufficient for basic video playback.
+
+ No new tests, covered by existing plugin tests.
+
+ * Target.pri:
+ * WebCore.pri:
+ * platform/qt/QWebPageClient.h:
+ (QWebPageClient):
+ * plugins/PluginView.h:
+ (PluginView):
+ * plugins/qt/PluginPackageQt.cpp:
+ (WebCore::PluginPackage::isPluginBlacklisted):
+ Blacklist plugins that are incompatible with Qt5.
+ The only one I know about currently is skypebuttons
+ but the list can be extended in the future.
+ (WebCore):
+ (WebCore::PluginPackage::load):
+ * plugins/qt/PluginViewQt.cpp:
+ (X11Environment):
+ (WebCore):
+ (WebCore::x11Display):
+ (WebCore::x11Screen):
+ (WebCore::rootWindowID):
+ (WebCore::displayDepth):
+ (WebCore::syncX):
+ (WebCore::PluginView::platformPageClient): Added a safe
+ convenience getter for the QWebpageClient.
+ (WebCore::PluginView::updatePluginWidget):
+ (WebCore::PluginView::setFocus):
+ (WebCore::setupGraphicsExposeEvent):
+ (WebCore::PluginView::paintUsingXPixmap):
+ (WebCore::setSharedXEventFields):
+ (WebCore::PluginView::initXEvent):
+ (WebCore::PluginView::setXKeyEventSpecificFields):
+ (WebCore::setXButtonEventSpecificFields):
+ (WebCore::setXMotionEventSpecificFields):
+ (WebCore::setXCrossingEventSpecificFields):
+ (WebCore::PluginView::setNPWindowIfNeeded):
+ (WebCore::PluginView::setParentVisible):
+ (WebCore::PluginView::platformGetValue):
+ (WebCore::PluginView::invalidateRect):
+ (WebCore::getVisualAndColormap):
+ Refactored this function to make it more clear
+ what does it actually do.
+ (WebCore::PluginView::platformStart):
+ (WebCore::PluginView::platformDestroy):
+
2012-05-07 Antti Koivisto <[email protected]>
Inline Node::traverseNextNode
Modified: trunk/Source/WebCore/Target.pri (116402 => 116403)
--- trunk/Source/WebCore/Target.pri 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Source/WebCore/Target.pri 2012-05-08 08:42:37 UTC (rev 116403)
@@ -2970,11 +2970,13 @@
plugins/mac/PluginViewMac.mm
} else {
SOURCES += \
- plugins/qt/PluginContainerQt.cpp \
plugins/qt/PluginPackageQt.cpp \
plugins/qt/PluginViewQt.cpp
- HEADERS += \
- plugins/qt/PluginContainerQt.h
+
+ haveQt(4) {
+ SOURCES += plugins/qt/PluginContainerQt.cpp
+ HEADERS += plugins/qt/PluginContainerQt.h
+ }
}
}
Modified: trunk/Source/WebCore/WebCore.pri (116402 => 116403)
--- trunk/Source/WebCore/WebCore.pri 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Source/WebCore/WebCore.pri 2012-05-08 08:42:37 UTC (rev 116403)
@@ -134,7 +134,7 @@
INCLUDEPATH += platform/mac
# Note: XP_MACOSX is defined in npapi.h
} else {
- !embedded {
+ xlibAvailable() {
CONFIG += x11
LIBS += -lXrender
DEFINES += MOZ_X11
Modified: trunk/Source/WebCore/platform/qt/QWebPageClient.h (116402 => 116403)
--- trunk/Source/WebCore/platform/qt/QWebPageClient.h 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Source/WebCore/platform/qt/QWebPageClient.h 2012-05-08 08:42:37 UTC (rev 116403)
@@ -43,6 +43,7 @@
QT_BEGIN_NAMESPACE
class QStyle;
+class QWindow;
QT_END_NAMESPACE
namespace WebCore {
@@ -109,6 +110,9 @@
virtual void createPlatformGraphicsContext3D(PlatformGraphicsContext3D*,
PlatformGraphicsSurface3D*) = 0;
#endif
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ virtual QWindow* ownerWindow() const;
+#endif
protected:
#ifndef QT_NO_CURSOR
Modified: trunk/Source/WebCore/plugins/PluginView.h (116402 => 116403)
--- trunk/Source/WebCore/plugins/PluginView.h 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Source/WebCore/plugins/PluginView.h 2012-05-08 08:42:37 UTC (rev 116403)
@@ -426,6 +426,7 @@
static bool s_isRunningUnderDRT;
static void setXKeyEventSpecificFields(XEvent*, KeyboardEvent*);
void paintUsingXPixmap(QPainter* painter, const QRect &exposedRect);
+ QWebPageClient* platformPageClient() const;
#endif
#if USE(ACCELERATED_COMPOSITING_PLUGIN_LAYER)
OwnPtr<PlatformLayer> m_platformLayer;
Modified: trunk/Source/WebCore/plugins/qt/PluginPackageQt.cpp (116402 => 116403)
--- trunk/Source/WebCore/plugins/qt/PluginPackageQt.cpp 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Source/WebCore/plugins/qt/PluginPackageQt.cpp 2012-05-08 08:42:37 UTC (rev 116403)
@@ -31,6 +31,7 @@
#include "npruntime_impl.h"
#include "PluginDatabase.h"
#include "PluginDebug.h"
+#include <QFileInfo>
#include <wtf/text/CString.h>
namespace WebCore {
@@ -129,6 +130,23 @@
}
}
+bool PluginPackage::isPluginBlacklisted()
+{
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ // TODO: enumerate all plugins that are incompatible with Qt5.
+ const QLatin1String pluginBlacklist[] = {
+ QLatin1String("skypebuttons")
+ };
+
+ QString baseName = QFileInfo(static_cast<QString>(m_path)).baseName();
+ for (unsigned i = 0; i < sizeof(pluginBlacklist) / sizeof(QLatin1String); ++i) {
+ if (baseName == pluginBlacklist[i])
+ return true;
+ }
+#endif
+ return false;
+}
+
bool PluginPackage::load()
{
if (m_isLoaded) {
@@ -136,6 +154,9 @@
return true;
}
+ if (isPluginBlacklisted())
+ return false;
+
m_module = new QLibrary((QString)m_path);
m_module->setLoadHints(QLibrary::ResolveAllSymbolsHint);
if (!m_module->load()) {
Modified: trunk/Source/WebCore/plugins/qt/PluginViewQt.cpp (116402 => 116403)
--- trunk/Source/WebCore/plugins/qt/PluginViewQt.cpp 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Source/WebCore/plugins/qt/PluginViewQt.cpp 2012-05-08 08:42:37 UTC (rev 116403)
@@ -58,7 +58,6 @@
#include "Page.h"
#include "PlatformMouseEvent.h"
#include "PlatformKeyboardEvent.h"
-#include "PluginContainerQt.h"
#include "PluginDebug.h"
#include "PluginPackage.h"
#include "PluginMainThreadScheduler.h"
@@ -69,15 +68,8 @@
#if USE(JSC)
#include "runtime_root.h"
#endif
-
-#include <QApplication>
-#include <QDesktopWidget>
-#include <QGraphicsWidget>
#include <QKeyEvent>
#include <QPainter>
-#include <QStyleOptionGraphicsItem>
-#include <QWidget>
-#include <QX11Info>
#include <X11/X.h>
#ifndef QT_NO_XRENDER
#define Bool int
@@ -87,6 +79,23 @@
#include <runtime/JSLock.h>
#include <runtime/JSValue.h>
+#define HAVE_QT5 (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
+
+#if HAVE(QT5)
+#include "QtX11ImageConversion.h"
+#include <QGuiApplication>
+#include <QPlatformNativeInterface>
+#include <QWindow>
+#else
+#include "PluginContainerQt.h"
+#include <QApplication>
+#include <QDesktopWidget>
+#include <QGraphicsWidget>
+#include <QStyleOptionGraphicsItem>
+#include <QWidget>
+#include <QX11Info>
+#endif
+
using JSC::ExecState;
#if USE(JSC)
using JSC::Interpreter;
@@ -105,7 +114,37 @@
using namespace HTMLNames;
-#if USE(ACCELERATED_COMPOSITING)
+struct X11Environment {
+ Display* display;
+ int screenID;
+ unsigned long rootWindowID;
+ int displayDepth;
+};
+
+static X11Environment x11Environment = { 0, 0, 0, 0 };
+
+static inline Display* x11Display() { return x11Environment.display; }
+static inline int x11Screen() { return x11Environment.screenID; }
+static inline unsigned long rootWindowID() { return x11Environment.rootWindowID; }
+static inline int displayDepth() { return x11Environment.displayDepth; }
+
+static inline void syncX()
+{
+ XSync(x11Display(), false);
+}
+
+QWebPageClient* PluginView::platformPageClient() const
+{
+ FrameView* view = m_parentFrame->view();
+ if (!view)
+ return 0;
+ HostWindow* hostWindow = view->hostWindow();
+ if (!hostWindow)
+ return 0;
+ return hostWindow->platformPageClient();
+}
+
+#if !HAVE(QT5) && USE(ACCELERATED_COMPOSITING)
// Qt's GraphicsLayer (GraphicsLayerQt) requires layers to be QGraphicsWidgets
class PluginGraphicsLayerQt : public QGraphicsWidget {
public:
@@ -154,11 +193,11 @@
if (!m_isWindowed && m_windowRect.size() != oldWindowRect.size()) {
if (m_drawable)
- XFreePixmap(QX11Info::display(), m_drawable);
+ XFreePixmap(x11Display(), m_drawable);
- m_drawable = XCreatePixmap(QX11Info::display(), QX11Info::appRootWindow(), m_windowRect.width(), m_windowRect.height(),
+ m_drawable = XCreatePixmap(x11Display(), rootWindowID(), m_windowRect.width(), m_windowRect.height(),
((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth);
- QApplication::syncX(); // make sure that the server knows about the Drawable
+ syncX(); // make sure that the server knows about the Drawable
}
// do not call setNPWindowIfNeeded immediately, will be called on paint()
@@ -187,12 +226,13 @@
void PluginView::setFocus(bool focused)
{
+#if !HAVE(QT5) // Windowed mode is not supported with Qt5 yet (so platformPluginWidget() is always null).
if (platformPluginWidget()) {
if (focused)
static_cast<QWidget*>(platformPluginWidget())->setFocus(Qt::OtherFocusReason);
- } else {
+ } else
+#endif
Widget::setFocus(focused);
- }
}
void PluginView::show()
@@ -207,12 +247,30 @@
Widget::hide();
}
+static void setupGraphicsExposeEvent(Pixmap drawable, const QRect& exposedRect, XEvent& xevent)
+{
+ memset(&xevent, 0, sizeof(XEvent));
+ XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose;
+ exposeEvent.type = GraphicsExpose;
+ exposeEvent.display = x11Display();
+ exposeEvent.drawable = drawable;
+ exposeEvent.x = exposedRect.x();
+ exposeEvent.y = exposedRect.y();
+ exposeEvent.width = exposedRect.x() + exposedRect.width(); // flash bug? it thinks width is the right in transparent mode
+ exposeEvent.height = exposedRect.y() + exposedRect.height(); // flash bug? it thinks height is the bottom in transparent mode
+}
+
void PluginView::paintUsingXPixmap(QPainter* painter, const QRect &exposedRect)
{
+ bool shouldSyncX = m_pluginDisplay && m_pluginDisplay != x11Display();
+ XEvent xevent;
+
+#if HAVE(QT5)
+ setupGraphicsExposeEvent(m_drawable, exposedRect, xevent);
+#else
QPixmap qtDrawable = QPixmap::fromX11Pixmap(m_drawable, QPixmap::ExplicitlyShared);
const int drawableDepth = ((NPSetWindowCallbackStruct*)m_npWindow.ws_info)->depth;
ASSERT(drawableDepth == qtDrawable.depth());
- const bool syncX = m_pluginDisplay && m_pluginDisplay != QX11Info::display();
// When printing, Qt uses a QPicture to capture the output in preview mode. The
// QPicture holds a reference to the X Pixmap. As a result, the print preview would
@@ -232,7 +290,7 @@
// We cannot grab contents from the backing store when painting on QGraphicsView items
// (because backing store contents are already transformed). What we really mean to do
// here is to check if we are painting on QWebView, but let's be a little permissive :)
- QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
+ QWebPageClient* client = platformPageClient();
const bool backingStoreHasUntransformedContents = client && qobject_cast<QWidget*>(client->pluginParent());
if (hasValidBackingStore && backingStorePixmap->depth() == drawableDepth
@@ -246,27 +304,26 @@
painter.fillRect(exposedRect, Qt::white);
}
- if (syncX)
- QApplication::syncX();
+ if (shouldSyncX)
+ syncX();
}
- XEvent xevent;
- memset(&xevent, 0, sizeof(XEvent));
- XGraphicsExposeEvent& exposeEvent = xevent.xgraphicsexpose;
- exposeEvent.type = GraphicsExpose;
- exposeEvent.display = QX11Info::display();
- exposeEvent.drawable = qtDrawable.handle();
- exposeEvent.x = exposedRect.x();
- exposeEvent.y = exposedRect.y();
- exposeEvent.width = exposedRect.x() + exposedRect.width(); // flash bug? it thinks width is the right in transparent mode
- exposeEvent.height = exposedRect.y() + exposedRect.height(); // flash bug? it thinks height is the bottom in transparent mode
+ setupGraphicsExposeEvent(qtDrawable.handle(), exposedRect, xevent);
+#endif
dispatchNPEvent(xevent);
- if (syncX)
+ if (shouldSyncX)
XSync(m_pluginDisplay, false); // sync changes by plugin
+#if HAVE(QT5)
+ XImage* xImage = XGetImage(x11Display(), m_drawable, exposedRect.x(), exposedRect.y(),
+ exposedRect.width(), exposedRect.height(), ULONG_MAX, ZPixmap);
+ painter->drawImage(QPoint(exposedRect.x(), exposedRect.y()), qimageFromXImage(xImage), exposedRect);
+ XDestroyImage(xImage);
+#else
painter->drawPixmap(QPoint(exposedRect.x(), exposedRect.y()), qtDrawable, exposedRect);
+#endif
}
void PluginView::paint(GraphicsContext* context, const IntRect& rect)
@@ -331,24 +388,29 @@
return accepted;
}
-void setSharedXEventFields(XEvent* xEvent, QWidget* ownerWidget)
+void setSharedXEventFields(XEvent* xEvent, QWebPageClient* pageClient)
{
xEvent->xany.serial = 0; // we are unaware of the last request processed by X Server
xEvent->xany.send_event = false;
- xEvent->xany.display = QX11Info::display();
+ xEvent->xany.display = x11Display();
// NOTE: event->xany.window doesn't always respond to the .window property of other XEvent's
// but does in the case of KeyPress, KeyRelease, ButtonPress, ButtonRelease, and MotionNotify
// events; thus, this is right:
- xEvent->xany.window = ownerWidget ? ownerWidget->window()->handle() : 0;
+#if HAVE(QT5)
+ QWindow* window = pageClient ? pageClient->ownerWindow() : 0;
+ xEvent->xany.window = window ? window->winId() : 0;
+#else
+ QWidget* ownerWidget = pageClient ? pageClient->ownerWidget() : 0;
+ xEvent->xany.window = ownerWidget ? ownerWidget->window()->winId() : 0;
+#endif
}
void PluginView::initXEvent(XEvent* xEvent)
{
memset(xEvent, 0, sizeof(XEvent));
- QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
- QWidget* ownerWidget = client ? client->ownerWidget() : 0;
- setSharedXEventFields(xEvent, ownerWidget);
+ QWebPageClient* client = platformPageClient();
+ setSharedXEventFields(xEvent, client);
}
void PluginView::setXKeyEventSpecificFields(XEvent* xEvent, KeyboardEvent* event)
@@ -356,7 +418,7 @@
const PlatformKeyboardEvent* keyEvent = event->keyEvent();
xEvent->type = (event->type() == eventNames().keydownEvent) ? 2 : 3; // ints as Qt unsets KeyPress and KeyRelease
- xEvent->xkey.root = QX11Info::appRootWindow();
+ xEvent->xkey.root = rootWindowID();
xEvent->xkey.subwindow = 0; // we have no child window
xEvent->xkey.time = event->timeStamp();
xEvent->xkey.state = keyEvent->nativeModifiers();
@@ -370,7 +432,7 @@
QKeyEvent* qKeyEvent = keyEvent->qtEvent();
ASSERT(qKeyEvent);
QString keyText = qKeyEvent->text().left(1);
- xEvent->xkey.keycode = XKeysymToKeycode(QX11Info::display(), XStringToKeysym(keyText.toUtf8().constData()));
+ xEvent->xkey.keycode = XKeysymToKeycode(x11Display(), XStringToKeysym(keyText.toUtf8().constData()));
}
xEvent->xkey.same_screen = true;
@@ -419,7 +481,7 @@
{
XButtonEvent& xbutton = xEvent->xbutton;
xbutton.type = event->type() == eventNames().mousedownEvent ? ButtonPress : ButtonRelease;
- xbutton.root = QX11Info::appRootWindow();
+ xbutton.root = rootWindowID();
xbutton.subwindow = 0;
xbutton.time = event->timeStamp();
xbutton.x = postZoomPos.x();
@@ -446,7 +508,7 @@
{
XMotionEvent& xmotion = xEvent->xmotion;
xmotion.type = MotionNotify;
- xmotion.root = QX11Info::appRootWindow();
+ xmotion.root = rootWindowID();
xmotion.subwindow = 0;
xmotion.time = event->timeStamp();
xmotion.x = postZoomPos.x();
@@ -462,7 +524,7 @@
{
XCrossingEvent& xcrossing = xEvent->xcrossing;
xcrossing.type = event->type() == eventNames().mouseoverEvent ? EnterNotify : LeaveNotify;
- xcrossing.root = QX11Info::appRootWindow();
+ xcrossing.root = rootWindowID();
xcrossing.subwindow = 0;
xcrossing.time = event->timeStamp();
xcrossing.x = postZoomPos.y();
@@ -571,6 +633,7 @@
return;
m_hasPendingGeometryChange = false;
+#if !HAVE(QT5) // Windowed mode is not supported with Qt5 yet
if (m_isWindowed) {
QWidget* widget = static_cast<QWidget*>(platformPluginWidget());
widget->setGeometry(m_windowRect);
@@ -590,7 +653,9 @@
m_npWindow.x = m_windowRect.x();
m_npWindow.y = m_windowRect.y();
- } else {
+ } else
+#endif
+ {
m_npWindow.x = 0;
m_npWindow.y = 0;
}
@@ -639,8 +704,10 @@
Widget::setParentVisible(visible);
+#if !HAVE(QT5) // Windowed mode is not supported with Qt5 yet.
if (isSelfVisible() && platformPluginWidget())
static_cast<QWidget*>(platformPluginWidget())->setVisible(visible);
+#endif
}
NPError PluginView::handlePostReadFile(Vector<char>& buffer, uint32_t len, const char* buf)
@@ -701,7 +768,7 @@
{
switch (variable) {
case NPNVxDisplay:
- *(void **)value = QX11Info::display();
+ *reinterpret_cast<void**>(value) = x11Display();
*result = NPERR_NO_ERROR;
return true;
@@ -710,9 +777,13 @@
return true;
case NPNVnetscapeWindow: {
- void* w = reinterpret_cast<void*>(value);
- QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
- *((XID *)w) = client ? client->ownerWidget()->window()->winId() : 0;
+ QWebPageClient* client = platformPageClient();
+#if HAVE(QT5)
+ QWindow* window = client ? client->ownerWindow() : 0;
+ *reinterpret_cast<XID*>(value) = window ? window->winId() : 0;
+#else
+ *reinterpret_cast<XID*>(value) = client ? client->ownerWidget()->window()->winId() : 0;
+#endif
*result = NPERR_NO_ERROR;
return true;
}
@@ -739,6 +810,7 @@
}
#endif
+#if !HAVE(QT5) // Windowed mode is not supported with Qt5 yet.
if (m_isWindowed) {
if (platformWidget()) {
// update() will schedule a repaint of the widget so ensure
@@ -749,6 +821,7 @@
}
return;
}
+#endif
invalidateWindowlessPluginRect(rect);
}
@@ -803,47 +876,53 @@
return (Display*)gdk_x11_display_get_xdisplay(gdk_display_get_default());
}
-static void getVisualAndColormap(int depth, Visual **visual, Colormap *colormap)
+static bool getVisualAndColormap(int depth, Visual*& visual, Colormap& colormap, bool forceARGB32)
{
- *visual = 0;
- *colormap = 0;
+ ASSERT(depth == 32 || !forceARGB32);
-#ifndef QT_NO_XRENDER
+ visual = 0;
+ colormap = 0;
+
+#if !HAVE(QT5) && !defined(QT_NO_XRENDER)
static const bool useXRender = qgetenv("QT_X11_NO_XRENDER").isNull(); // Should also check for XRender >= 0.5
#else
static const bool useXRender = false;
#endif
+ if (!useXRender && forceARGB32)
+ return false;
- if (!useXRender && depth == 32)
- return;
-
int nvi;
XVisualInfo templ;
- templ.screen = QX11Info::appScreen();
+ templ.screen = x11Screen();
templ.depth = depth;
templ.c_class = TrueColor;
- XVisualInfo* xvi = XGetVisualInfo(QX11Info::display(), VisualScreenMask | VisualDepthMask | VisualClassMask, &templ, &nvi);
-
+ XVisualInfo* xvi = XGetVisualInfo(x11Display(), VisualScreenMask | VisualDepthMask | VisualClassMask, &templ, &nvi);
+ ASSERT(xvi || forceARGB32);
if (!xvi)
- return;
+ return false;
-#ifndef QT_NO_XRENDER
- if (depth == 32) {
+#if !HAVE(QT5) && !defined(QT_NO_XRENDER)
+ if (forceARGB32) {
for (int idx = 0; idx < nvi; ++idx) {
- XRenderPictFormat* format = XRenderFindVisualFormat(QX11Info::display(), xvi[idx].visual);
+ XRenderPictFormat* format = XRenderFindVisualFormat(x11Display(), xvi[idx].visual);
if (format->type == PictTypeDirect && format->direct.alphaMask) {
- *visual = xvi[idx].visual;
+ visual = xvi[idx].visual;
break;
}
- }
+ }
+ if (!visual)
+ return false;
} else
-#endif // QT_NO_XRENDER
- *visual = xvi[0].visual;
+#endif
+ {
+ visual = xvi[0].visual;
+ }
+ ASSERT(visual);
XFree(xvi);
- if (*visual)
- *colormap = XCreateColormap(QX11Info::display(), QX11Info::appRootWindow(), *visual, AllocNone);
+ colormap = XCreateColormap(x11Display(), rootWindowID(), visual, AllocNone);
+ return true;
}
bool PluginView::platformStart()
@@ -851,6 +930,24 @@
ASSERT(m_isStarted);
ASSERT(m_status == PluginStatusLoadedSuccessfully);
+ if (!x11Environment.display) {
+ Display* display;
+#if HAVE(QT5)
+ display = static_cast<Display*>(QGuiApplication::platformNativeInterface()->nativeResourceForWindow("display", 0));
+#else
+ display = QX11Info::display();
+#endif
+ x11Environment.display = display;
+ x11Environment.screenID = XDefaultScreen(display);
+ x11Environment.displayDepth = XDefaultDepth(display, x11Environment.screenID);
+ x11Environment.rootWindowID = XDefaultRootWindow(display);
+ }
+
+#if HAVE(QT5)
+ // Windowed mode is not supported with Qt5 yet.
+ if (m_isWindowed)
+ return false;
+#else
if (m_plugin->pluginFuncs()->getvalue) {
PluginView::setCurrentPluginView(this);
#if USE(JSC)
@@ -863,7 +960,7 @@
}
if (m_isWindowed) {
- QWebPageClient* client = m_parentFrame->view()->hostWindow()->platformPageClient();
+ QWebPageClient* client = platformPageClient();
if (m_needsXEmbed && client) {
setPlatformWidget(new PluginContainerQt(this, client->ownerWidget()));
// sync our XEmbed container window creation before sending the xid to plugins.
@@ -873,7 +970,9 @@
m_status = PluginStatusCanNotLoadPlugin;
return false;
}
- } else {
+ } else
+#endif // HAVE(QT5)
+ {
setPlatformWidget(0);
m_pluginDisplay = getPluginDisplay();
@@ -893,6 +992,7 @@
NPSetWindowCallbackStruct* wsi = new NPSetWindowCallbackStruct();
wsi->type = 0;
+#if !HAVE(QT5)
if (m_isWindowed) {
const QX11Info* x11Info = &static_cast<QWidget*>(platformPluginWidget())->x11Info();
@@ -905,20 +1005,24 @@
m_npWindow.window = (void*)static_cast<QWidget*>(platformPluginWidget())->winId();
m_npWindow.width = -1;
m_npWindow.height = -1;
- } else {
+ } else
+#endif
+ {
+#if !HAVE(QT5)
const QX11Info* x11Info = &QApplication::desktop()->x11Info();
-
- if (x11Info->depth() == 32 || !m_plugin->quirks().contains(PluginQuirkRequiresDefaultScreenDepth)) {
- getVisualAndColormap(32, &m_visual, &m_colormap);
+ if ((x11Info->depth() == 32 || !m_plugin->quirks().contains(PluginQuirkRequiresDefaultScreenDepth))
+ && getVisualAndColormap(32, m_visual, m_colormap, /* forceARGB32 = */ true))
wsi->depth = 32;
+ else
+#endif
+ {
+ int depth = displayDepth();
+ bool found = getVisualAndColormap(depth, m_visual, m_colormap, /* forceARGB32 = */ false);
+ ASSERT_UNUSED(found, found);
+ wsi->depth = depth;
}
- if (!m_visual) {
- getVisualAndColormap(x11Info->depth(), &m_visual, &m_colormap);
- wsi->depth = x11Info->depth();
- }
-
- wsi->display = x11Info->display();
+ wsi->display = x11Display();
wsi->visual = m_visual;
wsi->colormap = m_colormap;
@@ -946,10 +1050,10 @@
delete platformPluginWidget();
if (m_drawable)
- XFreePixmap(QX11Info::display(), m_drawable);
+ XFreePixmap(x11Display(), m_drawable);
if (m_colormap)
- XFreeColormap(QX11Info::display(), m_colormap);
+ XFreeColormap(x11Display(), m_colormap);
}
#if USE(ACCELERATED_COMPOSITING)
Modified: trunk/Source/WebKit/qt/Api/qwebsettings.cpp (116402 => 116403)
--- trunk/Source/WebKit/qt/Api/qwebsettings.cpp 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Source/WebKit/qt/Api/qwebsettings.cpp 2012-05-08 08:42:37 UTC (rev 116403)
@@ -1174,7 +1174,11 @@
#if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
// All applications can share the common QtWebkit cache file(s).
// Path is not configurable and uses QDesktopServices::CacheLocation by default.
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
+#else
QString cachePath = QDesktopServices::storageLocation(QDesktopServices::CacheLocation);
+#endif
WebCore::makeAllDirectories(cachePath);
QFileInfo info(cachePath);
Modified: trunk/Source/WebKit/qt/ChangeLog (116402 => 116403)
--- trunk/Source/WebKit/qt/ChangeLog 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Source/WebKit/qt/ChangeLog 2012-05-08 08:42:37 UTC (rev 116403)
@@ -1,3 +1,24 @@
+2012-05-08 Balazs Kelemen <[email protected]>
+
+ [Qt] X11 plugins need to be reworked for Qt5+WK1
+ https://bugs.webkit.org/show_bug.cgi?id=80691
+
+ Reviewed by Simon Hausmann.
+
+ * Api/qwebsettings.cpp:
+ (QWebSettings::enablePersistentStorage):
+ Build fix for Qt5.
+ * WebCoreSupport/FrameLoaderClientQt.cpp:
+ (WebCore::FrameLoaderClientQt::createPlugin):
+ Inject the wmode parameter for flash so it will
+ work in windowless, non-transparent mode which
+ is the only one we support currently.
+ * WebCoreSupport/PageClientQt.cpp:
+ (WebCore):
+ (WebCore::QWebPageClient::ownerWindow):
+ Added a getter for the top level window so the PluginView
+ can get it without calling into QtWidgets code.
+
2012-05-06 Gyuyoung Kim <[email protected]>
Convert isPageBoxVisible to use Internals interface.
Modified: trunk/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp (116402 => 116403)
--- trunk/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Source/WebKit/qt/WebCoreSupport/FrameLoaderClientQt.cpp 2012-05-08 08:42:37 UTC (rev 116403)
@@ -1603,9 +1603,14 @@
Vector<String> params = paramNames;
Vector<String> values = paramValues;
if (mimeType == "application/x-shockwave-flash") {
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ const bool shouldInjectWmode = true;
+#else
+ // Inject wmode=opaque when there is no client or the client is not a QWebView.
QWebPageClient* client = m_webFrame->page()->d->client.get();
- const bool isQWebView = client && qobject_cast<QWidget*>(client->pluginParent());
- if (!isQWebView) {
+ const bool shouldInjectWmode = !(client && qobject_cast<QWidget*>(client->pluginParent()));
+#endif
+ if (shouldInjectWmode) {
// Inject wmode=opaque when there is no client or the client is not a QWebView.
size_t wmodeIndex = params.find("wmode");
if (wmodeIndex == WTF::notFound) {
Modified: trunk/Source/WebKit/qt/WebCoreSupport/PageClientQt.cpp (116402 => 116403)
--- trunk/Source/WebKit/qt/WebCoreSupport/PageClientQt.cpp 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Source/WebKit/qt/WebCoreSupport/PageClientQt.cpp 2012-05-08 08:42:37 UTC (rev 116403)
@@ -69,6 +69,20 @@
#include "texmap/TextureMapperLayer.h"
#endif
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+QWindow* QWebPageClient::ownerWindow() const
+{
+ QWidget* widget = ownerWidget();
+ if (!widget)
+ return 0;
+ if (QWindow *window = widget->windowHandle())
+ return window;
+ if (const QWidget *nativeParent = widget->nativeParentWidget())
+ return nativeParent->windowHandle();
+ return 0;
+}
+#endif
+
namespace WebCore {
#if USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER)
Modified: trunk/Tools/ChangeLog (116402 => 116403)
--- trunk/Tools/ChangeLog 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Tools/ChangeLog 2012-05-08 08:42:37 UTC (rev 116403)
@@ -1,3 +1,18 @@
+2012-05-08 Balazs Kelemen <[email protected]>
+
+ [Qt] X11 plugins need to be reworked for Qt5+WK1
+ https://bugs.webkit.org/show_bug.cgi?id=80691
+
+ Reviewed by Simon Hausmann.
+
+ Implement basic windowless plugin support with Qt5.
+
+ * qmake/mkspecs/features/features.prf:
+ Enable NPAPI plugins if X11 libraries are available.
+ * qmake/mkspecs/features/functions.prf:
+ Added a convenience function to determine availability
+ of X11 libraries.
+
2012-05-07 Raphael Kubo da Costa <[email protected]>
[webkitpy] Remove Python 2.5-specific workaround from http_server_base.py.
Modified: trunk/Tools/qmake/mkspecs/features/features.prf (116402 => 116403)
--- trunk/Tools/qmake/mkspecs/features/features.prf 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Tools/qmake/mkspecs/features/features.prf 2012-05-08 08:42:37 UTC (rev 116403)
@@ -80,8 +80,11 @@
# Nescape plugins support (NPAPI)
!contains(DEFINES, ENABLE_NETSCAPE_PLUGIN_API=.) {
- unix:haveQt(4)|win32-*:!embedded:!wince*: {
+ haveQt(5):xlibAvailable() {
DEFINES += ENABLE_NETSCAPE_PLUGIN_API=1
+ CONFIG += plugin_backend_xlib
+ } else: unix|win32-*:!embedded:!wince* {
+ DEFINES += ENABLE_NETSCAPE_PLUGIN_API=1
}
}
Modified: trunk/Tools/qmake/mkspecs/features/functions.prf (116402 => 116403)
--- trunk/Tools/qmake/mkspecs/features/functions.prf 2012-05-08 08:31:29 UTC (rev 116402)
+++ trunk/Tools/qmake/mkspecs/features/functions.prf 2012-05-08 08:42:37 UTC (rev 116403)
@@ -323,3 +323,19 @@
return(true)
}
+
+defineTest(xlibAvailable) {
+ haveQt(5) {
+ contains(QT_CONFIG, xcb-xlib) {
+ return(true)
+ } else {
+ return(false)
+ }
+ } else {
+ unix:!mac:!embedded {
+ return(true)
+ } else {
+ return(false)
+ }
+ }
+}
_______________________________________________ webkit-changes mailing list [email protected] http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes
