summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Negyokru <negyokru@inf.u-szeged.hu>2023-07-31 15:08:09 +0200
committerMartin Negyokru <negyokru@inf.u-szeged.hu>2023-09-28 15:47:27 +0200
commitbd8572420779a916969fc2286e04269616348f71 (patch)
tree626549ab76ab5b36f3d8eb67eaed5083857a9cc1
parentba20f9e892746639ebf888ef2e86add8839c3631 (diff)
Add QWebEngineSettings::ForceDarkMode
Enable forcibly modifying content rendering to result in dark color scheme. [ChangeLog][Settings] ForceDarkMode added, disabled by default. Fixes: QTBUG-84484 Change-Id: I4b3512dc365c61da8f91d8dead0715dadce91f75 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--src/core/api/qwebenginesettings.h1
-rw-r--r--src/core/doc/src/qwebenginesettings_lgpl.qdoc3
-rw-r--r--src/core/web_engine_settings.cpp3
-rw-r--r--src/webenginequick/api/qquickwebenginesettings.cpp21
-rw-r--r--src/webenginequick/api/qquickwebenginesettings_p.h4
-rw-r--r--tests/auto/core/qwebenginesettings/CMakeLists.txt1
-rw-r--r--tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp65
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp2
-rw-r--r--tests/auto/quick/qmltests/data/tst_settings.qml26
9 files changed, 126 insertions, 0 deletions
diff --git a/src/core/api/qwebenginesettings.h b/src/core/api/qwebenginesettings.h
index 7919719a1..0d1ac5295 100644
--- a/src/core/api/qwebenginesettings.h
+++ b/src/core/api/qwebenginesettings.h
@@ -61,6 +61,7 @@ public:
PdfViewerEnabled,
NavigateOnDropEnabled,
ReadingFromCanvasEnabled,
+ ForceDarkMode,
};
enum FontSize {
diff --git a/src/core/doc/src/qwebenginesettings_lgpl.qdoc b/src/core/doc/src/qwebenginesettings_lgpl.qdoc
index 63e9c9710..a6ec8916e 100644
--- a/src/core/doc/src/qwebenginesettings_lgpl.qdoc
+++ b/src/core/doc/src/qwebenginesettings_lgpl.qdoc
@@ -172,6 +172,9 @@
This setting will have impact on all HTML5 canvas elements irrespective of origin, and can be disabled
to prevent canvas fingerprinting.
Enabled by default. (Added in Qt 6.6)
+ \value ForceDarkMode Specifies that all web contents will be rendered using a dark theme.
+ For more information, see \l{https://developer.chrome.com/blog/auto-dark-theme/}{Auto dark theme}.
+ Disabled by default. (Added in Qt 6.7)
*/
/*!
diff --git a/src/core/web_engine_settings.cpp b/src/core/web_engine_settings.cpp
index 23ba7a31a..8b916029e 100644
--- a/src/core/web_engine_settings.cpp
+++ b/src/core/web_engine_settings.cpp
@@ -264,6 +264,8 @@ void WebEngineSettings::initDefaults()
bool noReadingFromCanvas =
commandLine->HasSwitch(switches::kDisableReadingFromCanvas);
s_defaultAttributes.insert(QWebEngineSettings::ReadingFromCanvasEnabled, !noReadingFromCanvas);
+ bool forceDarkMode = commandLine->HasSwitch(switches::kForceDarkMode);
+ s_defaultAttributes.insert(QWebEngineSettings::ForceDarkMode, forceDarkMode);
}
if (s_defaultFontFamilies.isEmpty()) {
@@ -360,6 +362,7 @@ void WebEngineSettings::applySettingsToWebPreferences(blink::web_pref::WebPrefer
prefs->fullscreen_supported = testAttribute(QWebEngineSettings::FullScreenSupportEnabled);
prefs->accelerated_2d_canvas_enabled =
testAttribute(QWebEngineSettings::Accelerated2dCanvasEnabled);
+ prefs->force_dark_mode_enabled = testAttribute(QWebEngineSettings::ForceDarkMode);
prefs->webgl1_enabled = prefs->webgl2_enabled = testAttribute(QWebEngineSettings::WebGLEnabled);
prefs->should_print_backgrounds = testAttribute(QWebEngineSettings::PrintElementBackgrounds);
prefs->allow_running_insecure_content =
diff --git a/src/webenginequick/api/qquickwebenginesettings.cpp b/src/webenginequick/api/qquickwebenginesettings.cpp
index 2686a5774..b185f0b7a 100644
--- a/src/webenginequick/api/qquickwebenginesettings.cpp
+++ b/src/webenginequick/api/qquickwebenginesettings.cpp
@@ -449,6 +449,19 @@ bool QQuickWebEngineSettings::readingFromCanvasEnabled() const
}
/*!
+ \qmlproperty bool WebEngineSettings::forceDarkMode
+ \since QtWebEngine 6.7
+
+ Automatically render all web contents using a dark theme.
+
+ Disabled by default.
+ */
+bool QQuickWebEngineSettings::forceDarkMode() const
+{
+ return d_ptr->testAttribute(QWebEngineSettings::ForceDarkMode);
+}
+
+/*!
\qmlproperty string WebEngineSettings::defaultTextEncoding
\since QtWebEngine 1.2
@@ -739,6 +752,14 @@ void QQuickWebEngineSettings::setReadingFromCanvasEnabled(bool on)
Q_EMIT readingFromCanvasEnabledChanged();
}
+void QQuickWebEngineSettings::setForceDarkMode(bool on)
+{
+ bool wasOn = d_ptr->testAttribute(QWebEngineSettings::ForceDarkMode);
+ d_ptr->setAttribute(QWebEngineSettings::ForceDarkMode, on);
+ if (wasOn != on)
+ Q_EMIT forceDarkModeChanged();
+}
+
void QQuickWebEngineSettings::setUnknownUrlSchemePolicy(QQuickWebEngineSettings::UnknownUrlSchemePolicy policy)
{
QWebEngineSettings::UnknownUrlSchemePolicy oldPolicy = d_ptr->unknownUrlSchemePolicy();
diff --git a/src/webenginequick/api/qquickwebenginesettings_p.h b/src/webenginequick/api/qquickwebenginesettings_p.h
index 53156da02..375f6544a 100644
--- a/src/webenginequick/api/qquickwebenginesettings_p.h
+++ b/src/webenginequick/api/qquickwebenginesettings_p.h
@@ -58,6 +58,7 @@ class Q_WEBENGINEQUICK_PRIVATE_EXPORT QQuickWebEngineSettings : public QObject {
Q_PROPERTY(bool pdfViewerEnabled READ pdfViewerEnabled WRITE setPdfViewerEnabled NOTIFY pdfViewerEnabledChanged REVISION(1,8) FINAL)
Q_PROPERTY(bool navigateOnDropEnabled READ navigateOnDropEnabled WRITE setNavigateOnDropEnabled NOTIFY navigateOnDropEnabledChanged REVISION(6,4) FINAL)
Q_PROPERTY(bool readingFromCanvasEnabled READ readingFromCanvasEnabled WRITE setReadingFromCanvasEnabled NOTIFY readingFromCanvasEnabledChanged REVISION(6,6) FINAL)
+ Q_PROPERTY(bool forceDarkMode READ forceDarkMode WRITE setForceDarkMode NOTIFY forceDarkModeChanged REVISION(6,7) FINAL)
QML_NAMED_ELEMENT(WebEngineSettings)
QML_ADDED_IN_VERSION(1, 1)
QML_EXTRA_VERSION(2, 0)
@@ -106,6 +107,7 @@ public:
bool pdfViewerEnabled() const;
bool navigateOnDropEnabled() const;
bool readingFromCanvasEnabled() const;
+ bool forceDarkMode() const;
void setAutoLoadImages(bool on);
void setJavascriptEnabled(bool on);
@@ -140,6 +142,7 @@ public:
void setPdfViewerEnabled(bool on);
void setNavigateOnDropEnabled(bool on);
void setReadingFromCanvasEnabled(bool on);
+ void setForceDarkMode(bool on);
signals:
void autoLoadImagesChanged();
@@ -175,6 +178,7 @@ signals:
Q_REVISION(1,8) void pdfViewerEnabledChanged();
Q_REVISION(6,4) void navigateOnDropEnabledChanged();
Q_REVISION(6,6) void readingFromCanvasEnabledChanged();
+ Q_REVISION(6,7) void forceDarkModeChanged();
private:
explicit QQuickWebEngineSettings(QQuickWebEngineSettings *parentSettings = nullptr);
diff --git a/tests/auto/core/qwebenginesettings/CMakeLists.txt b/tests/auto/core/qwebenginesettings/CMakeLists.txt
index 44e8f5252..756b99bbb 100644
--- a/tests/auto/core/qwebenginesettings/CMakeLists.txt
+++ b/tests/auto/core/qwebenginesettings/CMakeLists.txt
@@ -8,5 +8,6 @@ qt_internal_add_test(tst_qwebenginesettings
tst_qwebenginesettings.cpp
LIBRARIES
Qt::WebEngineCore
+ Qt::WebEngineWidgets
Test::Util
)
diff --git a/tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp b/tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp
index 14492c728..e856dd094 100644
--- a/tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp
+++ b/tests/auto/core/qwebenginesettings/tst_qwebenginesettings.cpp
@@ -27,6 +27,7 @@
#include <QtGui/qclipboard.h>
#include <QtGui/qguiapplication.h>
+#include <QtWebEngineWidgets/qwebengineview.h>
class tst_QWebEngineSettings: public QObject {
Q_OBJECT
@@ -40,6 +41,8 @@ private Q_SLOTS:
void setInAcceptNavigationRequest();
void disableReadingFromCanvas_data();
void disableReadingFromCanvas();
+ void forceDarkMode();
+ void forceDarkModeMultiView();
};
void tst_QWebEngineSettings::resetAttributes()
@@ -237,6 +240,68 @@ void tst_QWebEngineSettings::disableReadingFromCanvas()
QCOMPARE(evaluateJavaScriptSync(&page, jsCode).toBool(), result);
}
+void tst_QWebEngineSettings::forceDarkMode()
+{
+ QWebEnginePage page;
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
+
+ // based on: https://developer.chrome.com/blog/auto-dark-theme/#detecting-auto-dark-theme
+ page.setHtml("<html><body>"
+ "<div id=\"detection\", style=\"display: none; background-color: canvas; color-scheme: light\"</div>"
+ "</body></html>");
+
+ const QString isAutoDark("(() => {"
+ " const detectionDiv = document.querySelector('#detection');"
+ " return getComputedStyle(detectionDiv).backgroundColor != 'rgb(255, 255, 255)';"
+ "})()");
+
+ QVERIFY(loadFinishedSpy.wait());
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, isAutoDark).toBool(), false);
+ page.settings()->setAttribute(QWebEngineSettings::ForceDarkMode, true);
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, isAutoDark).toBool(), true);
+}
+
+void tst_QWebEngineSettings::forceDarkModeMultiView()
+{
+ QWebEngineView view1;
+ QWebEngineView view2;
+ QWebEnginePage *page1 = view1.page();
+ QWebEnginePage *page2 = view2.page();
+ page1->settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
+ page2->settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
+ view1.resize(300,300);
+ view2.resize(300,300);
+ view1.show();
+ view2.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view1));
+ QVERIFY(QTest::qWaitForWindowExposed(&view2));
+
+ QSignalSpy loadFinishedSpy(page1, SIGNAL(loadFinished(bool)));
+ QSignalSpy loadFinishedSpy2(page2, SIGNAL(loadFinished(bool)));
+ QString html("<html><body>"
+ "<div id=\"detection\", style=\"display: none; background-color: canvas; color-scheme: light\"</div>"
+ "</body></html>");
+
+ const QString isAutoDark("(() => {"
+ " const detectionDiv = document.querySelector('#detection');"
+ " return getComputedStyle(detectionDiv).backgroundColor != 'rgb(255, 255, 255)';"
+ "})()");
+
+ view1.setHtml(html);
+ QVERIFY(loadFinishedSpy.wait());
+ view2.setHtml(html);
+ QVERIFY(loadFinishedSpy2.wait());
+
+ // both views has light color-scheme
+ QTRY_COMPARE(evaluateJavaScriptSync(page1, isAutoDark).toBool(), false);
+ QTRY_COMPARE(evaluateJavaScriptSync(page2, isAutoDark).toBool(), false);
+ view1.settings()->setAttribute(QWebEngineSettings::ForceDarkMode, true);
+ // dark mode should apply only for view1
+ QTRY_COMPARE(evaluateJavaScriptSync(page1, isAutoDark).toBool(), true);
+ QTRY_COMPARE(evaluateJavaScriptSync(page2, isAutoDark).toBool(), false);
+}
+
QTEST_MAIN(tst_QWebEngineSettings)
#include "tst_qwebenginesettings.moc"
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 581a77673..f97ceca69 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -401,6 +401,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineSettings.dnsPrefetchEnabledChanged() --> void"
<< "QQuickWebEngineSettings.errorPageEnabled --> bool"
<< "QQuickWebEngineSettings.errorPageEnabledChanged() --> void"
+ << "QQuickWebEngineSettings.forceDarkMode --> bool"
+ << "QQuickWebEngineSettings.forceDarkModeChanged() --> void"
<< "QQuickWebEngineSettings.focusOnNavigationEnabled --> bool"
<< "QQuickWebEngineSettings.focusOnNavigationEnabledChanged() --> void"
<< "QQuickWebEngineSettings.fullScreenSupportEnabled --> bool"
diff --git a/tests/auto/quick/qmltests/data/tst_settings.qml b/tests/auto/quick/qmltests/data/tst_settings.qml
index 6b351a293..f47674aa7 100644
--- a/tests/auto/quick/qmltests/data/tst_settings.qml
+++ b/tests/auto/quick/qmltests/data/tst_settings.qml
@@ -114,6 +114,32 @@ TestWebEngineView {
});
tryVerify(function() { return isDataRead === data.result });
}
+
+ function test_forceDarkMode() {
+ // based on: https://developer.chrome.com/blog/auto-dark-theme/#detecting-auto-dark-theme
+ webEngineView.loadHtml("<html><body>" +
+ "<div id=\"detection\", style=\"display: none; background-color: canvas; color-scheme: light\"</div>" +
+ "</body></html>");
+ const script = "(() => {"
+ + " const detectionDiv = document.querySelector('#detection');"
+ + " return getComputedStyle(detectionDiv).backgroundColor != 'rgb(255, 255, 255)';"
+ + "})()";
+ verify(webEngineView.waitForLoadSucceeded());
+
+ var isAutoDark = true;
+ runJavaScript(script, result => isAutoDark = result);
+ tryVerify(() => {return !isAutoDark});
+
+ webEngineView.settings.forceDarkMode = true;
+ verify(webEngineView.settings.forceDarkMode == true)
+
+ isAutoDark = false;
+ // the page is not updated immediately
+ tryVerify(function() {
+ runJavaScript(script, result => isAutoDark = result);
+ return isAutoDark;
+ });
+ }
}
}