From 3320515bb4578769dee8b0f0d6ab4ad77284f383 Mon Sep 17 00:00:00 2001
From: Szabolcs David <davidsz@inf.u-szeged.hu>
Date: Tue, 18 Aug 2015 11:31:52 +0200
Subject: [PATCH] Widgets: Add fullscreen support

Change-Id: Ibf1697d2bb3b3af5e7d71149305c5acffba43f0f
Reviewed-by: Szabolcs David <davidsz@inf.u-szeged.hu>
Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
---
 src/core/web_engine_settings.cpp              |  4 +-
 src/core/web_engine_settings.h                |  2 +-
 src/webengine/api/qquickwebengineprofile.cpp  |  2 +-
 src/webengine/api/qquickwebenginesettings.cpp | 12 ++---
 src/webengine/api/qquickwebenginesettings_p.h |  8 +--
 src/webenginewidgets/api/qwebenginepage.cpp   | 19 +++++++
 src/webenginewidgets/api/qwebenginepage.h     |  3 +-
 src/webenginewidgets/api/qwebenginepage_p.h   |  5 +-
 .../api/qwebenginesettings.cpp                |  2 +
 src/webenginewidgets/api/qwebenginesettings.h |  3 +-
 .../qwebenginepage/resources/fullscreen.html  | 10 ++++
 .../qwebenginepage/tst_qwebenginepage.cpp     | 52 +++++++++++++++++++
 .../qwebenginepage/tst_qwebenginepage.qrc     |  3 +-
 13 files changed, 106 insertions(+), 19 deletions(-)
 create mode 100644 tests/auto/widgets/qwebenginepage/resources/fullscreen.html

diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index b59ec7311..19558980b 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -214,7 +214,7 @@ void WebEngineSettings::initDefaults(bool offTheRecord)
     m_attributes.insert(ScrollAnimatorEnabled, false);
     m_attributes.insert(ErrorPageEnabled, true);
     m_attributes.insert(PluginsEnabled, false);
-    m_attributes.insert(FullscreenSupportEnabled, false);
+    m_attributes.insert(FullScreenSupportEnabled, false);
 
     // Default fonts
     QFont defaultFont;
@@ -280,7 +280,7 @@ void WebEngineSettings::applySettingsToWebPreferences(content::WebPreferences *p
     prefs->enable_scroll_animator = testAttribute(ScrollAnimatorEnabled);
     prefs->enable_error_page = testAttribute(ErrorPageEnabled);
     prefs->plugins_enabled = testAttribute(PluginsEnabled);
-    prefs->fullscreen_supported = testAttribute(FullscreenSupportEnabled);
+    prefs->fullscreen_supported = testAttribute(FullScreenSupportEnabled);
 
     // Fonts settings.
     prefs->standard_font_family_map[content::kCommonScript] = toString16(fontFamily(StandardFont));
diff --git a/src/core/web_engine_settings.h b/src/core/web_engine_settings.h
index 1d8f83184..29ef079b7 100644
--- a/src/core/web_engine_settings.h
+++ b/src/core/web_engine_settings.h
@@ -72,7 +72,7 @@ public:
         ScrollAnimatorEnabled,
         ErrorPageEnabled,
         PluginsEnabled,
-        FullscreenSupportEnabled,
+        FullScreenSupportEnabled,
     };
 
     // Must match the values from the public API in qwebenginesettings.h.
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index 38b042fff..027ac3b22 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -58,7 +58,7 @@ QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(BrowserContextAdapt
     m_settings->d_ptr->initDefaults(browserContext->isOffTheRecord());
     // Fullscreen API was implemented before the supported setting, so we must
     // make it default true to avoid change in default API behavior.
-    m_settings->d_ptr->setAttribute(QtWebEngineCore::WebEngineSettings::FullscreenSupportEnabled, true);
+    m_settings->d_ptr->setAttribute(QtWebEngineCore::WebEngineSettings::FullScreenSupportEnabled, true);
 }
 
 QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
diff --git a/src/webengine/api/qquickwebenginesettings.cpp b/src/webengine/api/qquickwebenginesettings.cpp
index 0da01d69d..9662a9ef9 100644
--- a/src/webengine/api/qquickwebenginesettings.cpp
+++ b/src/webengine/api/qquickwebenginesettings.cpp
@@ -228,9 +228,9 @@ bool QQuickWebEngineSettings::pluginsEnabled() const
 
     Enabled by default.
 */
-bool QQuickWebEngineSettings::fullscreenSupportEnabled() const
+bool QQuickWebEngineSettings::fullScreenSupportEnabled() const
 {
-    return d_ptr->testAttribute(WebEngineSettings::FullscreenSupportEnabled);
+    return d_ptr->testAttribute(WebEngineSettings::FullScreenSupportEnabled);
 }
 
 /*!
@@ -345,12 +345,12 @@ void QQuickWebEngineSettings::setPluginsEnabled(bool on)
         Q_EMIT pluginsEnabledChanged();
 }
 
-void QQuickWebEngineSettings::setFullscreenSupportEnabled(bool on)
+void QQuickWebEngineSettings::setFullScreenSupportEnabled(bool on)
 {
-    bool wasOn = d_ptr->testAttribute(WebEngineSettings::FullscreenSupportEnabled);
-    d_ptr->setAttribute(WebEngineSettings::FullscreenSupportEnabled, on);
+    bool wasOn = d_ptr->testAttribute(WebEngineSettings::FullScreenSupportEnabled);
+    d_ptr->setAttribute(WebEngineSettings::FullScreenSupportEnabled, on);
     if (wasOn != on)
-        Q_EMIT fullscreenSupportEnabledChanged();
+        Q_EMIT fullScreenSupportEnabledChanged();
 }
 
 void QQuickWebEngineSettings::setDefaultTextEncoding(QString encoding)
diff --git a/src/webengine/api/qquickwebenginesettings_p.h b/src/webengine/api/qquickwebenginesettings_p.h
index e3f28ac92..604e5693d 100644
--- a/src/webengine/api/qquickwebenginesettings_p.h
+++ b/src/webengine/api/qquickwebenginesettings_p.h
@@ -72,7 +72,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject {
     Q_PROPERTY(bool hyperlinkAuditingEnabled READ hyperlinkAuditingEnabled WRITE setHyperlinkAuditingEnabled NOTIFY hyperlinkAuditingEnabledChanged)
     Q_PROPERTY(bool errorPageEnabled READ errorPageEnabled WRITE setErrorPageEnabled NOTIFY errorPageEnabledChanged)
     Q_PROPERTY(bool pluginsEnabled READ pluginsEnabled WRITE setPluginsEnabled NOTIFY pluginsEnabledChanged)
-    Q_PROPERTY(bool fullscreenSupportEnabled READ fullscreenSupportEnabled WRITE setFullscreenSupportEnabled NOTIFY fullscreenSupportEnabledChanged REVISION 1)
+    Q_PROPERTY(bool fullScreenSupportEnabled READ fullScreenSupportEnabled WRITE setFullScreenSupportEnabled NOTIFY fullScreenSupportEnabledChanged REVISION 1)
     Q_PROPERTY(QString defaultTextEncoding READ defaultTextEncoding WRITE setDefaultTextEncoding NOTIFY defaultTextEncodingChanged)
 
 public:
@@ -90,7 +90,7 @@ public:
     bool hyperlinkAuditingEnabled() const;
     bool errorPageEnabled() const;
     bool pluginsEnabled() const;
-    bool fullscreenSupportEnabled() const;
+    bool fullScreenSupportEnabled() const;
     QString defaultTextEncoding() const;
 
     void setAutoLoadImages(bool on);
@@ -105,7 +105,7 @@ public:
     void setHyperlinkAuditingEnabled(bool on);
     void setErrorPageEnabled(bool on);
     void setPluginsEnabled(bool on);
-    void setFullscreenSupportEnabled(bool on);
+    void setFullScreenSupportEnabled(bool on);
     void setDefaultTextEncoding(QString encoding);
 
 signals:
@@ -121,7 +121,7 @@ signals:
     void hyperlinkAuditingEnabledChanged();
     void errorPageEnabledChanged();
     void pluginsEnabledChanged();
-    Q_REVISION(1) void fullscreenSupportEnabledChanged();
+    Q_REVISION(1) void fullScreenSupportEnabledChanged();
     void defaultTextEncodingChanged();
 
 private:
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index dd96c3890..1cf51df72 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -88,6 +88,7 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
     , isLoading(false)
     , scriptCollection(new QWebEngineScriptCollectionPrivate(browserContextAdapter()->userScriptController(), adapter.data()))
     , m_backgroundColor(Qt::white)
+    , m_fullscreenRequested(false)
 {
     memset(actions, 0, sizeof(actions));
 }
@@ -826,6 +827,18 @@ void QWebEnginePagePrivate::navigationRequested(int navigationType, const QUrl &
     navigationRequestAction = accepted ? WebContentsAdapterClient::AcceptRequest : WebContentsAdapterClient::IgnoreRequest;
 }
 
+void QWebEnginePagePrivate::requestFullScreen(bool fullScreen)
+{
+    Q_Q(QWebEnginePage);
+    m_fullscreenRequested = fullScreen;
+    Q_EMIT q->fullScreenRequested(fullScreen);
+}
+
+bool QWebEnginePagePrivate::isFullScreen() const
+{
+    return m_fullscreenRequested && q_ptr->isFullScreen();
+}
+
 void QWebEnginePagePrivate::javascriptDialog(QSharedPointer<JavaScriptDialogController> controller)
 {
     Q_Q(QWebEnginePage);
@@ -1207,6 +1220,12 @@ bool QWebEnginePage::acceptNavigationRequest(const QUrl &url, NavigationType typ
     return true;
 }
 
+bool QWebEnginePage::isFullScreen()
+{
+    Q_D(const QWebEnginePage);
+    return d->view ? d->view->isFullScreen() : false;
+}
+
 QT_END_NAMESPACE
 
 #include "moc_qwebenginepage.cpp"
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index 1753cd75a..c324f3737 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -236,6 +236,7 @@ Q_SIGNALS:
 
     void linkHovered(const QString &url);
     void selectionChanged();
+    void fullScreenRequested(bool fullScreen);
     void geometryChangeRequested(const QRect& geom);
     void windowCloseRequested();
 
@@ -260,7 +261,7 @@ protected:
     virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID);
     virtual bool certificateError(const QWebEngineCertificateError &certificateError);
     virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame);
-
+    virtual bool isFullScreen();
 private:
     Q_DISABLE_COPY(QWebEnginePage)
     Q_DECLARE_PRIVATE(QWebEnginePage)
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index af37ae82f..84974d6a7 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -97,8 +97,8 @@ public:
     virtual void close() Q_DECL_OVERRIDE;
     virtual bool contextMenuRequested(const QtWebEngineCore::WebEngineContextMenuData &data) Q_DECL_OVERRIDE;
     virtual void navigationRequested(int navigationType, const QUrl &url, int &navigationRequestAction, bool isMainFrame) Q_DECL_OVERRIDE;
-    virtual void requestFullScreen(bool) Q_DECL_OVERRIDE { }
-    virtual bool isFullScreen() const Q_DECL_OVERRIDE { return false; }
+    virtual void requestFullScreen(bool) Q_DECL_OVERRIDE;
+    virtual bool isFullScreen() const Q_DECL_OVERRIDE;
     virtual void javascriptDialog(QSharedPointer<QtWebEngineCore::JavaScriptDialogController>) Q_DECL_OVERRIDE;
     virtual void runFileChooser(QtWebEngineCore::FilePickerController *controller) Q_DECL_OVERRIDE;
     virtual void didRunJavaScript(quint64 requestId, const QVariant& result) Q_DECL_OVERRIDE;
@@ -139,6 +139,7 @@ public:
     bool isLoading;
     QWebEngineScriptCollection scriptCollection;
     QColor m_backgroundColor;
+    bool m_fullscreenRequested;
 
     mutable QtWebEngineCore::CallbackDirectory m_callbacks;
     mutable QAction *actions[QWebEnginePage::WebActionCount];
diff --git a/src/webenginewidgets/api/qwebenginesettings.cpp b/src/webenginewidgets/api/qwebenginesettings.cpp
index aaa93ab9f..1c45095b8 100644
--- a/src/webenginewidgets/api/qwebenginesettings.cpp
+++ b/src/webenginewidgets/api/qwebenginesettings.cpp
@@ -74,6 +74,8 @@ static WebEngineSettings::Attribute toWebEngineAttribute(QWebEngineSettings::Web
         return WebEngineSettings::ErrorPageEnabled;
     case QWebEngineSettings::PluginsEnabled:
         return WebEngineSettings::PluginsEnabled;
+    case QWebEngineSettings::FullScreenSupportEnabled:
+        return WebEngineSettings::FullScreenSupportEnabled;
     default:
         return WebEngineSettings::UnsupportedInCoreSettings;
     }
diff --git a/src/webenginewidgets/api/qwebenginesettings.h b/src/webenginewidgets/api/qwebenginesettings.h
index 50a93e393..327fd447b 100644
--- a/src/webenginewidgets/api/qwebenginesettings.h
+++ b/src/webenginewidgets/api/qwebenginesettings.h
@@ -59,7 +59,8 @@ public:
         HyperlinkAuditingEnabled,
         ScrollAnimatorEnabled,
         ErrorPageEnabled,
-        PluginsEnabled
+        PluginsEnabled,
+        FullScreenSupportEnabled
     };
 
     enum FontSize {
diff --git a/tests/auto/widgets/qwebenginepage/resources/fullscreen.html b/tests/auto/widgets/qwebenginepage/resources/fullscreen.html
new file mode 100644
index 000000000..84771ca85
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/fullscreen.html
@@ -0,0 +1,10 @@
+<html>
+<body onkeypress='onKeyPress()'>
+<a>This is test content</a>
+<script>
+function onKeyPress() {
+    document.documentElement.webkitRequestFullScreen();
+}
+</script>
+</body>
+</html>
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 9562871b3..ae66d928f 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -192,6 +192,7 @@ private Q_SLOTS:
 #endif
 
     void runJavaScript();
+    void fullScreenRequested();
 
 private:
     QWebEngineView* m_view;
@@ -3740,5 +3741,56 @@ void tst_QWebEnginePage::runJavaScript()
     QTest::qWait(100);
 }
 
+class FullScreenPage : public QWebEnginePage {
+    Q_OBJECT
+public:
+    FullScreenPage(QObject* parent = 0)
+        : QWebEnginePage(parent)
+        , m_isFullScreen(true)
+    { }
+
+    void setIsFullScreen(bool b) { m_isFullScreen = b; }
+
+protected:
+    bool isFullScreen() override
+    {
+        return m_isFullScreen;
+    }
+    bool m_isFullScreen;
+};
+
+void tst_QWebEnginePage::fullScreenRequested()
+{
+    FullScreenPage* page = new FullScreenPage;
+    QWebEngineView* view = new QWebEngineView;
+    view->setPage(page);
+    view->show();
+
+    page->settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true);
+
+    QSignalSpy loadSpy(view, SIGNAL(loadFinished(bool)));
+    page->load(QUrl("qrc:///resources/fullscreen.html"));
+    QTRY_COMPARE(loadSpy.count(), 1);
+
+    page->runJavaScript("document.webkitFullscreenEnabled", JavaScriptCallback(true));
+    page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(false));
+
+    // FullscreenRequest must be a user gesture
+    QTest::keyPress(qApp->focusWindow(), Qt::Key_Space);
+    QTest::qWait(100);
+    page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(true));
+    page->runJavaScript("document.webkitExitFullscreen()");
+    QTest::qWait(100);
+    page->setIsFullScreen(false);
+    page->runJavaScript("document.webkitFullscreenEnabled", JavaScriptCallback(true));
+    QTest::keyPress(qApp->focusWindow(), Qt::Key_Space);
+    QTest::qWait(100);
+    page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(false));
+    QTest::qWait(100);
+
+    delete view;
+    delete page;
+}
+
 QTEST_MAIN(tst_QWebEnginePage)
 #include "tst_qwebenginepage.moc"
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
index 994d71b43..0a8995090 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
@@ -1,5 +1,6 @@
 <!DOCTYPE RCC><RCC version="1.0">
 <qresource>
+    <file>resources/content.html</file>
     <file>resources/index.html</file>
     <file>resources/frame_a.html</file>
     <file>resources/frame_c.html</file>
@@ -7,7 +8,7 @@
     <file>resources/iframe2.html</file>
     <file>resources/iframe3.html</file>
     <file>resources/framedindex.html</file>
-    <file>resources/content.html</file>
+    <file>resources/fullscreen.html</file>
     <file>resources/script.html</file>
     <file>resources/user.css</file>
 </qresource>
-- 
GitLab