diff --git a/.qmake.conf b/.qmake.conf index a988f0face6e1d7a181f8a7d1b08fdea22d77d12..71d8c7d74d129b58e793bf69ac78495b1148ad80 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,5 +1,3 @@ -QMAKEPATH += $$PWD/tools/qmake - # Resolve root directories for sources QTWEBENGINE_ROOT = $$PWD QTWEBENGINE_OUT_ROOT = $$shadowed($$PWD) diff --git a/tools/qmake/config.tests/alsa/alsa.pro b/config.tests/alsa/alsa.pro similarity index 100% rename from tools/qmake/config.tests/alsa/alsa.pro rename to config.tests/alsa/alsa.pro diff --git a/tools/qmake/config.tests/alsa/alsatest.cpp b/config.tests/alsa/alsatest.cpp similarity index 100% rename from tools/qmake/config.tests/alsa/alsatest.cpp rename to config.tests/alsa/alsatest.cpp diff --git a/tools/qmake/config.tests/khr/khr.cpp b/config.tests/khr/khr.cpp similarity index 100% rename from tools/qmake/config.tests/khr/khr.cpp rename to config.tests/khr/khr.cpp diff --git a/tools/qmake/config.tests/khr/khr.pro b/config.tests/khr/khr.pro similarity index 100% rename from tools/qmake/config.tests/khr/khr.pro rename to config.tests/khr/khr.pro diff --git a/tools/qmake/config.tests/libvpx/libvpx.cpp b/config.tests/libvpx/libvpx.cpp similarity index 100% rename from tools/qmake/config.tests/libvpx/libvpx.cpp rename to config.tests/libvpx/libvpx.cpp diff --git a/tools/qmake/config.tests/libvpx/libvpx.pro b/config.tests/libvpx/libvpx.pro similarity index 100% rename from tools/qmake/config.tests/libvpx/libvpx.pro rename to config.tests/libvpx/libvpx.pro diff --git a/tools/qmake/config.tests/snappy/snappy.cpp b/config.tests/snappy/snappy.cpp similarity index 100% rename from tools/qmake/config.tests/snappy/snappy.cpp rename to config.tests/snappy/snappy.cpp diff --git a/tools/qmake/config.tests/snappy/snappy.pro b/config.tests/snappy/snappy.pro similarity index 100% rename from tools/qmake/config.tests/snappy/snappy.pro rename to config.tests/snappy/snappy.pro diff --git a/tools/qmake/config.tests/srtp/srtp.cpp b/config.tests/srtp/srtp.cpp similarity index 100% rename from tools/qmake/config.tests/srtp/srtp.cpp rename to config.tests/srtp/srtp.cpp diff --git a/tools/qmake/config.tests/srtp/srtp.pro b/config.tests/srtp/srtp.pro similarity index 100% rename from tools/qmake/config.tests/srtp/srtp.pro rename to config.tests/srtp/srtp.pro diff --git a/tools/qmake/config.tests/winversion/winversion.cpp b/config.tests/winversion/winversion.cpp similarity index 100% rename from tools/qmake/config.tests/winversion/winversion.cpp rename to config.tests/winversion/winversion.cpp diff --git a/tools/qmake/config.tests/winversion/winversion.pro b/config.tests/winversion/winversion.pro similarity index 100% rename from tools/qmake/config.tests/winversion/winversion.pro rename to config.tests/winversion/winversion.pro diff --git a/configure.json b/configure.json index 62b56bbb1ab5a63087a6271c3960a5453fcaf900..805ed400124dd4c9c86706db68245c02d0010ab3 100644 --- a/configure.json +++ b/configure.json @@ -4,13 +4,10 @@ "printsupport" ], - "testDir": "tools/qmake/config.tests", - "commandline": { "options": { "alsa": "boolean", "embedded": "boolean", - "optimize-for-size": { "type": "boolean", "name": "optimize_size" }, "ffmpeg": { "type": "enum", "name": "system-ffmpeg", "values": { "system": "yes", "qt": "no" } }, "opus": { "type": "enum", "name": "system-opus", "values": { "system": "yes", "qt": "no" } }, "webp": { "type": "enum", "name": "system-webp", "values": { "system": "yes", "qt": "no" } }, @@ -58,6 +55,11 @@ }, "tests" : { + "python2": { + "label": "Python 2", + "type": "detectPython2", + "log": "location" + }, "ninja": { "label": "system ninja", "type": "detectNinja" @@ -73,6 +75,13 @@ }, "features": { + "python2": { + "label": "Python 2", + "condition": "tests.python2", + "output": [ + { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.python2.location" } + ] + }, "embedded": { "label": "Embedded build", "condition": "config.unix", @@ -80,11 +89,6 @@ "purpose": "Enables the embedded build configuration", "output": [ "privateFeature" ] }, - "optimize_size": { - "label": "Optimize for size", - "autoDetect": "tests.embedded", - "output": [ "privateFeature" ] - }, "alsa": { "label": "ALSA", "condition": "config.unix && libs.alsa", @@ -157,12 +161,19 @@ } }, + "report": [ + { + "type": "warning", + "condition": "!features.python2", + "message": "Python version 2 (2.7.5 or later) is required to build QtWebEngine." + } + ], + "summary": [ { "section": "Qt WebEngine", "entries": [ "embedded", - "optimize_size", "pepper-plugins", "printing-and-pdf", "proprietary-codecs", diff --git a/configure.pri b/configure.pri index 23f31686e8e88f61a2bf55acc4ac40707f5cf873..ce36642bbbf939c73e9e37e3a7e33079eb1431b6 100644 --- a/configure.pri +++ b/configure.pri @@ -1,5 +1,46 @@ equals(QMAKE_HOST.os, Windows): EXE_SUFFIX = .exe +defineTest(isPythonVersionSupported) { + python = $$system_quote($$system_path($$1)) + python_version = $$system('$$python -c "import sys; print(sys.version_info[0:3])"') + python_version ~= s/[()]//g + python_version = $$split(python_version, ',') + python_major_version = $$first(python_version) + greaterThan(python_major_version, 2) { + qtLog("Python version 3 is not supported by Chromium.") + return(false) + } + python_minor_version = $$member(python_version, 1) + python_patch_version = $$member(python_version, 2) + greaterThan(python_major_version, 1): greaterThan(python_minor_version, 6): greaterThan(python_patch_version, 4): return(true) + qtLog("Unsupported python version: $${python_major_version}.$${python_minor_version}.$${python_patch_version}.") + return(false) +} + +defineTest(qtConfTest_detectPython2) { + python = $$qtConfFindInPath("python2") + isEmpty(python) { + qtLog("'python2' not found in PATH. Checking for 'python'.") + python = $$qtConfFindInPath("python$$EXE_SUFFIX") + } + isEmpty(python) { + qtLog("'python$$EXE_SUFFIX' not found in PATH. Giving up.") + return(false) + } + !isPythonVersionSupported($$python) { + qtLog("A suitable Python 2 executable could not be located.") + return(false) + } + + # Make tests.python2.location available in configure.json. + $${1}.location = $$clean_path($$python) + export($${1}.location) + $${1}.cache += location + export($${1}.cache) + + return(true) +} + defineTest(qtConfTest_detectNinja) { ninja = $$qtConfFindInPath("ninja$$EXE_SUFFIX") !isEmpty(ninja) { diff --git a/examples/webengine/quicknanobrowser/ApplicationRoot.qml b/examples/webengine/quicknanobrowser/ApplicationRoot.qml index 6735be932f30e2ebd7ff7ddc645b5614e5dc8f85..78defab802384daadccc347b32d9575c98b9da4b 100644 --- a/examples/webengine/quicknanobrowser/ApplicationRoot.qml +++ b/examples/webengine/quicknanobrowser/ApplicationRoot.qml @@ -70,18 +70,18 @@ QtObject { onClosing: destroy() } function createWindow(profile) { - var newWindow = browserWindowComponent.createObject(root) - newWindow.currentWebView.profile = profile - profile.downloadRequested.connect(newWindow.onDownloadRequested) - return newWindow + var newWindow = browserWindowComponent.createObject(root); + newWindow.currentWebView.profile = profile; + profile.downloadRequested.connect(newWindow.onDownloadRequested); + return newWindow; } function createDialog(profile) { - var newDialog = browserDialogComponent.createObject(root) - newDialog.currentWebView.profile = profile - return newDialog + var newDialog = browserDialogComponent.createObject(root); + newDialog.currentWebView.profile = profile; + return newDialog; } function load(url) { - var browserWindow = createWindow(defaultProfile) - browserWindow.currentWebView.url = url + var browserWindow = createWindow(defaultProfile); + browserWindow.currentWebView.url = url; } } diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml index c008425d98896be94d2ae29704e8c4bff20a3aa8..596e4a76ed532bfd635955d685058293011e47d0 100644 --- a/examples/webengine/quicknanobrowser/BrowserWindow.qml +++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml @@ -48,15 +48,16 @@ ** ****************************************************************************/ +import Qt.labs.settings 1.0 +import QtQml 2.2 import QtQuick 2.2 -import QtWebEngine 1.2 import QtQuick.Controls 1.0 +import QtQuick.Controls.Private 1.0 import QtQuick.Controls.Styles 1.0 +import QtQuick.Dialogs 1.2 import QtQuick.Layouts 1.0 import QtQuick.Window 2.1 -import QtQuick.Controls.Private 1.0 -import QtQuick.Dialogs 1.2 -import Qt.labs.settings 1.0 +import QtWebEngine 1.3 ApplicationWindow { id: browserWindow @@ -79,19 +80,19 @@ ApplicationWindow { Settings { id : appSettings - property alias autoLoadImages: loadImages.checked; - property alias javaScriptEnabled: javaScriptEnabled.checked; - property alias errorPageEnabled: errorPageEnabled.checked; - property alias pluginsEnabled: pluginsEnabled.checked; - property alias fullScreenSupportEnabled: fullScreenSupportEnabled.checked; - property alias autoLoadIconsForPage: autoLoadIconsForPage.checked; - property alias touchIconsEnabled: touchIconsEnabled.checked; + property alias autoLoadImages: loadImages.checked + property alias javaScriptEnabled: javaScriptEnabled.checked + property alias errorPageEnabled: errorPageEnabled.checked + property alias pluginsEnabled: pluginsEnabled.checked + property alias fullScreenSupportEnabled: fullScreenSupportEnabled.checked + property alias autoLoadIconsForPage: autoLoadIconsForPage.checked + property alias touchIconsEnabled: touchIconsEnabled.checked } Action { shortcut: "Ctrl+D" onTriggered: { - downloadView.visible = !downloadView.visible + downloadView.visible = !downloadView.visible; } } Action { @@ -106,14 +107,14 @@ ApplicationWindow { shortcut: StandardKey.Refresh onTriggered: { if (currentWebView) - currentWebView.reload() + currentWebView.reload(); } } Action { shortcut: StandardKey.AddTab onTriggered: { - tabs.createEmptyTab(currentWebView.profile) - tabs.currentIndex = tabs.count - 1 + tabs.createEmptyTab(currentWebView.profile); + tabs.currentIndex = tabs.count - 1; addressBar.forceActiveFocus(); addressBar.selectAll(); } @@ -128,23 +129,23 @@ ApplicationWindow { shortcut: "Escape" onTriggered: { if (currentWebView.state == "FullScreen") { - browserWindow.visibility = browserWindow.previousVisibility - fullScreenNotification.hide() + browserWindow.visibility = browserWindow.previousVisibility; + fullScreenNotification.hide(); currentWebView.triggerWebAction(WebEngineView.ExitFullScreen); } } } Action { shortcut: "Ctrl+0" - onTriggered: currentWebView.zoomFactor = 1.0; + onTriggered: currentWebView.zoomFactor = 1.0 } Action { shortcut: StandardKey.ZoomOut - onTriggered: currentWebView.zoomFactor -= 0.1; + onTriggered: currentWebView.zoomFactor -= 0.1 } Action { shortcut: StandardKey.ZoomIn - onTriggered: currentWebView.zoomFactor += 0.1; + onTriggered: currentWebView.zoomFactor += 0.1 } Action { @@ -187,7 +188,7 @@ ApplicationWindow { toolBar: ToolBar { id: navigationBar RowLayout { - anchors.fill: parent; + anchors.fill: parent ToolButton { enabled: currentWebView && (currentWebView.canGoBack || currentWebView.canGoForward) menu:Menu { @@ -294,7 +295,7 @@ ApplicationWindow { id: httpDiskCacheEnabled text: "HTTP Disk Cache" checkable: !currentWebView.profile.offTheRecord - checked: (currentWebView.profile.httpCacheType == WebEngineProfile.DiskHttpCache) + checked: (currentWebView.profile.httpCacheType === WebEngineProfile.DiskHttpCache) onToggled: currentWebView.profile.httpCacheType = checked ? WebEngineProfile.DiskHttpCache : WebEngineProfile.MemoryHttpCache } MenuItem { @@ -336,12 +337,12 @@ ApplicationWindow { TabView { id: tabs function createEmptyTab(profile) { - var tab = addTab("", tabComponent) + var tab = addTab("", tabComponent); // We must do this first to make sure that tab.active gets set so that tab.item gets instantiated immediately. - tab.active = true - tab.title = Qt.binding(function() { return tab.item.title }) - tab.item.profile = profile - return tab + tab.active = true; + tab.title = Qt.binding(function() { return tab.item.title }); + tab.item.profile = profile; + return tab; } anchors.fill: parent @@ -355,10 +356,10 @@ ApplicationWindow { onLinkHovered: { if (hoveredUrl == "") - resetStatusText.start() + resetStatusText.start(); else { - resetStatusText.stop() - statusText.text = hoveredUrl + resetStatusText.stop(); + statusText.text = hoveredUrl; } } @@ -385,69 +386,69 @@ ApplicationWindow { settings.touchIconsEnabled: appSettings.touchIconsEnabled onCertificateError: { - error.defer() - sslDialog.enqueue(error) + error.defer(); + sslDialog.enqueue(error); } onNewViewRequested: { if (!request.userInitiated) - print("Warning: Blocked a popup window.") + print("Warning: Blocked a popup window."); else if (request.destination == WebEngineView.NewViewInTab) { - var tab = tabs.createEmptyTab(currentWebView.profile) - tabs.currentIndex = tabs.count - 1 - request.openIn(tab.item) + var tab = tabs.createEmptyTab(currentWebView.profile); + tabs.currentIndex = tabs.count - 1; + request.openIn(tab.item); } else if (request.destination == WebEngineView.NewViewInBackgroundTab) { - var tab = tabs.createEmptyTab(currentWebView.profile) - request.openIn(tab.item) + var backgroundTab = tabs.createEmptyTab(currentWebView.profile); + request.openIn(backgroundTab.item); } else if (request.destination == WebEngineView.NewViewInDialog) { - var dialog = applicationRoot.createDialog(currentWebView.profile) - request.openIn(dialog.currentWebView) + var dialog = applicationRoot.createDialog(currentWebView.profile); + request.openIn(dialog.currentWebView); } else { - var window = applicationRoot.createWindow(currentWebView.profile) - request.openIn(window.currentWebView) + var window = applicationRoot.createWindow(currentWebView.profile); + request.openIn(window.currentWebView); } } onFullScreenRequested: { if (request.toggleOn) { - webEngineView.state = "FullScreen" - browserWindow.previousVisibility = browserWindow.visibility - browserWindow.showFullScreen() - fullScreenNotification.show() + webEngineView.state = "FullScreen"; + browserWindow.previousVisibility = browserWindow.visibility; + browserWindow.showFullScreen(); + fullScreenNotification.show(); } else { - webEngineView.state = "" - browserWindow.visibility = browserWindow.previousVisibility - fullScreenNotification.hide() + webEngineView.state = ""; + browserWindow.visibility = browserWindow.previousVisibility; + fullScreenNotification.hide(); } - request.accept() + request.accept(); } onRenderProcessTerminated: { - var status = "" + var status = ""; switch (terminationStatus) { case WebEngineView.NormalTerminationStatus: - status = "(normal exit)" + status = "(normal exit)"; break; case WebEngineView.AbnormalTerminationStatus: - status = "(abnormal exit)" + status = "(abnormal exit)"; break; case WebEngineView.CrashedTerminationStatus: - status = "(crashed)" + status = "(crashed)"; break; case WebEngineView.KilledTerminationStatus: - status = "(killed)" + status = "(killed)"; break; } - print("Render process exited with code " + exitCode + " " + status) - reloadTimer.running = true + print("Render process exited with code " + exitCode + " " + status); + reloadTimer.running = true; } onWindowCloseRequested: { if (tabs.count == 1) - browserWindow.close() + browserWindow.close(); else - tabs.removeTab(tabs.currentIndex) + tabs.removeTab(tabs.currentIndex); } Timer { @@ -473,19 +474,19 @@ ApplicationWindow { "you may not be connected with the host you tried to connect to.\n" + "Do you wish to override the security check and continue?" onYes: { - certErrors.shift().ignoreCertificateError() - presentError() + certErrors.shift().ignoreCertificateError(); + presentError(); } onNo: reject() onRejected: reject() function reject(){ - certErrors.shift().rejectCertificate() - presentError() + certErrors.shift().rejectCertificate(); + presentError(); } function enqueue(error){ - certErrors.push(error) - presentError() + certErrors.push(error); + presentError(); } function presentError(){ visible = certErrors.length > 0 @@ -503,9 +504,9 @@ ApplicationWindow { } function onDownloadRequested(download) { - downloadView.visible = true - downloadView.append(download) - download.accept() + downloadView.visible = true; + downloadView.append(download); + download.accept(); } Rectangle { diff --git a/examples/webengine/quicknanobrowser/DownloadView.qml b/examples/webengine/quicknanobrowser/DownloadView.qml index 13be4bd780b3b7aadeb560bf070f71beb79e27b1..ed28c761c9cb5fa42c1f955705de72365a900f55 100644 --- a/examples/webengine/quicknanobrowser/DownloadView.qml +++ b/examples/webengine/quicknanobrowser/DownloadView.qml @@ -64,8 +64,8 @@ Rectangle { } function append(download) { - downloadModel.append(download) - downloadModel.downloads.push(download) + downloadModel.append(download); + downloadModel.downloads.push(download); } Component { @@ -113,14 +113,14 @@ Rectangle { anchors.right: parent.right iconSource: "icons/process-stop.png" onClicked: { - var download = downloadModel.downloads[index] + var download = downloadModel.downloads[index]; - download.cancel() + download.cancel(); downloadModel.downloads = downloadModel.downloads.filter(function (el) { return el.id !== download.id; }); - downloadModel.remove(index) + downloadModel.remove(index); } } } @@ -167,7 +167,7 @@ Rectangle { text: "OK" anchors.centerIn: parent onClicked: { - downloadView.visible = false + downloadView.visible = false; } } } diff --git a/examples/webengine/quicknanobrowser/FullScreenNotification.qml b/examples/webengine/quicknanobrowser/FullScreenNotification.qml index 80a63d4791f8c2fa54fd05cde04803ccff673823..f0487e868d437d77fff2ef24c93c0155db3e7176 100644 --- a/examples/webengine/quicknanobrowser/FullScreenNotification.qml +++ b/examples/webengine/quicknanobrowser/FullScreenNotification.qml @@ -51,14 +51,14 @@ Rectangle { opacity: 0 function show() { - visible = true - opacity = 1 - reset.start() + visible = true; + opacity = 1; + reset.start(); } function hide() { - reset.stop() - opacity = 0 + reset.stop(); + opacity = 0; } Behavior on opacity { @@ -66,7 +66,7 @@ Rectangle { duration: 750 onStopped: { if (opacity == 0) - visible = false + visible = false; } } } diff --git a/examples/webenginewidgets/markdowneditor/document.h b/examples/webenginewidgets/markdowneditor/document.h index 3c16c251d4d0a47cd8c75f5de34f7d9387129d9a..bc65527314b8bf4d9966e0f1efa98989f40b91e2 100644 --- a/examples/webenginewidgets/markdowneditor/document.h +++ b/examples/webenginewidgets/markdowneditor/document.h @@ -57,7 +57,7 @@ class Document : public QObject { Q_OBJECT - Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged) + Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged FINAL) public: explicit Document(QObject *parent = nullptr) : QObject(parent) {} diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.h b/examples/webenginewidgets/markdowneditor/mainwindow.h index ad032037367b9c0d54e29e986c246e78a91481d1..817f626d80ffb8b168bf168a91400a66bb7dc5fe 100644 --- a/examples/webenginewidgets/markdowneditor/mainwindow.h +++ b/examples/webenginewidgets/markdowneditor/mainwindow.h @@ -67,7 +67,7 @@ class MainWindow : public QMainWindow Q_OBJECT public: - explicit MainWindow(QWidget *parent = 0); + explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); void openFile(const QString &path); diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.cpp b/examples/webenginewidgets/simplebrowser/browserwindow.cpp index c01f912d3ef9506f6b857368c84f1823e932b180..762d56c85766332d0ab7febf20bb787d03f35973 100644 --- a/examples/webenginewidgets/simplebrowser/browserwindow.cpp +++ b/examples/webenginewidgets/simplebrowser/browserwindow.cpp @@ -105,6 +105,13 @@ BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags) m_urlLineEdit->setFavIcon(QIcon(QStringLiteral(":defaulticon.png"))); + QAction *focusUrlLineEditAction = new QAction(this); + addAction(focusUrlLineEditAction); + focusUrlLineEditAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_L)); + connect(focusUrlLineEditAction, &QAction::triggered, this, [this] () { + m_urlLineEdit->setFocus(Qt::ShortcutFocusReason); + }); + handleWebViewTitleChanged(tr("Qt Simple Browser")); m_tabWidget->createTab(); } diff --git a/examples/webenginewidgets/videoplayer/data/index.html b/examples/webenginewidgets/videoplayer/data/index.html new file mode 100644 index 0000000000000000000000000000000000000000..4a1bdc33e36c609cc6f93d456a129afb4d70f365 --- /dev/null +++ b/examples/webenginewidgets/videoplayer/data/index.html @@ -0,0 +1,23 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <style type="text/css"> + #ytplayer { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } + </style> + </head> + <body> + <iframe + id="ytplayer" + src="https://www.youtube.com/embed/CjyjEUFn_FI" + frameborder="0" + allowfullscreen> + </iframe> + </body> +</html> diff --git a/examples/webenginewidgets/videoplayer/data/videoplayer.qrc b/examples/webenginewidgets/videoplayer/data/videoplayer.qrc new file mode 100644 index 0000000000000000000000000000000000000000..c3322b45413f5f7085ea562d67ea20f93ad3849e --- /dev/null +++ b/examples/webenginewidgets/videoplayer/data/videoplayer.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/"> + <file>index.html</file> + </qresource> +</RCC> diff --git a/examples/webenginewidgets/videoplayer/doc/images/videoplayer-example.png b/examples/webenginewidgets/videoplayer/doc/images/videoplayer-example.png new file mode 100644 index 0000000000000000000000000000000000000000..9cf51d84aaa00f8136df365c5edf3c514780c6e9 Binary files /dev/null and b/examples/webenginewidgets/videoplayer/doc/images/videoplayer-example.png differ diff --git a/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc b/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc new file mode 100644 index 0000000000000000000000000000000000000000..599e13e6c14105a5a3f025da6d41833bbac879bf --- /dev/null +++ b/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: http://www.gnu.org/copyleft/fdl.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \example webenginewidgets/videoplayer + \title WebEngine Widgets Video Player Example + \ingroup webengine-widgetexamples + \brief Displays full screen video using \l QWebEngineView + + \image videoplayer-example.png + + \e {Video Player} demonstrates how to support full screen playback of HTML5 + video using \l QWebEngineView. + + \l {https://fullscreen.spec.whatwg.org/}{The Fullscreen API} is a + cross-browser Javascript API that enables a web page to request that one of + its HTML elements be made to occupy the user's entire screen. It is + commonly used for full screen video playback via the \c <video> element, but + can in principle be used to display any HTML content in full screen mode. Qt + WebEngine supports this API, however it is disabled by default. This example + shows the steps needed to switch it on, including: + + \list + \li Enabling it in \l QWebEngineSettings. + \li Handling the \l QWebEnginePage::fullScreenRequested signal by creating + a new full screen window. + \li Displaying a notification popup to ensure that the user is aware + that something is being displayed full screen. + \endlist + + \include examples-run.qdocinc + + \section1 Overview + + Once started, the example program will create a normal (non-fullscreen) + window with a \l QWebEngineView showing an embedded YouTube video player. + You can then click on the full screen toggle button (bottom-right corner) to + enter full screen mode. This should also display a centered notification + overlay informing you that you can exit full screen mode by pressing the + escape key. + + Implementation-wise entering full screen mode entails creating a new full + screen window with a separate \l QWebEngineView instance and migrating the + \l QWebEnginePage from the normal window's \l QWebEngineView to this new \l + QWebEngineView. Exiting full screen mode reverses this migration. + + The example code is divided between three classes, \c MainWindow, \c + FullScreenWindow, and \c FullScreenNotification. The classes \c MainWindow + and \c FullScreenWindow are each responsible for managing one top-level + window, while \c FullScreenNotification is responsible for styling and + animating the notification box. A \c MainWindow is created on startup and + lives for the entire program runtime, while a new \c FullScreenWindow is + created every time full screen mode is entered. + + \section1 MainWindow Class Declaration + + A \c MainWindow is a \l QMainWindow with a \l QWebEngineView as the central + widget: + + \quotefromfile webenginewidgets/videoplayer/mainwindow.h + \skipto #include + \printuntil /^\}/ + + \section1 MainWindow Class Definition + + In the constructor we start by setting up the \l QWebEngineView as the + central widget: + + \quotefromfile webenginewidgets/videoplayer/mainwindow.cpp + \skipto MainWindow::MainWindow + \printuntil setCentralWidget + + We then configure Qt WebEngine to advertise support for the Fullscreen API: + + \printline QWebEngineSettings + + Without this line the full screen toggle button would be disabled (grayed + out) as the Javascript running on the page can detect that our browser + does not support full screen mode. + + Next we connect the \c fullScreenRequested signal to our slot: + + \printuntil &MainWindow::fullScreenRequested + + This signal is emitted whenever the Javascript on the page wants to enter or + exit full screen mode. Without handling this signal (but still keeping the + \c FullScreenSupportEnabled attribute as \c true) the toggle button will be + enabled but clicking on it will have no effect as Javascript's full screen + request will be denied. + + Finally, we load some HTML (see + \l{webenginewidgets/videoplayer/data/index.html}{index.html} included with + the example) into our \l QWebEngineView: + + \printline load + + The second part of \c MainWindow is handling the full screen requests: + + \skipto MainWindow::fullScreenRequested + \printuntil /^\}/ + + We create a new \c FullScreenWindow when entering full screen mode, and + delete it when exiting. + + \section1 FullScreenWindow Class Declaration + + A \c FullScreenWindow is a \l QWidget containing a \l QWebEngineView and a + \c FullScreenNotification. + + \quotefromfile webenginewidgets/videoplayer/fullscreenwindow.h + \skipto #include + \printuntil /^\}/ + + \section1 FullScreenWindow Class Definition + + The constructor is responsible for hiding the normal window (while saving + its geometry) and showing the new \c FullScreenWindow instead: + + \quotefromfile webenginewidgets/videoplayer/fullscreenwindow.cpp + \skipto FullScreenWindow::FullScreenWindow + \printuntil /^\}/ + + The call to \l QWebEngineView::setPage will move the web page from the \c + MainWindow's view to \c FullScreenWindow's view. + + In the destructor we use the same method to move the page back, after which + we restore the main window's geometry and visibility: + + \skipto FullScreenWindow::~FullScreenWindow + \printuntil /^\}/ + + We override \l QWidget::resizeEvent to do manual layout, keeping the \l + QWebEngineView maximized, and the \c FullScreenNotification centered within + the window: + + \skipto FullScreenWindow::resizeEvent + \printuntil /^\}/ + + \section1 FullScreenNotification Class Declaration + + A \c FullScreenNotification is just a \l QLabel with some styling and + animation: + + \quotefromfile webenginewidgets/videoplayer/fullscreennotification.h + \skipto #include + \printuntil /^\}/ + + \section1 FullScreenWindow Class Definition + + In the constructor we configure the QLabel and set up a delayed fade-out + animation using \l {The Animation Framework}: + + \quotefromfile webenginewidgets/videoplayer/fullscreennotification.cpp + \skipto FullScreenNotification::FullScreenNotification + \printuntil /^\}/ + + The custom signal \c shown, which we use to trigger the animation, is + emitted from the \c showEvent method: + + \skipto FullScreenNotification::showEvent + \printuntil /^\}/ +*/ diff --git a/examples/webenginewidgets/videoplayer/fullscreennotification.cpp b/examples/webenginewidgets/videoplayer/fullscreennotification.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e65e2cbad30b120d6f55f6aba7c44ee78859740a --- /dev/null +++ b/examples/webenginewidgets/videoplayer/fullscreennotification.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "fullscreennotification.h" + +#include <QGraphicsOpacityEffect> +#include <QPropertyAnimation> +#include <QSequentialAnimationGroup> + +FullScreenNotification::FullScreenNotification(QWidget *parent) + : QLabel(parent) + , m_previouslyVisible(false) +{ + setText(tr("You are now in full screen mode. Press ESC to quit!")); + setStyleSheet( + "font-size: 24px;" + "color: white;" + "background-color: black;" + "border-color: white;" + "border-width: 2px;" + "border-style: solid;" + "padding: 100px"); + setAttribute(Qt::WA_TransparentForMouseEvents); + + auto effect = new QGraphicsOpacityEffect; + effect->setOpacity(1); + setGraphicsEffect(effect); + + auto animations = new QSequentialAnimationGroup(this); + animations->addPause(3000); + auto opacityAnimation = new QPropertyAnimation(effect, "opacity", animations); + opacityAnimation->setDuration(2000); + opacityAnimation->setStartValue(1.0); + opacityAnimation->setEndValue(0.0); + opacityAnimation->setEasingCurve(QEasingCurve::OutQuad); + animations->addAnimation(opacityAnimation); + + connect(this, &FullScreenNotification::shown, + [animations](){ animations->start(); }); + + connect(animations, &QAbstractAnimation::finished, + [this](){ this->hide(); }); +} + +void FullScreenNotification::showEvent(QShowEvent *event) +{ + QLabel::showEvent(event); + if (!m_previouslyVisible && isVisible()) + emit shown(); + m_previouslyVisible = isVisible(); +} diff --git a/examples/webenginewidgets/videoplayer/fullscreennotification.h b/examples/webenginewidgets/videoplayer/fullscreennotification.h new file mode 100644 index 0000000000000000000000000000000000000000..9f1befb9f9eaabf7f8d4de6f68590fea60d1196c --- /dev/null +++ b/examples/webenginewidgets/videoplayer/fullscreennotification.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef FULLSCREENNOTIFICATION_H +#define FULLSCREENNOTIFICATION_H + +#include <QLabel> + +class FullScreenNotification : public QLabel +{ + Q_OBJECT +public: + FullScreenNotification(QWidget *parent = nullptr); + +protected: + void showEvent(QShowEvent *event) override; + +signals: + void shown(); + +private: + bool m_previouslyVisible; +}; + +#endif // FULLSCREENNOTIFICATION_H diff --git a/examples/webenginewidgets/videoplayer/fullscreenwindow.cpp b/examples/webenginewidgets/videoplayer/fullscreenwindow.cpp new file mode 100644 index 0000000000000000000000000000000000000000..df28839a2e2f438a279ff62781e42caec36a7d2b --- /dev/null +++ b/examples/webenginewidgets/videoplayer/fullscreenwindow.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "fullscreenwindow.h" + +#include "fullscreennotification.h" + +#include <QAction> +#include <QLabel> +#include <QWebEngineView> + +FullScreenWindow::FullScreenWindow(QWebEngineView *oldView, QWidget *parent) + : QWidget(parent) + , m_view(new QWebEngineView(this)) + , m_notification(new FullScreenNotification(this)) + , m_oldView(oldView) + , m_oldGeometry(oldView->window()->geometry()) +{ + m_view->stackUnder(m_notification); + + auto exitAction = new QAction(this); + exitAction->setShortcut(Qt::Key_Escape); + connect(exitAction, &QAction::triggered, [this]() { + m_view->triggerPageAction(QWebEnginePage::ExitFullScreen); + }); + addAction(exitAction); + + m_view->setPage(m_oldView->page()); + setGeometry(m_oldGeometry); + showFullScreen(); + m_oldView->window()->hide(); +} + +FullScreenWindow::~FullScreenWindow() +{ + m_oldView->setPage(m_view->page()); + m_oldView->window()->setGeometry(m_oldGeometry); + m_oldView->window()->show(); + hide(); +} + +void FullScreenWindow::resizeEvent(QResizeEvent *event) +{ + QRect viewGeometry(QPoint(0, 0), size()); + m_view->setGeometry(viewGeometry); + + QRect notificationGeometry(QPoint(0, 0), m_notification->sizeHint()); + notificationGeometry.moveCenter(viewGeometry.center()); + m_notification->setGeometry(notificationGeometry); + + QWidget::resizeEvent(event); +} diff --git a/examples/webenginewidgets/videoplayer/fullscreenwindow.h b/examples/webenginewidgets/videoplayer/fullscreenwindow.h new file mode 100644 index 0000000000000000000000000000000000000000..dda0a9885aaac6c6f23859e6a1fa0408e326d1d6 --- /dev/null +++ b/examples/webenginewidgets/videoplayer/fullscreenwindow.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef FULLSCREENWINDOW_H +#define FULLSCREENWINDOW_H + +#include <QWidget> + +QT_BEGIN_NAMESPACE +class QWebEngineView; +QT_END_NAMESPACE + +class FullScreenNotification; + +class FullScreenWindow : public QWidget +{ + Q_OBJECT +public: + explicit FullScreenWindow(QWebEngineView *oldView, QWidget *parent = nullptr); + ~FullScreenWindow(); + +protected: + void resizeEvent(QResizeEvent *event) override; + +private: + QWebEngineView *m_view; + FullScreenNotification *m_notification; + QWebEngineView *m_oldView; + QRect m_oldGeometry; +}; + +#endif // FULLSCREENWINDOW_H diff --git a/examples/webenginewidgets/videoplayer/main.cpp b/examples/webenginewidgets/videoplayer/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fcddd988e9520223fa6b6d57bc10de104c376f7c --- /dev/null +++ b/examples/webenginewidgets/videoplayer/main.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" +#include <QApplication> + +int main(int argc, char *argv[]) +{ + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication app(argc, argv); + + MainWindow mainWindow; + mainWindow.show(); + + return app.exec(); +} diff --git a/examples/webenginewidgets/videoplayer/mainwindow.cpp b/examples/webenginewidgets/videoplayer/mainwindow.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55885e0c5ba72dd8d32a30b7ff4923ea4acfcb32 --- /dev/null +++ b/examples/webenginewidgets/videoplayer/mainwindow.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "mainwindow.h" + +#include <QWebEngineView> +#include <QWebEngineSettings> +#include <QWebEngineFullScreenRequest> + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent) + , m_view(new QWebEngineView(this)) +{ + setCentralWidget(m_view); + m_view->settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true); + connect(m_view->page(), + &QWebEnginePage::fullScreenRequested, + this, + &MainWindow::fullScreenRequested); + m_view->load(QUrl(QStringLiteral("qrc:/index.html"))); +} + +void MainWindow::fullScreenRequested(QWebEngineFullScreenRequest request) +{ + if (request.toggleOn()) { + if (m_fullScreenWindow) + return; + request.accept(); + m_fullScreenWindow.reset(new FullScreenWindow(m_view)); + } else { + if (!m_fullScreenWindow) + return; + request.accept(); + m_fullScreenWindow.reset(); + } +} diff --git a/examples/webenginewidgets/videoplayer/mainwindow.h b/examples/webenginewidgets/videoplayer/mainwindow.h new file mode 100644 index 0000000000000000000000000000000000000000..a270c6295e65a522c7f5f1a2d0a98b058ab5504f --- /dev/null +++ b/examples/webenginewidgets/videoplayer/mainwindow.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include "fullscreenwindow.h" + +#include <QMainWindow> +#include <QWebEngineView> +#include <QWebEngineFullScreenRequest> + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = nullptr); + +private slots: + void fullScreenRequested(QWebEngineFullScreenRequest request); + +private: + QWebEngineView *m_view; + QScopedPointer<FullScreenWindow> m_fullScreenWindow; +}; + +#endif // MAINWINDOW_H diff --git a/examples/webenginewidgets/videoplayer/videoplayer.pro b/examples/webenginewidgets/videoplayer/videoplayer.pro new file mode 100644 index 0000000000000000000000000000000000000000..ab55992e0fe94d198588aaf329158c676ee2eb22 --- /dev/null +++ b/examples/webenginewidgets/videoplayer/videoplayer.pro @@ -0,0 +1,19 @@ +TEMPLATE = app + +QT += webenginewidgets + +HEADERS += \ + mainwindow.h \ + fullscreenwindow.h \ + fullscreennotification.h + +SOURCES += main.cpp \ + mainwindow.cpp \ + fullscreenwindow.cpp \ + fullscreennotification.cpp + +RESOURCES += \ + data/videoplayer.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/videoplayer +INSTALLS += target diff --git a/examples/webenginewidgets/webenginewidgets.pro b/examples/webenginewidgets/webenginewidgets.pro index 353104d6ac7025bf268bc78d99fce2f401989849..41582bbf7a1642752a3a475750a59f6a686817dd 100644 --- a/examples/webenginewidgets/webenginewidgets.pro +++ b/examples/webenginewidgets/webenginewidgets.pro @@ -6,7 +6,8 @@ SUBDIRS += \ cookiebrowser \ demobrowser \ markdowneditor \ - simplebrowser + simplebrowser \ + videoplayer contains(WEBENGINE_CONFIG, use_spellchecker):!cross_compile { !contains(WEBENGINE_CONFIG, use_native_spellchecker) { diff --git a/tools/qmake/mkspecs/features/configure.prf b/mkspecs/features/configure.prf similarity index 97% rename from tools/qmake/mkspecs/features/configure.prf rename to mkspecs/features/configure.prf index 55a7c45a412c637b30356bb2556ed8dda1ac89b5..9b0be0140097fd08855a465d7061238c906150e8 100644 --- a/tools/qmake/mkspecs/features/configure.prf +++ b/mkspecs/features/configure.prf @@ -11,7 +11,7 @@ defineTest(runConfigure) { # Ignore the cached config tests results in case they were not successful CONFIG += recheck #Override the config.tests path - QMAKE_CONFIG_TESTS_DIR = $$QTWEBENGINE_ROOT/tools/qmake/config.tests + QMAKE_CONFIG_TESTS_DIR = $$QTWEBENGINE_ROOT/config.tests CONFIG_TESTS = $$files($$QMAKE_CONFIG_TESTS_DIR/*.pro, true) log("Running configure tests$${EOL}") for(test, CONFIG_TESTS) { @@ -30,7 +30,6 @@ defineTest(runConfigure) { qtConfig(spellchecker): WEBENGINE_CONFIG += use_spellchecker qtConfig(webrtc): WEBENGINE_CONFIG += use_webrtc qtConfig(embedded): WEBENGINE_CONFIG += embedded_build - qtConfig(optimize_size): WEBENGINE_CONFIG += reduce_binary_size qtConfig(system-webp): WEBENGINE_CONFIG += use_system_libwebp else: WEBENGINE_CONFIG += use_bundled_libwebp qtConfig(system-opus): WEBENGINE_CONFIG += use_system_opus @@ -42,6 +41,9 @@ defineTest(runConfigure) { } isQtMinimum(5, 9) { qtConfig(appstore-compliant): WEBENGINE_CONFIG += use_appstore_compliant_code + optimize_size: WEBENGINE_CONFIG += reduce_binary_size + } else { + qtConfig(embedded): WEBENGINE_CONFIG += reduce_binary_size } linux { diff --git a/tools/qmake/mkspecs/features/default_pre.prf b/mkspecs/features/default_pre.prf similarity index 82% rename from tools/qmake/mkspecs/features/default_pre.prf rename to mkspecs/features/default_pre.prf index 77e437bc9693065f055a04d9d6fa2bad7ade13a5..c7440fa7a2b3846d72c1a19efd62d7712cd46acf 100644 --- a/tools/qmake/mkspecs/features/default_pre.prf +++ b/mkspecs/features/default_pre.prf @@ -1,6 +1,3 @@ -# We depend on libc++ to build chromium so our macosx-version-min has to be 10.7 -QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7 - QTWEBENGINEPROCESS_NAME_RELEASE = QtWebEngineProcess debug_and_release { QTWEBENGINEPROCESS_NAME_DEBUG = $$join(QTWEBENGINEPROCESS_NAME_RELEASE,,,d) diff --git a/tools/qmake/mkspecs/features/functions.prf b/mkspecs/features/functions.prf similarity index 93% rename from tools/qmake/mkspecs/features/functions.prf rename to mkspecs/features/functions.prf index ed113303783c386ce558b85b6f7988233be38993..eb421f8b5f92b426cc4b5f0caac9e999c2b8a6e9 100644 --- a/tools/qmake/mkspecs/features/functions.prf +++ b/mkspecs/features/functions.prf @@ -86,7 +86,6 @@ defineTest(isPlatformSupported) { skipBuild("Static builds of QtWebEngine aren't supported.") return(false) } - !isPythonVersionSupported(): return(false) !isArchSupported(): return(false) isSanitizerEnabled():!isSanitizerSupported():!forceSanitizerBuild(): return(false) return(true) @@ -101,25 +100,6 @@ defineTest(isArchSupported) { return(false) } -defineTest(isPythonVersionSupported) { - python_error_msg = "Python version 2 (2.7.5 or later) is required to build Qt WebEngine." - python_version = $$system('python -c "import sys; print(sys.version_info[0:3])"') - python_version ~= s/[()]//g - python_version = $$split(python_version, ',') - python_major_version = $$first(python_version) - greaterThan(python_major_version, 2) { - skipBuild("Python version 3 is not supported by Chromium.") - skipBuild($$python_error_msg) - return(false) - } - python_minor_version = $$member(python_version, 1) - python_patch_version = $$member(python_version, 2) - greaterThan(python_major_version, 1): greaterThan(python_minor_version, 6): greaterThan(python_patch_version, 4): return(true) - skipBuild("Using Python version $${python_major_version}.$${python_minor_version}.$${python_patch_version}.") - skipBuild($$python_error_msg) - return(false) -} - defineTest(isSanitizerEnabled) { sanitize_address|sanitize_memory|sanitize_undefined|sanitize_thread: return(true) return(false) @@ -358,6 +338,25 @@ defineTest(use?) { return(false) } +# Returns the unquoted path to the python executable. +defineReplace(pythonPath) { + isEmpty(QMAKE_PYTHON2) { + # Fallback for building QtWebEngine with Qt < 5.8 + QMAKE_PYTHON2 = python + } + return($$QMAKE_PYTHON2) +} + +# Returns the python executable for use with shell / make targets. +defineReplace(pythonPathForShell) { + return($$shell_quote($$shell_path($$pythonPath()))) +} + +# Returns the python executable for use with $$system() +defineReplace(pythonPathForSystem) { + return($$system_quote($$system_path($$pythonPath()))) +} + defineReplace(ninjaPath) { src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT") out = $$shadowed($$absolute_path(ninja/ninja, $$src_3rd_party_dir)) diff --git a/tools/qmake/mkspecs/features/gn_generator.prf b/mkspecs/features/gn_generator.prf similarity index 100% rename from tools/qmake/mkspecs/features/gn_generator.prf rename to mkspecs/features/gn_generator.prf diff --git a/qtwebengine.pro b/qtwebengine.pro index b6e7358763c9089a97dfe2982c0f85a0fcb72774..c8f3555e33e7370b7044cbb0dd49c6696ce0b60f 100644 --- a/qtwebengine.pro +++ b/qtwebengine.pro @@ -16,9 +16,9 @@ isPlatformSupported() { OTHER_FILES = \ tools/buildscripts/* \ tools/scripts/* \ - tools/qmake/config.tests/khr/* \ - tools/qmake/config.tests/libcap/* \ - tools/qmake/config.tests/libvpx/* \ - tools/qmake/config.tests/snappy/* \ - tools/qmake/config.tests/srtp/* \ - tools/qmake/mkspecs/features/* + config.tests/khr/* \ + config.tests/libcap/* \ + config.tests/libvpx/* \ + config.tests/snappy/* \ + config.tests/srtp/* \ + mkspecs/features/* diff --git a/src/3rdparty b/src/3rdparty index 853d4069e45b06106f33611c458f5480f71e7c57..898afbbf79637101bbd5e6ab12695ced6a759ae7 160000 --- a/src/3rdparty +++ b/src/3rdparty @@ -1 +1 @@ -Subproject commit 853d4069e45b06106f33611c458f5480f71e7c57 +Subproject commit 898afbbf79637101bbd5e6ab12695ced6a759ae7 diff --git a/src/buildtools/gn.pro b/src/buildtools/gn.pro index 092888e0e59f59d5e0a6479ab484848b431ce9ea..829e7a31af3ac2891df8b205f6d62033e7899ec3 100644 --- a/src/buildtools/gn.pro +++ b/src/buildtools/gn.pro @@ -1,36 +1,30 @@ TEMPLATE = aux -CONFIG += release - option(host_build) -defineReplace(buildGn) { - gn_args = $$1 - out = $$gnPath() - !qtConfig(system-ninja): ninja_path = "--path $$ninjaPath()" - # check if it is not already build - !exists($$out) { - mkpath($$dirname(out)) - src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT") - gn_bootstrap = $$system_path($$absolute_path(chromium/tools/gn/bootstrap/bootstrap.py, $$src_3rd_party_dir)) - gn_args = $$system_quote($$gn_args) - gn_configure = $$system_quote($$gn_bootstrap) --shadow --gn-gen-args=$$gn_args $$ninja_path - !system("cd $$system_quote($$system_path($$dirname(out))) && python $$gn_configure") { - error("GN build error!") - } - } -} +!debug_and_release: CONFIG += release isQtMinimum(5, 8) { include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri) QT_FOR_CONFIG += webengine-private } -!qtConfig(system-gn) { - buildgn.target = build_gn - buildgn.commands = $$buildGn($$gnArgs()) - QMAKE_EXTRA_TARGETS += buildgn - - default_target.target = first - default_target.depends = buildgn - QMAKE_EXTRA_TARGETS += default_target +build_pass|!debug_and_release { + !qtConfig(system-gn): CONFIG(release, debug|release) { + buildgn.target = build_gn + gn_args = $$gnArgs() + out = $$gnPath() + !qtConfig(system-ninja): ninja_path = "--path $$ninjaPath()" + # check if it is not already build + !exists($$out) { + mkpath($$dirname(out)) + src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT") + gn_bootstrap = $$system_path($$absolute_path(chromium/tools/gn/bootstrap/bootstrap.py, $$src_3rd_party_dir)) + gn_args = $$system_quote($$gn_args) + gn_configure = $$system_quote($$gn_bootstrap) --shadow --gn-gen-args=$$gn_args $$ninja_path + !system("cd $$system_quote($$system_path($$dirname(out))) && $$pythonPathForSystem() $$gn_configure") { + error("GN build error!") + } + } + QMAKE_DISTCLEAN += $$out + } } diff --git a/src/buildtools/ninja.pro b/src/buildtools/ninja.pro index c391d6e84f3c7697a2dbcf2da4bc7dbf21a8b805..1b17c6dfa8f417e31fe78bc4e44942adef77999a 100644 --- a/src/buildtools/ninja.pro +++ b/src/buildtools/ninja.pro @@ -1,31 +1,25 @@ TEMPLATE = aux -CONFIG += release -defineReplace(buildNinja) { - out = $$ninjaPath() - # check if it is not already build - !exists($$out) { - mkpath($$dirname(out)) - src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT") - ninja_configure = $$system_quote($$system_path($$absolute_path(ninja/configure.py, $$src_3rd_party_dir))) - !system("cd $$system_quote($$system_path($$dirname(out))) && python $$ninja_configure --bootstrap") { - error("NINJA build error!") - } - } -} +!debug_and_release: CONFIG += release isQtMinimum(5, 8) { include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri) QT_FOR_CONFIG += webengine-private } -!qtConfig(system-ninja) { - buildninja.target = build_ninja - buildninja.commands = $$buildNinja() - QMAKE_EXTRA_TARGETS += buildninja - - default_target.target = first - default_target.depends = buildninja - QMAKE_EXTRA_TARGETS += default_target +build_pass|!debug_and_release { + !qtConfig(system-ninja): CONFIG(release, debug|release) { + out = $$ninjaPath() + # check if it is not already build + !exists($$out) { + mkpath($$dirname(out)) + src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT") + ninja_configure = $$system_quote($$system_path($$absolute_path(ninja/configure.py, $$src_3rd_party_dir))) + !system("cd $$system_quote($$system_path($$dirname(out))) && $$pythonPathForSystem() $$ninja_configure --bootstrap") { + error("NINJA build error!") + } + } + QMAKE_DISTCLEAN += $$out + } } diff --git a/src/core/core.pro b/src/core/core.pro index 91c5044b6eb369fc73467f88b3bc4db237516577..6cc8080e0c6b268c3d886de243ddc610d37bf66a 100644 --- a/src/core/core.pro +++ b/src/core/core.pro @@ -41,7 +41,7 @@ core_api.depends = gn_run # A fake project for qt creator core_project.file = core_project.pro -core_project.depends = core_headers +core_project.depends = gn_run SUBDIRS += \ core_headers \ diff --git a/src/core/core_common.pri b/src/core/core_common.pri index 9c29aea718dffe4158a2625d3db091b8e303a461..370fe4d2a03dc15263e3df9c83ba867630af3614 100644 --- a/src/core/core_common.pri +++ b/src/core/core_common.pri @@ -5,8 +5,4 @@ TARGET = QtWebEngineCore QT += qml quick webchannel QT_PRIVATE += quick-private gui-private core-private webenginecoreheaders-private -# Make QtCreator happy. -CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir() -INCLUDEPATH += $$CHROMIUM_SRC_DIR - qtHaveModule(positioning):QT += positioning diff --git a/src/core/core_module.pro b/src/core/core_module.pro index f4f3fb736240a3ed399bc37ffc4a8d8e529c57a4..44e8ac61354bb816bb00e0711e248e03b22d4386 100644 --- a/src/core/core_module.pro +++ b/src/core/core_module.pro @@ -130,9 +130,6 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat } OTHER_FILES = \ - $$files(../3rdparty/chromium/*.h, true) \ - $$files(../3rdparty/chromium/*.cc, true) \ - $$files(../3rdparty/chromium/*.mm, true) \ $$files(../3rdparty/chromium/*.py, true) \ $$files(../3rdparty/chromium/*.gyp, true) \ $$files(../3rdparty/chromium/*.gypi, true) \ diff --git a/src/core/core_project.pro b/src/core/core_project.pro index 8418ab22b1e8be032db15dbffe2eeaca50e0e394..c046ce1ff5886893e25be39dffbc8bb83fb53fdd 100644 --- a/src/core/core_project.pro +++ b/src/core/core_project.pro @@ -1,3 +1,18 @@ TEMPLATE = lib +# Fake project to make QtCreator happy. -include(core_chromium.pri) +include(core_common.pri) + +linking_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}.pri + +!include($$linking_pri) { + error("Could not find the linking information that gn should have generated.") +} + +CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir() +INCLUDEPATH += $$CHROMIUM_SRC_DIR \ + $$OUT_PWD/$$getConfigDir()/gen + +SOURCES += $$NINJA_SOURCES +HEADERS += $$NINJA_HEADERS +DEFINES += $$NINJA_DEFINES diff --git a/src/core/gn_run.pro b/src/core/gn_run.pro index 07635d04c6d0c0749511c45a3d3054e7fab0fce9..ee4e7892e6efa81fb67706aa4d3a4a54c47850b4 100644 --- a/src/core/gn_run.pro +++ b/src/core/gn_run.pro @@ -5,13 +5,6 @@ isQtMinimum(5, 8) { TEMPLATE = aux -defineReplace(runGn) { - message("Running: $$1") - !system($$1) { - error("GN run error!") - } -} - qtConfig(debug_and_release): CONFIG += debug_and_release build_all qtConfig(system-ninja) { @@ -42,16 +35,22 @@ build_pass|!debug_and_release { gn_args += is_debug=false } - gn_args += "qtwebengine_target=\"$$shell_path($$OUT_PWD/$$getConfigDir()):QtWebEngineCore\"" + gn_args += "qtwebengine_target=\"$$system_path($$OUT_PWD/$$getConfigDir()):QtWebEngineCore\"" !qtConfig(system-gn) { - gn_binary = $$shell_quote($$shell_path($$gnPath())) + gn_binary = $$system_quote($$system_path($$gnPath())) } - gn_args = $$shell_quote($$gn_args) - gn_src_root = $$shell_quote($$shell_path($$QTWEBENGINE_ROOT/$$getChromiumSrcDir())) - gn_build_root = $$shell_quote($$shell_path($$OUT_PWD/$$getConfigDir())) - $$runGn($$gn_binary gen $$gn_build_root --args=$$gn_args --root=$$gn_src_root) + gn_args = $$system_quote($$gn_args) + gn_src_root = $$system_quote($$system_path($$QTWEBENGINE_ROOT/$$getChromiumSrcDir())) + gn_build_root = $$system_quote($$system_path($$OUT_PWD/$$getConfigDir())) + gn_python = "--script-executable=$$pythonPathForSystem()" + gn_run = $$gn_binary gen $$gn_build_root $$gn_python --args=$$gn_args --root=$$gn_src_root + + message("Running: $$gn_run ") + !system($$gn_run) { + error("GN run error!") + } runninja.commands = $$NINJA \$\(NINJAFLAGS\) -C $$gn_build_root QtWebEngineCore QMAKE_EXTRA_TARGETS += runninja diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp index 81f968d115388cd6266fd8a0536df12d1f2abc2e..60622b4ae6fd25368202366dc59df96ca75d7a02 100644 --- a/src/core/web_engine_context.cpp +++ b/src/core/web_engine_context.cpp @@ -91,6 +91,7 @@ #ifndef QT_NO_OPENGL # include <QOpenGLContext> #endif +#include <QQuickWindow> #include <QStringList> #include <QSurfaceFormat> #include <QVector> @@ -157,6 +158,8 @@ bool usingQtQuick2DRenderer() } } + if (device.isEmpty()) + device = QQuickWindow::sceneGraphBackend(); if (device.isEmpty()) device = QString::fromLocal8Bit(qgetenv("QT_QUICK_BACKEND")); if (device.isEmpty()) diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf index fe83b082f076111a4e50806e4dfe758b3e4f2237..bc63addbe56243c6234dec4afe22e099b09b231d 100644 --- a/src/webengine/doc/qtwebengine.qdocconf +++ b/src/webengine/doc/qtwebengine.qdocconf @@ -67,7 +67,7 @@ exampledirs += . \ ../../core/doc/snippets \ ../../webenginewidgets/doc/snippets -examples.fileextensions += *.aff *.dic +examples.fileextensions += *.aff *.dic *.html imagedirs += images diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro index 27239225b6af709e713e403c6cc5e200e5e057bc..5ac93c9a7ee4e491c2d90922ad933954926b6172 100644 --- a/src/webengine/webengine.pro +++ b/src/webengine/webengine.pro @@ -71,9 +71,10 @@ use?(pdf) { } !build_pass { + python = $$pythonPathForShell() chromium_attributions.commands = \ cd $$shell_quote($$shell_path($$PWD/../3rdparty)) && \ - python chromium/tools/licenses.py \ + $$python chromium/tools/licenses.py \ --file-template ../../tools/about_credits.tmpl \ --entry-template ../../tools/about_credits_entry.tmpl credits \ > $$shell_quote($$shell_path($$OUT_PWD/chromium_attributions.qdoc)) diff --git a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml index 677727632f6c18eb97a18c8d84c2efff6f175191..2536f319b983bce46bb7234fd50ba50e847bb8da 100644 --- a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml +++ b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml @@ -143,7 +143,7 @@ TestWebEngineView { keyPress(Qt.Key_B); compareElementValue("combobox", "b"); // Must wait with the second key press to simulate selection of another element - wait(1000); + wait(1100); // blink::typeAheadTimeout + 0.1s keyPress(Qt.Key_C); compareElementValue("combobox", "c"); diff --git a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml index 754a9e018c71e47068904dcf1e19b6cdd89874ab..7a04d5f5b999542f31223774ea2b30a11d37101b 100644 --- a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml +++ b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml @@ -93,7 +93,7 @@ TestWebEngineView { compare(newViewRequest.destination, WebEngineView.NewViewInTab); verify(!newViewRequest.userInitiated); - verify(dialog.webEngineView.waitForLoadSucceeded); + verify(dialog.webEngineView.waitForLoadSucceeded()); compare(dialog.webEngineView.url, ""); newViewRequestedSpy.clear(); dialog.destroy(); @@ -109,7 +109,7 @@ TestWebEngineView { compare(newViewRequest.destination, WebEngineView.NewViewInDialog); verify(!newViewRequest.userInitiated); - verify(dialog.webEngineView.waitForLoadSucceeded); + verify(dialog.webEngineView.waitForLoadSucceeded()); newViewRequestedSpy.clear(); dialog.destroy(); @@ -128,7 +128,7 @@ TestWebEngineView { compare(newViewRequest.destination, WebEngineView.NewViewInDialog); verify(newViewRequest.userInitiated); - verify(dialog.webEngineView.waitForLoadSucceeded); + verify(dialog.webEngineView.waitForLoadSucceeded()); newViewRequestedSpy.clear(); dialog.destroy(); } diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index ce88ace16747f51e07de39d199d31c282b3771ea..32a518ad8e80da99fb122a8ff01f6e3ab7dddcc3 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -1109,7 +1109,7 @@ void tst_QWebEngineView::keyboardEvents() QTest::keyPress(view.focusProxy(), Qt::Key_B); QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('combobox').value").toString(), QStringLiteral("b")); // Must wait with the second key press to simulate selection of another element - QTest::keyPress(view.focusProxy(), Qt::Key_C, Qt::NoModifier, 1000); + QTest::keyPress(view.focusProxy(), Qt::Key_C, Qt::NoModifier, 1100 /* blink::typeAheadTimeout + 0.1s */); QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('combobox').value").toString(), QStringLiteral("c")); // Test the Enter key by loading a page with a hyperlink