Add automatic backend selection in earlyinit
This commit is contained in:
parent
7fe86b196d
commit
b1a95a3930
@ -30,6 +30,7 @@ Changed
|
||||
- New way of clicking hints with which solves various small issues
|
||||
- When yanking a mailto: link via hints, the mailto: prefix is now stripped
|
||||
- Zoom level messages are now not stacked on top of each other anymore.
|
||||
- qutebrowser now automatically uses QtWebEngine if QtWebKit is unavailable
|
||||
|
||||
Fixed
|
||||
-----
|
||||
|
@ -446,7 +446,7 @@ def _init_modules(args, crash_handler):
|
||||
else:
|
||||
os.environ.pop('QT_WAYLAND_DISABLE_WINDOWDECORATION', None)
|
||||
# Init backend-specific stuff
|
||||
browsertab.init(args)
|
||||
browsertab.init()
|
||||
|
||||
|
||||
def _init_late_modules(args):
|
||||
|
@ -28,7 +28,7 @@ from PyQt5.QtWidgets import QWidget, QApplication
|
||||
from qutebrowser.keyinput import modeman
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import utils, objreg, usertypes, log, qtutils
|
||||
from qutebrowser.misc import miscwidgets
|
||||
from qutebrowser.misc import miscwidgets, objects
|
||||
from qutebrowser.browser import mouse, hints
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ def create(win_id, parent=None):
|
||||
# Importing modules here so we don't depend on QtWebEngine without the
|
||||
# argument and to avoid circular imports.
|
||||
mode_manager = modeman.instance(win_id)
|
||||
if objreg.get('args').backend == 'webengine':
|
||||
if objects.backend == usertypes.Backend.QtWebEngine:
|
||||
from qutebrowser.browser.webengine import webenginetab
|
||||
tab_class = webenginetab.WebEngineTab
|
||||
else:
|
||||
@ -54,9 +54,9 @@ def create(win_id, parent=None):
|
||||
return tab_class(win_id=win_id, mode_manager=mode_manager, parent=parent)
|
||||
|
||||
|
||||
def init(args):
|
||||
def init():
|
||||
"""Initialize backend-specific modules."""
|
||||
if args.backend == 'webengine':
|
||||
if objects.backend == usertypes.Backend.QtWebEngine:
|
||||
from qutebrowser.browser.webengine import webenginetab
|
||||
webenginetab.init()
|
||||
else:
|
||||
|
@ -28,7 +28,7 @@ from qutebrowser.commands import cmdutils
|
||||
from qutebrowser.utils import (utils, objreg, standarddir, log, qtutils,
|
||||
usertypes)
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.misc import lineparser
|
||||
from qutebrowser.misc import lineparser, objects
|
||||
|
||||
|
||||
class Entry:
|
||||
@ -293,7 +293,6 @@ def init(parent=None):
|
||||
parent=parent)
|
||||
objreg.register('web-history', history)
|
||||
|
||||
used_backend = usertypes.arg2backend[objreg.get('args').backend]
|
||||
if used_backend == usertypes.Backend.QtWebKit:
|
||||
if objects.backend == usertypes.Backend.QtWebKit:
|
||||
from qutebrowser.browser.webkit import webkithistory
|
||||
webkithistory.init(history)
|
||||
|
@ -24,8 +24,8 @@ import binascii
|
||||
|
||||
from PyQt5.QtWidgets import QWidget
|
||||
|
||||
from qutebrowser.utils import log, objreg
|
||||
from qutebrowser.misc import miscwidgets
|
||||
from qutebrowser.utils import log, objreg, usertypes
|
||||
from qutebrowser.misc import miscwidgets, objects
|
||||
|
||||
|
||||
def create(parent=None):
|
||||
@ -36,7 +36,7 @@ def create(parent=None):
|
||||
"""
|
||||
# Importing modules here so we don't depend on QtWebEngine without the
|
||||
# argument and to avoid circular imports.
|
||||
if objreg.get('args').backend == 'webengine':
|
||||
if objects.backend == usertypes.Backend.QtWebEngine:
|
||||
from qutebrowser.browser.webengine import webengineinspector
|
||||
return webengineinspector.WebEngineInspector(parent)
|
||||
else:
|
||||
|
@ -28,7 +28,8 @@ import urllib.parse
|
||||
|
||||
import qutebrowser
|
||||
from qutebrowser.utils import (version, utils, jinja, log, message, docutils,
|
||||
objreg, usertypes)
|
||||
objreg)
|
||||
from qutebrowser.misc import objects
|
||||
|
||||
|
||||
pyeval_output = ":pyeval was never called"
|
||||
@ -89,8 +90,7 @@ class add_handler: # pylint: disable=invalid-name
|
||||
return function
|
||||
|
||||
def wrapper(self, *args, **kwargs):
|
||||
used_backend = usertypes.arg2backend[objreg.get('args').backend]
|
||||
if self._backend is not None and used_backend != self._backend:
|
||||
if self._backend is not None and objects.backend != self._backend:
|
||||
return self.wrong_backend_handler(*args, **kwargs)
|
||||
else:
|
||||
return self._function(*args, **kwargs)
|
||||
|
@ -27,6 +27,7 @@ from qutebrowser.commands import cmdexc, argparser
|
||||
from qutebrowser.utils import (log, utils, message, docutils, objreg,
|
||||
usertypes, typing)
|
||||
from qutebrowser.utils import debug as debug_utils
|
||||
from qutebrowser.misc import objects
|
||||
|
||||
|
||||
class ArgInfo:
|
||||
@ -158,8 +159,7 @@ class Command:
|
||||
window=win_id)
|
||||
self.validate_mode(mode_manager.mode)
|
||||
|
||||
used_backend = usertypes.arg2backend[objreg.get('args').backend]
|
||||
if self.backend is not None and used_backend != self.backend:
|
||||
if self.backend is not None and objects.backend != self.backend:
|
||||
raise cmdexc.PrerequisitesError(
|
||||
"{}: Only available with {} "
|
||||
"backend.".format(self.name, self.backend.name))
|
||||
|
@ -43,6 +43,7 @@ from qutebrowser.config.parsers import ini
|
||||
from qutebrowser.commands import cmdexc, cmdutils
|
||||
from qutebrowser.utils import (message, objreg, utils, standarddir, log,
|
||||
qtutils, error, usertypes)
|
||||
from qutebrowser.misc import objects
|
||||
from qutebrowser.utils.usertypes import Completion
|
||||
|
||||
|
||||
@ -882,10 +883,9 @@ class ConfigManager(QObject):
|
||||
# Will be handled later in .setv()
|
||||
pass
|
||||
else:
|
||||
backend = usertypes.arg2backend[objreg.get('args').backend]
|
||||
if (allowed_backends is not None and
|
||||
backend not in allowed_backends):
|
||||
raise configexc.BackendError(backend)
|
||||
objects.backend not in allowed_backends):
|
||||
raise configexc.BackendError(objects.backend)
|
||||
else:
|
||||
interpolated = None
|
||||
|
||||
|
@ -20,7 +20,8 @@
|
||||
"""Bridge from QWeb(Engine)Settings to our own settings."""
|
||||
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.utils import log, utils, debug, objreg
|
||||
from qutebrowser.utils import log, utils, debug, objreg, usertypes
|
||||
from qutebrowser.misc import objects
|
||||
|
||||
UNSET = object()
|
||||
|
||||
@ -261,7 +262,7 @@ def update_mappings(mappings, section, option):
|
||||
|
||||
def init(args):
|
||||
"""Initialize all QWeb(Engine)Settings."""
|
||||
if args.backend == 'webengine':
|
||||
if objects.backend == usertypes.Backend.QtWebEngine:
|
||||
from qutebrowser.browser.webengine import webenginesettings
|
||||
webenginesettings.init(args)
|
||||
else:
|
||||
@ -271,7 +272,7 @@ def init(args):
|
||||
|
||||
def shutdown():
|
||||
"""Shut down QWeb(Engine)Settings."""
|
||||
if objreg.get('args').backend == 'webengine':
|
||||
if objects.backend == usertypes.Backend.QtWebEngine:
|
||||
from qutebrowser.browser.webengine import webenginesettings
|
||||
webenginesettings.shutdown()
|
||||
else:
|
||||
|
@ -28,6 +28,7 @@ from qutebrowser.keyinput import modeparsers, keyparser
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.commands import cmdexc, cmdutils
|
||||
from qutebrowser.utils import usertypes, log, objreg, utils
|
||||
from qutebrowser.misc import objects
|
||||
|
||||
|
||||
class KeyEvent:
|
||||
@ -266,13 +267,12 @@ class ModeManager(QObject):
|
||||
except KeyError:
|
||||
raise cmdexc.CommandError("Mode {} does not exist!".format(mode))
|
||||
|
||||
backend = usertypes.arg2backend[objreg.get('args').backend]
|
||||
if m in [usertypes.KeyMode.hint, usertypes.KeyMode.command,
|
||||
usertypes.KeyMode.yesno, usertypes.KeyMode.prompt]:
|
||||
raise cmdexc.CommandError(
|
||||
"Mode {} can't be entered manually!".format(mode))
|
||||
elif (m == usertypes.KeyMode.caret and
|
||||
backend == usertypes.Backend.QtWebEngine):
|
||||
objects.backend == usertypes.Backend.QtWebEngine):
|
||||
raise cmdexc.CommandError("Caret mode is not supported with "
|
||||
"QtWebEngine yet.")
|
||||
|
||||
|
@ -29,6 +29,7 @@ from PyQt5.QtGui import QIcon, QPalette, QColor
|
||||
|
||||
from qutebrowser.utils import qtutils, objreg, utils, usertypes, log
|
||||
from qutebrowser.config import config
|
||||
from qutebrowser.misc import objects
|
||||
|
||||
|
||||
PixelMetrics = usertypes.enum('PixelMetrics', ['icon_padding'],
|
||||
@ -124,7 +125,7 @@ class TabWidget(QTabWidget):
|
||||
fields['title'] = page_title
|
||||
fields['title_sep'] = ' - ' if page_title else ''
|
||||
fields['perc_raw'] = tab.progress()
|
||||
fields['backend'] = objreg.get('args').backend
|
||||
fields['backend'] = objects.backend.name
|
||||
|
||||
if tab.load_status() == usertypes.LoadStatus.loading:
|
||||
fields['perc'] = '[{}%] '.format(tab.progress())
|
||||
|
@ -239,7 +239,27 @@ def check_pyqt_core():
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def check_qt_version(args):
|
||||
def get_backend(args):
|
||||
"""Find out what backend to use based on available libraries.
|
||||
|
||||
Note this function returns the backend as a string so we don't have to
|
||||
import qutebrowser.utils.usertypes yet.
|
||||
"""
|
||||
try:
|
||||
import PyQt5.QtWebKit
|
||||
webkit_available = True
|
||||
except ImportError:
|
||||
webkit_available = False
|
||||
|
||||
if args.backend is not None:
|
||||
return args.backend
|
||||
elif webkit_available:
|
||||
return 'webkit'
|
||||
else:
|
||||
return 'webengine'
|
||||
|
||||
|
||||
def check_qt_version(backend):
|
||||
"""Check if the Qt version is recent enough."""
|
||||
from PyQt5.QtCore import qVersion
|
||||
from qutebrowser.utils import qtutils
|
||||
@ -247,8 +267,8 @@ def check_qt_version(args):
|
||||
text = ("Fatal error: Qt and PyQt >= 5.2.0 are required, but {} is "
|
||||
"installed.".format(qVersion()))
|
||||
_die(text)
|
||||
elif args.backend == 'webengine' and qtutils.version_check('5.6.0',
|
||||
operator.lt):
|
||||
elif backend == 'webengine' and qtutils.version_check('5.6.0',
|
||||
operator.lt):
|
||||
text = ("Fatal error: Qt and PyQt >= 5.6.0 are required for "
|
||||
"QtWebEngine support, but {} is installed.".format(qVersion()))
|
||||
_die(text)
|
||||
@ -267,7 +287,7 @@ def check_ssl_support():
|
||||
_die(text)
|
||||
|
||||
|
||||
def check_libraries(args):
|
||||
def check_libraries(backend):
|
||||
"""Check if all needed Python libraries are installed."""
|
||||
modules = {
|
||||
'pkg_resources':
|
||||
@ -293,10 +313,11 @@ def check_libraries(args):
|
||||
"or Install via pip.",
|
||||
pip="PyYAML"),
|
||||
}
|
||||
if args.backend == 'webengine':
|
||||
if backend == 'webengine':
|
||||
modules['PyQt5.QtWebEngineWidgets'] = _missing_str("QtWebEngine",
|
||||
webengine=True)
|
||||
else:
|
||||
assert backend == 'webkit'
|
||||
modules['PyQt5.QtWebKit'] = _missing_str("PyQt5.QtWebKit")
|
||||
|
||||
from qutebrowser.utils import log
|
||||
@ -345,6 +366,17 @@ def check_optimize_flag():
|
||||
"unexpected behavior may occur.")
|
||||
|
||||
|
||||
def set_backend(backend):
|
||||
"""Set the objects.backend global to the given backend (as string)."""
|
||||
from qutebrowser.misc import objects
|
||||
from qutebrowser.utils import usertypes
|
||||
backends = {
|
||||
'webkit': usertypes.Backend.QtWebKit,
|
||||
'webengine': usertypes.Backend.QtWebEngine,
|
||||
}
|
||||
objects.backend = backends[backend]
|
||||
|
||||
|
||||
def earlyinit(args):
|
||||
"""Do all needed early initialization.
|
||||
|
||||
@ -367,8 +399,10 @@ def earlyinit(args):
|
||||
fix_harfbuzz(args)
|
||||
# Now we can be sure QtCore is available, so we can print dialogs on
|
||||
# errors, so people only using the GUI notice them as well.
|
||||
check_qt_version(args)
|
||||
backend = get_backend(args)
|
||||
check_qt_version(backend)
|
||||
remove_inputhook()
|
||||
check_libraries(args)
|
||||
check_libraries(backend)
|
||||
check_ssl_support()
|
||||
check_optimize_flag()
|
||||
set_backend(backend)
|
||||
|
26
qutebrowser/misc/objects.py
Normal file
26
qutebrowser/misc/objects.py
Normal file
@ -0,0 +1,26 @@
|
||||
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
||||
|
||||
# Copyright 2017 Florian Bruhin (The Compiler) <mail@qutebrowser.org>
|
||||
#
|
||||
# This file is part of qutebrowser.
|
||||
#
|
||||
# qutebrowser is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# qutebrowser is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Various global objects."""
|
||||
|
||||
# NOTE: We need to be careful with imports here, as this is imported from
|
||||
# earlyinit.
|
||||
|
||||
# A usertypes.Backend member
|
||||
backend = None
|
@ -65,7 +65,7 @@ def get_argparser():
|
||||
"qutebrowser instance running.")
|
||||
parser.add_argument('--backend', choices=['webkit', 'webengine'],
|
||||
help="Which backend to use (webengine backend is "
|
||||
"EXPERIMENTAL!).", default='webkit')
|
||||
"EXPERIMENTAL!).")
|
||||
parser.add_argument('--enable-webengine-inspector', action='store_true',
|
||||
help="Enable the web inspector for QtWebEngine. Note "
|
||||
"that this is a SECURITY RISK and you should not "
|
||||
|
@ -255,10 +255,6 @@ LoadStatus = enum('LoadStatus', ['none', 'success', 'success_https', 'error',
|
||||
|
||||
# Backend of a tab
|
||||
Backend = enum('Backend', ['QtWebKit', 'QtWebEngine'])
|
||||
arg2backend = {
|
||||
'webkit': Backend.QtWebKit,
|
||||
'webengine': Backend.QtWebEngine,
|
||||
}
|
||||
|
||||
|
||||
# JS world for QtWebEngine
|
||||
|
@ -155,11 +155,10 @@ def tab_registry(win_registry):
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fake_web_tab(stubs, tab_registry, mode_manager, qapp, fake_args):
|
||||
def fake_web_tab(stubs, tab_registry, mode_manager, qapp):
|
||||
"""Fixture providing the FakeWebTab *class*."""
|
||||
if PYQT_VERSION < 0x050600:
|
||||
pytest.skip('Causes segfaults, see #1638')
|
||||
fake_args.backend = 'webengine'
|
||||
return stubs.FakeWebTab
|
||||
|
||||
|
||||
|
@ -22,6 +22,7 @@ import logging
|
||||
|
||||
from PyQt5.QtCore import QUrl
|
||||
|
||||
from qutebrowser.utils import usertypes
|
||||
from qutebrowser.browser import pdfjs, qutescheme
|
||||
# pylint: disable=unused-import
|
||||
from qutebrowser.browser.webkit.network import webkitqutescheme
|
||||
@ -42,8 +43,9 @@ class TestPDFJSHandler:
|
||||
get_pdfjs_res)
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def patch_args(self, fake_args):
|
||||
fake_args.backend = 'webkit'
|
||||
def patch_backend(self, monkeypatch):
|
||||
monkeypatch.setattr(qutescheme.objects, 'backend',
|
||||
usertypes.Backend.QtWebKit)
|
||||
|
||||
def test_existing_resource(self):
|
||||
"""Test with a resource that exists."""
|
||||
|
@ -27,7 +27,7 @@ from hypothesis import strategies
|
||||
from PyQt5.QtCore import QUrl
|
||||
|
||||
from qutebrowser.browser import history
|
||||
from qutebrowser.utils import objreg, urlutils
|
||||
from qutebrowser.utils import objreg, urlutils, usertypes
|
||||
|
||||
|
||||
class FakeWebHistory:
|
||||
@ -380,14 +380,14 @@ def test_history_interface(qtbot, webview, hist_interface):
|
||||
webview.load(url)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('backend', ['webengine', 'webkit'])
|
||||
def test_init(backend, qapp, tmpdir, monkeypatch, fake_save_manager,
|
||||
fake_args):
|
||||
@pytest.mark.parametrize('backend', [usertypes.Backend.QtWebEngine,
|
||||
usertypes.Backend.QtWebKit])
|
||||
def test_init(backend, qapp, tmpdir, monkeypatch, fake_save_manager):
|
||||
if backend == 'webkit':
|
||||
pytest.importorskip('PyQt5.QtWebKitWidgets')
|
||||
|
||||
fake_args.backend = backend
|
||||
monkeypatch.setattr(history.standarddir, 'data', lambda: str(tmpdir))
|
||||
monkeypatch.setattr(history.objects, 'backend', backend)
|
||||
history.init(qapp)
|
||||
hist = objreg.get('web-history')
|
||||
assert hist.parent() is qapp
|
||||
@ -397,11 +397,11 @@ def test_init(backend, qapp, tmpdir, monkeypatch, fake_save_manager,
|
||||
except ImportError:
|
||||
QWebHistoryInterface = None
|
||||
|
||||
if backend == 'webkit':
|
||||
if backend == usertypes.Backend.QtWebKit:
|
||||
default_interface = QWebHistoryInterface.defaultInterface()
|
||||
assert default_interface._history is hist
|
||||
else:
|
||||
assert backend == 'webengine'
|
||||
assert backend == usertypes.Backend.QtWebEngine
|
||||
if QWebHistoryInterface is None:
|
||||
default_interface = None
|
||||
else:
|
||||
|
@ -446,19 +446,20 @@ class TestArgument:
|
||||
class TestRun:
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def patching(self, mode_manager, fake_args):
|
||||
fake_args.backend = 'webkit'
|
||||
def patch_backend(self, mode_manager, monkeypatch):
|
||||
monkeypatch.setattr(command.objects, 'backend',
|
||||
usertypes.Backend.QtWebKit)
|
||||
|
||||
@pytest.mark.parametrize('backend, used, ok', [
|
||||
(usertypes.Backend.QtWebEngine, 'webengine', True),
|
||||
(usertypes.Backend.QtWebEngine, 'webkit', False),
|
||||
(usertypes.Backend.QtWebKit, 'webengine', False),
|
||||
(usertypes.Backend.QtWebKit, 'webkit', True),
|
||||
(None, 'webengine', True),
|
||||
(None, 'webkit', True),
|
||||
(usertypes.Backend.QtWebEngine, usertypes.Backend.QtWebEngine, True),
|
||||
(usertypes.Backend.QtWebEngine, usertypes.Backend.QtWebKit, False),
|
||||
(usertypes.Backend.QtWebKit, usertypes.Backend.QtWebEngine, False),
|
||||
(usertypes.Backend.QtWebKit, usertypes.Backend.QtWebKit, True),
|
||||
(None, usertypes.Backend.QtWebEngine, True),
|
||||
(None, usertypes.Backend.QtWebKit, True),
|
||||
])
|
||||
def test_backend(self, fake_args, backend, used, ok):
|
||||
fake_args.backend = used
|
||||
def test_backend(self, monkeypatch, backend, used, ok):
|
||||
monkeypatch.setattr(command.objects, 'backend', used)
|
||||
cmd = _get_cmd(backend=backend)
|
||||
if ok:
|
||||
cmd.run(win_id=0)
|
||||
@ -471,7 +472,7 @@ class TestRun:
|
||||
cmd = _get_cmd()
|
||||
cmd.run(win_id=0)
|
||||
|
||||
def test_instance_unavailable_with_backend(self, fake_args):
|
||||
def test_instance_unavailable_with_backend(self, monkeypatch):
|
||||
"""Test what happens when a backend doesn't have an objreg object.
|
||||
|
||||
For example, QtWebEngine doesn't have 'hintmanager' registered. We make
|
||||
@ -484,7 +485,8 @@ class TestRun:
|
||||
"""Blah."""
|
||||
pass
|
||||
|
||||
fake_args.backend = 'webkit'
|
||||
monkeypatch.setattr(command.objects, 'backend',
|
||||
usertypes.Backend.QtWebKit)
|
||||
cmd = cmdutils.cmd_dict['fun']
|
||||
with pytest.raises(cmdexc.PrerequisitesError) as excinfo:
|
||||
cmd.run(win_id=0)
|
||||
|
@ -21,11 +21,14 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from qutebrowser.mainwindow import tabwidget
|
||||
from qutebrowser.config import configtypes
|
||||
from PyQt5.QtGui import QIcon, QPixmap, QFont, QColor
|
||||
from PyQt5.QtCore import Qt
|
||||
|
||||
from qutebrowser.mainwindow import tabwidget
|
||||
from qutebrowser.config import configtypes
|
||||
from qutebrowser.misc import objects
|
||||
from qutebrowser.utils import usertypes
|
||||
|
||||
|
||||
class TestTabWidget:
|
||||
|
||||
@ -56,10 +59,12 @@ class TestTabWidget:
|
||||
}
|
||||
|
||||
@pytest.fixture
|
||||
def widget(self, qtbot, config_stub):
|
||||
def widget(self, qtbot, monkeypatch, config_stub):
|
||||
config_stub.data = self.CONFIG
|
||||
w = tabwidget.TabWidget(0)
|
||||
qtbot.addWidget(w)
|
||||
monkeypatch.setattr(tabwidget.objects, 'backend',
|
||||
usertypes.Backend.QtWebKit)
|
||||
return w
|
||||
|
||||
def test_small_icon_doesnt_crash(self, widget, qtbot, fake_web_tab):
|
||||
|
Loading…
Reference in New Issue
Block a user