From fb9ac1bc4c96ddaef1f616a1251ba8e915a5a7ac Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 22 Apr 2014 20:49:16 +0200 Subject: [PATCH 01/11] Restyle tabbar --- THANKS | 1 + qutebrowser/config/configdata.py | 12 ++++++++---- qutebrowser/widgets/tabwidget.py | 8 ++------ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/THANKS b/THANKS index 3c38b4427..106f95e35 100644 --- a/THANKS +++ b/THANKS @@ -24,6 +24,7 @@ valuable ones: - andrean - chelmuth - quark + - Bleeding Fingers Thanks to these people for helpful bits and pieces in the Qt bugtracker and IRC channel: diff --git a/qutebrowser/config/configdata.py b/qutebrowser/config/configdata.py index a439c09d5..808b61b18 100644 --- a/qutebrowser/config/configdata.py +++ b/qutebrowser/config/configdata.py @@ -497,18 +497,22 @@ DATA = OrderedDict([ ('tab.fg', SettingValue(types.Color(), "white"), - "Foreground color of the tabbar."), + "Foreground color of tabs."), ('tab.bg', SettingValue(types.Color(), "grey"), - "Background color of the tabbar."), + "Background color of unselected tabs."), ('tab.bg.selected', SettingValue(types.Color(), "black"), - "Background color of the tabbar for the selected tab."), + "Background color of selected tabs."), + + ('tab.bg.bar', + SettingValue(types.Color(), "#555555"), + "Background color of the tabbar."), ('tab.seperator', - SettingValue(types.Color(), "white"), + SettingValue(types.Color(), "#555555"), "Color for the tab seperator."), ('hints.fg', diff --git a/qutebrowser/widgets/tabwidget.py b/qutebrowser/widgets/tabwidget.py index f19c0c6c7..a05a56319 100644 --- a/qutebrowser/widgets/tabwidget.py +++ b/qutebrowser/widgets/tabwidget.py @@ -33,9 +33,6 @@ class TabWidget(QTabWidget): STYLESHEET: The stylesheet template to be used. """ - # FIXME there is still some ugly 1px white stripe from somewhere if we do - # background-color: grey for QTabBar... - STYLESHEET = """ QTabWidget::pane {{ position: absolute; @@ -44,6 +41,7 @@ class TabWidget(QTabWidget): QTabBar {{ {font[tabbar]} + {color[tab.bg.bar]} }} QTabBar::tab {{ @@ -53,9 +51,6 @@ class TabWidget(QTabWidget): padding-right: 5px; padding-top: 0px; padding-bottom: 0px; - }} - - QTabBar::tab:first, QTabBar::tab:middle {{ border-right: 1px solid {color[tab.seperator]}; }} @@ -71,6 +66,7 @@ class TabWidget(QTabWidget): set_register_stylesheet(self) self.setDocumentMode(True) self.setElideMode(Qt.ElideRight) + self.tabBar().setDrawBase(False) self._init_config() def _init_config(self): From 06ff2e00e9ed5a704e44c9ccd2d3c841f1a460e5 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 22 Apr 2014 21:38:06 +0200 Subject: [PATCH 02/11] Always draw categories correctly in completion --- qutebrowser/models/completion.py | 9 +++++---- qutebrowser/widgets/completion.py | 10 ++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/qutebrowser/models/completion.py b/qutebrowser/models/completion.py index 4f95351ac..7cd0d8ab2 100644 --- a/qutebrowser/models/completion.py +++ b/qutebrowser/models/completion.py @@ -263,11 +263,12 @@ class CompletionModel(QAbstractItemModel): """ if not index.isValid(): return Qt.NoItemFlags - flags = Qt.ItemIsEnabled - if len(self._id_map[index.internalId()].children) > 0: - return flags + if index.parent().isValid(): + # item + return Qt.ItemIsEnabled | Qt.ItemIsSelectable else: - return flags | Qt.ItemIsSelectable + # category + return Qt.NoItemFlags def index(self, row, column, parent=QModelIndex()): """Return the QModelIndex for row/column/parent. diff --git a/qutebrowser/widgets/completion.py b/qutebrowser/widgets/completion.py index 9363fc32d..7c80c1d95 100644 --- a/qutebrowser/widgets/completion.py +++ b/qutebrowser/widgets/completion.py @@ -79,17 +79,20 @@ class CompletionView(QTreeView): {color[completion.bg]} outline: 0; }} - QTreeView::item {{ + + QTreeView::item:enabled {{ {color[completion.item.fg]} {color[completion.item.bg]} }} - QTreeView::item:has-children {{ + + QTreeView::item:disabled {{ {color[completion.category.fg]} {color[completion.category.bg]} border-top: 1px solid {color[completion.category.border.top]}; border-bottom: 1px solid {color[completion.category.border.bottom]}; }} + QTreeView::item:selected {{ border-top: 1px solid {color[completion.item.selected.border.top]}; border-bottom: 1px solid @@ -98,8 +101,7 @@ class CompletionView(QTreeView): {color[completion.item.selected.fg]} }} """ - # FIXME because we use :has-children, if a category is empty, it won't look - # like one anymore + change_completed_part = pyqtSignal(str) def __init__(self, parent=None): From 21bb9840d9596a31a6b89d419c5b7b89b02a4649 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 22 Apr 2014 23:02:51 +0200 Subject: [PATCH 03/11] Simplify padding in Qt-CSS --- THANKS | 1 + qutebrowser/widgets/tabwidget.py | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/THANKS b/THANKS index 106f95e35..6273bb206 100644 --- a/THANKS +++ b/THANKS @@ -52,6 +52,7 @@ channel: - AlexWMF - scummos - svuorela + - kpj Thanks to these projects which were essential while developing qutebrowser: - Python diff --git a/qutebrowser/widgets/tabwidget.py b/qutebrowser/widgets/tabwidget.py index a05a56319..80521d69e 100644 --- a/qutebrowser/widgets/tabwidget.py +++ b/qutebrowser/widgets/tabwidget.py @@ -47,10 +47,7 @@ class TabWidget(QTabWidget): QTabBar::tab {{ {color[tab.bg]} {color[tab.fg]} - padding-left: 5px; - padding-right: 5px; - padding-top: 0px; - padding-bottom: 0px; + padding: 0px 5px 0px 5px; border-right: 1px solid {color[tab.seperator]}; }} From 877fe2402b6321c8431271f2d87047238663df8a Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 22 Apr 2014 23:25:51 +0200 Subject: [PATCH 04/11] Update TODO --- TODO | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index d416d77bd..f0eb17fda 100644 --- a/TODO +++ b/TODO @@ -11,6 +11,7 @@ Style ===== Refactor completion widget mess (initializing / changing completions) +keypress-signal-foo is a bit of a chaos and might be done better Major features ============== @@ -25,7 +26,6 @@ Plugin architecture NoScript Certificate Patrol https://chrome.google.com/webstore/detail/remove-google-redirects/ccenmflbeofaceccfhhggbagkblihpoh -Insert mode Extern editor Downloads webinterface for settings/colors/bindings @@ -37,6 +37,12 @@ Before Blink session handling / saving IPC, like dwb -x Mode handling? + - Problem: how to detect we're going to insert mode: + -> Detect mouse clicks and use QWebFrame::hitTestContent (only mouse) + -> Use javascript: http://stackoverflow.com/a/2848120/2085149 + -> Use microFocusChanged and check active element via: + frame = page.currentFrame() + elem = frame.findFirstElement('*:focus') Bookmarks Internationalization Marks @@ -53,7 +59,16 @@ handle completion for aliases keybind should have completion for commands/arguments Hiding scrollbars Ctrl+A/X to increase/decrease last number in URL -keypress-signal-foo is a bit of a chaos and might be done better +command completion gets hidden when doing a new ValueList value + +Qt Bugs +======== + +- Printing under windows produced blank pages + https://bugreports.qt-project.org/browse/QTBUG-19571 + If this isn't fixed in Qt 5.3, bug should be reopened. + +- Web inspector is blank unless .hide()/.show() is called. Other stuff =========== From 48d0215a98901b577e3d3655249175167f7cc248 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 22 Apr 2014 23:30:33 +0200 Subject: [PATCH 05/11] Update TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index f0eb17fda..f18e844ca 100644 --- a/TODO +++ b/TODO @@ -60,6 +60,8 @@ keybind should have completion for commands/arguments Hiding scrollbars Ctrl+A/X to increase/decrease last number in URL command completion gets hidden when doing a new ValueList value +log_events class decorator +logging contexts Qt Bugs ======== From 46f1a2a0d07d649ae14660340e54913a4fc2af46 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 22 Apr 2014 23:50:56 +0200 Subject: [PATCH 06/11] Add log_events decorator --- TODO | 1 - qutebrowser/utils/debug.py | 22 +++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index f18e844ca..6fb83bfad 100644 --- a/TODO +++ b/TODO @@ -60,7 +60,6 @@ keybind should have completion for commands/arguments Hiding scrollbars Ctrl+A/X to increase/decrease last number in URL command completion gets hidden when doing a new ValueList value -log_events class decorator logging contexts Qt Bugs diff --git a/qutebrowser/utils/debug.py b/qutebrowser/utils/debug.py index 69f68c52b..2fbe55148 100644 --- a/qutebrowser/utils/debug.py +++ b/qutebrowser/utils/debug.py @@ -18,8 +18,10 @@ """Utilities used for debugging.""" import sys +import logging +from functools import wraps -from PyQt5.QtCore import pyqtRemoveInputHook +from PyQt5.QtCore import pyqtRemoveInputHook, QEvent try: # pylint: disable=import-error @@ -29,6 +31,24 @@ except ImportError: import qutebrowser.commands.utils as cmdutils +EVENTS = {n: x for x, n in vars(QEvent).items() + if isinstance(n, QEvent.Type)} + + +def log_events(klass): + """Class decorator to log Qt events.""" + old_event = klass.event + + @wraps(old_event) + def new_event(self, e, *args, **kwargs): + """Wrapper for event() which logs events.""" + logging.debug("Event in {}: {}".format(klass.__name__, + EVENTS[e.type()])) + return old_event(self, e, *args, **kwargs) + + klass.event = new_event + return klass + @cmdutils.register(name='settrace', hide=True) def set_trace(): From c02d46e364e927c92f9c9434a7e9d5836ed86ee8 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 22 Apr 2014 23:52:02 +0200 Subject: [PATCH 07/11] Add catching import errors to TODO --- TODO | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO b/TODO index 6fb83bfad..36a6c049e 100644 --- a/TODO +++ b/TODO @@ -61,6 +61,7 @@ Hiding scrollbars Ctrl+A/X to increase/decrease last number in URL command completion gets hidden when doing a new ValueList value logging contexts +catch import errors for PyQt and QtWebKit Qt Bugs ======== From 61802725a6ebd1ef3983d124587bbb7a9b672f66 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 23 Apr 2014 06:17:29 +0200 Subject: [PATCH 08/11] Actually use message.error for errors --- qutebrowser/browser/curcommand.py | 4 ++-- qutebrowser/widgets/tabbedbrowser.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/qutebrowser/browser/curcommand.py b/qutebrowser/browser/curcommand.py index d9006c478..c74704d42 100644 --- a/qutebrowser/browser/curcommand.py +++ b/qutebrowser/browser/curcommand.py @@ -164,7 +164,7 @@ class CurCommandDispatcher(QObject): if self._tabs.currentWidget().page_.history().canGoBack(): self._tabs.currentWidget().back() else: - message.info("At beginning of history.") + message.error("At beginning of history.") break @cmdutils.register(instance='mainwindow.tabs.cur') @@ -180,7 +180,7 @@ class CurCommandDispatcher(QObject): if self._tabs.currentWidget().page_.history().canGoForward(): self._tabs.currentWidget().forward() else: - message.info("At end of history.") + message.error("At end of history.") break @cmdutils.register(instance='mainwindow.tabs.cur') diff --git a/qutebrowser/widgets/tabbedbrowser.py b/qutebrowser/widgets/tabbedbrowser.py index ccc54a5cd..b0354423d 100644 --- a/qutebrowser/widgets/tabbedbrowser.py +++ b/qutebrowser/widgets/tabbedbrowser.py @@ -284,7 +284,7 @@ class TabbedBrowser(TabWidget): elif config.get('tabbar', 'wrap'): self.setCurrentIndex(newidx % self.count()) else: - message.info("First tab") + message.error("First tab") @cmdutils.register(instance='mainwindow.tabs', name='tabnext') def switch_next(self, count=1): @@ -301,7 +301,7 @@ class TabbedBrowser(TabWidget): elif config.get('tabbar', 'wrap'): self.setCurrentIndex(newidx % self.count()) else: - message.info("Last tab") + message.error("Last tab") @cmdutils.register(instance='mainwindow.tabs', nargs=(0, 1)) def paste(self, sel=False, tab=False): From 7acd32a5d7ab8755a70cbece28921b203677db3f Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 23 Apr 2014 06:17:36 +0200 Subject: [PATCH 09/11] Display error when there's nothing to undo --- qutebrowser/widgets/tabbedbrowser.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qutebrowser/widgets/tabbedbrowser.py b/qutebrowser/widgets/tabbedbrowser.py index b0354423d..ddd5460c4 100644 --- a/qutebrowser/widgets/tabbedbrowser.py +++ b/qutebrowser/widgets/tabbedbrowser.py @@ -268,6 +268,8 @@ class TabbedBrowser(TabWidget): """ if self._url_stack: self.tabopen(self._url_stack.pop()) + else: + message.error("Nothing to undo!") @cmdutils.register(instance='mainwindow.tabs', name='tabprev') def switch_prev(self, count=1): From 2c5bb6a41302e31de0f9221a7e0c20f60fed0351 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 23 Apr 2014 07:32:00 +0200 Subject: [PATCH 10/11] cmdutils.register: Support functions with no docstring --- qutebrowser/commands/utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qutebrowser/commands/utils.py b/qutebrowser/commands/utils.py index 323f8f665..e3f252b39 100644 --- a/qutebrowser/commands/utils.py +++ b/qutebrowser/commands/utils.py @@ -88,7 +88,10 @@ class register: # pylint: disable=invalid-name mainname = name[0] names += name count, nargs = self._get_nargs_count(func) - desc = func.__doc__.splitlines()[0].strip().rstrip('.') + if func.__doc__ is not None: + desc = func.__doc__.splitlines()[0].strip().rstrip('.') + else: + desc = "" cmd = Command(name=mainname, maxsplit=self.maxsplit, hide=self.hide, nargs=nargs, count=count, desc=desc, instance=self.instance, handler=func, From a67ed4d05407085e9caa66a75b12e4333ae8b94c Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Wed, 23 Apr 2014 07:32:27 +0200 Subject: [PATCH 11/11] Override mousePressEvent instead of event --- qutebrowser/widgets/browsertab.py | 37 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/qutebrowser/widgets/browsertab.py b/qutebrowser/widgets/browsertab.py index 3301db8a4..e22032434 100644 --- a/qutebrowser/widgets/browsertab.py +++ b/qutebrowser/widgets/browsertab.py @@ -20,7 +20,7 @@ import logging import functools -from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QEvent +from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt from PyQt5.QtWidgets import QApplication from PyQt5.QtWebKit import QWebSettings from PyQt5.QtWebKitWidgets import QWebView, QWebPage @@ -248,10 +248,10 @@ class BrowserTab(QWebView): # Let superclass handle the event return super().paintEvent(e) - def event(self, e): + def mousePressEvent(self, e): """Check if a link was clicked with the middle button or Ctrl. - Extend the superclass event(). + Extend the superclass mousePressEvent(). This also is a bit of a hack, but it seems it's the only possible way. Set the _open_target attribute accordingly. @@ -260,21 +260,20 @@ class BrowserTab(QWebView): e: The arrived event. Return: - The superclass event return value. + The superclass return value. """ - if e.type() in [QEvent.MouseButtonPress, QEvent.MouseButtonDblClick]: - if self._force_open_target is not None: - self._open_target = self._force_open_target - self._force_open_target = None - logging.debug("Setting force target: {}".format( - self._open_target)) - elif (e.button() == Qt.MidButton or - e.modifiers() & Qt.ControlModifier): - if config.get('general', 'background_tabs'): - self._open_target = "bgtab" - else: - self._open_target = "tab" - logging.debug("Setting target: {}".format(self._open_target)) + if self._force_open_target is not None: + self._open_target = self._force_open_target + self._force_open_target = None + logging.debug("Setting force target: {}".format( + self._open_target)) + elif (e.button() == Qt.MidButton or + e.modifiers() & Qt.ControlModifier): + if config.get('general', 'background_tabs'): + self._open_target = "bgtab" else: - self._open_target = "normal" - return super().event(e) + self._open_target = "tab" + logging.debug("Setting target: {}".format(self._open_target)) + else: + self._open_target = "normal" + return super().mousePressEvent(e)