From 431b2c163377cb9998c81b237cc241f01e001755 Mon Sep 17 00:00:00 2001 From: bosshogg Date: Fri, 11 Oct 2024 22:23:30 +0200 Subject: [PATCH 01/69] Fix zero division bug in tab-move + Do the modulo by 1 incase self._count() is 0 or negative --- qutebrowser/browser/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 32533709c..8853c7dbf 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -1048,7 +1048,7 @@ class CommandDispatcher: new_idx += delta if config.val.tabs.wrap: - new_idx %= self._count() + new_idx %= max(1, self._count()) else: # pylint: disable=else-if-used # absolute moving From de5fbf711d8f2e965684773dc41ee49bf7832535 Mon Sep 17 00:00:00 2001 From: bosshogg Date: Sun, 13 Oct 2024 22:40:18 +0200 Subject: [PATCH 02/69] Raise CommandError if there are no tabs or widgets Show the user "No WebView avaible" when tryin to do an action on tabs or widgets that don't exist. --- qutebrowser/browser/commands.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 8853c7dbf..49b64df78 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -59,7 +59,10 @@ class CommandDispatcher: def _count(self) -> int: """Convenience method to get the widget count.""" - return self._tabbed_browser.widget.count() + count = self._tabbed_browser.widget.count() + if count <= 0: + raise cmdutils.CommandError("No WebView available yet!") + return count def _set_current_index(self, idx): """Convenience method to set the current widget index.""" @@ -68,7 +71,10 @@ class CommandDispatcher: def _current_index(self): """Convenience method to get the current widget index.""" - return self._tabbed_browser.widget.currentIndex() + current_index = self._tabbed_browser.widget.currentIndex() + if current_index <= 0: + raise cmdutils.CommandError("No WebView available yet!") + return current_index def _current_url(self): """Convenience method to get the current url.""" @@ -1048,7 +1054,7 @@ class CommandDispatcher: new_idx += delta if config.val.tabs.wrap: - new_idx %= max(1, self._count()) + new_idx %= self._count() else: # pylint: disable=else-if-used # absolute moving From 9fc6ea04345ade79177ca71613398c7bcbb97fc6 Mon Sep 17 00:00:00 2001 From: bosshogg Date: Wed, 16 Oct 2024 17:13:01 +0200 Subject: [PATCH 03/69] Fix checks failing on first tab --- qutebrowser/browser/commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 49b64df78..5f5b56512 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -60,7 +60,7 @@ class CommandDispatcher: def _count(self) -> int: """Convenience method to get the widget count.""" count = self._tabbed_browser.widget.count() - if count <= 0: + if count < 0: raise cmdutils.CommandError("No WebView available yet!") return count @@ -72,7 +72,7 @@ class CommandDispatcher: def _current_index(self): """Convenience method to get the current widget index.""" current_index = self._tabbed_browser.widget.currentIndex() - if current_index <= 0: + if current_index < 0: raise cmdutils.CommandError("No WebView available yet!") return current_index From 5691e04afc84f19e575faafafdbfe0d61d861d5b Mon Sep 17 00:00:00 2001 From: bosshogg Date: Wed, 16 Oct 2024 17:20:08 +0200 Subject: [PATCH 04/69] Remove duplicate checking of widget existence _run_userscript handles the case different than _current_index() --- qutebrowser/browser/commands.py | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 5f5b56512..520f8274b 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -868,10 +868,6 @@ class CommandDispatcher: Args: count: How many tabs to switch back. """ - if self._count() == 0: - # Running :tab-prev after last tab was closed - # See https://github.com/qutebrowser/qutebrowser/issues/1448 - return newidx = self._current_index() - count if newidx >= 0: self._set_current_index(newidx) @@ -888,10 +884,6 @@ class CommandDispatcher: Args: count: How many tabs to switch forward. """ - if self._count() == 0: - # Running :tab-next after last tab was closed - # See https://github.com/qutebrowser/qutebrowser/issues/1448 - return newidx = self._current_index() + count if newidx < self._count(): self._set_current_index(newidx) @@ -1172,7 +1164,7 @@ class CommandDispatcher: if count is not None: env['QUTE_COUNT'] = str(count) - idx = self._current_index() + idx = self._tabbed_browser.widget.currentIndex() if idx != -1: env['QUTE_TAB_INDEX'] = str(idx + 1) env['QUTE_TITLE'] = self._tabbed_browser.widget.page_title(idx) From 85435c7574b02109195a3d80db6c6a4feddea6f6 Mon Sep 17 00:00:00 2001 From: bosshogg Date: Wed, 16 Oct 2024 18:40:44 +0200 Subject: [PATCH 05/69] Revert change to _count Adds a specific check for only -1 in _current_index --- qutebrowser/browser/commands.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 520f8274b..bc7201107 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -59,10 +59,7 @@ class CommandDispatcher: def _count(self) -> int: """Convenience method to get the widget count.""" - count = self._tabbed_browser.widget.count() - if count < 0: - raise cmdutils.CommandError("No WebView available yet!") - return count + return self._tabbed_browser.widget.count() def _set_current_index(self, idx): """Convenience method to set the current widget index.""" @@ -72,7 +69,7 @@ class CommandDispatcher: def _current_index(self): """Convenience method to get the current widget index.""" current_index = self._tabbed_browser.widget.currentIndex() - if current_index < 0: + if current_index == -1: raise cmdutils.CommandError("No WebView available yet!") return current_index From 58dec07d2739f2375208e698caa81257cf12ee81 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 17 Oct 2024 10:01:10 +0200 Subject: [PATCH 06/69] Tests: Catch error with :tab-next/:tab-prev and no tabs Ref #1448 --- tests/end2end/features/tabs.feature | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/end2end/features/tabs.feature b/tests/end2end/features/tabs.feature index 942ee2028..ecb3e0d5d 100644 --- a/tests/end2end/features/tabs.feature +++ b/tests/end2end/features/tabs.feature @@ -1469,14 +1469,16 @@ Feature: Tab management When I set tabs.last_close to close And I run :tab-only And I run :tab-close ;; tab-next - Then qutebrowser should quit + Then the error "No WebView available yet!" should be shown + And qutebrowser should quit And no crash should happen Scenario: Using :tab-prev after closing last tab (#1448) When I set tabs.last_close to close And I run :tab-only And I run :tab-close ;; tab-prev - Then qutebrowser should quit + Then the error "No WebView available yet!" should be shown + And qutebrowser should quit And no crash should happen Scenario: Opening link with tabs_are_windows set (#2162) From d49c96aa29ad1b602d56f8b0d68d390b734c8f0d Mon Sep 17 00:00:00 2001 From: dezeroku Date: Sun, 16 Mar 2025 16:47:08 +0100 Subject: [PATCH 07/69] userscripts: fix qute-bitwarden failing with expired session This could be seen as "Vault is locked" error in the logs, if run with the --nointeraction flag --- misc/userscripts/qute-bitwarden | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/misc/userscripts/qute-bitwarden b/misc/userscripts/qute-bitwarden index ad17ec08f..4e883a52e 100755 --- a/misc/userscripts/qute-bitwarden +++ b/misc/userscripts/qute-bitwarden @@ -133,7 +133,7 @@ def get_session_key(auto_lock, password_prompt_invocation): def pass_(domain, encoding, auto_lock, password_prompt_invocation): session_key = get_session_key(auto_lock, password_prompt_invocation) process = subprocess.run( - ['bw', 'list', 'items', '--session', session_key, '--url', domain], + ['bw', 'list', 'items', '--nointeraction', '--session', session_key, '--url', domain], capture_output=True, ) @@ -142,6 +142,10 @@ def pass_(domain, encoding, auto_lock, password_prompt_invocation): msg = 'Bitwarden CLI returned for {:s} - {:s}'.format(domain, err) stderr(msg) + if "Vault is locked" in err: + stderr("Bitwarden Vault got locked, trying again with clean session") + return pass_(domain, encoding, 0, password_prompt_invocation) + if process.returncode: return '[]' @@ -153,7 +157,7 @@ def pass_(domain, encoding, auto_lock, password_prompt_invocation): def get_totp_code(selection_id, domain_name, encoding, auto_lock, password_prompt_invocation): session_key = get_session_key(auto_lock, password_prompt_invocation) process = subprocess.run( - ['bw', 'get', 'totp', '--session', session_key, selection_id], + ['bw', 'get', 'totp', '--nointeraction', '--session', session_key, selection_id], capture_output=True, ) @@ -163,6 +167,10 @@ def get_totp_code(selection_id, domain_name, encoding, auto_lock, password_promp msg = 'Bitwarden CLI returned for {:s} - {:s}'.format(domain_name, err) stderr(msg) + if "Vault is locked" in err: + stderr("Bitwarden Vault got locked, trying again with clean session") + return get_totp_code(selection_id, domain_name, encoding, 0, password_prompt_invocation) + if process.returncode: return '[]' From cc20112a67eef0f67f02d34e25c9de87665149c2 Mon Sep 17 00:00:00 2001 From: qutebrowser bot Date: Mon, 17 Mar 2025 04:20:14 +0000 Subject: [PATCH 08/69] Update dependencies --- misc/requirements/requirements-dev.txt | 2 +- misc/requirements/requirements-flake8.txt | 2 +- misc/requirements/requirements-pyroma.txt | 2 +- misc/requirements/requirements-tests.txt | 8 ++++---- misc/requirements/requirements-tox.txt | 2 +- misc/requirements/requirements-yamllint.txt | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt index fc290a9f6..c05ec95d1 100644 --- a/misc/requirements/requirements-dev.txt +++ b/misc/requirements/requirements-dev.txt @@ -1,7 +1,7 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py annotated-types==0.7.0 -anyio==4.8.0 +anyio==4.9.0 autocommand==2.2.2 backports.tarfile==1.2.0 bracex==2.5.post1 diff --git a/misc/requirements/requirements-flake8.txt b/misc/requirements/requirements-flake8.txt index 5f41db35f..2e4c9e89d 100644 --- a/misc/requirements/requirements-flake8.txt +++ b/misc/requirements/requirements-flake8.txt @@ -1,6 +1,6 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py -attrs==25.1.0 +attrs==25.3.0 flake8==7.1.2 flake8-bugbear==24.12.12 flake8-builtins==2.5.0 diff --git a/misc/requirements/requirements-pyroma.txt b/misc/requirements/requirements-pyroma.txt index 7224c4cd5..f1d899891 100644 --- a/misc/requirements/requirements-pyroma.txt +++ b/misc/requirements/requirements-pyroma.txt @@ -12,6 +12,6 @@ pyproject_hooks==1.2.0 pyroma==4.2 requests==2.32.3 tomli==2.2.1 -trove-classifiers==2025.3.3.18 +trove-classifiers==2025.3.13.13 urllib3==2.3.0 zipp==3.21.0 diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt index 7646a5970..831fb440b 100644 --- a/misc/requirements/requirements-tests.txt +++ b/misc/requirements/requirements-tests.txt @@ -1,6 +1,6 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py -attrs==25.1.0 +attrs==25.3.0 autocommand==2.2.2 backports.tarfile==1.2.0 beautifulsoup4==4.13.3 @@ -9,14 +9,14 @@ certifi==2025.1.31 charset-normalizer==3.4.1 cheroot==10.0.1 click==8.1.8 -coverage==7.6.12 +coverage==7.7.0 exceptiongroup==1.2.2 execnet==2.1.1 -filelock==3.17.0 +filelock==3.18.0 Flask==3.1.0 gherkin-official==29.0.0 hunter==3.7.0 -hypothesis==6.128.1 +hypothesis==6.129.3 idna==3.10 importlib_metadata==8.6.1 importlib_resources==6.5.2 diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt index 169109940..06cadb159 100644 --- a/misc/requirements/requirements-tox.txt +++ b/misc/requirements/requirements-tox.txt @@ -4,7 +4,7 @@ cachetools==5.5.2 chardet==5.2.0 colorama==0.4.6 distlib==0.3.9 -filelock==3.17.0 +filelock==3.18.0 packaging==24.2 pip==25.0.1 platformdirs==4.3.6 diff --git a/misc/requirements/requirements-yamllint.txt b/misc/requirements/requirements-yamllint.txt index a501b1d56..a2cb3579c 100644 --- a/misc/requirements/requirements-yamllint.txt +++ b/misc/requirements/requirements-yamllint.txt @@ -2,4 +2,4 @@ pathspec==0.12.1 PyYAML==6.0.2 -yamllint==1.35.1 +yamllint==1.36.1 From 18db4cc9375ca6939e71a30e431cc2eed6149ea4 Mon Sep 17 00:00:00 2001 From: toofar Date: Wed, 19 Mar 2025 20:24:10 +1300 Subject: [PATCH 09/69] changelog entries for bitwarden userscript Will it be cherry picked to the release branch? Should I have made a new section for the 3.5.0 release? We'll see! --- doc/changelog.asciidoc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index ded12a6b9..8b87b0651 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -25,6 +25,10 @@ Changed - The `content.headers.user_agent` setting now has a new `{upstream_browser_version_short}` template field, which is the upstream/Chromium version but shortened to only major version. +- Changed features in userscripts: + * `qute-bitwarden` now passes your password to the subprocess in an + environment variable when unlocking your vault, instead of as a command + line argument. (#7781) Fixed ~~~~~ @@ -36,6 +40,9 @@ Fixed error is shown instead). - The default user agent now only contains the shortened Chromium version number, which fixes overzealous blocking on ScienceDirect. +- Resolved issues in userscripts: + * `qute-bitwarden` will now prompt a re-login if its cached session has + been invalidated since last used. (#8456) [[v3.4.0]] v3.4.0 (2024-12-14) From 939e0fa81786d46a654d4857481c1e36b82fdecc Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 17 Mar 2025 08:25:15 +0100 Subject: [PATCH 10/69] Adjust Slack UA quirk See #8510 --- .../browser/webengine/webenginesettings.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/qutebrowser/browser/webengine/webenginesettings.py b/qutebrowser/browser/webengine/webenginesettings.py index 721360f46..a5c45d5cf 100644 --- a/qutebrowser/browser/webengine/webenginesettings.py +++ b/qutebrowser/browser/webengine/webenginesettings.py @@ -528,9 +528,19 @@ def _init_site_specific_quirks(): # Needed because Slack adds an error which prevents using it relatively # aggressively, despite things actually working fine. - # October 2023: Slack claims they only support 112+. On #7951 at least - # one user claims it still works fine on 108 based Qt versions. - ("ua-slack", 'https://*.slack.com/*', maybe_newer_chrome_ua(112)), + # + # March 2025 situation: + # - https://slack.com/help/articles/1500001836081-Slack-support-lifecycle-for-operating-systems-app-versions-and-browsers + # claims that Chrome 123 is needed + # - Qt 6.9 (130 based) works fine and doesn't display any banner, but is + # not released yet. + # - Qt 6.8 (122 based) displays a "This browser won’t be supported + # starting March 15th, 2025" banner on March 17th, but works just fine + # with the default UA still... + # - With the default UA, Qt 6.7 (118 based) breaks. + # - With the workaround, Qt 6.4 (102 based) still seems to work perfectly fine, + # while Qt 6.3 (94 based) works fine but has some styling issues. + ("ua-slack", 'https://*.slack.com/*', maybe_newer_chrome_ua(123)), ] for name, pattern, ua in user_agents: From b43c79989e1e646204e845d1453b4cdd3d5263a0 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 21 Mar 2025 10:33:18 +0100 Subject: [PATCH 11/69] pdfjs: Add new no-system-pdfjs debug flag This can be used to easily test a different PDF.js version manually (which is installed via update_3rdparty.py), without having to uninstall the system-wide one first. --- qutebrowser/browser/pdfjs.py | 8 +++++++- qutebrowser/qutebrowser.py | 4 +++- tests/unit/browser/test_pdfjs.py | 31 +++++++++++++++++++++++-------- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/qutebrowser/browser/pdfjs.py b/qutebrowser/browser/pdfjs.py index 78982d98d..e999a503e 100644 --- a/qutebrowser/browser/pdfjs.py +++ b/qutebrowser/browser/pdfjs.py @@ -11,6 +11,7 @@ from qutebrowser.qt.core import QUrl, QUrlQuery from qutebrowser.utils import resources, javascript, jinja, standarddir, log, urlutils from qutebrowser.config import config +from qutebrowser.misc import objects _SYSTEM_PATHS = [ @@ -127,7 +128,12 @@ def get_pdfjs_res_and_path(path): content = None file_path = None - system_paths = _SYSTEM_PATHS + [ + if 'no-system-pdfjs' in objects.debug_flags: + system_paths = [] + else: + system_paths = _SYSTEM_PATHS[:] + + system_paths += [ # fallback os.path.join(standarddir.data(), 'pdfjs'), # hardcoded fallback for --temp-basedir diff --git a/qutebrowser/qutebrowser.py b/qutebrowser/qutebrowser.py index e68156759..044a6cceb 100644 --- a/qutebrowser/qutebrowser.py +++ b/qutebrowser/qutebrowser.py @@ -172,12 +172,14 @@ def debug_flag_error(flag): werror: Turn Python warnings into errors. test-notification-service: Use the testing libnotify service. caret: Enable debug logging for caret.js. + no-system-pdfjs: Ignore system-wide PDF.js installations """ valid_flags = ['debug-exit', 'pdb-postmortem', 'no-sql-history', 'no-scroll-filtering', 'log-requests', 'log-cookies', 'log-scroll-pos', 'log-sensitive-keys', 'stack', 'chromium', 'wait-renderer-process', 'avoid-chromium-init', 'werror', - 'test-notification-service', 'log-qt-events', 'caret'] + 'test-notification-service', 'log-qt-events', 'caret', + 'no-system-pdfjs'] if flag in valid_flags: return flag diff --git a/tests/unit/browser/test_pdfjs.py b/tests/unit/browser/test_pdfjs.py index 867e8e1de..b13e5b356 100644 --- a/tests/unit/browser/test_pdfjs.py +++ b/tests/unit/browser/test_pdfjs.py @@ -3,6 +3,8 @@ # SPDX-License-Identifier: GPL-3.0-or-later import logging +import pathlib +import unittest.mock import os.path import pytest @@ -10,6 +12,7 @@ from qutebrowser.qt.core import QUrl from qutebrowser.browser import pdfjs from qutebrowser.utils import urlmatch, utils +from qutebrowser.misc import objects pytestmark = [pytest.mark.usefixtures('data_tmpdir')] @@ -73,20 +76,32 @@ class TestResources: read_system_mock.assert_called_with('/usr/share/pdf.js/', ['web/test', 'test']) - def test_get_pdfjs_res_bundled(self, read_system_mock, read_file_mock, - tmpdir): + @pytest.mark.parametrize("with_system", [True, False]) + def test_get_pdfjs_res_bundled( + self, + read_system_mock: unittest.mock.Mock, + read_file_mock: unittest.mock.Mock, + tmp_path: pathlib.Path, + monkeypatch: pytest.MonkeyPatch, + with_system: bool, + ) -> None: read_system_mock.return_value = (None, None) - read_file_mock.return_value = b'content' + if not with_system: + monkeypatch.setattr(objects, 'debug_flags', {'no-system-pdfjs'}) assert pdfjs.get_pdfjs_res_and_path('web/test') == (b'content', None) assert pdfjs.get_pdfjs_res('web/test') == b'content' - for path in ['/usr/share/pdf.js/', - str(tmpdir / 'data' / 'pdfjs'), - # hardcoded for --temp-basedir - os.path.expanduser('~/.local/share/qutebrowser/pdfjs/')]: - read_system_mock.assert_any_call(path, ['web/test', 'test']) + paths = {call.args[0] for call in read_system_mock.mock_calls} + expected_paths = { + str(tmp_path / 'data' / 'pdfjs'), + # hardcoded for --temp-basedir + os.path.expanduser('~/.local/share/qutebrowser/pdfjs/') + } + assert expected_paths.issubset(paths) + if not with_system: + assert '/usr/share/pdf.js/' not in paths def test_get_pdfjs_res_not_found(self, read_system_mock, read_file_mock, caplog): From 59be37007d97b97ffce0e0d95c8ee8da00e55fb5 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 21 Mar 2025 10:41:48 +0100 Subject: [PATCH 12/69] Polyfill URL.parse for PDF.js v5 modern build --- doc/changelog.asciidoc | 5 +++++ qutebrowser/javascript/pdfjs_polyfills.js | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 8b87b0651..643d2fb4a 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -29,6 +29,11 @@ Changed * `qute-bitwarden` now passes your password to the subprocess in an environment variable when unlocking your vault, instead of as a command line argument. (#7781) +- New `-D no-system-pdfjs` debug flag to ignore system-wide PDF.js installations + for testing. +- Polyfill for missing `URL.parse` with PDF.js v5 and QtWebEngine < 6.9. Note + this is a "best effort" fix and you should be using the "older browsers" + ("legacy") build of PDF.js instead. Fixed ~~~~~ diff --git a/qutebrowser/javascript/pdfjs_polyfills.js b/qutebrowser/javascript/pdfjs_polyfills.js index 54e71652d..d27e1e65d 100644 --- a/qutebrowser/javascript/pdfjs_polyfills.js +++ b/qutebrowser/javascript/pdfjs_polyfills.js @@ -19,4 +19,16 @@ SPDX-License-Identifier: GPL-3.0-or-later return { promise, resolve, reject } } } + + // Chromium 126 / QtWebEngine 6.9 + // https://caniuse.com/mdn-api_url_parse_static + if (typeof URL.parse === "undefined") { + URL.parse = function(url, base) { + try { + return new URL(url, base); + } catch (e) { + return null; + } + } + } })(); From d0407852f4aad76ecac5b0dfeb796d2ace6fc4ff Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 21 Mar 2025 11:24:24 +0100 Subject: [PATCH 13/69] Fix lint --- qutebrowser/javascript/pdfjs_polyfills.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/javascript/pdfjs_polyfills.js b/qutebrowser/javascript/pdfjs_polyfills.js index d27e1e65d..880642bbe 100644 --- a/qutebrowser/javascript/pdfjs_polyfills.js +++ b/qutebrowser/javascript/pdfjs_polyfills.js @@ -26,7 +26,7 @@ SPDX-License-Identifier: GPL-3.0-or-later URL.parse = function(url, base) { try { return new URL(url, base); - } catch (e) { + } catch (ex) { return null; } } From e4ab45e3b21d7d1b8da47dffdb44b7ab52a245b9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 21 Mar 2025 11:25:45 +0100 Subject: [PATCH 14/69] setup: Move from deprecated license classifier to SPDX --- qutebrowser/__init__.py | 2 +- setup.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/qutebrowser/__init__.py b/qutebrowser/__init__.py index c2dc1c775..66e4cda81 100644 --- a/qutebrowser/__init__.py +++ b/qutebrowser/__init__.py @@ -11,7 +11,7 @@ _year = datetime.date.today().year __author__ = "Florian Bruhin" __copyright__ = "Copyright 2013-{} Florian Bruhin (The Compiler)".format(_year) -__license__ = "GPL" +__license__ = "GPL-3.0-or-later" __maintainer__ = __author__ __email__ = "mail@qutebrowser.org" __version__ = "3.4.0" diff --git a/setup.py b/setup.py index 97a87a65c..baba8f749 100755 --- a/setup.py +++ b/setup.py @@ -72,8 +72,6 @@ try: 'Development Status :: 5 - Production/Stable', 'Environment :: X11 Applications :: Qt', 'Intended Audience :: End Users/Desktop', - 'License :: OSI Approved :: GNU General Public License v3 or later ' - '(GPLv3+)', 'Natural Language :: English', 'Operating System :: Microsoft :: Windows', 'Operating System :: POSIX :: Linux', From a460770414821590b29ecc66f7d5f31c34d0cb9e Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 21 Mar 2025 11:29:32 +0100 Subject: [PATCH 15/69] tests: Adjust qt69_ci_flaky --- tests/conftest.py | 2 +- tests/end2end/features/qutescheme.feature | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 210f23fad..ab98100ee 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -128,7 +128,7 @@ def _apply_platform_markers(config, item): "Failing due to cheroot: https://github.com/cherrypy/cheroot/issues/346"), ( "qt69_ci_flaky", # WORKAROUND: https://github.com/qutebrowser/qutebrowser/issues/8444#issuecomment-2569610110 - pytest.mark.flaky, + pytest.mark.flaky(reruns=3), ( config.webengine and version.qtwebengine_versions(avoid_init=True).webengine diff --git a/tests/end2end/features/qutescheme.feature b/tests/end2end/features/qutescheme.feature index 3e84c39fd..68d5a0fd8 100644 --- a/tests/end2end/features/qutescheme.feature +++ b/tests/end2end/features/qutescheme.feature @@ -303,14 +303,12 @@ Feature: Special qute:// pages # :version - @qt69_ci_flaky Scenario: Open qute://version When I open qute://version Then the page should contain the plaintext "Version info" # qute://gpl - @qt69_ci_flaky Scenario: Open qute://gpl When I open qute://gpl Then the page should contain the plaintext "GNU GENERAL PUBLIC LICENSE" From 873b874c5fdcaaa23a630fd15ee2e4c46a2022d5 Mon Sep 17 00:00:00 2001 From: qutebrowser bot Date: Mon, 24 Mar 2025 04:20:44 +0000 Subject: [PATCH 16/69] Update dependencies --- misc/requirements/requirements-dev.txt | 4 ++-- misc/requirements/requirements-pyinstaller.txt | 2 +- misc/requirements/requirements-pylint.txt | 4 ++-- misc/requirements/requirements-pyroma.txt | 2 +- misc/requirements/requirements-tests.txt | 8 ++++---- misc/requirements/requirements-tox.txt | 4 ++-- misc/requirements/requirements-yamllint.txt | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt index c05ec95d1..b011fdffd 100644 --- a/misc/requirements/requirements-dev.txt +++ b/misc/requirements/requirements-dev.txt @@ -6,7 +6,7 @@ autocommand==2.2.2 backports.tarfile==1.2.0 bracex==2.5.post1 build==1.2.2.post1 -bump-my-version==1.0.2 +bump-my-version==1.1.1 certifi==2025.1.31 cffi==1.17.1 charset-normalizer==3.4.1 @@ -37,7 +37,7 @@ mdurl==0.1.2 more-itertools==10.6.0 nh3==0.2.21 packaging==24.2 -platformdirs==4.3.6 +platformdirs==4.3.7 prompt_toolkit==3.0.50 pycparser==2.22 pydantic==2.10.6 diff --git a/misc/requirements/requirements-pyinstaller.txt b/misc/requirements/requirements-pyinstaller.txt index e2439cd84..b309a56d9 100644 --- a/misc/requirements/requirements-pyinstaller.txt +++ b/misc/requirements/requirements-pyinstaller.txt @@ -4,5 +4,5 @@ altgraph==0.17.4 importlib_metadata==8.6.1 packaging==24.2 pyinstaller==6.12.0 -pyinstaller-hooks-contrib==2025.1 +pyinstaller-hooks-contrib==2025.2 zipp==3.21.0 diff --git a/misc/requirements/requirements-pylint.txt b/misc/requirements/requirements-pylint.txt index fb6f3f090..8edee185b 100644 --- a/misc/requirements/requirements-pylint.txt +++ b/misc/requirements/requirements-pylint.txt @@ -11,10 +11,10 @@ idna==3.10 isort==6.0.1 mccabe==0.7.0 pefile==2024.8.26 -platformdirs==4.3.6 +platformdirs==4.3.7 pycparser==2.22 PyJWT==2.10.1 -pylint==3.3.5 +pylint==3.3.6 python-dateutil==2.9.0.post0 ./scripts/dev/pylint_checkers requests==2.32.3 diff --git a/misc/requirements/requirements-pyroma.txt b/misc/requirements/requirements-pyroma.txt index f1d899891..a2b9519d3 100644 --- a/misc/requirements/requirements-pyroma.txt +++ b/misc/requirements/requirements-pyroma.txt @@ -12,6 +12,6 @@ pyproject_hooks==1.2.0 pyroma==4.2 requests==2.32.3 tomli==2.2.1 -trove-classifiers==2025.3.13.13 +trove-classifiers==2025.3.19.19 urllib3==2.3.0 zipp==3.21.0 diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt index 831fb440b..10661bb08 100644 --- a/misc/requirements/requirements-tests.txt +++ b/misc/requirements/requirements-tests.txt @@ -9,19 +9,19 @@ certifi==2025.1.31 charset-normalizer==3.4.1 cheroot==10.0.1 click==8.1.8 -coverage==7.7.0 +coverage==7.7.1 exceptiongroup==1.2.2 execnet==2.1.1 filelock==3.18.0 Flask==3.1.0 gherkin-official==29.0.0 hunter==3.7.0 -hypothesis==6.129.3 +hypothesis==6.130.3 idna==3.10 importlib_metadata==8.6.1 importlib_resources==6.5.2 inflect==7.3.1 -iniconfig==2.0.0 +iniconfig==2.1.0 itsdangerous==2.2.0 jaraco.collections==5.1.0 jaraco.context==6.0.1 @@ -36,7 +36,7 @@ packaging==24.2 parse==1.20.2 parse_type==0.6.4 pillow==11.1.0 -platformdirs==4.3.6 +platformdirs==4.3.7 pluggy==1.5.0 py-cpuinfo==9.0.0 Pygments==2.19.1 diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt index 06cadb159..d4e146845 100644 --- a/misc/requirements/requirements-tox.txt +++ b/misc/requirements/requirements-tox.txt @@ -7,10 +7,10 @@ distlib==0.3.9 filelock==3.18.0 packaging==24.2 pip==25.0.1 -platformdirs==4.3.6 +platformdirs==4.3.7 pluggy==1.5.0 pyproject-api==1.9.0 -setuptools==76.0.0 +setuptools==77.0.3 tomli==2.2.1 tox==4.24.2 typing_extensions==4.12.2 diff --git a/misc/requirements/requirements-yamllint.txt b/misc/requirements/requirements-yamllint.txt index a2cb3579c..67862705e 100644 --- a/misc/requirements/requirements-yamllint.txt +++ b/misc/requirements/requirements-yamllint.txt @@ -2,4 +2,4 @@ pathspec==0.12.1 PyYAML==6.0.2 -yamllint==1.36.1 +yamllint==1.37.0 From 2f20e3b60b7174b5034a6538404ea6ebd8a41840 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 24 Mar 2025 11:29:35 +0100 Subject: [PATCH 17/69] Update iniconfig changelog url --- scripts/dev/changelog_urls.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/dev/changelog_urls.json b/scripts/dev/changelog_urls.json index d225919d3..f1f4f9c38 100644 --- a/scripts/dev/changelog_urls.json +++ b/scripts/dev/changelog_urls.json @@ -28,7 +28,7 @@ "types-docutils": "https://github.com/python/typeshed/commits/main/stubs/docutils", "types-Pygments": "https://github.com/python/typeshed/commits/main/stubs/Pygments", "pytest": "https://docs.pytest.org/en/latest/changelog.html", - "iniconfig": "https://github.com/pytest-dev/iniconfig/blob/master/CHANGELOG", + "iniconfig": "https://github.com/pytest-dev/iniconfig/blob/main/CHANGELOG", "tox": "https://tox.readthedocs.io/en/latest/changelog.html", "cachetools": "https://github.com/tkem/cachetools/blob/master/CHANGELOG.rst", "pyproject-api": "https://github.com/tox-dev/pyproject-api/releases", From c4d8502872682defc1a3228d61436652a6e5e40c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 25 Mar 2025 13:04:26 +0100 Subject: [PATCH 18/69] Add site-specific quirk for Digitec/Galaxus madness --- doc/changelog.asciidoc | 2 ++ doc/help/settings.asciidoc | 1 + qutebrowser/browser/webengine/webenginetab.py | 5 +++++ qutebrowser/config/configdata.yml | 1 + .../javascript/quirks/digitecgalaxus.user.js | 17 +++++++++++++++++ 5 files changed, 26 insertions(+) create mode 100644 qutebrowser/javascript/quirks/digitecgalaxus.user.js diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 643d2fb4a..7ef58ee2c 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -45,6 +45,8 @@ Fixed error is shown instead). - The default user agent now only contains the shortened Chromium version number, which fixes overzealous blocking on ScienceDirect. +- New site-specific quirk to fix existing accounts showing as non-existant on + Digitec/Galaxus. - Resolved issues in userscripts: * `qute-bitwarden` will now prompt a re-login if its cached session has been invalidated since last used. (#8456) diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index bb3e51a35..66ac5c011 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -2773,6 +2773,7 @@ Valid values: * +ua-google+ * +ua-slack+ * +ua-googledocs+ + * +ua-digitecgalaxus+ * +js-whatsapp-web+ * +js-discord+ * +js-string-replaceall+ diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index 8142c071e..a6fdc1067 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -1201,6 +1201,11 @@ class _WebEngineScripts(QObject): # will be an UA quirk once we set the JS UA as well name='ua-googledocs', ), + _Quirk( + 'digitecgalaxus', + # will be an UA quirk once we set the JS UA as well + name='ua-digitecgalaxus', + ), _Quirk( 'string_replaceall', diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index ca84d45ea..81bccdfc9 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -660,6 +660,7 @@ content.site_specific_quirks.skip: - ua-google - ua-slack - ua-googledocs + - ua-digitecgalaxus - js-whatsapp-web - js-discord - js-string-replaceall diff --git a/qutebrowser/javascript/quirks/digitecgalaxus.user.js b/qutebrowser/javascript/quirks/digitecgalaxus.user.js new file mode 100644 index 000000000..47870f3c7 --- /dev/null +++ b/qutebrowser/javascript/quirks/digitecgalaxus.user.js @@ -0,0 +1,17 @@ +// ==UserScript== +// @include https://id.digitecgalaxus.ch/* +// @include https://id.galaxus.eu/* +// ==/UserScript== + +// Needed because their /api/v1/login/_actions/find-user endpoint claims +// that the user does not exist (!?) with the default UA + +"use strict"; + +const originalUserAgent = navigator.userAgent; + +Object.defineProperty(navigator, "userAgent", { + get() { + return originalUserAgent.replace(/QtWebEngine\/[\d.]+ /, ""); + }, +}); From b6d5a5cf14ccdc849d3c94805079a135ee4adc31 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 25 Mar 2025 14:23:48 +0100 Subject: [PATCH 19/69] Fix and simplify JS quirks tests --- doc/changelog.asciidoc | 2 +- tests/unit/javascript/test_js_quirks.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 7ef58ee2c..483038110 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -45,7 +45,7 @@ Fixed error is shown instead). - The default user agent now only contains the shortened Chromium version number, which fixes overzealous blocking on ScienceDirect. -- New site-specific quirk to fix existing accounts showing as non-existant on +- New site-specific quirk to fix existing accounts showing as non-existent on Digitec/Galaxus. - Resolved issues in userscripts: * `qute-bitwarden` will now prompt a re-login if its cached session has diff --git a/tests/unit/javascript/test_js_quirks.py b/tests/unit/javascript/test_js_quirks.py index 981f9d9e8..b7760b980 100644 --- a/tests/unit/javascript/test_js_quirks.py +++ b/tests/unit/javascript/test_js_quirks.py @@ -61,17 +61,17 @@ def test_js_quirks_match_files(webengine_tab): def test_js_quirks_match_settings(webengine_tab, configdata_init): + quirks_code = {q.name for q in webengine_tab._scripts._get_quirks()} + opt = configdata.DATA["content.site_specific_quirks.skip"] - prefix = "js-" valid_values = opt.typ.get_valid_values() assert valid_values is not None quirks_config = { - val.removeprefix(prefix).replace("-", "_") + val for val in valid_values - if val.startswith(prefix) + # some JS quirks are actually only setting the user agent, so we include + # those as well. + if val.startswith("js-") or (val.startswith("ua-") and val in quirks_code) } - quirks_code = {q.filename for q in webengine_tab._scripts._get_quirks()} - quirks_code -= {"googledocs"} # special case, UA quirk - assert quirks_code == quirks_config From 4dde8e15949dc96770a08f038b808fe2502a3fb5 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 26 Mar 2025 13:51:52 +0100 Subject: [PATCH 20/69] version: Add security patch version for Qt 6.8.3 --- qutebrowser/utils/version.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index 5a88b8c2b..087bd290c 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -639,6 +639,7 @@ class WebEngineVersions: utils.VersionNumber(6, 8): (_BASES[122], '129.0.6668.70'), # 2024-09-24 utils.VersionNumber(6, 8, 1): (_BASES[122], '131.0.6778.70'), # 2024-11-12 utils.VersionNumber(6, 8, 2): (_BASES[122], '132.0.6834.111'), # 2025-01-22 + utils.VersionNumber(6, 8, 3): (_BASES[122], '134.0.6998.89'), # 2025-03-10 ## Qt 6.9 (Beta 3) utils.VersionNumber(6, 9): (_BASES[130], '133.0.6943.141'), # 2025-02-25 From c60ebe8eeff9cef2826b2bf7ddee288ab38af49b Mon Sep 17 00:00:00 2001 From: qutebrowser bot Date: Mon, 31 Mar 2025 04:21:42 +0000 Subject: [PATCH 21/69] Update dependencies --- misc/requirements/requirements-dev.txt | 11 ++++++----- misc/requirements/requirements-flake8.txt | 6 +++--- misc/requirements/requirements-mypy.txt | 4 ++-- misc/requirements/requirements-pylint.txt | 2 +- misc/requirements/requirements-tests.txt | 6 +++--- misc/requirements/requirements-tox.txt | 6 +++--- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt index b011fdffd..4cd7ba6ab 100644 --- a/misc/requirements/requirements-dev.txt +++ b/misc/requirements/requirements-dev.txt @@ -40,22 +40,22 @@ packaging==24.2 platformdirs==4.3.7 prompt_toolkit==3.0.50 pycparser==2.22 -pydantic==2.10.6 +pydantic==2.11.1 pydantic-settings==2.8.1 -pydantic_core==2.27.2 +pydantic_core==2.33.0 Pygments==2.19.1 PyJWT==2.10.1 Pympler==1.1 pyproject_hooks==1.2.0 PyQt-builder==1.18.1 python-dateutil==2.9.0.post0 -python-dotenv==1.0.1 +python-dotenv==1.1.0 questionary==2.1.0 readme_renderer==44.0 requests==2.32.3 requests-toolbelt==1.0.0 rfc3986==2.0.0 -rich==13.9.4 +rich==14.0.0 rich-click==1.8.8 SecretStorage==3.3.3 sip==6.10.0 @@ -65,7 +65,8 @@ tomli==2.2.1 tomlkit==0.13.2 twine==6.1.0 typeguard==4.3.0 -typing_extensions==4.12.2 +typing-inspection==0.4.0 +typing_extensions==4.13.0 uritemplate==4.1.1 # urllib3==2.3.0 wcmatch==10.0 diff --git a/misc/requirements/requirements-flake8.txt b/misc/requirements/requirements-flake8.txt index 2e4c9e89d..33638de7e 100644 --- a/misc/requirements/requirements-flake8.txt +++ b/misc/requirements/requirements-flake8.txt @@ -1,7 +1,7 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py attrs==25.3.0 -flake8==7.1.2 +flake8==7.2.0 flake8-bugbear==24.12.12 flake8-builtins==2.5.0 flake8-comprehensions==3.16.0 @@ -16,8 +16,8 @@ flake8-tidy-imports==4.11.0 flake8-tuple==0.4.1 mccabe==0.7.0 pep8-naming==0.14.1 -pycodestyle==2.12.1 +pycodestyle==2.13.0 pydocstyle==6.3.0 -pyflakes==3.2.0 +pyflakes==3.3.1 six==1.17.0 snowballstemmer==2.2.0 diff --git a/misc/requirements/requirements-mypy.txt b/misc/requirements/requirements-mypy.txt index de5f4a05f..893736057 100644 --- a/misc/requirements/requirements-mypy.txt +++ b/misc/requirements/requirements-mypy.txt @@ -14,5 +14,5 @@ tomli==2.2.1 types-colorama==0.4.15.20240311 types-docutils==0.21.0.20241128 types-Pygments==2.19.0.20250305 -types-PyYAML==6.0.12.20241230 -typing_extensions==4.12.2 +types-PyYAML==6.0.12.20250326 +typing_extensions==4.13.0 diff --git a/misc/requirements/requirements-pylint.txt b/misc/requirements/requirements-pylint.txt index 8edee185b..3d7a9d4ac 100644 --- a/misc/requirements/requirements-pylint.txt +++ b/misc/requirements/requirements-pylint.txt @@ -21,6 +21,6 @@ requests==2.32.3 six==1.17.0 tomli==2.2.1 tomlkit==0.13.2 -typing_extensions==4.12.2 +typing_extensions==4.13.0 uritemplate==4.1.1 # urllib3==2.3.0 diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt index 10661bb08..8075e5d8e 100644 --- a/misc/requirements/requirements-tests.txt +++ b/misc/requirements/requirements-tests.txt @@ -9,14 +9,14 @@ certifi==2025.1.31 charset-normalizer==3.4.1 cheroot==10.0.1 click==8.1.8 -coverage==7.7.1 +coverage==7.8.0 exceptiongroup==1.2.2 execnet==2.1.1 filelock==3.18.0 Flask==3.1.0 gherkin-official==29.0.0 hunter==3.7.0 -hypothesis==6.130.3 +hypothesis==6.130.5 idna==3.10 importlib_metadata==8.6.1 importlib_resources==6.5.2 @@ -60,7 +60,7 @@ soupsieve==2.6 tldextract==5.1.3 tomli==2.2.1 typeguard==4.3.0 -typing_extensions==4.12.2 +typing_extensions==4.13.0 urllib3==2.3.0 vulture==2.14 Werkzeug==3.1.3 diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt index d4e146845..f036395fb 100644 --- a/misc/requirements/requirements-tox.txt +++ b/misc/requirements/requirements-tox.txt @@ -10,9 +10,9 @@ pip==25.0.1 platformdirs==4.3.7 pluggy==1.5.0 pyproject-api==1.9.0 -setuptools==77.0.3 +setuptools==78.1.0 tomli==2.2.1 -tox==4.24.2 -typing_extensions==4.12.2 +tox==4.25.0 +typing_extensions==4.13.0 virtualenv==20.29.3 wheel==0.45.1 From ef397e94178d312a5947190e9d51cb27ce24d22d Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 31 Mar 2025 08:40:01 +0200 Subject: [PATCH 22/69] Update changelog URLs --- scripts/dev/changelog_urls.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/dev/changelog_urls.json b/scripts/dev/changelog_urls.json index f1f4f9c38..5029eb9c1 100644 --- a/scripts/dev/changelog_urls.json +++ b/scripts/dev/changelog_urls.json @@ -92,7 +92,7 @@ "pydantic": "https://docs.pydantic.dev/latest/changelog/", "pydantic-settings": "https://github.com/pydantic/pydantic-settings/releases", "pydantic_core": "https://github.com/pydantic/pydantic-core/releases", - "python-dotenv": "https://saurabh-kumar.com/python-dotenv/changelog/", + "python-dotenv": "https://github.com/theskumar/python-dotenv/blob/main/CHANGELOG.md", "questionary": "https://github.com/tmbo/questionary/blob/master/docs/pages/changelog.rst", "rich-click": "https://ewels.github.io/rich-click/changelog/", "wcmatch": "https://github.com/facelessuser/wcmatch/releases", @@ -133,6 +133,7 @@ "idna": "https://github.com/kjd/idna/blob/master/HISTORY.rst", "tldextract": "https://github.com/john-kurkowski/tldextract/blob/master/CHANGELOG.md", "typing_extensions": "https://github.com/python/typing_extensions/blob/main/CHANGELOG.md", + "typing-inspection": "https://github.com/pydantic/typing-inspection/blob/main/HISTORY.md", "diff_cover": "https://github.com/Bachmann1234/diff_cover/blob/main/CHANGELOG", "beautifulsoup4": "https://git.launchpad.net/beautifulsoup/tree/CHANGELOG", "check-manifest": "https://github.com/mgedmin/check-manifest/blob/master/CHANGES.rst", From 69f0eae60007fd247e5e9ff51455618def335e07 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 31 Mar 2025 08:44:45 +0200 Subject: [PATCH 23/69] Drop unneeded nonlocal --- tests/unit/components/test_braveadblock.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/components/test_braveadblock.py b/tests/unit/components/test_braveadblock.py index dab842139..b23827827 100644 --- a/tests/unit/components/test_braveadblock.py +++ b/tests/unit/components/test_braveadblock.py @@ -105,7 +105,6 @@ def assert_none_blocked(ad_blocker): assert_urls(ad_blocker, NOT_OKAY_URLS + OKAY_URLS, False) def assert_not_blocked(url, source_url, resource_type): - nonlocal ad_blocker assert not ad_blocker._is_blocked(url, source_url, resource_type) run_function_on_dataset(assert_not_blocked) From c165d1a0dabbb1c2fa1fb4973432eb0ae6fc3cde Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 31 Mar 2025 13:40:22 +0200 Subject: [PATCH 24/69] Update changelog --- doc/changelog.asciidoc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 483038110..1ee0b53e7 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -43,6 +43,8 @@ Fixed QtWebEngine and now correctly disabled on the JS side. (#8449) - Crash when a buggy notification presenter returns a duplicate ID (now an error is shown instead). +- Crashes when running `:tab-move` or `:yank title` at startup, before a tab is + available. - The default user agent now only contains the shortened Chromium version number, which fixes overzealous blocking on ScienceDirect. - New site-specific quirk to fix existing accounts showing as non-existent on From 163bb9fa0c841389c69839c252ca684270412367 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Apr 2025 12:52:24 +0200 Subject: [PATCH 25/69] Python 3.14: Update cheroot workaround https://github.com/cherrypy/cheroot/issues/734 https://github.com/python/cpython/issues/129354 Part of #8529 --- tests/end2end/fixtures/webserver_sub.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/tests/end2end/fixtures/webserver_sub.py b/tests/end2end/fixtures/webserver_sub.py index 117232068..fc1cc5264 100644 --- a/tests/end2end/fixtures/webserver_sub.py +++ b/tests/end2end/fixtures/webserver_sub.py @@ -341,7 +341,7 @@ class WSGIServer(cheroot.wsgi.Server): def unraisable_hook(unraisable: "sys.UnraisableHookArgs") -> None: if ( - sys.version_info[:2] == (3, 13) + sys.version_info[:2] >= (3, 13) and isinstance(unraisable.exc_value, OSError) and ( unraisable.exc_value.errno == errno.EBADF @@ -351,7 +351,19 @@ def unraisable_hook(unraisable: "sys.UnraisableHookArgs") -> None: and unraisable.exc_value.winerror == errno.WSAENOTSOCK ) ) - and unraisable.object.__qualname__ == "IOBase.__del__" + and ( + ( + # Python 3.14 + unraisable.object is None + and unraisable.err_msg.startswith( + "Exception ignored while calling deallocator Date: Wed, 2 Apr 2025 13:15:32 +0200 Subject: [PATCH 26/69] Python 3.14: Ignore DeprecationWarnings in plugins https://github.com/pytest-dev/pytest-mock/issues/468 https://github.com/ionelmc/pytest-benchmark/issues/283 Part of #8529 --- pytest.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pytest.ini b/pytest.ini index 4b7649c13..1e44011e0 100644 --- a/pytest.ini +++ b/pytest.ini @@ -95,5 +95,9 @@ filterwarnings = # https://github.com/cucumber/gherkin/commit/2f4830093149eae7ff7bd82f683b3d3bb7320d39 # https://github.com/pytest-dev/pytest-bdd/issues/752 ignore:'maxsplit' is passed as positional argument:DeprecationWarning:gherkin.gherkin_line + # https://github.com/pytest-dev/pytest-mock/issues/468 + ignore:'asyncio\.iscoroutinefunction' is deprecated and slated for removal:DeprecationWarning:pytest_mock.plugin + # https://github.com/ionelmc/pytest-benchmark/issues/283 + ignore:FileType is deprecated\. Simply open files after parsing arguments\.:PendingDeprecationWarning:pytest_benchmark.plugin faulthandler_timeout = 90 xvfb_colordepth = 24 From 3aa839998bbc4cec566a4c1c02632a4a9ea10355 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Apr 2025 13:22:35 +0200 Subject: [PATCH 27/69] Python 3.14: Add to tox/CI Part of #8529 --- .github/workflows/ci.yml | 4 ++++ tox.ini | 1 + 2 files changed, 5 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0ec73024f..fc12aef9a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -193,6 +193,10 @@ jobs: - testenv: py313-pyqt68 os: ubuntu-24.04 python: "3.13" + ### PyQt 6.8 (Python 3.14) + - testenv: py313-pyqt68 + os: ubuntu-24.04 + python: "3.14" ### macOS Ventura - testenv: py313-pyqt68 os: macos-13 diff --git a/tox.ini b/tox.ini index 92f61e55b..0c966f0e1 100644 --- a/tox.ini +++ b/tox.ini @@ -41,6 +41,7 @@ basepython = py311: {env:PYTHON:python3.11} py312: {env:PYTHON:python3.12} py313: {env:PYTHON:python3.13} + py314: {env:PYTHON:python3.14} deps = -r{toxinidir}/requirements.txt -r{toxinidir}/misc/requirements/requirements-tests.txt From 71381c0da65fe6e0a7f7f9c20a4edf7f4eef71b9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Apr 2025 13:30:46 +0200 Subject: [PATCH 28/69] ci: Try to fix Python 3.14 version --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fc12aef9a..c68496be2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -196,7 +196,7 @@ jobs: ### PyQt 6.8 (Python 3.14) - testenv: py313-pyqt68 os: ubuntu-24.04 - python: "3.14" + python: "3.14-dev" ### macOS Ventura - testenv: py313-pyqt68 os: macos-13 From 72647298b7a4caa7798446e051a810fad4feed49 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Apr 2025 13:31:55 +0200 Subject: [PATCH 29/69] ci: Fix Python 3.14 derp --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c68496be2..577ba165a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -194,7 +194,7 @@ jobs: os: ubuntu-24.04 python: "3.13" ### PyQt 6.8 (Python 3.14) - - testenv: py313-pyqt68 + - testenv: py314-pyqt68 os: ubuntu-24.04 python: "3.14-dev" ### macOS Ventura From 4e5eb90857b1d4628934c7d756f2d941af961ea0 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 2 Apr 2025 13:34:27 +0200 Subject: [PATCH 30/69] ci: Fix Python 3.14 Pillow build --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 577ba165a..293b354b1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -232,7 +232,7 @@ jobs: - name: Install apt dependencies run: | sudo apt-get update - sudo apt-get install --no-install-recommends libyaml-dev libegl1 libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 libxcb-cursor0 + sudo apt-get install --no-install-recommends libyaml-dev libegl1 libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-shape0 libxcb-cursor0 libjpeg-dev if: "startsWith(matrix.os, 'ubuntu-')" - name: Install dependencies run: | From b09a1385f5a5d0367fcf63d0662e50b39354f222 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 4 Apr 2025 12:02:42 +0200 Subject: [PATCH 31/69] Make private browsing asserts more useful The assert in commands.py sometimes fails, hopefully this will help track things down. --- qutebrowser/browser/commands.py | 2 +- qutebrowser/mainwindow/mainwindow.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index ebce4b37a..679d9ddb1 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -124,7 +124,7 @@ class CommandDispatcher: private = self._tabbed_browser.is_private if window or private: - assert isinstance(private, bool) + assert isinstance(private, bool), private tabbed_browser = self._new_tabbed_browser(private) tabbed_browser.tabopen(url) tabbed_browser.window().show() diff --git a/qutebrowser/mainwindow/mainwindow.py b/qutebrowser/mainwindow/mainwindow.py index 6e6821612..7460524c5 100644 --- a/qutebrowser/mainwindow/mainwindow.py +++ b/qutebrowser/mainwindow/mainwindow.py @@ -224,6 +224,7 @@ class MainWindow(QWidget): model=self._download_model) self.is_private = config.val.content.private_browsing or private + assert isinstance(self.is_private, bool), private self.tabbed_browser: tabbedbrowser.TabbedBrowser = tabbedbrowser.TabbedBrowser( win_id=self.win_id, private=self.is_private, parent=self) From ab3b77cb1e99c4b6cf391a94f174c9b9f42dfbed Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 4 Apr 2025 12:55:28 +0200 Subject: [PATCH 32/69] Revert "Make private browsing asserts more useful" This reverts commit b09a1385f5a5d0367fcf63d0662e50b39354f222. --- qutebrowser/browser/commands.py | 2 +- qutebrowser/mainwindow/mainwindow.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 679d9ddb1..ebce4b37a 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -124,7 +124,7 @@ class CommandDispatcher: private = self._tabbed_browser.is_private if window or private: - assert isinstance(private, bool), private + assert isinstance(private, bool) tabbed_browser = self._new_tabbed_browser(private) tabbed_browser.tabopen(url) tabbed_browser.window().show() diff --git a/qutebrowser/mainwindow/mainwindow.py b/qutebrowser/mainwindow/mainwindow.py index 7460524c5..6e6821612 100644 --- a/qutebrowser/mainwindow/mainwindow.py +++ b/qutebrowser/mainwindow/mainwindow.py @@ -224,7 +224,6 @@ class MainWindow(QWidget): model=self._download_model) self.is_private = config.val.content.private_browsing or private - assert isinstance(self.is_private, bool), private self.tabbed_browser: tabbedbrowser.TabbedBrowser = tabbedbrowser.TabbedBrowser( win_id=self.win_id, private=self.is_private, parent=self) From c32f5afcc43092de49c0597a0bfd5a1ddf0363ae Mon Sep 17 00:00:00 2001 From: toofar Date: Sat, 5 Apr 2025 18:18:10 +1300 Subject: [PATCH 33/69] Fix crash when JS is run async on deleted tabs My reproducer is this: * open the browser with the auto insert mode JS primed, and two tabs: `python3 -m qutebrowser -T -s input.insert_mode.auto_load true about:blank?1 about:blank?2` * close the second tab: `d` * re-open the closed tab then close it again real quick: `u` then `d` If you have trouble reproducing, try increasing the 65ms delay in `handle_auto_insert_mode` to be bigger (like 500ms). Closes: #3895 --- qutebrowser/browser/webengine/webenginetab.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index a6fdc1067..35e155e8b 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -1368,6 +1368,11 @@ class WebEngineTab(browsertab.AbstractTab): self._widget.page().toHtml(callback) def run_js_async(self, code, callback=None, *, world=None): + if sip.isdeleted(self._widget): + # https://github.com/qutebrowser/qutebrowser/issues/3895 + log.misc.debug("run_js_async called on deleted tab") + return + world_id_type = Union[QWebEngineScript.ScriptWorldId, int] if world is None: world_id: world_id_type = QWebEngineScript.ScriptWorldId.ApplicationWorld From 21b2d63f4d57b852ed2db7a6f99681e775ffab9a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 6 Apr 2025 14:35:51 +0200 Subject: [PATCH 34/69] doc: Remove dead matrix bridge link --- doc/help/index.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/help/index.asciidoc b/doc/help/index.asciidoc index 4f2b009c7..b52d1c82c 100644 --- a/doc/help/index.asciidoc +++ b/doc/help/index.asciidoc @@ -26,7 +26,7 @@ Getting help You can get help in the IRC channel link:ircs://irc.libera.chat:6697/#qutebrowser[`#qutebrowser`] on https://libera.chat/[Libera Chat] -(https://web.libera.chat/#qutebrowser[webchat], https://matrix.to/#qutebrowser:libera.chat[via Matrix]), +(https://web.libera.chat/#qutebrowser[webchat]), or by writing a message to the https://listi.jpberlin.de/mailman/listinfo/qutebrowser[mailinglist] at mailto:qutebrowser@lists.qutebrowser.org[]. From 9a23ce6c3c2c9eb5ad08b2425e25634be87244b0 Mon Sep 17 00:00:00 2001 From: qutebrowser bot Date: Mon, 7 Apr 2025 04:20:42 +0000 Subject: [PATCH 35/69] Update dependencies --- misc/requirements/requirements-dev.txt | 6 +++--- misc/requirements/requirements-flake8.txt | 2 +- misc/requirements/requirements-mypy.txt | 6 +++--- misc/requirements/requirements-pylint.txt | 2 +- misc/requirements/requirements-tests.txt | 6 +++--- misc/requirements/requirements-tox.txt | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt index 4cd7ba6ab..7ae7b806f 100644 --- a/misc/requirements/requirements-dev.txt +++ b/misc/requirements/requirements-dev.txt @@ -40,9 +40,9 @@ packaging==24.2 platformdirs==4.3.7 prompt_toolkit==3.0.50 pycparser==2.22 -pydantic==2.11.1 +pydantic==2.11.2 pydantic-settings==2.8.1 -pydantic_core==2.33.0 +pydantic_core==2.33.1 Pygments==2.19.1 PyJWT==2.10.1 Pympler==1.1 @@ -66,7 +66,7 @@ tomlkit==0.13.2 twine==6.1.0 typeguard==4.3.0 typing-inspection==0.4.0 -typing_extensions==4.13.0 +typing_extensions==4.13.1 uritemplate==4.1.1 # urllib3==2.3.0 wcmatch==10.0 diff --git a/misc/requirements/requirements-flake8.txt b/misc/requirements/requirements-flake8.txt index 33638de7e..d421edb84 100644 --- a/misc/requirements/requirements-flake8.txt +++ b/misc/requirements/requirements-flake8.txt @@ -18,6 +18,6 @@ mccabe==0.7.0 pep8-naming==0.14.1 pycodestyle==2.13.0 pydocstyle==6.3.0 -pyflakes==3.3.1 +pyflakes==3.3.2 six==1.17.0 snowballstemmer==2.2.0 diff --git a/misc/requirements/requirements-mypy.txt b/misc/requirements/requirements-mypy.txt index 893736057..f5cc3cf57 100644 --- a/misc/requirements/requirements-mypy.txt +++ b/misc/requirements/requirements-mypy.txt @@ -3,7 +3,7 @@ chardet==5.2.0 diff_cover==9.2.4 Jinja2==3.1.6 -lxml==5.3.1 +lxml==5.3.2 MarkupSafe==3.0.2 mypy==1.15.0 mypy-extensions==1.0.0 @@ -14,5 +14,5 @@ tomli==2.2.1 types-colorama==0.4.15.20240311 types-docutils==0.21.0.20241128 types-Pygments==2.19.0.20250305 -types-PyYAML==6.0.12.20250326 -typing_extensions==4.13.0 +types-PyYAML==6.0.12.20250402 +typing_extensions==4.13.1 diff --git a/misc/requirements/requirements-pylint.txt b/misc/requirements/requirements-pylint.txt index 3d7a9d4ac..cb1c9baa0 100644 --- a/misc/requirements/requirements-pylint.txt +++ b/misc/requirements/requirements-pylint.txt @@ -21,6 +21,6 @@ requests==2.32.3 six==1.17.0 tomli==2.2.1 tomlkit==0.13.2 -typing_extensions==4.13.0 +typing_extensions==4.13.1 uritemplate==4.1.1 # urllib3==2.3.0 diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt index 8075e5d8e..6e7167167 100644 --- a/misc/requirements/requirements-tests.txt +++ b/misc/requirements/requirements-tests.txt @@ -16,7 +16,7 @@ filelock==3.18.0 Flask==3.1.0 gherkin-official==29.0.0 hunter==3.7.0 -hypothesis==6.130.5 +hypothesis==6.130.9 idna==3.10 importlib_metadata==8.6.1 importlib_resources==6.5.2 @@ -43,7 +43,7 @@ Pygments==2.19.1 pytest==8.3.5 pytest-bdd==8.1.0 pytest-benchmark==5.1.0 -pytest-cov==6.0.0 +pytest-cov==6.1.1 pytest-instafail==0.5.0 pytest-mock==3.14.0 pytest-qt==4.4.0 @@ -60,7 +60,7 @@ soupsieve==2.6 tldextract==5.1.3 tomli==2.2.1 typeguard==4.3.0 -typing_extensions==4.13.0 +typing_extensions==4.13.1 urllib3==2.3.0 vulture==2.14 Werkzeug==3.1.3 diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt index f036395fb..fea0150a8 100644 --- a/misc/requirements/requirements-tox.txt +++ b/misc/requirements/requirements-tox.txt @@ -13,6 +13,6 @@ pyproject-api==1.9.0 setuptools==78.1.0 tomli==2.2.1 tox==4.25.0 -typing_extensions==4.13.0 -virtualenv==20.29.3 +typing_extensions==4.13.1 +virtualenv==20.30.0 wheel==0.45.1 From ef2ceccd297d737ed910fc27013b8af767abda32 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 7 Apr 2025 21:58:45 +0200 Subject: [PATCH 36/69] Qt 6.9: Work around QtWebEngine not handling element See #8539 --- doc/changelog.asciidoc | 3 +++ qutebrowser/config/qtargs.py | 5 +++++ tests/unit/config/test_qtargs.py | 31 +++++++++++++++---------------- 3 files changed, 23 insertions(+), 16 deletions(-) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 1ee0b53e7..15ba6cee1 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -49,6 +49,9 @@ Fixed number, which fixes overzealous blocking on ScienceDirect. - New site-specific quirk to fix existing accounts showing as non-existent on Digitec/Galaxus. +- Workaround for microphone/camera permissions not being requested with + QtWebEngine 6.9.0 on Google Meet, Zoom, or other pages using the new + `` element. - Resolved issues in userscripts: * `qute-bitwarden` will now prompt a re-login if its cached session has been invalidated since last used. (#8456) diff --git a/qutebrowser/config/qtargs.py b/qutebrowser/config/qtargs.py index b02899e28..b9519d0eb 100644 --- a/qutebrowser/config/qtargs.py +++ b/qutebrowser/config/qtargs.py @@ -159,6 +159,11 @@ def _qtwebengine_features( # TODO adjust if fixed in Qt 6.8.2/.3 or 6.9.0/.1 disabled_features.append('DocumentPictureInPictureAPI') + if versions.webengine == utils.VersionNumber(6, 9): + # WORKAROUND for https://bugreports.qt.io/browse/QTBUG-135787 + # TODO adjust if still present in 6.9.1 + disabled_features.append('PermissionElement') + if not config.val.input.media_keys: disabled_features.append('HardwareMediaKeyHandling') diff --git a/tests/unit/config/test_qtargs.py b/tests/unit/config/test_qtargs.py index ab06aeb76..ed2d6ae45 100644 --- a/tests/unit/config/test_qtargs.py +++ b/tests/unit/config/test_qtargs.py @@ -448,25 +448,25 @@ class TestWebEngineArgs: expected = ['--disable-features=InstalledApp'] if has_workaround else [] assert disable_features_args == expected - @pytest.mark.parametrize('qt_version, has_workaround', [ + @pytest.mark.parametrize('qt_version, disabled', [ # Qt 6.6 - ('6.6.3', False), + ('6.6.3', None), # Qt 6.7 - ('6.7.0', True), - ('6.7.1', True), - ('6.7.2', True), - ('6.7.3', True), + ('6.7.0', "DocumentPictureInPictureAPI"), + ('6.7.1', "DocumentPictureInPictureAPI"), + ('6.7.2', "DocumentPictureInPictureAPI"), + ('6.7.3', "DocumentPictureInPictureAPI"), # Qt 6.8 - ('6.8.0', True), - ('6.8.1', True), - ('6.8.2', True), # tbd - ('6.8.3', True), # tbd + ('6.8.0', "DocumentPictureInPictureAPI"), + ('6.8.1', "DocumentPictureInPictureAPI"), + ('6.8.2', "DocumentPictureInPictureAPI"), + ('6.8.3', "DocumentPictureInPictureAPI"), # Qt 6.9 - ('6.9.0', True), # tbd - ('6.9.1', True), # tbd + ('6.9.0', "DocumentPictureInPictureAPI,PermissionElement"), + ('6.9.1', "DocumentPictureInPictureAPI"), # tbd ]) - def test_document_pip_workaround( - self, parser, version_patcher, qt_version, has_workaround + def test_disble_feature_workaround( + self, parser, version_patcher, qt_version, disabled ): version_patcher(qt_version) @@ -477,8 +477,7 @@ class TestWebEngineArgs: if arg.startswith(qtargs._DISABLE_FEATURES) ] - flag = "--disable-features=DocumentPictureInPictureAPI" - expected = [flag] if has_workaround else [] + expected = [f"--disable-features={disabled}"] if disabled else [] assert disable_features_args == expected @pytest.mark.parametrize('enabled', [True, False]) From de3fa06effe0fb261f41336cadced280da716e85 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 10:42:42 +0200 Subject: [PATCH 37/69] Fix lint mccabe complexity too high, but despite a lot of 'if' the function is quite linear. --- qutebrowser/config/qtargs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/config/qtargs.py b/qutebrowser/config/qtargs.py index b9519d0eb..da0050b0d 100644 --- a/qutebrowser/config/qtargs.py +++ b/qutebrowser/config/qtargs.py @@ -78,7 +78,7 @@ def qt_args(namespace: argparse.Namespace) -> list[str]: return argv -def _qtwebengine_features( +def _qtwebengine_features( # noqa: C901 versions: version.WebEngineVersions, special_flags: Sequence[str], ) -> tuple[Sequence[str], Sequence[str]]: From 54b6c927138c6186146a74b4b44045e489c346e3 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 12:35:51 +0200 Subject: [PATCH 38/69] Python 3.14: Skip newly added stdlib file test See #8529 --- tests/unit/utils/test_qtutils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/unit/utils/test_qtutils.py b/tests/unit/utils/test_qtutils.py index 0a3afa416..a839eb100 100644 --- a/tests/unit/utils/test_qtutils.py +++ b/tests/unit/utils/test_qtutils.py @@ -577,7 +577,7 @@ if test_file is not None: qiodev.name = test_file.TESTFN qiodev.mode = mode # Create empty TESTFN file because the Python tests try to unlink - # it.after the test. + # it after the test. with open(test_file.TESTFN, 'w', encoding='utf-8'): pass return qiodev @@ -598,6 +598,9 @@ if test_file is not None: def testSetBufferSize(self): """Skip this test as setting buffer size is unsupported.""" + def testDefaultBufferSize(self): + """Skip this test as getting buffer size is unsupported.""" + def testTruncateOnWindows(self): """Skip this test truncating is unsupported.""" From 3280c8dacc39b0d95d5fc2d6e89bbec8006fede5 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 14:02:50 +0200 Subject: [PATCH 39/69] tests: Avoid CI issues with qutescheme and Qt 6.9 see #8536 --- pytest.ini | 1 + tests/conftest.py | 11 +++++++++++ tests/end2end/features/qutescheme.feature | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pytest.ini b/pytest.ini index 1e44011e0..54df9528c 100644 --- a/pytest.ini +++ b/pytest.ini @@ -43,6 +43,7 @@ markers = qt5_xfail: Tests which fail with Qt 5 qt6_xfail: Tests which fail with Qt 6 qt69_ci_flaky: Tests which are flaky with Qt 6.9 on CI + qt69_ci_skip: Tests which should be skipped with Qt 6.9 on CI qt_log_level_fail = WARNING qt_log_ignore = # GitHub Actions diff --git a/tests/conftest.py b/tests/conftest.py index ab98100ee..bf8691033 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -137,6 +137,17 @@ def _apply_platform_markers(config, item): ), "Flaky with QtWebEngine 6.9 on CI", ), + ( + "qt69_ci_skip", # WORKAROUND: https://github.com/qutebrowser/qutebrowser/issues/8444#issuecomment-2569610110 + pytest.mark.skipif, + ( + config.webengine + and version.qtwebengine_versions(avoid_init=True).webengine + == utils.VersionNumber(6, 9) + and testutils.ON_CI + ), + "Skipped with QtWebEngine 6.9 on CI", + ), ] for searched_marker, new_marker_kind, condition, default_reason in markers: diff --git a/tests/end2end/features/qutescheme.feature b/tests/end2end/features/qutescheme.feature index 68d5a0fd8..19d3c2b77 100644 --- a/tests/end2end/features/qutescheme.feature +++ b/tests/end2end/features/qutescheme.feature @@ -308,7 +308,7 @@ Feature: Special qute:// pages Then the page should contain the plaintext "Version info" # qute://gpl - + @qt69_ci_flaky Scenario: Open qute://gpl When I open qute://gpl Then the page should contain the plaintext "GNU GENERAL PUBLIC LICENSE" @@ -316,7 +316,7 @@ Feature: Special qute:// pages # qute://start # QtWebKit doesn't support formaction; unknown Qt 6.9 renderer process crashes - @qtwebkit_skip @qt69_ci_flaky + @qtwebkit_skip @qt69_ci_skip Scenario: Searching on qute://start When I set url.searchengines to {"DEFAULT": "http://localhost:(port)/data/title.html?q={}"} And I open qute://start From d9d8701696373d08cbf0e0b6996130c4fe43bb25 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 14:36:34 +0200 Subject: [PATCH 40/69] Fix flake8 --- tests/unit/utils/test_qtutils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/utils/test_qtutils.py b/tests/unit/utils/test_qtutils.py index a839eb100..240cc42dd 100644 --- a/tests/unit/utils/test_qtutils.py +++ b/tests/unit/utils/test_qtutils.py @@ -530,7 +530,7 @@ class TestSavefileOpen: assert data == b'foo\nbar\nbaz' -if test_file is not None: +if test_file is not None: # noqa: C901 # If we were able to import Python's test_file module, we run some code # here which defines unittest TestCases to run the python tests over # PyQIODevice. From bbdf9faf5e0110bf0cc9fc1029416ac197a0e5ac Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 14:37:51 +0200 Subject: [PATCH 41/69] Qt 6.9: Mark one more test as flaky --- tests/end2end/features/qutescheme.feature | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/end2end/features/qutescheme.feature b/tests/end2end/features/qutescheme.feature index 19d3c2b77..ad1d0a48a 100644 --- a/tests/end2end/features/qutescheme.feature +++ b/tests/end2end/features/qutescheme.feature @@ -303,11 +303,13 @@ Feature: Special qute:// pages # :version + @qt69_ci_flaky Scenario: Open qute://version When I open qute://version Then the page should contain the plaintext "Version info" # qute://gpl + @qt69_ci_flaky Scenario: Open qute://gpl When I open qute://gpl From b5a399831b27b8b12328be0953748ec315e99add Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 19:42:16 +0200 Subject: [PATCH 42/69] tests: Disable MAP_DISCARD workaround for fixed Qt versions --- tests/helpers/testutils.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/tests/helpers/testutils.py b/tests/helpers/testutils.py index 5407823e6..9b13b9dfe 100644 --- a/tests/helpers/testutils.py +++ b/tests/helpers/testutils.py @@ -277,7 +277,7 @@ DISABLE_SECCOMP_BPF_FLAG = "--disable-seccomp-filter-sandbox" DISABLE_SECCOMP_BPF_ARGS = ["-s", "qt.chromium.sandboxing", "disable-seccomp-bpf"] -def _needs_map_discard_workaround(webengine_version: utils.VersionNumber) -> bool: +def _needs_map_discard_workaround(qtwe_version: utils.VersionNumber) -> bool: """Check if this system needs the glibc 2.41+ MAP_DISCARD workaround. WORKAROUND for https://bugreports.qt.io/browse/QTBUG-134631 @@ -286,9 +286,6 @@ def _needs_map_discard_workaround(webengine_version: utils.VersionNumber) -> boo if not utils.is_posix: return False - # Not fixed yet as of Qt 6.9 Beta 3 - utils.unused(webengine_version) - libc_name, libc_version_str = platform.libc_ver() if libc_name != "glibc": return False @@ -300,7 +297,21 @@ def _needs_map_discard_workaround(webengine_version: utils.VersionNumber) -> boo affected_glibc = utils.VersionNumber(2, 41) affected_kernel = utils.VersionNumber(6, 11) - return libc_version >= affected_glibc and kernel_version >= affected_kernel + return ( + libc_version >= affected_glibc + and kernel_version >= affected_kernel + and not ( + # https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/631749 + # -> Fixed in QtWebEngine 5.15.9 + utils.VersionNumber(5, 15, 19) <= qtwe_version < utils.VersionNumber(6) + # https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/631750 + # -> Fixed in QtWebEngine 6.8.4 + or utils.VersionNumber(6, 8, 4) <= qtwe_version < utils.VersionNumber(6, 9) + # https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/631348 + # -> Fixed in QtWebEngine 6.9.1 + or utils.VersionNumber(6, 9, 1) <= qtwe_version + ) + ) def disable_seccomp_bpf_sandbox() -> bool: From 961a9390da7556617e550a06e5f0ef1a00453379 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 20:19:34 +0200 Subject: [PATCH 43/69] Remove the ua-slack site specific quirk Closes #8510 --- doc/changelog.asciidoc | 5 ++++ doc/help/settings.asciidoc | 1 - .../browser/webengine/webenginesettings.py | 24 ++++--------------- qutebrowser/config/configdata.yml | 1 - 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 15ba6cee1..57c0b0b79 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -35,6 +35,11 @@ Changed this is a "best effort" fix and you should be using the "older browsers" ("legacy") build of PDF.js instead. +Removed +~~~~~~~ + +- The `ua-slack` site-specific quirk, as things seem to work better nowadays without a quirk needed. + Fixed ~~~~~ diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 66ac5c011..3e68fb720 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -2771,7 +2771,6 @@ Valid values: * +ua-whatsapp+ * +ua-google+ - * +ua-slack+ * +ua-googledocs+ * +ua-digitecgalaxus+ * +js-whatsapp-web+ diff --git a/qutebrowser/browser/webengine/webenginesettings.py b/qutebrowser/browser/webengine/webenginesettings.py index a5c45d5cf..a37a47b8d 100644 --- a/qutebrowser/browser/webengine/webenginesettings.py +++ b/qutebrowser/browser/webengine/webenginesettings.py @@ -26,7 +26,7 @@ from qutebrowser.config import config, websettings from qutebrowser.config.websettings import AttributeInfo as Attr from qutebrowser.misc import pakjoy from qutebrowser.utils import (standarddir, qtutils, message, log, - urlmatch, usertypes, objreg, version) + urlmatch, usertypes, objreg, version, utils) if TYPE_CHECKING: from qutebrowser.browser.webengine import interceptor @@ -514,33 +514,19 @@ def _init_site_specific_quirks(): "Safari/537.36" ) + utils.unused(maybe_newer_chrome_ua) + user_agents = [ # Needed to avoid a ""WhatsApp works with Google Chrome 36+" error # page which doesn't allow to use WhatsApp Web at all. Also see the # additional JS quirk: qutebrowser/javascript/quirks/whatsapp_web.user.js # https://github.com/qutebrowser/qutebrowser/issues/4445 - ("ua-whatsapp", 'https://web.whatsapp.com/', no_qtwe_ua), + ("ua-whatsapp", "https://web.whatsapp.com/", no_qtwe_ua), # Needed to avoid a "you're using a browser [...] that doesn't allow us # to keep your account secure" error. # https://github.com/qutebrowser/qutebrowser/issues/5182 - ("ua-google", 'https://accounts.google.com/*', firefox_ua), - - # Needed because Slack adds an error which prevents using it relatively - # aggressively, despite things actually working fine. - # - # March 2025 situation: - # - https://slack.com/help/articles/1500001836081-Slack-support-lifecycle-for-operating-systems-app-versions-and-browsers - # claims that Chrome 123 is needed - # - Qt 6.9 (130 based) works fine and doesn't display any banner, but is - # not released yet. - # - Qt 6.8 (122 based) displays a "This browser won’t be supported - # starting March 15th, 2025" banner on March 17th, but works just fine - # with the default UA still... - # - With the default UA, Qt 6.7 (118 based) breaks. - # - With the workaround, Qt 6.4 (102 based) still seems to work perfectly fine, - # while Qt 6.3 (94 based) works fine but has some styling issues. - ("ua-slack", 'https://*.slack.com/*', maybe_newer_chrome_ua(123)), + ("ua-google", "https://accounts.google.com/*", firefox_ua), ] for name, pattern, ua in user_agents: diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index 81bccdfc9..523bd29cc 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -658,7 +658,6 @@ content.site_specific_quirks.skip: valid_values: - ua-whatsapp - ua-google - - ua-slack - ua-googledocs - ua-digitecgalaxus - js-whatsapp-web From b16551548fb220be309b64f079cf5495083e7911 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 20:28:15 +0200 Subject: [PATCH 44/69] Remove QtWebEngine/... from default UA Good old https://webaim.org/blog/user-agent-string-history/ strikes yet again. Let's just masquerade as Chromium instead of the constant pointless fight. --- doc/changelog.asciidoc | 17 +++++++++++------ doc/help/settings.asciidoc | 13 +++++-------- .../browser/webengine/webenginesettings.py | 10 ---------- qutebrowser/browser/webengine/webenginetab.py | 5 ----- qutebrowser/config/configdata.yml | 13 +++++-------- .../javascript/quirks/digitecgalaxus.user.js | 17 ----------------- 6 files changed, 21 insertions(+), 54 deletions(-) delete mode 100644 qutebrowser/javascript/quirks/digitecgalaxus.user.js diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 57c0b0b79..fc853dcb8 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -25,6 +25,12 @@ Changed - The `content.headers.user_agent` setting now has a new `{upstream_browser_version_short}` template field, which is the upstream/Chromium version but shortened to only major version. +- The default user agent now uses the shortened Chromium version and doesn't + expose the `QtWebEngine/...` part anymore, thus making it equal to the + corresponding Chromium user agent. This increases compatibilty due to various + overzealous "security" products used by a variety of websites that block + QtWebEngine, presumably as a bot (known issues existed with Whatsapp Web, UPS, + Digitec Galaxus). - Changed features in userscripts: * `qute-bitwarden` now passes your password to the subprocess in an environment variable when unlocking your vault, instead of as a command @@ -38,7 +44,10 @@ Changed Removed ~~~~~~~ -- The `ua-slack` site-specific quirk, as things seem to work better nowadays without a quirk needed. +- The `ua-slack` site-specific quirk, as things seem to work better nowadays + without a quirk needed. +- The `ua-whatsapp` site-specific quirk, as it's unneeded with the default UA + change described above. Fixed ~~~~~ @@ -50,13 +59,9 @@ Fixed error is shown instead). - Crashes when running `:tab-move` or `:yank title` at startup, before a tab is available. -- The default user agent now only contains the shortened Chromium version - number, which fixes overzealous blocking on ScienceDirect. -- New site-specific quirk to fix existing accounts showing as non-existent on - Digitec/Galaxus. - Workaround for microphone/camera permissions not being requested with QtWebEngine 6.9.0 on Google Meet, Zoom, or other pages using the new - `` element. + `` element. (#8539) - Resolved issues in userscripts: * `qute-bitwarden` will now prompt a re-login if its cached session has been invalidated since last used. (#8456) diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 3e68fb720..1d039bc05 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -2279,19 +2279,18 @@ The following placeholders are defined: version, but only with its major version. * `{qutebrowser_version}`: The currently running qutebrowser version. -The default value is equal to the unchanged user agent of -QtWebKit/QtWebEngine. +The default value is equal to the default user agent of +QtWebKit/QtWebEngine, but with the `QtWebEngine/...` part removed for +increased compatibility. -Note that the value read from JavaScript is always the global value. With -QtWebEngine between 5.12 and 5.14 (inclusive), changing the value exposed -to JavaScript requires a restart. +Note that the value read from JavaScript is always the global value. This setting supports link:configuring{outfilesuffix}#patterns[URL patterns]. Type: <> -Default: +pass:[Mozilla/5.0 ({os_info}) AppleWebKit/{webkit_version} (KHTML, like Gecko) {qt_key}/{qt_version} {upstream_browser_key}/{upstream_browser_version_short} Safari/{webkit_version}]+ +Default: +pass:[Mozilla/5.0 ({os_info}) AppleWebKit/{webkit_version} (KHTML, like Gecko) {upstream_browser_key}/{upstream_browser_version_short} Safari/{webkit_version}]+ [[content.hyperlink_auditing]] === content.hyperlink_auditing @@ -2769,10 +2768,8 @@ Type: <> Valid values: - * +ua-whatsapp+ * +ua-google+ * +ua-googledocs+ - * +ua-digitecgalaxus+ * +js-whatsapp-web+ * +js-discord+ * +js-string-replaceall+ diff --git a/qutebrowser/browser/webengine/webenginesettings.py b/qutebrowser/browser/webengine/webenginesettings.py index a37a47b8d..2d2d3c188 100644 --- a/qutebrowser/browser/webengine/webenginesettings.py +++ b/qutebrowser/browser/webengine/webenginesettings.py @@ -495,10 +495,6 @@ def _init_site_specific_quirks(): # "{qt_key}/{qt_version} " # "{upstream_browser_key}/{upstream_browser_version_short} " # "Safari/{webkit_version}") - no_qtwe_ua = ("Mozilla/5.0 ({os_info}) " - "AppleWebKit/{webkit_version} (KHTML, like Gecko) " - "{upstream_browser_key}/{upstream_browser_version_short} " - "Safari/{webkit_version}") firefox_ua = "Mozilla/5.0 ({os_info}; rv:136.0) Gecko/20100101 Firefox/136.0" def maybe_newer_chrome_ua(at_least_version): @@ -517,12 +513,6 @@ def _init_site_specific_quirks(): utils.unused(maybe_newer_chrome_ua) user_agents = [ - # Needed to avoid a ""WhatsApp works with Google Chrome 36+" error - # page which doesn't allow to use WhatsApp Web at all. Also see the - # additional JS quirk: qutebrowser/javascript/quirks/whatsapp_web.user.js - # https://github.com/qutebrowser/qutebrowser/issues/4445 - ("ua-whatsapp", "https://web.whatsapp.com/", no_qtwe_ua), - # Needed to avoid a "you're using a browser [...] that doesn't allow us # to keep your account secure" error. # https://github.com/qutebrowser/qutebrowser/issues/5182 diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index 35e155e8b..cebc77767 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -1201,11 +1201,6 @@ class _WebEngineScripts(QObject): # will be an UA quirk once we set the JS UA as well name='ua-googledocs', ), - _Quirk( - 'digitecgalaxus', - # will be an UA quirk once we set the JS UA as well - name='ua-digitecgalaxus', - ), _Quirk( 'string_replaceall', diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index 523bd29cc..e03fad005 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -656,10 +656,8 @@ content.site_specific_quirks.skip: type: name: FlagList valid_values: - - ua-whatsapp - ua-google - ua-googledocs - - ua-digitecgalaxus - js-whatsapp-web - js-discord - js-string-replaceall @@ -752,7 +750,7 @@ content.headers.referer: content.headers.user_agent: default: 'Mozilla/5.0 ({os_info}) AppleWebKit/{webkit_version} (KHTML, like Gecko) - {qt_key}/{qt_version} {upstream_browser_key}/{upstream_browser_version_short} + {upstream_browser_key}/{upstream_browser_version_short} Safari/{webkit_version}' type: name: FormatString @@ -800,12 +798,11 @@ content.headers.user_agent: version, but only with its major version. * `{qutebrowser_version}`: The currently running qutebrowser version. - The default value is equal to the unchanged user agent of - QtWebKit/QtWebEngine. + The default value is equal to the default user agent of + QtWebKit/QtWebEngine, but with the `QtWebEngine/...` part removed for + increased compatibility. - Note that the value read from JavaScript is always the global value. With - QtWebEngine between 5.12 and 5.14 (inclusive), changing the value exposed - to JavaScript requires a restart. + Note that the value read from JavaScript is always the global value. content.host_blocking.enabled: renamed: content.blocking.enabled diff --git a/qutebrowser/javascript/quirks/digitecgalaxus.user.js b/qutebrowser/javascript/quirks/digitecgalaxus.user.js deleted file mode 100644 index 47870f3c7..000000000 --- a/qutebrowser/javascript/quirks/digitecgalaxus.user.js +++ /dev/null @@ -1,17 +0,0 @@ -// ==UserScript== -// @include https://id.digitecgalaxus.ch/* -// @include https://id.galaxus.eu/* -// ==/UserScript== - -// Needed because their /api/v1/login/_actions/find-user endpoint claims -// that the user does not exist (!?) with the default UA - -"use strict"; - -const originalUserAgent = navigator.userAgent; - -Object.defineProperty(navigator, "userAgent", { - get() { - return originalUserAgent.replace(/QtWebEngine\/[\d.]+ /, ""); - }, -}); From c073a30afe746aded3723c1ae41eaab34c83a4ff Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 20:38:50 +0200 Subject: [PATCH 45/69] Update changelog --- doc/changelog.asciidoc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index fc853dcb8..c127038f6 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -15,8 +15,8 @@ breaking changes (such as renamed commands) can happen in minor releases. // `Fixed` for any bug fixes. // `Security` to invite users to upgrade in case of vulnerabilities. -[[v3.4.1]] -v3.4.1 (unreleased) +[[v3.5.0]] +v3.5.0 (unreleased) ------------------- Changed @@ -59,6 +59,8 @@ Fixed error is shown instead). - Crashes when running `:tab-move` or `:yank title` at startup, before a tab is available. +- Crash with `input.insert_mode.auto_load`, when closing a new tab quickly after + opening it, but before it was fully loaded. (#3895, #8400) - Workaround for microphone/camera permissions not being requested with QtWebEngine 6.9.0 on Google Meet, Zoom, or other pages using the new `` element. (#8539) From 6b5ebe71876124c48b7983ca87614abbbfdcc7c5 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 20:47:54 +0200 Subject: [PATCH 46/69] Add a test for js_async crash Follow-up to c32f5afcc43092de49c0597a0bfd5a1ddf0363ae See #3895 and #8400. --- tests/end2end/test_insert_mode.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/end2end/test_insert_mode.py b/tests/end2end/test_insert_mode.py index 95757591d..a8840069f 100644 --- a/tests/end2end/test_insert_mode.py +++ b/tests/end2end/test_insert_mode.py @@ -56,6 +56,18 @@ def test_auto_load(quteproc, auto_load, background, insert_mode): quteproc.ensure_not_logged(message=log_message) +def test_auto_load_delayed_tab_close(quteproc): + """We shouldn't try to run JS on dead tabs async. + + Triggering the bug is pretty timing-dependent, so this test might still pass + even if a bug is present. Howevber, with those timings, it triggers consistently + on my machine. + """ + quteproc.set_setting('input.insert_mode.auto_load', "true") + quteproc.send_cmd(":later 50 open -t about:blank") + quteproc.send_cmd(":later 110 tab-close") + + def test_auto_leave_insert_mode(quteproc): url_path = 'data/insert_mode_settings/html/autofocus.html' quteproc.open_path(url_path) From afeb1ebbaa6ccc4ad446902381346c419fe16a33 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 20:50:13 +0200 Subject: [PATCH 47/69] tests: Fix TestYamlMigrations.test_user_agent --- tests/unit/config/test_configfiles.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/config/test_configfiles.py b/tests/unit/config/test_configfiles.py index 25e2d7e50..d01a0e721 100644 --- a/tests/unit/config/test_configfiles.py +++ b/tests/unit/config/test_configfiles.py @@ -787,7 +787,6 @@ class TestYamlMigrations: @pytest.mark.parametrize('old, new', [ (None, ('Mozilla/5.0 ({os_info}) ' 'AppleWebKit/{webkit_version} (KHTML, like Gecko) ' - '{qt_key}/{qt_version} ' '{upstream_browser_key}/{upstream_browser_version_short} ' 'Safari/{webkit_version}')), ('toaster', 'toaster'), From 8b820f015b8fa7c13bd203a0e7626dc6405eb04b Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 21:08:26 +0200 Subject: [PATCH 48/69] ci/tox/requirements: Update for Qt 6.9 --- .github/workflows/ci.yml | 4 ++++ misc/requirements/requirements-pyqt-6.9.txt | 7 +++++++ misc/requirements/requirements-pyqt-6.9.txt-raw | 4 ++++ misc/requirements/requirements-pyqt-6.txt | 8 ++++---- misc/requirements/requirements-pyqt.txt | 8 ++++---- tox.ini | 3 ++- 6 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 misc/requirements/requirements-pyqt-6.9.txt create mode 100644 misc/requirements/requirements-pyqt-6.9.txt-raw diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 293b354b1..b293dc338 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -197,6 +197,10 @@ jobs: - testenv: py314-pyqt68 os: ubuntu-24.04 python: "3.14-dev" + ### PyQt 6.9 (Python 3.13) + - testenv: py313-pyqt69 + os: ubuntu-24.04 + python: "3.13" ### macOS Ventura - testenv: py313-pyqt68 os: macos-13 diff --git a/misc/requirements/requirements-pyqt-6.9.txt b/misc/requirements/requirements-pyqt-6.9.txt new file mode 100644 index 000000000..a70577da1 --- /dev/null +++ b/misc/requirements/requirements-pyqt-6.9.txt @@ -0,0 +1,7 @@ +# This file is automatically generated by scripts/dev/recompile_requirements.py + +PyQt6==6.9.0 +PyQt6-Qt6==6.9.0 +PyQt6-WebEngine==6.9.0 +PyQt6-WebEngine-Qt6==6.9.0 +PyQt6_sip==13.10.0 diff --git a/misc/requirements/requirements-pyqt-6.9.txt-raw b/misc/requirements/requirements-pyqt-6.9.txt-raw new file mode 100644 index 000000000..edeae013a --- /dev/null +++ b/misc/requirements/requirements-pyqt-6.9.txt-raw @@ -0,0 +1,4 @@ +PyQt6 >= 6.9, < 6.10 +PyQt6-Qt6 >= 6.9, < 6.10 +PyQt6-WebEngine >= 6.9, < 6.10 +PyQt6-WebEngine-Qt6 >= 6.9, < 6.10 diff --git a/misc/requirements/requirements-pyqt-6.txt b/misc/requirements/requirements-pyqt-6.txt index 84c0d21f7..a70577da1 100644 --- a/misc/requirements/requirements-pyqt-6.txt +++ b/misc/requirements/requirements-pyqt-6.txt @@ -1,7 +1,7 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py -PyQt6==6.8.1 -PyQt6-Qt6==6.8.2 -PyQt6-WebEngine==6.8.0 -PyQt6-WebEngine-Qt6==6.8.2 +PyQt6==6.9.0 +PyQt6-Qt6==6.9.0 +PyQt6-WebEngine==6.9.0 +PyQt6-WebEngine-Qt6==6.9.0 PyQt6_sip==13.10.0 diff --git a/misc/requirements/requirements-pyqt.txt b/misc/requirements/requirements-pyqt.txt index 84c0d21f7..a70577da1 100644 --- a/misc/requirements/requirements-pyqt.txt +++ b/misc/requirements/requirements-pyqt.txt @@ -1,7 +1,7 @@ # This file is automatically generated by scripts/dev/recompile_requirements.py -PyQt6==6.8.1 -PyQt6-Qt6==6.8.2 -PyQt6-WebEngine==6.8.0 -PyQt6-WebEngine-Qt6==6.8.2 +PyQt6==6.9.0 +PyQt6-Qt6==6.9.0 +PyQt6-WebEngine==6.9.0 +PyQt6-WebEngine-Qt6==6.9.0 PyQt6_sip==13.10.0 diff --git a/tox.ini b/tox.ini index 0c966f0e1..18da47b7f 100644 --- a/tox.ini +++ b/tox.ini @@ -56,8 +56,9 @@ deps = pyqt66: -r{toxinidir}/misc/requirements/requirements-pyqt-6.6.txt pyqt67: -r{toxinidir}/misc/requirements/requirements-pyqt-6.7.txt pyqt68: -r{toxinidir}/misc/requirements/requirements-pyqt-6.8.txt + pyqt69: -r{toxinidir}/misc/requirements/requirements-pyqt-6.9.txt commands = - !pyqt-!pyqt515-!pyqt5152-!pyqt62-!pyqt63-!pyqt64-!pyqt65-!pyqt66-!pyqt67-!pyqt68: {envpython} scripts/link_pyqt.py --tox {envdir} + !pyqt-!pyqt515-!pyqt5152-!pyqt62-!pyqt63-!pyqt64-!pyqt65-!pyqt66-!pyqt67-!pyqt68-!pyqt69: {envpython} scripts/link_pyqt.py --tox {envdir} {envpython} -bb -m pytest {posargs:tests} cov: {envpython} scripts/dev/check_coverage.py {posargs} From 40532492292ef85e8a26cfe41ce5972efb6a2c12 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 8 Apr 2025 21:11:43 +0200 Subject: [PATCH 49/69] tests: Fix deprecated usage --- tests/end2end/test_insert_mode.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/end2end/test_insert_mode.py b/tests/end2end/test_insert_mode.py index a8840069f..a28d02770 100644 --- a/tests/end2end/test_insert_mode.py +++ b/tests/end2end/test_insert_mode.py @@ -64,8 +64,8 @@ def test_auto_load_delayed_tab_close(quteproc): on my machine. """ quteproc.set_setting('input.insert_mode.auto_load', "true") - quteproc.send_cmd(":later 50 open -t about:blank") - quteproc.send_cmd(":later 110 tab-close") + quteproc.send_cmd(":cmd-later 50 open -t about:blank") + quteproc.send_cmd(":cmd-later 110 tab-close") def test_auto_leave_insert_mode(quteproc): From 351fef8c1ea6a353f4a74b324744f55cbfce8211 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 10 Apr 2025 15:52:50 +0200 Subject: [PATCH 50/69] Update comment --- qutebrowser/utils/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py index 087bd290c..eaa3662be 100644 --- a/qutebrowser/utils/version.py +++ b/qutebrowser/utils/version.py @@ -641,7 +641,7 @@ class WebEngineVersions: utils.VersionNumber(6, 8, 2): (_BASES[122], '132.0.6834.111'), # 2025-01-22 utils.VersionNumber(6, 8, 3): (_BASES[122], '134.0.6998.89'), # 2025-03-10 - ## Qt 6.9 (Beta 3) + ## Qt 6.9 utils.VersionNumber(6, 9): (_BASES[130], '133.0.6943.141'), # 2025-02-25 } From 3dc212a81520237318f65d130def2a9229eca2d9 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 11 Apr 2025 15:41:59 +0200 Subject: [PATCH 51/69] userscripts: Avoid tldextract warning --- doc/changelog.asciidoc | 1 + misc/userscripts/qute-bitwarden | 20 ++++++++++++++------ misc/userscripts/qute-lastpass | 15 ++++++++++++++- misc/userscripts/qute-pass | 15 ++++++++++++++- 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index c127038f6..79f89bb00 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -67,6 +67,7 @@ Fixed - Resolved issues in userscripts: * `qute-bitwarden` will now prompt a re-login if its cached session has been invalidated since last used. (#8456) + * `qute-bitwarden`, `-lastpass` and `-pass` now avoid a `DeprecationWarning` from the upcoming 6.0 release of `tldextract` [[v3.4.0]] v3.4.0 (2024-12-14) diff --git a/misc/userscripts/qute-bitwarden b/misc/userscripts/qute-bitwarden index 4e883a52e..6a34318f7 100755 --- a/misc/userscripts/qute-bitwarden +++ b/misc/userscripts/qute-bitwarden @@ -204,12 +204,20 @@ def main(arguments): # the registered domain name and finally: the IPv4 address if that's what # the URL represents candidates = [] - for target in filter(None, [ - extract_result.fqdn, - extract_result.registered_domain, - extract_result.subdomain + '.' + extract_result.domain, - extract_result.domain, - extract_result.ipv4]): + for target in filter( + None, + [ + extract_result.fqdn, + getattr( + extract_result, + "top_domain_under_public_suffix", + getattr(extract_result, "registered_domain"), + ), + extract_result.subdomain + "." + extract_result.domain, + extract_result.domain, + extract_result.ipv4, + ], + ): target_candidates = json.loads( pass_( target, diff --git a/misc/userscripts/qute-lastpass b/misc/userscripts/qute-lastpass index d79ef658a..44c68aca4 100755 --- a/misc/userscripts/qute-lastpass +++ b/misc/userscripts/qute-lastpass @@ -117,7 +117,20 @@ def main(arguments): # the URL represents candidates = [] seen_id = set() - for target in filter(None, [extract_result.fqdn, extract_result.registered_domain, extract_result.subdomain + extract_result.domain, extract_result.domain, extract_result.ipv4]): + for target in filter( + None, + [ + extract_result.fqdn, + getattr( + extract_result, + "top_domain_under_public_suffix", + getattr(extract_result, "registered_domain"), + ), + extract_result.subdomain + extract_result.domain, + extract_result.domain, + extract_result.ipv4, + ], + ): target_candidates, err = pass_(target, arguments.io_encoding) if err: stderr("LastPass CLI returned for {:s} - {:s}".format(target, err)) diff --git a/misc/userscripts/qute-pass b/misc/userscripts/qute-pass index 0b483c0e2..1023798cb 100755 --- a/misc/userscripts/qute-pass +++ b/misc/userscripts/qute-pass @@ -243,7 +243,20 @@ def main(arguments): netloc = urlparse(arguments.url).netloc - for target in filter(None, [extract_result.fqdn, extract_result.registered_domain, extract_result.ipv4, private_domain, netloc]): + for target in filter( + None, + [ + extract_result.fqdn, + getattr( + extract_result, + "top_domain_under_public_suffix", + getattr(extract_result, "registered_domain"), + ), + extract_result.ipv4, + private_domain, + netloc, + ], + ): attempted_targets.append(target) target_candidates = find_pass_candidates(target, unfiltered=arguments.unfiltered) if not target_candidates: From 72041686847f6a22bc391f767fccd56a7243f425 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 11 Apr 2025 16:00:45 +0200 Subject: [PATCH 52/69] tests: Try to combat Qt 6.9 flakiness more See #8536 --- tests/end2end/features/qutescheme.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/end2end/features/qutescheme.feature b/tests/end2end/features/qutescheme.feature index ad1d0a48a..dc9343b19 100644 --- a/tests/end2end/features/qutescheme.feature +++ b/tests/end2end/features/qutescheme.feature @@ -305,23 +305,23 @@ Feature: Special qute:// pages @qt69_ci_flaky Scenario: Open qute://version - When I open qute://version + When I open qute://version in a new tab Then the page should contain the plaintext "Version info" # qute://gpl @qt69_ci_flaky Scenario: Open qute://gpl - When I open qute://gpl + When I open qute://gpl in a new tab Then the page should contain the plaintext "GNU GENERAL PUBLIC LICENSE" # qute://start # QtWebKit doesn't support formaction; unknown Qt 6.9 renderer process crashes - @qtwebkit_skip @qt69_ci_skip + @qtwebkit_skip @qt69_ci_flaky Scenario: Searching on qute://start When I set url.searchengines to {"DEFAULT": "http://localhost:(port)/data/title.html?q={}"} - And I open qute://start + And I open qute://start in a new tab And I run :click-element id search-field And I wait for "Entering mode KeyMode.insert *" in the log And I press the keys "test" From 13b87e59686de8e0cf8aba147ad051999447a4f4 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 11 Apr 2025 17:18:06 +0200 Subject: [PATCH 53/69] ci: Avoid Python 3.14 Alpha 7 See https://www.riverbankcomputing.com/pipermail/pyqt/2025-April/046210.html and #8529 --- .github/workflows/ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b293dc338..2d4f0bd47 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -194,9 +194,11 @@ jobs: os: ubuntu-24.04 python: "3.13" ### PyQt 6.8 (Python 3.14) + # Pinned to Alpha 6: + # https://www.riverbankcomputing.com/pipermail/pyqt/2025-April/046210.html - testenv: py314-pyqt68 os: ubuntu-24.04 - python: "3.14-dev" + python: "3.14.0-alpha.6" ### PyQt 6.9 (Python 3.13) - testenv: py313-pyqt69 os: ubuntu-24.04 From 4f4ad4147a3a94e6806c136ba61c2ac989abfff1 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 11 Apr 2025 17:18:32 +0200 Subject: [PATCH 54/69] Revert "tests: Try to combat Qt 6.9 flakiness more" This reverts commit 72041686847f6a22bc391f767fccd56a7243f425. Doesn't actually help on CI... --- tests/end2end/features/qutescheme.feature | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/end2end/features/qutescheme.feature b/tests/end2end/features/qutescheme.feature index dc9343b19..ad1d0a48a 100644 --- a/tests/end2end/features/qutescheme.feature +++ b/tests/end2end/features/qutescheme.feature @@ -305,23 +305,23 @@ Feature: Special qute:// pages @qt69_ci_flaky Scenario: Open qute://version - When I open qute://version in a new tab + When I open qute://version Then the page should contain the plaintext "Version info" # qute://gpl @qt69_ci_flaky Scenario: Open qute://gpl - When I open qute://gpl in a new tab + When I open qute://gpl Then the page should contain the plaintext "GNU GENERAL PUBLIC LICENSE" # qute://start # QtWebKit doesn't support formaction; unknown Qt 6.9 renderer process crashes - @qtwebkit_skip @qt69_ci_flaky + @qtwebkit_skip @qt69_ci_skip Scenario: Searching on qute://start When I set url.searchengines to {"DEFAULT": "http://localhost:(port)/data/title.html?q={}"} - And I open qute://start in a new tab + And I open qute://start And I run :click-element id search-field And I wait for "Entering mode KeyMode.insert *" in the log And I press the keys "test" From 86c89e00c59b323fed7c071ec6d27345f7f093cd Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 11 Apr 2025 17:18:51 +0200 Subject: [PATCH 55/69] Qt 6.9: Skip more qutescheme tests If the renderer process crash happens, rerunning doesn't seem to fix anything, even if the page is opened in a new tab. See #8536 --- tests/end2end/features/qutescheme.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/end2end/features/qutescheme.feature b/tests/end2end/features/qutescheme.feature index ad1d0a48a..7c6a17e21 100644 --- a/tests/end2end/features/qutescheme.feature +++ b/tests/end2end/features/qutescheme.feature @@ -303,14 +303,14 @@ Feature: Special qute:// pages # :version - @qt69_ci_flaky + @qt69_ci_skip Scenario: Open qute://version When I open qute://version Then the page should contain the plaintext "Version info" # qute://gpl - @qt69_ci_flaky + @qt69_ci_skip Scenario: Open qute://gpl When I open qute://gpl Then the page should contain the plaintext "GNU GENERAL PUBLIC LICENSE" From f6f2a1252bf1289e7c82754ce9cdc2d071c711a8 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 11 Apr 2025 17:28:31 +0200 Subject: [PATCH 56/69] tests: Try to stabilize test_auto_leave_insert_mode We sometimes tried to use hints before the page was fully rendered (?), thus causing no elements to be found. It also doesn't make much sense to test leaving insert mode if we aren't in insert mode yet, so make sure we entered it first. See #5390 --- tests/end2end/test_insert_mode.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/end2end/test_insert_mode.py b/tests/end2end/test_insert_mode.py index a28d02770..bc151c5ba 100644 --- a/tests/end2end/test_insert_mode.py +++ b/tests/end2end/test_insert_mode.py @@ -69,8 +69,11 @@ def test_auto_load_delayed_tab_close(quteproc): def test_auto_leave_insert_mode(quteproc): + quteproc.set_setting('input.insert_mode.auto_load', 'true') + url_path = 'data/insert_mode_settings/html/autofocus.html' quteproc.open_path(url_path) + quteproc.wait_for(message='Entering mode KeyMode.insert (reason: *)') quteproc.set_setting('input.insert_mode.auto_leave', 'true') quteproc.send_cmd(':zoom 100') From 1d2faf2fa2b60f8dc11de906af29cbe3648b4fee Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Fri, 11 Apr 2025 19:45:41 +0200 Subject: [PATCH 57/69] Revert "tests: Try to stabilize test_auto_leave_insert_mode" This reverts commit f6f2a1252bf1289e7c82754ce9cdc2d071c711a8. Does more harm than good, for reasons I don't entirely understand yet. --- tests/end2end/test_insert_mode.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/end2end/test_insert_mode.py b/tests/end2end/test_insert_mode.py index bc151c5ba..a28d02770 100644 --- a/tests/end2end/test_insert_mode.py +++ b/tests/end2end/test_insert_mode.py @@ -69,11 +69,8 @@ def test_auto_load_delayed_tab_close(quteproc): def test_auto_leave_insert_mode(quteproc): - quteproc.set_setting('input.insert_mode.auto_load', 'true') - url_path = 'data/insert_mode_settings/html/autofocus.html' quteproc.open_path(url_path) - quteproc.wait_for(message='Entering mode KeyMode.insert (reason: *)') quteproc.set_setting('input.insert_mode.auto_leave', 'true') quteproc.send_cmd(':zoom 100') From 9e0f7ccc513845e59eacf269f83d787debdbbff3 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 12 Apr 2025 21:16:30 +0200 Subject: [PATCH 58/69] tests: Make sure we don't leave stale download managers behind Speculative fix for test_early_timeout_handler in tests/unit/utils/usertypes/test_timer.py failing: > assert len(caplog.messages) == 1 E AssertionError: assert 5 == 1 due to: ------------------------------ Captured log call ------------------------------- WARNING misc:usertypes.py:467 Timer download-update (id 620757000) triggered too early: interval 500 but only -609.805s passed WARNING misc:usertypes.py:467 Timer download-update (id 922746881) triggered too early: interval 500 but only -609.429s passed WARNING misc:usertypes.py:467 Timer download-update (id 1056964613) triggered too early: interval 500 but only -609.537s passed WARNING misc:usertypes.py:467 Timer download-update (id 1912602631) triggered too early: interval 500 but only -609.671s passed WARNING misc:usertypes.py:467 Timer t (id -1) triggered too early: interval 3 but only 0.001s passed --- tests/unit/browser/test_downloads.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/unit/browser/test_downloads.py b/tests/unit/browser/test_downloads.py index 8dd4f0c31..75b9a27cc 100644 --- a/tests/unit/browser/test_downloads.py +++ b/tests/unit/browser/test_downloads.py @@ -10,7 +10,9 @@ from qutebrowser.browser import downloads, qtnetworkdownloads @pytest.fixture def manager(config_stub, cookiejar_and_cache): """A QtNetwork download manager.""" - return qtnetworkdownloads.DownloadManager() + dl_manager = qtnetworkdownloads.DownloadManager() + yield dl_manager + dl_manager.deleteLater() def test_download_model(qapp, qtmodeltester, manager): From 7bc6c33bb5fae09c7b47572bf55b7d38a0dba132 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 12 Apr 2025 21:25:11 +0200 Subject: [PATCH 59/69] Reapply "tests: Try to stabilize test_auto_leave_insert_mode" This reverts commit 1d2faf2fa2b60f8dc11de906af29cbe3648b4fee. This seems to be correct, the issue is the previous test not waiting until it's finished properly. --- tests/end2end/test_insert_mode.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/end2end/test_insert_mode.py b/tests/end2end/test_insert_mode.py index a28d02770..bc151c5ba 100644 --- a/tests/end2end/test_insert_mode.py +++ b/tests/end2end/test_insert_mode.py @@ -69,8 +69,11 @@ def test_auto_load_delayed_tab_close(quteproc): def test_auto_leave_insert_mode(quteproc): + quteproc.set_setting('input.insert_mode.auto_load', 'true') + url_path = 'data/insert_mode_settings/html/autofocus.html' quteproc.open_path(url_path) + quteproc.wait_for(message='Entering mode KeyMode.insert (reason: *)') quteproc.set_setting('input.insert_mode.auto_leave', 'true') quteproc.send_cmd(':zoom 100') From 9aa53ea205110f73278760db4a61198ef88e2d5f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 12 Apr 2025 21:28:30 +0200 Subject: [PATCH 60/69] tests: Wait for tab-close being run properly Leaks into the next test otherwise, making it flaky. --- tests/end2end/test_insert_mode.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/end2end/test_insert_mode.py b/tests/end2end/test_insert_mode.py index bc151c5ba..7b76f605f 100644 --- a/tests/end2end/test_insert_mode.py +++ b/tests/end2end/test_insert_mode.py @@ -66,6 +66,7 @@ def test_auto_load_delayed_tab_close(quteproc): quteproc.set_setting('input.insert_mode.auto_load', "true") quteproc.send_cmd(":cmd-later 50 open -t about:blank") quteproc.send_cmd(":cmd-later 110 tab-close") + quteproc.wait_for(message="command called: tab-close") def test_auto_leave_insert_mode(quteproc): From dea1de5dabcf0b5a7f1c89494211f896d230b322 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sat, 12 Apr 2025 21:33:19 +0200 Subject: [PATCH 61/69] Update changelog --- doc/changelog.asciidoc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 79f89bb00..8ce0eb020 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -22,6 +22,9 @@ v3.5.0 (unreleased) Changed ~~~~~~~ +- Windows/macOS releases are now built with Qt 6.9.0 + * Based on Chromium 130.0.6723.192 + * Security fixes up to Chromium 133.0.6943.141 - The `content.headers.user_agent` setting now has a new `{upstream_browser_version_short}` template field, which is the upstream/Chromium version but shortened to only major version. @@ -67,7 +70,8 @@ Fixed - Resolved issues in userscripts: * `qute-bitwarden` will now prompt a re-login if its cached session has been invalidated since last used. (#8456) - * `qute-bitwarden`, `-lastpass` and `-pass` now avoid a `DeprecationWarning` from the upcoming 6.0 release of `tldextract` + * `qute-bitwarden`, `-lastpass` and `-pass` now avoid a + `DeprecationWarning` from the upcoming 6.0 release of `tldextract` [[v3.4.0]] v3.4.0 (2024-12-14) From 67d8e012a31219ac4cc5ee3e9cd6453e9262c5cf Mon Sep 17 00:00:00 2001 From: qutebrowser bot Date: Sat, 12 Apr 2025 21:28:50 +0000 Subject: [PATCH 62/69] Release v3.5.0 --- .bumpversion.toml | 2 +- doc/changelog.asciidoc | 2 +- misc/org.qutebrowser.qutebrowser.appdata.xml | 1 + qutebrowser/__init__.py | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.bumpversion.toml b/.bumpversion.toml index 51524959d..a2e463db9 100644 --- a/.bumpversion.toml +++ b/.bumpversion.toml @@ -1,5 +1,5 @@ [tool.bumpversion] -current_version = "3.4.0" +current_version = "3.5.0" commit = true message = "Release v{new_version}" tag = true diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 8ce0eb020..b51a43cdd 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -16,7 +16,7 @@ breaking changes (such as renamed commands) can happen in minor releases. // `Security` to invite users to upgrade in case of vulnerabilities. [[v3.5.0]] -v3.5.0 (unreleased) +v3.5.0 (2025-04-12) ------------------- Changed diff --git a/misc/org.qutebrowser.qutebrowser.appdata.xml b/misc/org.qutebrowser.qutebrowser.appdata.xml index 1fcc18cbe..636ceae1d 100644 --- a/misc/org.qutebrowser.qutebrowser.appdata.xml +++ b/misc/org.qutebrowser.qutebrowser.appdata.xml @@ -44,6 +44,7 @@ + diff --git a/qutebrowser/__init__.py b/qutebrowser/__init__.py index 66e4cda81..85b5db5db 100644 --- a/qutebrowser/__init__.py +++ b/qutebrowser/__init__.py @@ -14,7 +14,7 @@ __copyright__ = "Copyright 2013-{} Florian Bruhin (The Compiler)".format(_year) __license__ = "GPL-3.0-or-later" __maintainer__ = __author__ __email__ = "mail@qutebrowser.org" -__version__ = "3.4.0" +__version__ = "3.5.0" __version_info__ = tuple(int(part) for part in __version__.split('.')) __description__ = "A keyboard-driven, vim-like browser based on Python and Qt." From ecbca59deaa1a7bf09fbb59a1c0e8178713ebcb6 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 13 Apr 2025 10:25:43 +0200 Subject: [PATCH 63/69] Update changelog --- doc/changelog.asciidoc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index b51a43cdd..9afb2a0f1 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -15,6 +15,10 @@ breaking changes (such as renamed commands) can happen in minor releases. // `Fixed` for any bug fixes. // `Security` to invite users to upgrade in case of vulnerabilities. +[[v3.5.1]] +v3.5.1 (unreleased) +------------------- + [[v3.5.0]] v3.5.0 (2025-04-12) ------------------- @@ -25,6 +29,7 @@ Changed - Windows/macOS releases are now built with Qt 6.9.0 * Based on Chromium 130.0.6723.192 * Security fixes up to Chromium 133.0.6943.141 + * Also fixes issues with opening links on macOS - The `content.headers.user_agent` setting now has a new `{upstream_browser_version_short}` template field, which is the upstream/Chromium version but shortened to only major version. From 84ec45c13f947078556cc0acc294c19f9ca045d0 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 13 Apr 2025 13:28:34 +0200 Subject: [PATCH 64/69] ci: Try Python 3.14 again Cache is now cleared, so it might just work --- .github/workflows/ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d4f0bd47..656aee3f1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -194,9 +194,7 @@ jobs: os: ubuntu-24.04 python: "3.13" ### PyQt 6.8 (Python 3.14) - # Pinned to Alpha 6: - # https://www.riverbankcomputing.com/pipermail/pyqt/2025-April/046210.html - - testenv: py314-pyqt68 + - testenv: py314-dev os: ubuntu-24.04 python: "3.14.0-alpha.6" ### PyQt 6.9 (Python 3.13) From 77b5c0c1cd9dc7c0d6875cb0bfc83c7180fb84a4 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 13 Apr 2025 13:37:44 +0200 Subject: [PATCH 65/69] ci: Fix config --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 656aee3f1..6debd2df1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -194,9 +194,9 @@ jobs: os: ubuntu-24.04 python: "3.13" ### PyQt 6.8 (Python 3.14) - - testenv: py314-dev + - testenv: py314 os: ubuntu-24.04 - python: "3.14.0-alpha.6" + python: "3.14-dev" ### PyQt 6.9 (Python 3.13) - testenv: py313-pyqt69 os: ubuntu-24.04 From 05b42c57eef3c210e636148e4fb8d9bbb37a2872 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 13 Apr 2025 13:40:37 +0200 Subject: [PATCH 66/69] ci: Fix config properly... --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6debd2df1..b293dc338 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -194,7 +194,7 @@ jobs: os: ubuntu-24.04 python: "3.13" ### PyQt 6.8 (Python 3.14) - - testenv: py314 + - testenv: py314-pyqt68 os: ubuntu-24.04 python: "3.14-dev" ### PyQt 6.9 (Python 3.13) From aa41b6719f474676832b920954b328a20d639c7b Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Sun, 13 Apr 2025 14:53:21 +0200 Subject: [PATCH 67/69] tests: Ignore another message --- tests/end2end/fixtures/quteprocess.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/end2end/fixtures/quteprocess.py b/tests/end2end/fixtures/quteprocess.py index 6db4771e3..7d2856fb7 100644 --- a/tests/end2end/fixtures/quteprocess.py +++ b/tests/end2end/fixtures/quteprocess.py @@ -131,6 +131,8 @@ def is_ignored_chromium_message(line): # Qt 6.2: # [503633:503650:0509/185222.442798:ERROR:ssl_client_socket_impl.cc(959)] handshake failed; returned -1, SSL error code 1, net_error -202 'handshake failed; returned -1, SSL error code 1, net_error -202', + # Qt 6.8 + Python 3.14 + 'handshake failed; returned -1, SSL error code 1, net_error -101', # Qt 6.2: # [2432160:7:0429/195800.168435:ERROR:command_buffer_proxy_impl.cc(140)] ContextResult::kTransientFailure: Failed to send GpuChannelMsg_CreateCommandBuffer. From 95f9472a6be45e3f0e860fe5d41f67d165b4614b Mon Sep 17 00:00:00 2001 From: qutebrowser bot Date: Mon, 14 Apr 2025 04:21:48 +0000 Subject: [PATCH 68/69] Update dependencies --- misc/requirements/requirements-dev.txt | 10 +++++----- misc/requirements/requirements-mypy.txt | 2 +- misc/requirements/requirements-pylint.txt | 4 ++-- misc/requirements/requirements-pyroma.txt | 4 ++-- misc/requirements/requirements-sphinx.txt | 2 +- misc/requirements/requirements-tests.txt | 14 +++++++------- misc/requirements/requirements-tox.txt | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/misc/requirements/requirements-dev.txt b/misc/requirements/requirements-dev.txt index 7ae7b806f..832923a83 100644 --- a/misc/requirements/requirements-dev.txt +++ b/misc/requirements/requirements-dev.txt @@ -6,7 +6,7 @@ autocommand==2.2.2 backports.tarfile==1.2.0 bracex==2.5.post1 build==1.2.2.post1 -bump-my-version==1.1.1 +bump-my-version==1.1.2 certifi==2025.1.31 cffi==1.17.1 charset-normalizer==3.4.1 @@ -16,7 +16,7 @@ docutils==0.21.2 exceptiongroup==1.2.2 github3.py==4.0.1 h11==0.14.0 -httpcore==1.0.7 +httpcore==1.0.8 httpx==0.28.1 hunter==3.7.0 id==1.5.0 @@ -40,7 +40,7 @@ packaging==24.2 platformdirs==4.3.7 prompt_toolkit==3.0.50 pycparser==2.22 -pydantic==2.11.2 +pydantic==2.11.3 pydantic-settings==2.8.1 pydantic_core==2.33.1 Pygments==2.19.1 @@ -66,9 +66,9 @@ tomlkit==0.13.2 twine==6.1.0 typeguard==4.3.0 typing-inspection==0.4.0 -typing_extensions==4.13.1 +typing_extensions==4.13.2 uritemplate==4.1.1 -# urllib3==2.3.0 +# urllib3==2.4.0 wcmatch==10.0 wcwidth==0.2.13 zipp==3.21.0 diff --git a/misc/requirements/requirements-mypy.txt b/misc/requirements/requirements-mypy.txt index f5cc3cf57..475554363 100644 --- a/misc/requirements/requirements-mypy.txt +++ b/misc/requirements/requirements-mypy.txt @@ -15,4 +15,4 @@ types-colorama==0.4.15.20240311 types-docutils==0.21.0.20241128 types-Pygments==2.19.0.20250305 types-PyYAML==6.0.12.20250402 -typing_extensions==4.13.1 +typing_extensions==4.13.2 diff --git a/misc/requirements/requirements-pylint.txt b/misc/requirements/requirements-pylint.txt index cb1c9baa0..299c2f58d 100644 --- a/misc/requirements/requirements-pylint.txt +++ b/misc/requirements/requirements-pylint.txt @@ -21,6 +21,6 @@ requests==2.32.3 six==1.17.0 tomli==2.2.1 tomlkit==0.13.2 -typing_extensions==4.13.1 +typing_extensions==4.13.2 uritemplate==4.1.1 -# urllib3==2.3.0 +# urllib3==2.4.0 diff --git a/misc/requirements/requirements-pyroma.txt b/misc/requirements/requirements-pyroma.txt index a2b9519d3..b2beabb54 100644 --- a/misc/requirements/requirements-pyroma.txt +++ b/misc/requirements/requirements-pyroma.txt @@ -12,6 +12,6 @@ pyproject_hooks==1.2.0 pyroma==4.2 requests==2.32.3 tomli==2.2.1 -trove-classifiers==2025.3.19.19 -urllib3==2.3.0 +trove-classifiers==2025.4.11.15 +urllib3==2.4.0 zipp==3.21.0 diff --git a/misc/requirements/requirements-sphinx.txt b/misc/requirements/requirements-sphinx.txt index abe6d9c69..332583170 100644 --- a/misc/requirements/requirements-sphinx.txt +++ b/misc/requirements/requirements-sphinx.txt @@ -22,5 +22,5 @@ sphinxcontrib-jsmath==1.0.1 sphinxcontrib-qthelp==2.0.0 sphinxcontrib-serializinghtml==2.0.0 tomli==2.2.1 -urllib3==2.3.0 +urllib3==2.4.0 zipp==3.21.0 diff --git a/misc/requirements/requirements-tests.txt b/misc/requirements/requirements-tests.txt index 6e7167167..f6d7c2b77 100644 --- a/misc/requirements/requirements-tests.txt +++ b/misc/requirements/requirements-tests.txt @@ -16,7 +16,7 @@ filelock==3.18.0 Flask==3.1.0 gherkin-official==29.0.0 hunter==3.7.0 -hypothesis==6.130.9 +hypothesis==6.131.0 idna==3.10 importlib_metadata==8.6.1 importlib_resources==6.5.2 @@ -28,14 +28,14 @@ jaraco.context==6.0.1 jaraco.functools==4.1.0 jaraco.text==3.12.1 # Jinja2==3.1.6 -Mako==1.3.9 +Mako==1.3.10 manhole==1.8.1 # MarkupSafe==3.0.2 more-itertools==10.6.0 packaging==24.2 parse==1.20.2 parse_type==0.6.4 -pillow==11.1.0 +pillow==11.2.1 platformdirs==4.3.7 pluggy==1.5.0 py-cpuinfo==9.0.0 @@ -47,7 +47,7 @@ pytest-cov==6.1.1 pytest-instafail==0.5.0 pytest-mock==3.14.0 pytest-qt==4.4.0 -pytest-repeat==0.9.3 +pytest-repeat==0.9.4 pytest-rerunfailures==15.0 pytest-xdist==3.6.1 pytest-xvfb==3.1.1 @@ -57,11 +57,11 @@ requests-file==2.1.0 six==1.17.0 sortedcontainers==2.4.0 soupsieve==2.6 -tldextract==5.1.3 +tldextract==5.2.0 tomli==2.2.1 typeguard==4.3.0 -typing_extensions==4.13.1 -urllib3==2.3.0 +typing_extensions==4.13.2 +urllib3==2.4.0 vulture==2.14 Werkzeug==3.1.3 zipp==3.21.0 diff --git a/misc/requirements/requirements-tox.txt b/misc/requirements/requirements-tox.txt index fea0150a8..6b1a9f51b 100644 --- a/misc/requirements/requirements-tox.txt +++ b/misc/requirements/requirements-tox.txt @@ -13,6 +13,6 @@ pyproject-api==1.9.0 setuptools==78.1.0 tomli==2.2.1 tox==4.25.0 -typing_extensions==4.13.1 +typing_extensions==4.13.2 virtualenv==20.30.0 wheel==0.45.1 From f9933d2f3e9b3c0b98de3cfd82d3024ae38ce576 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Thu, 17 Apr 2025 11:11:33 +0200 Subject: [PATCH 69/69] userscripts: Properly avoid tldextract warning The previous fix in 3dc212a81520237318f65d130def2a9229eca2d9 was insufficient, as the inner `getattr(extract_result, "registered_domain")` was always evaluated first (thus triggering the deprecation warning again). We also cannot do: getattr(extract_result, "top_domain_under_public_suffix", None) or extract_result.registered_domain as `""` is a valid value for it. --- doc/changelog.asciidoc | 8 ++++++++ misc/userscripts/qute-bitwarden | 8 ++++---- misc/userscripts/qute-lastpass | 8 ++++---- misc/userscripts/qute-pass | 8 ++++---- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/doc/changelog.asciidoc b/doc/changelog.asciidoc index 9afb2a0f1..1081bbc40 100644 --- a/doc/changelog.asciidoc +++ b/doc/changelog.asciidoc @@ -19,6 +19,14 @@ breaking changes (such as renamed commands) can happen in minor releases. v3.5.1 (unreleased) ------------------- +Fixed +~~~~~ + +- Resolved issues in userscripts: + * `qute-bitwarden`, `-lastpass` and `-pass` now properly avoid a + `DeprecationWarning` from the upcoming 6.0 release of `tldextract`. + The previous fix in v3.5.1 was insufficient. + [[v3.5.0]] v3.5.0 (2025-04-12) ------------------- diff --git a/misc/userscripts/qute-bitwarden b/misc/userscripts/qute-bitwarden index 6a34318f7..4e7557727 100755 --- a/misc/userscripts/qute-bitwarden +++ b/misc/userscripts/qute-bitwarden @@ -208,10 +208,10 @@ def main(arguments): None, [ extract_result.fqdn, - getattr( - extract_result, - "top_domain_under_public_suffix", - getattr(extract_result, "registered_domain"), + ( + extract_result.top_domain_under_public_suffix + if hasattr(extract_result, "top_domain_under_public_suffix") + else extract_result.registered_domain ), extract_result.subdomain + "." + extract_result.domain, extract_result.domain, diff --git a/misc/userscripts/qute-lastpass b/misc/userscripts/qute-lastpass index 44c68aca4..5a7658699 100755 --- a/misc/userscripts/qute-lastpass +++ b/misc/userscripts/qute-lastpass @@ -121,10 +121,10 @@ def main(arguments): None, [ extract_result.fqdn, - getattr( - extract_result, - "top_domain_under_public_suffix", - getattr(extract_result, "registered_domain"), + ( + extract_result.top_domain_under_public_suffix + if hasattr(extract_result, "top_domain_under_public_suffix") + else extract_result.registered_domain ), extract_result.subdomain + extract_result.domain, extract_result.domain, diff --git a/misc/userscripts/qute-pass b/misc/userscripts/qute-pass index 1023798cb..902f785fd 100755 --- a/misc/userscripts/qute-pass +++ b/misc/userscripts/qute-pass @@ -247,10 +247,10 @@ def main(arguments): None, [ extract_result.fqdn, - getattr( - extract_result, - "top_domain_under_public_suffix", - getattr(extract_result, "registered_domain"), + ( + extract_result.top_domain_under_public_suffix + if hasattr(extract_result, "top_domain_under_public_suffix") + else extract_result.registered_domain ), extract_result.ipv4, private_domain,