Fix focus handling when closing hidden statusbar

From knezi's analysis in #8722:

    The problem was that in Qt, slots are called in the order of connection, so
    even though there's a code that tries to set up the focus correctly, it's
    run after the cmd widget is hidden and hence the focus is already moved and
    it doesn't work as expected.

Follow-up for #2236/#8024.
Fixes #8223.
Supersedes and closes #8722.
Also see #8625 and #8174 (which are not fixed by this).
This commit is contained in:
Florian Bruhin 2025-10-10 20:15:12 +02:00
parent 6b48ae4084
commit 6f21accfae
4 changed files with 19 additions and 2 deletions

View File

@ -49,7 +49,10 @@ Fixed
(#8674).
- Fixed exception when closing a qutebrowser window while a download prompt is
still open.
- Fixed crash with Qt 6.10 (and possibly older Qt versions) when navigating from a `qute://` page to a web page, e.g. when searching on `qute://start`
- Fixed crash with Qt 6.10 (and possibly older Qt versions) when navigating
from a `qute://` page to a web page, e.g. when searching on `qute://start`
- Hopefully proper fix for some web pages jumping to the top when the statusbar
is hidden. (#8223)
[[v3.5.1]]
v3.5.1 (2025-06-05)

View File

@ -562,7 +562,7 @@ class MainWindow(QWidget):
self._completion.on_clear_completion_selection)
self.status.cmd.hide_completion.connect(
self._completion.hide)
self.status.cmd.hide_cmd.connect(self.tabbed_browser.on_release_focus)
self.status.release_focus.connect(self.tabbed_browser.on_release_focus)
def _set_decoration(self, hidden):
"""Set the visibility of the window decoration via Qt."""

View File

@ -140,10 +140,12 @@ class StatusBar(QWidget):
moved: Emitted when the statusbar has moved, so the completion widget
can move to the right position.
arg: The new position.
release_focus: Emitted just before the statusbar is hidden.
"""
resized = pyqtSignal('QRect')
moved = pyqtSignal('QPoint')
release_focus = pyqtSignal()
STYLESHEET = _generate_stylesheet()
@ -284,16 +286,20 @@ class StatusBar(QWidget):
strategy = config.val.statusbar.show
tab = self._current_tab()
if tab is not None and tab.data.fullscreen:
self.release_focus.emit()
self.hide()
elif strategy == 'never':
self.release_focus.emit()
self.hide()
elif strategy == 'in-mode':
try:
mode_manager = modeman.instance(self._win_id)
except modeman.UnavailableError:
self.release_focus.emit()
self.hide()
else:
if mode_manager.mode == usertypes.KeyMode.normal:
self.release_focus.emit()
self.hide()
else:
self.show()

View File

@ -339,3 +339,11 @@ Feature: Scrolling
And I run :tab-next
And I run :jseval --world main checkAnchor()
Then "[*] [PASS] Positions equal: *" should be logged
Scenario: Showing/hiding statusbar (#2236, #8223)
When I set statusbar.show to never
And I run :scroll-to-perc 100
And I wait until the scroll position changed
And I run :cmd-set-text /
And I run :fake-key -g <Escape>
Then "Scroll position changed to Py*.QtCore.QPoint()" should not be logged