diff --git a/doc/help/settings.asciidoc b/doc/help/settings.asciidoc index 672166657..90d6facac 100644 --- a/doc/help/settings.asciidoc +++ b/doc/help/settings.asciidoc @@ -4511,8 +4511,8 @@ Type: <> Default: +pass:[800]+ -[[tabs.show_on_tab_close]] -=== tabs.show_on_tab_close +[[tabs.show_on_close]] +=== tabs.show_on_close Show the tab bar for a short duration when a tab is closed, if tabs.show is set to 'switching'. Type: <> diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index b751aa47a..2b85a8d21 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -2343,9 +2343,9 @@ tabs.show_switching_delay: desc: "Duration (in milliseconds) to show the tab bar before hiding it when tabs.show is set to 'switching'." -tabs.show_on_tab_close: - default: false +tabs.show_on_close: type: Bool + default: false desc: >- Show the tab bar for a short duration when a tab is closed, if tabs.show is set to 'switching'. diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py index 0d60b30a0..996154596 100644 --- a/qutebrowser/mainwindow/tabwidget.py +++ b/qutebrowser/mainwindow/tabwidget.py @@ -746,7 +746,7 @@ class TabBar(QTabBar): def tabRemoved(self, idx): """Update visibility when a tab was removed.""" super().tabRemoved(idx) - if config.val.tabs.show_on_tab_close and config.val.tabs.show == 'switching': + if config.val.tabs.show_on_close and config.val.tabs.show == 'switching': self.show() self._auto_hide_timer.start() else: diff --git a/tests/unit/mainwindow/test_tabwidget.py b/tests/unit/mainwindow/test_tabwidget.py index 4f40620b8..9ea8aa8d4 100644 --- a/tests/unit/mainwindow/test_tabwidget.py +++ b/tests/unit/mainwindow/test_tabwidget.py @@ -162,58 +162,6 @@ class TestTabWidget: widget.addTab(fake_web_tab(), 'foobar' + str(i)) assert not widget.tabBar().isVisible() - def test_show_on_tab_close(self, widget, fake_web_tab, config_stub, monkeypatch): - tab_bar = widget.tabBar() - mock_show = Mock() - mock_start_timer = Mock() - mock_maybe_hide = Mock() - - # Mock the config object that tabwidget.py imports - mock_config_val_tabs = Mock() - mock_config_val = Mock(tabs=mock_config_val_tabs) - mock_config = Mock(val=mock_config_val) - monkeypatch.setattr(tabwidget, 'config', mock_config) - - # Mock the parent class's tabRemoved method to prevent side effects - monkeypatch.setattr(tabwidget.QTabBar, 'tabRemoved', Mock()) - - monkeypatch.setattr(tab_bar, 'show', mock_show) - monkeypatch.setattr(tab_bar._auto_hide_timer, 'start', mock_start_timer) - monkeypatch.setattr(tab_bar, 'maybe_hide', mock_maybe_hide) - - # Test case 1: show_on_tab_close is True, tabs.show is 'switching' - mock_config_val_tabs.show_on_tab_close = True - mock_config_val_tabs.show = 'switching' - tab_bar.tabRemoved(0) - mock_show.assert_called_once() - mock_start_timer.assert_called_once() - mock_maybe_hide.assert_not_called() - - # Reset mocks for next test case - mock_show.reset_mock() - mock_start_timer.reset_mock() - mock_maybe_hide.reset_mock() - - # Test case 2: show_on_tab_close is False - mock_config_val_tabs.show_on_tab_close = False - tab_bar.tabRemoved(0) - mock_show.assert_not_called() - mock_start_timer.assert_not_called() - mock_maybe_hide.assert_called_once() - - # Reset mocks for next test case - mock_show.reset_mock() - mock_start_timer.reset_mock() - mock_maybe_hide.reset_mock() - - # Test case 3: show_on_tab_close is True, tabs.show is not 'switching' - mock_config_val_tabs.show_on_tab_close = True - mock_config_val_tabs.show = 'always' # or 'never', 'multiple' - tab_bar.tabRemoved(0) - mock_show.assert_not_called() - mock_start_timer.assert_not_called() - mock_maybe_hide.assert_called_once() - @pytest.mark.parametrize("num_tabs", [4, 70]) @pytest.mark.parametrize("rev", [True, False]) def test_add_remove_tab_benchmark(self, benchmark, widget, @@ -239,3 +187,51 @@ class TestTabWidget: widget.addTab(fake_web_tab(), 'foobar') tab_bar = widget.tabBar() benchmark(functools.partial(tab_bar._tab_pinned, 0)) + + +class TestTabBarShowOnClose: + + @pytest.fixture + def widget(self, qtbot, monkeypatch, config_stub, fake_web_tab): + """A tab widget with two tabs.""" + w = tabwidget.TabWidget(0) + qtbot.add_widget(w) + monkeypatch.setattr(tabwidget.objects, 'backend', + usertypes.Backend.QtWebKit) + w.addTab(fake_web_tab(), 'tab1') + w.addTab(fake_web_tab(), 'tab2') + w.show() + return w + + def test_show_on_close_true_and_switching(self, widget, config_stub, qtbot): + """Test tabs.show_on_close=True and tabs.show='switching'.""" + config_stub.val.tabs.show = 'switching' + config_stub.val.tabs.show_on_close = True + tab_bar = widget.tabBar() + assert not tab_bar.isVisible() + + widget.removeTab(0) + assert tab_bar.isVisible() + + qtbot.wait(config_stub.val.tabs.show_switching_delay) + assert not tab_bar.isVisible() + + def test_show_on_close_false(self, widget, config_stub): + """Test tabs.show_on_close=False.""" + config_stub.val.tabs.show = 'switching' + config_stub.val.tabs.show_on_close = False + tab_bar = widget.tabBar() + assert not tab_bar.isVisible() + + widget.removeTab(0) + assert not tab_bar.isVisible() + + def test_show_on_close_true_not_switching(self, widget, config_stub): + """Test tabs.show_on_close=True and tabs.show!='switching'.""" + config_stub.val.tabs.show = 'always' + config_stub.val.tabs.show_on_close = True + tab_bar = widget.tabBar() + assert tab_bar.isVisible() + + widget.removeTab(0) + assert tab_bar.isVisible()