Merge branch 'master' of https://github.com/qutebrowser/qutebrowser into jay/tab-bg-focus

This commit is contained in:
Jay Kamat 2018-05-22 23:17:52 -07:00
commit 74ea696a5c
No known key found for this signature in database
GPG Key ID: 5D2E399600F4F7B5
23 changed files with 100 additions and 35 deletions

View File

@ -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

View File

@ -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
------

View File

@ -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
-----------------

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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)

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -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: