Merge branch 'master' of https://github.com/qutebrowser/qutebrowser into jay/tab-bg-focus
This commit is contained in:
commit
74ea696a5c
@ -1,6 +1,5 @@
|
||||
recursive-include qutebrowser *.py
|
||||
recursive-include qutebrowser/img *.svg *.png
|
||||
recursive-include qutebrowser/test *.py
|
||||
recursive-include qutebrowser/javascript *.js
|
||||
graft qutebrowser/html
|
||||
graft qutebrowser/3rdparty
|
||||
@ -27,20 +26,18 @@ prune scripts/dev
|
||||
prune scripts/testbrowser/cpp
|
||||
prune .github
|
||||
exclude scripts/asciidoc2html.py
|
||||
exclude doc/notes
|
||||
recursive-exclude doc *.asciidoc
|
||||
include doc/qutebrowser.1.asciidoc
|
||||
include doc/changelog.asciidoc
|
||||
prune tests
|
||||
prune qutebrowser/3rdparty
|
||||
exclude pytest.ini
|
||||
exclude qutebrowser.rcc
|
||||
exclude qutebrowser/javascript/.eslintrc.yaml
|
||||
exclude qutebrowser/javascript/.eslintignore
|
||||
exclude doc/help
|
||||
exclude .*
|
||||
exclude misc/appveyor_install.py
|
||||
exclude misc/qutebrowser.spec
|
||||
exclude misc/qutebrowser.nsi
|
||||
exclude misc/qutebrowser.rcc
|
||||
|
||||
global-exclude __pycache__ *.pyc *.pyo
|
||||
|
@ -36,6 +36,23 @@ Changed
|
||||
- There's now completion for commands taking a variable count of arguments
|
||||
(like `:config-cycle`).
|
||||
|
||||
|
||||
v1.3.1 (unreleased)
|
||||
-------------------
|
||||
|
||||
Added
|
||||
~~~~~
|
||||
|
||||
- Work around a bug in Qt 5.11 where only the top/bottom half of the window is used.
|
||||
- Work around keyboard focus issues with Qt 5.11
|
||||
|
||||
Fixed
|
||||
~~~~~
|
||||
|
||||
- Work around an issue in Qt 5.11 where e.g. activating JavaScript per-domain
|
||||
needed a manual relaod in some cases.
|
||||
- Don't crash when a ² key is pressed (e.g. on AZERTY keyboards).
|
||||
|
||||
v1.3.0
|
||||
------
|
||||
|
||||
|
@ -567,6 +567,20 @@ can be useful for debugging:
|
||||
- chrome://ppapiflashcrash/
|
||||
- chrome://ppapiflashhang/
|
||||
|
||||
QtWebEngine internals
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is mostly useful for qutebrowser maintainers to work around issues in Qt - if you don't understand it, don't worry, just ignore it.
|
||||
|
||||
The hierarchy of widgets when QtWebEngine is involved looks like this:
|
||||
|
||||
- qutebrowser has a `WebEngineTab` object, which is its abstraction over QtWebKit/QtWebEngine.
|
||||
- The `WebEngineTab` has a `_widget` attribute, which is the https://doc.qt.io/qt-5/qwebengineview.html[QWebEngineView]
|
||||
- That view has a https://doc.qt.io/qt-5/qwebenginepage.html[QWebEnginePage] for everything which doesn't require rendering.
|
||||
- The view also has a layout with exactly one element (which also is its `focusProxy()`)
|
||||
- That element is the http://code.qt.io/cgit/qt/qtwebengine.git/tree/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp[RenderWidgetHostViewQtDelegateWidget] (it inherits https://doc.qt.io/qt-5/qquickwidget.html[QQuickWidget]) - also often referred to as RWHV or RWHVQDW. It can be obtained via `sip.cast(tab._widget.focusProxy(), QQuickWidget)`.
|
||||
- Calling `rootObject()` on that gives us the https://doc.qt.io/qt-5/qquickitem.html[QQuickItem] where Chromium renders into (?). With it, we can do things like `.setRotation(20)`.
|
||||
|
||||
Style conventions
|
||||
-----------------
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
attrs==18.1.0
|
||||
flake8==3.5.0
|
||||
flake8-bugbear==18.2.0
|
||||
flake8-builtins==1.3.1 # rq.filter: != 1.4.0
|
||||
flake8-builtins==1.4.1 # rq.filter: != 1.4.0
|
||||
flake8-comprehensions==1.4.1
|
||||
flake8-copyright==0.2.0
|
||||
flake8-debugger==3.1.0
|
||||
@ -18,10 +18,10 @@ flake8-tidy-imports==1.1.0
|
||||
flake8-tuple==0.2.13
|
||||
mccabe==0.6.1
|
||||
pathmatch==0.2.1
|
||||
pep8-naming==0.6.1
|
||||
pep8-naming==0.7.0
|
||||
pycodestyle==2.3.1 # rq.filter: < 2.4.0
|
||||
pydocstyle==2.1.1
|
||||
pyflakes==1.6.0
|
||||
pyflakes==2.0.0
|
||||
six==1.11.0
|
||||
snowballstemmer==1.2.1
|
||||
typing==3.6.4
|
||||
|
@ -3,6 +3,6 @@
|
||||
appdirs==1.4.3
|
||||
packaging==17.1
|
||||
pyparsing==2.2.0
|
||||
setuptools==39.1.0
|
||||
setuptools==39.2.0
|
||||
six==1.11.0
|
||||
wheel==0.31.0
|
||||
wheel==0.31.1
|
||||
|
@ -9,7 +9,7 @@ isort==4.3.4
|
||||
lazy-object-proxy==1.3.1
|
||||
mccabe==0.6.1
|
||||
-e git+https://github.com/PyCQA/pylint.git#egg=pylint
|
||||
python-dateutil==2.7.2
|
||||
python-dateutil==2.7.3
|
||||
./scripts/dev/pylint_checkers
|
||||
requests==2.18.4
|
||||
six==1.11.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
# This file is automatically generated by scripts/dev/recompile_requirements.py
|
||||
|
||||
astroid==1.6.3
|
||||
astroid==1.6.4
|
||||
certifi==2018.4.16
|
||||
chardet==3.0.4
|
||||
github3.py==1.1.0
|
||||
@ -8,8 +8,8 @@ idna==2.6
|
||||
isort==4.3.4
|
||||
lazy-object-proxy==1.3.1
|
||||
mccabe==0.6.1
|
||||
pylint==1.8.4
|
||||
python-dateutil==2.7.2
|
||||
pylint==1.9.1
|
||||
python-dateutil==2.7.3
|
||||
./scripts/dev/pylint_checkers
|
||||
requests==2.18.4
|
||||
six==1.11.0
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
attrs==18.1.0
|
||||
beautifulsoup4==4.6.0
|
||||
cheroot==6.2.4
|
||||
cheroot==6.3.1
|
||||
click==6.7
|
||||
# colorama==0.3.9
|
||||
coverage==4.5.1
|
||||
@ -11,7 +11,7 @@ fields==5.0.0
|
||||
Flask==1.0.2
|
||||
glob2==0.6
|
||||
hunter==2.0.2
|
||||
hypothesis==3.56.5
|
||||
hypothesis==3.57.0
|
||||
itsdangerous==0.24
|
||||
# Jinja2==2.10
|
||||
Mako==1.0.7
|
||||
@ -27,9 +27,9 @@ pytest-bdd==2.21.0
|
||||
pytest-benchmark==3.1.1
|
||||
pytest-cov==2.5.1
|
||||
pytest-faulthandler==1.5.0
|
||||
pytest-instafail==0.3.0
|
||||
pytest-instafail==0.4.0
|
||||
pytest-mock==1.10.0
|
||||
pytest-qt==2.3.1
|
||||
pytest-qt==2.3.2
|
||||
pytest-repeat==0.4.1
|
||||
pytest-rerunfailures==4.0
|
||||
pytest-travis-fold==1.3.0
|
||||
|
@ -4,4 +4,4 @@ pluggy==0.6.0
|
||||
py==1.5.3
|
||||
six==1.11.0
|
||||
tox==3.0.0
|
||||
virtualenv==15.2.0
|
||||
virtualenv==16.0.0
|
||||
|
@ -1674,7 +1674,7 @@ class CommandDispatcher:
|
||||
"""
|
||||
try:
|
||||
elem.set_value(text)
|
||||
except webelem.OrphanedError as e:
|
||||
except webelem.OrphanedError:
|
||||
message.error('Edited element vanished')
|
||||
ed.backup()
|
||||
except webelem.Error as e:
|
||||
|
@ -22,7 +22,7 @@
|
||||
from PyQt5.QtCore import QObject, QEvent, Qt, QTimer
|
||||
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import message, log, usertypes
|
||||
from qutebrowser.utils import message, log, usertypes, qtutils
|
||||
from qutebrowser.keyinput import modeman
|
||||
|
||||
|
||||
@ -54,6 +54,11 @@ class ChildEventFilter(QObject):
|
||||
obj, child))
|
||||
assert obj is self._widget
|
||||
child.installEventFilter(self._filter)
|
||||
|
||||
if qtutils.version_check('5.11', compiled=False, exact=True):
|
||||
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-68076
|
||||
QTimer.singleShot(0, self._widget.setFocus)
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
@ -177,7 +177,7 @@ def data_for_url(url):
|
||||
except OSError as e:
|
||||
# FIXME:qtwebengine how to handle this?
|
||||
raise QuteSchemeOSError(e)
|
||||
except QuteSchemeError as e:
|
||||
except QuteSchemeError:
|
||||
raise
|
||||
|
||||
assert mimetype is not None, url
|
||||
|
@ -789,8 +789,6 @@ class WebEngineTab(browsertab.AbstractTab):
|
||||
url: The QUrl to open.
|
||||
predict: If set to False, predicted_navigation is not emitted.
|
||||
"""
|
||||
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-68076
|
||||
self._widget.setFocus()
|
||||
self._saved_zoom = self.zoom.factor()
|
||||
self._openurl_prepare(url, predict=predict)
|
||||
self._widget.load(url)
|
||||
@ -1057,23 +1055,46 @@ class WebEngineTab(browsertab.AbstractTab):
|
||||
@pyqtSlot(usertypes.NavigationRequest)
|
||||
def _on_navigation_request(self, navigation):
|
||||
super()._on_navigation_request(navigation)
|
||||
|
||||
if qtutils.version_check('5.11.0', exact=True, compiled=False):
|
||||
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-68224
|
||||
layout = self._widget.layout()
|
||||
count = layout.count()
|
||||
if count > 1:
|
||||
for i in range(count):
|
||||
item = layout.itemAt(i)
|
||||
if item is None:
|
||||
continue
|
||||
widget = item.widget()
|
||||
if widget is not self._widget.focusProxy():
|
||||
log.webview.debug("Removing widget {} (QTBUG-68224)"
|
||||
.format(widget))
|
||||
layout.removeWidget(widget)
|
||||
|
||||
if not navigation.accepted or not navigation.is_main_frame:
|
||||
return
|
||||
|
||||
needs_reload = {
|
||||
settings_needing_reload = {
|
||||
'content.plugins',
|
||||
'content.javascript.enabled',
|
||||
'content.javascript.can_access_clipboard',
|
||||
'content.javascript.can_access_clipboard',
|
||||
'content.print_element_backgrounds',
|
||||
'input.spatial_navigation',
|
||||
'input.spatial_navigation',
|
||||
}
|
||||
assert needs_reload.issubset(configdata.DATA)
|
||||
assert settings_needing_reload.issubset(configdata.DATA)
|
||||
|
||||
changed = self.settings.update_for_url(navigation.url)
|
||||
if (changed & needs_reload and navigation.navigation_type !=
|
||||
navigation.Type.link_clicked):
|
||||
reload_needed = changed & settings_needing_reload
|
||||
|
||||
# On Qt < 5.11, we don't don't need a reload when type == link_clicked.
|
||||
# On Qt 5.11.0, we always need a reload.
|
||||
# TODO on Qt > 5.11.0, we hopefully never need a reload:
|
||||
# https://codereview.qt-project.org/#/c/229525/1
|
||||
if not qtutils.version_check('5.11.0', exact=True, compiled=False):
|
||||
if navigation.navigation_type != navigation.Type.link_clicked:
|
||||
reload_needed = False
|
||||
|
||||
if reload_needed:
|
||||
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-66656
|
||||
self._reload_url = navigation.url
|
||||
|
||||
|
@ -102,7 +102,7 @@ def _parse_yaml_type(name, node):
|
||||
|
||||
try:
|
||||
typ = getattr(configtypes, type_name)
|
||||
except AttributeError as e:
|
||||
except AttributeError:
|
||||
raise AttributeError("Did not find type {} for {}".format(
|
||||
type_name, name))
|
||||
|
||||
|
@ -573,7 +573,7 @@ def read_autoconfig():
|
||||
"""Read the autoconfig.yml file."""
|
||||
try:
|
||||
config.instance.read_yaml()
|
||||
except configexc.ConfigFileErrors as e:
|
||||
except configexc.ConfigFileErrors:
|
||||
raise # caught in outer block
|
||||
except configexc.Error as e:
|
||||
desc = configexc.ConfigErrorDesc("Error", e)
|
||||
|
@ -1409,7 +1409,7 @@ class SearchEngineUrl(BaseType):
|
||||
|
||||
try:
|
||||
value.format("")
|
||||
except (KeyError, IndexError) as e:
|
||||
except (KeyError, IndexError):
|
||||
raise configexc.ValidationError(
|
||||
value, "may not contain {...} (use {{ and }} for literal {/})")
|
||||
except ValueError as e:
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
"""Base class for vim-like key sequence parser."""
|
||||
|
||||
import string
|
||||
|
||||
from PyQt5.QtCore import pyqtSignal, QObject
|
||||
from PyQt5.QtGui import QKeySequence
|
||||
|
||||
@ -136,7 +138,7 @@ class BaseKeyParser(QObject):
|
||||
def _match_count(self, sequence, dry_run):
|
||||
"""Try to match a key as count."""
|
||||
txt = str(sequence[-1]) # To account for sequences changed above.
|
||||
if (txt.isdigit() and self._supports_count and
|
||||
if (txt in string.digits and self._supports_count and
|
||||
not (not self._count and txt == '0')):
|
||||
self._debug_log("Trying match as count")
|
||||
assert len(txt) == 1, txt
|
||||
|
@ -494,6 +494,7 @@ class TabbedBrowser(QWidget):
|
||||
else:
|
||||
self.widget.setCurrentWidget(tab)
|
||||
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-68076
|
||||
# Still seems to be needed with Qt 5.11.1
|
||||
tab.setFocus()
|
||||
|
||||
mode = modeman.instance(self._win_id).mode
|
||||
|
@ -293,7 +293,7 @@ class _CrashDialog(QDialog):
|
||||
self._paste_text = '\n\n'.join(lines)
|
||||
try:
|
||||
user = getpass.getuser()
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
log.misc.exception("Error while getting user")
|
||||
user = 'unknown'
|
||||
try:
|
||||
|
@ -498,7 +498,7 @@ def send_or_listen(args):
|
||||
server = IPCServer(socketname)
|
||||
server.listen()
|
||||
return server
|
||||
except AddressInUseError as e:
|
||||
except AddressInUseError:
|
||||
# This could be a race condition...
|
||||
log.init.debug("Got AddressInUseError, trying again.")
|
||||
time.sleep(0.5)
|
||||
|
@ -399,6 +399,7 @@ def version():
|
||||
lines += [
|
||||
'Frozen: {}'.format(hasattr(sys, 'frozen')),
|
||||
"Imported from {}".format(importpath),
|
||||
"Using Python from {}".format(sys.executable),
|
||||
"Qt library executable path: {}, data path: {}".format(
|
||||
QLibraryInfo.location(QLibraryInfo.LibraryExecutablesPath),
|
||||
QLibraryInfo.location(QLibraryInfo.DataPath)
|
||||
|
@ -320,6 +320,10 @@ class TestCount:
|
||||
keyparser.execute.assert_called_once_with('message-info ccc', 23)
|
||||
assert not keyparser._sequence
|
||||
|
||||
def test_superscript(self, handle_text, keyparser):
|
||||
# https://github.com/qutebrowser/qutebrowser/issues/3743
|
||||
handle_text(Qt.Key_twosuperior, Qt.Key_B, Qt.Key_A)
|
||||
|
||||
def test_count_keystring_update(self, qtbot, handle_text, keyparser):
|
||||
"""Make sure the keystring is updated correctly when entering count."""
|
||||
with qtbot.waitSignals([keyparser.keystring_updated,
|
||||
|
@ -874,6 +874,7 @@ def test_version_output(params, stubs, monkeypatch):
|
||||
'_git_str': lambda: ('GIT COMMIT' if params.git_commit else None),
|
||||
'platform.python_implementation': lambda: 'PYTHON IMPLEMENTATION',
|
||||
'platform.python_version': lambda: 'PYTHON VERSION',
|
||||
'sys.executable': 'EXECUTABLE PATH',
|
||||
'PYQT_VERSION_STR': 'PYQT VERSION',
|
||||
'earlyinit.qt_version': lambda: 'QT VERSION',
|
||||
'_module_versions': lambda: ['MODULE VERSION 1', 'MODULE VERSION 2'],
|
||||
@ -897,6 +898,7 @@ def test_version_output(params, stubs, monkeypatch):
|
||||
'qt': 'QT VERSION',
|
||||
'frozen': str(params.frozen),
|
||||
'import_path': import_path,
|
||||
'python_path': 'EXECUTABLE PATH',
|
||||
}
|
||||
|
||||
if params.with_webkit:
|
||||
@ -951,6 +953,7 @@ def test_version_output(params, stubs, monkeypatch):
|
||||
Platform: PLATFORM, ARCHITECTURE{linuxdist}
|
||||
Frozen: {frozen}
|
||||
Imported from {import_path}
|
||||
Using Python from {python_path}
|
||||
Qt library executable path: QT PATH, data path: QT PATH
|
||||
{osinfo}
|
||||
Paths:
|
||||
|
Loading…
Reference in New Issue
Block a user