summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Albrecht <palbrecht@mailbox.org>2023-08-13 13:33:04 +0200
committerPhilipp Albrecht <palbrecht@mailbox.org>2023-08-16 09:39:51 +0200
commit5faae69f7711578182ad6b85bbe893f2b0e6ef8e (patch)
tree35c562824c60f003ee9ccce04bd0b237ad1bcc00
parent0d431ddc5dd83def79aff884033b34ee3e597abe (diff)
downloadqutebrowser-5faae69f7711578182ad6b85bbe893f2b0e6ef8e.tar.gz
qutebrowser-5faae69f7711578182ad6b85bbe893f2b0e6ef8e.zip
Skip invalid history items when saving a session
Opening a download in a new tab leaves a "dead" tab (see example of a "dead" tab below) behind. When saving a session containing such a "dead" tab, we end up with entries in the session like this one: ```yaml - active: true history: - active: true last_visited: '1970-01-01T02:00:00' pinned: false scroll-pos: x: 0 y: 0 title: '' url: '' zoom: 1.0 ``` When loading a session containing such a "dead" tab, qutebrowser does not restore any history of that session and logs the following error: ``` ERROR: Failed to load session default: PyQt6.QtCore.QUrl('') is not valid ``` As pointed out by @The-Compiler in this comment[1], the behavior of `QWebEngineHistoryItem::isValid()`[2] changed somehow between Qt 6.4 and 6.5. `QWebEngineHistoryItem::isValid()` now returns `True` for "dead" tabs, even though the history item is not valid (i.e. `url().isValid()` returns `False`). To fix this we simply add an additional check if the URL is valid before adding a tab to the session to be saved. [1] https://github.com/qutebrowser/qutebrowser/issues/7696#issuecomment-1672854592 [2] https://github.com/qt/qtwebengine/blob/v6.5.2/src/core/api/qwebenginehistory.cpp#L69-L75
-rw-r--r--qutebrowser/misc/sessions.py7
-rw-r--r--tests/end2end/features/sessions.feature20
2 files changed, 27 insertions, 0 deletions
diff --git a/qutebrowser/misc/sessions.py b/qutebrowser/misc/sessions.py
index da447c747..dd63904cd 100644
--- a/qutebrowser/misc/sessions.py
+++ b/qutebrowser/misc/sessions.py
@@ -239,6 +239,13 @@ class SessionManager(QObject):
for idx, item in enumerate(history):
qtutils.ensure_valid(item)
item_data = self._save_tab_item(tab, idx, item)
+
+ if not item.url().isValid():
+ # WORKAROUND Qt 6.5 regression
+ # https://github.com/qutebrowser/qutebrowser/issues/7696
+ log.sessions.debug(f"Skipping invalid history item: {item}")
+ continue
+
if item.url().scheme() == 'qute' and item.url().host() == 'back':
# don't add qute://back to the session file
if item_data.get('active', False) and data['history']:
diff --git a/tests/end2end/features/sessions.feature b/tests/end2end/features/sessions.feature
index a5533f014..9a61baf61 100644
--- a/tests/end2end/features/sessions.feature
+++ b/tests/end2end/features/sessions.feature
@@ -328,6 +328,26 @@ Feature: Saving and loading sessions
- active: true
url: http://localhost:*/data/numbers/5.txt
+ # https://github.com/qutebrowser/qutebrowser/issues/7696
+ @qtwebkit_skip
+ Scenario: Saving session with an empty download tab
+ When I open data/downloads/downloads.html
+ And I run :click-element --force-event -t tab id download
+ And I wait for "Asking question <qutebrowser.utils.usertypes.Question default='*' mode=<PromptMode.download: 5> *" in the log
+ And I run :mode-leave
+ And I run :session-save current
+ And I run :session-load --clear current
+ And I wait until data/downloads/downloads.html is loaded
+ Then the session should look like:
+ windows:
+ - tabs:
+ - history:
+ - active: true
+ title: Simple downloads
+ url: http://localhost:*/data/downloads/downloads.html
+ - active: true
+ history: []
+
# :session-delete
Scenario: Deleting a directory