Diff
Modified: trunk/ChangeLog (240140 => 240141)
--- trunk/ChangeLog 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/ChangeLog 2019-01-18 13:07:38 UTC (rev 240141)
@@ -1,3 +1,12 @@
+2019-01-18 Philippe Normand <[email protected]>
+
+ [WPE] Add Qt extension
+ https://bugs.webkit.org/show_bug.cgi?id=191464
+
+ Reviewed by Carlos Garcia Campos.
+
+ * Source/cmake/OptionsWPE.cmake: Add ENABLE_WPE_QT_API CMake option. Disabled by default.
+
2019-01-17 Truitt Savell <[email protected]>
Unreviewed, rolling out r240124.
Modified: trunk/Source/WebKit/ChangeLog (240140 => 240141)
--- trunk/Source/WebKit/ChangeLog 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Source/WebKit/ChangeLog 2019-01-18 13:07:38 UTC (rev 240141)
@@ -1,3 +1,94 @@
+2019-01-18 Philippe Normand <[email protected]>
+
+ [WPE] Add Qt extension
+ https://bugs.webkit.org/show_bug.cgi?id=191464
+
+ Reviewed by Carlos Garcia Campos.
+
+ This new extension is a QML plugin embedding a WPE ViewBackend
+ implementation. It provides a public API very similar to Qt's
+ WebView module. It comes with a simple mini-browser implemented in
+ QML.
+
+ QtWPE is known to work with the Wayland-EGL (in GNOME and Weston
+ compositors) and EGLFS QPAs.
+
+ * PlatformWPE.cmake:
+ * UIProcess/API/wpe/qt/WPEQmlExtensionPlugin.cpp: Added.
+ (WPEQmlExtensionPlugin::registerTypes):
+ * UIProcess/API/wpe/qt/WPEQmlExtensionPlugin.h: Added.
+ * UIProcess/API/wpe/qt/WPEQtView.cpp: Added.
+ (WPEQtView::WPEQtView):
+ (WPEQtView::~WPEQtView):
+ (WPEQtView::geometryChanged):
+ (WPEQtView::configureWindow):
+ (WPEQtView::createOffscreen):
+ (WPEQtView::backendCreated):
+ (WPEQtView::notifyUrlChangedCallback):
+ (WPEQtView::notifyTitleChangedCallback):
+ (WPEQtView::notifyLoadProgressCallback):
+ (WPEQtView::notifyLoadChangedCallback):
+ (WPEQtView::notifyLoadFailedCallback):
+ (WPEQtView::updatePaintNode):
+ (WPEQtView::url const):
+ (WPEQtView::setUrl):
+ (WPEQtView::loadProgress const):
+ (WPEQtView::title const):
+ (WPEQtView::canGoBack const):
+ (WPEQtView::isLoading const):
+ (WPEQtView::canGoForward const):
+ (WPEQtView::goBack):
+ (WPEQtView::goForward):
+ (WPEQtView::reload):
+ (WPEQtView::stop):
+ (WPEQtView::loadHtml):
+ (WPEQtView::jsAsyncReadyCallback):
+ (WPEQtView::handleJsResult):
+ (WPEQtView::runJavaScript):
+ (WPEQtView::mousePressEvent):
+ (WPEQtView::mouseReleaseEvent):
+ (WPEQtView::hoverEnterEvent):
+ (WPEQtView::hoverLeaveEvent):
+ (WPEQtView::hoverMoveEvent):
+ (WPEQtView::wheelEvent):
+ (WPEQtView::keyPressEvent):
+ (WPEQtView::keyReleaseEvent):
+ (WPEQtView::touchEvent):
+ * UIProcess/API/wpe/qt/WPEQtView.h: Added.
+ * UIProcess/API/wpe/qt/WPEQtViewBackend.cpp: Added.
+ (configureCallback):
+ (WPEQtViewBackend::WPEQtViewBackend):
+ (WPEQtViewBackend::~WPEQtViewBackend):
+ (WPEQtViewBackend::configureGlibEglDisplay):
+ (WPEQtViewBackend::configureEglDisplay):
+ (WPEQtViewBackend::initialize):
+ (WPEQtViewBackend::backend const):
+ (WPEQtViewBackend::resize):
+ (WPEQtViewBackend::getTexture):
+ (WPEQtViewBackend::initSurface):
+ (WPEQtViewBackend::displayImage):
+ (WPEQtViewBackend::modifiers const):
+ (WPEQtViewBackend::dispatchHoverEnterEvent):
+ (WPEQtViewBackend::dispatchHoverLeaveEvent):
+ (WPEQtViewBackend::dispatchHoverMoveEvent):
+ (WPEQtViewBackend::dispatchMousePressEvent):
+ (WPEQtViewBackend::dispatchMouseReleaseEvent):
+ (WPEQtViewBackend::dispatchWheelEvent):
+ (WPEQtViewBackend::dispatchKeyEvent):
+ (WPEQtViewBackend::dispatchTouchEvent):
+ * UIProcess/API/wpe/qt/WPEQtViewBackend.h: Added.
+ * UIProcess/API/wpe/qt/WPEQtViewLoadRequest.cpp: Added.
+ (WPEQtViewLoadRequest::WPEQtViewLoadRequest):
+ (WPEQtViewLoadRequest::~WPEQtViewLoadRequest):
+ (WPEQtViewLoadRequest::url const):
+ (WPEQtViewLoadRequest::status const):
+ (WPEQtViewLoadRequest::errorString const):
+ * UIProcess/API/wpe/qt/WPEQtViewLoadRequest.h: Added.
+ * UIProcess/API/wpe/qt/WPEQtViewLoadRequestPrivate.h: Added.
+ (WPEQtViewLoadRequestPrivate::WPEQtViewLoadRequestPrivate):
+ (WPEQtViewLoadRequestPrivate::~WPEQtViewLoadRequestPrivate):
+ * UIProcess/API/wpe/qt/qmldir: Added.
+
2019-01-17 Wenson Hsieh <[email protected]>
[iOS] Content offset jumps erratically when autoscrolling near scroll view content inset areas
Modified: trunk/Source/WebKit/PlatformWPE.cmake (240140 => 240141)
--- trunk/Source/WebKit/PlatformWPE.cmake 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Source/WebKit/PlatformWPE.cmake 2019-01-18 13:07:38 UTC (rev 240141)
@@ -1,4 +1,5 @@
include(InspectorGResources.cmake)
+include(GNUInstallDirs)
set(WebKit_OUTPUT_NAME WPEWebKit-${WPE_API_VERSION})
set(WebKit_WebProcess_OUTPUT_NAME WPEWebProcess)
@@ -316,22 +317,6 @@
target_include_directories(WPEInjectedBundle PRIVATE ${WebKit_INCLUDE_DIRECTORIES})
target_include_directories(WPEInjectedBundle SYSTEM PRIVATE ${WebKit_SYSTEM_INCLUDE_DIRECTORIES})
-install(TARGETS WPEInjectedBundle
- DESTINATION "${LIB_INSTALL_DIR}/wpe-webkit-${WPE_API_VERSION}/injected-bundle"
-)
-
-install(FILES "${CMAKE_BINARY_DIR}/wpe-webkit-${WPE_API_VERSION}.pc"
- "${CMAKE_BINARY_DIR}/wpe-web-extension-${WPE_API_VERSION}.pc"
- DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
- COMPONENT "Development"
-)
-
-install(FILES ${WPE_API_INSTALLED_HEADERS}
- ${WPE_WEB_EXTENSION_API_INSTALLED_HEADERS}
- DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/wpe-webkit-${WPE_API_VERSION}/wpe"
- COMPONENT "Development"
-)
-
file(WRITE ${CMAKE_BINARY_DIR}/gtkdoc-wpe.cfg
"[wpe-${WPE_API_VERSION}]\n"
"pkgconfig_file=${WPE_PKGCONFIG_FILE}\n"
@@ -370,3 +355,67 @@
"headers=${WPE_WEB_EXTENSION_API_INSTALLED_HEADERS}\n"
"main_sgml_file=wpe-webextensions-docs.sgml\n"
)
+
+if (ENABLE_WPE_QT_API)
+ set(qtwpe_SOURCES
+ ${WEBKIT_DIR}/UIProcess/API/wpe/qt/WPEQtViewBackend.cpp
+ ${WEBKIT_DIR}/UIProcess/API/wpe/qt/WPEQmlExtensionPlugin.cpp
+ ${WEBKIT_DIR}/UIProcess/API/wpe/qt/WPEQtView.cpp
+ ${WEBKIT_DIR}/UIProcess/API/wpe/qt/WPEQtViewLoadRequest.cpp
+ )
+
+ set(qtwpe_LIBRARIES
+ Qt5::Core Qt5::Quick
+ WebKit
+ ${LIBEPOXY_LIBRARIES}
+ ${WPE_BACKEND_FDO_LIBRARIES}
+ )
+
+ set(qtwpe_INCLUDE_DIRECTORIES
+ ${Qt5_INCLUDE_DIRS}
+ ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
+ ${LIBEPOXY_INCLUDE_DIRS}
+ ${WPE_BACKEND_FDO_INCLUDE_DIRS}
+ )
+
+ list(APPEND WPE_API_INSTALLED_HEADERS
+ ${WEBKIT_DIR}/UIProcess/API/wpe/qt/WPEQtView.h
+ ${WEBKIT_DIR}/UIProcess/API/wpe/qt/WPEQtViewLoadRequest.h
+ )
+
+ add_library(qtwpe SHARED ${qtwpe_SOURCES})
+ set_target_properties(qtwpe PROPERTIES
+ OUTPUT_NAME qtwpe
+ AUTOMOC ON
+ CXX_STANDARD 14
+ )
+ target_compile_definitions(qtwpe PUBLIC QT_NO_KEYWORDS=1)
+ target_link_libraries(qtwpe ${qtwpe_LIBRARIES})
+ target_include_directories(qtwpe SYSTEM PRIVATE ${qtwpe_INCLUDE_DIRECTORIES})
+ install(TARGETS qtwpe DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/qml/org/wpewebkit/qtwpe/")
+ install(FILES ${WEBKIT_DIR}/UIProcess/API/wpe/qt/qmldir DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}/qml/org/wpewebkit/qtwpe/")
+
+ file(MAKE_DIRECTORY ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/qml/org/wpewebkit/qtwpe)
+ add_custom_command(TARGET qtwpe POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libqtwpe.so
+ ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/qml/org/wpewebkit/qtwpe)
+ add_custom_command(TARGET qtwpe POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy
+ ${WEBKIT_DIR}/UIProcess/API/wpe/qt/qmldir
+ ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/qml/org/wpewebkit/qtwpe)
+endif ()
+
+install(TARGETS WPEInjectedBundle
+ DESTINATION "${LIB_INSTALL_DIR}/wpe-webkit-${WPE_API_VERSION}/injected-bundle"
+)
+
+install(FILES "${CMAKE_BINARY_DIR}/wpe-webkit-${WPE_API_VERSION}.pc"
+ "${CMAKE_BINARY_DIR}/wpe-web-extension-${WPE_API_VERSION}.pc"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
+ COMPONENT "Development"
+)
+
+install(FILES ${WPE_API_INSTALLED_HEADERS}
+ ${WPE_WEB_EXTENSION_API_INSTALLED_HEADERS}
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/wpe-webkit-${WPE_API_VERSION}/wpe"
+ COMPONENT "Development"
+)
Added: trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQmlExtensionPlugin.cpp (0 => 240141)
--- trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQmlExtensionPlugin.cpp (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQmlExtensionPlugin.cpp 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L
+ * Copyright (C) 2018, 2019 Zodiac Inflight Innovations
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WPEQmlExtensionPlugin.h"
+
+#include "WPEQtView.h"
+#include "WPEQtViewLoadRequest.h"
+#include <qqml.h>
+
+void WPEQmlExtensionPlugin::registerTypes(const char* uri)
+{
+ // @uri org.wpewebkit.qtwpe
+ qmlRegisterType<WPEQtView>(uri, 1, 0, "WPEView");
+
+ const QString& msg = QObject::tr("Cannot create separate instance of WPEQtViewLoadRequest");
+ qmlRegisterUncreatableType<WPEQtViewLoadRequest>(uri, 1, 0, "WPEViewLoadRequest", msg);
+}
Added: trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQmlExtensionPlugin.h (0 => 240141)
--- trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQmlExtensionPlugin.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQmlExtensionPlugin.h 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L
+ * Copyright (C) 2018, 2019 Zodiac Inflight Innovations
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include <QQmlExtensionPlugin>
+
+class WPEQmlExtensionPlugin : public QQmlExtensionPlugin {
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
+
+public:
+ void registerTypes(const char* uri);
+};
Added: trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtView.cpp (0 => 240141)
--- trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtView.cpp (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtView.cpp 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,499 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L
+ * Copyright (C) 2018, 2019 Zodiac Inflight Innovations
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WPEQtView.h"
+
+#include "WPEQtViewLoadRequest.h"
+#include "WPEQtViewLoadRequestPrivate.h"
+#include <QGuiApplication>
+#include <QQuickWindow>
+#include <QSGSimpleTextureNode>
+#include <QScreen>
+#include <QtPlatformHeaders/QEGLNativeContext>
+#include <qpa/qplatformnativeinterface.h>
+#include <wtf/glib/GUniquePtr.h>
+
+/*!
+ \qmltype WPEView
+ \inqmlmodule org.wpewebkit.qtwpe
+ \brief A component for displaying web content.
+
+ WPEView is a component for displaying web content which is implemented using native
+ APIs on the platforms where this is available, thus it does not necessarily require
+ including a full web browser stack as part of the application.
+
+ WPEView provides an API compatible with Qt's QtWebView component. However
+ WPEView is limited to Linux platforms supporting EGL KHR extensions. WPEView
+ was successfully tested with the EGLFS and Wayland-EGL QPAs.
+*/
+WPEQtView::WPEQtView(QQuickItem* parent)
+ : QQuickItem(parent)
+{
+ connect(this, &QQuickItem::windowChanged, this, &WPEQtView::configureWindow);
+ setFlag(ItemHasContents, true);
+ setAcceptedMouseButtons(Qt::AllButtons);
+ setAcceptHoverEvents(true);
+ setAcceptTouchEvents(true);
+}
+
+WPEQtView::~WPEQtView()
+{
+ g_signal_handlers_disconnect_by_func(m_webView.get(), reinterpret_cast<gpointer>(notifyUrlChangedCallback), this);
+ g_signal_handlers_disconnect_by_func(m_webView.get(), reinterpret_cast<gpointer>(notifyTitleChangedCallback), this);
+ g_signal_handlers_disconnect_by_func(m_webView.get(), reinterpret_cast<gpointer>(notifyLoadChangedCallback), this);
+ g_signal_handlers_disconnect_by_func(m_webView.get(), reinterpret_cast<gpointer>(notifyLoadFailedCallback), this);
+ g_signal_handlers_disconnect_by_func(m_webView.get(), reinterpret_cast<gpointer>(notifyLoadProgressCallback), this);
+}
+
+void WPEQtView::geometryChanged(const QRectF& newGeometry, const QRectF&)
+{
+ m_size = newGeometry.size();
+ if (m_backend)
+ m_backend->resize(newGeometry.size());
+}
+
+void WPEQtView::configureWindow()
+{
+ auto* win = window();
+ if (!win)
+ return;
+
+ win->setSurfaceType(QWindow::OpenGLSurface);
+ connect(win, &QQuickWindow::sceneGraphInitialized, this, &WPEQtView::createWebView);
+}
+
+void WPEQtView::createWebView()
+{
+ if (m_backend)
+ return;
+
+ auto display = static_cast<EGLDisplay>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("egldisplay"));
+ auto* context = window()->openglContext();
+ std::unique_ptr<WPEQtViewBackend> backend = WPEQtViewBackend::create(m_size, context, display, QPointer<WPEQtView>(this));
+ RELEASE_ASSERT_WITH_MESSAGE(backend, "EGL initialization failed");
+ if (!backend)
+ return;
+
+ m_backend = backend.get();
+ auto settings = adoptGRef(webkit_settings_new_with_settings("enable-developer-extras", TRUE,
+ "enable-webgl", TRUE, "enable-mediasource", TRUE, nullptr));
+ m_webView = adoptGRef(WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW,
+ "backend", webkit_web_view_backend_new(m_backend->backend(), [](gpointer data) {
+ delete static_cast<WPEQtViewBackend*>(data);
+ }, backend.release()),
+ "settings", settings.get(), nullptr)));
+
+ g_signal_connect_swapped(m_webView.get(), "notify::uri", G_CALLBACK(notifyUrlChangedCallback), this);
+ g_signal_connect_swapped(m_webView.get(), "notify::title", G_CALLBACK(notifyTitleChangedCallback), this);
+ g_signal_connect_swapped(m_webView.get(), "notify::estimated-load-progress", G_CALLBACK(notifyLoadProgressCallback), this);
+ g_signal_connect(m_webView.get(), "load-changed", G_CALLBACK(notifyLoadChangedCallback), this);
+ g_signal_connect(m_webView.get(), "load-failed", G_CALLBACK(notifyLoadFailedCallback), this);
+
+ if (!m_url.isEmpty())
+ webkit_web_view_load_uri(m_webView.get(), m_url.toString().toUtf8().constData());
+ else if (!m_html.isEmpty())
+ webkit_web_view_load_html(m_webView.get(), m_html.toUtf8().constData(), m_baseUrl.toString().toUtf8().constData());
+
+ Q_EMIT webViewCreated();
+}
+
+void WPEQtView::notifyUrlChangedCallback(WPEQtView* view)
+{
+ Q_EMIT view->urlChanged();
+}
+
+void WPEQtView::notifyTitleChangedCallback(WPEQtView* view)
+{
+ Q_EMIT view->titleChanged();
+}
+
+void WPEQtView::notifyLoadProgressCallback(WPEQtView* view)
+{
+ Q_EMIT view->loadProgressChanged();
+}
+
+void WPEQtView::notifyLoadChangedCallback(WebKitWebView*, WebKitLoadEvent event, WPEQtView* view)
+{
+ bool statusSet = false;
+ WPEQtView::LoadStatus loadStatus;
+ switch (event) {
+ case WEBKIT_LOAD_STARTED:
+ loadStatus = WPEQtView::LoadStatus::LoadStartedStatus;
+ statusSet = true;
+ break;
+ case WEBKIT_LOAD_FINISHED:
+ loadStatus = WPEQtView::LoadStatus::LoadSucceededStatus;
+ statusSet = !view->errorOccured();
+ view->setErrorOccured(false);
+ break;
+ default:
+ break;
+ }
+
+ if (statusSet) {
+ WPEQtViewLoadRequestPrivate loadRequestPrivate(view->url(), loadStatus, "");
+ std::unique_ptr<WPEQtViewLoadRequest> loadRequest = std::make_unique<WPEQtViewLoadRequest>(loadRequestPrivate);
+ Q_EMIT view->loadingChanged(loadRequest.get());
+ }
+}
+
+void WPEQtView::notifyLoadFailedCallback(WebKitWebView*, WebKitLoadEvent, const gchar* failingURI, GError* error, WPEQtView* view)
+{
+ view->setErrorOccured(true);
+
+ WPEQtView::LoadStatus loadStatus;
+ if (g_error_matches(error, WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED))
+ loadStatus = WPEQtView::LoadStatus::LoadStoppedStatus;
+ else
+ loadStatus = WPEQtView::LoadStatus::LoadFailedStatus;
+
+ WPEQtViewLoadRequestPrivate loadRequestPrivate(QUrl(QString(failingURI)), loadStatus, error->message);
+ std::unique_ptr<WPEQtViewLoadRequest> loadRequest = std::make_unique<WPEQtViewLoadRequest>(loadRequestPrivate);
+ Q_EMIT view->loadingChanged(loadRequest.get());
+}
+
+QSGNode* WPEQtView::updatePaintNode(QSGNode* node, UpdatePaintNodeData*)
+{
+ if (!m_webView || !m_backend)
+ return node;
+
+ auto* textureNode = static_cast<QSGSimpleTextureNode*>(node);
+ if (!textureNode)
+ textureNode = new QSGSimpleTextureNode();
+
+ GLuint textureId = m_backend->texture(window()->openglContext());
+ if (!textureId)
+ return node;
+
+ textureNode->setTexture(window()->createTextureFromId(textureId, m_size.toSize(), QQuickWindow::TextureHasAlphaChannel));
+ textureNode->setRect(boundingRect());
+ return textureNode;
+}
+
+QUrl WPEQtView::url() const
+{
+ if (!m_webView)
+ return m_url;
+
+ const gchar* uri = webkit_web_view_get_uri(m_webView.get());
+ return uri ? QUrl(QString(uri)) : m_url;
+}
+
+/*!
+ \qmlproperty url WPEView::url
+
+ The URL of currently loaded web page. Changing this will trigger
+ loading new content.
+
+ The URL is used as-is. URLs that originate from user input should
+ be parsed with QUrl::fromUserInput().
+
+ \note The WPEView does not support loading content through the Qt Resource system.
+*/
+void WPEQtView::setUrl(const QUrl& url)
+{
+ if (url == m_url)
+ return;
+
+ m_errorOccured = false;
+ m_url = url;
+ if (m_webView)
+ webkit_web_view_load_uri(m_webView.get(), m_url.toString().toUtf8().constData());
+}
+
+/*!
+ \qmlproperty int WPEView::loadProgress
+ \readonly
+
+ The current load progress of the web content, represented as
+ an integer between 0 and 100.
+*/
+int WPEQtView::loadProgress() const
+{
+ if (!m_webView)
+ return 0;
+
+ return webkit_web_view_get_estimated_load_progress(m_webView.get()) * 100;
+}
+
+/*!
+ \qmlproperty string WPEView::title
+ \readonly
+
+ The title of the currently loaded web page.
+*/
+QString WPEQtView::title() const
+{
+ if (!m_webView)
+ return "";
+
+ return webkit_web_view_get_title(m_webView.get());
+}
+
+/*!
+ \qmlproperty bool WPEView::canGoBack
+ \readonly
+
+ Holds \c true if it's currently possible to navigate back in the web history.
+*/
+bool WPEQtView::canGoBack() const
+{
+ if (!m_webView)
+ return false;
+
+ return webkit_web_view_can_go_back(m_webView.get());
+}
+
+/*!
+ \qmlproperty bool WPEView::loading
+ \readonly
+
+ Holds \c true if the WPEView is currently in the process of loading
+ new content, \c false otherwise.
+
+ \sa loadingChanged()
+*/
+
+/*!
+ \qmlsignal WPEView::loadingChanged(WPEViewLoadRequest loadRequest)
+
+ This signal is emitted when the state of loading the web content changes.
+ By handling this signal it's possible, for example, to react to page load
+ errors.
+
+ The \a loadRequest parameter holds the \e url and \e status of the request,
+ as well as an \e errorString containing an error message for a failed
+ request.
+
+ \sa WPEViewLoadRequest
+*/
+bool WPEQtView::isLoading() const
+{
+ if (!m_webView)
+ return false;
+
+ return webkit_web_view_is_loading(m_webView.get());
+}
+
+/*!
+ \qmlproperty bool WPEView::canGoForward
+ \readonly
+
+ Holds \c true if it's currently possible to navigate forward in the web history.
+*/
+bool WPEQtView::canGoForward() const
+{
+ if (!m_webView)
+ return false;
+
+ return webkit_web_view_can_go_forward(m_webView.get());
+}
+
+/*!
+ \qmlmethod void WPEView::goBack()
+
+ Navigates back in the web history.
+*/
+void WPEQtView::goBack()
+{
+ if (m_webView)
+ webkit_web_view_go_back(m_webView.get());
+}
+
+/*!
+ \qmlmethod void WPEView::goForward()
+
+ Navigates forward in the web history.
+*/
+void WPEQtView::goForward()
+{
+ if (m_webView)
+ webkit_web_view_go_forward(m_webView.get());
+}
+
+/*!
+ \qmlmethod void WPEView::reload()
+
+ Reloads the current \l url.
+*/
+void WPEQtView::reload()
+{
+ if (m_webView)
+ webkit_web_view_reload(m_webView.get());
+}
+
+/*!
+ \qmlmethod void WPEView::stop()
+
+ Stops loading the current \l url.
+*/
+void WPEQtView::stop()
+{
+ if (m_webView)
+ webkit_web_view_stop_loading(m_webView.get());
+}
+
+/*!
+ \qmlmethod void WPEView::loadHtml(string html, url baseUrl)
+
+ Loads the specified \a html content to the web view.
+
+ This method offers a lower-level alternative to the \l url property,
+ which references HTML pages via URL.
+
+ External objects such as stylesheets or images referenced in the HTML
+ document should be located relative to \a baseUrl. For example, if \a html
+ is retrieved from \c http://www.example.com/documents/overview.html, which
+ is the base URL, then an image referenced with the relative url, \c diagram.png,
+ should be at \c{http://www.example.com/documents/diagram.png}.
+
+ \note The WPEView does not support loading content through the Qt Resource system.
+
+ \sa url
+*/
+void WPEQtView::loadHtml(const QString& html, const QUrl& baseUrl)
+{
+ m_html = html;
+ m_baseUrl = baseUrl;
+ m_errorOccured = false;
+
+ if (m_webView)
+ webkit_web_view_load_html(m_webView.get(), html.toUtf8().constData(), baseUrl.toString().toUtf8().constData());
+}
+
+struct _javascript_CallbackData {
+ _javascript_CallbackData(QJSValue cb, QPointer<WPEQtView> obj)
+ : callback(cb)
+ , object(obj) { }
+
+ QJSValue callback;
+ QPointer<WPEQtView> object;
+};
+
+static void jsAsyncReadyCallback(GObject* object, GAsyncResult* result, gpointer userData)
+{
+ GUniqueOutPtr<GError> error;
+ std::unique_ptr<_javascript_CallbackData> data(reinterpret_cast<_javascript_CallbackData*>(userData));
+ WebKitJavascriptResult* jsResult = webkit_web_view_run_javascript_finish(WEBKIT_WEB_VIEW(object), result, &error.outPtr());
+ if (!jsResult) {
+ qWarning("Error running _javascript_: %s", error->message);
+ return;
+ }
+
+ if (data->object.data()) {
+ QQmlEngine* engine = qmlEngine(data->object.data());
+ if (!engine) {
+ qWarning("No _javascript_ engine, unable to handle _javascript_ callback!");
+ webkit_javascript_result_unref(jsResult);
+ return;
+ }
+
+ QJSValueList args;
+ JSCValue* value = webkit_javascript_result_get_js_value(jsResult);
+ QVariant variant;
+ // FIXME: Handle more value types?
+ if (jsc_value_is_string(value)) {
+ GUniquePtr<gchar> strValue(jsc_value_to_string(value));
+ JSCContext* context = jsc_value_get_context(value);
+ JSCException* exception = jsc_context_get_exception(context);
+ if (exception) {
+ qWarning("Error running _javascript_: %s", jsc_exception_get_message(exception));
+ jsc_context_clear_exception(context);
+ } else
+ variant.setValue(QString(g_strdup(strValue.get())));
+ }
+ args.append(engine->toScriptValue(variant));
+ data->callback.call(args);
+ }
+ webkit_javascript_result_unref(jsResult);
+}
+
+/*!
+ \qmlmethod void WPEView::runJavaScript(string script, variant callback)
+
+ Runs the specified _javascript_.
+ In case a \a callback function is provided, it will be invoked after the \a script
+ finished running.
+
+ \badcode
+ runJavaScript("document.title", function(result) { console.log(result); });
+ \endcode
+*/
+void WPEQtView::runJavaScript(const QString& script, const QJSValue& callback)
+{
+ std::unique_ptr<_javascript_CallbackData> data = "" QPointer<WPEQtView>(this));
+ webkit_web_view_run_javascript(m_webView.get(), script.toUtf8().constData(), nullptr, jsAsyncReadyCallback, data.release());
+}
+
+void WPEQtView::mousePressEvent(QMouseEvent* event)
+{
+ forceActiveFocus();
+ if (m_backend)
+ m_backend->dispatchMousePressEvent(event);
+}
+
+void WPEQtView::mouseReleaseEvent(QMouseEvent* event)
+{
+ if (m_backend)
+ m_backend->dispatchMouseReleaseEvent(event);
+}
+
+void WPEQtView::hoverEnterEvent(QHoverEvent* event)
+{
+ if (m_backend)
+ m_backend->dispatchHoverEnterEvent(event);
+}
+
+void WPEQtView::hoverLeaveEvent(QHoverEvent* event)
+{
+ if (m_backend)
+ m_backend->dispatchHoverLeaveEvent(event);
+}
+
+void WPEQtView::hoverMoveEvent(QHoverEvent* event)
+{
+ if (m_backend)
+ m_backend->dispatchHoverMoveEvent(event);
+}
+
+void WPEQtView::wheelEvent(QWheelEvent* event)
+{
+ if (m_backend)
+ m_backend->dispatchWheelEvent(event);
+}
+
+void WPEQtView::keyPressEvent(QKeyEvent* event)
+{
+ if (m_backend)
+ m_backend->dispatchKeyEvent(event, true);
+}
+
+void WPEQtView::keyReleaseEvent(QKeyEvent* event)
+{
+ if (m_backend)
+ m_backend->dispatchKeyEvent(event, false);
+}
+
+void WPEQtView::touchEvent(QTouchEvent* event)
+{
+ if (m_backend)
+ m_backend->dispatchTouchEvent(event);
+}
Added: trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtView.h (0 => 240141)
--- trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtView.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtView.h 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L
+ * Copyright (C) 2018, 2019 Zodiac Inflight Innovations
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "config.h"
+
+#include "WPEQtViewBackend.h"
+#include <QQmlEngine>
+#include <QQuickItem>
+#include <QUrl>
+#include <memory>
+#include <wpe/webkit.h>
+#include <wtf/glib/GRefPtr.h>
+
+class WPEQtViewLoadRequest;
+
+class WPEQtView : public QQuickItem {
+ Q_OBJECT
+ Q_DISABLE_COPY(WPEQtView)
+ Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged)
+ Q_PROPERTY(bool loading READ isLoading NOTIFY loadingChanged)
+ Q_PROPERTY(int loadProgress READ loadProgress NOTIFY loadProgressChanged)
+ Q_PROPERTY(QString title READ title NOTIFY titleChanged)
+ Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY loadingChanged)
+ Q_PROPERTY(bool canGoForward READ canGoForward NOTIFY loadingChanged)
+ Q_ENUMS(LoadStatus)
+
+public:
+ enum LoadStatus {
+ LoadStartedStatus,
+ LoadStoppedStatus,
+ LoadSucceededStatus,
+ LoadFailedStatus
+ };
+
+ WPEQtView(QQuickItem* parent = nullptr);
+ ~WPEQtView();
+ QSGNode* updatePaintNode(QSGNode*, UpdatePaintNodeData*) final;
+
+ void triggerUpdate() { QMetaObject::invokeMethod(this, "update"); };
+
+ QUrl url() const;
+ void setUrl(const QUrl&);
+ int loadProgress() const;
+ QString title() const;
+ bool canGoBack() const;
+ bool isLoading() const;
+ bool canGoForward() const;
+
+public Q_SLOTS:
+ void goBack();
+ void goForward();
+ void reload();
+ void stop();
+ void loadHtml(const QString& html, const QUrl& baseUrl = QUrl());
+ void runJavaScript(const QString& script, const QJSValue& callback = QJSValue());
+
+Q_SIGNALS:
+ void webViewCreated();
+ void urlChanged();
+ void titleChanged();
+ void loadingChanged(WPEQtViewLoadRequest*);
+ void loadProgressChanged();
+
+protected:
+ bool errorOccured() const { return m_errorOccured; };
+ void setErrorOccured(bool errorOccured) { m_errorOccured = errorOccured; };
+
+ void geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) override;
+
+ void hoverEnterEvent(QHoverEvent*) override;
+ void hoverLeaveEvent(QHoverEvent*) override;
+ void hoverMoveEvent(QHoverEvent*) override;
+
+ void mousePressEvent(QMouseEvent*) override;
+ void mouseReleaseEvent(QMouseEvent*) override;
+ void wheelEvent(QWheelEvent*) override;
+
+ void keyPressEvent(QKeyEvent*) override;
+ void keyReleaseEvent(QKeyEvent*) override;
+
+ void touchEvent(QTouchEvent*) override;
+
+private Q_SLOTS:
+ void configureWindow();
+ void createWebView();
+
+private:
+ static void notifyUrlChangedCallback(WPEQtView*);
+ static void notifyTitleChangedCallback(WPEQtView*);
+ static void notifyLoadProgressCallback(WPEQtView*);
+ static void notifyLoadChangedCallback(WebKitWebView*, WebKitLoadEvent, WPEQtView*);
+ static void notifyLoadFailedCallback(WebKitWebView*, WebKitLoadEvent, const gchar* failingURI, GError*, WPEQtView*);
+
+ GRefPtr<WebKitWebView> m_webView;
+ QUrl m_url;
+ QString m_html;
+ QUrl m_baseUrl;
+ QSizeF m_size;
+ WPEQtViewBackend* m_backend;
+ bool m_errorOccured { false };
+};
Added: trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewBackend.cpp (0 => 240141)
--- trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewBackend.cpp (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewBackend.cpp 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L
+ * Copyright (C) 2018, 2019 Zodiac Inflight Innovations
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WPEQtViewBackend.h"
+
+#include "WPEQtView.h"
+#include <QGuiApplication>
+#include <QOpenGLFunctions>
+
+static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC imageTargetTexture2DOES;
+
+std::unique_ptr<WPEQtViewBackend> WPEQtViewBackend::create(const QSizeF& size, QPointer<QOpenGLContext> context, EGLDisplay eglDisplay, QPointer<WPEQtView> view)
+{
+ if (!context || !view)
+ return nullptr;
+
+ if (eglDisplay == EGL_NO_DISPLAY)
+ return nullptr;
+
+ eglInitialize(eglDisplay, nullptr, nullptr);
+
+ if (!eglBindAPI(EGL_OPENGL_ES_API))
+ return nullptr;
+
+ static const EGLint configAttributes[13] = {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RED_SIZE, 1,
+ EGL_GREEN_SIZE, 1,
+ EGL_BLUE_SIZE, 1,
+ EGL_ALPHA_SIZE, 1,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
+ EGL_NONE
+ };
+
+ EGLint count = 0;
+ if (!eglGetConfigs(eglDisplay, nullptr, 0, &count) || count < 1)
+ return nullptr;
+
+ EGLConfig eglConfig;
+ EGLint matched = 0;
+ EGLContext eglContext = nullptr;
+ if (eglChooseConfig(eglDisplay, configAttributes, &eglConfig, 1, &matched) && !!matched) {
+ static const EGLint contextAttributes[3] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+ eglContext = eglCreateContext(eglDisplay, eglConfig, nullptr, contextAttributes);
+ }
+
+ if (!eglContext)
+ return nullptr;
+
+ return std::make_unique<WPEQtViewBackend>(size, eglDisplay, eglContext, context, view);
+}
+
+WPEQtViewBackend::WPEQtViewBackend(const QSizeF& size, EGLDisplay display, EGLContext eglContext, QPointer<QOpenGLContext> context, QPointer<WPEQtView> view)
+ : m_eglDisplay(display)
+ , m_eglContext(eglContext)
+ , m_view(view)
+ , m_size(size)
+{
+#if defined(WPE_BACKEND_CHECK_VERSION) && WPE_BACKEND_CHECK_VERSION(0, 2, 0)
+ wpe_loader_init("libWPEBackend-fdo-0.1.so");
+#endif
+
+ wpe_fdo_initialize_for_egl_display(m_eglDisplay);
+
+ imageTargetTexture2DOES = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
+
+ static const char* vertexShaderSource =
+ "attribute vec2 pos;\n"
+ "attribute vec2 texture;\n"
+ "varying vec2 v_texture;\n"
+ "void main() {\n"
+ " v_texture = texture;\n"
+ " gl_Position = vec4(pos, 0, 1);\n"
+ "}\n";
+ static const char* fragmentShaderSource =
+ "precision mediump float;\n"
+ "uniform sampler2D u_texture;\n"
+ "varying vec2 v_texture;\n"
+ "void main() {\n"
+ " gl_FragColor = texture2D(u_texture, v_texture);\n"
+ "}\n";
+
+ QOpenGLFunctions* glFunctions = context->functions();
+ GLuint vertexShader = glFunctions->glCreateShader(GL_VERTEX_SHADER);
+ glFunctions->glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
+ glFunctions->glCompileShader(vertexShader);
+
+ GLuint fragmentShader = glFunctions->glCreateShader(GL_FRAGMENT_SHADER);
+ glFunctions->glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
+ glFunctions->glCompileShader(fragmentShader);
+
+ m_program = glFunctions->glCreateProgram();
+ glFunctions->glAttachShader(m_program, vertexShader);
+ glFunctions->glAttachShader(m_program, fragmentShader);
+ glFunctions->glLinkProgram(m_program);
+
+ glFunctions->glBindAttribLocation(m_program, 0, "pos");
+ glFunctions->glBindAttribLocation(m_program, 1, "texture");
+ m_textureUniform = glFunctions->glGetUniformLocation(m_program, "u_texture");
+
+ static struct wpe_view_backend_exportable_fdo_egl_client exportableClient = {
+ // export_buffer_resource
+ [](void* data, EGLImageKHR image)
+ {
+ static_cast<WPEQtViewBackend*>(data)->displayImage(image);
+ },
+ // padding
+ nullptr, nullptr, nullptr, nullptr
+ };
+
+ m_exportable = wpe_view_backend_exportable_fdo_egl_create(&exportableClient, this, m_size.width(), m_size.height());
+
+#if defined(WPE_BACKEND_CHECK_VERSION) && WPE_BACKEND_CHECK_VERSION(1, 1, 0)
+ wpe_view_backend_add_activity_state(backend(), wpe_view_activity_state_visible | wpe_view_activity_state_focused | wpe_view_activity_state_in_window);
+#endif
+
+ m_surface.setFormat(context->format());
+ m_surface.create();
+}
+
+WPEQtViewBackend::~WPEQtViewBackend()
+{
+ wpe_view_backend_exportable_fdo_destroy(m_exportable);
+ eglDestroyContext(m_eglDisplay, m_eglContext);
+}
+
+void WPEQtViewBackend::resize(const QSizeF& newSize)
+{
+ if (!newSize.isValid())
+ return;
+
+ m_size = newSize;
+ wpe_view_backend_dispatch_set_size(backend(), m_size.width(), m_size.height());
+}
+
+GLuint WPEQtViewBackend::texture(QOpenGLContext* context)
+{
+ if (!m_lockedImage || !hasValidSurface())
+ return 0;
+
+ context->makeCurrent(&m_surface);
+
+ QOpenGLFunctions* glFunctions = context->functions();
+ if (!m_textureId) {
+ glFunctions->glGenTextures(1, &m_textureId);
+ glFunctions->glBindTexture(GL_TEXTURE_2D, m_textureId);
+ glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glFunctions->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.width(), m_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ glFunctions->glBindTexture(GL_TEXTURE_2D, 0);
+ }
+
+ glFunctions->glClearColor(1, 0, 0, 1);
+ glFunctions->glClear(GL_COLOR_BUFFER_BIT);
+
+ glFunctions->glUseProgram(m_program);
+
+ glFunctions->glActiveTexture(GL_TEXTURE0);
+ glFunctions->glBindTexture(GL_TEXTURE_2D, m_textureId);
+ imageTargetTexture2DOES(GL_TEXTURE_2D, m_lockedImage);
+ glFunctions->glUniform1i(m_textureUniform, 0);
+
+ static const GLfloat vertices[4][2] = {
+ { -1.0, 1.0 },
+ { 1.0, 1.0 },
+ { -1.0, -1.0 },
+ { 1.0, -1.0 },
+ };
+
+ static const GLfloat texturePos[4][2] = {
+ { 0, 0 },
+ { 1, 0 },
+ { 0, 1 },
+ { 1, 1 },
+ };
+
+ glFunctions->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
+ glFunctions->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texturePos);
+
+ glFunctions->glEnableVertexAttribArray(0);
+ glFunctions->glEnableVertexAttribArray(1);
+
+ glFunctions->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ glFunctions->glDisableVertexAttribArray(0);
+ glFunctions->glDisableVertexAttribArray(1);
+
+ wpe_view_backend_exportable_fdo_dispatch_frame_complete(m_exportable);
+ wpe_view_backend_exportable_fdo_egl_dispatch_release_image(m_exportable, m_lockedImage);
+ m_lockedImage = EGL_NO_IMAGE_KHR;
+
+ return m_textureId;
+}
+
+void WPEQtViewBackend::displayImage(EGLImageKHR image)
+{
+ RELEASE_ASSERT(m_lockedImage == EGL_NO_IMAGE_KHR);
+ m_lockedImage = image;
+ if (m_view)
+ m_view->triggerUpdate();
+}
+
+uint32_t WPEQtViewBackend::modifiers() const
+{
+ uint32_t mask = m_keyboardModifiers;
+ if (m_mouseModifiers)
+ mask |= m_mouseModifiers;
+ return mask;
+}
+
+void WPEQtViewBackend::dispatchHoverEnterEvent(QHoverEvent*)
+{
+ m_hovering = true;
+ m_mouseModifiers = 0;
+}
+
+void WPEQtViewBackend::dispatchHoverLeaveEvent(QHoverEvent*)
+{
+ m_hovering = false;
+}
+
+void WPEQtViewBackend::dispatchHoverMoveEvent(QHoverEvent* event)
+{
+ if (!m_hovering)
+ return;
+
+ uint32_t state = !!m_mousePressedButton;
+ struct wpe_input_pointer_event wpeEvent = { wpe_input_pointer_event_type_motion,
+ static_cast<uint32_t>(event->timestamp()),
+ event->pos().x(), event->pos().y(),
+ m_mousePressedButton, state, modifiers() };
+ wpe_view_backend_dispatch_pointer_event(backend(), &wpeEvent);
+}
+
+void WPEQtViewBackend::dispatchMousePressEvent(QMouseEvent* event)
+{
+ uint32_t button = 0;
+ uint32_t modifier = 0;
+ switch (event->button()) {
+ case Qt::LeftButton:
+ button = 1;
+ modifier = wpe_input_pointer_modifier_button1;
+ break;
+ case Qt::RightButton:
+ button = 2;
+ modifier = wpe_input_pointer_modifier_button2;
+ break;
+ default:
+ break;
+ }
+ m_mousePressedButton = button;
+ uint32_t state = 1;
+ m_mouseModifiers |= modifier;
+ struct wpe_input_pointer_event wpeEvent = { wpe_input_pointer_event_type_button,
+ static_cast<uint32_t>(event->timestamp()),
+ event->x(), event->y(), button, state, modifiers() };
+ wpe_view_backend_dispatch_pointer_event(backend(), &wpeEvent);
+}
+
+void WPEQtViewBackend::dispatchMouseReleaseEvent(QMouseEvent* event)
+{
+ uint32_t button = 0;
+ uint32_t modifier = 0;
+ switch (event->button()) {
+ case Qt::LeftButton:
+ button = 1;
+ modifier = wpe_input_pointer_modifier_button1;
+ break;
+ case Qt::RightButton:
+ button = 2;
+ modifier = wpe_input_pointer_modifier_button2;
+ break;
+ default:
+ break;
+ }
+ m_mousePressedButton = 0;
+ uint32_t state = 0;
+ m_mouseModifiers &= ~modifier;
+ struct wpe_input_pointer_event wpeEvent = { wpe_input_pointer_event_type_button,
+ static_cast<uint32_t>(event->timestamp()),
+ event->x(), event->y(), button, state, modifiers() };
+ wpe_view_backend_dispatch_pointer_event(backend(), &wpeEvent);
+}
+
+void WPEQtViewBackend::dispatchWheelEvent(QWheelEvent* event)
+{
+ QPoint delta = event->angleDelta();
+ uint32_t axis = delta.y() == event->y();
+ QPoint numDegrees = delta / 8;
+ QPoint numSteps = numDegrees / 15;
+ int32_t length = numSteps.y() ? numSteps.y() : numSteps.x();
+ struct wpe_input_axis_event wpeEvent = { wpe_input_axis_event_type_motion,
+ static_cast<uint32_t>(event->timestamp()),
+ event->x(), event->y(), axis, length, modifiers() };
+ wpe_view_backend_dispatch_axis_event(backend(), &wpeEvent);
+}
+
+void WPEQtViewBackend::dispatchKeyEvent(QKeyEvent* event, bool state)
+{
+ uint32_t keysym = event->nativeVirtualKey();
+ if (!keysym)
+ keysym = wpe_input_xkb_context_get_key_code(wpe_input_xkb_context_get_default(), event->key(), state);
+
+ uint32_t modifiers = 0;
+ Qt::KeyboardModifiers qtModifiers = event->modifiers();
+ if (!qtModifiers)
+ qtModifiers = QGuiApplication::keyboardModifiers();
+
+ if (qtModifiers & Qt::ShiftModifier)
+ modifiers |= wpe_input_keyboard_modifier_shift;
+
+ if (qtModifiers & Qt::ControlModifier)
+ modifiers |= wpe_input_keyboard_modifier_control;
+ if (qtModifiers & Qt::MetaModifier)
+ modifiers |= wpe_input_keyboard_modifier_meta;
+ if (qtModifiers & Qt::AltModifier)
+ modifiers |= wpe_input_keyboard_modifier_alt;
+
+ struct wpe_input_keyboard_event wpeEvent = { static_cast<uint32_t>(event->timestamp()),
+ keysym, event->nativeScanCode(), state, modifiers };
+ wpe_view_backend_dispatch_keyboard_event(backend(), &wpeEvent);
+}
+
+void WPEQtViewBackend::dispatchTouchEvent(QTouchEvent* event)
+{
+ wpe_input_touch_event_type eventType;
+ switch (event->type()) {
+ case QEvent::TouchBegin:
+ eventType = wpe_input_touch_event_type_down;
+ break;
+ case QEvent::TouchUpdate:
+ eventType = wpe_input_touch_event_type_motion;
+ break;
+ case QEvent::TouchEnd:
+ eventType = wpe_input_touch_event_type_up;
+ break;
+ default:
+ eventType = wpe_input_touch_event_type_null;
+ break;
+ }
+
+ int i = 0;
+ struct wpe_input_touch_event_raw* rawEvents = g_new0(wpe_input_touch_event_raw, event->touchPoints().length());
+ for (auto& point : event->touchPoints()) {
+ rawEvents[i] = { eventType, static_cast<uint32_t>(event->timestamp()),
+ point.id(), static_cast<int32_t>(point.pos().x()), static_cast<int32_t>(point.pos().y()) };
+ i++;
+ }
+
+ struct wpe_input_touch_event wpeEvent = { rawEvents, static_cast<uint64_t>(i), eventType,
+ static_cast<int32_t>(rawEvents[0].id),
+ static_cast<uint32_t>(event->timestamp()), modifiers() };
+ wpe_view_backend_dispatch_touch_event(backend(), &wpeEvent);
+ g_free(rawEvents);
+}
Added: trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewBackend.h (0 => 240141)
--- trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewBackend.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewBackend.h 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L
+ * Copyright (C) 2018, 2019 Zodiac Inflight Innovations
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+// This include order is necessary to enforce the GBM EGL platform.
+#include <gbm.h>
+#include <epoxy/egl.h>
+
+#include <QHoverEvent>
+#include <QKeyEvent>
+#include <QMouseEvent>
+#include <QOffscreenSurface>
+#include <QOpenGLContext>
+#include <QPointer>
+#include <QWheelEvent>
+#include <wpe/fdo-egl.h>
+#include <wpe/fdo.h>
+
+class WPEQtView;
+
+class Q_DECL_EXPORT WPEQtViewBackend {
+public:
+ static std::unique_ptr<WPEQtViewBackend> create(const QSizeF&, QPointer<QOpenGLContext>, EGLDisplay, QPointer<WPEQtView>);
+ WPEQtViewBackend(const QSizeF&, EGLDisplay, EGLContext, QPointer<QOpenGLContext>, QPointer<WPEQtView>);
+ virtual ~WPEQtViewBackend();
+
+ void resize(const QSizeF&);
+ GLuint texture(QOpenGLContext*);
+ bool hasValidSurface() const { return m_surface.isValid(); };
+
+ void dispatchHoverEnterEvent(QHoverEvent*);
+ void dispatchHoverLeaveEvent(QHoverEvent*);
+ void dispatchHoverMoveEvent(QHoverEvent*);
+
+ void dispatchMousePressEvent(QMouseEvent*);
+ void dispatchMouseReleaseEvent(QMouseEvent*);
+ void dispatchWheelEvent(QWheelEvent*);
+
+ void dispatchKeyEvent(QKeyEvent*, bool state);
+
+ void dispatchTouchEvent(QTouchEvent*);
+
+ struct wpe_view_backend* backend() const { return wpe_view_backend_exportable_fdo_get_view_backend(m_exportable); };
+
+private:
+ void displayImage(EGLImageKHR);
+ uint32_t modifiers() const;
+
+ EGLDisplay m_eglDisplay { nullptr };
+ EGLContext m_eglContext { nullptr };
+ struct wpe_view_backend_exportable_fdo* m_exportable { nullptr };
+
+ EGLImageKHR m_lockedImage { EGL_NO_IMAGE_KHR };
+
+ QPointer<WPEQtView> m_view;
+ QOffscreenSurface m_surface;
+ QSizeF m_size;
+ GLuint m_textureId { 0 };
+ unsigned m_program { 0 };
+ unsigned m_textureUniform { 0 };
+
+ bool m_hovering { false };
+ uint32_t m_mouseModifiers { 0 };
+ uint32_t m_keyboardModifiers { 0 };
+ uint32_t m_mousePressedButton { 0 };
+};
Added: trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewLoadRequest.cpp (0 => 240141)
--- trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewLoadRequest.cpp (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewLoadRequest.cpp 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L
+ * Copyright (C) 2018, 2019 Zodiac Inflight Innovations
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WPEQtViewLoadRequest.h"
+
+#include "WPEQtView.h"
+#include "WPEQtViewLoadRequestPrivate.h"
+
+/*!
+ \qmltype WPEViewLoadRequest
+ \instantiates WPEQtViewLoadRequest
+ \inqmlmodule org.wpewebkit.qtwpe
+
+ \brief A utility type for \l {WPEView}'s \l {WPEView::}{loadingChanged()} signal.
+
+ The WPEViewLoadRequest type contains load status information for the requested URL.
+
+ \sa {WPEView::loadingChanged()}{WPEView.loadingChanged()}
+*/
+WPEQtViewLoadRequest::WPEQtViewLoadRequest(const WPEQtViewLoadRequestPrivate& d)
+ : d_ptr(new WPEQtViewLoadRequestPrivate(d))
+{
+
+}
+
+WPEQtViewLoadRequest::~WPEQtViewLoadRequest()
+{
+
+}
+
+/*!
+ \qmlproperty url WPEView::WPEViewLoadRequest::url
+ \readonly
+
+ The URL of the load request.
+*/
+QUrl WPEQtViewLoadRequest::url() const
+{
+ Q_D(const WPEQtViewLoadRequest);
+ return d->m_url;
+}
+
+/*!
+ \qmlproperty enumeration WPEViewLoadRequest::status
+ \readonly
+
+ This enumeration represents the load status of a web page load request.
+
+ \value WPEView.LoadStartedStatus The page is currently loading.
+ \value WPEView.LoadStoppedStatus The page loading was interrupted.
+ \value WPEView.LoadSucceededStatus The page was loaded successfully.
+ \value WPEView.LoadFailedStatus The page could not be loaded.
+
+ \sa {WPEView::loadingChanged()}{WPEView.loadingChanged}
+*/
+WPEQtView::LoadStatus WPEQtViewLoadRequest::status() const
+{
+ Q_D(const WPEQtViewLoadRequest);
+ return d->m_status;
+}
+
+/*!
+ \qmlproperty string WPEView::WPEViewLoadRequest::errorString
+ \readonly
+
+ Holds the error message if the load request failed.
+*/
+QString WPEQtViewLoadRequest::errorString() const
+{
+ Q_D(const WPEQtViewLoadRequest);
+ return d->m_errorString;
+}
Added: trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewLoadRequest.h (0 => 240141)
--- trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewLoadRequest.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewLoadRequest.h 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L
+ * Copyright (C) 2018, 2019 Zodiac Inflight Innovations
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "WPEQtView.h"
+
+#include <QObject>
+
+class WPEQtViewLoadRequestPrivate;
+
+class WPEQtViewLoadRequest : public QObject {
+ Q_OBJECT
+ Q_PROPERTY(QUrl url READ url)
+ Q_PROPERTY(WPEQtView::LoadStatus status READ status)
+ Q_PROPERTY(QString errorString READ errorString)
+
+public:
+ ~WPEQtViewLoadRequest();
+
+ QUrl url() const;
+ WPEQtView::LoadStatus status() const;
+ QString errorString() const;
+
+ explicit WPEQtViewLoadRequest(const WPEQtViewLoadRequestPrivate&);
+
+private:
+ friend class WPEQtView;
+
+ Q_DECLARE_PRIVATE(WPEQtViewLoadRequest)
+ QScopedPointer<WPEQtViewLoadRequestPrivate> d_ptr;
+};
+
Added: trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewLoadRequestPrivate.h (0 => 240141)
--- trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewLoadRequestPrivate.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/wpe/qt/WPEQtViewLoadRequestPrivate.h 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L
+ * Copyright (C) 2018, 2019 Zodiac Inflight Innovations
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+#include "WPEQtView.h"
+#include <QtCore/qstring.h>
+#include <QtCore/qurl.h>
+
+class WPEQtViewLoadRequestPrivate {
+public:
+ WPEQtViewLoadRequestPrivate() { }
+ WPEQtViewLoadRequestPrivate(const QUrl& url, WPEQtView::LoadStatus status, const QString& errorString)
+ : m_url(url)
+ , m_status(status)
+ , m_errorString(errorString)
+ { }
+ ~WPEQtViewLoadRequestPrivate() { }
+
+ QUrl m_url;
+ WPEQtView::LoadStatus m_status;
+ QString m_errorString;
+};
+
+Q_DECLARE_METATYPE(WPEQtViewLoadRequestPrivate)
Added: trunk/Source/WebKit/UIProcess/API/wpe/qt/qmldir (0 => 240141)
--- trunk/Source/WebKit/UIProcess/API/wpe/qt/qmldir (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/wpe/qt/qmldir 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,2 @@
+module org.wpewebkit.qtwpe
+plugin qtwpe
Modified: trunk/Source/cmake/OptionsWPE.cmake (240140 => 240141)
--- trunk/Source/cmake/OptionsWPE.cmake 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Source/cmake/OptionsWPE.cmake 2019-01-18 13:07:38 UTC (rev 240141)
@@ -45,6 +45,7 @@
# and the option is not relevant to any other WebKit ports.
WEBKIT_OPTION_DEFINE(ENABLE_GTKDOC "Whether or not to use generate gtkdoc." PUBLIC OFF)
WEBKIT_OPTION_DEFINE(USE_WOFF2 "Whether to enable support for WOFF2 Web Fonts." PUBLIC ON)
+WEBKIT_OPTION_DEFINE(ENABLE_WPE_QT_API "Whether to enable support for the Qt5/QML plugin" PUBLIC OFF)
# Private options specific to the WPE port.
WEBKIT_OPTION_DEFINE(USE_OPENVR "Whether to use OpenVR as WebVR backend." PRIVATE ${ENABLE_EXPERIMENTAL_FEATURES})
@@ -110,6 +111,13 @@
find_package(LibXslt 1.1.7 REQUIRED)
endif ()
+if (ENABLE_WPE_QT_API)
+ find_package(Qt5 REQUIRED COMPONENTS Core Quick Gui)
+ find_package(Qt5Test REQUIRED)
+ find_package(PkgConfig)
+ pkg_check_modules(WPE_BACKEND_FDO REQUIRED wpebackend-fdo-0.1)
+endif ()
+
add_definitions(-DBUILDING_WPE__=1)
add_definitions(-DGETTEXT_PACKAGE="WPE")
add_definitions(-DJSC_GLIB_API_ENABLED)
Modified: trunk/Tools/ChangeLog (240140 => 240141)
--- trunk/Tools/ChangeLog 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Tools/ChangeLog 2019-01-18 13:07:38 UTC (rev 240141)
@@ -1,3 +1,68 @@
+2019-01-18 Philippe Normand <[email protected]>
+
+ [WPE] Add Qt extension
+ https://bugs.webkit.org/show_bug.cgi?id=191464
+
+ Reviewed by Carlos Garcia Campos.
+
+ MiniBrowser and API tests for the WPE Qt API. To run the
+ MiniBrowser a new script is introduced. Example invocation:
+
+ $ run-qt-wpe-minibrowser -platform wayland https://webkit.org
+
+ Also note-worthy is the introduction of the python2-subprocess32
+ dependency to run the GLib API tests.
+
+ * MiniBrowser/wpe/CMakeLists.txt:
+ * MiniBrowser/wpe/qt/CMakeLists.txt: Added.
+ * MiniBrowser/wpe/qt/main.cpp: Added.
+ (main):
+ * MiniBrowser/wpe/qt/main.qml: Added.
+ * MiniBrowser/wpe/qt/qml.qrc: Added.
+ * Scripts/run-gtk-tests:
+ (GtkTestRunner.is_google_test):
+ (GtkTestRunner):
+ (GtkTestRunner.is_qt_test):
+ * Scripts/run-qt-wpe-minibrowser: Added.
+ * Scripts/run-wpe-tests:
+ (WPETestRunner):
+ (WPETestRunner.is_google_test):
+ (WPETestRunner.is_qt_test):
+ * TestWebKitAPI/Tests/WPEQt/TestLoad.cpp: Added.
+ (TestLoad::main):
+ * TestWebKitAPI/Tests/WPEQt/TestLoadHtml.cpp: Added.
+ (TestLoadHtml::main):
+ * TestWebKitAPI/Tests/WPEQt/TestLoadRequest.cpp: Added.
+ (TestLoadRequest::main):
+ * TestWebKitAPI/Tests/WPEQt/TestRunJavaScript.cpp: Added.
+ (TestRunJavaScript::main):
+ * TestWebKitAPI/Tests/WPEQt/WPEQtTest.cpp: Added.
+ (waitForSignal):
+ * TestWebKitAPI/Tests/WPEQt/WPEQtTest.h: Added.
+ (LoadSpy::LoadSpy):
+ (LoadSpy::~LoadSpy):
+ (LoadSpy::onLoadingChanged):
+ (LoadStartedCatcher::LoadStartedCatcher):
+ (LoadStartedCatcher::~LoadStartedCatcher):
+ (LoadStartedCatcher::onLoadingChanged):
+ (waitForLoadSucceeded):
+ (waitForLoadFailed):
+ * TestWebKitAPI/glib/CMakeLists.txt:
+ * flatpak/flatpakutils.py:
+ (WebkitFlatpak.load_from_args):
+ (WebkitFlatpak.__init__):
+ (WebkitFlatpak.clean_args):
+ (WebkitFlatpak.run_in_sandbox):
+ * flatpak/org.webkit.CommonModules.yaml:
+ * flatpak/org.webkit.WPE.yaml:
+ * flatpak/org.webkit.WPEModules.yaml:
+ * flatpak/org.webkit.WPEQT.yaml: Copied from Tools/flatpak/org.webkit.WebKit.yaml.
+ * flatpak/org.webkit.WebKit.yaml:
+ * glib/api_test_runner.py:
+ (TestRunner._run_test_qt):
+ (TestRunner.is_qt_test):
+ (TestRunner._run_test):
+
2019-01-17 Wenson Hsieh <[email protected]>
[iOS] Content offset jumps erratically when autoscrolling near scroll view content inset areas
Modified: trunk/Tools/MiniBrowser/wpe/CMakeLists.txt (240140 => 240141)
--- trunk/Tools/MiniBrowser/wpe/CMakeLists.txt 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Tools/MiniBrowser/wpe/CMakeLists.txt 2019-01-18 13:07:38 UTC (rev 240141)
@@ -34,3 +34,7 @@
target_link_libraries(MiniBrowser ${MiniBrowser_LIBRARIES})
install(TARGETS MiniBrowser DESTINATION "${LIBEXEC_INSTALL_DIR}")
+
+if (ENABLE_WPE_QT_API)
+ add_subdirectory(qt)
+endif ()
Added: trunk/Tools/MiniBrowser/wpe/qt/CMakeLists.txt (0 => 240141)
--- trunk/Tools/MiniBrowser/wpe/qt/CMakeLists.txt (rev 0)
+++ trunk/Tools/MiniBrowser/wpe/qt/CMakeLists.txt 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,13 @@
+
+if (ENABLE_WPE_QT_API)
+ set(CMAKE_AUTOMOC ON)
+ set(CMAKE_AUTORCC ON)
+
+ if (DEVELOPER_MODE)
+ add_definitions(-DWEBKIT_INJECTED_BUNDLE_PATH="${CMAKE_LIBRARY_OUTPUT_DIRECTORY}")
+ endif ()
+
+ add_executable(qt-wpe-mini-browser "main.cpp" "qml.qrc")
+ target_link_libraries(qt-wpe-mini-browser Qt5::Core Qt5::Quick)
+ install(TARGETS qt-wpe-mini-browser DESTINATION "${LIBEXEC_INSTALL_DIR}")
+endif ()
Added: trunk/Tools/MiniBrowser/wpe/qt/main.cpp (0 => 240141)
--- trunk/Tools/MiniBrowser/wpe/qt/main.cpp (rev 0)
+++ trunk/Tools/MiniBrowser/wpe/qt/main.cpp 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L
+ * Copyright (C) 2018, 2019 Zodiac Inflight Innovations
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <QCommandLineOption>
+#include <QCommandLineParser>
+#include <QGuiApplication>
+#include <QProcessEnvironment>
+#include <QQmlApplicationEngine>
+#include <QQmlContext>
+#include <QUrl>
+
+int main(int argc, char* argv[])
+{
+#if defined(WEBKIT_INJECTED_BUNDLE_PATH)
+ setenv("WEBKIT_INJECTED_BUNDLE_PATH", WEBKIT_INJECTED_BUNDLE_PATH, 0);
+#endif
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+
+ QGuiApplication app(argc, argv);
+
+ QCommandLineParser parser;
+ QCoreApplication::setApplicationVersion("0.1");
+ parser.setApplicationDescription(QGuiApplication::applicationDisplayName());
+ parser.addHelpOption();
+ parser.addVersionOption();
+ parser.addPositionalArgument("initialUrl", "The URL to open.");
+ QStringList arguments = app.arguments();
+ parser.process(arguments);
+ const QString initialUrl = parser.positionalArguments().isEmpty() ?
+ QStringLiteral("https://wpewebkit.org") : parser.positionalArguments().first();
+
+ QQmlApplicationEngine engine;
+ QQmlContext* context = engine.rootContext();
+ context->setContextProperty(QStringLiteral("initialUrl"), QUrl(initialUrl));
+
+ engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
+ if (engine.rootObjects().isEmpty())
+ return -1;
+
+ return app.exec();
+}
Added: trunk/Tools/MiniBrowser/wpe/qt/main.qml (0 => 240141)
--- trunk/Tools/MiniBrowser/wpe/qt/main.qml (rev 0)
+++ trunk/Tools/MiniBrowser/wpe/qt/main.qml 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,20 @@
+import QtQuick 2.11
+import QtQuick.Window 2.11
+import org.wpewebkit.qtwpe 1.0
+
+Window {
+ id: main_window
+ visible: true
+ width: 1280
+ height: 720
+ title: qsTr("Hello WPE!")
+
+ WPEView {
+ url: initialUrl
+ focus: true
+ anchors.fill: parent
+ onTitleChanged: {
+ main_window.title = title;
+ }
+ }
+}
Added: trunk/Tools/MiniBrowser/wpe/qt/qml.qrc (0 => 240141)
--- trunk/Tools/MiniBrowser/wpe/qt/qml.qrc (rev 0)
+++ trunk/Tools/MiniBrowser/wpe/qt/qml.qrc 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>main.qml</file>
+ </qresource>
+</RCC>
Modified: trunk/Tools/Scripts/run-gtk-tests (240140 => 240141)
--- trunk/Tools/Scripts/run-gtk-tests 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Tools/Scripts/run-gtk-tests 2019-01-18 13:07:38 UTC (rev 240141)
@@ -125,6 +125,9 @@
def is_google_test(self, test_program):
return os.path.basename(os.path.dirname(test_program)) in ["WebKit", "WTF", "WebCore", "WebCoreGtk"]
+ def is_qt_test(self, test_program):
+ return False
+
if __name__ == "__main__":
flatpakutils.run_in_sandbox_if_available(sys.argv)
if not flatpakutils.is_sandboxed() and not jhbuildutils.enter_jhbuild_environment_if_available("gtk"):
Added: trunk/Tools/Scripts/run-qt-wpe-minibrowser (0 => 240141)
--- trunk/Tools/Scripts/run-qt-wpe-minibrowser (rev 0)
+++ trunk/Tools/Scripts/run-qt-wpe-minibrowser 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,60 @@
+#!/usr/bin/env perl
+# Copyright (C) 2018, 2019 Igalia S.L.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+
+# Simplified "run" script for launching the QtWPE MiniBrowser.
+
+use strict;
+use warnings;
+use File::Spec::Functions qw/catdir/;
+use FindBin;
+use lib $FindBin::Bin;
+use webkitdirs;
+
+my $launcherName;
+my $libPath;
+my $launcherPath;
+my @jhbuildWrapper;
+
+prohibitUnknownPort();
+setConfiguration();
+
+if (isWPE()) {
+ my $configuration = passedConfiguration();
+ my $productDir = productDir();
+ my $libPath;
+ $libPath = "/app/webkit/WebKitBuild/$configuration/lib/qml" if $configuration;
+ $ENV{"QML2_IMPORT_PATH"} = "$libPath" if $libPath;
+ runInFlatpakIfAvailable("/app/webkit/Tools/Scripts/run-qt-wpe-minibrowser");
+
+ # Check to see that all the frameworks are built.
+ checkFrameworks();
+
+ if (!inFlatpakSandbox()) {
+ $libPath = "$productDir/lib/qml" if $productDir;
+ $ENV{"QML2_IMPORT_PATH"} = "$libPath" if $libPath;
+ }
+
+ $launcherPath = catdir($productDir, "bin", "qt-wpe-mini-browser");
+ die "Can't find $launcherPath" unless -x $launcherPath;
+ @jhbuildWrapper = wrapperPrefixIfNeeded();
+
+ print "Starting MiniBrowser.\n";
+ exec @jhbuildWrapper, $launcherPath, @ARGV or die;
+} else {
+ die "Unsupported platform."
+}
Property changes on: trunk/Tools/Scripts/run-qt-wpe-minibrowser
___________________________________________________________________
Added: svn:executable
+*
\ No newline at end of property
Modified: trunk/Tools/Scripts/run-wpe-tests (240140 => 240141)
--- trunk/Tools/Scripts/run-wpe-tests 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Tools/Scripts/run-wpe-tests 2019-01-18 13:07:38 UTC (rev 240141)
@@ -26,12 +26,13 @@
sys.path.insert(0, os.path.join(top_level_directory, "Tools", "jhbuild"))
sys.path.insert(0, os.path.join(top_level_directory, "Tools", "flatpak"))
sys.path.insert(0, os.path.join(top_level_directory, "Tools", "glib"))
+import common
import jhbuildutils
import flatpakutils
from api_test_runner import TestRunner, add_options
class WPETestRunner(TestRunner):
- TestRunner.TEST_DIRS = [ "WPE", "WebKit", "_javascript_Core", "WTF", "WebCore" ]
+ TestRunner.TEST_DIRS = [ "WPE", "WPEQt", "WebKit", "_javascript_Core", "WTF", "WebCore" ]
def __init__(self, options, tests=[]):
super(WPETestRunner, self).__init__("wpe", options, tests)
@@ -42,6 +43,8 @@
def is_google_test(self, test_program):
return os.path.basename(os.path.dirname(test_program)) in ["WebKit", "WTF", "WebCore"]
+ def is_qt_test(self, test_program):
+ return os.path.basename(os.path.dirname(test_program)) == "WPEQt"
if __name__ == "__main__":
flatpakutils.run_in_sandbox_if_available([sys.argv[0], "--wpe"] + sys.argv[1:])
Added: trunk/Tools/TestWebKitAPI/Tests/WPEQt/TestLoad.cpp (0 => 240141)
--- trunk/Tools/TestWebKitAPI/Tests/WPEQt/TestLoad.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WPEQt/TestLoad.cpp 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include "WPEQtTest.h"
+
+#include <QtCore/QTemporaryFile>
+#include <QtCore/qdir.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qstandardpaths.h>
+#include <QtCore/qtemporarydir.h>
+
+class TestLoad : public WPEQtTest {
+Q_OBJECT
+private:
+ void main() override;
+};
+
+void TestLoad::main()
+{
+ QString cacheLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
+ static const char* testHTML = "<html><head><title>FooBar</title></head><body><p>This is a test</p></body></html>";
+
+ QTemporaryFile file(cacheLocation + QStringLiteral("/XXXXXXfile.html"));
+ QVERIFY2(file.open(), qPrintable(QStringLiteral("Cannot create temporary file:") + file.errorString()));
+
+ file.write(testHTML);
+ const QString fileName(file.fileName());
+ file.close();
+
+ const QUrl url(QUrl::fromLocalFile(fileName));
+ m_view->setUrl(url);
+
+ waitForLoadSucceeded(m_view);
+ QTRY_COMPARE(m_view->loadProgress(), 100);
+ QTRY_VERIFY(!m_view->isLoading());
+ QCOMPARE(m_view->title(), QStringLiteral("FooBar"));
+ QVERIFY(!m_view->canGoBack());
+ QVERIFY(!m_view->canGoForward());
+ QCOMPARE(m_view->url(), url);
+}
+
+QTEST_APPLESS_MAIN(TestLoad)
+#include "TestLoad.moc"
Added: trunk/Tools/TestWebKitAPI/Tests/WPEQt/TestLoadHtml.cpp (0 => 240141)
--- trunk/Tools/TestWebKitAPI/Tests/WPEQt/TestLoadHtml.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WPEQt/TestLoadHtml.cpp 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include "WPEQtTest.h"
+
+class TestLoadHtml : public WPEQtTest {
+Q_OBJECT
+private:
+ void main() override;
+};
+
+void TestLoadHtml::main()
+{
+ m_view->loadHtml(QString("<html><head><title>WebViewTitle</title></head><body />"));
+ waitForLoadSucceeded(m_view);
+ QTRY_COMPARE(m_view->loadProgress(), 100);
+ QTRY_VERIFY(!m_view->isLoading());
+ QCOMPARE(m_view->title(), QStringLiteral("WebViewTitle"));
+}
+
+QTEST_APPLESS_MAIN(TestLoadHtml)
+#include "TestLoadHtml.moc"
Added: trunk/Tools/TestWebKitAPI/Tests/WPEQt/TestLoadRequest.cpp (0 => 240141)
--- trunk/Tools/TestWebKitAPI/Tests/WPEQt/TestLoadRequest.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WPEQt/TestLoadRequest.cpp 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include "WPEQtTest.h"
+
+#include <QtCore/QTemporaryFile>
+#include <QtCore/qdir.h>
+#include <QtCore/qfileinfo.h>
+#include <QtCore/qstandardpaths.h>
+#include <QtCore/qtemporarydir.h>
+
+class TestLoadRequest : public WPEQtTest {
+Q_OBJECT
+private:
+ void main() override;
+};
+
+void TestLoadRequest::main()
+{
+ {
+ QString cacheLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
+ QTemporaryFile file(cacheLocation + QStringLiteral("/XXXXXXfile.html"));
+ QVERIFY2(file.open(), qPrintable(QStringLiteral("Cannot create temporary file:") + file.errorString()));
+
+ file.write("<html><head><title>FooBar</title></head><body />");
+ const QString fileName = file.fileName();
+ file.close();
+ const QUrl url = ""
+ QSignalSpy loadChangedSignalSpy(m_view, SIGNAL(loadingChanged(WPEQtViewLoadRequest*)));
+ m_view->setUrl(url);
+ waitForLoadSucceeded(m_view);
+ QVERIFY(!m_view->isLoading());
+ QCOMPARE(m_view->loadProgress(), 100);
+ QCOMPARE(m_view->title(), QStringLiteral("FooBar"));
+ QCOMPARE(m_view->url(), url);
+ QCOMPARE(loadChangedSignalSpy.count(), 2);
+ }
+
+ {
+ QSignalSpy loadChangedSignalSpy(m_view, SIGNAL(loadingChanged(WPEQtViewLoadRequest*)));
+ m_view->setUrl(QUrl("file://IDONTEXIST.html"));
+ waitForLoadFailed(m_view);
+ QCOMPARE(loadChangedSignalSpy.count(), 2);
+ }
+}
+
+QTEST_APPLESS_MAIN(TestLoadRequest)
+#include "TestLoadRequest.moc"
Added: trunk/Tools/TestWebKitAPI/Tests/WPEQt/TestRunJavaScript.cpp (0 => 240141)
--- trunk/Tools/TestWebKitAPI/Tests/WPEQt/TestRunJavaScript.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WPEQt/TestRunJavaScript.cpp 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+
+#include "WPEQtTest.h"
+
+class TestRunJavaScript : public WPEQtTest {
+ Q_OBJECT
+private:
+ void main() override;
+};
+
+void TestRunJavaScript::main()
+{
+ const QString title = QString(QLatin1String("WebViewTitle"));
+ m_view->loadHtml(QString("<html><head><title>%1</title></head><body /></html>").arg(title));
+
+ waitForLoadSucceeded(m_view);
+ QCOMPARE(m_view->loadProgress(), 100);
+ QVERIFY(!m_view->isLoading());
+ QCOMPARE(m_view->title(), title);
+ const QString tstProperty = QString(QLatin1String("Qt.tst_data"));
+ QJSValue callback = m_engine.evaluate(QString("function(result) { %1 = result; }").arg(tstProperty));
+ QVERIFY2(!callback.isError(), qPrintable(callback.toString()));
+ QVERIFY(!callback.isUndefined());
+ QVERIFY(callback.isCallable());
+ m_view->runJavaScript(QString(QLatin1String("document.title")), callback);
+ QTRY_COMPARE(m_engine.evaluate(tstProperty).toString(), title);
+}
+
+QTEST_APPLESS_MAIN(TestRunJavaScript)
+#include "TestRunJavaScript.moc"
Added: trunk/Tools/TestWebKitAPI/Tests/WPEQt/WPEQtTest.cpp (0 => 240141)
--- trunk/Tools/TestWebKitAPI/Tests/WPEQt/WPEQtTest.cpp (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WPEQt/WPEQtTest.cpp 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WPEQtTest.h"
+
+bool waitForSignal(QObject* obj, const char* signal, int timeout)
+{
+ QEventLoop loop;
+ QObject::connect(obj, signal, &loop, SLOT(quit()));
+ QTimer timer;
+ QSignalSpy timeoutSpy(&timer, SIGNAL(timeout()));
+ if (timeout > 0) {
+ QObject::connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
+ timer.setSingleShot(true);
+ timer.start(timeout);
+ }
+ loop.exec();
+ return timeoutSpy.isEmpty();
+}
+
+#include "WPEQtTest.moc"
Added: trunk/Tools/TestWebKitAPI/Tests/WPEQt/WPEQtTest.h (0 => 240141)
--- trunk/Tools/TestWebKitAPI/Tests/WPEQt/WPEQtTest.h (rev 0)
+++ trunk/Tools/TestWebKitAPI/Tests/WPEQt/WPEQtTest.h 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2018, 2019 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2,1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+// WPEQt has to be included before the remaining Qt headers, because of epoxy.
+#include <wpe/qt/WPEQtView.h>
+#include <wpe/qt/WPEQtViewLoadRequest.h>
+
+#include <QEventLoop>
+#include <QQmlApplicationEngine>
+#include <QQuickWindow>
+#include <QSignalSpy>
+#include <QTimer>
+#include <QtTest/QTest>
+
+class LoadSpy : public QEventLoop {
+ Q_OBJECT
+
+public:
+ LoadSpy(WPEQtView *webView)
+ {
+ connect(webView, SIGNAL(loadingChanged(WPEQtViewLoadRequest*)), SLOT(onLoadingChanged(WPEQtViewLoadRequest*)));
+ }
+
+ ~LoadSpy() { }
+
+Q_SIGNALS:
+ void loadSucceeded();
+ void loadFailed();
+
+private Q_SLOTS:
+ void onLoadingChanged(WPEQtViewLoadRequest *loadRequest)
+ {
+ if (loadRequest->status() == WPEQtView::LoadSucceededStatus)
+ Q_EMIT loadSucceeded();
+ else if (loadRequest->status() == WPEQtView::LoadFailedStatus)
+ Q_EMIT loadFailed();
+ }
+};
+
+class LoadStartedCatcher : public QObject {
+ Q_OBJECT
+
+public:
+ LoadStartedCatcher(WPEQtView *webView)
+ : m_webView(webView)
+ {
+ connect(m_webView, SIGNAL(loadingChanged(WPEQtViewLoadRequest*)), this, SLOT(onLoadingChanged(WPEQtViewLoadRequest*)));
+ }
+
+ virtual ~LoadStartedCatcher() { }
+
+public Q_SLOTS:
+ void onLoadingChanged(WPEQtViewLoadRequest *loadRequest)
+ {
+ if (loadRequest->status() == WPEQtView::LoadStartedStatus)
+ QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
+ }
+
+Q_SIGNALS:
+ void finished();
+
+private:
+ WPEQtView* m_webView;
+};
+
+bool waitForSignal(QObject*, const char* signal, int timeout = 10000);
+
+inline bool waitForLoadSucceeded(WPEQtView* webView, int timeout = 10000)
+{
+ LoadSpy loadSpy(webView);
+ return waitForSignal(&loadSpy, SIGNAL(loadSucceeded()), timeout);
+}
+
+inline bool waitForLoadFailed(WPEQtView* webView, int timeout = 10000)
+{
+ LoadSpy loadSpy(webView);
+ return waitForSignal(&loadSpy, SIGNAL(loadFailed()), timeout);
+}
+
+class WPEQtTest: public QObject {
+ Q_OBJECT
+public:
+ WPEQtTest()
+ : m_argc(0)
+ , m_app(m_argc, nullptr)
+ , m_engine()
+ {
+ g_setenv("WEBKIT_EXEC_PATH", WEBKIT_EXEC_PATH, FALSE);
+ g_setenv("WEBKIT_INJECTED_BUNDLE_PATH", WEBKIT_INJECTED_BUNDLE_PATH, FALSE);
+
+ QQmlComponent component(&m_engine);
+ component.setData("import QtQuick 2.11\n"
+ "import QtQuick.Window 2.11\n"
+ "import org.wpewebkit.qtwpe 1.0\n"
+ "Window {\n"
+ " id: main_window\n"
+ " visible: true\n"
+ " width: 1280\n"
+ " height: 720\n"
+ " WPEView {\n"
+ " objectName: \"wpeview\"\n"
+ " focus: true\n"
+ " anchors.fill: parent\n"
+ " }\n"
+ "}", QUrl());
+
+ QObject* object = component.create();
+ m_view = object->findChild<WPEQtView*>("wpeview");
+
+ QTRY_COMPARE(m_view->loadProgress(), 0);
+ }
+
+ virtual ~WPEQtTest()
+ {
+ delete m_view;
+ }
+
+private Q_SLOTS:
+ void run()
+ {
+ QObject::connect(m_view, &WPEQtView::webViewCreated, this, [this] {
+ main();
+ m_app.quit();
+ });
+ m_app.exec();
+ }
+
+private:
+ virtual void main() = 0;
+
+ int m_argc;
+ QGuiApplication m_app;
+
+protected:
+ WPEQtView* m_view { nullptr };
+ QQmlEngine m_engine;
+};
Modified: trunk/Tools/TestWebKitAPI/glib/CMakeLists.txt (240140 => 240141)
--- trunk/Tools/TestWebKitAPI/glib/CMakeLists.txt 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Tools/TestWebKitAPI/glib/CMakeLists.txt 2019-01-18 13:07:38 UTC (rev 240141)
@@ -21,9 +21,13 @@
${LIBSOUP_INCLUDE_DIRS}
)
-set(WebKitGLibAPITest_LIBRARIES
+set(WebKitAPITest_LIBRARIES
_javascript_Core
WebKit
+)
+
+set(WebKitGLibAPITest_LIBRARIES
+ ${WebKitAPITest_LIBRARIES}
WebKitGLibAPITestsCore
${GLIB_LIBRARIES}
${LIBSOUP_LIBRARIES}
@@ -145,3 +149,32 @@
if (PORT STREQUAL "GTK")
ADD_WK2_TEST(TestCookieManager ${TOOLS_DIR}/TestWebKitAPI/Tests/WebKitGLib/TestCookieManager.cpp)
endif ()
+
+macro(ADD_WPE_QT_TEST test_name)
+ add_executable(${test_name} ${ARGN} ${TOOLS_DIR}/TestWebKitAPI/Tests/WPEQt/WPEQtTest.cpp)
+ set_target_properties(${test_name} PROPERTIES
+ RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/TestWebKitAPI/WPEQt
+ AUTOMOC ON
+ CXX_STANDARD 14
+ )
+ target_compile_definitions(${test_name} PUBLIC QT_NO_KEYWORDS=1)
+ target_link_libraries(${test_name} ${WPEQtAPITest_LIBRARIES})
+ target_include_directories(${test_name} SYSTEM PRIVATE ${WPEQtAPITests_INCLUDE_DIRECTORIES})
+ target_include_directories(${test_name} PRIVATE
+ ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/Source/WebKit/UIProcess/API/wpe/qt)
+endmacro()
+
+if (PORT STREQUAL "WPE" AND ENABLE_WPE_QT_API)
+ set(WPEQtAPITests_INCLUDE_DIRECTORIES
+ ${Qt5_INCLUDE_DIRS}
+ ${Qt5Test_INCLUDE_DIRS}
+ )
+ set(WPEQtAPITest_LIBRARIES
+ ${WebKitAPITest_LIBRARIES}
+ Qt5::Test qtwpe
+ )
+ ADD_WPE_QT_TEST(TestLoad ${TOOLS_DIR}/TestWebKitAPI/Tests/WPEQt/TestLoad.cpp)
+ ADD_WPE_QT_TEST(TestLoadHtml ${TOOLS_DIR}/TestWebKitAPI/Tests/WPEQt/TestLoadHtml.cpp)
+ ADD_WPE_QT_TEST(TestLoadRequest ${TOOLS_DIR}/TestWebKitAPI/Tests/WPEQt/TestLoadRequest.cpp)
+ ADD_WPE_QT_TEST(TestRunJavaScript ${TOOLS_DIR}/TestWebKitAPI/Tests/WPEQt/TestRunJavaScript.cpp)
+endif ()
Modified: trunk/Tools/flatpak/flatpakutils.py (240140 => 240141)
--- trunk/Tools/flatpak/flatpakutils.py 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Tools/flatpak/flatpakutils.py 2019-01-18 13:07:38 UTC (rev 240141)
@@ -52,6 +52,10 @@
("flatpak-builder", "0.10.0"),
]
+WPE_MANIFEST_MAP = {
+ "qt": "org.webkit.WPEQT.yaml",
+}
+
scriptdir = os.path.abspath(os.path.dirname(__file__))
_log = logging.getLogger(__name__)
@@ -498,6 +502,7 @@
dest="user_command")
general.add_argument('--available', action='', dest="check_available", help='Check if required dependencies are available.'),
general.add_argument("--use-icecream", help="Use the distributed icecream (icecc) compiler.", action=""
+ general.add_argument("--wpe-extension", action="" dest="wpe_extension", help="WPE Extension to enable")
debugoptions = parser.add_argument_group("Debugging")
debugoptions.add_argument("--gdb", nargs="?", help="Activate gdb, passing extra args to it if wanted.")
@@ -553,6 +558,7 @@
self.app_module = None
self.flatpak_default_args = []
self.check_available = False
+ self.wpe_extension = None
# Default application to run in the sandbox
self.command = None
@@ -596,7 +602,13 @@
" --debug" if self.debug else " --release")
self.name = "org.webkit.%s" % self.platform
- self.manifest_path = os.path.abspath(os.path.join(scriptdir, '../flatpak/org.webkit.WebKit.yaml'))
+
+ if self.wpe_extension:
+ manifest_filename = WPE_MANIFEST_MAP[self.wpe_extension]
+ else:
+ manifest_filename = "org.webkit.WebKit.yaml"
+ self.manifest_path = os.path.abspath(os.path.join(scriptdir, '../flatpak/') + manifest_filename)
+
self.build_name = self.name + "-generated"
build_root = os.path.join(self.source_root, 'WebKitBuild')
@@ -679,6 +691,9 @@
"--bind-mount=/etc/perl=%s" % os.path.join(self.flatpak_build_path, "files/lib/perl"),
"--bind-mount=/run/host/%s=%s" % (tempfile.gettempdir(), tempfile.gettempdir()),
"--bind-mount=%s=%s" % (self.sandbox_source_root, self.source_root),
+ "--talk-name=org.a11y.Bus",
+ "--talk-name=org.gtk.vfs",
+ "--talk-name=org.gtk.vfs.*",
# We mount WebKitBuild/PORTNAME/BuildType to /app/webkit/WebKitBuild/BuildType
# so we can build WPE and GTK in a same source tree.
"--bind-mount=%s=%s" % (sandbox_build_path, self.build_path)]
@@ -708,6 +723,7 @@
"LANG",
"NUMBER_OF_PROCESSORS",
"CCACHE_PREFIX",
+ "QML2_IMPORT_PATH",
]
if self.use_icecream:
Modified: trunk/Tools/flatpak/org.webkit.CommonModules.yaml (240140 => 240141)
--- trunk/Tools/flatpak/org.webkit.CommonModules.yaml 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Tools/flatpak/org.webkit.CommonModules.yaml 2019-01-18 13:07:38 UTC (rev 240141)
@@ -15,7 +15,7 @@
sources:
- type: git
url: https://github.com/apache/httpd.git
- branch: 2.4.33
+ branch: 2.4.37
- type : file
path : files/httpd-autogen.sh
dest-filename : autogen.sh
@@ -81,6 +81,15 @@
url: https://files.pythonhosted.org/packages/9e/17/1d4ed6e1a4c0918a0357dfa2fdbe26bf63f6e616013c04a14bce9fd33e40/pyaml-17.12.1.tar.gz
sha256: 66623c52f34d83a2c0fc963e08e8b9d0c13d88404e3b43b1852ef71eda19afa3
+- name: python2-subprocess32
+ buildsystem: simple
+ build-commands:
+ - pip2 install --target=/app/lib/python2.7/site-packages/ .
+ sources:
+ - type: archive
+ url: https://files.pythonhosted.org/packages/be/2b/beeba583e9877e64db10b52a96915afc0feabf7144dcbf2a0d0ea68bf73d/subprocess32-3.5.3.tar.gz
+ sha256: 6bc82992316eef3ccff319b5033809801c0c3372709c5f6985299c88ac7225c3
+
# GStreamer modules
- name: libvpx
no-autogen: true
@@ -90,7 +99,7 @@
branch: v1.7.0
config-opts:
- --enable-pic
- - --as=yasm
+ - --as=nasm
- --disable-unit-tests
- --size-limit=16384x16384
- --enable-postproc
@@ -181,6 +190,7 @@
- "--enable-static"
- "--enable-pic"
- "--disable-lavf"
+ - "--disable-asm"
sources:
- type: archive
url: http://download.videolan.org/pub/x264/snapshots/x264-snapshot-20140212-2245-stable.tar.bz2
@@ -205,8 +215,61 @@
path: ../gstreamer/patches/gst-plugins-bad-0002-aomenc-Handle-8-bit_depth-images-with-AOM_IMG_FMT_HI.patch
config-opts:
- -Ddisable_gtkdoc=true
+- name: ffmpeg
+ sources:
+ - type: archive
+ url: https://ffmpeg.org/releases/ffmpeg-3.4.5.tar.gz
+ sha256: 18f80cc9ca322134ed40d25d7489af954fa519b4e7e6289b7084f1b0a1cdf472
+ config-opts:
+ - --enable-static
+ - --enable-pic
+ - --disable-avdevice
+ - --disable-postproc
+ - --disable-swscale
+ - --disable-programs
+ - --disable-ffplay
+ - --disable-ffprobe
+ - --disable-ffmpeg
+ - --disable-encoder=flac
+ - --disable-protocols
+ - --disable-devices
+ - --disable-network
+ - --disable-hwaccels
+ - --disable-dxva2
+ - --disable-vdpau
+ - --disable-filters
+ - --enable-filter=yadif
+ - --disable-doc
+ - --disable-d3d11va
+ - --disable-dxva2
+ - --disable-audiotoolbox
+ - --disable-videotoolbox
+ - --disable-vaapi
+ - --disable-crystalhd
+ - --disable-mediacodec
+ - --disable-nvenc
+ - --disable-mmal
+ - --disable-omx
+ - --disable-omx-rpi
+ - --disable-cuda
+ - --disable-cuvid
+ - --disable-libmfx
+ - --disable-libnpp
+ - --disable-iconv
+ - --disable-jni
+ - --disable-v4l2_m2m
+ - --enable-optimizations
+- name: gst-libav
+ buildsystem: meson
+ builddir: true
+ sources:
+ - type: archive
+ url: https://gstreamer.freedesktop.org/src/gst-libav/gst-libav-1.14.4.tar.xz
+ sha256: dfd78591901df7853eab7e56a86c34a1b03635da0d3d56b89aa577f1897865da
+ config-opts:
+ - -Ddisable_gtkdoc=true
-- name: libgcrypt # Speedup libgrcypt
+- name: libgcrypt # Speedup libgcrypt
sources:
- type: git
url: https://dev.gnupg.org/source/libgcrypt.git
Modified: trunk/Tools/flatpak/org.webkit.WPE.yaml (240140 => 240141)
--- trunk/Tools/flatpak/org.webkit.WPE.yaml 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Tools/flatpak/org.webkit.WPE.yaml 2019-01-18 13:07:38 UTC (rev 240141)
@@ -1,15 +1,4 @@
-- name: libwpe
- buildsystem: cmake-ninja
- sources:
- - type: archive
- url: https://wpewebkit.org/releases/libwpe-1.0.0.tar.xz
- sha256: aff11612123f9ab85a8b9a4bcdfb3a7503eba0a0d2d96f2cdecd30e911091719
-- name: wpebackend-fdo
- buildsystem: cmake-ninja
- sources:
- - type: archive
- url: https://wpewebkit.org/releases/wpebackend-fdo-1.0.0.tar.xz
- sha256: 7a747f87a1ae46d30144369050e3ce348b58986d04e1a139ba75c198fa636729
+- org.webkit.WPEModules.yaml
- name: webkitgtk-test-fonts
no-autogen: true
sources:
Modified: trunk/Tools/flatpak/org.webkit.WPEModules.yaml (240140 => 240141)
--- trunk/Tools/flatpak/org.webkit.WPEModules.yaml 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Tools/flatpak/org.webkit.WPEModules.yaml 2019-01-18 13:07:38 UTC (rev 240141)
@@ -2,11 +2,11 @@
buildsystem: cmake-ninja
sources:
- type: archive
- url: https://wpewebkit.org/releases/libwpe-1.0.0.tar.xz
- sha256: aff11612123f9ab85a8b9a4bcdfb3a7503eba0a0d2d96f2cdecd30e911091719
+ url: https://wpewebkit.org/releases/libwpe-1.1.0.tar.xz
+ sha256: 72e34ad754be11abd1a438cfe195d8d644c52105ab2b1c3b39dec6228bc776ce
- name: wpebackend-fdo
buildsystem: cmake-ninja
sources:
- type: archive
- url: https://wpewebkit.org/releases/wpebackend-fdo-1.0.0.tar.xz
- sha256: 7a747f87a1ae46d30144369050e3ce348b58986d04e1a139ba75c198fa636729
+ url: https://wpewebkit.org/releases/wpebackend-fdo-1.1.0.tar.xz
+ sha256: f6c72130d16e50860cb83eb0f6e109c76f1826d2c6bee39025fb3651941761e7
Copied: trunk/Tools/flatpak/org.webkit.WPEQT.yaml (from rev 240140, trunk/Tools/flatpak/org.webkit.WebKit.yaml) (0 => 240141)
--- trunk/Tools/flatpak/org.webkit.WPEQT.yaml (rev 0)
+++ trunk/Tools/flatpak/org.webkit.WPEQT.yaml 2019-01-18 13:07:38 UTC (rev 240141)
@@ -0,0 +1,39 @@
+app-id: org.webkit.WPEQT
+runtime: org.kde.Platform
+runtime-version: "5.11"
+# Control the exact version of the Sdk/Runtime that is being used.
+sdk-hash: dd9e5d3b3134c24fc191226f058fc78c6bdf1c25fd7be38bea977fcb15307e95
+runtime-hash: 02ede84d3591a5ea8028204d86059bffaccb778159ec53c859bbc60d9e7025e8
+sdk: org.kde.Sdk
+command: %(COMMAND)s
+finish-args:
+ # Basically no sandboxing, the goal here is to make it flexible
+ # for developers, not really to isolate (openning all devices
+ # to allow acces video cameras until we have a portal at least).
+ - --share=ipc
+ - --socket=x11
+ - --socket=wayland
+ - --device=all
+ - --share=network
+ - --socket=pulseaudio
+ - --system-talk-name=org.freedesktop.GeoClue2
+ - --system-talk-name=org.a11y.Bus
+ - --filesystem=host
+ - --socket=system-bus
+ - --talk-name=org.freedesktop.Flatpak
+ - --env=GST_PRESET_PATH=/app/share/gstreamer-1.0/presets/
+build-options:
+ cflags: -O2 -g
+ cxxflags: -O2 -g
+ strip: false
+ no-debuginfo: true
+modules:
+ - org.webkit.CommonModules.yaml
+ - org.webkit.WPEModules.yaml
+
+ # This module is not actually built.
+ - name: org.webkit.WPEQT
+ buildsystem: cmake
+ sources:
+ - type: dir
+ path: /app/webkit/Source/WebKit/UIProcess/API/wpe/qt
Modified: trunk/Tools/flatpak/org.webkit.WebKit.yaml (240140 => 240141)
--- trunk/Tools/flatpak/org.webkit.WebKit.yaml 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Tools/flatpak/org.webkit.WebKit.yaml 2019-01-18 13:07:38 UTC (rev 240141)
@@ -17,6 +17,7 @@
- --share=network
- --socket=pulseaudio
- --system-talk-name=org.freedesktop.GeoClue2
+ - --system-talk-name=org.a11y.Bus
- --filesystem=host
- --socket=system-bus
- --talk-name=org.freedesktop.Flatpak
Modified: trunk/Tools/glib/api_test_runner.py (240140 => 240141)
--- trunk/Tools/glib/api_test_runner.py 2019-01-18 08:07:02 UTC (rev 240140)
+++ trunk/Tools/glib/api_test_runner.py 2019-01-18 13:07:38 UTC (rev 240141)
@@ -17,7 +17,6 @@
# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
-import subprocess
import os
import errno
import sys
@@ -32,6 +31,10 @@
from webkitpy.common.test_expectations import TestExpectations
from webkitpy.common.timeout_context import Timeout
+if os.name == 'posix' and sys.version_info[0] < 3:
+ import subprocess32 as subprocess
+else:
+ import subprocess
class TestRunner(object):
TEST_DIRS = []
@@ -157,6 +160,29 @@
return GLibTestRunner(test_program, timeout, is_slow_test, timeout * 10).run(skipped=self._test_cases_to_skip(test_program), env=self._test_env)
+ def _run_test_qt(self, test_program):
+ env = self._test_env
+ env['XDG_SESSION_TYPE'] = 'wayland'
+ env['QML2_IMPORT_PATH'] = common.library_build_path('qml')
+
+ name = os.path.basename(test_program)
+ try:
+ output = subprocess.check_output([test_program, ], stderr=subprocess.STDOUT,
+ env=env, timeout=self._options.timeout)
+ except subprocess.CalledProcessError, exc:
+ print(exc.output)
+ if exc.returncode > 0:
+ result = "FAIL"
+ elif exc.returncode < 0:
+ result = "CRASH"
+ except subprocess.TimeoutExpired, exp:
+ result = "TIMEOUT"
+ print(exp.output)
+ else:
+ result = "PASS"
+ print("**PASS** %s" % name)
+ return {name: result}
+
def _get_tests_from_google_test_suite(self, test_program):
try:
output = subprocess.check_output([test_program, '--gtest_list_tests'], env=self._test_env)
@@ -222,6 +248,9 @@
def is_google_test(self, test_program):
raise NotImplementedError
+ def is_qt_test(self, test_program):
+ raise NotImplementedError
+
def _run_test(self, test_program):
if self.is_glib_test(test_program):
return self._run_test_glib(test_program)
@@ -229,6 +258,9 @@
if self.is_google_test(test_program):
return self._run_google_test_suite(test_program)
+ if self.is_qt_test(test_program):
+ return self._run_test_qt(test_program)
+
return {}
def run_tests(self):