From 74629398688ee63933c9c6c9d465dd65193cfdf5 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 9 Jan 2025 11:20:48 +0100 Subject: [PATCH] Disable DocumentPictureInPicture API The DocumentPictureInPicture JS API added in Chromium 116 is not implemented in QtWebEngine. This results in createWindow() being called with a window type with random value, which then causes qutebrowser to bail out: Traceback (most recent call last): File ".../qutebrowser/browser/webengine/webview.py", line 123, in createWindow raise ValueError("Invalid wintype {}".format(debug_type)) ValueError: Invalid wintype 843995690 Until this is fixed in Qt, we pass an argument to Chromium to disable the API entirely, so that web pages hopefully fall back to something else. In the case of the new Google Huddle feature, this results in them still working with an on-page overlay instead. Thanks to Joshua Cold and Vivia for helping to debug this! Fixes #8449 See https://bugreports.qt.io/browse/QTBUG-132681 (cherry picked from commit d272804126de00a4a59776aa7b1808abb96ecb0e) --- qutebrowser/config/qtargs.py | 5 +++ .../crashers/document_picture_in_picture.html | 21 ++++++++++++ tests/end2end/features/misc.feature | 7 ++++ tests/unit/config/test_qtargs.py | 33 +++++++++++++++++++ 4 files changed, 66 insertions(+) create mode 100644 tests/end2end/data/crashers/document_picture_in_picture.html diff --git a/qutebrowser/config/qtargs.py b/qutebrowser/config/qtargs.py index cafc6ff38..c35e3fbf6 100644 --- a/qutebrowser/config/qtargs.py +++ b/qutebrowser/config/qtargs.py @@ -154,6 +154,11 @@ def _qtwebengine_features( # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-89740 disabled_features.append('InstalledApp') + if versions.webengine >= utils.VersionNumber(6, 7): + # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-132681 + # TODO adjust if fixed in Qt 6.8.2/.3 or 6.9.0/.1 + disabled_features.append('DocumentPictureInPictureAPI') + if not config.val.input.media_keys: disabled_features.append('HardwareMediaKeyHandling') diff --git a/tests/end2end/data/crashers/document_picture_in_picture.html b/tests/end2end/data/crashers/document_picture_in_picture.html new file mode 100644 index 000000000..94362e991 --- /dev/null +++ b/tests/end2end/data/crashers/document_picture_in_picture.html @@ -0,0 +1,21 @@ + + + + + Document Picture-in-Picture API Crasher + + + + + + + + diff --git a/tests/end2end/features/misc.feature b/tests/end2end/features/misc.feature index 8f5453adc..6825621ea 100644 --- a/tests/end2end/features/misc.feature +++ b/tests/end2end/features/misc.feature @@ -644,3 +644,10 @@ Feature: Various utility commands. And I open data/scroll/simple.html And I run :fake-key "" Then the page should be scrolled vertically + + @qtwebkit_skip + Scenario: Using DocumentPictureInPicture API + When I set content.javascript.can_open_tabs_automatically to true + And I open data/crashers/document_picture_in_picture.html + And I run :click-element id toggle + Then the javascript message "documentPictureInPicture support disabled!" should be logged diff --git a/tests/unit/config/test_qtargs.py b/tests/unit/config/test_qtargs.py index d7a95aad1..ab06aeb76 100644 --- a/tests/unit/config/test_qtargs.py +++ b/tests/unit/config/test_qtargs.py @@ -448,6 +448,39 @@ class TestWebEngineArgs: expected = ['--disable-features=InstalledApp'] if has_workaround else [] assert disable_features_args == expected + @pytest.mark.parametrize('qt_version, has_workaround', [ + # Qt 6.6 + ('6.6.3', False), + # Qt 6.7 + ('6.7.0', True), + ('6.7.1', True), + ('6.7.2', True), + ('6.7.3', True), + # Qt 6.8 + ('6.8.0', True), + ('6.8.1', True), + ('6.8.2', True), # tbd + ('6.8.3', True), # tbd + # Qt 6.9 + ('6.9.0', True), # tbd + ('6.9.1', True), # tbd + ]) + def test_document_pip_workaround( + self, parser, version_patcher, qt_version, has_workaround + ): + version_patcher(qt_version) + + parsed = parser.parse_args([]) + args = qtargs.qt_args(parsed) + disable_features_args = [ + arg for arg in args + if arg.startswith(qtargs._DISABLE_FEATURES) + ] + + flag = "--disable-features=DocumentPictureInPictureAPI" + expected = [flag] if has_workaround else [] + assert disable_features_args == expected + @pytest.mark.parametrize('enabled', [True, False]) def test_media_keys(self, config_stub, parser, enabled): config_stub.val.input.media_keys = enabled