Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc63cea917 | ||
|
|
effbe36919 | ||
|
|
db466097e0 | ||
|
|
0446babb3d | ||
|
|
85d643ff49 | ||
|
|
12c35ff836 | ||
|
|
b33bb94593 | ||
|
|
25a11f492b | ||
|
|
d0453542c3 | ||
|
|
4bff63f17b | ||
|
|
a5426ca4ac | ||
|
|
ec9981f0d1 | ||
|
|
5ebca1c309 | ||
|
|
1559965e6b | ||
|
|
9a2d451bc5 | ||
|
|
5a080ebea5 | ||
|
|
2f3e3c3073 | ||
|
|
457bba7e79 | ||
|
|
0045af8738 | ||
|
|
7dc82407e8 | ||
|
|
0becdfa6b0 | ||
|
|
b69b5c81fc | ||
|
|
8607ddce24 |
@@ -51,7 +51,7 @@ matrix:
|
||||
env: TESTENV=eslint
|
||||
language: node_js
|
||||
python: null
|
||||
node_js: node
|
||||
node_js: "lts/*"
|
||||
fast_finish: true
|
||||
|
||||
cache:
|
||||
|
||||
@@ -15,10 +15,32 @@ breaking changes (such as renamed commands) can happen in minor releases.
|
||||
// `Fixed` for any bug fixes.
|
||||
// `Security` to invite users to upgrade in case of vulnerabilities.
|
||||
|
||||
v1.0.3
|
||||
------
|
||||
|
||||
Changed
|
||||
~~~~~~~
|
||||
|
||||
- macOS and Windows builds are now built with PyQt 5.9.1 and Qt 5.9.2, including
|
||||
various bugfixes, as well as security fixes from Chromium up to version
|
||||
61.0.3163.79.
|
||||
- Performance improvements for tab rendering.
|
||||
- The :open-editor command is now not hidden anymore as it's also usable in
|
||||
normal mode.
|
||||
|
||||
Fixed
|
||||
~~~~~
|
||||
|
||||
- Handle accessing a locked sqlite database gracefully
|
||||
- Abort pinned tab dialogs properly when a tab is closed e.g. by closing a
|
||||
window
|
||||
- Unbinding a default keybinding twice now doesn't bind it again
|
||||
- Completions are now sorted correctly again when filtered
|
||||
|
||||
v1.0.2
|
||||
------
|
||||
|
||||
Fixes
|
||||
Fixed
|
||||
~~~~~
|
||||
|
||||
- Fix workaround for black screens or crashes with Nvidia cards
|
||||
@@ -36,7 +58,7 @@ Changed
|
||||
v1.0.1
|
||||
------
|
||||
|
||||
Fixes
|
||||
Fixed
|
||||
~~~~~
|
||||
|
||||
- Fixed starting after customizing `fonts.tabs` or `fonts.debug_console`.
|
||||
@@ -74,6 +96,9 @@ Major changes
|
||||
the entire browsing history. The default for
|
||||
`completion.web_history_max_items` got changed to `-1` (unlimited). If the
|
||||
completion is too slow on your machine, try setting it to a few 1000 items.
|
||||
- Up/Down now navigates through the command history instead of selecting
|
||||
completion items. Either use Tab to cycle through the completion, or
|
||||
https://github.com/qutebrowser/qutebrowser/blob/master/doc/help/configuring.asciidoc#migrating-older-configurations[restore the old behavior].
|
||||
|
||||
Added
|
||||
~~~~~
|
||||
|
||||
@@ -60,6 +60,7 @@ It is possible to run or bind multiple commands by separating them with `;;`.
|
||||
|<<messages,messages>>|Show a log of past messages.
|
||||
|<<navigate,navigate>>|Open typical prev/next links or navigate using the URL path.
|
||||
|<<open,open>>|Open a URL in the current/[count]th tab.
|
||||
|<<open-editor,open-editor>>|Open an external editor with the currently selected form field.
|
||||
|<<print,print>>|Print the current/[count]th tab.
|
||||
|<<quickmark-add,quickmark-add>>|Add a new quickmark.
|
||||
|<<quickmark-del,quickmark-del>>|Delete a quickmark.
|
||||
@@ -653,6 +654,12 @@ The tab index to open the URL in.
|
||||
==== note
|
||||
* This command does not split arguments after the last argument and handles quotes literally.
|
||||
|
||||
[[open-editor]]
|
||||
=== open-editor
|
||||
Open an external editor with the currently selected form field.
|
||||
|
||||
The editor which should be launched can be configured via the `editor.command` config option.
|
||||
|
||||
[[print]]
|
||||
=== print
|
||||
Syntax: +:print [*--preview*] [*--pdf* 'file']+
|
||||
@@ -1137,7 +1144,6 @@ How many steps to zoom out.
|
||||
|<<move-to-start-of-next-block,move-to-start-of-next-block>>|Move the cursor or selection to the start of next block.
|
||||
|<<move-to-start-of-prev-block,move-to-start-of-prev-block>>|Move the cursor or selection to the start of previous block.
|
||||
|<<nop,nop>>|Do nothing.
|
||||
|<<open-editor,open-editor>>|Open an external editor with the currently selected form field.
|
||||
|<<prompt-accept,prompt-accept>>|Accept the current prompt.
|
||||
|<<prompt-item-focus,prompt-item-focus>>|Shift the focus of the prompt file completion menu to another item.
|
||||
|<<prompt-open-download,prompt-open-download>>|Immediately open a download.
|
||||
@@ -1388,12 +1394,6 @@ How many blocks to move.
|
||||
=== nop
|
||||
Do nothing.
|
||||
|
||||
[[open-editor]]
|
||||
=== open-editor
|
||||
Open an external editor with the currently selected form field.
|
||||
|
||||
The editor which should be launched can be configured via the `editor.command` config option.
|
||||
|
||||
[[prompt-accept]]
|
||||
=== prompt-accept
|
||||
Syntax: +:prompt-accept ['value']+
|
||||
|
||||
@@ -22,8 +22,8 @@ Other changes in default settings:
|
||||
doing:
|
||||
+
|
||||
----
|
||||
:bind -f -m command <Up> completion-item-focus prev
|
||||
:bind -f -m command <Down> completion-item-focus next
|
||||
:bind -m command <Up> completion-item-focus prev
|
||||
:bind -m command <Down> completion-item-focus next
|
||||
----
|
||||
|
||||
- The default for `completion.web_history_max_items` is now set to `-1`, showing
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
PyQt5==5.9
|
||||
sip==4.19.3
|
||||
PyQt5==5.9.1
|
||||
sip==4.19.4
|
||||
|
||||
@@ -26,7 +26,7 @@ __copyright__ = "Copyright 2014-2017 Florian Bruhin (The Compiler)"
|
||||
__license__ = "GPL"
|
||||
__maintainer__ = __author__
|
||||
__email__ = "mail@qutebrowser.org"
|
||||
__version_info__ = (1, 0, 2)
|
||||
__version_info__ = (1, 0, 3)
|
||||
__version__ = '.'.join(str(e) for e in __version_info__)
|
||||
__description__ = "A keyboard-driven, vim-like browser based on PyQt5."
|
||||
|
||||
|
||||
@@ -1599,8 +1599,7 @@ class CommandDispatcher:
|
||||
self.on_editing_finished, elem))
|
||||
ed.edit(text)
|
||||
|
||||
@cmdutils.register(instance='command-dispatcher', hide=True,
|
||||
scope='window')
|
||||
@cmdutils.register(instance='command-dispatcher', scope='window')
|
||||
def open_editor(self):
|
||||
"""Open an external editor with the currently selected form field.
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ def option(*, info):
|
||||
model = completionmodel.CompletionModel(column_widths=(20, 70, 10))
|
||||
options = ((opt.name, opt.description, info.config.get_str(opt.name))
|
||||
for opt in configdata.DATA.values())
|
||||
model.add_category(listcategory.ListCategory("Options", sorted(options)))
|
||||
model.add_category(listcategory.ListCategory("Options", options))
|
||||
return model
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ def customized_option(*, info):
|
||||
options = ((opt.name, opt.description, info.config.get_str(opt.name))
|
||||
for opt, _value in info.config)
|
||||
model.add_category(listcategory.ListCategory("Customized options",
|
||||
sorted(options)))
|
||||
options))
|
||||
return model
|
||||
|
||||
|
||||
@@ -66,8 +66,7 @@ def value(optname, *_values, info):
|
||||
|
||||
vals = opt.typ.complete()
|
||||
if vals is not None:
|
||||
model.add_category(listcategory.ListCategory("Completions",
|
||||
sorted(vals)))
|
||||
model.add_category(listcategory.ListCategory("Completions", vals))
|
||||
return model
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class ListCategory(QSortFilterProxyModel):
|
||||
|
||||
"""Expose a list of items as a category for the CompletionModel."""
|
||||
|
||||
def __init__(self, name, items, delete_func=None, parent=None):
|
||||
def __init__(self, name, items, sort=True, delete_func=None, parent=None):
|
||||
super().__init__(parent)
|
||||
self.name = name
|
||||
self.srcmodel = QStandardItemModel(parent=self)
|
||||
@@ -43,6 +43,7 @@ class ListCategory(QSortFilterProxyModel):
|
||||
self.srcmodel.appendRow([QStandardItem(x) for x in item])
|
||||
self.setSourceModel(self.srcmodel)
|
||||
self.delete_func = delete_func
|
||||
self._sort = sort
|
||||
|
||||
def set_pattern(self, val):
|
||||
"""Setter for pattern.
|
||||
@@ -60,19 +61,33 @@ class ListCategory(QSortFilterProxyModel):
|
||||
sortcol = 0
|
||||
self.sort(sortcol)
|
||||
|
||||
def lessThan(self, _lindex, rindex):
|
||||
def lessThan(self, lindex, rindex):
|
||||
"""Custom sorting implementation.
|
||||
|
||||
Prefers all items which start with self._pattern. Other than that, keep
|
||||
items in their original order.
|
||||
Prefers all items which start with self._pattern. Other than that, uses
|
||||
normal Python string sorting.
|
||||
|
||||
Args:
|
||||
_lindex: The QModelIndex of the left item (*left* < right)
|
||||
lindex: The QModelIndex of the left item (*left* < right)
|
||||
rindex: The QModelIndex of the right item (left < *right*)
|
||||
|
||||
Return:
|
||||
True if left < right, else False
|
||||
"""
|
||||
qtutils.ensure_valid(lindex)
|
||||
qtutils.ensure_valid(rindex)
|
||||
|
||||
left = self.srcmodel.data(lindex)
|
||||
right = self.srcmodel.data(rindex)
|
||||
return not right.startswith(self._pattern)
|
||||
|
||||
leftstart = left.startswith(self._pattern)
|
||||
rightstart = right.startswith(self._pattern)
|
||||
|
||||
if leftstart and not rightstart:
|
||||
return True
|
||||
elif rightstart and not leftstart:
|
||||
return False
|
||||
elif self._sort:
|
||||
return left < right
|
||||
else:
|
||||
return False
|
||||
|
||||
@@ -43,7 +43,7 @@ def helptopic(*, info):
|
||||
for opt in configdata.DATA.values())
|
||||
|
||||
model.add_category(listcategory.ListCategory("Commands", cmdlist))
|
||||
model.add_category(listcategory.ListCategory("Settings", sorted(settings)))
|
||||
model.add_category(listcategory.ListCategory("Settings", settings))
|
||||
return model
|
||||
|
||||
|
||||
@@ -59,7 +59,8 @@ def quickmark(*, info=None): # pylint: disable=unused-argument
|
||||
model = completionmodel.CompletionModel(column_widths=(30, 70, 0))
|
||||
marks = objreg.get('quickmark-manager').marks.items()
|
||||
model.add_category(listcategory.ListCategory('Quickmarks', marks,
|
||||
delete_func=delete))
|
||||
delete_func=delete,
|
||||
sort=False))
|
||||
return model
|
||||
|
||||
|
||||
@@ -75,7 +76,8 @@ def bookmark(*, info=None): # pylint: disable=unused-argument
|
||||
model = completionmodel.CompletionModel(column_widths=(30, 70, 0))
|
||||
marks = objreg.get('bookmark-manager').marks.items()
|
||||
model.add_category(listcategory.ListCategory('Bookmarks', marks,
|
||||
delete_func=delete))
|
||||
delete_func=delete,
|
||||
sort=False))
|
||||
return model
|
||||
|
||||
|
||||
|
||||
@@ -61,9 +61,9 @@ def url(*, info):
|
||||
bookmarks = objreg.get('bookmark-manager').marks.items()
|
||||
|
||||
model.add_category(listcategory.ListCategory(
|
||||
'Quickmarks', quickmarks, delete_func=_delete_quickmark))
|
||||
'Quickmarks', quickmarks, delete_func=_delete_quickmark, sort=False))
|
||||
model.add_category(listcategory.ListCategory(
|
||||
'Bookmarks', bookmarks, delete_func=_delete_bookmark))
|
||||
'Bookmarks', bookmarks, delete_func=_delete_bookmark, sort=False))
|
||||
|
||||
if info.config.get('completion.web_history_max_items') != 0:
|
||||
hist_cat = histcategory.HistoryCategory(delete_func=_delete_history)
|
||||
|
||||
@@ -198,7 +198,7 @@ class KeyConfig:
|
||||
|
||||
bindings_commands = self._config.get_obj('bindings.commands')
|
||||
|
||||
if key in val.bindings.commands[mode]:
|
||||
if val.bindings.commands[mode].get(key, None) is not None:
|
||||
# In custom bindings -> remove it
|
||||
del bindings_commands[mode][key]
|
||||
elif key in val.bindings.default[mode]:
|
||||
|
||||
@@ -755,6 +755,6 @@ def get_diff():
|
||||
lexer = pygments.lexers.DiffLexer()
|
||||
formatter = pygments.formatters.HtmlFormatter(
|
||||
full=True, linenos='table',
|
||||
title='Config diff')
|
||||
title='Diffing pre-1.0 default config with pre-1.0 modified config')
|
||||
# pylint: enable=no-member
|
||||
return pygments.highlight(conf_diff + key_diff, lexer, formatter)
|
||||
|
||||
@@ -249,13 +249,14 @@ class TabbedBrowser(tabwidget.TabWidget):
|
||||
def tab_close_prompt_if_pinned(self, tab, force, yes_action):
|
||||
"""Helper method for tab_close.
|
||||
|
||||
If tab is pinned, prompt. If everything is good, run yes_action.
|
||||
If tab is pinned, prompt. If not, run yes_action.
|
||||
If tab is destroyed, abort question.
|
||||
"""
|
||||
if tab.data.pinned and not force:
|
||||
message.confirm_async(
|
||||
title='Pinned Tab',
|
||||
text="Are you sure you want to close a pinned tab?",
|
||||
yes_action=yes_action, default=False)
|
||||
yes_action=yes_action, default=False, abort_on=[tab.destroyed])
|
||||
else:
|
||||
yes_action()
|
||||
|
||||
|
||||
@@ -310,7 +310,7 @@ class TabBar(QTabBar):
|
||||
return self.parent().currentWidget()
|
||||
|
||||
@pyqtSlot(str)
|
||||
def _on_config_changed(self, option):
|
||||
def _on_config_changed(self, option: str):
|
||||
if option == 'fonts.tabs':
|
||||
self._set_font()
|
||||
elif option == 'tabs.favicons.scale':
|
||||
@@ -325,6 +325,12 @@ class TabBar(QTabBar):
|
||||
if option.startswith('colors.tabs.'):
|
||||
self.update()
|
||||
|
||||
# Clear _minimum_tab_size_hint_helper cache when appropriate
|
||||
if option in ["tabs.indicator_padding",
|
||||
"tabs.padding",
|
||||
"tabs.width.indicator"]:
|
||||
self._minimum_tab_size_hint_helper.cache_clear()
|
||||
|
||||
def _on_show_switching_delay_changed(self):
|
||||
"""Set timer interval when tabs.show_switching_delay got changed."""
|
||||
self._auto_hide_timer.setInterval(config.val.tabs.show_switching_delay)
|
||||
@@ -424,7 +430,7 @@ class TabBar(QTabBar):
|
||||
return
|
||||
super().mousePressEvent(e)
|
||||
|
||||
def minimumTabSizeHint(self, index, ellipsis: bool = True):
|
||||
def minimumTabSizeHint(self, index, ellipsis: bool = True) -> QSize:
|
||||
"""Set the minimum tab size to indicator/icon/... text.
|
||||
|
||||
Args:
|
||||
@@ -434,38 +440,47 @@ class TabBar(QTabBar):
|
||||
Return:
|
||||
A QSize of the smallest tab size we can make.
|
||||
"""
|
||||
text = '\u2026' if ellipsis else self.tabText(index)
|
||||
icon = self.tabIcon(index)
|
||||
extent = self.style().pixelMetric(QStyle.PM_TabBarIconSize, None, self)
|
||||
if icon.isNull():
|
||||
icon_width = 0
|
||||
else:
|
||||
icon_width = icon.actualSize(QSize(extent, extent)).width()
|
||||
return self._minimum_tab_size_hint_helper(self.tabText(index),
|
||||
icon_width,
|
||||
ellipsis)
|
||||
|
||||
@functools.lru_cache(maxsize=2**9)
|
||||
def _minimum_tab_size_hint_helper(self, tab_text: str,
|
||||
icon_width: int,
|
||||
ellipsis: bool) -> QSize:
|
||||
"""Helper function to cache tab results.
|
||||
|
||||
Config values accessed in here should be added to _on_config_changed to
|
||||
ensure cache is flushed when needed.
|
||||
"""
|
||||
text = '\u2026' if ellipsis else tab_text
|
||||
# Don't ever shorten if text is shorter than the ellipsis
|
||||
text_width = min(self.fontMetrics().width(text),
|
||||
self.fontMetrics().width(self.tabText(index)))
|
||||
icon = self.tabIcon(index)
|
||||
self.fontMetrics().width(tab_text))
|
||||
padding = config.val.tabs.padding
|
||||
indicator_padding = config.val.tabs.indicator_padding
|
||||
padding_h = padding.left + padding.right
|
||||
padding_h += indicator_padding.left + indicator_padding.right
|
||||
padding_v = padding.top + padding.bottom
|
||||
if icon.isNull():
|
||||
icon_size = QSize(0, 0)
|
||||
else:
|
||||
extent = self.style().pixelMetric(QStyle.PM_TabBarIconSize, None,
|
||||
self)
|
||||
icon_size = icon.actualSize(QSize(extent, extent))
|
||||
height = self.fontMetrics().height() + padding_v
|
||||
width = (text_width + icon_size.width() +
|
||||
width = (text_width + icon_width +
|
||||
padding_h + config.val.tabs.width.indicator)
|
||||
return QSize(width, height)
|
||||
|
||||
def _tab_total_width_pinned(self):
|
||||
"""Get the current total width of pinned tabs.
|
||||
|
||||
This width is calculated assuming no shortening due to ellipsis."""
|
||||
return sum(self.minimumTabSizeHint(idx, ellipsis=False).width()
|
||||
for idx in range(self.count())
|
||||
if self._tab_pinned(idx))
|
||||
|
||||
def _pinnedCount(self) -> int:
|
||||
"""Get the number of pinned tabs."""
|
||||
return sum(self._tab_pinned(idx) for idx in range(self.count()))
|
||||
def _pinned_statistics(self) -> (int, int):
|
||||
"""Get the number of pinned tabs and the total width of pinned tabs."""
|
||||
pinned_list = [idx for idx in range(self.count())
|
||||
if self._tab_pinned(idx)]
|
||||
pinned_count = len(pinned_list)
|
||||
pinned_width = sum(self.minimumTabSizeHint(idx, ellipsis=False).width()
|
||||
for idx in pinned_list)
|
||||
return (pinned_count, pinned_width)
|
||||
|
||||
def _tab_pinned(self, index: int) -> bool:
|
||||
"""Return True if tab is pinned."""
|
||||
@@ -504,8 +519,8 @@ class TabBar(QTabBar):
|
||||
return QSize()
|
||||
else:
|
||||
pinned = self._tab_pinned(index)
|
||||
no_pinned_count = self.count() - self._pinnedCount()
|
||||
pinned_width = self._tab_total_width_pinned()
|
||||
pinned_count, pinned_width = self._pinned_statistics()
|
||||
no_pinned_count = self.count() - pinned_count
|
||||
no_pinned_width = self.width() - pinned_width
|
||||
|
||||
if pinned:
|
||||
|
||||
@@ -68,9 +68,9 @@ class SqliteError(SqlError):
|
||||
# https://github.com/qutebrowser/qutebrowser/issues/2930
|
||||
# https://github.com/qutebrowser/qutebrowser/issues/3004
|
||||
environmental_errors = [
|
||||
'5', # SQLITE_BUSY ("database is locked")
|
||||
'8', # SQLITE_READONLY
|
||||
'9', # SQLITE_LOCKED,
|
||||
'13', # SQLITE_FULL,
|
||||
'13', # SQLITE_FULL
|
||||
]
|
||||
self.environmental = error.nativeErrorCode() in environmental_errors
|
||||
|
||||
|
||||
@@ -171,6 +171,7 @@ def debug_cache_stats():
|
||||
prefix_info = configdata.is_valid_prefix.cache_info()
|
||||
# pylint: disable=protected-access
|
||||
render_stylesheet_info = config._render_stylesheet.cache_info()
|
||||
# pylint: enable=protected-access
|
||||
|
||||
history_info = None
|
||||
try:
|
||||
@@ -181,9 +182,17 @@ def debug_cache_stats():
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
tabbed_browser = objreg.get('tabbed-browser', scope='window',
|
||||
window='last-focused')
|
||||
# pylint: disable=protected-access
|
||||
tab_bar = tabbed_browser.tabBar()
|
||||
tabbed_browser_info = tab_bar._minimum_tab_size_hint_helper.cache_info()
|
||||
# pylint: enable=protected-access
|
||||
|
||||
log.misc.debug('is_valid_prefix: {}'.format(prefix_info))
|
||||
log.misc.debug('_render_stylesheet: {}'.format(render_stylesheet_info))
|
||||
log.misc.debug('history: {}'.format(history_info))
|
||||
log.misc.debug('tab width cache: {}'.format(tabbed_browser_info))
|
||||
|
||||
|
||||
@cmdutils.register(debug=True)
|
||||
|
||||
@@ -147,7 +147,7 @@ def test_remove_rows(hist, model_validator):
|
||||
cat.set_pattern('')
|
||||
hist.delete('url', 'foo')
|
||||
cat.removeRows(0, 1)
|
||||
model_validator.validate([('bar', 'Bar', '1970-01-01')])
|
||||
model_validator.validate([('bar', 'Bar')])
|
||||
|
||||
|
||||
def test_remove_rows_fetch(hist):
|
||||
|
||||
@@ -24,27 +24,36 @@ import pytest
|
||||
from qutebrowser.completion.models import listcategory
|
||||
|
||||
|
||||
@pytest.mark.parametrize('pattern, before, after', [
|
||||
@pytest.mark.parametrize('pattern, before, after, after_nosort', [
|
||||
('foo',
|
||||
[('foo', ''), ('bar', '')],
|
||||
[('foo', '')],
|
||||
[('foo', '')]),
|
||||
|
||||
('foo',
|
||||
[('foob', ''), ('fooc', ''), ('fooa', '')],
|
||||
[('fooa', ''), ('foob', ''), ('fooc', '')],
|
||||
[('foob', ''), ('fooc', ''), ('fooa', '')]),
|
||||
|
||||
# prefer foobar as it starts with the pattern
|
||||
('foo',
|
||||
[('barfoo', ''), ('foobar', '')],
|
||||
[('foobar', ''), ('barfoo', '')]),
|
||||
[('barfoo', ''), ('foobaz', ''), ('foobar', '')],
|
||||
[('foobar', ''), ('foobaz', ''), ('barfoo', '')],
|
||||
[('foobaz', ''), ('foobar', ''), ('barfoo', '')]),
|
||||
|
||||
('foo',
|
||||
[('foo', 'bar'), ('bar', 'foo'), ('bar', 'bar')],
|
||||
[('foo', 'bar'), ('bar', 'foo')],
|
||||
[('foo', 'bar'), ('bar', 'foo')]),
|
||||
])
|
||||
def test_set_pattern(pattern, before, after, model_validator):
|
||||
def test_set_pattern(pattern, before, after, after_nosort, model_validator):
|
||||
"""Validate the filtering and sorting results of set_pattern."""
|
||||
cat = listcategory.ListCategory('Foo', before)
|
||||
model_validator.set_model(cat)
|
||||
cat.set_pattern(pattern)
|
||||
model_validator.validate(after)
|
||||
|
||||
cat = listcategory.ListCategory('Foo', before, sort=False)
|
||||
model_validator.set_model(cat)
|
||||
cat.set_pattern(pattern)
|
||||
model_validator.validate(after_nosort)
|
||||
|
||||
@@ -466,9 +466,9 @@ def test_session_completion(qtmodeltester, session_manager_stub):
|
||||
qtmodeltester.check(model)
|
||||
|
||||
_check_completions(model, {
|
||||
"Sessions": [('default', None, None),
|
||||
('1', None, None),
|
||||
('2', None, None)]
|
||||
"Sessions": [('1', None, None),
|
||||
('2', None, None),
|
||||
('default', None, None)]
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -269,6 +269,22 @@ class TestKeyConfig:
|
||||
match="Can't find binding 'foobar' in normal mode"):
|
||||
key_config_stub.unbind('foobar', mode='normal')
|
||||
|
||||
def test_unbound_twice(self, key_config_stub, config_stub, no_bindings):
|
||||
"""Try unbinding an already-unbound default key.
|
||||
|
||||
For custom-bound keys (in bindings.commands), it's okay to display an
|
||||
error, as this isn't something you'd do in e.g a config.py anyways.
|
||||
|
||||
https://github.com/qutebrowser/qutebrowser/issues/3162
|
||||
"""
|
||||
config_stub.val.bindings.default = {'normal': {'a': 'nop'}}
|
||||
config_stub.val.bindings.commands = no_bindings
|
||||
|
||||
key_config_stub.unbind('a')
|
||||
assert key_config_stub.get_command('a', mode='normal') is None
|
||||
key_config_stub.unbind('a')
|
||||
assert key_config_stub.get_command('a', mode='normal') is None
|
||||
|
||||
|
||||
class TestConfig:
|
||||
|
||||
|
||||
@@ -52,3 +52,16 @@ class TestTabWidget:
|
||||
|
||||
with qtbot.waitExposed(widget):
|
||||
widget.show()
|
||||
|
||||
def test_update_tab_titles_benchmark(self, benchmark, widget,
|
||||
qtbot, fake_web_tab):
|
||||
"""Benchmark for update_tab_titles."""
|
||||
widget.addTab(fake_web_tab(), 'foobar')
|
||||
widget.addTab(fake_web_tab(), 'foobar2')
|
||||
widget.addTab(fake_web_tab(), 'foobar3')
|
||||
widget.addTab(fake_web_tab(), 'foobar4')
|
||||
|
||||
with qtbot.waitExposed(widget):
|
||||
widget.show()
|
||||
|
||||
benchmark(widget._update_tab_titles)
|
||||
|
||||
@@ -39,7 +39,7 @@ def test_sqlerror():
|
||||
class TestSqliteError:
|
||||
|
||||
@pytest.mark.parametrize('error_code, environmental', [
|
||||
('9', True), # SQLITE_LOCKED
|
||||
('5', True), # SQLITE_BUSY
|
||||
('19', False), # SQLITE_CONSTRAINT
|
||||
])
|
||||
def test_environmental(self, error_code, environmental):
|
||||
|
||||
Reference in New Issue
Block a user