diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index 8160b4b7a..9cd29f3b5 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -430,6 +430,14 @@ DATA = OrderedDict([ '20%'), "The width of the tab bar if it's vertical, in px or as percentage " "of the window."), + + ('indicator-width', + SettingValue(types.Int(minval=0), '3'), + "Width of the progress indicator."), + + ('indicator-space', + SettingValue(types.Int(minval=0), '3'), + "Spacing between tab edge and indicator."), )), ('storage', sect.KeyValue( @@ -874,6 +882,22 @@ DATA = OrderedDict([ SettingValue(types.Color(), '#555555'), "Background color of the tabbar."), + ('tab.indicator.start', + SettingValue(types.QtColor(), '#0000aa'), + "Color gradient start for the tab indicator."), + + ('tab.indicator.stop', + SettingValue(types.QtColor(), '#00aa00'), + "Color gradient end for the tab indicator."), + + ('tab.indicator.error', + SettingValue(types.QtColor(), '#ff0000'), + "Color for the tab indicator on errors.."), + + ('tab.indicator.system', + SettingValue(types.ColorSystem(), 'rgb'), + "Color gradient interpolation system for the tab indicator."), + ('tab.seperator', SettingValue(types.Color(), '#555555'), "Color for the tab seperator."), diff --git a/qutebrowser/widgets/tabbedbrowser.py b/qutebrowser/widgets/tabbedbrowser.py index c4f5af38a..eab090da0 100644 --- a/qutebrowser/widgets/tabbedbrowser.py +++ b/qutebrowser/widgets/tabbedbrowser.py @@ -29,6 +29,7 @@ import qutebrowser.config.config as config import qutebrowser.commands.utils as cmdutils import qutebrowser.keyinput.modeman as modeman import qutebrowser.utils.log as log +import qutebrowser.utils.misc as utils from qutebrowser.widgets.tabwidget import TabWidget from qutebrowser.widgets.webview import WebView from qutebrowser.browser.signalfilter import SignalFilter @@ -181,6 +182,8 @@ class TabbedBrowser(TabWidget): # misc tab.titleChanged.connect(partial(self.on_title_changed, tab)) tab.iconChanged.connect(partial(self.on_icon_changed, tab)) + tab.loadProgress.connect(partial(self.on_load_progress, tab)) + frame.loadFinished.connect(partial(self.on_load_finished, tab)) frame.loadStarted.connect(partial(self.on_load_started, tab)) page.windowCloseRequested.connect( partial(self.on_window_close_requested, tab)) @@ -442,6 +445,27 @@ class TabbedBrowser(TabWidget): self.current_tab_changed.emit(tab) self.title_changed.emit('{} - qutebrowser'.format(self.tabText(idx))) + def on_load_progress(self, tab, perc): + """Adjust tab indicator on load progress.""" + idx = self.indexOf(tab) + start = config.get('colors', 'tab.indicator.start') + stop = config.get('colors', 'tab.indicator.stop') + system = config.get('colors', 'tab.indicator.system') + color = utils.interpolate_color(start, stop, perc, system) + self.tabBar().set_tab_indicator_color(idx, color) + + def on_load_finished(self, tab, ok): + """Adjust tab indicator when loading finished.""" + idx = self.indexOf(tab) + if ok: + start = config.get('colors', 'tab.indicator.start') + stop = config.get('colors', 'tab.indicator.stop') + system = config.get('colors', 'tab.indicator.system') + color = utils.interpolate_color(start, stop, 100, system) + else: + color = config.get('colors', 'tab.indicator.error') + self.tabBar().set_tab_indicator_color(idx, color) + def resizeEvent(self, e): """Extend resizeEvent of QWidget to emit a resized signal afterwards. diff --git a/qutebrowser/widgets/tabwidget.py b/qutebrowser/widgets/tabwidget.py index 23597d8fd..ab65e7f68 100644 --- a/qutebrowser/widgets/tabwidget.py +++ b/qutebrowser/widgets/tabwidget.py @@ -26,15 +26,15 @@ Module attributes: import functools -from PyQt5.QtCore import pyqtSlot, Qt, QSize, QRect +from PyQt5.QtCore import pyqtSlot, Qt, QSize, QRect, QPoint from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle, QStyle, QStylePainter, QStyleOptionTab, QApplication) from PyQt5.QtGui import QIcon, QPalette, QColor -import qutebrowser.config.config as config from qutebrowser.config.style import set_register_stylesheet from qutebrowser.utils.qt import qt_ensure_valid +import qutebrowser.config.config as config PM_TabBarPadding = QStyle.PM_CustomBase @@ -125,6 +125,16 @@ class TabBar(QTabBar): return '<{} with {} tabs>'.format(self.__class__.__name__, self.count()) + def set_tab_indicator_color(self, idx, color): + """Set the tab indicator color. + + Args: + idx: The tab index. + color: A QColor. + """ + self.setTabData(idx, color) + self.update(self.tabRect(idx)) + def mousePressEvent(self, e): """Override mousePressEvent to close tabs if configured.""" button = config.get('tabbar', 'close-mouse-button') @@ -216,6 +226,10 @@ class TabBar(QTabBar): tab.palette.setColor(QPalette.Window, QColor(color)) tab.palette.setColor(QPalette.WindowText, QColor(config.get('colors', 'tab.fg'))) + indicator_color = self.tabData(idx) + if indicator_color is None: + indicator_color = QColor() + tab.palette.setColor(QPalette.Base, indicator_color) if tab.rect.right() < 0 or tab.rect.left() > self.width(): # Don't bother drawing a tab if the entire tab is outside of # the visible tab bar. @@ -279,11 +293,18 @@ class TabBarStyle(QCommonStyle): self.drawControl(QStyle.CE_TabBarTabShape, opt, p, widget) self.drawControl(QStyle.CE_TabBarTabLabel, opt, p, widget) elif element == QStyle.CE_TabBarTabShape: + p.fillRect(opt.rect, opt.palette.window()) + indicator_color = opt.palette.base().color() + indicator_width = config.get('tabbar', 'indicator-width') + if indicator_color.isValid() and indicator_width != 0: + topleft = opt.rect.topLeft() + topleft += QPoint(config.get('tabbar', 'indicator-space'), 2) + p.fillRect(topleft.x(), topleft.y(), indicator_width, + opt.rect.height() - 4, indicator_color) # We use super() rather than self._style here because we don't want # any sophisticated drawing. super().drawControl(QStyle.CE_TabBarTabShape, opt, p, widget) elif element == QStyle.CE_TabBarTabLabel: - p.fillRect(opt.rect, opt.palette.window()) text_rect, icon_rect = self._tab_layout(opt) if not opt.icon.isNull(): qt_ensure_valid(icon_rect) @@ -359,6 +380,8 @@ class TabBarStyle(QCommonStyle): text_rect = QRect(opt.rect) qt_ensure_valid(text_rect) text_rect.adjust(padding, 0, 0, 0) + text_rect.adjust(config.get('tabbar', 'indicator-width') + + config.get('tabbar', 'indicator-space'), 0, 0, 0) if not opt.icon.isNull(): icon_rect = self._get_icon_rect(opt, text_rect) text_rect.adjust(icon_rect.width() + padding, 0, 0, 0)