diff --git a/qutebrowser/config/configdata.yml b/qutebrowser/config/configdata.yml index 5e47eb84e..ff67cc414 100644 --- a/qutebrowser/config/configdata.yml +++ b/qutebrowser/config/configdata.yml @@ -1171,6 +1171,23 @@ statusbar.position: default: bottom desc: Position of the status bar. +statusbar.widgets: + type: + name: List + valtype: + name: String + valid_values: + - url: "Current page URL." + - scroll: "Percentage of the current page position like `10%`." + - scroll_raw: "Raw percentage of the current page position like `10`." + - history: "Display an arrow when possible to go back/forward in history." + - tabs: "Current active tab, e.g. `2`." + - keypress: "Display pressed keys when composing a vi command." + - progress: "Progress bar for the current page loading." + none_ok: true + default: ['keypress', 'url', 'scroll', 'history', 'tabs', 'progress'] + desc: List of widgets displayed in the statusbar. + ## tabs tabs.background: diff --git a/qutebrowser/mainwindow/statusbar/backforward.py b/qutebrowser/mainwindow/statusbar/backforward.py index b214b894d..8ea60ee75 100644 --- a/qutebrowser/mainwindow/statusbar/backforward.py +++ b/qutebrowser/mainwindow/statusbar/backforward.py @@ -26,6 +26,10 @@ class Backforward(textbase.TextBase): """Shows navigation indicator (if you can go backward and/or forward).""" + def __init__(self, parent=None): + super().__init__(parent) + self.enabled = False + def on_tab_cur_url_changed(self, tabs): """Called on URL changes.""" tab = tabs.currentWidget() @@ -45,4 +49,4 @@ class Backforward(textbase.TextBase): if text: text = '[' + text + ']' self.setText(text) - self.setVisible(bool(text)) + self.setVisible(bool(text) and self.enabled) diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py index ae6832eb0..8057bfdb8 100644 --- a/qutebrowser/mainwindow/statusbar/bar.py +++ b/qutebrowser/mainwindow/statusbar/bar.py @@ -182,26 +182,13 @@ class StatusBar(QWidget): self.cmd.hide_cmd.connect(self._hide_cmd_widget) self._hide_cmd_widget() - self.keystring = keystring.KeyString() - self._hbox.addWidget(self.keystring) - self.url = url.UrlText() - self._hbox.addWidget(self.url) - self.percentage = percentage.Percentage() - self._hbox.addWidget(self.percentage) - self.backforward = backforward.Backforward() - self._hbox.addWidget(self.backforward) - self.tabindex = tabindex.TabIndex() - self._hbox.addWidget(self.tabindex) - - # We add a parent to Progress here because it calls self.show() based - # on some signals, and if that happens before it's added to the layout, - # it will quickly blink up as independent window. + self.keystring = keystring.KeyString() self.prog = progress.Progress(self) - self._hbox.addWidget(self.prog) + self._draw_widgets() config.instance.changed.connect(self._on_config_changed) QTimer.singleShot(0, self.maybe_hide) @@ -215,6 +202,48 @@ class StatusBar(QWidget): self.maybe_hide() elif option == 'statusbar.padding': self._set_hbox_padding() + elif option == 'statusbar.widgets': + self._draw_widgets() + + def _draw_widgets(self): + """Draw statusbar widgets.""" + # Start with widgets hidden and show them when needed + for widget in [self.url, self.percentage, + self.backforward, self.tabindex, + self.keystring, self.prog]: + widget.hide() + self._hbox.removeWidget(widget) + + tab = self._current_tab() + + # Read the list and set widgets accordingly + for segment in config.val.statusbar.widgets: + if segment == 'url': + self._hbox.addWidget(self.url) + self.url.show() + elif segment == 'scroll': + self._hbox.addWidget(self.percentage) + self.percentage.show() + elif segment == 'scroll_raw': + self._hbox.addWidget(self.percentage) + self.percentage.raw = True + self.percentage.show() + elif segment == 'history': + self._hbox.addWidget(self.backforward) + self.backforward.enabled = True + if tab: + self.backforward.on_tab_changed(tab) + elif segment == 'tabs': + self._hbox.addWidget(self.tabindex) + self.tabindex.show() + elif segment == 'keypress': + self._hbox.addWidget(self.keystring) + self.keystring.show() + elif segment == 'progress': + self._hbox.addWidget(self.prog) + self.prog.enabled = True + if tab: + self.prog.on_tab_changed(tab) @pyqtSlot() def maybe_hide(self): diff --git a/qutebrowser/mainwindow/statusbar/percentage.py b/qutebrowser/mainwindow/statusbar/percentage.py index a3f30e50d..a362fd9d6 100644 --- a/qutebrowser/mainwindow/statusbar/percentage.py +++ b/qutebrowser/mainwindow/statusbar/percentage.py @@ -32,6 +32,7 @@ class Percentage(textbase.TextBase): """Constructor. Set percentage to 0%.""" super().__init__(parent) self.set_perc(0, 0) + self.raw = False @pyqtSlot(int, int) def set_perc(self, x, y): # pylint: disable=unused-argument @@ -48,7 +49,8 @@ class Percentage(textbase.TextBase): elif y is None: self.setText('[???]') else: - self.setText('[{:2}%]'.format(y)) + text = '[{:02}]' if self.raw else '[{:02}%]' + self.setText(text.format(y)) def on_tab_changed(self, tab): """Update scroll position when tab changed.""" diff --git a/qutebrowser/mainwindow/statusbar/progress.py b/qutebrowser/mainwindow/statusbar/progress.py index 930282771..6c467150b 100644 --- a/qutebrowser/mainwindow/statusbar/progress.py +++ b/qutebrowser/mainwindow/statusbar/progress.py @@ -46,6 +46,7 @@ class Progress(QProgressBar): def __init__(self, parent=None): super().__init__(parent) config.set_register_stylesheet(self) + self.enabled = False self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.setTextVisible(False) self.hide() @@ -57,12 +58,12 @@ class Progress(QProgressBar): def on_load_started(self): """Clear old error and show progress, used as slot to loadStarted.""" self.setValue(0) - self.show() + self.setVisible(self.enabled) def on_tab_changed(self, tab): """Set the correct value when the current tab changed.""" self.setValue(tab.progress()) - if tab.load_status() == usertypes.LoadStatus.loading: + if self.enabled and tab.load_status() == usertypes.LoadStatus.loading: self.show() else: self.hide() diff --git a/tests/unit/mainwindow/statusbar/test_backforward.py b/tests/unit/mainwindow/statusbar/test_backforward.py index b355fcfdf..6e594c0d2 100644 --- a/tests/unit/mainwindow/statusbar/test_backforward.py +++ b/tests/unit/mainwindow/statusbar/test_backforward.py @@ -45,14 +45,22 @@ def test_backforward_widget(backforward_widget, tabbed_browser_stubs, tabbed_browser = tabbed_browser_stubs[0] tabbed_browser.current_index = 1 tabbed_browser.tabs = [tab] + backforward_widget.enabled = True backforward_widget.on_tab_cur_url_changed(tabbed_browser) assert backforward_widget.text() == expected_text assert backforward_widget.isVisible() == bool(expected_text) + # Check that the widget stays hidden if not in the statusbar + backforward_widget.enabled = False + backforward_widget.hide() + backforward_widget.on_tab_cur_url_changed(tabbed_browser) + assert backforward_widget.isHidden() + # Check that the widget gets reset if empty. if can_go_back and can_go_forward: tab = fake_web_tab(can_go_back=False, can_go_forward=False) tabbed_browser.tabs = [tab] + backforward_widget.enabled = True backforward_widget.on_tab_cur_url_changed(tabbed_browser) assert backforward_widget.text() == '' assert not backforward_widget.isVisible() @@ -64,6 +72,7 @@ def test_none_tab(backforward_widget, tabbed_browser_stubs, fake_web_tab): tabbed_browser = tabbed_browser_stubs[0] tabbed_browser.current_index = 1 tabbed_browser.tabs = [tab] + backforward_widget.enabled = True backforward_widget.on_tab_cur_url_changed(tabbed_browser) assert backforward_widget.text() == '[<>]' diff --git a/tests/unit/mainwindow/statusbar/test_percentage.py b/tests/unit/mainwindow/statusbar/test_percentage.py index 91de051d1..c7b5b9fe2 100644 --- a/tests/unit/mainwindow/statusbar/test_percentage.py +++ b/tests/unit/mainwindow/statusbar/test_percentage.py @@ -33,15 +33,21 @@ def percentage(qtbot): return widget -@pytest.mark.parametrize('y, expected', [ - (0, '[top]'), - (100, '[bot]'), - (75, '[75%]'), - (25, '[25%]'), - (5, '[ 5%]'), - (None, '[???]'), +@pytest.mark.parametrize('y, raw, expected', [ + (0, False, '[top]'), + (100, False, '[bot]'), + (75, False, '[75%]'), + (25, False, '[25%]'), + (5, False, '[05%]'), + (None, False, '[???]'), + (0, True, '[top]'), + (100, True, '[bot]'), + (75, True, '[75]'), + (25, True, '[25]'), + (5, True, '[05]'), + (None, True, '[???]'), ]) -def test_percentage_text(percentage, y, expected): +def test_percentage_text(percentage, y, raw, expected): """Test text displayed by the widget based on the y position of a page. Args: @@ -49,6 +55,7 @@ def test_percentage_text(percentage, y, expected): parametrized. expected: expected text given y position. parametrized. """ + percentage.raw = raw percentage.set_perc(x=None, y=y) assert percentage.text() == expected diff --git a/tests/unit/mainwindow/statusbar/test_progress.py b/tests/unit/mainwindow/statusbar/test_progress.py index 763ea1059..6d054a5c9 100644 --- a/tests/unit/mainwindow/statusbar/test_progress.py +++ b/tests/unit/mainwindow/statusbar/test_progress.py @@ -30,6 +30,7 @@ from qutebrowser.utils import usertypes def progress_widget(qtbot, config_stub): """Create a Progress widget and checks its initial state.""" widget = Progress() + widget.enabled = True qtbot.add_widget(widget) assert not widget.isVisible() assert not widget.isTextVisible()