summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJimmy <jimmy@spalge.com>2022-04-16 14:11:26 +1200
committerJimmy <jimmy@spalge.com>2022-04-30 13:34:31 +1200
commitdf32aa482c05312e0244e7da5449b10b9a25ab34 (patch)
treef8e11338e8ee6ae6ec1185f9af35e924caf7fdab
parente2785664c8ac9f6e055fd035ea4644a1e7071f67 (diff)
downloadqutebrowser-df32aa482c05312e0244e7da5449b10b9a25ab34.tar.gz
qutebrowser-df32aa482c05312e0244e7da5449b10b9a25ab34.zip
Re-write PyQt5 imports to be via our wrapper.
Still some manual fixes to make, see #995 and linked PRs. This was done like: date ; for mod in QtCore QtDBus QtGui QtNetwork QtPrintSupport QtQml QtSql QtWebEngine QtWebEngineCore QtWebEngineWidgets QtWebKit QtWebKitWidgets QtWidgets; do echo "renaming $mod" python3 -m libcst.tool codemod rename_pyqt.RenameCommand qutebrowser/ tests --old_name=PyQt5.$mod.* --new_name=qutebrowser.qt:$mod.* --no-format done ; dat Where the list of modules was obtained via: semgrep --lang=py -e 'from PyQt5.$SUBMODULE import ($IMPORTEES)' -o findings.json --json qutebrowser scripts/ tests/ and then with open("findings.json") as f: data=json.load(f) results = data['results'] submodules = sorted(set(r['extra']['metavars']['$SUBMODULE']['abstract_content'] for r in results)) for m in submodules: print(m)
-rw-r--r--qutebrowser/api/config.py4
-rw-r--r--qutebrowser/api/downloads.py11
-rw-r--r--qutebrowser/app.py36
-rw-r--r--qutebrowser/browser/browsertab.py178
-rw-r--r--qutebrowser/browser/commands.py70
-rw-r--r--qutebrowser/browser/downloads.py103
-rw-r--r--qutebrowser/browser/downloadview.py34
-rw-r--r--qutebrowser/browser/eventfilter.py35
-rw-r--r--qutebrowser/browser/greasemonkey.py13
-rw-r--r--qutebrowser/browser/hints.py46
-rw-r--r--qutebrowser/browser/history.py44
-rw-r--r--qutebrowser/browser/inspector.py32
-rw-r--r--qutebrowser/browser/navigate.py28
-rw-r--r--qutebrowser/browser/network/pac.py53
-rw-r--r--qutebrowser/browser/network/proxy.py20
-rw-r--r--qutebrowser/browser/pdfjs.py19
-rw-r--r--qutebrowser/browser/qtnetworkdownloads.py60
-rw-r--r--qutebrowser/browser/qutescheme.py76
-rw-r--r--qutebrowser/browser/shared.py23
-rw-r--r--qutebrowser/browser/signalfilter.py4
-rw-r--r--qutebrowser/browser/urlmarks.py13
-rw-r--r--qutebrowser/browser/webelem.py49
-rw-r--r--qutebrowser/browser/webengine/certificateerror.py9
-rw-r--r--qutebrowser/browser/webengine/interceptor.py63
-rw-r--r--qutebrowser/browser/webengine/notification.py176
-rw-r--r--qutebrowser/browser/webengine/tabhistory.py11
-rw-r--r--qutebrowser/browser/webengine/webenginedownloads.py51
-rw-r--r--qutebrowser/browser/webengine/webengineelem.py27
-rw-r--r--qutebrowser/browser/webengine/webengineinspector.py14
-rw-r--r--qutebrowser/browser/webengine/webenginequtescheme.py44
-rw-r--r--qutebrowser/browser/webengine/webenginesettings.py104
-rw-r--r--qutebrowser/browser/webengine/webenginetab.py238
-rw-r--r--qutebrowser/browser/webengine/webview.py60
-rw-r--r--qutebrowser/browser/webkit/cache.py4
-rw-r--r--qutebrowser/browser/webkit/certificateerror.py6
-rw-r--r--qutebrowser/browser/webkit/cookies.py14
-rw-r--r--qutebrowser/browser/webkit/http.py4
-rw-r--r--qutebrowser/browser/webkit/mhtml.py14
-rw-r--r--qutebrowser/browser/webkit/network/networkmanager.py41
-rw-r--r--qutebrowser/browser/webkit/network/networkreply.py40
-rw-r--r--qutebrowser/browser/webkit/network/webkitqutescheme.py21
-rw-r--r--qutebrowser/browser/webkit/tabhistory.py11
-rw-r--r--qutebrowser/browser/webkit/webkitelem.py46
-rw-r--r--qutebrowser/browser/webkit/webkithistory.py6
-rw-r--r--qutebrowser/browser/webkit/webkitinspector.py14
-rw-r--r--qutebrowser/browser/webkit/webkitsettings.py111
-rw-r--r--qutebrowser/browser/webkit/webkittab.py218
-rw-r--r--qutebrowser/browser/webkit/webpage.py102
-rw-r--r--qutebrowser/browser/webkit/webview.py40
-rw-r--r--qutebrowser/commands/argparser.py4
-rw-r--r--qutebrowser/commands/runners.py13
-rw-r--r--qutebrowser/commands/userscripts.py32
-rw-r--r--qutebrowser/completion/completer.py14
-rw-r--r--qutebrowser/completion/completiondelegate.py103
-rw-r--r--qutebrowser/completion/completionwidget.py29
-rw-r--r--qutebrowser/completion/models/completionmodel.py41
-rw-r--r--qutebrowser/completion/models/filepathcategory.py17
-rw-r--r--qutebrowser/completion/models/histcategory.py7
-rw-r--r--qutebrowser/completion/models/listcategory.py16
-rw-r--r--qutebrowser/completion/models/urlmodel.py4
-rw-r--r--qutebrowser/components/braveadblock.py6
-rw-r--r--qutebrowser/components/hostblock.py4
-rw-r--r--qutebrowser/components/misccommands.py11
-rw-r--r--qutebrowser/components/readlinecommands.py11
-rw-r--r--qutebrowser/components/utils/blockutils.py15
-rw-r--r--qutebrowser/config/config.py13
-rw-r--r--qutebrowser/config/configcommands.py8
-rw-r--r--qutebrowser/config/configfiles.py26
-rw-r--r--qutebrowser/config/configinit.py4
-rw-r--r--qutebrowser/config/configtypes.py60
-rw-r--r--qutebrowser/config/configutils.py14
-rw-r--r--qutebrowser/config/qtargs.py7
-rw-r--r--qutebrowser/config/stylesheet.py11
-rw-r--r--qutebrowser/config/websettings.py17
-rw-r--r--qutebrowser/extensions/interceptors.py8
-rw-r--r--qutebrowser/extensions/loader.py4
-rw-r--r--qutebrowser/keyinput/basekeyparser.py52
-rw-r--r--qutebrowser/keyinput/eventfilter.py24
-rw-r--r--qutebrowser/keyinput/keyutils.py300
-rw-r--r--qutebrowser/keyinput/modeman.py45
-rw-r--r--qutebrowser/keyinput/modeparsers.py63
-rw-r--r--qutebrowser/mainwindow/mainwindow.py66
-rw-r--r--qutebrowser/mainwindow/messageview.py26
-rw-r--r--qutebrowser/mainwindow/prompt.py99
-rw-r--r--qutebrowser/mainwindow/statusbar/bar.py41
-rw-r--r--qutebrowser/mainwindow/statusbar/command.py39
-rw-r--r--qutebrowser/mainwindow/statusbar/keystring.py4
-rw-r--r--qutebrowser/mainwindow/statusbar/percentage.py7
-rw-r--r--qutebrowser/mainwindow/statusbar/progress.py14
-rw-r--r--qutebrowser/mainwindow/statusbar/tabindex.py4
-rw-r--r--qutebrowser/mainwindow/statusbar/textbase.py18
-rw-r--r--qutebrowser/mainwindow/statusbar/url.py14
-rw-r--r--qutebrowser/mainwindow/tabbedbrowser.py112
-rw-r--r--qutebrowser/mainwindow/tabwidget.py168
-rw-r--r--qutebrowser/mainwindow/windowundo.py8
-rw-r--r--qutebrowser/misc/autoupdate.py13
-rw-r--r--qutebrowser/misc/backendproblem.py45
-rw-r--r--qutebrowser/misc/cmdhistory.py9
-rw-r--r--qutebrowser/misc/consolewidget.py30
-rw-r--r--qutebrowser/misc/crashdialog.py88
-rw-r--r--qutebrowser/misc/crashsignal.py31
-rw-r--r--qutebrowser/misc/earlyinit.py31
-rw-r--r--qutebrowser/misc/editor.py21
-rw-r--r--qutebrowser/misc/elf.py4
-rw-r--r--qutebrowser/misc/guiprocess.py64
-rw-r--r--qutebrowser/misc/httpclient.py27
-rw-r--r--qutebrowser/misc/ipc.py55
-rw-r--r--qutebrowser/misc/keyhintwidget.py14
-rw-r--r--qutebrowser/misc/lineparser.py9
-rw-r--r--qutebrowser/misc/miscwidgets.py85
-rw-r--r--qutebrowser/misc/msgbox.py15
-rw-r--r--qutebrowser/misc/objects.py2
-rw-r--r--qutebrowser/misc/pastebin.py13
-rw-r--r--qutebrowser/misc/quitter.py13
-rw-r--r--qutebrowser/misc/savemanager.py11
-rw-r--r--qutebrowser/misc/sessions.py22
-rw-r--r--qutebrowser/misc/sql.py31
-rw-r--r--qutebrowser/misc/throttle.py6
-rw-r--r--qutebrowser/misc/utilcmds.py9
-rw-r--r--qutebrowser/utils/debug.py28
-rw-r--r--qutebrowser/utils/error.py4
-rw-r--r--qutebrowser/utils/jinja.py6
-rw-r--r--qutebrowser/utils/log.py2
-rw-r--r--qutebrowser/utils/message.py19
-rw-r--r--qutebrowser/utils/objreg.py15
-rw-r--r--qutebrowser/utils/qtutils.py109
-rw-r--r--qutebrowser/utils/standarddir.py57
-rw-r--r--qutebrowser/utils/urlmatch.py6
-rw-r--r--qutebrowser/utils/urlutils.py81
-rw-r--r--qutebrowser/utils/usertypes.py32
-rw-r--r--qutebrowser/utils/utils.py28
-rw-r--r--qutebrowser/utils/version.py44
-rw-r--r--tests/conftest.py8
-rw-r--r--tests/end2end/conftest.py12
-rw-r--r--tests/end2end/features/test_downloads_bdd.py4
-rw-r--r--tests/end2end/features/test_editor_bdd.py10
-rw-r--r--tests/end2end/fixtures/notificationserver.py44
-rw-r--r--tests/end2end/fixtures/quteprocess.py17
-rw-r--r--tests/end2end/fixtures/test_testprocess.py4
-rw-r--r--tests/end2end/fixtures/testprocess.py21
-rw-r--r--tests/end2end/fixtures/webserver.py6
-rw-r--r--tests/end2end/test_dirbrowser.py6
-rw-r--r--tests/end2end/test_invocations.py16
-rw-r--r--tests/helpers/fixtures.py32
-rw-r--r--tests/helpers/messagemock.py12
-rw-r--r--tests/helpers/stubs.py88
-rw-r--r--tests/helpers/testutils.py6
-rw-r--r--tests/unit/browser/test_caret.py4
-rw-r--r--tests/unit/browser/test_downloadview.py6
-rw-r--r--tests/unit/browser/test_hints.py8
-rw-r--r--tests/unit/browser/test_history.py139
-rw-r--r--tests/unit/browser/test_inspector.py6
-rw-r--r--tests/unit/browser/test_navigate.py48
-rw-r--r--tests/unit/browser/test_pdfjs.py14
-rw-r--r--tests/unit/browser/test_qutescheme.py44
-rw-r--r--tests/unit/browser/test_signalfilter.py14
-rw-r--r--tests/unit/browser/test_urlmarks.py26
-rw-r--r--tests/unit/browser/webengine/test_webengine_cookies.py12
-rw-r--r--tests/unit/browser/webengine/test_webenginedownloads.py4
-rw-r--r--tests/unit/browser/webengine/test_webengineinterceptor.py6
-rw-r--r--tests/unit/browser/webkit/http/test_http.py4
-rw-r--r--tests/unit/browser/webkit/network/test_filescheme.py15
-rw-r--r--tests/unit/browser/webkit/network/test_networkreply.py24
-rw-r--r--tests/unit/browser/webkit/network/test_pac.py34
-rw-r--r--tests/unit/browser/webkit/test_cache.py43
-rw-r--r--tests/unit/browser/webkit/test_certificateerror.py8
-rw-r--r--tests/unit/browser/webkit/test_cookies.py10
-rw-r--r--tests/unit/browser/webkit/test_tabhistory.py32
-rw-r--r--tests/unit/browser/webkit/test_webkitelem.py95
-rw-r--r--tests/unit/commands/test_argparser.py4
-rw-r--r--tests/unit/commands/test_userscripts.py4
-rw-r--r--tests/unit/completion/test_completer.py7
-rw-r--r--tests/unit/completion/test_completiondelegate.py24
-rw-r--r--tests/unit/completion/test_completionmodel.py4
-rw-r--r--tests/unit/completion/test_completionwidget.py4
-rw-r--r--tests/unit/completion/test_models.py110
-rw-r--r--tests/unit/components/test_blockutils.py6
-rw-r--r--tests/unit/components/test_braveadblock.py24
-rw-r--r--tests/unit/components/test_hostblock.py24
-rw-r--r--tests/unit/components/test_readlinecommands.py9
-rw-r--r--tests/unit/config/test_config.py11
-rw-r--r--tests/unit/config/test_configcommands.py12
-rw-r--r--tests/unit/config/test_configfiles.py6
-rw-r--r--tests/unit/config/test_configtypes.py96
-rw-r--r--tests/unit/config/test_configutils.py37
-rw-r--r--tests/unit/config/test_qtargs_locale_workaround.py4
-rw-r--r--tests/unit/config/test_stylesheet.py4
-rw-r--r--tests/unit/javascript/conftest.py8
-rw-r--r--tests/unit/javascript/test_greasemonkey.py10
-rw-r--r--tests/unit/javascript/test_js_execution.py22
-rw-r--r--tests/unit/javascript/test_js_quirks.py12
-rw-r--r--tests/unit/keyinput/key_data.py6
-rw-r--r--tests/unit/keyinput/test_basekeyparser.py90
-rw-r--r--tests/unit/keyinput/test_bindingtrie.py30
-rw-r--r--tests/unit/keyinput/test_keyutils.py335
-rw-r--r--tests/unit/keyinput/test_modeman.py17
-rw-r--r--tests/unit/keyinput/test_modeparsers.py25
-rw-r--r--tests/unit/mainwindow/statusbar/test_textbase.py10
-rw-r--r--tests/unit/mainwindow/statusbar/test_url.py30
-rw-r--r--tests/unit/mainwindow/test_messageview.py10
-rw-r--r--tests/unit/mainwindow/test_prompt.py10
-rw-r--r--tests/unit/mainwindow/test_tabwidget.py6
-rw-r--r--tests/unit/misc/test_autoupdate.py4
-rw-r--r--tests/unit/misc/test_editor.py24
-rw-r--r--tests/unit/misc/test_guiprocess.py15
-rw-r--r--tests/unit/misc/test_ipc.py73
-rw-r--r--tests/unit/misc/test_miscwidgets.py33
-rw-r--r--tests/unit/misc/test_msgbox.py21
-rw-r--r--tests/unit/misc/test_pastebin.py8
-rw-r--r--tests/unit/misc/test_sessions.py16
-rw-r--r--tests/unit/misc/test_sql.py12
-rw-r--r--tests/unit/misc/test_throttle.py4
-rw-r--r--tests/unit/misc/test_utilcmds.py4
-rw-r--r--tests/unit/test_app.py4
-rw-r--r--tests/unit/utils/test_debug.py57
-rw-r--r--tests/unit/utils/test_error.py9
-rw-r--r--tests/unit/utils/test_jinja.py6
-rw-r--r--tests/unit/utils/test_log.py1
-rw-r--r--tests/unit/utils/test_qtutils.py175
-rw-r--r--tests/unit/utils/test_standarddir.py10
-rw-r--r--tests/unit/utils/test_urlmatch.py42
-rw-r--r--tests/unit/utils/test_urlutils.py155
-rw-r--r--tests/unit/utils/test_utils.py17
-rw-r--r--tests/unit/utils/test_version.py11
-rw-r--r--tests/unit/utils/usertypes/test_timer.py4
225 files changed, 3719 insertions, 4001 deletions
diff --git a/qutebrowser/api/config.py b/qutebrowser/api/config.py
index 19e2b3c3e..cfb726840 100644
--- a/qutebrowser/api/config.py
+++ b/qutebrowser/api/config.py
@@ -21,7 +21,7 @@
from typing import cast, Any
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.config import config
@@ -38,6 +38,6 @@ from qutebrowser.config import config
val = cast('config.ConfigContainer', None)
-def get(name: str, url: QUrl = None) -> Any:
+def get(name: str, url: QtCore.QUrl = None) -> Any:
"""Get a value from the config based on a string name."""
return config.instance.get(name, url)
diff --git a/qutebrowser/api/downloads.py b/qutebrowser/api/downloads.py
index cd33f5709..54902b711 100644
--- a/qutebrowser/api/downloads.py
+++ b/qutebrowser/api/downloads.py
@@ -23,20 +23,19 @@
import io
-from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, QUrl
-
from qutebrowser.browser import downloads, qtnetworkdownloads
from qutebrowser.utils import objreg
+from qutebrowser.qt import QtCore
UnsupportedAttribute = downloads.UnsupportedAttribute
-class TempDownload(QObject):
+class TempDownload(QtCore.QObject):
"""A download of some data into a file object."""
- finished = pyqtSignal()
+ finished = QtCore.pyqtSignal()
def __init__(self, item: qtnetworkdownloads.DownloadItem) -> None:
super().__init__()
@@ -45,13 +44,13 @@ class TempDownload(QObject):
self.successful = False
self.fileobj = item.fileobj
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_download_finished(self) -> None:
self.successful = self._item.successful
self.finished.emit()
-def download_temp(url: QUrl) -> TempDownload:
+def download_temp(url: QtCore.QUrl) -> TempDownload:
"""Download the given URL into a file object.
The download is not saved to disk.
diff --git a/qutebrowser/app.py b/qutebrowser/app.py
index c046475b5..54b19a44f 100644
--- a/qutebrowser/app.py
+++ b/qutebrowser/app.py
@@ -46,10 +46,6 @@ import datetime
import argparse
from typing import Iterable, Optional
-from PyQt5.QtWidgets import QApplication, QWidget
-from PyQt5.QtGui import QDesktopServices, QPixmap, QIcon
-from PyQt5.QtCore import pyqtSlot, QUrl, QObject, QEvent, pyqtSignal, Qt
-
import qutebrowser
from qutebrowser.commands import runners
from qutebrowser.config import (config, websettings, configfiles, configinit,
@@ -73,6 +69,8 @@ from qutebrowser.utils import (log, version, message, utils, urlutils, objreg,
from qutebrowser.mainwindow.statusbar import command
from qutebrowser.misc import utilcmds
from qutebrowser.browser import commands
+from qutebrowser.qt import QtWidgets, QtGui, QtCore
+
# pylint: enable=unused-import
@@ -146,7 +144,7 @@ def init(*, args: argparse.Namespace) -> None:
crashsignal.crash_handler.init_faulthandler()
objects.qapp.setQuitOnLastWindowClosed(False)
- quitter.instance.shutting_down.connect(QApplication.closeAllWindows)
+ quitter.instance.shutting_down.connect(QtWidgets.QApplication.closeAllWindows)
_init_icon()
_init_pulseaudio()
@@ -170,7 +168,7 @@ def init(*, args: argparse.Namespace) -> None:
_process_args(args)
for scheme in ['http', 'https', 'qute']:
- QDesktopServices.setUrlHandler(
+ QtGui.QDesktopServices.setUrlHandler(
scheme, open_desktopservices_url)
log.init.debug("Init done!")
@@ -179,16 +177,16 @@ def init(*, args: argparse.Namespace) -> None:
def _init_icon():
"""Initialize the icon of qutebrowser."""
- fallback_icon = QIcon()
+ fallback_icon = QtGui.QIcon()
for size in [16, 24, 32, 48, 64, 96, 128, 256, 512]:
filename = 'icons/qutebrowser-{size}x{size}.png'.format(size=size)
- pixmap = QPixmap()
+ pixmap = QtGui.QPixmap()
pixmap.loadFromData(resources.read_file_binary(filename))
if pixmap.isNull():
log.init.warning("Failed to load {}".format(filename))
else:
fallback_icon.addPixmap(pixmap)
- icon = QIcon.fromTheme('qutebrowser', fallback_icon)
+ icon = QtGui.QIcon.fromTheme('qutebrowser', fallback_icon)
if icon.isNull():
log.init.warning("Failed to load icon")
else:
@@ -381,7 +379,7 @@ def _open_special_pages(args):
for state, condition, url in pages:
if general_sect.get(state) != '1' and condition:
- tabbed_browser.tabopen(QUrl(url), background=False)
+ tabbed_browser.tabopen(QtCore.QUrl(url), background=False)
general_sect[state] = '1'
# Show changelog on new releases
@@ -408,7 +406,7 @@ def _open_special_pages(args):
message.info(f"Showing changelog after upgrade to qutebrowser v{qbversion}.")
changelog_url = f'qute://help/changelog.html#v{qbversion}'
- tabbed_browser.tabopen(QUrl(changelog_url), background=False)
+ tabbed_browser.tabopen(QtCore.QUrl(changelog_url), background=False)
def on_focus_changed(_old, new):
@@ -416,7 +414,7 @@ def on_focus_changed(_old, new):
if new is None:
return
- if not isinstance(new, QWidget):
+ if not isinstance(new, QtWidgets.QWidget):
log.misc.debug("on_focus_changed called with non-QWidget {!r}".format(
new))
return
@@ -527,7 +525,7 @@ def _init_modules(*, args):
windowundo.init()
-class Application(QApplication):
+class Application(QtWidgets.QApplication):
"""Main application instance.
@@ -540,8 +538,8 @@ class Application(QApplication):
window_closing: A window is being closed.
"""
- new_window = pyqtSignal(mainwindow.MainWindow)
- window_closing = pyqtSignal(mainwindow.MainWindow)
+ new_window = QtCore.pyqtSignal(mainwindow.MainWindow)
+ window_closing = QtCore.pyqtSignal(mainwindow.MainWindow)
def __init__(self, args):
"""Constructor.
@@ -564,16 +562,16 @@ class Application(QApplication):
self.launch_time = datetime.datetime.now()
self.focusObjectChanged.connect( # type: ignore[attr-defined]
self.on_focus_object_changed)
- self.setAttribute(Qt.AA_UseHighDpiPixmaps, True)
+ self.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps, True)
self.new_window.connect(self._on_new_window)
- @pyqtSlot(mainwindow.MainWindow)
+ @QtCore.pyqtSlot(mainwindow.MainWindow)
def _on_new_window(self, window):
window.tabbed_browser.shutting_down.connect(functools.partial(
self.window_closing.emit, window))
- @pyqtSlot(QObject)
+ @QtCore.pyqtSlot(QtCore.QObject)
def on_focus_object_changed(self, obj):
"""Log when the focus object changed."""
output = repr(obj)
@@ -583,7 +581,7 @@ class Application(QApplication):
def event(self, e):
"""Handle macOS FileOpen events."""
- if e.type() != QEvent.FileOpen:
+ if e.type() != QtCore.QEvent.FileOpen:
return super().event(e)
url = e.url()
diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py
index 661c5f68b..1ee429b70 100644
--- a/qutebrowser/browser/browsertab.py
+++ b/qutebrowser/browser/browsertab.py
@@ -25,17 +25,11 @@ import functools
import dataclasses
from typing import (cast, TYPE_CHECKING, Any, Callable, Iterable, List, Optional,
Sequence, Set, Type, Union)
-
-from PyQt5.QtCore import (pyqtSignal, pyqtSlot, QUrl, QObject, QSizeF, Qt,
- QEvent, QPoint, QRect)
-from PyQt5.QtGui import QKeyEvent, QIcon, QPixmap
-from PyQt5.QtWidgets import QWidget, QApplication, QDialog
-from PyQt5.QtPrintSupport import QPrintDialog, QPrinter
-from PyQt5.QtNetwork import QNetworkAccessManager
+from qutebrowser.qt import QtWidgets, QtWebKitWidgets, QtPrintSupport, QtNetwork
if TYPE_CHECKING:
from PyQt5.QtWebKit import QWebHistory, QWebHistoryItem
- from PyQt5.QtWebKitWidgets import QWebPage
+ from qutebrowser.qt import QWebPage
from PyQt5.QtWebEngineWidgets import (
QWebEngineHistory, QWebEngineHistoryItem, QWebEnginePage)
@@ -45,7 +39,7 @@ from qutebrowser.utils import (utils, objreg, usertypes, log, qtutils,
urlutils, message, jinja)
from qutebrowser.misc import miscwidgets, objects, sessions
from qutebrowser.browser import eventfilter, inspector
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtGui, QtCore, sip
if TYPE_CHECKING:
from qutebrowser.browser import webelem
@@ -57,7 +51,7 @@ tab_id_gen = itertools.count(0)
def create(win_id: int,
private: bool,
- parent: QWidget = None) -> 'AbstractTab':
+ parent: QtWidgets.QWidget = None) -> 'AbstractTab':
"""Get a QtWebKit/QtWebEngine tab object.
Args:
@@ -156,7 +150,7 @@ class AbstractAction:
action_base: Type[Union['QWebPage.WebAction', 'QWebEnginePage.WebAction']]
def __init__(self, tab: 'AbstractTab') -> None:
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
self._tab = tab
def exit_fullscreen(self) -> None:
@@ -229,7 +223,7 @@ class AbstractPrinting:
"""Attribute ``printing`` of AbstractTab for printing the page."""
def __init__(self, tab: 'AbstractTab') -> None:
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
self._tab = tab
def check_pdf_support(self) -> None:
@@ -252,7 +246,7 @@ class AbstractPrinting:
"""Print the tab to a PDF with the given filename."""
raise NotImplementedError
- def to_printer(self, printer: QPrinter,
+ def to_printer(self, printer: QtPrintSupport.QPrinter,
callback: Callable[[bool], None] = None) -> None:
"""Print the tab.
@@ -275,17 +269,17 @@ class AbstractPrinting:
"""Called when the dialog was closed."""
self.to_printer(diag.printer(), print_callback)
- diag = QPrintDialog(self._tab)
+ diag = QtPrintSupport.QPrintDialog(self._tab)
if utils.is_mac:
# For some reason we get a segfault when using open() on macOS
ret = diag.exec()
- if ret == QDialog.Accepted:
+ if ret == QtWidgets.QDialog.Accepted:
do_print()
else:
diag.open(do_print)
-class AbstractSearch(QObject):
+class AbstractSearch(QtCore.QObject):
"""Attribute ``search`` of AbstractTab for doing searches.
@@ -299,16 +293,16 @@ class AbstractSearch(QObject):
#: Signal emitted when a search was finished
#: (True if the text was found, False otherwise)
- finished = pyqtSignal(bool)
+ finished = QtCore.pyqtSignal(bool)
#: Signal emitted when an existing search was cleared.
- cleared = pyqtSignal()
+ cleared = QtCore.pyqtSignal()
_Callback = Callable[[bool], None]
- def __init__(self, tab: 'AbstractTab', parent: QWidget = None):
+ def __init__(self, tab: 'AbstractTab', parent: QtWidgets.QWidget = None):
super().__init__(parent)
self._tab = tab
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
self.text: Optional[str] = None
self.search_displayed = False
@@ -365,21 +359,21 @@ class AbstractSearch(QObject):
raise NotImplementedError
-class AbstractZoom(QObject):
+class AbstractZoom(QtCore.QObject):
"""Attribute ``zoom`` of AbstractTab for controlling zoom."""
- def __init__(self, tab: 'AbstractTab', parent: QWidget = None) -> None:
+ def __init__(self, tab: 'AbstractTab', parent: QtWidgets.QWidget = None) -> None:
super().__init__(parent)
self._tab = tab
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
# Whether zoom was changed from the default.
self._default_zoom_changed = False
self._init_neighborlist()
config.instance.changed.connect(self._on_config_changed)
self._zoom_factor = float(config.val.zoom.default) / 100
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _on_config_changed(self, option: str) -> None:
if option in ['zoom.levels', 'zoom.default']:
if not self._default_zoom_changed:
@@ -452,21 +446,21 @@ class SelectionState(enum.Enum):
line = enum.auto()
-class AbstractCaret(QObject):
+class AbstractCaret(QtCore.QObject):
"""Attribute ``caret`` of AbstractTab for caret browsing."""
#: Signal emitted when the selection was toggled.
- selection_toggled = pyqtSignal(SelectionState)
+ selection_toggled = QtCore.pyqtSignal(SelectionState)
#: Emitted when a ``follow_selection`` action is done.
- follow_selected_done = pyqtSignal()
+ follow_selected_done = QtCore.pyqtSignal()
def __init__(self,
tab: 'AbstractTab',
mode_manager: modeman.ModeManager,
- parent: QWidget = None) -> None:
+ parent: QtWidgets.QWidget = None) -> None:
super().__init__(parent)
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
self._mode_manager = mode_manager
mode_manager.entered.connect(self._on_mode_entered)
mode_manager.left.connect(self._on_mode_left)
@@ -538,37 +532,37 @@ class AbstractCaret(QObject):
def _follow_enter(self, tab: bool) -> None:
"""Follow a link by faking an enter press."""
if tab:
- self._tab.fake_key_press(Qt.Key_Enter, modifier=Qt.ControlModifier)
+ self._tab.fake_key_press(QtCore.Qt.Key_Enter, modifier=QtCore.Qt.ControlModifier)
else:
- self._tab.fake_key_press(Qt.Key_Enter)
+ self._tab.fake_key_press(QtCore.Qt.Key_Enter)
def follow_selected(self, *, tab: bool = False) -> None:
raise NotImplementedError
-class AbstractScroller(QObject):
+class AbstractScroller(QtCore.QObject):
"""Attribute ``scroller`` of AbstractTab to manage scroll position."""
#: Signal emitted when the scroll position changed (int, int)
- perc_changed = pyqtSignal(int, int)
+ perc_changed = QtCore.pyqtSignal(int, int)
#: Signal emitted before the user requested a jump.
#: Used to set the special ' mark so the user can return.
- before_jump_requested = pyqtSignal()
+ before_jump_requested = QtCore.pyqtSignal()
- def __init__(self, tab: 'AbstractTab', parent: QWidget = None):
+ def __init__(self, tab: 'AbstractTab', parent: QtWidgets.QWidget = None):
super().__init__(parent)
self._tab = tab
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
if 'log-scroll-pos' in objects.debug_flags:
self.perc_changed.connect(self._log_scroll_pos_change)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _log_scroll_pos_change(self) -> None:
log.webview.vdebug( # type: ignore[attr-defined]
"Scroll position changed to {}".format(self.pos_px()))
- def _init_widget(self, widget: QWidget) -> None:
+ def _init_widget(self, widget: QtWidgets.QWidget) -> None:
self._widget = widget
def pos_px(self) -> int:
@@ -580,7 +574,7 @@ class AbstractScroller(QObject):
def to_perc(self, x: int = None, y: int = None) -> None:
raise NotImplementedError
- def to_point(self, point: QPoint) -> None:
+ def to_point(self, point: QtCore.QPoint) -> None:
raise NotImplementedError
def to_anchor(self, name: str) -> None:
@@ -711,7 +705,7 @@ class AbstractElements:
_ErrorCallback = Callable[[Exception], None]
def __init__(self, tab: 'AbstractTab') -> None:
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
self._tab = tab
def find_css(self, selector: str,
@@ -750,7 +744,7 @@ class AbstractElements:
"""
raise NotImplementedError
- def find_at_pos(self, pos: QPoint, callback: _SingleCallback) -> None:
+ def find_at_pos(self, pos: QtCore.QPoint, callback: _SingleCallback) -> None:
"""Find the element at the given position async.
This is also called "hit test" elsewhere.
@@ -763,16 +757,16 @@ class AbstractElements:
raise NotImplementedError
-class AbstractAudio(QObject):
+class AbstractAudio(QtCore.QObject):
"""Handling of audio/muting for this tab."""
- muted_changed = pyqtSignal(bool)
- recently_audible_changed = pyqtSignal(bool)
+ muted_changed = QtCore.pyqtSignal(bool)
+ recently_audible_changed = QtCore.pyqtSignal(bool)
- def __init__(self, tab: 'AbstractTab', parent: QWidget = None) -> None:
+ def __init__(self, tab: 'AbstractTab', parent: QtWidgets.QWidget = None) -> None:
super().__init__(parent)
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
self._tab = tab
def set_muted(self, muted: bool, override: bool = False) -> None:
@@ -804,11 +798,11 @@ class AbstractTabPrivate:
def __init__(self, mode_manager: modeman.ModeManager,
tab: 'AbstractTab') -> None:
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
self._tab = tab
self._mode_manager = mode_manager
- def event_target(self) -> QWidget:
+ def event_target(self) -> QtWidgets.QWidget:
"""Return the widget events should be sent to."""
raise NotImplementedError
@@ -837,7 +831,7 @@ class AbstractTabPrivate:
def clear_ssl_errors(self) -> None:
raise NotImplementedError
- def networkaccessmanager(self) -> Optional[QNetworkAccessManager]:
+ def networkaccessmanager(self) -> Optional[QtNetwork.QNetworkAccessManager]:
"""Get the QNetworkAccessManager for this tab.
This is only implemented for QtWebKit.
@@ -882,7 +876,7 @@ class AbstractTabPrivate:
def _init_inspector(self, splitter: 'miscwidgets.InspectorSplitter',
win_id: int,
- parent: QWidget = None) -> 'AbstractWebInspector':
+ parent: QtWidgets.QWidget = None) -> 'AbstractWebInspector':
"""Get a WebKitInspector/WebEngineInspector.
Args:
@@ -893,49 +887,49 @@ class AbstractTabPrivate:
raise NotImplementedError
-class AbstractTab(QWidget):
+class AbstractTab(QtWidgets.QWidget):
"""An adapter for QWebView/QWebEngineView representing a single tab."""
#: Signal emitted when a website requests to close this tab.
- window_close_requested = pyqtSignal()
+ window_close_requested = QtCore.pyqtSignal()
#: Signal emitted when a link is hovered (the hover text)
- link_hovered = pyqtSignal(str)
+ link_hovered = QtCore.pyqtSignal(str)
#: Signal emitted when a page started loading
- load_started = pyqtSignal()
+ load_started = QtCore.pyqtSignal()
#: Signal emitted when a page is loading (progress percentage)
- load_progress = pyqtSignal(int)
+ load_progress = QtCore.pyqtSignal(int)
#: Signal emitted when a page finished loading (success as bool)
- load_finished = pyqtSignal(bool)
+ load_finished = QtCore.pyqtSignal(bool)
#: Signal emitted when a page's favicon changed (icon as QIcon)
- icon_changed = pyqtSignal(QIcon)
+ icon_changed = QtCore.pyqtSignal(QtGui.QIcon)
#: Signal emitted when a page's title changed (new title as str)
- title_changed = pyqtSignal(str)
+ title_changed = QtCore.pyqtSignal(str)
#: Signal emitted when this tab was pinned/unpinned (new pinned state as bool)
- pinned_changed = pyqtSignal(bool)
+ pinned_changed = QtCore.pyqtSignal(bool)
#: Signal emitted when a new tab should be opened (url as QUrl)
- new_tab_requested = pyqtSignal(QUrl)
+ new_tab_requested = QtCore.pyqtSignal(QtCore.QUrl)
#: Signal emitted when a page's URL changed (url as QUrl)
- url_changed = pyqtSignal(QUrl)
+ url_changed = QtCore.pyqtSignal(QtCore.QUrl)
#: Signal emitted when a tab's content size changed
#: (new size as QSizeF)
- contents_size_changed = pyqtSignal(QSizeF)
+ contents_size_changed = QtCore.pyqtSignal(QtCore.QSizeF)
#: Signal emitted when a page requested full-screen (bool)
- fullscreen_requested = pyqtSignal(bool)
+ fullscreen_requested = QtCore.pyqtSignal(bool)
#: Signal emitted before load starts (URL as QUrl)
- before_load_started = pyqtSignal(QUrl)
+ before_load_started = QtCore.pyqtSignal(QtCore.QUrl)
# Signal emitted when a page's load status changed
# (argument: usertypes.LoadStatus)
- load_status_changed = pyqtSignal(usertypes.LoadStatus)
+ load_status_changed = QtCore.pyqtSignal(usertypes.LoadStatus)
# Signal emitted before shutting down
- shutting_down = pyqtSignal()
+ shutting_down = QtCore.pyqtSignal()
# Signal emitted when a history item should be added
- history_item_triggered = pyqtSignal(QUrl, QUrl, str)
+ history_item_triggered = QtCore.pyqtSignal(QtCore.QUrl, QtCore.QUrl, str)
# Signal emitted when the underlying renderer process terminated.
# arg 0: A TerminationStatus member.
# arg 1: The exit code.
- renderer_process_terminated = pyqtSignal(TerminationStatus, int)
+ renderer_process_terminated = QtCore.pyqtSignal(TerminationStatus, int)
# Hosts for which a certificate error happened. Shared between all tabs.
#
@@ -947,7 +941,7 @@ class AbstractTab(QWidget):
def __init__(self, *, win_id: int,
mode_manager: 'modeman.ModeManager',
private: bool,
- parent: QWidget = None) -> None:
+ parent: QtWidgets.QWidget = None) -> None:
utils.unused(mode_manager) # needed for mypy
self.is_private = private
self.win_id = win_id
@@ -962,7 +956,7 @@ class AbstractTab(QWidget):
self.data = TabData()
self._layout = miscwidgets.WrapperLayout(self)
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
self._progress = 0
self._load_status = usertypes.LoadStatus.none
self._tab_event_filter = eventfilter.TabEventFilter(
@@ -976,7 +970,7 @@ class AbstractTab(QWidget):
self.before_load_started.connect(self._on_before_load_started)
- def _set_widget(self, widget: QWidget) -> None:
+ def _set_widget(self, widget: QtWidgets.QWidget) -> None:
# pylint: disable=protected-access
self._widget = widget
self.data.splitter = miscwidgets.InspectorSplitter(
@@ -1009,7 +1003,7 @@ class AbstractTab(QWidget):
self._load_status = val
self.load_status_changed.emit(val)
- def send_event(self, evt: QEvent) -> None:
+ def send_event(self, evt: QtCore.QEvent) -> None:
"""Send the given event to the underlying widget.
The event will be sent via QApplication.postEvent.
@@ -1028,35 +1022,35 @@ class AbstractTab(QWidget):
return
evt.posted = True # type: ignore[attr-defined]
- QApplication.postEvent(recipient, evt)
+ QtWidgets.QApplication.postEvent(recipient, evt)
def navigation_blocked(self) -> bool:
"""Test if navigation is allowed on the current tab."""
return self.data.pinned and config.val.tabs.pinned.frozen
- @pyqtSlot(QUrl)
- def _on_before_load_started(self, url: QUrl) -> None:
+ @QtCore.pyqtSlot(QtCore.QUrl)
+ def _on_before_load_started(self, url: QtCore.QUrl) -> None:
"""Adjust the title if we are going to visit a URL soon."""
qtutils.ensure_valid(url)
url_string = url.toDisplayString()
log.webview.debug("Going to start loading: {}".format(url_string))
self.title_changed.emit(url_string)
- @pyqtSlot(QUrl)
- def _on_url_changed(self, url: QUrl) -> None:
+ @QtCore.pyqtSlot(QtCore.QUrl)
+ def _on_url_changed(self, url: QtCore.QUrl) -> None:
"""Update title when URL has changed and no title is available."""
if url.isValid() and not self.title():
self.title_changed.emit(url.toDisplayString())
self.url_changed.emit(url)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_load_started(self) -> None:
self._progress = 0
self.data.viewing_source = False
self._set_load_status(usertypes.LoadStatus.loading)
self.load_started.emit()
- @pyqtSlot(usertypes.NavigationRequest)
+ @QtCore.pyqtSlot(usertypes.NavigationRequest)
def _on_navigation_request(
self,
navigation: usertypes.NavigationRequest
@@ -1084,7 +1078,7 @@ class AbstractTab(QWidget):
navigation.url.errorString()))
navigation.accepted = False
- @pyqtSlot(bool)
+ @QtCore.pyqtSlot(bool)
def _on_load_finished(self, ok: bool) -> None:
assert self._widget is not None
if sip.isdeleted(self._widget):
@@ -1121,17 +1115,17 @@ class AbstractTab(QWidget):
self._set_load_status(loadstatus)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_history_trigger(self) -> None:
"""Emit history_item_triggered based on backend-specific signal."""
raise NotImplementedError
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def _on_load_progress(self, perc: int) -> None:
self._progress = perc
self.load_progress.emit(perc)
- def url(self, *, requested: bool = False) -> QUrl:
+ def url(self, *, requested: bool = False) -> QtCore.QUrl:
raise NotImplementedError
def progress(self) -> int:
@@ -1140,11 +1134,11 @@ class AbstractTab(QWidget):
def load_status(self) -> usertypes.LoadStatus:
return self._load_status
- def _load_url_prepare(self, url: QUrl) -> None:
+ def _load_url_prepare(self, url: QtCore.QUrl) -> None:
qtutils.ensure_valid(url)
self.before_load_started.emit(url)
- def load_url(self, url: QUrl) -> None:
+ def load_url(self, url: QtCore.QUrl) -> None:
raise NotImplementedError
def reload(self, *, force: bool = False) -> None:
@@ -1154,11 +1148,11 @@ class AbstractTab(QWidget):
raise NotImplementedError
def fake_key_press(self,
- key: Qt.Key,
- modifier: Qt.KeyboardModifier = Qt.NoModifier) -> None:
+ key: QtCore.Qt.Key,
+ modifier: QtCore.Qt.KeyboardModifier = QtCore.Qt.NoModifier) -> None:
"""Send a fake key event to this tab."""
- press_evt = QKeyEvent(QEvent.KeyPress, key, modifier, 0, 0, 0)
- release_evt = QKeyEvent(QEvent.KeyRelease, key, modifier,
+ press_evt = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, key, modifier, 0, 0, 0)
+ release_evt = QtGui.QKeyEvent(QtCore.QEvent.KeyRelease, key, modifier,
0, 0, 0)
self.send_event(press_evt)
self.send_event(release_evt)
@@ -1198,7 +1192,7 @@ class AbstractTab(QWidget):
def icon(self) -> None:
raise NotImplementedError
- def set_html(self, html: str, base_url: QUrl = QUrl()) -> None:
+ def set_html(self, html: str, base_url: QtCore.QUrl = QtCore.QUrl()) -> None:
raise NotImplementedError
def set_pinned(self, pinned: bool) -> None:
@@ -1213,7 +1207,7 @@ class AbstractTab(QWidget):
"""
raise NotImplementedError
- def grab_pixmap(self, rect: QRect = None) -> Optional[QPixmap]:
+ def grab_pixmap(self, rect: QtCore.QRect = None) -> Optional[QtGui.QPixmap]:
"""Grab a QPixmap of the displayed page.
Returns None if we got a null pixmap from Qt.
@@ -1233,7 +1227,7 @@ class AbstractTab(QWidget):
try:
qurl = self.url()
url = qurl.toDisplayString(
- QUrl.EncodeUnicode) # type: ignore[arg-type]
+ QtCore.QUrl.EncodeUnicode) # type: ignore[arg-type]
except (AttributeError, RuntimeError) as exc:
url = '<{}>'.format(exc.__class__.__name__)
else:
diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py
index 00d5e521f..af5cc2223 100644
--- a/qutebrowser/browser/commands.py
+++ b/qutebrowser/browser/commands.py
@@ -24,9 +24,6 @@ import shlex
import functools
from typing import cast, Callable, Dict, Union
-from PyQt5.QtWidgets import QApplication, QTabBar
-from PyQt5.QtCore import Qt, QUrl, QEvent, QUrlQuery
-
from qutebrowser.commands import userscripts, runners
from qutebrowser.api import cmdutils
from qutebrowser.config import config, configdata
@@ -39,6 +36,7 @@ from qutebrowser.utils.usertypes import KeyMode
from qutebrowser.misc import editor, guiprocess, objects
from qutebrowser.completion.models import urlmodel, miscmodels
from qutebrowser.mainwindow import mainwindow, windowundo
+from qutebrowser.qt import QtWidgets, QtCore
class CommandDispatcher:
@@ -197,16 +195,16 @@ class CommandDispatcher:
"""
cmdutils.check_exclusive((prev, next_, opposite), 'pno')
if prev:
- return QTabBar.SelectLeftTab
+ return QtWidgets.QTabBar.SelectLeftTab
elif next_:
- return QTabBar.SelectRightTab
+ return QtWidgets.QTabBar.SelectRightTab
elif opposite:
conf_selection = config.val.tabs.select_on_remove
- if conf_selection == QTabBar.SelectLeftTab:
- return QTabBar.SelectRightTab
- elif conf_selection == QTabBar.SelectRightTab:
- return QTabBar.SelectLeftTab
- elif conf_selection == QTabBar.SelectPreviousTab:
+ if conf_selection == QtWidgets.QTabBar.SelectLeftTab:
+ return QtWidgets.QTabBar.SelectRightTab
+ elif conf_selection == QtWidgets.QTabBar.SelectRightTab:
+ return QtWidgets.QTabBar.SelectLeftTab
+ elif conf_selection == QtWidgets.QTabBar.SelectPreviousTab:
raise cmdutils.CommandError(
"-o is not supported with 'tabs.select_on_remove' set to "
"'last-used'!")
@@ -366,7 +364,7 @@ class CommandDispatcher:
Return:
A list of URLs that can be opened.
"""
- if isinstance(url, QUrl):
+ if isinstance(url, QtCore.QUrl):
yield url
return
@@ -604,7 +602,7 @@ class CommandDispatcher:
widget = self._current_widget()
url = self._current_url()
- handlers: Dict[str, Callable[..., QUrl]] = {
+ handlers: Dict[str, Callable[..., QtCore.QUrl]] = {
'prev': functools.partial(navigate.prevnext, prev=True),
'next': functools.partial(navigate.prevnext, prev=False),
'up': navigate.path_up,
@@ -671,12 +669,12 @@ class CommandDispatcher:
assert what in ['url', 'pretty-url'], what
if what == 'pretty-url':
- flags = QUrl.RemovePassword | QUrl.DecodeReserved
+ flags = QtCore.QUrl.RemovePassword | QtCore.QUrl.DecodeReserved
else:
- flags = QUrl.RemovePassword | QUrl.FullyEncoded
+ flags = QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded
- url = QUrl(self._current_url())
- url_query = QUrlQuery()
+ url = QtCore.QUrl(self._current_url())
+ url_query = QtCore.QUrlQuery()
url_query_str = url.query()
if '&' not in url_query_str and ';' in url_query_str:
url_query.setQueryDelimiters('=', ';')
@@ -908,7 +906,7 @@ class CommandDispatcher:
idx = int(index_parts[1])
elif len(index_parts) == 1:
idx = int(index_parts[0])
- active_win = QApplication.activeWindow()
+ active_win = QtWidgets.QApplication.activeWindow()
if active_win is None:
# Not sure how you enter a command without an active window...
raise cmdutils.CommandError(
@@ -1099,7 +1097,7 @@ class CommandDispatcher:
if output:
tb = objreg.get('tabbed-browser', scope='window',
window='last-focused')
- tb.load_url(QUrl(f'qute://process/{proc.pid}'), newtab=True)
+ tb.load_url(QtCore.QUrl(f'qute://process/{proc.pid}'), newtab=True)
if userscript:
def _selection_callback(s):
@@ -1163,7 +1161,7 @@ class CommandDispatcher:
except qtutils.QtValueError:
pass
else:
- env['QUTE_URL'] = url.toString(QUrl.FullyEncoded)
+ env['QUTE_URL'] = url.toString(QtCore.QUrl.FullyEncoded)
try:
runner = userscripts.run_async(
@@ -1294,8 +1292,8 @@ class CommandDispatcher:
current page's url.
"""
if url is None:
- url = self._current_url().toString(QUrl.RemovePassword |
- QUrl.FullyEncoded)
+ url = self._current_url().toString(QtCore.QUrl.RemovePassword |
+ QtCore.QUrl.FullyEncoded)
try:
objreg.get('bookmark-manager').delete(url)
except KeyError:
@@ -1312,7 +1310,7 @@ class CommandDispatcher:
window: Open in a new window.
jump: Jump to the "bookmarks" header.
"""
- url = QUrl('qute://bookmarks/')
+ url = QtCore.QUrl('qute://bookmarks/')
if jump:
url.setFragment('bookmarks')
self._open(url, tab, bg, window)
@@ -1341,7 +1339,7 @@ class CommandDispatcher:
if mhtml_:
raise cmdutils.CommandError("Can only download the current "
"page as mhtml.")
- url = QUrl.fromUserInput(url)
+ url = QtCore.QUrl.fromUserInput(url)
urlutils.raise_cmdexc_if_invalid(url)
download_manager.get(url, target=target)
elif mhtml_:
@@ -1406,7 +1404,7 @@ class CommandDispatcher:
bg: Open in a background tab.
window: Open in a new window.
"""
- url = QUrl('qute://history/')
+ url = QtCore.QUrl('qute://history/')
self._open(url, tab, bg, window)
@cmdutils.register(instance='command-dispatcher', name='help',
@@ -1442,7 +1440,7 @@ class CommandDispatcher:
path = 'settings.html#{}'.format(topic)
else:
raise cmdutils.CommandError("Invalid help topic {}!".format(topic))
- url = QUrl('qute://help/{}'.format(path))
+ url = QtCore.QUrl('qute://help/{}'.format(path))
self._open(url, tab, bg, window)
@cmdutils.register(instance='command-dispatcher', scope='window')
@@ -1465,7 +1463,7 @@ class CommandDispatcher:
if level.upper() not in log.LOG_LEVELS:
raise cmdutils.CommandError("Invalid log level {}!".format(level))
- query = QUrlQuery()
+ query = QtCore.QUrlQuery()
query.addQueryItem('level', level)
if plain:
query.addQueryItem('plain', cast(str, None))
@@ -1477,7 +1475,7 @@ class CommandDispatcher:
raise cmdutils.CommandError(e)
query.addQueryItem('logfilter', logfilter)
- url = QUrl('qute://log')
+ url = QtCore.QUrl('qute://log')
url.setQuery(query)
self._open(url, tab, bg, window)
@@ -1730,7 +1728,7 @@ class CommandDispatcher:
raise cmdutils.CommandError(str(e))
elif url:
try:
- js_code = urlutils.parse_javascript_url(QUrl(js_code))
+ js_code = urlutils.parse_javascript_url(QtCore.QUrl(js_code))
except urlutils.Error as e:
raise cmdutils.CommandError(str(e))
@@ -1758,15 +1756,15 @@ class CommandDispatcher:
raise cmdutils.CommandError(str(e))
for keyinfo in sequence:
- press_event = keyinfo.to_event(QEvent.KeyPress)
- release_event = keyinfo.to_event(QEvent.KeyRelease)
+ press_event = keyinfo.to_event(QtCore.QEvent.KeyPress)
+ release_event = keyinfo.to_event(QtCore.QEvent.KeyRelease)
if global_:
- window = QApplication.focusWindow()
+ window = QtWidgets.QApplication.focusWindow()
if window is None:
raise cmdutils.CommandError("No focused window!")
- QApplication.postEvent(window, press_event)
- QApplication.postEvent(window, release_event)
+ QtWidgets.QApplication.postEvent(window, press_event)
+ QtWidgets.QApplication.postEvent(window, release_event)
else:
tab = self._current_widget()
tab.send_event(press_event)
@@ -1866,9 +1864,9 @@ class CommandDispatcher:
if not window.isFullScreen():
window.state_before_fullscreen = window.windowState()
if enter:
- window.setWindowState(window.windowState() | Qt.WindowFullScreen)
+ window.setWindowState(window.windowState() | QtCore.Qt.WindowFullScreen)
else:
- window.setWindowState(window.windowState() ^ Qt.WindowFullScreen)
+ window.setWindowState(window.windowState() ^ QtCore.Qt.WindowFullScreen)
log.misc.debug('state before fullscreen: {}'.format(
- debug.qflags_key(Qt, window.state_before_fullscreen)))
+ debug.qflags_key(QtCore.Qt, window.state_before_fullscreen)))
diff --git a/qutebrowser/browser/downloads.py b/qutebrowser/browser/downloads.py
index 32bfd2693..b4dd859d8 100644
--- a/qutebrowser/browser/downloads.py
+++ b/qutebrowser/browser/downloads.py
@@ -30,22 +30,19 @@ import tempfile
import enum
from typing import Any, Dict, IO, List, MutableSequence, Optional, Union
-from PyQt5.QtCore import (pyqtSlot, pyqtSignal, Qt, QObject, QModelIndex,
- QTimer, QAbstractListModel, QUrl)
-
from qutebrowser.browser import pdfjs
from qutebrowser.api import cmdutils
from qutebrowser.config import config
from qutebrowser.utils import (usertypes, standarddir, utils, message, log,
qtutils, objreg)
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
class ModelRole(enum.IntEnum):
"""Custom download model roles."""
- item = Qt.UserRole
+ item = QtCore.Qt.UserRole
# Remember the last used directory
@@ -78,7 +75,7 @@ def init():
config.instance.changed.connect(_clear_last_used)
-@pyqtSlot()
+@QtCore.pyqtSlot()
def shutdown():
temp_download_manager.cleanup()
@@ -188,7 +185,7 @@ def get_filename_question(*, suggested_filename, url, parent=None):
q.title = "Save file to:"
q.text = "Please enter a location for <b>{}</b>".format(
html.escape(url.toDisplayString()))
- q.url = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ q.url = url.toString(QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded)
q.mode = usertypes.PromptMode.download
q.completed.connect(q.deleteLater)
q.default = _path_suggestion(suggested_filename)
@@ -329,7 +326,7 @@ class PDFJSDownloadTarget(_DownloadTarget):
return 'temporary PDF.js file'
-class DownloadItemStats(QObject):
+class DownloadItemStats(QtCore.QObject):
"""Statistics (bytes done, total bytes, time, etc.) about a download.
@@ -398,7 +395,7 @@ class DownloadItemStats(QObject):
else:
return remaining_bytes / avg
- @pyqtSlot('qint64', 'qint64')
+ @QtCore.pyqtSlot('qint64', 'qint64')
def on_download_progress(self, bytes_done, bytes_total):
"""Update local variables when the download progress changed.
@@ -412,7 +409,7 @@ class DownloadItemStats(QObject):
self.total = bytes_total
-class AbstractDownloadItem(QObject):
+class AbstractDownloadItem(QtCore.QObject):
"""Shared QtNetwork/QtWebEngine part of a download item.
@@ -441,12 +438,12 @@ class AbstractDownloadItem(QObject):
arg 2: The original download URL.
"""
- data_changed = pyqtSignal()
- finished = pyqtSignal()
- error = pyqtSignal(str)
- cancelled = pyqtSignal()
- remove_requested = pyqtSignal()
- pdfjs_requested = pyqtSignal(str, QUrl)
+ data_changed = QtCore.pyqtSignal()
+ finished = QtCore.pyqtSignal()
+ error = QtCore.pyqtSignal(str)
+ cancelled = QtCore.pyqtSignal()
+ remove_requested = QtCore.pyqtSignal()
+ pdfjs_requested = QtCore.pyqtSignal(str, QtCore.QUrl)
def __init__(self, manager, parent=None):
super().__init__(parent)
@@ -565,7 +562,7 @@ class AbstractDownloadItem(QObject):
"""Actual cancel implementation."""
raise NotImplementedError
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def cancel(self, *, remove_data=True):
"""Cancel the download.
@@ -581,7 +578,7 @@ class AbstractDownloadItem(QObject):
self.finished.emit()
self.data_changed.emit()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def remove(self):
"""Remove the download from the model."""
self.remove_requested.emit()
@@ -597,12 +594,12 @@ class AbstractDownloadItem(QObject):
except OSError:
log.downloads.exception("Failed to remove partial file")
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def retry(self):
"""Retry a failed download."""
raise NotImplementedError
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def try_retry(self):
"""Try to retry a download and show an error if it's unsupported."""
try:
@@ -610,11 +607,11 @@ class AbstractDownloadItem(QObject):
except UnsupportedOperationError as e:
message.error(str(e))
- def url(self) -> QUrl:
+ def url(self) -> QtCore.QUrl:
"""Get the download's URL (i.e. where the file is downloaded from)."""
raise NotImplementedError
- def origin(self) -> QUrl:
+ def origin(self) -> QtCore.QUrl:
"""Get the download's origin URL (i.e. the page starting the download)."""
raise NotImplementedError
@@ -625,7 +622,7 @@ class AbstractDownloadItem(QObject):
"""
raise NotImplementedError
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def open_file(self, cmdline=None, open_dir=False):
"""Open the downloaded file.
@@ -647,7 +644,7 @@ class AbstractDownloadItem(QObject):
# is important on systems where process creation takes long, as
# otherwise the prompt might hang around and cause bugs
# (see issue #2296)
- QTimer.singleShot(0, lambda: utils.open_file(filename, cmdline))
+ QtCore.QTimer.singleShot(0, lambda: utils.open_file(filename, cmdline))
def _ensure_can_set_filename(self, filename):
"""Make sure we can still set a filename."""
@@ -884,7 +881,7 @@ class AbstractDownloadItem(QObject):
raise ValueError("Unsupported download target: {}".format(target))
-class AbstractDownloadManager(QObject):
+class AbstractDownloadManager(QtCore.QObject):
"""Backend-independent download manager code.
@@ -901,11 +898,11 @@ class AbstractDownloadManager(QObject):
The argument is the index of the changed download
"""
- begin_remove_row = pyqtSignal(int)
- end_remove_row = pyqtSignal()
- begin_insert_row = pyqtSignal(int)
- end_insert_row = pyqtSignal()
- data_changed = pyqtSignal(int)
+ begin_remove_row = QtCore.pyqtSignal(int)
+ end_remove_row = QtCore.pyqtSignal()
+ begin_insert_row = QtCore.pyqtSignal(int)
+ end_insert_row = QtCore.pyqtSignal()
+ data_changed = QtCore.pyqtSignal(int)
def __init__(self, parent=None):
super().__init__(parent)
@@ -917,7 +914,7 @@ class AbstractDownloadManager(QObject):
def __repr__(self):
return utils.get_repr(self, downloads=len(self.downloads))
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _update_gui(self):
"""Periodical GUI update of all items."""
assert self.downloads
@@ -925,8 +922,8 @@ class AbstractDownloadManager(QObject):
dl.stats.update_speed()
self.data_changed.emit(-1)
- @pyqtSlot(str, QUrl)
- def _on_pdfjs_requested(self, filename: str, original_url: QUrl) -> None:
+ @QtCore.pyqtSlot(str, QtCore.QUrl)
+ def _on_pdfjs_requested(self, filename: str, original_url: QtCore.QUrl) -> None:
"""Open PDF.js when a download requests it."""
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window='last-focused')
@@ -942,7 +939,7 @@ class AbstractDownloadManager(QObject):
delay = config.val.downloads.remove_finished
if delay > -1:
download.finished.connect(
- lambda: QTimer.singleShot(delay, download.remove))
+ lambda: QtCore.QTimer.singleShot(delay, download.remove))
elif auto_remove:
download.finished.connect(download.remove)
@@ -961,7 +958,7 @@ class AbstractDownloadManager(QObject):
if not self._update_timer.isActive():
self._update_timer.start()
- @pyqtSlot(AbstractDownloadItem)
+ @QtCore.pyqtSlot(AbstractDownloadItem)
def _on_data_changed(self, download):
"""Emit data_changed signal when download data changed."""
try:
@@ -971,12 +968,12 @@ class AbstractDownloadManager(QObject):
return
self.data_changed.emit(idx)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _on_error(self, msg):
"""Display error message on download errors."""
message.error("Download error: {}".format(msg))
- @pyqtSlot(AbstractDownloadItem)
+ @QtCore.pyqtSlot(AbstractDownloadItem)
def _remove_item(self, download):
"""Remove a given download."""
if sip.isdeleted(self):
@@ -1009,7 +1006,7 @@ class AbstractDownloadManager(QObject):
download.cancelled.connect(question.abort)
download.error.connect(question.abort)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def shutdown(self):
"""Cancel all downloads when shutting down."""
for download in self.downloads:
@@ -1017,7 +1014,7 @@ class AbstractDownloadManager(QObject):
download.cancel(remove_data=False)
-class DownloadModel(QAbstractListModel):
+class DownloadModel(QtCore.QAbstractListModel):
"""A list model showing downloads."""
@@ -1066,25 +1063,25 @@ class DownloadModel(QAbstractListModel):
log.downloads.debug("_on_begin_insert_row with idx {}, "
"webengine {}".format(idx, webengine))
if idx == -1:
- self.beginInsertRows(QModelIndex(), 0, -1)
+ self.beginInsertRows(QtCore.QModelIndex(), 0, -1)
return
assert idx >= 0, idx
if webengine:
idx += len(self._qtnetwork_manager.downloads)
- self.beginInsertRows(QModelIndex(), idx, idx)
+ self.beginInsertRows(QtCore.QModelIndex(), idx, idx)
def _on_begin_remove_row(self, idx, webengine=False):
log.downloads.debug("_on_begin_remove_row with idx {}, "
"webengine {}".format(idx, webengine))
if idx == -1:
- self.beginRemoveRows(QModelIndex(), 0, -1)
+ self.beginRemoveRows(QtCore.QModelIndex(), 0, -1)
return
assert idx >= 0, idx
if webengine:
idx += len(self._qtnetwork_manager.downloads)
- self.beginRemoveRows(QModelIndex(), idx, idx)
+ self.beginRemoveRows(QtCore.QModelIndex(), idx, idx)
def _on_data_changed(self, idx, *, webengine):
"""Called when a downloader's data changed.
@@ -1266,10 +1263,10 @@ class DownloadModel(QAbstractListModel):
idx = self.index(self.rowCount() - 1)
return idx
- def headerData(self, section, orientation, role=Qt.DisplayRole):
+ def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
"""Simple constant header."""
- if (section == 0 and orientation == Qt.Horizontal and
- role == Qt.DisplayRole):
+ if (section == 0 and orientation == QtCore.Qt.Horizontal and
+ role == QtCore.Qt.DisplayRole):
return "Downloads"
else:
return ""
@@ -1283,15 +1280,15 @@ class DownloadModel(QAbstractListModel):
return None
item = self[index.row()]
- if role == Qt.DisplayRole:
+ if role == QtCore.Qt.DisplayRole:
data: Any = str(item)
- elif role == Qt.ForegroundRole:
+ elif role == QtCore.Qt.ForegroundRole:
data = item.get_status_color('fg')
- elif role == Qt.BackgroundRole:
+ elif role == QtCore.Qt.BackgroundRole:
data = item.get_status_color('bg')
elif role == ModelRole.item:
data = item
- elif role == Qt.ToolTipRole:
+ elif role == QtCore.Qt.ToolTipRole:
if item.error_msg is None:
data = None
else:
@@ -1306,10 +1303,10 @@ class DownloadModel(QAbstractListModel):
The default would be Qt.ItemIsEnabled | Qt.ItemIsSelectable.
"""
if not index.isValid():
- return Qt.ItemFlags()
- return Qt.ItemIsEnabled | Qt.ItemNeverHasChildren
+ return QtCore.Qt.ItemFlags()
+ return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemNeverHasChildren
- def rowCount(self, parent=QModelIndex()):
+ def rowCount(self, parent=QtCore.QModelIndex()):
"""Get count of active downloads."""
if parent.isValid():
# We don't have children
diff --git a/qutebrowser/browser/downloadview.py b/qutebrowser/browser/downloadview.py
index 69c58741a..5edead500 100644
--- a/qutebrowser/browser/downloadview.py
+++ b/qutebrowser/browser/downloadview.py
@@ -22,12 +22,10 @@
import functools
from typing import Callable, MutableSequence, Tuple, Union
-from PyQt5.QtCore import pyqtSlot, QSize, Qt
-from PyQt5.QtWidgets import QListView, QSizePolicy, QMenu, QStyleFactory
-
from qutebrowser.browser import downloads
from qutebrowser.config import stylesheet
from qutebrowser.utils import qtutils, utils
+from qutebrowser.qt import QtWidgets, QtCore
_ActionListType = MutableSequence[
@@ -38,7 +36,7 @@ _ActionListType = MutableSequence[
]
-class DownloadView(QListView):
+class DownloadView(QtWidgets.QListView):
"""QListView which shows currently running downloads as a bar.
@@ -60,13 +58,13 @@ class DownloadView(QListView):
def __init__(self, model, parent=None):
super().__init__(parent)
if not utils.is_mac:
- self.setStyle(QStyleFactory.create('Fusion'))
+ self.setStyle(QtWidgets.QStyleFactory.create('Fusion'))
stylesheet.set_register(self)
- self.setResizeMode(QListView.Adjust)
- self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
- self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
- self.setFocusPolicy(Qt.NoFocus)
- self.setFlow(QListView.LeftToRight)
+ self.setResizeMode(QtWidgets.QListView.Adjust)
+ self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
+ self.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
+ self.setFocusPolicy(QtCore.Qt.NoFocus)
+ self.setFlow(QtWidgets.QListView.LeftToRight)
self.setSpacing(1)
self._menu = None
model.rowsInserted.connect(self._update_geometry)
@@ -74,7 +72,7 @@ class DownloadView(QListView):
model.dataChanged.connect(self._update_geometry)
self.setModel(model)
self.setWrapping(True)
- self.setContextMenuPolicy(Qt.CustomContextMenu)
+ self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.show_context_menu)
self.clicked.connect(self.on_clicked)
@@ -86,7 +84,7 @@ class DownloadView(QListView):
count = model.rowCount()
return utils.get_repr(self, count=count)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _update_geometry(self):
"""Wrapper to call updateGeometry.
@@ -95,7 +93,7 @@ class DownloadView(QListView):
"""
self.updateGeometry()
- @pyqtSlot(bool)
+ @QtCore.pyqtSlot(bool)
def on_fullscreen_requested(self, on):
"""Hide/show the downloadview when entering/leaving fullscreen."""
if on:
@@ -103,7 +101,7 @@ class DownloadView(QListView):
else:
self.show()
- @pyqtSlot('QModelIndex')
+ @QtCore.pyqtSlot('QModelIndex')
def on_clicked(self, index):
"""Handle clicking of an item.
@@ -149,7 +147,7 @@ class DownloadView(QListView):
actions.append(("Remove all finished", model.download_clear))
return actions
- @pyqtSlot('QPoint')
+ @QtCore.pyqtSlot('QPoint')
def show_context_menu(self, point):
"""Show the context menu."""
index = self.indexAt(point)
@@ -157,7 +155,7 @@ class DownloadView(QListView):
item = self.model().data(index, downloads.ModelRole.item)
else:
item = None
- self._menu = QMenu(self)
+ self._menu = QtWidgets.QMenu(self)
actions = self._get_menu_actions(item)
for (name, handler) in actions:
if name is None and handler is None:
@@ -182,8 +180,8 @@ class DownloadView(QListView):
margins = self.contentsMargins()
height = (bottom + margins.top() + margins.bottom() +
2 * self.spacing())
- size = QSize(0, height)
+ size = QtCore.QSize(0, height)
else:
- size = QSize(0, 0)
+ size = QtCore.QSize(0, 0)
qtutils.ensure_valid(size)
return size
diff --git a/qutebrowser/browser/eventfilter.py b/qutebrowser/browser/eventfilter.py
index 0b5fab096..0af93482a 100644
--- a/qutebrowser/browser/eventfilter.py
+++ b/qutebrowser/browser/eventfilter.py
@@ -19,15 +19,14 @@
"""Event handling for a browser tab."""
-from PyQt5.QtCore import QObject, QEvent, Qt, QTimer
-
from qutebrowser.config import config
from qutebrowser.utils import message, log, usertypes, qtutils
from qutebrowser.misc import objects
from qutebrowser.keyinput import modeman
+from qutebrowser.qt import QtCore
-class ChildEventFilter(QObject):
+class ChildEventFilter(QtCore.QObject):
"""An event filter re-adding TabEventFilter on ChildEvent.
@@ -48,7 +47,7 @@ class ChildEventFilter(QObject):
def eventFilter(self, obj, event):
"""Act on ChildAdded events."""
- if event.type() == QEvent.ChildAdded:
+ if event.type() == QtCore.QEvent.ChildAdded:
child = event.child()
log.misc.debug("{} got new child {}, installing filter"
.format(obj, child))
@@ -58,14 +57,14 @@ class ChildEventFilter(QObject):
assert obj is self._widget
child.installEventFilter(self._filter)
- elif event.type() == QEvent.ChildRemoved:
+ elif event.type() == QtCore.QEvent.ChildRemoved:
child = event.child()
log.misc.debug("{}: removed child {}".format(obj, child))
return False
-class TabEventFilter(QObject):
+class TabEventFilter(QtCore.QObject):
"""Handle mouse/keyboard events on a tab.
@@ -81,10 +80,10 @@ class TabEventFilter(QObject):
super().__init__(parent)
self._tab = tab
self._handlers = {
- QEvent.MouseButtonPress: self._handle_mouse_press,
- QEvent.MouseButtonRelease: self._handle_mouse_release,
- QEvent.Wheel: self._handle_wheel,
- QEvent.KeyRelease: self._handle_key_release,
+ QtCore.QEvent.MouseButtonPress: self._handle_mouse_press,
+ QtCore.QEvent.MouseButtonRelease: self._handle_mouse_release,
+ QtCore.QEvent.Wheel: self._handle_wheel,
+ QtCore.QEvent.KeyRelease: self._handle_key_release,
}
self._ignore_wheel_event = False
self._check_insertmode_on_release = False
@@ -99,9 +98,9 @@ class TabEventFilter(QObject):
True if the event should be filtered, False otherwise.
"""
is_rocker_gesture = (config.val.input.mouse.rocker_gestures and
- e.buttons() == Qt.LeftButton | Qt.RightButton)
+ e.buttons() == QtCore.Qt.LeftButton | QtCore.Qt.RightButton)
- if e.button() in [Qt.XButton1, Qt.XButton2] or is_rocker_gesture:
+ if e.button() in [QtCore.Qt.XButton1, QtCore.Qt.XButton2] or is_rocker_gesture:
self._mousepress_backforward(e)
return True
@@ -112,7 +111,7 @@ class TabEventFilter(QObject):
log.mouse.warning("Ignoring invalid click at {}".format(pos))
return False
- if e.button() != Qt.NoButton:
+ if e.button() != QtCore.Qt.NoButton:
self._tab.elements.find_at_pos(pos, self._mousepress_insertmode_cb)
return False
@@ -128,7 +127,7 @@ class TabEventFilter(QObject):
"""
# We want to make sure we check the focus element after the WebView is
# updated completely.
- QTimer.singleShot(0, self._mouserelease_insertmode)
+ QtCore.QTimer.singleShot(0, self._mouserelease_insertmode)
return False
def _handle_wheel(self, e):
@@ -150,7 +149,7 @@ class TabEventFilter(QObject):
if mode == usertypes.KeyMode.hint:
return True
- elif e.modifiers() & Qt.ControlModifier:
+ elif e.modifiers() & QtCore.Qt.ControlModifier:
if mode == usertypes.KeyMode.passthrough:
return False
@@ -240,17 +239,17 @@ class TabEventFilter(QObject):
True if the event should be filtered, False otherwise.
"""
if (not config.val.input.mouse.back_forward_buttons and
- e.button() in [Qt.XButton1, Qt.XButton2]):
+ e.button() in [QtCore.Qt.XButton1, QtCore.Qt.XButton2]):
# Back and forward on mice are disabled
return
- if e.button() in [Qt.XButton1, Qt.LeftButton]:
+ if e.button() in [QtCore.Qt.XButton1, QtCore.Qt.LeftButton]:
# Back button on mice which have it, or rocker gesture
if self._tab.history.can_go_back():
self._tab.history.back()
else:
message.error("At beginning of history.")
- elif e.button() in [Qt.XButton2, Qt.RightButton]:
+ elif e.button() in [QtCore.Qt.XButton2, QtCore.Qt.RightButton]:
# Forward button on mice which have it, or rocker gesture
if self._tab.history.can_go_forward():
self._tab.history.forward()
diff --git a/qutebrowser/browser/greasemonkey.py b/qutebrowser/browser/greasemonkey.py
index 5abb9a137..61594b329 100644
--- a/qutebrowser/browser/greasemonkey.py
+++ b/qutebrowser/browser/greasemonkey.py
@@ -29,13 +29,12 @@ import textwrap
import dataclasses
from typing import cast, List, Sequence
-from PyQt5.QtCore import pyqtSignal, QObject, QUrl
-
from qutebrowser.utils import (log, standarddir, jinja, objreg, utils,
javascript, urlmatch, version, usertypes, message)
from qutebrowser.api import cmdutils
from qutebrowser.browser import downloads
from qutebrowser.misc import objects
+from qutebrowser.qt import QtCore
gm_manager = cast('GreasemonkeyManager', None)
@@ -221,7 +220,7 @@ class MatchingScripts:
"""All userscripts registered to run on a particular url."""
- url: QUrl
+ url: QtCore.QUrl
start: List[GreasemonkeyScript] = dataclasses.field(default_factory=list)
end: List[GreasemonkeyScript] = dataclasses.field(default_factory=list)
idle: List[GreasemonkeyScript] = dataclasses.field(default_factory=list)
@@ -238,7 +237,7 @@ class GreasemonkeyMatcher:
def __init__(self, url):
self._url = url
- self._url_string = url.toString(QUrl.FullyEncoded)
+ self._url_string = url.toString(QtCore.QUrl.FullyEncoded)
self.is_greaseable = url.scheme() in self.GREASEABLE_SCHEMES
def _match_pattern(self, pattern):
@@ -263,7 +262,7 @@ class GreasemonkeyMatcher:
return (matching_includes or matching_match) and not matching_excludes
-class GreasemonkeyManager(QObject):
+class GreasemonkeyManager(QtCore.QObject):
"""Manager of userscripts and a Greasemonkey compatible environment.
@@ -273,7 +272,7 @@ class GreasemonkeyManager(QObject):
considered obsolete.
"""
- scripts_reloaded = pyqtSignal()
+ scripts_reloaded = QtCore.pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
@@ -412,7 +411,7 @@ class GreasemonkeyManager(QObject):
for url, target_path in required_dls:
target = downloads.FileDownloadTarget(target_path,
force_overwrite=True)
- download = download_manager.get(QUrl(url), target=target,
+ download = download_manager.get(QtCore.QUrl(url), target=target,
auto_remove=True)
download.requested_url = url
self._in_progress_dls.append(download)
diff --git a/qutebrowser/browser/hints.py b/qutebrowser/browser/hints.py
index 2e4e8e4b4..4e5157cf0 100644
--- a/qutebrowser/browser/hints.py
+++ b/qutebrowser/browser/hints.py
@@ -29,9 +29,7 @@ import dataclasses
from string import ascii_lowercase
from typing import (TYPE_CHECKING, Callable, Dict, Iterable, Iterator, List, Mapping,
MutableSequence, Optional, Sequence, Set)
-
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, Qt, QUrl
-from PyQt5.QtWidgets import QLabel
+from qutebrowser.qt import QtWidgets
from qutebrowser.config import config, configexc
from qutebrowser.keyinput import modeman, modeparsers, basekeyparser
@@ -39,6 +37,8 @@ from qutebrowser.browser import webelem, history
from qutebrowser.commands import runners
from qutebrowser.api import cmdutils
from qutebrowser.utils import usertypes, log, qtutils, message, objreg, utils
+from qutebrowser.qt import QtCore
+
if TYPE_CHECKING:
from qutebrowser.browser import browsertab
@@ -77,7 +77,7 @@ def on_mode_entered(mode: usertypes.KeyMode, win_id: int) -> None:
maybe=True)
-class HintLabel(QLabel):
+class HintLabel(QtWidgets.QLabel):
"""A label for a link.
@@ -92,12 +92,12 @@ class HintLabel(QLabel):
self._context = context
self.elem = elem
- self.setTextFormat(Qt.RichText)
+ self.setTextFormat(QtCore.Qt.RichText)
# Make sure we can style the background via a style sheet, and we don't
# get any extra text indent from Qt.
# The real stylesheet lives in mainwindow.py for performance reasons..
- self.setAttribute(Qt.WA_StyledBackground, True)
+ self.setAttribute(QtCore.Qt.WA_StyledBackground, True)
self.setIndent(0)
self._context.tab.contents_size_changed.connect(self._move_to_elem)
@@ -134,7 +134,7 @@ class HintLabel(QLabel):
self.setText(unmatched)
self.adjustSize()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _move_to_elem(self) -> None:
"""Reposition the label to its element."""
if not self.elem.has_frame():
@@ -189,7 +189,7 @@ class HintContext:
hint_mode: str
add_history: bool
first: bool
- baseurl: QUrl
+ baseurl: QtCore.QUrl
args: List[str]
group: str
@@ -247,14 +247,14 @@ class HintActions:
except webelem.Error as e:
raise HintingError(str(e))
- def yank(self, url: QUrl, context: HintContext) -> None:
+ def yank(self, url: QtCore.QUrl, context: HintContext) -> None:
"""Yank an element to the clipboard or primary selection."""
sel = (context.target == Target.yank_primary and
utils.supports_selection())
- flags = QUrl.FullyEncoded | QUrl.RemovePassword
+ flags = QtCore.QUrl.FullyEncoded | QtCore.QUrl.RemovePassword
if url.scheme() == 'mailto':
- flags |= QUrl.RemoveScheme
+ flags |= QtCore.QUrl.RemoveScheme
urlstr = url.toString(flags) # type: ignore[arg-type]
new_content = urlstr
@@ -274,16 +274,16 @@ class HintActions:
urlstr)
message.info(msg, replace='rapid-hints' if context.rapid else None)
- def run_cmd(self, url: QUrl, context: HintContext) -> None:
+ def run_cmd(self, url: QtCore.QUrl, context: HintContext) -> None:
"""Run the command based on a hint URL."""
- urlstr = url.toString(QUrl.FullyEncoded) # type: ignore[arg-type]
+ urlstr = url.toString(QtCore.QUrl.FullyEncoded) # type: ignore[arg-type]
args = context.get_args(urlstr)
commandrunner = runners.CommandRunner(self._win_id)
commandrunner.run_safely(' '.join(args))
- def preset_cmd_text(self, url: QUrl, context: HintContext) -> None:
+ def preset_cmd_text(self, url: QtCore.QUrl, context: HintContext) -> None:
"""Preset a commandline text based on a hint URL."""
- flags = QUrl.FullyEncoded
+ flags = QtCore.QUrl.FullyEncoded
urlstr = url.toDisplayString(flags) # type: ignore[arg-type]
args = context.get_args(urlstr)
text = ' '.join(args)
@@ -325,7 +325,7 @@ class HintActions:
cmd = context.args[0]
args = context.args[1:]
- flags = QUrl.FullyEncoded
+ flags = QtCore.QUrl.FullyEncoded
env = {
'QUTE_MODE': 'hints',
@@ -349,7 +349,7 @@ class HintActions:
_context: HintContext) -> None:
elem.delete()
- def spawn(self, url: QUrl, context: HintContext) -> None:
+ def spawn(self, url: QtCore.QUrl, context: HintContext) -> None:
"""Spawn a simple command from a hint.
Args:
@@ -357,7 +357,7 @@ class HintActions:
context: The HintContext to use.
"""
urlstr = url.toString(
- QUrl.FullyEncoded | QUrl.RemovePassword) # type: ignore[arg-type]
+ QtCore.QUrl.FullyEncoded | QtCore.QUrl.RemovePassword) # type: ignore[arg-type]
args = context.get_args(urlstr)
commandrunner = runners.CommandRunner(self._win_id)
commandrunner.run_safely('spawn ' + ' '.join(args))
@@ -367,7 +367,7 @@ _ElemsType = Sequence[webelem.AbstractWebElement]
_HintStringsType = MutableSequence[str]
-class HintManager(QObject):
+class HintManager(QtCore.QObject):
"""Manage drawing hints over links or other elements.
@@ -402,9 +402,9 @@ class HintManager(QObject):
Target.delete: "Delete an element",
}
- set_text = pyqtSignal(str)
+ set_text = QtCore.pyqtSignal(str)
- def __init__(self, win_id: int, parent: QObject = None) -> None:
+ def __init__(self, win_id: int, parent: QtCore.QObject = None) -> None:
"""Constructor."""
super().__init__(parent)
self._win_id = win_id
@@ -856,7 +856,7 @@ class HintManager(QObject):
# unpacking gets us the first (and only) key in the dict.
self._fire(*visible)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def handle_partial_key(self, keystr: str) -> None:
"""Handle a new partial keypress."""
if self._context is None:
@@ -1029,7 +1029,7 @@ class HintManager(QObject):
else:
self._fire(keystring)
- @pyqtSlot(usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode)
def on_mode_left(self, mode: usertypes.KeyMode) -> None:
"""Stop hinting when hinting mode was left."""
if mode != usertypes.KeyMode.hint or self._context is None:
diff --git a/qutebrowser/browser/history.py b/qutebrowser/browser/history.py
index d2046345f..ab39bed04 100644
--- a/qutebrowser/browser/history.py
+++ b/qutebrowser/browser/history.py
@@ -25,13 +25,11 @@ import contextlib
import pathlib
from typing import cast, Mapping, MutableSequence, Optional
-from PyQt5.QtCore import pyqtSlot, QUrl, QObject, pyqtSignal
-from PyQt5.QtWidgets import QProgressDialog, QApplication
-
from qutebrowser.config import config
from qutebrowser.api import cmdutils
from qutebrowser.utils import utils, log, usertypes, message, qtutils
from qutebrowser.misc import objects, sql
+from qutebrowser.qt import QtWidgets, QtCore
web_history = cast('WebHistory', None)
@@ -52,27 +50,27 @@ class HistoryProgress:
def start(self, text):
"""Start showing a progress dialog."""
- self._progress = QProgressDialog()
+ self._progress = QtWidgets.QProgressDialog()
self._progress.setMaximum(0) # unknown
self._progress.setMinimumDuration(0)
self._progress.setLabelText(text)
self._progress.setCancelButton(None)
self._progress.setAutoClose(False)
self._progress.show()
- QApplication.processEvents()
+ QtWidgets.QApplication.processEvents()
def set_maximum(self, maximum):
"""Set the progress maximum as soon as we know about it."""
assert self._progress is not None
self._progress.setMaximum(maximum)
- QApplication.processEvents()
+ QtWidgets.QApplication.processEvents()
def tick(self):
"""Increase the displayed progress value."""
self._value += 1
if self._progress is not None:
self._progress.setValue(self._value)
- QApplication.processEvents()
+ QtWidgets.QApplication.processEvents()
def finish(self):
"""Finish showing the progress dialog.
@@ -93,7 +91,7 @@ class CompletionMetaInfo(sql.SqlTable):
}
def __init__(self, database: sql.Database,
- parent: Optional[QObject] = None) -> None:
+ parent: Optional[QtCore.QObject] = None) -> None:
self._fields = ['key', 'value']
self._constraints = {'key': 'PRIMARY KEY'}
super().__init__(database, "CompletionMetaInfo", self._fields,
@@ -141,7 +139,7 @@ class CompletionHistory(sql.SqlTable):
"""History which only has the newest entry for each URL."""
def __init__(self, database: sql.Database,
- parent: Optional[QObject] = None) -> None:
+ parent: Optional[QtCore.QObject] = None) -> None:
super().__init__(database, "CompletionHistory", ['url', 'title', 'last_atime'],
constraints={'url': 'PRIMARY KEY',
'title': 'NOT NULL',
@@ -161,12 +159,12 @@ class WebHistory(sql.SqlTable):
"""
# All web history cleared
- history_cleared = pyqtSignal()
+ history_cleared = QtCore.pyqtSignal()
# one url cleared
- url_cleared = pyqtSignal(QUrl)
+ url_cleared = QtCore.pyqtSignal(QtCore.QUrl)
def __init__(self, database: sql.Database, progress: HistoryProgress,
- parent: Optional[QObject] = None) -> None:
+ parent: Optional[QtCore.QObject] = None) -> None:
super().__init__(database, "History", ['url', 'title', 'atime', 'redirect'],
constraints={'url': 'NOT NULL',
'title': 'NOT NULL',
@@ -300,14 +298,14 @@ class WebHistory(sql.SqlTable):
# Delete old entries
self.completion.delete_all()
- QApplication.processEvents()
+ QtWidgets.QApplication.processEvents()
# Select the latest entry for each url
q = self.database.query('SELECT url, title, max(atime) AS atime FROM History '
'WHERE NOT redirect '
'GROUP BY url ORDER BY atime asc')
result = q.run()
- QApplication.processEvents()
+ QtWidgets.QApplication.processEvents()
entries = list(result)
self._progress.set_maximum(len(entries))
@@ -315,7 +313,7 @@ class WebHistory(sql.SqlTable):
for entry in entries:
self._progress.tick()
- url = QUrl(entry.url)
+ url = QtCore.QUrl(entry.url)
if self._is_excluded_from_completion(url):
continue
data['url'].append(self._format_completion_url(url))
@@ -326,10 +324,10 @@ class WebHistory(sql.SqlTable):
# We might have caused fragmentation - let's clean up.
self.database.query('VACUUM').run()
- QApplication.processEvents()
+ QtWidgets.QApplication.processEvents()
self.completion.insert_batch(data, replace=True)
- QApplication.processEvents()
+ QtWidgets.QApplication.processEvents()
self._progress.finish()
self.metainfo['force_rebuild'] = False
@@ -373,7 +371,7 @@ class WebHistory(sql.SqlTable):
Args:
url: URL string to delete.
"""
- qurl = QUrl(url)
+ qurl = QtCore.QUrl(url)
qtutils.ensure_valid(qurl)
self.delete('url', self._format_url(qurl))
self.completion.delete('url', self._format_completion_url(qurl))
@@ -381,7 +379,7 @@ class WebHistory(sql.SqlTable):
self._last_url = None
self.url_cleared.emit(qurl)
- @pyqtSlot(QUrl, QUrl, str)
+ @QtCore.pyqtSlot(QtCore.QUrl, QtCore.QUrl, str)
def add_from_tab(self, url, requested_url, title):
"""Add a new history entry as slot, called from a BrowserTab."""
if self._is_excluded_entirely(url) or self._is_excluded_entirely(requested_url):
@@ -390,7 +388,7 @@ class WebHistory(sql.SqlTable):
# things set via setHtml
return
- no_formatting = QUrl.UrlFormattingOption(0)
+ no_formatting = QtCore.QUrl.UrlFormattingOption(0)
if (requested_url.isValid() and
not requested_url.matches(url, no_formatting)):
# If the url of the page is different than the url of the link
@@ -435,10 +433,10 @@ class WebHistory(sql.SqlTable):
}, replace=True)
def _format_url(self, url):
- return url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ return url.toString(QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded)
def _format_completion_url(self, url):
- return url.toString(QUrl.RemovePassword)
+ return url.toString(QtCore.QUrl.RemovePassword)
@cmdutils.register()
@@ -479,7 +477,7 @@ def debug_dump_history(dest):
raise cmdutils.CommandError(f'Could not write history: {e}')
-def init(db_path: pathlib.Path, parent: Optional[QObject] = None) -> None:
+def init(db_path: pathlib.Path, parent: Optional[QtCore.QObject] = None) -> None:
"""Initialize the web history.
Args:
diff --git a/qutebrowser/browser/inspector.py b/qutebrowser/browser/inspector.py
index 2b40e97e4..b2c6d91b1 100644
--- a/qutebrowser/browser/inspector.py
+++ b/qutebrowser/browser/inspector.py
@@ -24,15 +24,15 @@ import binascii
import enum
from typing import cast, Optional
-from PyQt5.QtWidgets import QWidget
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QEvent
-from PyQt5.QtGui import QCloseEvent
+from qutebrowser.qt import QtWidgets
+from qutebrowser.qt import QtGui
from qutebrowser.browser import eventfilter
from qutebrowser.config import configfiles
from qutebrowser.utils import log, usertypes
from qutebrowser.keyinput import modeman
from qutebrowser.misc import miscwidgets
+from qutebrowser.qt import QtCore
class Position(enum.Enum):
@@ -51,7 +51,7 @@ class Error(Exception):
"""Raised when the inspector could not be initialized."""
-class _EventFilter(QObject):
+class _EventFilter(QtCore.QObject):
"""Event filter to enter insert mode when inspector was clicked.
@@ -66,16 +66,16 @@ class _EventFilter(QObject):
the QWebInspector.
"""
- clicked = pyqtSignal()
+ clicked = QtCore.pyqtSignal()
- def eventFilter(self, _obj: QObject, event: QEvent) -> bool:
+ def eventFilter(self, _obj: QtCore.QObject, event: QtCore.QEvent) -> bool:
"""Translate mouse presses to a clicked signal."""
- if event.type() == QEvent.MouseButtonPress:
+ if event.type() == QtCore.QEvent.MouseButtonPress:
self.clicked.emit()
return False
-class AbstractWebInspector(QWidget):
+class AbstractWebInspector(QtWidgets.QWidget):
"""Base class for QtWebKit/QtWebEngine inspectors.
@@ -87,13 +87,13 @@ class AbstractWebInspector(QWidget):
recreate: Emitted when the inspector should be recreated.
"""
- recreate = pyqtSignal()
+ recreate = QtCore.pyqtSignal()
def __init__(self, splitter: 'miscwidgets.InspectorSplitter',
win_id: int,
- parent: QWidget = None) -> None:
+ parent: QtWidgets.QWidget = None) -> None:
super().__init__(parent)
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
self._layout = miscwidgets.WrapperLayout(self)
self._splitter = splitter
self._position: Optional[Position] = None
@@ -105,7 +105,7 @@ class AbstractWebInspector(QWidget):
eventfilter=self._event_filter,
parent=self)
- def _set_widget(self, widget: QWidget) -> None:
+ def _set_widget(self, widget: QtWidgets.QWidget) -> None:
self._widget = widget
self._widget.setWindowTitle("Web Inspector")
self._widget.installEventFilter(self._child_event_filter)
@@ -130,7 +130,7 @@ class AbstractWebInspector(QWidget):
"""
return False
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_clicked(self) -> None:
"""Enter insert mode if a docked inspector was clicked."""
if self._position != Position.window:
@@ -192,17 +192,17 @@ class AbstractWebInspector(QWidget):
if not ok:
log.init.warning("Error while loading geometry.")
- def closeEvent(self, _e: QCloseEvent) -> None:
+ def closeEvent(self, _e: QtGui.QCloseEvent) -> None:
"""Save the geometry when closed."""
data = self._widget.saveGeometry().data()
geom = base64.b64encode(data).decode('ASCII')
configfiles.state['inspector']['window'] = geom
- def inspect(self, page: QWidget) -> None:
+ def inspect(self, page: QtWidgets.QWidget) -> None:
"""Inspect the given QWeb(Engine)Page."""
raise NotImplementedError
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def shutdown(self) -> None:
"""Clean up the inspector."""
self.close()
diff --git a/qutebrowser/browser/navigate.py b/qutebrowser/browser/navigate.py
index 6217c8d00..efc36899d 100644
--- a/qutebrowser/browser/navigate.py
+++ b/qutebrowser/browser/navigate.py
@@ -23,7 +23,7 @@ import re
import posixpath
from typing import Optional, Set
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.browser import webelem
from qutebrowser.config import config
@@ -42,24 +42,24 @@ class Error(Exception):
# of information. (host and path use FullyDecoded by default)
_URL_SEGMENTS = [
('host',
- lambda url: url.host(QUrl.FullyEncoded),
- lambda url, host: url.setHost(host, QUrl.StrictMode)),
+ lambda url: url.host(QtCore.QUrl.FullyEncoded),
+ lambda url, host: url.setHost(host, QtCore.QUrl.StrictMode)),
('port',
lambda url: str(url.port()) if url.port() > 0 else '',
lambda url, x: url.setPort(int(x))),
('path',
- lambda url: url.path(QUrl.FullyEncoded),
- lambda url, path: url.setPath(path, QUrl.StrictMode)),
+ lambda url: url.path(QtCore.QUrl.FullyEncoded),
+ lambda url, path: url.setPath(path, QtCore.QUrl.StrictMode)),
('query',
- lambda url: url.query(QUrl.FullyEncoded),
- lambda url, query: url.setQuery(query, QUrl.StrictMode)),
+ lambda url: url.query(QtCore.QUrl.FullyEncoded),
+ lambda url, query: url.setQuery(query, QtCore.QUrl.StrictMode)),
('anchor',
- lambda url: url.fragment(QUrl.FullyEncoded),
- lambda url, fragment: url.setFragment(fragment, QUrl.StrictMode)),
+ lambda url: url.fragment(QtCore.QUrl.FullyEncoded),
+ lambda url, fragment: url.setFragment(fragment, QtCore.QUrl.StrictMode)),
]
@@ -102,7 +102,7 @@ def incdec(url, count, inc_or_dec):
segments = {'path', 'query'}
# Make a copy of the QUrl so we don't modify the original
- url = QUrl(url)
+ url = QtCore.QUrl(url)
# We're searching the last number so we walk the url segments backwards
for segment, getter, setter in reversed(_URL_SEGMENTS):
if segment not in segments:
@@ -130,14 +130,14 @@ def path_up(url, count):
count: The number of levels to go up in the url.
"""
urlutils.ensure_valid(url)
- url = url.adjusted(QUrl.RemoveFragment | QUrl.RemoveQuery)
- path = url.path(QUrl.FullyEncoded)
+ url = url.adjusted(QtCore.QUrl.RemoveFragment | QtCore.QUrl.RemoveQuery)
+ path = url.path(QtCore.QUrl.FullyEncoded)
if not path or path == '/':
raise Error("Can't go up!")
for _i in range(0, min(count, path.count('/'))):
path = posixpath.join(path, posixpath.pardir)
path = posixpath.normpath(path)
- url.setPath(path, QUrl.StrictMode)
+ url.setPath(path, QtCore.QUrl.StrictMode)
return url
@@ -146,7 +146,7 @@ def strip(url, count):
if count != 1:
raise Error("Count is not supported when stripping URL components")
urlutils.ensure_valid(url)
- return url.adjusted(QUrl.RemoveFragment | QUrl.RemoveQuery)
+ return url.adjusted(QtCore.QUrl.RemoveFragment | QtCore.QUrl.RemoveQuery)
def _find_prevnext(prev, elems):
diff --git a/qutebrowser/browser/network/pac.py b/qutebrowser/browser/network/pac.py
index 3a544c78f..c21e4f982 100644
--- a/qutebrowser/browser/network/pac.py
+++ b/qutebrowser/browser/network/pac.py
@@ -23,13 +23,8 @@ import sys
import functools
from typing import Optional
-from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot, QUrl
-from PyQt5.QtNetwork import (QNetworkProxy, QNetworkRequest, QHostInfo,
- QNetworkReply, QNetworkAccessManager,
- QHostAddress)
-from PyQt5.QtQml import QJSEngine, QJSValue
-
from qutebrowser.utils import log, utils, qtutils, resources
+from qutebrowser.qt import QtQml, QtNetwork, QtCore
class ParseProxyError(Exception):
@@ -66,12 +61,12 @@ def _js_slot(*args):
return self._error_con.callAsConstructor([e])
# pylint: enable=protected-access
- deco = pyqtSlot(*args, result=QJSValue)
+ deco = QtCore.pyqtSlot(*args, result=QtQml.QJSValue)
return deco(new_method)
return _decorator
-class _PACContext(QObject):
+class _PACContext(QtCore.QObject):
"""Implementation of PAC API functions that require native calls.
@@ -108,11 +103,11 @@ class _PACContext(QObject):
Args:
host: hostname to resolve.
"""
- ips = QHostInfo.fromName(host)
- if ips.error() != QHostInfo.NoError or not ips.addresses():
+ ips = QtNetwork.QHostInfo.fromName(host)
+ if ips.error() != QtNetwork.QHostInfo.NoError or not ips.addresses():
err_f = "Failed to resolve host during PAC evaluation: {}"
log.network.info(err_f.format(host))
- return QJSValue(QJSValue.NullValue)
+ return QtQml.QJSValue(QtQml.QJSValue.NullValue)
else:
return ips.addresses()[0].toString()
@@ -123,7 +118,7 @@ class _PACContext(QObject):
Return the server IP address of the current machine, as a string in
the dot-separated integer format.
"""
- return QHostAddress(QHostAddress.LocalHost).toString()
+ return QtNetwork.QHostAddress(QtNetwork.QHostAddress.LocalHost).toString()
class PACResolver:
@@ -150,17 +145,17 @@ class PACResolver:
if len(config) != 1:
raise ParseProxyError("Invalid number of parameters for " +
"DIRECT")
- return QNetworkProxy(QNetworkProxy.NoProxy)
+ return QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.NoProxy)
elif config[0] == "PROXY":
if len(config) != 2:
raise ParseProxyError("Invalid number of parameters for PROXY")
host, port = PACResolver._parse_proxy_host(config[1])
- return QNetworkProxy(QNetworkProxy.HttpProxy, host, port)
+ return QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.HttpProxy, host, port)
elif config[0] in ["SOCKS", "SOCKS5"]:
if len(config) != 2:
raise ParseProxyError("Invalid number of parameters for SOCKS")
host, port = PACResolver._parse_proxy_host(config[1])
- return QNetworkProxy(QNetworkProxy.Socks5Proxy, host, port)
+ return QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.Socks5Proxy, host, port)
else:
err = "Unknown proxy type: {}"
raise ParseProxyError(err.format(config[0]))
@@ -182,9 +177,9 @@ class PACResolver:
Args:
pac_str: JavaScript code containing PAC resolver.
"""
- self._engine = QJSEngine()
+ self._engine = QtQml.QJSEngine()
- self._engine.installExtensions(QJSEngine.ConsoleExtension)
+ self._engine.installExtensions(QtQml.QJSEngine.ConsoleExtension)
self._ctx = _PACContext(self._engine)
self._engine.globalObject().setProperty(
@@ -215,12 +210,12 @@ class PACResolver:
qtutils.ensure_valid(query.url())
if from_file:
- string_flags = QUrl.PrettyDecoded
+ string_flags = QtCore.QUrl.PrettyDecoded
else:
- string_flags = QUrl.RemoveUserInfo # type: ignore[assignment]
+ string_flags = QtCore.QUrl.RemoveUserInfo # type: ignore[assignment]
if query.url().scheme() == 'https':
- string_flags |= QUrl.RemovePath # type: ignore[assignment]
- string_flags |= QUrl.RemoveQuery # type: ignore[assignment]
+ string_flags |= QtCore.QUrl.RemovePath # type: ignore[assignment]
+ string_flags |= QtCore.QUrl.RemoveQuery # type: ignore[assignment]
result = self._resolver.call([query.url().toString(string_flags),
query.peerHostName()])
@@ -231,11 +226,11 @@ class PACResolver:
return self._parse_proxy_string(result_str)
-class PACFetcher(QObject):
+class PACFetcher(QtCore.QObject):
"""Asynchronous fetcher of PAC files."""
- finished = pyqtSignal()
+ finished = QtCore.pyqtSignal()
def __init__(self, url, parent=None):
"""Resolve a PAC proxy from URL.
@@ -254,8 +249,8 @@ class PACFetcher(QObject):
with log.disable_qt_msghandler():
# WORKAROUND for a hang when messages are printed, see our
# NetworkAccessManager subclass for details.
- self._manager: Optional[QNetworkAccessManager] = QNetworkAccessManager()
- self._manager.setProxy(QNetworkProxy(QNetworkProxy.NoProxy))
+ self._manager: Optional[QtNetwork.QNetworkAccessManager] = QtNetwork.QNetworkAccessManager()
+ self._manager.setProxy(QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.NoProxy))
self._pac = None
self._error_message = None
self._reply = None
@@ -269,14 +264,14 @@ class PACFetcher(QObject):
def fetch(self):
"""Fetch the proxy from the remote URL."""
assert self._manager is not None
- self._reply = self._manager.get(QNetworkRequest(self._pac_url))
+ self._reply = self._manager.get(QtNetwork.QNetworkRequest(self._pac_url))
self._reply.finished.connect( # type: ignore[attr-defined]
self._finish)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _finish(self):
assert self._reply is not None
- if self._reply.error() != QNetworkReply.NoError:
+ if self._reply.error() != QtNetwork.QNetworkReply.NoError:
error = "Can't fetch PAC file from URL, error code {}: {}"
self._error_message = error.format(
self._reply.error(), self._reply.errorString())
@@ -335,4 +330,4 @@ class PACFetcher(QObject):
# Later NetworkManager.createRequest will detect this and display
# an error message.
error_host = "pac-resolve-error.qutebrowser.invalid"
- return [QNetworkProxy(QNetworkProxy.HttpProxy, error_host, 9)]
+ return [QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.HttpProxy, error_host, 9)]
diff --git a/qutebrowser/browser/network/proxy.py b/qutebrowser/browser/network/proxy.py
index 2c0187837..80a08f62a 100644
--- a/qutebrowser/browser/network/proxy.py
+++ b/qutebrowser/browser/network/proxy.py
@@ -19,13 +19,11 @@
"""Handling of proxies."""
-from PyQt5.QtCore import QUrl, pyqtSlot
-from PyQt5.QtNetwork import QNetworkProxy, QNetworkProxyFactory
-
from qutebrowser.config import config, configtypes
from qutebrowser.utils import message, usertypes, urlutils, utils
from qutebrowser.misc import objects
from qutebrowser.browser.network import pac
+from qutebrowser.qt import QtNetwork, QtCore
application_factory = None
@@ -35,7 +33,7 @@ def init():
"""Set the application wide proxy factory."""
global application_factory
application_factory = ProxyFactory()
- QNetworkProxyFactory.setApplicationProxyFactory(application_factory)
+ QtNetwork.QNetworkProxyFactory.setApplicationProxyFactory(application_factory)
config.instance.changed.connect(_warn_for_pac)
_warn_for_pac()
@@ -50,13 +48,13 @@ def _warn_for_pac():
message.error("PAC support isn't implemented for QtWebEngine yet!")
-@pyqtSlot()
+@QtCore.pyqtSlot()
def shutdown():
- QNetworkProxyFactory.setApplicationProxyFactory(
+ QtNetwork.QNetworkProxyFactory.setApplicationProxyFactory(
None) # type: ignore[arg-type]
-class ProxyFactory(QNetworkProxyFactory):
+class ProxyFactory(QtNetwork.QNetworkProxyFactory):
"""Factory for proxies to be used by qutebrowser."""
@@ -73,11 +71,11 @@ class ProxyFactory(QNetworkProxyFactory):
return None
def _set_capabilities(self, proxy):
- if proxy.type() == QNetworkProxy.NoProxy:
+ if proxy.type() == QtNetwork.QNetworkProxy.NoProxy:
return
capabilities = proxy.capabilities()
- lookup_cap = QNetworkProxy.HostNameLookupCapability
+ lookup_cap = QtNetwork.QNetworkProxy.HostNameLookupCapability
if config.val.content.proxy_dns_requests:
capabilities |= lookup_cap
else:
@@ -98,11 +96,11 @@ class ProxyFactory(QNetworkProxyFactory):
# On Linux, use "export http_proxy=socks5://host:port" to manually
# set system proxy.
# ref. https://doc.qt.io/qt-5/qnetworkproxyfactory.html#systemProxyForQuery
- proxies = QNetworkProxyFactory.systemProxyForQuery(query)
+ proxies = QtNetwork.QNetworkProxyFactory.systemProxyForQuery(query)
elif isinstance(proxy, pac.PACFetcher):
if objects.backend == usertypes.Backend.QtWebEngine:
# Looks like query.url() is always invalid on QtWebEngine...
- proxy = urlutils.proxy_from_url(QUrl('direct://'))
+ proxy = urlutils.proxy_from_url(QtCore.QUrl('direct://'))
assert not isinstance(proxy, pac.PACFetcher)
proxies = [proxy]
elif objects.backend == usertypes.Backend.QtWebKit:
diff --git a/qutebrowser/browser/pdfjs.py b/qutebrowser/browser/pdfjs.py
index c180c55f8..0942c78c3 100644
--- a/qutebrowser/browser/pdfjs.py
+++ b/qutebrowser/browser/pdfjs.py
@@ -22,10 +22,9 @@
import os
-from PyQt5.QtCore import QUrl, QUrlQuery
-
from qutebrowser.utils import resources, javascript, jinja, standarddir, log
from qutebrowser.config import config
+from qutebrowser.qt import QtCore
_SYSTEM_PATHS = [
@@ -90,13 +89,13 @@ def _generate_pdfjs_script(filename):
Args:
filename: The name of the file to open.
"""
- url = QUrl('qute://pdfjs/file')
- url_query = QUrlQuery()
+ url = QtCore.QUrl('qute://pdfjs/file')
+ url_query = QtCore.QUrlQuery()
url_query.addQueryItem('filename', filename)
url.setQuery(url_query)
js_url = javascript.to_js(
- url.toString(QUrl.FullyEncoded)) # type: ignore[arg-type]
+ url.toString(QtCore.QUrl.FullyEncoded)) # type: ignore[arg-type]
return jinja.js_environment.from_string("""
document.addEventListener("DOMContentLoaded", function() {
@@ -225,19 +224,19 @@ def should_use_pdfjs(mimetype, url):
"""Check whether PDF.js should be used."""
# e.g. 'blob:qute%3A///b45250b3-787e-44d1-a8d8-c2c90f81f981'
is_download_url = (url.scheme() == 'blob' and
- QUrl(url.path()).scheme() == 'qute')
+ QtCore.QUrl(url.path()).scheme() == 'qute')
is_pdf = mimetype in ['application/pdf', 'application/x-pdf']
config_enabled = config.instance.get('content.pdfjs', url=url)
return is_pdf and not is_download_url and config_enabled
-def get_main_url(filename: str, original_url: QUrl) -> QUrl:
+def get_main_url(filename: str, original_url: QtCore.QUrl) -> QtCore.QUrl:
"""Get the URL to be opened to view a local PDF."""
- url = QUrl('qute://pdfjs/web/viewer.html')
- query = QUrlQuery()
+ url = QtCore.QUrl('qute://pdfjs/web/viewer.html')
+ query = QtCore.QUrlQuery()
query.addQueryItem('filename', filename) # read from our JS
query.addQueryItem('file', '') # to avoid pdfjs opening the default PDF
- urlstr = original_url.toString(QUrl.FullyEncoded) # type: ignore[arg-type]
+ urlstr = original_url.toString(QtCore.QUrl.FullyEncoded) # type: ignore[arg-type]
query.addQueryItem('source', urlstr)
url.setQuery(query)
return url
diff --git a/qutebrowser/browser/qtnetworkdownloads.py b/qutebrowser/browser/qtnetworkdownloads.py
index 8adb7ea20..d8f1e645f 100644
--- a/qutebrowser/browser/qtnetworkdownloads.py
+++ b/qutebrowser/browser/qtnetworkdownloads.py
@@ -25,10 +25,7 @@ import shutil
import functools
import dataclasses
from typing import Dict, IO, Optional
-
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, QTimer, QUrl
-from PyQt5.QtWidgets import QApplication
-from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager
+from qutebrowser.qt import QtWidgets
from qutebrowser.config import config, websettings
from qutebrowser.utils import message, usertypes, log, urlutils, utils, debug, objreg
@@ -36,13 +33,14 @@ from qutebrowser.misc import quitter
from qutebrowser.browser import downloads
from qutebrowser.browser.webkit import http
from qutebrowser.browser.webkit.network import networkmanager
+from qutebrowser.qt import QtNetwork, QtCore
@dataclasses.dataclass
class _RetryInfo:
- request: QNetworkRequest
- manager: QNetworkAccessManager
+ request: QtNetwork.QNetworkRequest
+ manager: QtNetwork.QNetworkAccessManager
class DownloadItem(downloads.AbstractDownloadItem):
@@ -83,7 +81,7 @@ class DownloadItem(downloads.AbstractDownloadItem):
"""
_MAX_REDIRECTS = 10
- adopt_download = pyqtSignal(object) # DownloadItem
+ adopt_download = QtCore.pyqtSignal(object) # DownloadItem
def __init__(self, reply, manager):
"""Constructor.
@@ -162,8 +160,8 @@ class DownloadItem(downloads.AbstractDownloadItem):
# We could have got signals before we connected slots to them.
# Here no signals are connected to the DownloadItem yet, so we use a
# singleShot QTimer to emit them after they are connected.
- if reply.error() != QNetworkReply.NoError:
- QTimer.singleShot(0, lambda: self._die(reply.errorString()))
+ if reply.error() != QtNetwork.QNetworkReply.NoError:
+ QtCore.QTimer.singleShot(0, lambda: self._die(reply.errorString()))
def _do_cancel(self):
self._read_timer.stop()
@@ -176,7 +174,7 @@ class DownloadItem(downloads.AbstractDownloadItem):
self.fileobj.close()
self.cancelled.emit()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def retry(self):
"""Retry a failed download."""
assert self.done
@@ -199,20 +197,20 @@ class DownloadItem(downloads.AbstractDownloadItem):
filename = getattr(self.fileobj, 'name', None)
return filename
- def url(self) -> QUrl:
+ def url(self) -> QtCore.QUrl:
# Note: self._reply is deleted when the download finishes
return self._url
- def origin(self) -> QUrl:
+ def origin(self) -> QtCore.QUrl:
if self._reply is None:
- return QUrl()
+ return QtCore.QUrl()
origin = self._reply.request().originatingObject()
try:
return origin.url()
except AttributeError:
# Raised either if origin is None or some object that doesn't
# have its own url.
- return QUrl()
+ return QtCore.QUrl()
def _ensure_can_set_filename(self, filename):
if self.fileobj is not None: # pragma: no cover
@@ -286,7 +284,7 @@ class DownloadItem(downloads.AbstractDownloadItem):
self.fileobj.write(self._reply.readAll())
if self._autoclose:
self.fileobj.close()
- self.successful = self._reply.error() == QNetworkReply.NoError
+ self.successful = self._reply.error() == QtNetwork.QNetworkReply.NoError
self._reply.close()
self._reply.deleteLater()
self._reply = None
@@ -295,7 +293,7 @@ class DownloadItem(downloads.AbstractDownloadItem):
log.downloads.debug("Download {} finished".format(self.basename))
self.data_changed.emit()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_reply_finished(self):
"""Clean up when the download was finished.
@@ -316,7 +314,7 @@ class DownloadItem(downloads.AbstractDownloadItem):
# clean up.
self._finish_download()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_ready_read(self):
"""Read available data and save file when ready to read."""
if self.fileobj is None or self._reply is None:
@@ -331,21 +329,21 @@ class DownloadItem(downloads.AbstractDownloadItem):
except OSError as e:
self._die(e.strerror)
- @pyqtSlot('QNetworkReply::NetworkError')
+ @QtCore.pyqtSlot('QNetworkReply::NetworkError')
def _on_reply_error(self, code):
"""Handle QNetworkReply errors."""
- if code == QNetworkReply.OperationCanceledError:
+ if code == QtNetwork.QNetworkReply.OperationCanceledError:
return
if self._reply is None:
error = "Unknown error: {}".format(
- debug.qenum_key(QNetworkReply, code))
+ debug.qenum_key(QtNetwork.QNetworkReply, code))
else:
error = self._reply.errorString()
self._die(error)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_read_timer_timeout(self):
"""Read some bytes from the QNetworkReply periodically."""
assert self._reply is not None
@@ -355,7 +353,7 @@ class DownloadItem(downloads.AbstractDownloadItem):
if data is not None:
self._buffer.write(data)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_meta_data_changed(self):
"""Update the download's metadata."""
if self._reply is None:
@@ -372,7 +370,7 @@ class DownloadItem(downloads.AbstractDownloadItem):
"""
assert self._reply is not None
redirect = self._reply.attribute(
- QNetworkRequest.RedirectionTargetAttribute)
+ QtNetwork.QNetworkRequest.RedirectionTargetAttribute)
if redirect is None or redirect.isEmpty():
return False
new_url = self._reply.url().resolved(redirect)
@@ -430,7 +428,7 @@ class DownloadManager(downloads.AbstractDownloadManager):
win_id=None, tab_id=None,
private=config.val.content.private_browsing, parent=self)
- @pyqtSlot('QUrl')
+ @QtCore.pyqtSlot('QUrl')
def get(self, url, cache=True, **kwargs):
"""Start a download with a link URL.
@@ -446,12 +444,12 @@ class DownloadManager(downloads.AbstractDownloadManager):
urlutils.invalid_url_error(url, "start download")
return None
- req = QNetworkRequest(url)
+ req = QtNetwork.QNetworkRequest(url)
user_agent = websettings.user_agent(url)
- req.setHeader(QNetworkRequest.UserAgentHeader, user_agent)
+ req.setHeader(QtNetwork.QNetworkRequest.UserAgentHeader, user_agent)
if not cache:
- req.setAttribute(QNetworkRequest.CacheSaveControlAttribute, False)
+ req.setAttribute(QtNetwork.QNetworkRequest.CacheSaveControlAttribute, False)
return self.get_request(req, **kwargs)
@@ -511,8 +509,8 @@ class DownloadManager(downloads.AbstractDownloadManager):
"""
# WORKAROUND for Qt corrupting data loaded from cache:
# https://bugreports.qt.io/browse/QTBUG-42757
- request.setAttribute(QNetworkRequest.CacheLoadControlAttribute,
- QNetworkRequest.AlwaysNetwork)
+ request.setAttribute(QtNetwork.QNetworkRequest.CacheLoadControlAttribute,
+ QtNetwork.QNetworkRequest.AlwaysNetwork)
if suggested_fn is None:
suggested_fn = self._get_suggested_filename(request)
@@ -538,7 +536,7 @@ class DownloadManager(downloads.AbstractDownloadManager):
reply = qnam.get(request)
return self.fetch(reply, **kwargs)
- @pyqtSlot('QNetworkReply')
+ @QtCore.pyqtSlot('QNetworkReply')
def fetch(self, reply, *, target=None, auto_remove=False,
suggested_filename=None, prompt_download_directory=None):
"""Download a QNetworkReply to disk.
@@ -608,6 +606,6 @@ class DownloadManager(downloads.AbstractDownloadManager):
def init():
"""Initialize the global QtNetwork download manager."""
- download_manager = DownloadManager(parent=QApplication.instance())
+ download_manager = DownloadManager(parent=QtWidgets.QApplication.instance())
objreg.register('qtnetwork-download-manager', download_manager)
quitter.instance.shutting_down.connect(download_manager.shutdown)
diff --git a/qutebrowser/browser/qutescheme.py b/qutebrowser/browser/qutescheme.py
index 68e36d249..c2fc257fc 100644
--- a/qutebrowser/browser/qutescheme.py
+++ b/qutebrowser/browser/qutescheme.py
@@ -34,15 +34,13 @@ import collections
import secrets
from typing import TypeVar, Callable, Dict, List, Optional, Union, Sequence, Tuple
-from PyQt5.QtCore import QUrlQuery, QUrl
-
import qutebrowser
from qutebrowser.browser import pdfjs, downloads, history
from qutebrowser.config import config, configdata, configexc
from qutebrowser.utils import (version, utils, jinja, log, message, docutils,
resources, objreg, standarddir)
from qutebrowser.misc import guiprocess, quitter
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
pyeval_output = ":pyeval was never called"
@@ -85,14 +83,14 @@ class Redirect(Exception):
url: The URL to redirect to, as a QUrl.
"""
- def __init__(self, url: QUrl):
+ def __init__(self, url: QtCore.QUrl):
super().__init__(url.toDisplayString())
self.url = url
# Return value: (mimetype, data) (encoded as utf-8 if a str is returned)
_HandlerRet = Tuple[str, Union[str, bytes]]
-_HandlerCallable = Callable[[QUrl], _HandlerRet]
+_HandlerCallable = Callable[[QtCore.QUrl], _HandlerRet]
_Handler = TypeVar('_Handler', bound=_HandlerCallable)
@@ -113,13 +111,13 @@ class add_handler: # noqa: N801,N806 pylint: disable=invalid-name
_HANDLERS[self._name] = self.wrapper
return function
- def wrapper(self, url: QUrl) -> _HandlerRet:
+ def wrapper(self, url: QtCore.QUrl) -> _HandlerRet:
"""Call the underlying function."""
assert self._function is not None
return self._function(url)
-def data_for_url(url: QUrl) -> Tuple[str, bytes]:
+def data_for_url(url: QtCore.QUrl) -> Tuple[str, bytes]:
"""Get the data to show for the given URL.
Args:
@@ -129,8 +127,8 @@ def data_for_url(url: QUrl) -> Tuple[str, bytes]:
A (mimetype, data) tuple.
"""
norm_url = url.adjusted(
- QUrl.NormalizePathSegments | # type: ignore[arg-type]
- QUrl.StripTrailingSlash)
+ QtCore.QUrl.NormalizePathSegments | # type: ignore[arg-type]
+ QtCore.QUrl.StripTrailingSlash)
if norm_url != url:
raise Redirect(norm_url)
@@ -141,7 +139,7 @@ def data_for_url(url: QUrl) -> Tuple[str, bytes]:
log.misc.debug("url: {}, path: {}, host {}".format(
url.toDisplayString(), path, host))
if not path or not host:
- new_url = QUrl()
+ new_url = QtCore.QUrl()
new_url.setScheme('qute')
# When path is absent, e.g. qute://help (with no trailing slash)
if host:
@@ -177,7 +175,7 @@ def data_for_url(url: QUrl) -> Tuple[str, bytes]:
@add_handler('bookmarks')
-def qute_bookmarks(_url: QUrl) -> _HandlerRet:
+def qute_bookmarks(_url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://bookmarks. Display all quickmarks / bookmarks."""
bookmarks = sorted(objreg.get('bookmark-manager').marks.items(),
key=lambda x: x[1]) # Sort by title
@@ -192,7 +190,7 @@ def qute_bookmarks(_url: QUrl) -> _HandlerRet:
@add_handler('tabs')
-def qute_tabs(_url: QUrl) -> _HandlerRet:
+def qute_tabs(_url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://tabs. Display information about all open tabs."""
tabs: Dict[str, List[Tuple[str, str]]] = collections.defaultdict(list)
for win_id, window in objreg.window_registry.items():
@@ -202,7 +200,7 @@ def qute_tabs(_url: QUrl) -> _HandlerRet:
scope='window',
window=win_id)
for tab in tabbed_browser.widgets():
- if tab.url() not in [QUrl("qute://tabs/"), QUrl("qute://tabs")]:
+ if tab.url() not in [QtCore.QUrl("qute://tabs/"), QtCore.QUrl("qute://tabs")]:
urlstr = tab.url().toDisplayString()
tabs[str(win_id)].append((tab.title(), urlstr))
@@ -238,17 +236,17 @@ def history_data(
@add_handler('history')
-def qute_history(url: QUrl) -> _HandlerRet:
+def qute_history(url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://history. Display and serve history."""
if url.path() == '/data':
- q_offset = QUrlQuery(url).queryItemValue("offset")
+ q_offset = QtCore.QUrlQuery(url).queryItemValue("offset")
try:
offset = int(q_offset) if q_offset else None
except ValueError:
raise UrlInvalidError("Query parameter offset is invalid")
# Use start_time in query or current time.
- q_start_time = QUrlQuery(url).queryItemValue("start_time")
+ q_start_time = QtCore.QUrlQuery(url).queryItemValue("start_time")
try:
start_time = float(q_start_time) if q_start_time else time.time()
except ValueError:
@@ -264,7 +262,7 @@ def qute_history(url: QUrl) -> _HandlerRet:
@add_handler('javascript')
-def qute_javascript(url: QUrl) -> _HandlerRet:
+def qute_javascript(url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://javascript.
Return content of file given as query parameter.
@@ -278,14 +276,14 @@ def qute_javascript(url: QUrl) -> _HandlerRet:
@add_handler('pyeval')
-def qute_pyeval(_url: QUrl) -> _HandlerRet:
+def qute_pyeval(_url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://pyeval."""
src = jinja.render('pre.html', title='pyeval', content=pyeval_output)
return 'text/html', src
@add_handler('process')
-def qute_process(url: QUrl) -> _HandlerRet:
+def qute_process(url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://process."""
path = url.path()[1:]
try:
@@ -307,7 +305,7 @@ def qute_process(url: QUrl) -> _HandlerRet:
@add_handler('version')
@add_handler('verizon')
-def qute_version(_url: QUrl) -> _HandlerRet:
+def qute_version(_url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://version."""
src = jinja.render('version.html', title='Version info',
version=version.version_info(),
@@ -316,7 +314,7 @@ def qute_version(_url: QUrl) -> _HandlerRet:
@add_handler('log')
-def qute_log(url: QUrl) -> _HandlerRet:
+def qute_log(url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://log.
There are three query parameters:
@@ -330,7 +328,7 @@ def qute_log(url: QUrl) -> _HandlerRet:
- logfilter: A filter string like the --logfilter commandline argument
accepts.
"""
- query = QUrlQuery(url)
+ query = QtCore.QUrlQuery(url)
plain = (query.hasQueryItem('plain') and
query.queryItemValue('plain').lower() != 'false')
@@ -358,7 +356,7 @@ def qute_log(url: QUrl) -> _HandlerRet:
@add_handler('gpl')
-def qute_gpl(_url: QUrl) -> _HandlerRet:
+def qute_gpl(_url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://gpl. Return HTML content as string."""
return 'text/html', resources.read_file('html/license.html')
@@ -373,7 +371,7 @@ def _asciidoc_fallback_path(html_path: str) -> Optional[str]:
@add_handler('help')
-def qute_help(url: QUrl) -> _HandlerRet:
+def qute_help(url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://help."""
urlpath = url.path()
if not urlpath or urlpath == '/':
@@ -422,11 +420,11 @@ def qute_help(url: QUrl) -> _HandlerRet:
return 'text/html', data
-def _qute_settings_set(url: QUrl) -> _HandlerRet:
+def _qute_settings_set(url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://settings/set."""
- query = QUrlQuery(url)
- option = query.queryItemValue('option', QUrl.FullyDecoded)
- value = query.queryItemValue('value', QUrl.FullyDecoded)
+ query = QtCore.QUrlQuery(url)
+ option = query.queryItemValue('option', QtCore.QUrl.FullyDecoded)
+ value = query.queryItemValue('value', QtCore.QUrl.FullyDecoded)
# https://github.com/qutebrowser/qutebrowser/issues/727
if option == 'content.javascript.enabled' and value == 'false':
@@ -444,7 +442,7 @@ def _qute_settings_set(url: QUrl) -> _HandlerRet:
@add_handler('settings')
-def qute_settings(url: QUrl) -> _HandlerRet:
+def qute_settings(url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://settings. View/change qute configuration."""
global csrf_token
@@ -470,7 +468,7 @@ def qute_settings(url: QUrl) -> _HandlerRet:
@add_handler('bindings')
-def qute_bindings(_url: QUrl) -> _HandlerRet:
+def qute_bindings(_url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://bindings. View keybindings."""
bindings = {}
defaults = config.val.bindings.default
@@ -488,7 +486,7 @@ def qute_bindings(_url: QUrl) -> _HandlerRet:
@add_handler('back')
-def qute_back(url: QUrl) -> _HandlerRet:
+def qute_back(url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://back.
Simple page to free ram / lazy load a site, goes back on focusing the tab.
@@ -500,14 +498,14 @@ def qute_back(url: QUrl) -> _HandlerRet:
@add_handler('configdiff')
-def qute_configdiff(_url: QUrl) -> _HandlerRet:
+def qute_configdiff(_url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://configdiff."""
data = config.instance.dump_userconfig().encode('utf-8')
return 'text/plain', data
@add_handler('pastebin-version')
-def qute_pastebin_version(_url: QUrl) -> _HandlerRet:
+def qute_pastebin_version(_url: QtCore.QUrl) -> _HandlerRet:
"""Handler that pastebins the version string."""
version.pastebin_version()
return 'text/plain', b'Paste called.'
@@ -520,14 +518,14 @@ def _pdf_path(filename: str) -> str:
@add_handler('pdfjs')
-def qute_pdfjs(url: QUrl) -> _HandlerRet:
+def qute_pdfjs(url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://pdfjs.
Return the pdf.js viewer or redirect to original URL if the file does not
exist.
"""
if url.path() == '/file':
- filename = QUrlQuery(url).queryItemValue('filename')
+ filename = QtCore.QUrlQuery(url).queryItemValue('filename')
if not filename:
raise UrlInvalidError("Missing filename")
if '/' in filename or os.sep in filename:
@@ -541,7 +539,7 @@ def qute_pdfjs(url: QUrl) -> _HandlerRet:
return mimetype, data
if url.path() == '/web/viewer.html':
- query = QUrlQuery(url)
+ query = QtCore.QUrlQuery(url)
filename = query.queryItemValue("filename")
if not filename:
raise UrlInvalidError("Missing filename")
@@ -551,7 +549,7 @@ def qute_pdfjs(url: QUrl) -> _HandlerRet:
source = query.queryItemValue('source')
if not source: # This may happen with old URLs stored in history
raise UrlInvalidError("Missing source")
- raise Redirect(QUrl(source))
+ raise Redirect(QtCore.QUrl(source))
data = pdfjs.generate_pdfjs_page(filename, url)
return 'text/html', data
@@ -571,7 +569,7 @@ def qute_pdfjs(url: QUrl) -> _HandlerRet:
@add_handler('warning')
-def qute_warning(url: QUrl) -> _HandlerRet:
+def qute_warning(url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://warning."""
path = url.path()
if path == '/webkit':
@@ -588,7 +586,7 @@ def qute_warning(url: QUrl) -> _HandlerRet:
@add_handler('resource')
-def qute_resource(url: QUrl) -> _HandlerRet:
+def qute_resource(url: QtCore.QUrl) -> _HandlerRet:
"""Handler for qute://resource."""
path = url.path().lstrip('/')
mimetype = utils.guess_mimetype(path, fallback=True)
diff --git a/qutebrowser/browser/shared.py b/qutebrowser/browser/shared.py
index f195bbf28..1b1f1e3d3 100644
--- a/qutebrowser/browser/shared.py
+++ b/qutebrowser/browser/shared.py
@@ -27,13 +27,12 @@ import netrc
import tempfile
from typing import Callable, Mapping, List, Optional, Iterable, Iterator
-from PyQt5.QtCore import QUrl, pyqtBoundSignal
-
from qutebrowser.config import config
from qutebrowser.utils import (usertypes, message, log, objreg, jinja, utils,
qtutils, version)
from qutebrowser.mainwindow import mainwindow
from qutebrowser.misc import guiprocess, objects
+from qutebrowser.qt import QtCore
class CallSuper(Exception):
@@ -72,7 +71,7 @@ def authentication_required(url, authenticator, abort_on):
else:
msg = '<b>{}</b> needs authentication'.format(
html.escape(url.toDisplayString()))
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded)
answer = message.ask(title="Authentication required", text=msg,
mode=usertypes.PromptMode.user_pwd,
abort_on=abort_on, url=urlstr)
@@ -95,7 +94,7 @@ def javascript_confirm(url, js_msg, abort_on):
msg = 'From <b>{}</b>:<br/>{}'.format(html.escape(url.toDisplayString()),
_format_msg(js_msg))
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded)
ans = message.ask('Javascript confirm', msg,
mode=usertypes.PromptMode.yesno,
abort_on=abort_on, url=urlstr)
@@ -112,7 +111,7 @@ def javascript_prompt(url, js_msg, default, abort_on):
msg = '<b>{}</b> asks:<br/>{}'.format(html.escape(url.toDisplayString()),
_format_msg(js_msg))
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded)
answer = message.ask('Javascript prompt', msg,
mode=usertypes.PromptMode.text,
default=default,
@@ -135,7 +134,7 @@ def javascript_alert(url, js_msg, abort_on):
msg = 'From <b>{}</b>:<br/>{}'.format(html.escape(url.toDisplayString()),
_format_msg(js_msg))
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded)
message.ask('Javascript alert', msg, mode=usertypes.PromptMode.alert,
abort_on=abort_on, url=urlstr)
@@ -160,10 +159,10 @@ def javascript_log_message(level, source, line, msg):
def ignore_certificate_error(
*,
- request_url: QUrl,
- first_party_url: QUrl,
+ request_url: QtCore.QUrl,
+ first_party_url: QtCore.QUrl,
error: usertypes.AbstractCertificateErrorWrapper,
- abort_on: Iterable[pyqtBoundSignal],
+ abort_on: Iterable[QtCore.pyqtBoundSignal],
) -> bool:
"""Display a certificate error question.
@@ -187,7 +186,7 @@ def ignore_certificate_error(
first_party_url.isValid() and
not request_url.matches(
first_party_url,
- QUrl.RemoveScheme)) # type: ignore[arg-type]
+ QtCore.QUrl.RemoveScheme)) # type: ignore[arg-type]
if conf == 'ask' or conf == 'ask-block-thirdparty' and not is_resource:
err_template = jinja.environment.from_string("""
@@ -218,7 +217,7 @@ def ignore_certificate_error(
)
urlstr = request_url.toString(
- QUrl.RemovePassword | QUrl.FullyEncoded) # type: ignore[arg-type]
+ QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded) # type: ignore[arg-type]
ignore = message.ask(title="Certificate error", text=msg,
mode=usertypes.PromptMode.yesno, default=False,
abort_on=abort_on, url=urlstr)
@@ -260,7 +259,7 @@ def feature_permission(url, option, msg, yes_action, no_action, abort_on,
config_val = config.instance.get(option, url=url)
if config_val == 'ask':
if url.isValid():
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded)
text = "Allow the website at <b>{}</b> to {}?".format(
html.escape(url.toDisplayString()), msg)
else:
diff --git a/qutebrowser/browser/signalfilter.py b/qutebrowser/browser/signalfilter.py
index 88ac4a65d..5e2f50860 100644
--- a/qutebrowser/browser/signalfilter.py
+++ b/qutebrowser/browser/signalfilter.py
@@ -21,12 +21,12 @@
import functools
-from PyQt5.QtCore import QObject
+from qutebrowser.qt import QtCore
from qutebrowser.utils import debug, log, objreg
-class SignalFilter(QObject):
+class SignalFilter(QtCore.QObject):
"""A filter for signals.
diff --git a/qutebrowser/browser/urlmarks.py b/qutebrowser/browser/urlmarks.py
index 944ec23d4..6821ecd76 100644
--- a/qutebrowser/browser/urlmarks.py
+++ b/qutebrowser/browser/urlmarks.py
@@ -32,12 +32,11 @@ import functools
import collections
from typing import MutableMapping
-from PyQt5.QtCore import pyqtSignal, QUrl, QObject
-
from qutebrowser.utils import (message, usertypes, qtutils, urlutils,
standarddir, objreg, log)
from qutebrowser.api import cmdutils
from qutebrowser.misc import lineparser
+from qutebrowser.qt import QtCore
class Error(Exception):
@@ -60,7 +59,7 @@ class AlreadyExistsError(Error):
"""Exception emitted when a given URL does already exist."""
-class UrlMarkManager(QObject):
+class UrlMarkManager(QtCore.QObject):
"""Base class for BookmarkManager and QuickmarkManager.
@@ -72,7 +71,7 @@ class UrlMarkManager(QObject):
changed: Emitted when anything changed.
"""
- changed = pyqtSignal()
+ changed = QtCore.pyqtSignal()
def __init__(self, parent=None):
"""Initialize and read quickmarks."""
@@ -149,7 +148,7 @@ class QuickmarkManager(UrlMarkManager):
if not url.isValid():
urlutils.invalid_url_error(url, "save quickmark")
return
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded)
message.ask_async(
"Add quickmark:", usertypes.PromptMode.text,
functools.partial(self.quickmark_add, urlstr),
@@ -196,7 +195,7 @@ class QuickmarkManager(UrlMarkManager):
Use a name instead where possible.
"""
qtutils.ensure_valid(url)
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded)
try:
index = list(self.marks.values()).index(urlstr)
@@ -268,7 +267,7 @@ class BookmarkManager(UrlMarkManager):
errstr = urlutils.get_errstring(url)
raise InvalidUrlError(errstr)
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded)
if urlstr in self.marks:
if toggle:
diff --git a/qutebrowser/browser/webelem.py b/qutebrowser/browser/webelem.py
index 05b0eadb3..a79af7c02 100644
--- a/qutebrowser/browser/webelem.py
+++ b/qutebrowser/browser/webelem.py
@@ -21,13 +21,12 @@
from typing import cast, TYPE_CHECKING, Iterator, Optional, Set, Union
import collections.abc
-
-from PyQt5.QtCore import QUrl, Qt, QEvent, QTimer, QRect, QPoint
-from PyQt5.QtGui import QMouseEvent
+from qutebrowser.qt import QtGui
from qutebrowser.config import config
from qutebrowser.keyinput import modeman
from qutebrowser.utils import log, usertypes, utils, qtutils, objreg
+from qutebrowser.qt import QtCore
if TYPE_CHECKING:
from qutebrowser.browser import browsertab
@@ -46,7 +45,7 @@ class OrphanedError(Error):
"""Raised when a webelement's parent has vanished."""
-def css_selector(group: str, url: QUrl) -> str:
+def css_selector(group: str, url: QtCore.QUrl) -> str:
"""Get a CSS selector for the given group/URL."""
selectors = config.instance.get('hints.selectors', url)
if group not in selectors:
@@ -98,7 +97,7 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
"""Check if this element has a valid frame attached."""
raise NotImplementedError
- def geometry(self) -> QRect:
+ def geometry(self) -> QtCore.QRect:
"""Get the geometry for this element."""
raise NotImplementedError
@@ -144,8 +143,8 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
"""Insert the given text into the element."""
raise NotImplementedError
- def rect_on_view(self, *, elem_geometry: QRect = None,
- no_js: bool = False) -> QRect:
+ def rect_on_view(self, *, elem_geometry: QtCore.QRect = None,
+ no_js: bool = False) -> QtCore.QRect:
"""Get the geometry of the element relative to the webview.
Args:
@@ -281,7 +280,7 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
"""Remove target from link."""
raise NotImplementedError
- def resolve_url(self, baseurl: QUrl) -> Optional[QUrl]:
+ def resolve_url(self, baseurl: QtCore.QUrl) -> Optional[QtCore.QUrl]:
"""Resolve the URL in the element's src/href attribute.
Args:
@@ -300,7 +299,7 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
else:
return None
- url = QUrl(text)
+ url = QtCore.QUrl(text)
if not url.isValid():
return None
if url.isRelative():
@@ -317,7 +316,7 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
"""Return True if clicking this element needs user interaction."""
raise NotImplementedError
- def _mouse_pos(self) -> QPoint:
+ def _mouse_pos(self) -> QtCore.QPoint:
"""Get the position to click/hover."""
# Click the center of the largest square fitting into the top/left
# corner of the rectangle, this will help if part of the <a> element
@@ -338,7 +337,7 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
raise NotImplementedError
def _click_fake_event(self, click_target: usertypes.ClickTarget,
- button: Qt.MouseButton = Qt.LeftButton) -> None:
+ button: QtCore.Qt.MouseButton = QtCore.Qt.LeftButton) -> None:
"""Send a fake click event to the element."""
pos = self._mouse_pos()
@@ -346,28 +345,28 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
"target {}".format(self, pos, click_target))
target_modifiers = {
- usertypes.ClickTarget.normal: Qt.NoModifier,
- usertypes.ClickTarget.window: Qt.AltModifier | Qt.ShiftModifier,
- usertypes.ClickTarget.tab: Qt.ControlModifier,
- usertypes.ClickTarget.tab_bg: Qt.ControlModifier,
+ usertypes.ClickTarget.normal: QtCore.Qt.NoModifier,
+ usertypes.ClickTarget.window: QtCore.Qt.AltModifier | QtCore.Qt.ShiftModifier,
+ usertypes.ClickTarget.tab: QtCore.Qt.ControlModifier,
+ usertypes.ClickTarget.tab_bg: QtCore.Qt.ControlModifier,
}
if config.val.tabs.background:
- target_modifiers[usertypes.ClickTarget.tab] |= Qt.ShiftModifier
+ target_modifiers[usertypes.ClickTarget.tab] |= QtCore.Qt.ShiftModifier
else:
- target_modifiers[usertypes.ClickTarget.tab_bg] |= Qt.ShiftModifier
+ target_modifiers[usertypes.ClickTarget.tab_bg] |= QtCore.Qt.ShiftModifier
- modifiers = cast(Qt.KeyboardModifiers, target_modifiers[click_target])
+ modifiers = cast(QtCore.Qt.KeyboardModifiers, target_modifiers[click_target])
events = [
- QMouseEvent(QEvent.MouseMove, pos, Qt.NoButton, Qt.NoButton, Qt.NoModifier),
- QMouseEvent(QEvent.MouseButtonPress, pos, button, button, modifiers),
- QMouseEvent(QEvent.MouseButtonRelease, pos, button, Qt.NoButton, modifiers),
+ QtGui.QMouseEvent(QtCore.QEvent.MouseMove, pos, QtCore.Qt.NoButton, QtCore.Qt.NoButton, QtCore.Qt.NoModifier),
+ QtGui.QMouseEvent(QtCore.QEvent.MouseButtonPress, pos, button, button, modifiers),
+ QtGui.QMouseEvent(QtCore.QEvent.MouseButtonRelease, pos, button, QtCore.Qt.NoButton, modifiers),
]
for evt in events:
self._tab.send_event(evt)
- QTimer.singleShot(0, self._move_text_cursor)
+ QtCore.QTimer.singleShot(0, self._move_text_cursor)
def _click_editable(self, click_target: usertypes.ClickTarget) -> None:
"""Fake a click on an editable input field."""
@@ -445,11 +444,11 @@ class AbstractWebElement(collections.abc.MutableMapping): # type: ignore[type-a
def hover(self) -> None:
"""Simulate a mouse hover over the element."""
pos = self._mouse_pos()
- event = QMouseEvent(QEvent.MouseMove, pos, Qt.NoButton, Qt.NoButton,
- Qt.NoModifier)
+ event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, pos, QtCore.Qt.NoButton, QtCore.Qt.NoButton,
+ QtCore.Qt.NoModifier)
self._tab.send_event(event)
def right_click(self) -> None:
"""Simulate a right-click on the element."""
self._click_fake_event(usertypes.ClickTarget.normal,
- button=Qt.RightButton)
+ button=QtCore.Qt.RightButton)
diff --git a/qutebrowser/browser/webengine/certificateerror.py b/qutebrowser/browser/webengine/certificateerror.py
index 4df7ce8ab..d057c47f3 100644
--- a/qutebrowser/browser/webengine/certificateerror.py
+++ b/qutebrowser/browser/webengine/certificateerror.py
@@ -19,8 +19,7 @@
"""Wrapper over a QWebEngineCertificateError."""
-from PyQt5.QtCore import QUrl
-from PyQt5.QtWebEngineWidgets import QWebEngineCertificateError
+from qutebrowser.qt import QtWebEngineWidgets, QtCore
from qutebrowser.utils import usertypes, utils, debug
@@ -29,7 +28,7 @@ class CertificateErrorWrapper(usertypes.AbstractCertificateErrorWrapper):
"""A wrapper over a QWebEngineCertificateError."""
- def __init__(self, error: QWebEngineCertificateError) -> None:
+ def __init__(self, error: QtWebEngineWidgets.QWebEngineCertificateError) -> None:
self._error = error
self.ignore = False
@@ -39,10 +38,10 @@ class CertificateErrorWrapper(usertypes.AbstractCertificateErrorWrapper):
def __repr__(self) -> str:
return utils.get_repr(
self,
- error=debug.qenum_key(QWebEngineCertificateError, self._error.error()),
+ error=debug.qenum_key(QtWebEngineWidgets.QWebEngineCertificateError, self._error.error()),
string=str(self))
- def url(self) -> QUrl:
+ def url(self) -> QtCore.QUrl:
return self._error.url()
def is_overridable(self) -> bool:
diff --git a/qutebrowser/browser/webengine/interceptor.py b/qutebrowser/browser/webengine/interceptor.py
index 0b1040c4d..91557f4df 100644
--- a/qutebrowser/browser/webengine/interceptor.py
+++ b/qutebrowser/browser/webengine/interceptor.py
@@ -19,29 +19,26 @@
"""A request interceptor taking care of adblocking and custom headers."""
-from PyQt5.QtCore import QUrl, QByteArray
-from PyQt5.QtWebEngineCore import (QWebEngineUrlRequestInterceptor,
- QWebEngineUrlRequestInfo)
-
from qutebrowser.config import websettings, config
from qutebrowser.browser import shared
from qutebrowser.utils import utils, log, debug, qtutils
from qutebrowser.extensions import interceptors
from qutebrowser.misc import objects
+from qutebrowser.qt import QtWebEngineCore, QtCore
class WebEngineRequest(interceptors.Request):
"""QtWebEngine-specific request interceptor functionality."""
- _WHITELISTED_REQUEST_METHODS = {QByteArray(b'GET'), QByteArray(b'HEAD')}
+ _WHITELISTED_REQUEST_METHODS = {QtCore.QByteArray(b'GET'), QtCore.QByteArray(b'HEAD')}
def __init__(self, *args, webengine_info, **kwargs):
super().__init__(*args, **kwargs)
self._webengine_info = webengine_info
self._redirected = False
- def redirect(self, url: QUrl, *, ignore_unsupported: bool = False) -> None:
+ def redirect(self, url: QtCore.QUrl, *, ignore_unsupported: bool = False) -> None:
if self._redirected:
raise interceptors.RedirectException("Request already redirected.")
if self._webengine_info is None:
@@ -62,7 +59,7 @@ class WebEngineRequest(interceptors.Request):
self._redirected = True
-class RequestInterceptor(QWebEngineUrlRequestInterceptor):
+class RequestInterceptor(QtWebEngineCore.QWebEngineUrlRequestInterceptor):
"""Handle ad blocking and custom headers."""
def __init__(self, parent=None):
@@ -71,50 +68,50 @@ class RequestInterceptor(QWebEngineUrlRequestInterceptor):
# extension ResourceTypes. If a ResourceType is added to Qt, this table
# should be updated too.
self._resource_types = {
- QWebEngineUrlRequestInfo.ResourceTypeMainFrame:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeMainFrame:
interceptors.ResourceType.main_frame,
- QWebEngineUrlRequestInfo.ResourceTypeSubFrame:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeSubFrame:
interceptors.ResourceType.sub_frame,
- QWebEngineUrlRequestInfo.ResourceTypeStylesheet:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeStylesheet:
interceptors.ResourceType.stylesheet,
- QWebEngineUrlRequestInfo.ResourceTypeScript:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeScript:
interceptors.ResourceType.script,
- QWebEngineUrlRequestInfo.ResourceTypeImage:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeImage:
interceptors.ResourceType.image,
- QWebEngineUrlRequestInfo.ResourceTypeFontResource:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeFontResource:
interceptors.ResourceType.font_resource,
- QWebEngineUrlRequestInfo.ResourceTypeSubResource:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeSubResource:
interceptors.ResourceType.sub_resource,
- QWebEngineUrlRequestInfo.ResourceTypeObject:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeObject:
interceptors.ResourceType.object,
- QWebEngineUrlRequestInfo.ResourceTypeMedia:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeMedia:
interceptors.ResourceType.media,
- QWebEngineUrlRequestInfo.ResourceTypeWorker:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeWorker:
interceptors.ResourceType.worker,
- QWebEngineUrlRequestInfo.ResourceTypeSharedWorker:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeSharedWorker:
interceptors.ResourceType.shared_worker,
- QWebEngineUrlRequestInfo.ResourceTypePrefetch:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypePrefetch:
interceptors.ResourceType.prefetch,
- QWebEngineUrlRequestInfo.ResourceTypeFavicon:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeFavicon:
interceptors.ResourceType.favicon,
- QWebEngineUrlRequestInfo.ResourceTypeXhr:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeXhr:
interceptors.ResourceType.xhr,
- QWebEngineUrlRequestInfo.ResourceTypePing:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypePing:
interceptors.ResourceType.ping,
- QWebEngineUrlRequestInfo.ResourceTypeServiceWorker:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeServiceWorker:
interceptors.ResourceType.service_worker,
- QWebEngineUrlRequestInfo.ResourceTypeCspReport:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeCspReport:
interceptors.ResourceType.csp_report,
- QWebEngineUrlRequestInfo.ResourceTypePluginResource:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypePluginResource:
interceptors.ResourceType.plugin_resource,
- QWebEngineUrlRequestInfo.ResourceTypeUnknown:
+ QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeUnknown:
interceptors.ResourceType.unknown,
}
try:
- preload_main_frame = (QWebEngineUrlRequestInfo.
+ preload_main_frame = (QtWebEngineCore.QWebEngineUrlRequestInfo.
ResourceTypeNavigationPreloadMainFrame)
- preload_sub_frame = (QWebEngineUrlRequestInfo.
+ preload_sub_frame = (QtWebEngineCore.QWebEngineUrlRequestInfo.
ResourceTypeNavigationPreloadSubFrame)
except AttributeError:
# Added in Qt 5.14
@@ -152,9 +149,9 @@ class RequestInterceptor(QWebEngineUrlRequestInterceptor):
info: QWebEngineUrlRequestInfo &info
"""
if 'log-requests' in objects.debug_flags:
- resource_type_str = debug.qenum_key(QWebEngineUrlRequestInfo,
+ resource_type_str = debug.qenum_key(QtWebEngineCore.QWebEngineUrlRequestInfo,
info.resourceType())
- navigation_type_str = debug.qenum_key(QWebEngineUrlRequestInfo,
+ navigation_type_str = debug.qenum_key(QtWebEngineCore.QWebEngineUrlRequestInfo,
info.navigationType())
log.network.debug("{} {}, first-party {}, resource {}, "
"navigation {}".format(
@@ -177,15 +174,15 @@ class RequestInterceptor(QWebEngineUrlRequestInterceptor):
except KeyError:
log.network.warning(
"Resource type {} not found in RequestInterceptor dict."
- .format(debug.qenum_key(QWebEngineUrlRequestInfo,
+ .format(debug.qenum_key(QtWebEngineCore.QWebEngineUrlRequestInfo,
info.resourceType())))
resource_type = interceptors.ResourceType.unknown
- is_xhr = info.resourceType() == QWebEngineUrlRequestInfo.ResourceTypeXhr
+ is_xhr = info.resourceType() == QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceTypeXhr
if ((url.scheme(), url.host(), url.path()) ==
('qute', 'settings', '/set')):
- if first_party != QUrl('qute://settings/') or not is_xhr:
+ if first_party != QtCore.QUrl('qute://settings/') or not is_xhr:
log.network.warning("Blocking malicious request from {} to {}"
.format(first_party.toDisplayString(),
url.toDisplayString()))
diff --git a/qutebrowser/browser/webengine/notification.py b/qutebrowser/browser/webengine/notification.py
index 2b77a5ac4..7ab769659 100644
--- a/qutebrowser/browser/webengine/notification.py
+++ b/qutebrowser/browser/webengine/notification.py
@@ -49,26 +49,20 @@ import itertools
import functools
import subprocess
from typing import Any, List, Dict, Optional, Iterator, TYPE_CHECKING
-
-from PyQt5.QtCore import (Qt, QObject, QVariant, QMetaType, QByteArray, pyqtSlot,
- pyqtSignal, QTimer, QProcess, QUrl)
-from PyQt5.QtGui import QImage, QIcon, QPixmap
-from PyQt5.QtDBus import (QDBusConnection, QDBusInterface, QDBus, QDBusServiceWatcher,
- QDBusArgument, QDBusMessage, QDBusError)
-from PyQt5.QtWidgets import QSystemTrayIcon
+from qutebrowser.qt import QtWidgets
if TYPE_CHECKING:
# putting these behind TYPE_CHECKING also means this module is importable
# on installs that don't have these
- from PyQt5.QtWebEngineCore import QWebEngineNotification
- from PyQt5.QtWebEngineWidgets import QWebEngineProfile
+ from qutebrowser.qt import QtWebEngineWidgets, QtWebEngineCore, QWebEngineNotification
+ from qutebrowser.qt import QWebEngineProfile
from qutebrowser.config import config
from qutebrowser.misc import objects
from qutebrowser.utils import (
qtutils, log, utils, debug, message, version, objreg, resources,
)
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtWebEngine, QtGui, QtDBus, QtCore, sip
bridge: Optional['NotificationBridgePresenter'] = None
@@ -105,7 +99,7 @@ class Error(Exception):
"""Raised when something goes wrong with notifications."""
-class AbstractNotificationAdapter(QObject):
+class AbstractNotificationAdapter(QtCore.QObject):
"""An adapter taking notifications and displaying them.
@@ -118,14 +112,14 @@ class AbstractNotificationAdapter(QObject):
# Emitted by the adapter when the notification with the given ID was closed or
# clicked by the user.
- close_id = pyqtSignal(int)
- click_id = pyqtSignal(int)
+ close_id = QtCore.pyqtSignal(int)
+ click_id = QtCore.pyqtSignal(int)
# Emitted by the adapter when an error occurred, which should result in the adapter
# getting swapped out (potentially initializing the same adapter again, or using a
# different one if that fails).
- error = pyqtSignal(str)
- clear_all = pyqtSignal()
+ error = QtCore.pyqtSignal(str)
+ clear_all = QtCore.pyqtSignal()
def present(
self,
@@ -143,7 +137,7 @@ class AbstractNotificationAdapter(QObject):
"""
raise NotImplementedError
- def _should_include_origin(self, origin: QUrl) -> bool:
+ def _should_include_origin(self, origin: QtCore.QUrl) -> bool:
"""Check if the origin is useful to include.
If we open the page via a file scheme, the origin is QUrl('file:///') which
@@ -154,13 +148,13 @@ class AbstractNotificationAdapter(QObject):
config.instance.get('content.notifications.show_origin', url=origin),
)
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def on_web_closed(self, notification_id: int) -> None:
"""Called when a notification was closed by the website."""
raise NotImplementedError
-class NotificationBridgePresenter(QObject):
+class NotificationBridgePresenter(QtCore.QObject):
"""Notification presenter which bridges notifications to an adapter.
@@ -171,7 +165,7 @@ class NotificationBridgePresenter(QObject):
- Switching out adapters if the current one emitted its error signal.
"""
- def __init__(self, parent: QObject = None) -> None:
+ def __init__(self, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
assert _notifications_supported()
@@ -235,13 +229,7 @@ class NotificationBridgePresenter(QObject):
def install(self, profile: "QWebEngineProfile") -> None:
"""Set the profile to use this bridge as the presenter."""
- # WORKAROUND for
- # https://www.riverbankcomputing.com/pipermail/pyqt/2020-May/042916.html
- # Fixed in PyQtWebEngine 5.15.0
- # PYQT_WEBENGINE_VERSION was added with PyQtWebEngine 5.13, but if we're here,
- # we already did a version check above.
- from PyQt5.QtWebEngine import PYQT_WEBENGINE_VERSION
- if PYQT_WEBENGINE_VERSION < 0x050F00:
+ if QtWebEngine.PYQT_WEBENGINE_VERSION < 0x050F00:
# PyQtWebEngine unrefs the callback after it's called, for some
# reason. So we call setNotificationPresenter again to *increase*
# its refcount to prevent it from getting GC'd. Otherwise, random
@@ -323,7 +311,7 @@ class NotificationBridgePresenter(QObject):
log.misc.debug("Did not find match")
return None
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def _on_adapter_closed(self, notification_id: int) -> None:
"""A notification was closed by the adapter (usually due to the user).
@@ -347,7 +335,7 @@ class NotificationBridgePresenter(QObject):
log.misc.debug(f"Ignoring close request for notification {notification_id} "
"due to PyQt bug")
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def _on_adapter_clicked(self, notification_id: int) -> None:
"""A notification was clicked by the adapter (usually due to the user).
@@ -377,7 +365,7 @@ class NotificationBridgePresenter(QObject):
for win_id in objreg.window_registry:
tabbedbrowser = objreg.get("tabbed-browser", window=win_id, scope="window")
for idx, tab in enumerate(tabbedbrowser.widgets()):
- if tab.url().matches(notification.origin(), QUrl.RemovePath):
+ if tab.url().matches(notification.origin(), QtCore.QUrl.RemovePath):
tabbedbrowser.widget.setCurrentIndex(idx)
return
log.misc.debug(f"No matching tab found for {notification.origin()}")
@@ -395,7 +383,7 @@ class NotificationBridgePresenter(QObject):
self._adapter = None
self._on_adapter_clear_all()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_adapter_clear_all(self) -> None:
"""Called when the adapter requests clearing all notifications.
@@ -409,7 +397,7 @@ class NotificationBridgePresenter(QObject):
for notification_id in list(self._active_notifications):
self._on_adapter_closed(notification_id)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _on_adapter_error(self, error: str) -> None:
"""A fatal error happened in the adapter.
@@ -440,14 +428,14 @@ class SystrayNotificationAdapter(AbstractNotificationAdapter):
NAME = "systray"
NOTIFICATION_ID = 1 # only one concurrent notification supported
- def __init__(self, parent: QObject = None) -> None:
+ def __init__(self, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
- if not QSystemTrayIcon.isSystemTrayAvailable():
+ if not QtWidgets.QSystemTrayIcon.isSystemTrayAvailable():
raise Error("No system tray available")
- if not QSystemTrayIcon.supportsMessages():
+ if not QtWidgets.QSystemTrayIcon.supportsMessages():
raise Error("System tray does not support messages")
- self._systray = QSystemTrayIcon(self)
+ self._systray = QtWidgets.QSystemTrayIcon(self)
self._systray.setIcon(objects.qapp.windowIcon())
self._systray.messageClicked.connect(self._on_systray_clicked)
@@ -468,27 +456,27 @@ class SystrayNotificationAdapter(AbstractNotificationAdapter):
return self.NOTIFICATION_ID
- def _convert_icon(self, image: QImage) -> QIcon:
+ def _convert_icon(self, image: QtGui.QImage) -> QtGui.QIcon:
"""Convert a QImage to a QIcon."""
if image.isNull():
- return QIcon()
- pixmap = QPixmap.fromImage(image, Qt.NoFormatConversion)
+ return QtGui.QIcon()
+ pixmap = QtGui.QPixmap.fromImage(image, QtCore.Qt.NoFormatConversion)
assert not pixmap.isNull()
- icon = QIcon(pixmap)
+ icon = QtGui.QIcon(pixmap)
assert not icon.isNull()
return icon
- def _format_message(self, text: str, origin: QUrl) -> str:
+ def _format_message(self, text: str, origin: QtCore.QUrl) -> str:
"""Format the message to display."""
if not self._should_include_origin(origin):
return text
return origin.toDisplayString() + '\n\n' + text
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_systray_clicked(self) -> None:
self.click_id.emit(self.NOTIFICATION_ID)
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def on_web_closed(self, notification_id: int) -> None:
assert notification_id == self.NOTIFICATION_ID, notification_id
if not sip.isdeleted(self._systray):
@@ -509,7 +497,7 @@ class MessagesNotificationAdapter(AbstractNotificationAdapter):
NAME = "messages"
- def __init__(self, parent: QObject = None) -> None:
+ def __init__(self, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
self._id_gen = itertools.count(1)
@@ -525,12 +513,12 @@ class MessagesNotificationAdapter(AbstractNotificationAdapter):
message.info(markup, replace=f'notifications-{new_id}')
# Faking closing, timing might not be 100% accurate
- QTimer.singleShot(
+ QtCore.QTimer.singleShot(
config.val.messages.timeout, lambda: self.close_id.emit(new_id))
return new_id
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def on_web_closed(self, _notification_id: int) -> None:
"""We can't close messages."""
@@ -561,7 +549,7 @@ class HerbeNotificationAdapter(AbstractNotificationAdapter):
NAME = "herbe"
- def __init__(self, parent: QObject = None) -> None:
+ def __init__(self, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
# Also cleans up potentially hanging semaphores from herbe.
# https://github.com/dudik/herbe#notifications-dont-show-up
@@ -582,7 +570,7 @@ class HerbeNotificationAdapter(AbstractNotificationAdapter):
if replaces_id is not None:
self.on_web_closed(replaces_id)
- proc = QProcess(self)
+ proc = QtCore.QProcess(self)
proc.errorOccurred.connect(self._on_error)
lines = list(self._message_lines(qt_notification))
@@ -610,7 +598,7 @@ class HerbeNotificationAdapter(AbstractNotificationAdapter):
if not qt_notification.icon().isNull():
yield "(icon not shown)"
- def _on_finished(self, pid: int, code: int, status: QProcess.ExitStatus) -> None:
+ def _on_finished(self, pid: int, code: int, status: QtCore.QProcess.ExitStatus) -> None:
"""Handle a closing herbe process.
From the GitHub page:
@@ -623,7 +611,7 @@ class HerbeNotificationAdapter(AbstractNotificationAdapter):
signals, we can't do much - emitting self.error would just go use herbe again,
so there's no point.
"""
- if status == QProcess.CrashExit:
+ if status == QtCore.QProcess.CrashExit:
return
if code == 0:
@@ -635,14 +623,14 @@ class HerbeNotificationAdapter(AbstractNotificationAdapter):
stderr = proc.readAllStandardError()
raise Error(f'herbe exited with status {code}: {stderr}')
- @pyqtSlot(QProcess.ProcessError)
- def _on_error(self, error: QProcess.ProcessError) -> None:
- if error == QProcess.Crashed:
+ @QtCore.pyqtSlot(QtCore.QProcess.ProcessError)
+ def _on_error(self, error: QtCore.QProcess.ProcessError) -> None:
+ if error == QtCore.QProcess.Crashed:
return
- name = debug.qenum_key(QProcess.ProcessError, error)
+ name = debug.qenum_key(QtCore.QProcess.ProcessError, error)
raise Error(f'herbe process error: {name}')
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def on_web_closed(self, notification_id: int) -> None:
"""Handle closing the notification from JS.
@@ -689,10 +677,10 @@ class _ServerCapabilities:
)
-def _as_uint32(x: int) -> QVariant:
+def _as_uint32(x: int) -> QtCore.QVariant:
"""Convert the given int to an uint32 for DBus."""
- variant = QVariant(x)
- successful = variant.convert(QVariant.UInt)
+ variant = QtCore.QVariant(x)
+ successful = variant.convert(QtCore.QVariant.UInt)
assert successful
return variant
@@ -734,7 +722,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
"org.freedesktop.DBus.Error.Spawn.ChildSignaled",
}
- def __init__(self, parent: QObject = None) -> None:
+ def __init__(self, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
assert _notifications_supported()
@@ -745,16 +733,16 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
# possible to run DBus there.
raise Error("libnotify is not supported on Windows")
- bus = QDBusConnection.sessionBus()
+ bus = QtDBus.QDBusConnection.sessionBus()
if not bus.isConnected():
raise Error(
"Failed to connect to DBus session bus: " +
self._dbus_error_str(bus.lastError()))
- self._watcher = QDBusServiceWatcher(
+ self._watcher = QtDBus.QDBusServiceWatcher(
self.SERVICE,
bus,
- QDBusServiceWatcher.WatchForUnregistration,
+ QtDBus.QDBusServiceWatcher.WatchForUnregistration,
self,
)
self._watcher.serviceUnregistered.connect( # type: ignore[attr-defined]
@@ -763,7 +751,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
test_service = 'test-notification-service' in objects.debug_flags
service = self.TEST_SERVICE if test_service else self.SERVICE
- self.interface = QDBusInterface(service, self.PATH, self.INTERFACE, bus)
+ self.interface = QtDBus.QDBusInterface(service, self.PATH, self.INTERFACE, bus)
if not self.interface.isValid():
raise Error(
"Could not construct a DBus interface: " +
@@ -790,7 +778,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
else:
self._fetch_capabilities()
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _on_service_unregistered(self) -> None:
"""Make sure we know when the notification daemon exits.
@@ -867,8 +855,8 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
def _get_server_info(self) -> None:
"""Query notification server information and set quirks."""
- reply = self.interface.call(QDBus.BlockWithGui, "GetServerInformation")
- self._verify_message(reply, "ssss", QDBusMessage.ReplyMessage)
+ reply = self.interface.call(QtDBus.QDBus.BlockWithGui, "GetServerInformation")
+ self._verify_message(reply, "ssss", QtDBus.QDBusMessage.ReplyMessage)
name, vendor, ver, spec_version = reply.arguments()
log.misc.debug(
@@ -895,7 +883,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
if spec_version in icon_key_overrides:
self._quirks.icon_key = icon_key_overrides[spec_version]
- def _dbus_error_str(self, error: QDBusError) -> str:
+ def _dbus_error_str(self, error: QtDBus.QDBusError) -> str:
"""Get a string for a DBus error."""
if not error.isValid():
return "Unknown error"
@@ -903,20 +891,20 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
def _verify_message(
self,
- msg: QDBusMessage,
+ msg: QtDBus.QDBusMessage,
expected_signature: str,
- expected_type: QDBusMessage.MessageType,
+ expected_type: QtDBus.QDBusMessage.MessageType,
) -> None:
"""Check the signature/type of a received message.
Raises DBusError if the signature doesn't match.
"""
assert expected_type not in [
- QDBusMessage.ErrorMessage,
- QDBusMessage.InvalidMessage,
+ QtDBus.QDBusMessage.ErrorMessage,
+ QtDBus.QDBusMessage.InvalidMessage,
], expected_type
- if msg.type() == QDBusMessage.ErrorMessage:
+ if msg.type() == QtDBus.QDBusMessage.ErrorMessage:
err = msg.errorName()
if err in self._NON_FATAL_ERRORS:
self.error.emit(msg.errorMessage())
@@ -932,8 +920,8 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
typ = msg.type()
if typ != expected_type:
- type_str = debug.qenum_key(QDBusMessage.MessageType, typ)
- expected_type_str = debug.qenum_key(QDBusMessage.MessageType, expected_type)
+ type_str = debug.qenum_key(QtDBus.QDBusMessage.MessageType, typ)
+ expected_type_str = debug.qenum_key(QtDBus.QDBusMessage.MessageType, expected_type)
raise Error(
f"Got a message of type {type_str} but expected {expected_type_str}"
f"(args: {msg.arguments()})")
@@ -951,7 +939,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
actions = []
if self._capabilities.actions:
actions = ['default', 'Activate'] # key, name
- actions_arg = QDBusArgument(actions, QMetaType.QStringList)
+ actions_arg = QtDBus.QDBusArgument(actions, QtCore.QMetaType.QStringList)
origin_url_str = qt_notification.origin().toDisplayString()
hints: Dict[str, Any] = {
@@ -968,7 +956,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
icon = qt_notification.icon()
if icon.isNull():
filename = 'icons/qutebrowser-64x64.png'
- icon = QImage.fromData(resources.read_file_binary(filename))
+ icon = QtGui.QImage.fromData(resources.read_file_binary(filename))
key = self._quirks.icon_key or "image-data"
data = self._convert_image(icon)
@@ -981,7 +969,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
title = html.escape(title, quote=False)
reply = self.interface.call(
- QDBus.BlockWithGui,
+ QtDBus.QDBus.BlockWithGui,
"Notify",
"qutebrowser", # application name
_as_uint32(replaces_id), # replaces notification id
@@ -992,7 +980,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
hints,
-1, # timeout; -1 means 'use default'
)
- self._verify_message(reply, "u", QDBusMessage.ReplyMessage)
+ self._verify_message(reply, "u", QtDBus.QDBusMessage.ReplyMessage)
notification_id = reply.arguments()[0]
@@ -1008,7 +996,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
return notification_id
- def _convert_image(self, qimage: QImage) -> Optional[QDBusArgument]:
+ def _convert_image(self, qimage: QtGui.QImage) -> Optional[QtDBus.QDBusArgument]:
"""Convert a QImage to the structure DBus expects.
https://specifications.freedesktop.org/notification-spec/latest/ar01s05.html#icons-and-images-formats
@@ -1016,10 +1004,10 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
bits_per_color = 8
has_alpha = qimage.hasAlphaChannel()
if has_alpha:
- image_format = QImage.Format_RGBA8888
+ image_format = QtGui.QImage.Format_RGBA8888
channel_count = 4
else:
- image_format = QImage.Format_RGB888
+ image_format = QtGui.QImage.Format_RGB888
channel_count = 3
qimage.convertTo(image_format)
@@ -1027,7 +1015,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
width = qimage.width()
height = qimage.height()
- image_data = QDBusArgument()
+ image_data = QtDBus.QDBusArgument()
image_data.beginStructure()
image_data.add(width)
image_data.add(height)
@@ -1076,31 +1064,31 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
return None
bits = qimage.constBits().asstring(size)
- image_data.add(QByteArray(bits))
+ image_data.add(QtCore.QByteArray(bits))
image_data.endStructure()
return image_data
- @pyqtSlot(QDBusMessage)
- def _handle_close(self, msg: QDBusMessage) -> None:
+ @QtCore.pyqtSlot(QtDBus.QDBusMessage)
+ def _handle_close(self, msg: QtDBus.QDBusMessage) -> None:
"""Handle NotificationClosed from DBus."""
- self._verify_message(msg, "uu", QDBusMessage.SignalMessage)
+ self._verify_message(msg, "uu", QtDBus.QDBusMessage.SignalMessage)
notification_id, _close_reason = msg.arguments()
self.close_id.emit(notification_id)
- @pyqtSlot(QDBusMessage)
- def _handle_action(self, msg: QDBusMessage) -> None:
+ @QtCore.pyqtSlot(QtDBus.QDBusMessage)
+ def _handle_action(self, msg: QtDBus.QDBusMessage) -> None:
"""Handle ActionInvoked from DBus."""
- self._verify_message(msg, "us", QDBusMessage.SignalMessage)
+ self._verify_message(msg, "us", QtDBus.QDBusMessage.SignalMessage)
notification_id, action_key = msg.arguments()
if action_key == "default":
self.click_id.emit(notification_id)
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def on_web_closed(self, notification_id: int) -> None:
"""Send CloseNotification if a notification was closed from JS."""
self.interface.call(
- QDBus.NoBlock,
+ QtDBus.QDBus.NoBlock,
"CloseNotification",
_as_uint32(notification_id),
)
@@ -1108,10 +1096,10 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
def _fetch_capabilities(self) -> None:
"""Fetch capabilities from the notification server."""
reply = self.interface.call(
- QDBus.BlockWithGui,
+ QtDBus.QDBus.BlockWithGui,
"GetCapabilities",
)
- self._verify_message(reply, "as", QDBusMessage.ReplyMessage)
+ self._verify_message(reply, "as", QtDBus.QDBusMessage.ReplyMessage)
caplist = reply.arguments()[0]
self._capabilities = _ServerCapabilities.from_list(caplist)
@@ -1122,7 +1110,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
log.misc.debug(f"Notification server capabilities: {self._capabilities}")
- def _format_body(self, body: str, origin_url: QUrl) -> str:
+ def _format_body(self, body: str, origin_url: QtCore.QUrl) -> str:
"""Format the body according to the server capabilities.
If the server doesn't support x-kde-origin-name, we include the origin URL as a
@@ -1138,7 +1126,7 @@ class DBusNotificationAdapter(AbstractNotificationAdapter):
prefix = None
elif self._capabilities.body_markup and self._capabilities.body_hyperlinks:
href = html.escape(
- origin_url.toString(QUrl.FullyEncoded) # type: ignore[arg-type]
+ origin_url.toString(QtCore.QUrl.FullyEncoded) # type: ignore[arg-type]
)
text = html.escape(urlstr, quote=False)
prefix = f'<a href="{href}">{text}</a>'
diff --git a/qutebrowser/browser/webengine/tabhistory.py b/qutebrowser/browser/webengine/tabhistory.py
index ab4b05fe9..37a8d7542 100644
--- a/qutebrowser/browser/webengine/tabhistory.py
+++ b/qutebrowser/browser/webengine/tabhistory.py
@@ -19,9 +19,8 @@
"""QWebHistory serializer for QtWebEngine."""
-from PyQt5.QtCore import QByteArray, QDataStream, QIODevice, QUrl
-
from qutebrowser.utils import qtutils
+from qutebrowser.qt import QtCore
# kHistoryStreamVersion = 3 was originally set when history serializing was
@@ -64,7 +63,7 @@ def _serialize_item(item, stream):
## QByteArray(encodedPageState.data(), encodedPageState.size());
# \xff\xff\xff\xff
- qtutils.serialize_stream(stream, QByteArray())
+ qtutils.serialize_stream(stream, QtCore.QByteArray())
## static_cast<qint32>(entry->GetTransitionType());
# chromium/ui/base/page_transition_types.h
@@ -77,7 +76,7 @@ def _serialize_item(item, stream):
## toQt(entry->GetReferrer().url);
# \xff\xff\xff\xff
- qtutils.serialize_stream(stream, QUrl())
+ qtutils.serialize_stream(stream, QtCore.QUrl())
## static_cast<qint32>(entry->GetReferrer().policy);
# chromium/third_party/WebKit/public/platform/WebReferrerPolicy.h
@@ -123,8 +122,8 @@ def serialize(items):
If 'data' goes out of scope, reading from 'stream' will result in a
segfault!
"""
- data = QByteArray()
- stream = QDataStream(data, QIODevice.ReadWrite)
+ data = QtCore.QByteArray()
+ stream = QtCore.QDataStream(data, QtCore.QIODevice.ReadWrite)
cur_user_data = None
current_idx = None
diff --git a/qutebrowser/browser/webengine/webenginedownloads.py b/qutebrowser/browser/webengine/webenginedownloads.py
index a6a2a1b93..2bae19952 100644
--- a/qutebrowser/browser/webengine/webenginedownloads.py
+++ b/qutebrowser/browser/webengine/webenginedownloads.py
@@ -22,13 +22,12 @@
import re
import os.path
import functools
-
-from PyQt5.QtCore import pyqtSlot, Qt, QUrl, QObject
-from PyQt5.QtWebEngineWidgets import QWebEngineDownloadItem
+from qutebrowser.qt import QtWebEngineWidgets
from qutebrowser.browser import downloads, pdfjs
from qutebrowser.utils import (debug, usertypes, message, log, objreg, urlutils,
utils, version)
+from qutebrowser.qt import QtCore
class DownloadItem(downloads.AbstractDownloadItem):
@@ -39,9 +38,9 @@ class DownloadItem(downloads.AbstractDownloadItem):
_qt_item: The wrapped item.
"""
- def __init__(self, qt_item: QWebEngineDownloadItem,
+ def __init__(self, qt_item: QtWebEngineWidgets.QWebEngineDownloadItem,
manager: downloads.AbstractDownloadManager,
- parent: QObject = None) -> None:
+ parent: QtCore.QObject = None) -> None:
super().__init__(manager=manager, parent=manager)
self._qt_item = qt_item
qt_item.downloadProgress.connect( # type: ignore[attr-defined]
@@ -56,19 +55,19 @@ class DownloadItem(downloads.AbstractDownloadItem):
def _is_page_download(self):
"""Check if this item is a page (i.e. mhtml) download."""
return (self._qt_item.savePageFormat() !=
- QWebEngineDownloadItem.UnknownSaveFormat)
+ QtWebEngineWidgets.QWebEngineDownloadItem.UnknownSaveFormat)
- @pyqtSlot(QWebEngineDownloadItem.DownloadState)
+ @QtCore.pyqtSlot(QtWebEngineWidgets.QWebEngineDownloadItem.DownloadState)
def _on_state_changed(self, state):
- state_name = debug.qenum_key(QWebEngineDownloadItem, state)
+ state_name = debug.qenum_key(QtWebEngineWidgets.QWebEngineDownloadItem, state)
log.downloads.debug("State for {!r} changed to {}".format(
self, state_name))
- if state == QWebEngineDownloadItem.DownloadRequested:
+ if state == QtWebEngineWidgets.QWebEngineDownloadItem.DownloadRequested:
pass
- elif state == QWebEngineDownloadItem.DownloadInProgress:
+ elif state == QtWebEngineWidgets.QWebEngineDownloadItem.DownloadInProgress:
pass
- elif state == QWebEngineDownloadItem.DownloadCompleted:
+ elif state == QtWebEngineWidgets.QWebEngineDownloadItem.DownloadCompleted:
log.downloads.debug("Download {} finished".format(self.basename))
if self._is_page_download():
# Same logging as QtWebKit mhtml downloads.
@@ -77,12 +76,12 @@ class DownloadItem(downloads.AbstractDownloadItem):
self.done = True
self.finished.emit()
self.stats.finish()
- elif state == QWebEngineDownloadItem.DownloadCancelled:
+ elif state == QtWebEngineWidgets.QWebEngineDownloadItem.DownloadCancelled:
self.successful = False
self.done = True
self.cancelled.emit()
self.stats.finish()
- elif state == QWebEngineDownloadItem.DownloadInterrupted:
+ elif state == QtWebEngineWidgets.QWebEngineDownloadItem.DownloadInterrupted:
self.successful = False
reason = self._qt_item.interruptReasonString()
self._die(reason)
@@ -93,22 +92,22 @@ class DownloadItem(downloads.AbstractDownloadItem):
def _do_die(self):
progress_signal = self._qt_item.downloadProgress
progress_signal.disconnect() # type: ignore[attr-defined]
- if self._qt_item.state() != QWebEngineDownloadItem.DownloadInterrupted:
+ if self._qt_item.state() != QtWebEngineWidgets.QWebEngineDownloadItem.DownloadInterrupted:
self._qt_item.cancel()
def _do_cancel(self):
state = self._qt_item.state()
- state_name = debug.qenum_key(QWebEngineDownloadItem, state)
- assert state not in [QWebEngineDownloadItem.DownloadCompleted,
- QWebEngineDownloadItem.DownloadCancelled], state_name
+ state_name = debug.qenum_key(QtWebEngineWidgets.QWebEngineDownloadItem, state)
+ assert state not in [QtWebEngineWidgets.QWebEngineDownloadItem.DownloadCompleted,
+ QtWebEngineWidgets.QWebEngineDownloadItem.DownloadCancelled], state_name
self._qt_item.cancel()
def retry(self):
state = self._qt_item.state()
- if state != QWebEngineDownloadItem.DownloadInterrupted:
+ if state != QtWebEngineWidgets.QWebEngineDownloadItem.DownloadInterrupted:
log.downloads.warning(
"Refusing to retry download in state {}".format(
- debug.qenum_key(QWebEngineDownloadItem, state)))
+ debug.qenum_key(QtWebEngineWidgets.QWebEngineDownloadItem, state)))
return
self._qt_item.resume()
@@ -116,12 +115,12 @@ class DownloadItem(downloads.AbstractDownloadItem):
def _get_open_filename(self):
return self._filename
- def url(self) -> QUrl:
+ def url(self) -> QtCore.QUrl:
return self._qt_item.url()
- def origin(self) -> QUrl:
+ def origin(self) -> QtCore.QUrl:
page = self._qt_item.page()
- return page.url() if page else QUrl()
+ return page.url() if page else QtCore.QUrl()
def _set_fileobj(self, fileobj, *, autoclose=True):
raise downloads.UnsupportedOperationError
@@ -133,8 +132,8 @@ class DownloadItem(downloads.AbstractDownloadItem):
def _ensure_can_set_filename(self, filename):
state = self._qt_item.state()
- if state != QWebEngineDownloadItem.DownloadRequested:
- state_name = debug.qenum_key(QWebEngineDownloadItem, state)
+ if state != QtWebEngineWidgets.QWebEngineDownloadItem.DownloadRequested:
+ state_name = debug.qenum_key(QtWebEngineWidgets.QWebEngineDownloadItem, state)
raise ValueError("Trying to set filename {} on {!r} which is "
"state {} (not in requested state)!".format(
filename, self, state_name))
@@ -247,9 +246,9 @@ class DownloadManager(downloads.AbstractDownloadManager):
def install(self, profile):
"""Set up the download manager on a QWebEngineProfile."""
profile.downloadRequested.connect(self.handle_download,
- Qt.DirectConnection)
+ QtCore.Qt.DirectConnection)
- @pyqtSlot(QWebEngineDownloadItem)
+ @QtCore.pyqtSlot(QtWebEngineWidgets.QWebEngineDownloadItem)
def handle_download(self, qt_item):
"""Start a download coming from a QWebEngineProfile."""
qt_filename = os.path.basename(qt_item.path()) # FIXME use 5.14 API
diff --git a/qutebrowser/browser/webengine/webengineelem.py b/qutebrowser/browser/webengine/webengineelem.py
index 5d4c6ad9a..8068e2278 100644
--- a/qutebrowser/browser/webengine/webengineelem.py
+++ b/qutebrowser/browser/webengine/webengineelem.py
@@ -21,13 +21,12 @@
from typing import (
TYPE_CHECKING, Any, Callable, Dict, Iterator, Optional, Set, Tuple, Union)
-
-from PyQt5.QtCore import QRect, QEventLoop
-from PyQt5.QtWidgets import QApplication
-from PyQt5.QtWebEngineWidgets import QWebEngineSettings
+from qutebrowser.qt import QtWidgets
+from qutebrowser.qt import QtWebEngineWidgets
from qutebrowser.utils import log, javascript, urlutils, usertypes, utils
from qutebrowser.browser import webelem
+from qutebrowser.qt import QtCore
if TYPE_CHECKING:
from qutebrowser.browser.webengine import webenginetab
@@ -114,9 +113,9 @@ class WebEngineElement(webelem.AbstractWebElement):
def has_frame(self) -> bool:
return True
- def geometry(self) -> QRect:
+ def geometry(self) -> QtCore.QRect:
log.stub()
- return QRect()
+ return QtCore.QRect()
def classes(self) -> Set[str]:
"""Get a list of classes assigned to this element."""
@@ -163,8 +162,8 @@ class WebEngineElement(webelem.AbstractWebElement):
log.webelem.debug("Inserting text into element {!r}".format(self))
self._js_call('insert_text', text)
- def rect_on_view(self, *, elem_geometry: QRect = None,
- no_js: bool = False) -> QRect:
+ def rect_on_view(self, *, elem_geometry: QtCore.QRect = None,
+ no_js: bool = False) -> QtCore.QRect:
"""Get the geometry of the element relative to the webview.
Skipping of small rectangles is due to <a> elements containing other
@@ -193,7 +192,7 @@ class WebEngineElement(webelem.AbstractWebElement):
# We're not checking for zoom.text_only here as that doesn't
# exist for QtWebEngine.
zoom = self._tab.zoom.factor()
- rect = QRect(int(left * zoom), int(top * zoom),
+ rect = QtCore.QRect(int(left * zoom), int(top * zoom),
int(width * zoom), int(height * zoom))
# FIXME:qtwebengine
# frame = self._elem.webFrame()
@@ -205,7 +204,7 @@ class WebEngineElement(webelem.AbstractWebElement):
return rect
log.webelem.debug("Couldn't find rectangle for {!r} ({})".format(
self, rects))
- return QRect()
+ return QtCore.QRect()
def remove_blank_target(self) -> None:
if self._js_dict['attributes'].get('target') == '_blank':
@@ -240,7 +239,7 @@ class WebEngineElement(webelem.AbstractWebElement):
view = self._tab._widget
assert view is not None
# pylint: enable=protected-access
- attribute = QWebEngineSettings.JavascriptCanOpenWindows
+ attribute = QtWebEngineWidgets.QWebEngineSettings.JavascriptCanOpenWindows
could_open_windows = view.settings().testAttribute(attribute)
view.settings().setAttribute(attribute, True)
@@ -248,9 +247,9 @@ class WebEngineElement(webelem.AbstractWebElement):
# (it does so with a 0ms QTimer...)
# This is also used in Qt's tests:
# https://github.com/qt/qtwebengine/commit/5e572e88efa7ba7c2b9138ec19e606d3e345ac90
- QApplication.processEvents( # type: ignore[call-overload]
- QEventLoop.ExcludeSocketNotifiers |
- QEventLoop.ExcludeUserInputEvents)
+ QtWidgets.QApplication.processEvents( # type: ignore[call-overload]
+ QtCore.QEventLoop.ExcludeSocketNotifiers |
+ QtCore.QEventLoop.ExcludeUserInputEvents)
def reset_setting(_arg: Any) -> None:
"""Set the JavascriptCanOpenWindows setting to its old value."""
diff --git a/qutebrowser/browser/webengine/webengineinspector.py b/qutebrowser/browser/webengine/webengineinspector.py
index ae31c0bee..a7384913a 100644
--- a/qutebrowser/browser/webengine/webengineinspector.py
+++ b/qutebrowser/browser/webengine/webengineinspector.py
@@ -21,9 +21,7 @@
import pathlib
-from PyQt5.QtCore import QLibraryInfo
-from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt import QtWidgets, QtWebEngineWidgets, QtCore
from qutebrowser.browser import inspector
from qutebrowser.browser.webengine import webenginesettings
@@ -32,7 +30,7 @@ from qutebrowser.utils import version, usertypes
from qutebrowser.keyinput import modeman
-class WebEngineInspectorView(QWebEngineView):
+class WebEngineInspectorView(QtWebEngineWidgets.QWebEngineView):
"""The QWebEngineView used for the inspector.
@@ -41,7 +39,7 @@ class WebEngineInspectorView(QWebEngineView):
"""
def createWindow(self,
- wintype: QWebEnginePage.WebWindowType) -> QWebEngineView:
+ wintype: QtWebEngineWidgets.QWebEnginePage.WebWindowType) -> QtWebEngineWidgets.QWebEngineView:
"""Called by Qt when a page wants to create a new tab or window.
In case the user wants to open a resource in a new tab, we use the
@@ -58,7 +56,7 @@ class WebEngineInspector(inspector.AbstractWebInspector):
def __init__(self, splitter: miscwidgets.InspectorSplitter,
win_id: int,
- parent: QWidget = None) -> None:
+ parent: QtWidgets.QWidget = None) -> None:
super().__init__(splitter, win_id, parent)
self._check_devtools_resources()
@@ -89,14 +87,14 @@ class WebEngineInspector(inspector.AbstractWebInspector):
if dist is None or dist.parsed != version.Distribution.fedora:
return
- data_path = pathlib.Path(QLibraryInfo.location(QLibraryInfo.DataPath))
+ data_path = pathlib.Path(QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.DataPath))
pak = data_path / 'resources' / 'qtwebengine_devtools_resources.pak'
if not pak.exists():
raise inspector.Error("QtWebEngine devtools resources not found, "
"please install the qt5-qtwebengine-devtools "
"Fedora package.")
- def inspect(self, page: QWebEnginePage) -> None: # type: ignore[override]
+ def inspect(self, page: QtWebEngineWidgets.QWebEnginePage) -> None: # type: ignore[override]
inspector_page = self._widget.page()
inspector_page.setInspectedPage(page)
self._settings.update_for_url(inspector_page.requestedUrl())
diff --git a/qutebrowser/browser/webengine/webenginequtescheme.py b/qutebrowser/browser/webengine/webenginequtescheme.py
index 64361f7c4..0a21d967f 100644
--- a/qutebrowser/browser/webengine/webenginequtescheme.py
+++ b/qutebrowser/browser/webengine/webenginequtescheme.py
@@ -19,23 +19,19 @@
"""QtWebEngine specific qute://* handlers and glue code."""
-from PyQt5.QtCore import QBuffer, QIODevice, QUrl
-from PyQt5.QtWebEngineCore import (QWebEngineUrlSchemeHandler,
- QWebEngineUrlRequestJob,
- QWebEngineUrlScheme)
-
from qutebrowser.browser import qutescheme
from qutebrowser.utils import log, qtutils
+from qutebrowser.qt import QtWebEngineCore, QtCore
-class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
+class QuteSchemeHandler(QtWebEngineCore.QWebEngineUrlSchemeHandler):
"""Handle qute://* requests on QtWebEngine."""
def install(self, profile):
"""Install the handler for qute:// URLs on the given profile."""
- if QWebEngineUrlScheme is not None:
- assert QWebEngineUrlScheme.schemeByName(b'qute') is not None
+ if QtWebEngineCore.QWebEngineUrlScheme is not None:
+ assert QtWebEngineCore.QWebEngineUrlScheme.schemeByName(b'qute') is not None
profile.installUrlSchemeHandler(b'qute', self)
@@ -55,7 +51,7 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
request_url = job.requestUrl()
# https://codereview.qt-project.org/#/c/234849/
- is_opaque = initiator == QUrl('null')
+ is_opaque = initiator == QtCore.QUrl('null')
target = request_url.scheme(), request_url.host()
if target == ('qute', 'testdata') and is_opaque:
@@ -67,7 +63,7 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
log.network.warning("Blocking malicious request from {} to {}"
.format(initiator.toDisplayString(),
request_url.toDisplayString()))
- job.fail(QWebEngineUrlRequestJob.RequestDenied)
+ job.fail(QtWebEngineCore.QWebEngineUrlRequestJob.RequestDenied)
return False
return True
@@ -87,7 +83,7 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
return
if job.requestMethod() != b'GET':
- job.fail(QWebEngineUrlRequestJob.RequestDenied)
+ job.fail(QtWebEngineCore.QWebEngineUrlRequestJob.RequestDenied)
return
assert url.scheme() == 'qute'
@@ -98,15 +94,15 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
except qutescheme.Error as e:
errors = {
qutescheme.NotFoundError:
- QWebEngineUrlRequestJob.UrlNotFound,
+ QtWebEngineCore.QWebEngineUrlRequestJob.UrlNotFound,
qutescheme.UrlInvalidError:
- QWebEngineUrlRequestJob.UrlInvalid,
+ QtWebEngineCore.QWebEngineUrlRequestJob.UrlInvalid,
qutescheme.RequestDeniedError:
- QWebEngineUrlRequestJob.RequestDenied,
+ QtWebEngineCore.QWebEngineUrlRequestJob.RequestDenied,
qutescheme.SchemeOSError:
- QWebEngineUrlRequestJob.UrlNotFound,
+ QtWebEngineCore.QWebEngineUrlRequestJob.UrlNotFound,
qutescheme.Error:
- QWebEngineUrlRequestJob.RequestFailed,
+ QtWebEngineCore.QWebEngineUrlRequestJob.RequestFailed,
}
exctype = type(e)
log.network.error(f"{exctype.__name__} while handling qute://* URL: {e}")
@@ -120,8 +116,8 @@ class QuteSchemeHandler(QWebEngineUrlSchemeHandler):
# We can't just use the QBuffer constructor taking a QByteArray,
# because that somehow segfaults...
# https://www.riverbankcomputing.com/pipermail/pyqt/2016-September/038075.html
- buf = QBuffer(parent=self)
- buf.open(QIODevice.WriteOnly)
+ buf = QtCore.QBuffer(parent=self)
+ buf.open(QtCore.QIODevice.WriteOnly)
buf.write(data)
buf.seek(0)
buf.close()
@@ -134,10 +130,10 @@ def init():
Note this needs to be called early, before constructing any QtWebEngine
classes.
"""
- if QWebEngineUrlScheme is not None:
- assert not QWebEngineUrlScheme.schemeByName(b'qute').name()
- scheme = QWebEngineUrlScheme(b'qute')
+ if QtWebEngineCore.QWebEngineUrlScheme is not None:
+ assert not QtWebEngineCore.QWebEngineUrlScheme.schemeByName(b'qute').name()
+ scheme = QtWebEngineCore.QWebEngineUrlScheme(b'qute')
scheme.setFlags(
- QWebEngineUrlScheme.LocalScheme | # type: ignore[arg-type]
- QWebEngineUrlScheme.LocalAccessAllowed)
- QWebEngineUrlScheme.registerScheme(scheme)
+ QtWebEngineCore.QWebEngineUrlScheme.LocalScheme | # type: ignore[arg-type]
+ QtWebEngineCore.QWebEngineUrlScheme.LocalAccessAllowed)
+ QtWebEngineCore.QWebEngineUrlScheme.registerScheme(scheme)
diff --git a/qutebrowser/browser/webengine/webenginesettings.py b/qutebrowser/browser/webengine/webenginesettings.py
index 5430cec77..55cbd3f08 100644
--- a/qutebrowser/browser/webengine/webenginesettings.py
+++ b/qutebrowser/browser/webengine/webenginesettings.py
@@ -28,9 +28,7 @@ import os
import operator
from typing import cast, Any, List, Optional, Tuple, Union, TYPE_CHECKING
-from PyQt5.QtGui import QFont
-from PyQt5.QtWidgets import QApplication
-from PyQt5.QtWebEngineWidgets import QWebEngineSettings, QWebEngineProfile
+from qutebrowser.qt import QtWidgets, QtWebEngineWidgets, QtGui
from qutebrowser.browser import history
from qutebrowser.browser.webengine import (spell, webenginequtescheme, cookies,
@@ -43,9 +41,9 @@ if TYPE_CHECKING:
from qutebrowser.browser.webengine import interceptor
# The default QWebEngineProfile
-default_profile = cast(QWebEngineProfile, None)
+default_profile = cast(QtWebEngineWidgets.QWebEngineProfile, None)
# The QWebEngineProfile used for private (off-the-record) windows
-private_profile: Optional[QWebEngineProfile] = None
+private_profile: Optional[QtWebEngineWidgets.QWebEngineProfile] = None
# The global WebEngineSettings object
_global_settings = cast('WebEngineSettings', None)
@@ -110,93 +108,93 @@ class WebEngineSettings(websettings.AbstractSettings):
_ATTRIBUTES = {
'content.xss_auditing':
- Attr(QWebEngineSettings.XSSAuditingEnabled),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.XSSAuditingEnabled),
'content.images':
- Attr(QWebEngineSettings.AutoLoadImages),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.AutoLoadImages),
'content.javascript.enabled':
- Attr(QWebEngineSettings.JavascriptEnabled),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.JavascriptEnabled),
'content.javascript.can_open_tabs_automatically':
- Attr(QWebEngineSettings.JavascriptCanOpenWindows),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.JavascriptCanOpenWindows),
'content.javascript.can_access_clipboard':
- Attr(QWebEngineSettings.JavascriptCanAccessClipboard),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.JavascriptCanAccessClipboard),
'content.plugins':
- Attr(QWebEngineSettings.PluginsEnabled),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.PluginsEnabled),
'content.hyperlink_auditing':
- Attr(QWebEngineSettings.HyperlinkAuditingEnabled),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.HyperlinkAuditingEnabled),
'content.local_content_can_access_remote_urls':
- Attr(QWebEngineSettings.LocalContentCanAccessRemoteUrls),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.LocalContentCanAccessRemoteUrls),
'content.local_content_can_access_file_urls':
- Attr(QWebEngineSettings.LocalContentCanAccessFileUrls),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.LocalContentCanAccessFileUrls),
'content.webgl':
- Attr(QWebEngineSettings.WebGLEnabled),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.WebGLEnabled),
'content.local_storage':
- Attr(QWebEngineSettings.LocalStorageEnabled),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.LocalStorageEnabled),
'content.desktop_capture':
- Attr(QWebEngineSettings.ScreenCaptureEnabled,
+ Attr(QtWebEngineWidgets.QWebEngineSettings.ScreenCaptureEnabled,
converter=lambda val: True if val == 'ask' else val),
# 'ask' is handled via the permission system
'input.spatial_navigation':
- Attr(QWebEngineSettings.SpatialNavigationEnabled),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.SpatialNavigationEnabled),
'input.links_included_in_focus_chain':
- Attr(QWebEngineSettings.LinksIncludedInFocusChain),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.LinksIncludedInFocusChain),
'scrolling.smooth':
- Attr(QWebEngineSettings.ScrollAnimatorEnabled),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.ScrollAnimatorEnabled),
'content.print_element_backgrounds':
- Attr(QWebEngineSettings.PrintElementBackgrounds),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.PrintElementBackgrounds),
'content.autoplay':
- Attr(QWebEngineSettings.PlaybackRequiresUserGesture,
+ Attr(QtWebEngineWidgets.QWebEngineSettings.PlaybackRequiresUserGesture,
converter=operator.not_),
'content.dns_prefetch':
- Attr(QWebEngineSettings.DnsPrefetchEnabled),
+ Attr(QtWebEngineWidgets.QWebEngineSettings.DnsPrefetchEnabled),
'tabs.favicons.show':
- Attr(QWebEngineSettings.AutoLoadIconsForPage,
+ Attr(QtWebEngineWidgets.QWebEngineSettings.AutoLoadIconsForPage,
converter=lambda val: val != 'never'),
}
_FONT_SIZES = {
'fonts.web.size.minimum':
- QWebEngineSettings.MinimumFontSize,
+ QtWebEngineWidgets.QWebEngineSettings.MinimumFontSize,
'fonts.web.size.minimum_logical':
- QWebEngineSettings.MinimumLogicalFontSize,
+ QtWebEngineWidgets.QWebEngineSettings.MinimumLogicalFontSize,
'fonts.web.size.default':
- QWebEngineSettings.DefaultFontSize,
+ QtWebEngineWidgets.QWebEngineSettings.DefaultFontSize,
'fonts.web.size.default_fixed':
- QWebEngineSettings.DefaultFixedFontSize,
+ QtWebEngineWidgets.QWebEngineSettings.DefaultFixedFontSize,
}
_FONT_FAMILIES = {
- 'fonts.web.family.standard': QWebEngineSettings.StandardFont,
- 'fonts.web.family.fixed': QWebEngineSettings.FixedFont,
- 'fonts.web.family.serif': QWebEngineSettings.SerifFont,
- 'fonts.web.family.sans_serif': QWebEngineSettings.SansSerifFont,
- 'fonts.web.family.cursive': QWebEngineSettings.CursiveFont,
- 'fonts.web.family.fantasy': QWebEngineSettings.FantasyFont,
+ 'fonts.web.family.standard': QtWebEngineWidgets.QWebEngineSettings.StandardFont,
+ 'fonts.web.family.fixed': QtWebEngineWidgets.QWebEngineSettings.FixedFont,
+ 'fonts.web.family.serif': QtWebEngineWidgets.QWebEngineSettings.SerifFont,
+ 'fonts.web.family.sans_serif': QtWebEngineWidgets.QWebEngineSettings.SansSerifFont,
+ 'fonts.web.family.cursive': QtWebEngineWidgets.QWebEngineSettings.CursiveFont,
+ 'fonts.web.family.fantasy': QtWebEngineWidgets.QWebEngineSettings.FantasyFont,
}
_UNKNOWN_URL_SCHEME_POLICY = {
'disallow':
- QWebEngineSettings.DisallowUnknownUrlSchemes,
+ QtWebEngineWidgets.QWebEngineSettings.DisallowUnknownUrlSchemes,
'allow-from-user-interaction':
- QWebEngineSettings.AllowUnknownUrlSchemesFromUserInteraction,
+ QtWebEngineWidgets.QWebEngineSettings.AllowUnknownUrlSchemesFromUserInteraction,
'allow-all':
- QWebEngineSettings.AllowAllUnknownUrlSchemes,
+ QtWebEngineWidgets.QWebEngineSettings.AllowAllUnknownUrlSchemes,
}
# Mapping from WebEngineSettings::initDefaults in
# qtwebengine/src/core/web_engine_settings.cpp
_FONT_TO_QFONT = {
- QWebEngineSettings.StandardFont: QFont.Serif,
- QWebEngineSettings.FixedFont: QFont.Monospace,
- QWebEngineSettings.SerifFont: QFont.Serif,
- QWebEngineSettings.SansSerifFont: QFont.SansSerif,
- QWebEngineSettings.CursiveFont: QFont.Cursive,
- QWebEngineSettings.FantasyFont: QFont.Fantasy,
+ QtWebEngineWidgets.QWebEngineSettings.StandardFont: QtGui.QFont.Serif,
+ QtWebEngineWidgets.QWebEngineSettings.FixedFont: QtGui.QFont.Monospace,
+ QtWebEngineWidgets.QWebEngineSettings.SerifFont: QtGui.QFont.Serif,
+ QtWebEngineWidgets.QWebEngineSettings.SansSerifFont: QtGui.QFont.SansSerif,
+ QtWebEngineWidgets.QWebEngineSettings.CursiveFont: QtGui.QFont.Cursive,
+ QtWebEngineWidgets.QWebEngineSettings.FantasyFont: QtGui.QFont.Fantasy,
}
def set_unknown_url_scheme_policy(
@@ -265,12 +263,12 @@ class ProfileSetter:
settings = self._profile.settings()
settings.setAttribute(
- QWebEngineSettings.FullScreenSupportEnabled, True)
+ QtWebEngineWidgets.QWebEngineSettings.FullScreenSupportEnabled, True)
settings.setAttribute(
- QWebEngineSettings.FocusOnNavigationEnabled, False)
+ QtWebEngineWidgets.QWebEngineSettings.FocusOnNavigationEnabled, False)
try:
- settings.setAttribute(QWebEngineSettings.PdfViewerEnabled, False)
+ settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.PdfViewerEnabled, False)
except AttributeError:
# Added in Qt 5.13
pass
@@ -305,9 +303,9 @@ class ProfileSetter:
if self._profile.isOffTheRecord():
return
if config.val.content.cookies.store:
- value = QWebEngineProfile.AllowPersistentCookies
+ value = QtWebEngineWidgets.QWebEngineProfile.AllowPersistentCookies
else:
- value = QWebEngineProfile.NoPersistentCookies
+ value = QtWebEngineWidgets.QWebEngineProfile.NoPersistentCookies
self._profile.setPersistentCookiesPolicy(value)
def set_dictionary_language(self):
@@ -343,10 +341,10 @@ def _init_user_agent_str(ua):
def init_user_agent():
- _init_user_agent_str(QWebEngineProfile.defaultProfile().httpUserAgent())
+ _init_user_agent_str(QtWebEngineWidgets.QWebEngineProfile.defaultProfile().httpUserAgent())
-def _init_profile(profile: QWebEngineProfile) -> None:
+def _init_profile(profile: QtWebEngineWidgets.QWebEngineProfile) -> None:
"""Initialize a new QWebEngineProfile.
This currently only contains the steps which are shared between a private and a
@@ -375,7 +373,7 @@ def _init_default_profile():
"""Init the default QWebEngineProfile."""
global default_profile
- default_profile = QWebEngineProfile.defaultProfile()
+ default_profile = QtWebEngineWidgets.QWebEngineProfile.defaultProfile()
assert parsed_user_agent is None # avoid earlier profile initialization
non_ua_version = version.qtwebengine_versions(avoid_init=True)
@@ -404,7 +402,7 @@ def init_private_profile():
if qtutils.is_single_process():
return
- private_profile = QWebEngineProfile()
+ private_profile = QtWebEngineWidgets.QWebEngineProfile()
assert private_profile.isOffTheRecord()
_init_profile(private_profile)
@@ -491,7 +489,7 @@ def init():
# won't work...
# https://www.riverbankcomputing.com/pipermail/pyqt/2016-September/038075.html
global _qute_scheme_handler
- app = QApplication.instance()
+ app = QtWidgets.QApplication.instance()
log.init.debug("Initializing qute://* handler...")
_qute_scheme_handler = webenginequtescheme.QuteSchemeHandler(parent=app)
diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py
index 7d355d10e..a0a83d7a7 100644
--- a/qutebrowser/browser/webengine/webenginetab.py
+++ b/qutebrowser/browser/webengine/webenginetab.py
@@ -25,12 +25,7 @@ import dataclasses
import re
import html as html_utils
from typing import cast, Union, Optional
-
-from PyQt5.QtCore import (pyqtSignal, pyqtSlot, Qt, QPoint, QPointF, QTimer, QUrl,
- QObject)
-from PyQt5.QtNetwork import QAuthenticator
-from PyQt5.QtWidgets import QWidget
-from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineScript, QWebEngineHistory
+from qutebrowser.qt import QtWidgets, QtWebEngineWidgets, QtWebEngineCore, QtNetwork
from qutebrowser.config import config
from qutebrowser.browser import browsertab, eventfilter, shared, webelem, greasemonkey
@@ -40,16 +35,16 @@ from qutebrowser.browser.webengine import (webview, webengineelem, tabhistory,
from qutebrowser.utils import (usertypes, qtutils, log, javascript, utils,
resources, message, jinja, debug, version)
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
from qutebrowser.misc import objects, miscwidgets
# Mapping worlds from usertypes.JsWorld to QWebEngineScript world IDs.
_JS_WORLD_MAP = {
- usertypes.JsWorld.main: QWebEngineScript.MainWorld,
- usertypes.JsWorld.application: QWebEngineScript.ApplicationWorld,
- usertypes.JsWorld.user: QWebEngineScript.UserWorld,
- usertypes.JsWorld.jseval: QWebEngineScript.UserWorld + 1,
+ usertypes.JsWorld.main: QtWebEngineWidgets.QWebEngineScript.MainWorld,
+ usertypes.JsWorld.application: QtWebEngineWidgets.QWebEngineScript.ApplicationWorld,
+ usertypes.JsWorld.user: QtWebEngineWidgets.QWebEngineScript.UserWorld,
+ usertypes.JsWorld.jseval: QtWebEngineWidgets.QWebEngineScript.UserWorld + 1,
}
@@ -57,22 +52,22 @@ class WebEngineAction(browsertab.AbstractAction):
"""QtWebEngine implementations related to web actions."""
- action_class = QWebEnginePage
- action_base = QWebEnginePage.WebAction
+ action_class = QtWebEngineWidgets.QWebEnginePage
+ action_base = QtWebEngineWidgets.QWebEnginePage.WebAction
def exit_fullscreen(self):
- self._widget.triggerPageAction(QWebEnginePage.ExitFullScreen)
+ self._widget.triggerPageAction(QtWebEngineWidgets.QWebEnginePage.ExitFullScreen)
def save_page(self):
"""Save the current page."""
- self._widget.triggerPageAction(QWebEnginePage.SavePage)
+ self._widget.triggerPageAction(QtWebEngineWidgets.QWebEnginePage.SavePage)
def show_source(self, pygments=False):
if pygments:
self._show_source_pygments()
return
- self._widget.triggerPageAction(QWebEnginePage.ViewSource)
+ self._widget.triggerPageAction(QtWebEngineWidgets.QWebEnginePage.ViewSource)
class WebEnginePrinting(browsertab.AbstractPrinting):
@@ -125,8 +120,7 @@ class _WebEngineSearchWrapHandler:
return
try:
- # pylint: disable=unused-import
- from PyQt5.QtWebEngineCore import QWebEngineFindTextResult
+ pass
except ImportError:
# WORKAROUND for some odd PyQt/packaging bug where the
# findTextResult signal is available, but QWebEngineFindTextResult
@@ -199,14 +193,14 @@ class WebEngineSearch(browsertab.AbstractSearch):
self._wrap_handler = _WebEngineSearchWrapHandler()
def _empty_flags(self):
- return QWebEnginePage.FindFlags(0) # type: ignore[call-overload]
+ return QtWebEngineWidgets.QWebEnginePage.FindFlags(0) # type: ignore[call-overload]
def _args_to_flags(self, reverse, ignore_case):
flags = self._empty_flags()
if self._is_case_sensitive(ignore_case):
- flags |= QWebEnginePage.FindCaseSensitively
+ flags |= QtWebEngineWidgets.QWebEnginePage.FindCaseSensitively
if reverse:
- flags |= QWebEnginePage.FindBackward
+ flags |= QtWebEngineWidgets.QWebEnginePage.FindBackward
return flags
def connect_signals(self):
@@ -238,7 +232,7 @@ class WebEngineSearch(browsertab.AbstractSearch):
found_text = 'found' if found else "didn't find"
if flags:
flag_text = 'with flags {}'.format(debug.qflags_key(
- QWebEnginePage, flags, klass=QWebEnginePage.FindFlag))
+ QtWebEngineWidgets.QWebEnginePage, flags, klass=QtWebEngineWidgets.QWebEnginePage.FindFlag))
else:
flag_text = ''
log.webview.debug(' '.join([caller, found_text, text, flag_text])
@@ -275,20 +269,20 @@ class WebEngineSearch(browsertab.AbstractSearch):
def prev_result(self, *, result_cb=None):
# The int() here makes sure we get a copy of the flags.
- flags = QWebEnginePage.FindFlags(
+ flags = QtWebEngineWidgets.QWebEnginePage.FindFlags(
int(self._flags)) # type: ignore[call-overload]
- if flags & QWebEnginePage.FindBackward:
+ if flags & QtWebEngineWidgets.QWebEnginePage.FindBackward:
if self._wrap_handler.prevent_wrapping(going_up=False):
return
- flags &= ~QWebEnginePage.FindBackward
+ flags &= ~QtWebEngineWidgets.QWebEnginePage.FindBackward
else:
if self._wrap_handler.prevent_wrapping(going_up=True):
return
- flags |= QWebEnginePage.FindBackward
+ flags |= QtWebEngineWidgets.QWebEnginePage.FindBackward
self._find(self.text, flags, result_cb, 'prev_result')
def next_result(self, *, result_cb=None):
- going_up = self._flags & QWebEnginePage.FindBackward
+ going_up = self._flags & QtWebEngineWidgets.QWebEnginePage.FindBackward
if self._wrap_handler.prevent_wrapping(going_up=going_up):
return
self._find(self.text, self._flags, result_cb, 'next_result')
@@ -307,7 +301,7 @@ class WebEngineCaret(browsertab.AbstractCaret):
flags.add('windows')
return list(flags)
- @pyqtSlot(usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode)
def _on_mode_entered(self, mode):
if mode != usertypes.KeyMode.caret:
return
@@ -335,7 +329,7 @@ class WebEngineCaret(browsertab.AbstractCaret):
else:
self.selection_toggled.emit(browsertab.SelectionState.none)
- @pyqtSlot(usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode)
def _on_mode_left(self, mode):
if mode != usertypes.KeyMode.caret:
return
@@ -496,7 +490,7 @@ class WebEngineScroller(browsertab.AbstractScroller):
def __init__(self, tab, parent=None):
super().__init__(tab, parent)
self._pos_perc = (0, 0)
- self._pos_px = QPoint()
+ self._pos_px = QtCore.QPoint()
self._at_bottom = False
def _init_widget(self, widget):
@@ -504,12 +498,12 @@ class WebEngineScroller(browsertab.AbstractScroller):
page = widget.page()
page.scrollPositionChanged.connect(self._update_pos)
- def _repeated_key_press(self, key, count=1, modifier=Qt.NoModifier):
+ def _repeated_key_press(self, key, count=1, modifier=QtCore.Qt.NoModifier):
"""Send count fake key presses to this scroller's WebEngineTab."""
for _ in range(min(count, 1000)):
self._tab.fake_key_press(key, modifier)
- @pyqtSlot(QPointF)
+ @QtCore.pyqtSlot(QtCore.QPointF)
def _update_pos(self, pos):
"""Update the scroll position attributes when it changed."""
self._pos_px = pos.toPoint()
@@ -583,28 +577,28 @@ class WebEngineScroller(browsertab.AbstractScroller):
self._tab.run_js_async(js_code)
def up(self, count=1):
- self._repeated_key_press(Qt.Key_Up, count)
+ self._repeated_key_press(QtCore.Qt.Key_Up, count)
def down(self, count=1):
- self._repeated_key_press(Qt.Key_Down, count)
+ self._repeated_key_press(QtCore.Qt.Key_Down, count)
def left(self, count=1):
- self._repeated_key_press(Qt.Key_Left, count)
+ self._repeated_key_press(QtCore.Qt.Key_Left, count)
def right(self, count=1):
- self._repeated_key_press(Qt.Key_Right, count)
+ self._repeated_key_press(QtCore.Qt.Key_Right, count)
def top(self):
- self._tab.fake_key_press(Qt.Key_Home)
+ self._tab.fake_key_press(QtCore.Qt.Key_Home)
def bottom(self):
- self._tab.fake_key_press(Qt.Key_End)
+ self._tab.fake_key_press(QtCore.Qt.Key_End)
def page_up(self, count=1):
- self._repeated_key_press(Qt.Key_PageUp, count)
+ self._repeated_key_press(QtCore.Qt.Key_PageUp, count)
def page_down(self, count=1):
- self._repeated_key_press(Qt.Key_PageDown, count)
+ self._repeated_key_press(QtCore.Qt.Key_PageDown, count)
def at_top(self):
return self.pos_px().y() == 0
@@ -619,7 +613,7 @@ class WebEngineHistoryPrivate(browsertab.AbstractHistoryPrivate):
def __init__(self, tab: 'WebEngineTab') -> None:
self._tab = tab
- self._history = cast(QWebEngineHistory, None)
+ self._history = cast(QtWebEngineWidgets.QWebEngineHistory, None)
def serialize(self):
return qtutils.serialize(self._history)
@@ -659,7 +653,7 @@ class WebEngineHistoryPrivate(browsertab.AbstractHistoryPrivate):
stream, _data, cur_data = tabhistory.serialize(items)
qtutils.deserialize_stream(stream, self._history)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_load_finished():
self._tab.scroller.to_point(cur_data['scroll-pos'])
self._tab.load_finished.disconnect(_on_load_finished)
@@ -668,7 +662,7 @@ class WebEngineHistoryPrivate(browsertab.AbstractHistoryPrivate):
if 'zoom' in cur_data:
self._tab.zoom.set_factor(cur_data['zoom'])
if ('scroll-pos' in cur_data and
- self._tab.scroller.pos_px() == QPoint(0, 0)):
+ self._tab.scroller.pos_px() == QtCore.QPoint(0, 0)):
self._tab.load_finished.connect(_on_load_finished)
@@ -806,7 +800,7 @@ class WebEngineAudio(browsertab.AbstractAudio):
# Implements the intended two-second delay specified at
# https://doc.qt.io/qt-5/qwebenginepage.html#recentlyAudibleChanged
delay_ms = 2000
- self._silence_timer = QTimer(self)
+ self._silence_timer = QtCore.QTimer(self)
self._silence_timer.setSingleShot(True)
self._silence_timer.setInterval(delay_ms)
@@ -854,7 +848,7 @@ class WebEngineAudio(browsertab.AbstractAudio):
page = self._widget.page()
return page.recentlyAudible()
- @pyqtSlot(QUrl)
+ @QtCore.pyqtSlot(QtCore.QUrl)
def _on_url_changed(self, url):
if self._overridden or not url.isValid():
return
@@ -866,7 +860,7 @@ class WebEngineAudio(browsertab.AbstractAudio):
self._on_url_changed(self._tab.url())
-class _WebEnginePermissions(QObject):
+class _WebEnginePermissions(QtCore.QObject):
"""Handling of various permission-related signals."""
@@ -875,30 +869,30 @@ class _WebEnginePermissions(QObject):
_options = {
0: 'content.notifications.enabled',
- QWebEnginePage.Geolocation: 'content.geolocation',
- QWebEnginePage.MediaAudioCapture: 'content.media.audio_capture',
- QWebEnginePage.MediaVideoCapture: 'content.media.video_capture',
- QWebEnginePage.MediaAudioVideoCapture: 'content.media.audio_video_capture',
- QWebEnginePage.MouseLock: 'content.mouse_lock',
- QWebEnginePage.DesktopVideoCapture: 'content.desktop_capture',
- QWebEnginePage.DesktopAudioVideoCapture: 'content.desktop_capture',
+ QtWebEngineWidgets.QWebEnginePage.Geolocation: 'content.geolocation',
+ QtWebEngineWidgets.QWebEnginePage.MediaAudioCapture: 'content.media.audio_capture',
+ QtWebEngineWidgets.QWebEnginePage.MediaVideoCapture: 'content.media.video_capture',
+ QtWebEngineWidgets.QWebEnginePage.MediaAudioVideoCapture: 'content.media.audio_video_capture',
+ QtWebEngineWidgets.QWebEnginePage.MouseLock: 'content.mouse_lock',
+ QtWebEngineWidgets.QWebEnginePage.DesktopVideoCapture: 'content.desktop_capture',
+ QtWebEngineWidgets.QWebEnginePage.DesktopAudioVideoCapture: 'content.desktop_capture',
}
_messages = {
0: 'show notifications',
- QWebEnginePage.Geolocation: 'access your location',
- QWebEnginePage.MediaAudioCapture: 'record audio',
- QWebEnginePage.MediaVideoCapture: 'record video',
- QWebEnginePage.MediaAudioVideoCapture: 'record audio/video',
- QWebEnginePage.MouseLock: 'hide your mouse pointer',
- QWebEnginePage.DesktopVideoCapture: 'capture your desktop',
- QWebEnginePage.DesktopAudioVideoCapture: 'capture your desktop and audio',
+ QtWebEngineWidgets.QWebEnginePage.Geolocation: 'access your location',
+ QtWebEngineWidgets.QWebEnginePage.MediaAudioCapture: 'record audio',
+ QtWebEngineWidgets.QWebEnginePage.MediaVideoCapture: 'record video',
+ QtWebEngineWidgets.QWebEnginePage.MediaAudioVideoCapture: 'record audio/video',
+ QtWebEngineWidgets.QWebEnginePage.MouseLock: 'hide your mouse pointer',
+ QtWebEngineWidgets.QWebEnginePage.DesktopVideoCapture: 'capture your desktop',
+ QtWebEngineWidgets.QWebEnginePage.DesktopAudioVideoCapture: 'capture your desktop and audio',
}
def __init__(self, tab, parent=None):
super().__init__(parent)
self._tab = tab
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
assert self._options.keys() == self._messages.keys()
def connect_signals(self):
@@ -913,7 +907,7 @@ class _WebEnginePermissions(QObject):
page.registerProtocolHandlerRequested.connect(
self._on_register_protocol_handler_requested)
- @pyqtSlot('QWebEngineFullScreenRequest')
+ @QtCore.pyqtSlot('QWebEngineFullScreenRequest')
def _on_fullscreen_requested(self, request):
request.accept()
on = request.toggleOn()
@@ -927,18 +921,18 @@ class _WebEnginePermissions(QObject):
notif.set_timeout(timeout)
notif.show()
- @pyqtSlot(QUrl, 'QWebEnginePage::Feature')
+ @QtCore.pyqtSlot(QtCore.QUrl, 'QWebEnginePage::Feature')
def _on_feature_permission_requested(self, url, feature):
"""Ask the user for approval for geolocation/media/etc.."""
page = self._widget.page()
grant_permission = functools.partial(
page.setFeaturePermission, url, feature,
- QWebEnginePage.PermissionGrantedByUser)
+ QtWebEngineWidgets.QWebEnginePage.PermissionGrantedByUser)
deny_permission = functools.partial(
page.setFeaturePermission, url, feature,
- QWebEnginePage.PermissionDeniedByUser)
+ QtWebEngineWidgets.QWebEnginePage.PermissionDeniedByUser)
- permission_str = debug.qenum_key(QWebEnginePage, feature)
+ permission_str = debug.qenum_key(QtWebEngineWidgets.QWebEnginePage, feature)
if not url.isValid():
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-85116
@@ -946,7 +940,7 @@ class _WebEnginePermissions(QObject):
compiled=False,
exact=True) and
self._tab.is_private and
- feature == QWebEnginePage.Notifications)
+ feature == QtWebEngineWidgets.QWebEnginePage.Notifications)
logger = log.webview.debug if is_qtbug else log.webview.warning
logger("Ignoring feature permission {} for invalid URL {}".format(
permission_str, url))
@@ -960,8 +954,8 @@ class _WebEnginePermissions(QObject):
return
if (
- feature in [QWebEnginePage.DesktopVideoCapture,
- QWebEnginePage.DesktopAudioVideoCapture] and
+ feature in [QtWebEngineWidgets.QWebEnginePage.DesktopVideoCapture,
+ QtWebEngineWidgets.QWebEnginePage.DesktopAudioVideoCapture] and
qtutils.version_check('5.13', compiled=False) and
not qtutils.version_check('5.13.2', compiled=False)
):
@@ -972,7 +966,7 @@ class _WebEnginePermissions(QObject):
return
question = shared.feature_permission(
- url=url.adjusted(QUrl.RemovePath),
+ url=url.adjusted(QtCore.QUrl.RemovePath),
option=self._options[feature], msg=self._messages[feature],
yes_action=grant_permission, no_action=deny_permission,
abort_on=[self._tab.abort_questions])
@@ -999,7 +993,7 @@ class _WebEnginePermissions(QObject):
def _on_quota_requested(self, request):
size = utils.format_size(request.requestedSize())
shared.feature_permission(
- url=request.origin().adjusted(QUrl.RemovePath),
+ url=request.origin().adjusted(QtCore.QUrl.RemovePath),
option='content.persistent_storage',
msg='use {} of persistent storage'.format(size),
yes_action=request.accept, no_action=request.reject,
@@ -1008,7 +1002,7 @@ class _WebEnginePermissions(QObject):
def _on_register_protocol_handler_requested(self, request):
shared.feature_permission(
- url=request.origin().adjusted(QUrl.RemovePath),
+ url=request.origin().adjusted(QtCore.QUrl.RemovePath),
option='content.register_protocol_handler',
msg='open all {} links'.format(request.scheme()),
yes_action=request.accept, no_action=request.reject,
@@ -1020,9 +1014,9 @@ class _WebEnginePermissions(QObject):
class _Quirk:
filename: str
- injection_point: QWebEngineScript.InjectionPoint = (
- QWebEngineScript.DocumentCreation)
- world: QWebEngineScript.ScriptWorldId = QWebEngineScript.MainWorld
+ injection_point: QtWebEngineWidgets.QWebEngineScript.InjectionPoint = (
+ QtWebEngineWidgets.QWebEngineScript.DocumentCreation)
+ world: QtWebEngineWidgets.QWebEngineScript.ScriptWorldId = QtWebEngineWidgets.QWebEngineScript.MainWorld
predicate: bool = True
name: Optional[str] = None
@@ -1031,12 +1025,12 @@ class _Quirk:
self.name = f"js-{self.filename.replace('_', '-')}"
-class _WebEngineScripts(QObject):
+class _WebEngineScripts(QtCore.QObject):
def __init__(self, tab, parent=None):
super().__init__(parent)
self._tab = tab
- self._widget = cast(QWidget, None)
+ self._widget = cast(QtWidgets.QWidget, None)
self._greasemonkey = greasemonkey.gm_manager
def connect_signals(self):
@@ -1047,13 +1041,13 @@ class _WebEngineScripts(QObject):
self._update_stylesheet, searching=False))
self._tab.search.finished.connect(self._update_stylesheet)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _on_config_changed(self, option):
if option in ['scrolling.bar', 'content.user_stylesheets']:
self._init_stylesheet()
self._update_stylesheet()
- @pyqtSlot(bool)
+ @QtCore.pyqtSlot(bool)
def _update_stylesheet(self, searching=False):
"""Update the custom stylesheet in existing tabs."""
css = shared.get_user_stylesheet(searching=searching)
@@ -1061,11 +1055,11 @@ class _WebEngineScripts(QObject):
self._tab.run_js_async(code)
def _inject_js(self, name, js_code, *,
- world=QWebEngineScript.ApplicationWorld,
- injection_point=QWebEngineScript.DocumentCreation,
+ world=QtWebEngineWidgets.QWebEngineScript.ApplicationWorld,
+ injection_point=QtWebEngineWidgets.QWebEngineScript.DocumentCreation,
subframes=False):
"""Inject the given script to run early on a page load."""
- script = QWebEngineScript()
+ script = QtWebEngineWidgets.QWebEngineScript()
script.setInjectionPoint(injection_point)
script.setSourceCode(js_code)
script.setWorldId(world)
@@ -1112,7 +1106,7 @@ class _WebEngineScripts(QObject):
)
self._inject_js('stylesheet', js_code, subframes=True)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _inject_all_greasemonkey_scripts(self):
scripts = self._greasemonkey.all_scripts()
self._inject_greasemonkey_scripts(scripts)
@@ -1149,7 +1143,7 @@ class _WebEngineScripts(QObject):
script.dedup_suffix += 1
seen_names.add(script.full_name())
- new_script = QWebEngineScript()
+ new_script = QtWebEngineWidgets.QWebEngineScript()
try:
world = int(script.jsworld)
@@ -1177,7 +1171,7 @@ class _WebEngineScripts(QObject):
# NOTE that this needs to be done before setSourceCode, so that
# QtWebEngine's parsing of GreaseMonkey tags will override it if there is a
# @run-at comment.
- new_script.setInjectionPoint(QWebEngineScript.DocumentReady)
+ new_script.setInjectionPoint(QtWebEngineWidgets.QWebEngineScript.DocumentReady)
new_script.setSourceCode(script.code())
new_script.setName(script.full_name())
@@ -1186,7 +1180,7 @@ class _WebEngineScripts(QObject):
if script.needs_document_end_workaround():
log.greasemonkey.debug(
f"Forcing @run-at document-end for {script.name}")
- new_script.setInjectionPoint(QWebEngineScript.DocumentReady)
+ new_script.setInjectionPoint(QtWebEngineWidgets.QWebEngineScript.DocumentReady)
log.greasemonkey.debug(f'adding script: {new_script.name()}')
page_scripts.insert(new_script)
@@ -1200,8 +1194,8 @@ class _WebEngineScripts(QObject):
quirks = [
_Quirk(
'whatsapp_web',
- injection_point=QWebEngineScript.DocumentReady,
- world=QWebEngineScript.ApplicationWorld,
+ injection_point=QtWebEngineWidgets.QWebEngineScript.DocumentReady,
+ world=QtWebEngineWidgets.QWebEngineScript.ApplicationWorld,
),
_Quirk('discord'),
_Quirk(
@@ -1273,7 +1267,7 @@ class WebEngineTab(browsertab.AbstractTab):
down.
"""
- abort_questions = pyqtSignal()
+ abort_questions = QtCore.pyqtSignal()
def __init__(self, *, win_id, mode_manager, private, parent=None):
super().__init__(win_id=win_id,
@@ -1322,7 +1316,7 @@ class WebEngineTab(browsertab.AbstractTab):
parent=self)
self._widget.installEventFilter(self._child_event_filter)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _restore_zoom(self):
if sip.isdeleted(self._widget):
# https://github.com/qutebrowser/qutebrowser/issues/3498
@@ -1359,9 +1353,9 @@ class WebEngineTab(browsertab.AbstractTab):
self._widget.page().toHtml(callback)
def run_js_async(self, code, callback=None, *, world=None):
- world_id_type = Union[QWebEngineScript.ScriptWorldId, int]
+ world_id_type = Union[QtWebEngineWidgets.QWebEngineScript.ScriptWorldId, int]
if world is None:
- world_id: world_id_type = QWebEngineScript.ApplicationWorld
+ world_id: world_id_type = QtWebEngineWidgets.QWebEngineScript.ApplicationWorld
elif isinstance(world, int):
world_id = world
if not 0 <= world_id <= qtutils.MAX_WORLD_ID:
@@ -1378,9 +1372,9 @@ class WebEngineTab(browsertab.AbstractTab):
def reload(self, *, force=False):
if force:
- action = QWebEnginePage.ReloadAndBypassCache
+ action = QtWebEngineWidgets.QWebEnginePage.ReloadAndBypassCache
else:
- action = QWebEnginePage.Reload
+ action = QtWebEngineWidgets.QWebEnginePage.Reload
self._widget.triggerPageAction(action)
def stop(self):
@@ -1400,7 +1394,7 @@ class WebEngineTab(browsertab.AbstractTab):
def icon(self):
return self._widget.icon()
- def set_html(self, html, base_url=QUrl()):
+ def set_html(self, html, base_url=QtCore.QUrl()):
# FIXME:qtwebengine
# check this and raise an exception if too big:
# Warning: The content will be percent encoded before being sent to the
@@ -1418,7 +1412,7 @@ class WebEngineTab(browsertab.AbstractTab):
url=url_string, error=error)
self.set_html(error_page)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_history_trigger(self):
try:
self._widget.page()
@@ -1434,10 +1428,10 @@ class WebEngineTab(browsertab.AbstractTab):
# Don't save the title if it's generated from the URL
title = self.title()
- title_url = QUrl(url)
+ title_url = QtCore.QUrl(url)
title_url.setScheme('')
title_url_str = title_url.toDisplayString(
- QUrl.RemoveScheme) # type: ignore[arg-type]
+ QtCore.QUrl.RemoveScheme) # type: ignore[arg-type]
if title == title_url_str.strip('/'):
title = ""
@@ -1448,26 +1442,26 @@ class WebEngineTab(browsertab.AbstractTab):
self.history_item_triggered.emit(url, requested_url, title)
- @pyqtSlot(QUrl, 'QAuthenticator*', 'QString')
+ @QtCore.pyqtSlot(QtCore.QUrl, 'QAuthenticator*', 'QString')
def _on_proxy_authentication_required(self, url, authenticator,
proxy_host):
"""Called when a proxy needs authentication."""
msg = "<b>{}</b> requires a username and password.".format(
html_utils.escape(proxy_host))
- urlstr = url.toString(QUrl.RemovePassword | QUrl.FullyEncoded)
+ urlstr = url.toString(QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded)
answer = message.ask(
title="Proxy authentication required", text=msg,
mode=usertypes.PromptMode.user_pwd,
abort_on=[self.abort_questions], url=urlstr)
if answer is None:
- sip.assign(authenticator, QAuthenticator())
+ sip.assign(authenticator, QtNetwork.QAuthenticator())
return
authenticator.setUser(answer.user)
authenticator.setPassword(answer.password)
- @pyqtSlot(QUrl, 'QAuthenticator*')
+ @QtCore.pyqtSlot(QtCore.QUrl, 'QAuthenticator*')
def _on_authentication_required(self, url, authenticator):
log.network.debug("Authentication requested for {}, netrc_used {}"
.format(url.toDisplayString(), self.data.netrc_used))
@@ -1483,9 +1477,9 @@ class WebEngineTab(browsertab.AbstractTab):
url, authenticator, abort_on=[self.abort_questions])
if not netrc_success and answer is None:
log.network.debug("Aborting auth")
- sip.assign(authenticator, QAuthenticator())
+ sip.assign(authenticator, QtNetwork.QAuthenticator())
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_load_started(self):
"""Clear search when a new load is started if needed."""
# WORKAROUND for
@@ -1495,27 +1489,27 @@ class WebEngineTab(browsertab.AbstractTab):
super()._on_load_started()
self.data.netrc_used = False
- @pyqtSlot('qint64')
+ @QtCore.pyqtSlot('qint64')
def _on_renderer_process_pid_changed(self, pid):
log.webview.debug("Renderer process PID for tab {}: {}"
.format(self.tab_id, pid))
- @pyqtSlot(QWebEnginePage.RenderProcessTerminationStatus, int)
+ @QtCore.pyqtSlot(QtWebEngineWidgets.QWebEnginePage.RenderProcessTerminationStatus, int)
def _on_render_process_terminated(self, status, exitcode):
"""Show an error when the renderer process terminated."""
- if (status == QWebEnginePage.AbnormalTerminationStatus and
+ if (status == QtWebEngineWidgets.QWebEnginePage.AbnormalTerminationStatus and
exitcode == 256):
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-58697
- status = QWebEnginePage.CrashedTerminationStatus
+ status = QtWebEngineWidgets.QWebEnginePage.CrashedTerminationStatus
status_map = {
- QWebEnginePage.NormalTerminationStatus:
+ QtWebEngineWidgets.QWebEnginePage.NormalTerminationStatus:
browsertab.TerminationStatus.normal,
- QWebEnginePage.AbnormalTerminationStatus:
+ QtWebEngineWidgets.QWebEnginePage.AbnormalTerminationStatus:
browsertab.TerminationStatus.abnormal,
- QWebEnginePage.CrashedTerminationStatus:
+ QtWebEngineWidgets.QWebEnginePage.CrashedTerminationStatus:
browsertab.TerminationStatus.crashed,
- QWebEnginePage.KilledTerminationStatus:
+ QtWebEngineWidgets.QWebEnginePage.KilledTerminationStatus:
browsertab.TerminationStatus.killed,
-1:
browsertab.TerminationStatus.unknown,
@@ -1543,7 +1537,7 @@ class WebEngineTab(browsertab.AbstractTab):
self._show_error_page(self.url(), error=error)
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def _on_load_progress(self, perc: int) -> None:
"""QtWebEngine-specific loadProgress workarounds.
@@ -1554,7 +1548,7 @@ class WebEngineTab(browsertab.AbstractTab):
self.load_status() != usertypes.LoadStatus.error):
self._update_load_status(ok=True)
- @pyqtSlot(bool)
+ @QtCore.pyqtSlot(bool)
def _on_load_finished(self, ok: bool) -> None:
"""QtWebEngine-specific loadFinished workarounds."""
super()._on_load_finished(ok)
@@ -1567,7 +1561,7 @@ class WebEngineTab(browsertab.AbstractTab):
self._error_page_workaround,
self.settings.test_attribute('content.javascript.enabled')))
- @pyqtSlot(certificateerror.CertificateErrorWrapper)
+ @QtCore.pyqtSlot(certificateerror.CertificateErrorWrapper)
def _on_ssl_errors(self, error):
url = error.url()
self._insecure_hosts.add(url.host())
@@ -1613,11 +1607,11 @@ class WebEngineTab(browsertab.AbstractTab):
# have happened when loading some resource.
is_resource = (
first_party_url.isValid() and
- url.matches(first_party_url, QUrl.RemoveScheme))
+ url.matches(first_party_url, QtCore.QUrl.RemoveScheme))
if show_non_overr_cert_error and is_resource:
self._show_error_page(url, str(error))
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_print_requested(self):
"""Slot for window.print() in JS."""
try:
@@ -1625,8 +1619,8 @@ class WebEngineTab(browsertab.AbstractTab):
except browsertab.WebTabError as e:
message.error(str(e))
- @pyqtSlot(QUrl)
- def _on_url_changed(self, url: QUrl) -> None:
+ @QtCore.pyqtSlot(QtCore.QUrl)
+ def _on_url_changed(self, url: QtCore.QUrl) -> None:
"""Update settings for the current URL.
Normally this is done below in _on_navigation_request, but we also need
@@ -1642,7 +1636,7 @@ class WebEngineTab(browsertab.AbstractTab):
not qtutils.version_check('5.14')):
self.settings.update_for_url(url)
- @pyqtSlot(usertypes.NavigationRequest)
+ @QtCore.pyqtSlot(usertypes.NavigationRequest)
def _on_navigation_request(self, navigation):
super()._on_navigation_request(navigation)
@@ -1699,9 +1693,7 @@ class WebEngineTab(browsertab.AbstractTab):
page.printRequested.connect(self._on_print_requested)
try:
- # pylint: disable=unused-import
- from PyQt5.QtWebEngineWidgets import (
- QWebEngineClientCertificateSelection)
+ pass
except ImportError:
pass
else:
diff --git a/qutebrowser/browser/webengine/webview.py b/qutebrowser/browser/webengine/webview.py
index 76ce1a42e..bf9440c22 100644
--- a/qutebrowser/browser/webengine/webview.py
+++ b/qutebrowser/browser/webengine/webview.py
@@ -20,20 +20,18 @@
"""The main browser widget for QtWebEngine."""
from typing import List, Iterable
-
-from PyQt5.QtCore import pyqtSignal, QUrl
-from PyQt5.QtGui import QPalette
-from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
+from qutebrowser.qt import QtWebEngineWidgets, QtGui
from qutebrowser.browser import shared
from qutebrowser.browser.webengine import webenginesettings, certificateerror
from qutebrowser.config import config
from qutebrowser.utils import log, debug, usertypes
+from qutebrowser.qt import QtCore
_QB_FILESELECTION_MODES = {
- QWebEnginePage.FileSelectOpen: shared.FileSelectionMode.single_file,
- QWebEnginePage.FileSelectOpenMultiple: shared.FileSelectionMode.multiple_files,
+ QtWebEngineWidgets.QWebEnginePage.FileSelectOpen: shared.FileSelectionMode.single_file,
+ QtWebEngineWidgets.QWebEnginePage.FileSelectOpenMultiple: shared.FileSelectionMode.multiple_files,
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-91489
#
# QtWebEngine doesn't expose this value from its internal
@@ -41,11 +39,11 @@ _QB_FILESELECTION_MODES = {
# the public QWebEnginePage::FileSelectionMode enum).
# However, QWebEnginePage::chooseFiles is still called with the matching value
# (2) when a file input with "webkitdirectory" is used.
- QWebEnginePage.FileSelectionMode(2): shared.FileSelectionMode.folder,
+ QtWebEngineWidgets.QWebEnginePage.FileSelectionMode(2): shared.FileSelectionMode.folder,
}
-class WebEngineView(QWebEngineView):
+class WebEngineView(QtWebEngineWidgets.QWebEngineView):
"""Custom QWebEngineView subclass with qutebrowser-specific features."""
@@ -54,7 +52,7 @@ class WebEngineView(QWebEngineView):
self._win_id = win_id
self._tabdata = tabdata
- theme_color = self.style().standardPalette().color(QPalette.Base)
+ theme_color = self.style().standardPalette().color(QtGui.QPalette.Base)
if private:
assert webenginesettings.private_profile is not None
profile = webenginesettings.private_profile
@@ -97,27 +95,27 @@ class WebEngineView(QWebEngineView):
Return:
The new QWebEngineView object.
"""
- debug_type = debug.qenum_key(QWebEnginePage, wintype)
+ debug_type = debug.qenum_key(QtWebEngineWidgets.QWebEnginePage, wintype)
background = config.val.tabs.background
log.webview.debug("createWindow with type {}, background {}".format(
debug_type, background))
- if wintype == QWebEnginePage.WebBrowserWindow:
+ if wintype == QtWebEngineWidgets.QWebEnginePage.WebBrowserWindow:
# Shift-Alt-Click
target = usertypes.ClickTarget.window
- elif wintype == QWebEnginePage.WebDialog:
+ elif wintype == QtWebEngineWidgets.QWebEnginePage.WebDialog:
log.webview.warning("{} requested, but we don't support "
"that!".format(debug_type))
target = usertypes.ClickTarget.tab
- elif wintype == QWebEnginePage.WebBrowserTab:
+ elif wintype == QtWebEngineWidgets.QWebEnginePage.WebBrowserTab:
# Middle-click / Ctrl-Click with Shift
# FIXME:qtwebengine this also affects target=_blank links...
if background:
target = usertypes.ClickTarget.tab
else:
target = usertypes.ClickTarget.tab_bg
- elif wintype == QWebEnginePage.WebBrowserBackgroundTab:
+ elif wintype == QtWebEngineWidgets.QWebEnginePage.WebBrowserBackgroundTab:
# Middle-click / Ctrl-Click
if background:
target = usertypes.ClickTarget.tab_bg
@@ -137,7 +135,7 @@ class WebEngineView(QWebEngineView):
super().contextMenuEvent(ev)
-class WebEnginePage(QWebEnginePage):
+class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):
"""Custom QWebEnginePage subclass with qutebrowser-specific features.
@@ -153,9 +151,9 @@ class WebEnginePage(QWebEnginePage):
navigation_request: Emitted on acceptNavigationRequest.
"""
- certificate_error = pyqtSignal(certificateerror.CertificateErrorWrapper)
- shutting_down = pyqtSignal()
- navigation_request = pyqtSignal(usertypes.NavigationRequest)
+ certificate_error = QtCore.pyqtSignal(certificateerror.CertificateErrorWrapper)
+ shutting_down = QtCore.pyqtSignal()
+ navigation_request = QtCore.pyqtSignal(usertypes.NavigationRequest)
def __init__(self, *, theme_color, profile, parent=None):
super().__init__(profile, parent)
@@ -214,33 +212,33 @@ class WebEnginePage(QWebEnginePage):
def javaScriptConsoleMessage(self, level, msg, line, source):
"""Log javascript messages to qutebrowser's log."""
level_map = {
- QWebEnginePage.InfoMessageLevel: usertypes.JsLogLevel.info,
- QWebEnginePage.WarningMessageLevel: usertypes.JsLogLevel.warning,
- QWebEnginePage.ErrorMessageLevel: usertypes.JsLogLevel.error,
+ QtWebEngineWidgets.QWebEnginePage.InfoMessageLevel: usertypes.JsLogLevel.info,
+ QtWebEngineWidgets.QWebEnginePage.WarningMessageLevel: usertypes.JsLogLevel.warning,
+ QtWebEngineWidgets.QWebEnginePage.ErrorMessageLevel: usertypes.JsLogLevel.error,
}
shared.javascript_log_message(level_map[level], source, line, msg)
def acceptNavigationRequest(self,
- url: QUrl,
- typ: QWebEnginePage.NavigationType,
+ url: QtCore.QUrl,
+ typ: QtWebEngineWidgets.QWebEnginePage.NavigationType,
is_main_frame: bool) -> bool:
"""Override acceptNavigationRequest to forward it to the tab API."""
type_map = {
- QWebEnginePage.NavigationTypeLinkClicked:
+ QtWebEngineWidgets.QWebEnginePage.NavigationTypeLinkClicked:
usertypes.NavigationRequest.Type.link_clicked,
- QWebEnginePage.NavigationTypeTyped:
+ QtWebEngineWidgets.QWebEnginePage.NavigationTypeTyped:
usertypes.NavigationRequest.Type.typed,
- QWebEnginePage.NavigationTypeFormSubmitted:
+ QtWebEngineWidgets.QWebEnginePage.NavigationTypeFormSubmitted:
usertypes.NavigationRequest.Type.form_submitted,
- QWebEnginePage.NavigationTypeBackForward:
+ QtWebEngineWidgets.QWebEnginePage.NavigationTypeBackForward:
usertypes.NavigationRequest.Type.back_forward,
- QWebEnginePage.NavigationTypeReload:
+ QtWebEngineWidgets.QWebEnginePage.NavigationTypeReload:
usertypes.NavigationRequest.Type.reloaded,
- QWebEnginePage.NavigationTypeOther:
+ QtWebEngineWidgets.QWebEnginePage.NavigationTypeOther:
usertypes.NavigationRequest.Type.other,
}
try:
- type_map[QWebEnginePage.NavigationTypeRedirect] = (
+ type_map[QtWebEngineWidgets.QWebEnginePage.NavigationTypeRedirect] = (
usertypes.NavigationRequest.Type.redirect)
except AttributeError:
# Added in Qt 5.14
@@ -256,7 +254,7 @@ class WebEnginePage(QWebEnginePage):
def chooseFiles(
self,
- mode: QWebEnginePage.FileSelectionMode,
+ mode: QtWebEngineWidgets.QWebEnginePage.FileSelectionMode,
old_files: Iterable[str],
accepted_mimetypes: Iterable[str],
) -> List[str]:
diff --git a/qutebrowser/browser/webkit/cache.py b/qutebrowser/browser/webkit/cache.py
index 8494a8477..74c682ed3 100644
--- a/qutebrowser/browser/webkit/cache.py
+++ b/qutebrowser/browser/webkit/cache.py
@@ -22,7 +22,7 @@
from typing import cast
import os.path
-from PyQt5.QtNetwork import QNetworkDiskCache
+from qutebrowser.qt import QtNetwork
from qutebrowser.config import config
from qutebrowser.utils import utils, standarddir
@@ -31,7 +31,7 @@ from qutebrowser.utils import utils, standarddir
diskcache = cast('DiskCache', None)
-class DiskCache(QNetworkDiskCache):
+class DiskCache(QtNetwork.QNetworkDiskCache):
"""Disk cache which sets correct cache dir and size."""
diff --git a/qutebrowser/browser/webkit/certificateerror.py b/qutebrowser/browser/webkit/certificateerror.py
index 09237dae9..569df3988 100644
--- a/qutebrowser/browser/webkit/certificateerror.py
+++ b/qutebrowser/browser/webkit/certificateerror.py
@@ -21,7 +21,7 @@
from typing import Sequence
-from PyQt5.QtNetwork import QSslError
+from qutebrowser.qt import QtNetwork
from qutebrowser.utils import usertypes, utils, debug, jinja
@@ -30,7 +30,7 @@ class CertificateErrorWrapper(usertypes.AbstractCertificateErrorWrapper):
"""A wrapper over a list of QSslErrors."""
- def __init__(self, errors: Sequence[QSslError]) -> None:
+ def __init__(self, errors: Sequence[QtNetwork.QSslError]) -> None:
self._errors = tuple(errors) # needs to be hashable
def __str__(self) -> str:
@@ -39,7 +39,7 @@ class CertificateErrorWrapper(usertypes.AbstractCertificateErrorWrapper):
def __repr__(self) -> str:
return utils.get_repr(
self,
- errors=[debug.qenum_key(QSslError, err.error()) for err in self._errors],
+ errors=[debug.qenum_key(QtNetwork.QSslError, err.error()) for err in self._errors],
string=str(self))
def __hash__(self) -> int:
diff --git a/qutebrowser/browser/webkit/cookies.py b/qutebrowser/browser/webkit/cookies.py
index 055ef64d8..e44f4532b 100644
--- a/qutebrowser/browser/webkit/cookies.py
+++ b/qutebrowser/browser/webkit/cookies.py
@@ -21,19 +21,17 @@
from typing import Sequence
-from PyQt5.QtNetwork import QNetworkCookie, QNetworkCookieJar
-from PyQt5.QtCore import pyqtSignal, QDateTime
-
from qutebrowser.config import config
from qutebrowser.utils import utils, standarddir, objreg, log
from qutebrowser.misc import lineparser, objects
+from qutebrowser.qt import QtNetwork, QtCore
cookie_jar = None
ram_cookie_jar = None
-class RAMCookieJar(QNetworkCookieJar):
+class RAMCookieJar(QtNetwork.QNetworkCookieJar):
"""An in-RAM cookie jar.
@@ -41,7 +39,7 @@ class RAMCookieJar(QNetworkCookieJar):
changed: Emitted when the cookie store was changed.
"""
- changed = pyqtSignal()
+ changed = QtCore.pyqtSignal()
def __repr__(self):
return utils.get_repr(self, count=len(self.allCookies()))
@@ -93,9 +91,9 @@ class CookieJar(RAMCookieJar):
def parse_cookies(self):
"""Parse cookies from lineparser and store them."""
- cookies: Sequence[QNetworkCookie] = []
+ cookies: Sequence[QtNetwork.QNetworkCookie] = []
for line in self._lineparser:
- line_cookies = QNetworkCookie.parseCookies(line)
+ line_cookies = QtNetwork.QNetworkCookie.parseCookies(line)
cookies += line_cookies # type: ignore[operator]
self.setAllCookies(cookies)
@@ -103,7 +101,7 @@ class CookieJar(RAMCookieJar):
"""Purge expired cookies from the cookie jar."""
# Based on:
# https://doc.qt.io/archives/qt-5.5/qtwebkitexamples-webkitwidgets-browser-cookiejar-cpp.html
- now = QDateTime.currentDateTime()
+ now = QtCore.QDateTime.currentDateTime()
cookies = [c for c in self.allCookies()
if c.isSessionCookie() or
c.expirationDate() >= now] # type: ignore[operator]
diff --git a/qutebrowser/browser/webkit/http.py b/qutebrowser/browser/webkit/http.py
index 5a7cd8b34..148e8b7f0 100644
--- a/qutebrowser/browser/webkit/http.py
+++ b/qutebrowser/browser/webkit/http.py
@@ -25,7 +25,7 @@ import dataclasses
import os.path
from typing import Type
-from PyQt5.QtNetwork import QNetworkRequest
+from qutebrowser.qt import QtNetwork
from qutebrowser.utils import log, utils
@@ -188,7 +188,7 @@ def parse_content_type(reply):
A [mimetype, rest] list, or [None, None] if unset.
Rest can be None.
"""
- content_type = reply.header(QNetworkRequest.ContentTypeHeader)
+ content_type = reply.header(QtNetwork.QNetworkRequest.ContentTypeHeader)
if content_type is None:
return [None, None]
if ';' in content_type:
diff --git a/qutebrowser/browser/webkit/mhtml.py b/qutebrowser/browser/webkit/mhtml.py
index d9f2d484e..7e106a57e 100644
--- a/qutebrowser/browser/webkit/mhtml.py
+++ b/qutebrowser/browser/webkit/mhtml.py
@@ -36,7 +36,7 @@ import quopri
import dataclasses
from typing import MutableMapping, Set, Tuple, Callable
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.browser import downloads
from qutebrowser.browser.webkit import webkitelem
@@ -137,7 +137,7 @@ class MHTMLWriter:
self.root_content = root_content
self.content_location = content_location
self.content_type = content_type
- self._files: MutableMapping[QUrl, _File] = {}
+ self._files: MutableMapping[QtCore.QUrl, _File] = {}
def add_file(self, location, content, content_type=None,
transfer_encoding=E_QUOPRI):
@@ -192,7 +192,7 @@ class MHTMLWriter:
return msg
-_PendingDownloadType = Set[Tuple[QUrl, downloads.AbstractDownloadItem]]
+_PendingDownloadType = Set[Tuple[QtCore.QUrl, downloads.AbstractDownloadItem]]
class _Downloader:
@@ -259,7 +259,7 @@ class _Downloader:
else:
# Might be a local <script> tag or something else
continue
- absolute_url = web_url.resolved(QUrl(element_url))
+ absolute_url = web_url.resolved(QtCore.QUrl(element_url))
self._fetch_url(absolute_url)
styles = web_frame.findAllElements('style')
@@ -273,14 +273,14 @@ class _Downloader:
if 'type' in style and style['type'] != 'text/css':
continue
for element_url in _get_css_imports(str(style)):
- self._fetch_url(web_url.resolved(QUrl(element_url)))
+ self._fetch_url(web_url.resolved(QtCore.QUrl(element_url)))
# Search for references in inline styles
for element in web_frame.findAllElements('[style]'):
element = webkitelem.WebKitElement(element, tab=self.tab)
style = element['style']
for element_url in _get_css_imports(style):
- self._fetch_url(web_url.resolved(QUrl(element_url)))
+ self._fetch_url(web_url.resolved(QtCore.QUrl(element_url)))
# Shortcut if no assets need to be downloaded, otherwise the file would
# never be saved. Also might happen if the downloads are fast enough to
@@ -366,7 +366,7 @@ class _Downloader:
css_string = item.fileobj.getvalue().decode('utf-8', 'ignore')
import_urls = _get_css_imports(css_string)
for import_url in import_urls:
- absolute_url = url.resolved(QUrl(import_url))
+ absolute_url = url.resolved(QtCore.QUrl(import_url))
self._fetch_url(absolute_url)
encode = E_QUOPRI if mime.startswith('text/') else E_BASE64
diff --git a/qutebrowser/browser/webkit/network/networkmanager.py b/qutebrowser/browser/webkit/network/networkmanager.py
index 83eaabda7..b5aaee394 100644
--- a/qutebrowser/browser/webkit/network/networkmanager.py
+++ b/qutebrowser/browser/webkit/network/networkmanager.py
@@ -24,10 +24,6 @@ import html
import dataclasses
from typing import TYPE_CHECKING, Dict, MutableMapping, Optional, Set
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, QUrl, QByteArray
-from PyQt5.QtNetwork import (QNetworkAccessManager, QNetworkReply, QSslConfiguration,
- QNetworkProxy)
-
from qutebrowser.config import config
from qutebrowser.utils import (message, log, usertypes, utils, objreg,
urlutils, debug)
@@ -38,6 +34,7 @@ from qutebrowser.browser.webkit import certificateerror, cookies, cache
from qutebrowser.browser.webkit.network import (webkitqutescheme, networkreply,
filescheme)
from qutebrowser.misc import objects
+from qutebrowser.qt import QtNetwork, QtCore
if TYPE_CHECKING:
from qutebrowser.mainwindow import prompt
@@ -52,7 +49,7 @@ class ProxyId:
"""Information identifying a proxy server."""
- type: QNetworkProxy.ProxyType
+ type: QtNetwork.QNetworkProxy.ProxyType
hostname: str
port: int
@@ -103,7 +100,7 @@ def _is_secure_cipher(cipher):
def init():
"""Disable insecure SSL ciphers on old Qt versions."""
- sslconfig = QSslConfiguration.defaultConfiguration()
+ sslconfig = QtNetwork.QSslConfiguration.defaultConfiguration()
default_ciphers = sslconfig.ciphers()
log.init.vdebug( # type: ignore[attr-defined]
"Default Qt ciphers: {}".format(
@@ -129,7 +126,7 @@ _SavedErrorsType = MutableMapping[
]
-class NetworkManager(QNetworkAccessManager):
+class NetworkManager(QtNetwork.QNetworkAccessManager):
"""Our own QNetworkAccessManager.
@@ -154,7 +151,7 @@ class NetworkManager(QNetworkAccessManager):
shutting_down: Emitted when the QNAM is shutting down.
"""
- shutting_down = pyqtSignal()
+ shutting_down = QtCore.pyqtSignal()
def __init__(self, *, win_id, tab_id, private, parent=None):
log.init.debug("Initializing NetworkManager")
@@ -239,7 +236,7 @@ class NetworkManager(QNetworkAccessManager):
def shutdown(self):
"""Abort all running requests."""
- self.setNetworkAccessible(QNetworkAccessManager.NotAccessible)
+ self.setNetworkAccessible(QtNetwork.QNetworkAccessManager.NotAccessible)
self.shutting_down.emit()
# No @pyqtSlot here, see
@@ -279,7 +276,7 @@ class NetworkManager(QNetworkAccessManager):
abort_on = self._get_abort_signals(reply)
tab = self._get_tab()
- first_party_url = QUrl() if tab is None else tab.data.last_navigation.url
+ first_party_url = QtCore.QUrl() if tab is None else tab.data.last_navigation.url
ignore = shared.ignore_certificate_error(
request_url=reply.url(),
@@ -299,7 +296,7 @@ class NetworkManager(QNetworkAccessManager):
self._accepted_ssl_errors.clear()
self._rejected_ssl_errors.clear()
- @pyqtSlot(QUrl)
+ @QtCore.pyqtSlot(QtCore.QUrl)
def clear_rejected_ssl_errors(self, url):
"""Clear the rejected SSL errors on a reload.
@@ -311,7 +308,7 @@ class NetworkManager(QNetworkAccessManager):
except KeyError:
pass
- @pyqtSlot('QNetworkReply*', 'QAuthenticator*')
+ @QtCore.pyqtSlot('QNetworkReply*', 'QAuthenticator*')
def on_authentication_required(self, reply, authenticator):
"""Called when a website needs authentication."""
url = reply.url()
@@ -329,7 +326,7 @@ class NetworkManager(QNetworkAccessManager):
shared.authentication_required(url, authenticator,
abort_on=abort_on)
- @pyqtSlot('QNetworkProxy', 'QAuthenticator*')
+ @QtCore.pyqtSlot('QNetworkProxy', 'QAuthenticator*')
def on_proxy_authentication_required(self, proxy, authenticator):
"""Called when a proxy needs authentication."""
proxy_id = ProxyId(proxy.type(), proxy.hostName(), proxy.port())
@@ -350,7 +347,7 @@ class NetworkManager(QNetworkAccessManager):
authenticator.setPassword(answer.password)
_proxy_auth_cache[proxy_id] = answer
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_adopted_download_destroyed(self):
"""Check if we can clean up if an adopted download was destroyed.
@@ -363,7 +360,7 @@ class NetworkManager(QNetworkAccessManager):
if self.adopted_downloads == 0:
self.deleteLater()
- @pyqtSlot(object) # DownloadItem
+ @QtCore.pyqtSlot(object) # DownloadItem
def adopt_download(self, download):
"""Adopt a new DownloadItem."""
self.adopted_downloads += 1
@@ -380,10 +377,10 @@ class NetworkManager(QNetworkAccessManager):
if referer_header_conf == 'never':
# Note: using ''.encode('ascii') sends a header with no value,
# instead of no header at all
- req.setRawHeader(b'Referer', QByteArray())
+ req.setRawHeader(b'Referer', QtCore.QByteArray())
elif (referer_header_conf == 'same-domain' and
not urlutils.same_domain(req.url(), current_url)):
- req.setRawHeader(b'Referer', QByteArray())
+ req.setRawHeader(b'Referer', QtCore.QByteArray())
# If refer_header_conf is set to 'always', we leave the header
# alone as QtWebKit did set it.
except urlutils.InvalidUrlError:
@@ -406,21 +403,21 @@ class NetworkManager(QNetworkAccessManager):
proxy_error = proxymod.application_factory.get_error()
if proxy_error is not None:
return networkreply.ErrorNetworkReply(
- req, proxy_error, QNetworkReply.UnknownProxyError,
+ req, proxy_error, QtNetwork.QNetworkReply.UnknownProxyError,
self)
if not req.url().isValid():
log.network.debug("Ignoring invalid requested URL: {}".format(
req.url().errorString()))
return networkreply.ErrorNetworkReply(
- req, "Invalid request URL", QNetworkReply.HostNotFoundError,
+ req, "Invalid request URL", QtNetwork.QNetworkReply.HostNotFoundError,
self)
for header, value in shared.custom_headers(url=req.url()):
req.setRawHeader(header, value)
tab = self._get_tab()
- current_url = QUrl()
+ current_url = QtCore.QUrl()
if tab is not None:
try:
current_url = tab.url()
@@ -433,11 +430,11 @@ class NetworkManager(QNetworkAccessManager):
interceptors.run(request)
if request.is_blocked:
return networkreply.ErrorNetworkReply(
- req, HOSTBLOCK_ERROR_STRING, QNetworkReply.ContentAccessDenied,
+ req, HOSTBLOCK_ERROR_STRING, QtNetwork.QNetworkReply.ContentAccessDenied,
self)
if 'log-requests' in objects.debug_flags:
- operation = debug.qenum_key(QNetworkAccessManager, op)
+ operation = debug.qenum_key(QtNetwork.QNetworkAccessManager, op)
operation = operation.replace('Operation', '').upper()
log.network.debug("{} {}, first-party {}".format(
operation,
diff --git a/qutebrowser/browser/webkit/network/networkreply.py b/qutebrowser/browser/webkit/network/networkreply.py
index c1ead3209..b29c6e5f2 100644
--- a/qutebrowser/browser/webkit/network/networkreply.py
+++ b/qutebrowser/browser/webkit/network/networkreply.py
@@ -25,12 +25,10 @@
# pylint: disable=unnecessary-lambda
"""Special network replies.."""
+from qutebrowser.qt import QtNetwork, QtCore
-from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
-from PyQt5.QtCore import pyqtSlot, QIODevice, QByteArray, QTimer
-
-class FixedDataNetworkReply(QNetworkReply):
+class FixedDataNetworkReply(QtNetwork.QNetworkReply):
"""QNetworkReply subclass for fixed data."""
@@ -49,27 +47,27 @@ class FixedDataNetworkReply(QNetworkReply):
self.setRequest(request)
self.setUrl(request.url())
- self.setOpenMode(QIODevice.ReadOnly)
+ self.setOpenMode(QtCore.QIODevice.ReadOnly)
- self.setHeader(QNetworkRequest.ContentTypeHeader, mimeType)
- self.setHeader(QNetworkRequest.ContentLengthHeader,
- QByteArray.number(len(fileData)))
- self.setAttribute(QNetworkRequest.HttpStatusCodeAttribute, 200)
- self.setAttribute(QNetworkRequest.HttpReasonPhraseAttribute, 'OK')
+ self.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader, mimeType)
+ self.setHeader(QtNetwork.QNetworkRequest.ContentLengthHeader,
+ QtCore.QByteArray.number(len(fileData)))
+ self.setAttribute(QtNetwork.QNetworkRequest.HttpStatusCodeAttribute, 200)
+ self.setAttribute(QtNetwork.QNetworkRequest.HttpReasonPhraseAttribute, 'OK')
# For some reason, a segfault will be triggered if these lambdas aren't
# there.
# pylint: disable=unnecessary-lambda
- QTimer.singleShot(
+ QtCore.QTimer.singleShot(
0,
lambda: self.metaDataChanged.emit()) # type: ignore[attr-defined]
- QTimer.singleShot(
+ QtCore.QTimer.singleShot(
0,
lambda: self.readyRead.emit()) # type: ignore[attr-defined]
- QTimer.singleShot(
+ QtCore.QTimer.singleShot(
0,
lambda: self.finished.emit()) # type: ignore[attr-defined]
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def abort(self):
"""Abort the operation."""
@@ -102,7 +100,7 @@ class FixedDataNetworkReply(QNetworkReply):
return False
-class ErrorNetworkReply(QNetworkReply):
+class ErrorNetworkReply(QtNetwork.QNetworkReply):
"""QNetworkReply which always returns an error."""
@@ -120,11 +118,11 @@ class ErrorNetworkReply(QNetworkReply):
self.setUrl(req.url())
# We don't actually want to read anything, but we still need to open
# the device to avoid getting a warning.
- self.setOpenMode(QIODevice.ReadOnly)
+ self.setOpenMode(QtCore.QIODevice.ReadOnly)
self.setError(error, errorstring)
- QTimer.singleShot(0, lambda:
+ QtCore.QTimer.singleShot(0, lambda:
self.error.emit(error)) # type: ignore[attr-defined]
- QTimer.singleShot(0, lambda:
+ QtCore.QTimer.singleShot(0, lambda:
self.finished.emit()) # type: ignore[attr-defined]
def abort(self):
@@ -145,14 +143,14 @@ class ErrorNetworkReply(QNetworkReply):
return False
-class RedirectNetworkReply(QNetworkReply):
+class RedirectNetworkReply(QtNetwork.QNetworkReply):
"""A reply which redirects to the given URL."""
def __init__(self, new_url, parent=None):
super().__init__(parent)
- self.setAttribute(QNetworkRequest.RedirectionTargetAttribute, new_url)
- QTimer.singleShot(0, lambda:
+ self.setAttribute(QtNetwork.QNetworkRequest.RedirectionTargetAttribute, new_url)
+ QtCore.QTimer.singleShot(0, lambda:
self.finished.emit()) # type: ignore[attr-defined]
def abort(self):
diff --git a/qutebrowser/browser/webkit/network/webkitqutescheme.py b/qutebrowser/browser/webkit/network/webkitqutescheme.py
index bccdd1acd..0fdc3b772 100644
--- a/qutebrowser/browser/webkit/network/webkitqutescheme.py
+++ b/qutebrowser/browser/webkit/network/webkitqutescheme.py
@@ -19,8 +19,7 @@
"""QtWebKit specific qute://* handlers and glue code."""
-from PyQt5.QtCore import QUrl
-from PyQt5.QtNetwork import QNetworkReply, QNetworkAccessManager
+from qutebrowser.qt import QtNetwork, QtCore
from qutebrowser.browser import qutescheme
from qutebrowser.browser.webkit.network import networkreply
@@ -38,37 +37,37 @@ def handler(request, operation, current_url):
Return:
A QNetworkReply.
"""
- if operation != QNetworkAccessManager.GetOperation:
+ if operation != QtNetwork.QNetworkAccessManager.GetOperation:
return networkreply.ErrorNetworkReply(
request, "Unsupported request type",
- QNetworkReply.ContentOperationNotPermittedError)
+ QtNetwork.QNetworkReply.ContentOperationNotPermittedError)
url = request.url()
if ((url.scheme(), url.host(), url.path()) ==
('qute', 'settings', '/set')):
- if current_url != QUrl('qute://settings/'):
+ if current_url != QtCore.QUrl('qute://settings/'):
log.network.warning("Blocking malicious request from {} to {}"
.format(current_url.toDisplayString(),
url.toDisplayString()))
return networkreply.ErrorNetworkReply(
request, "Invalid qute://settings request",
- QNetworkReply.ContentAccessDenied)
+ QtNetwork.QNetworkReply.ContentAccessDenied)
try:
mimetype, data = qutescheme.data_for_url(url)
except qutescheme.Error as e:
errors = {
qutescheme.NotFoundError:
- QNetworkReply.ContentNotFoundError,
+ QtNetwork.QNetworkReply.ContentNotFoundError,
qutescheme.UrlInvalidError:
- QNetworkReply.ContentOperationNotPermittedError,
+ QtNetwork.QNetworkReply.ContentOperationNotPermittedError,
qutescheme.RequestDeniedError:
- QNetworkReply.ContentAccessDenied,
+ QtNetwork.QNetworkReply.ContentAccessDenied,
qutescheme.SchemeOSError:
- QNetworkReply.ContentNotFoundError,
+ QtNetwork.QNetworkReply.ContentNotFoundError,
qutescheme.Error:
- QNetworkReply.InternalServerError,
+ QtNetwork.QNetworkReply.InternalServerError,
}
exctype = type(e)
log.misc.error("{} while handling qute://* URL".format(
diff --git a/qutebrowser/browser/webkit/tabhistory.py b/qutebrowser/browser/webkit/tabhistory.py
index a707030d1..02561bfc7 100644
--- a/qutebrowser/browser/webkit/tabhistory.py
+++ b/qutebrowser/browser/webkit/tabhistory.py
@@ -21,9 +21,8 @@
from typing import Any, List, Mapping
-from PyQt5.QtCore import QByteArray, QDataStream, QIODevice, QUrl
-
from qutebrowser.utils import qtutils
+from qutebrowser.qt import QtCore
def _serialize_items(items, current_idx, stream):
@@ -50,10 +49,10 @@ def _serialize_items(items, current_idx, stream):
def _serialize_item(item):
data = {
- 'originalURLString': item.original_url.toString(QUrl.FullyEncoded),
+ 'originalURLString': item.original_url.toString(QtCore.QUrl.FullyEncoded),
'scrollPosition': {'x': 0, 'y': 0},
'title': item.title,
- 'urlString': item.url.toString(QUrl.FullyEncoded),
+ 'urlString': item.url.toString(QtCore.QUrl.FullyEncoded),
}
try:
data['scrollPosition']['x'] = item.user_data['scroll-pos'].x()
@@ -79,8 +78,8 @@ def serialize(items):
If 'data' goes out of scope, reading from 'stream' will result in a
segfault!
"""
- data = QByteArray()
- stream = QDataStream(data, QIODevice.ReadWrite)
+ data = QtCore.QByteArray()
+ stream = QtCore.QDataStream(data, QtCore.QIODevice.ReadWrite)
user_data: List[Mapping[str, Any]] = []
current_idx = None
diff --git a/qutebrowser/browser/webkit/webkitelem.py b/qutebrowser/browser/webkit/webkitelem.py
index 5bf96a610..5b771f045 100644
--- a/qutebrowser/browser/webkit/webkitelem.py
+++ b/qutebrowser/browser/webkit/webkitelem.py
@@ -20,14 +20,12 @@
"""QtWebKit specific part of the web element API."""
from typing import cast, TYPE_CHECKING, Iterator, List, Optional, Set
-
-from PyQt5.QtCore import QRect, Qt
-from PyQt5.QtWebKit import QWebElement, QWebSettings
-from PyQt5.QtWebKitWidgets import QWebFrame
+from qutebrowser.qt import QtWebKitWidgets
from qutebrowser.config import config
from qutebrowser.utils import log, utils, javascript, usertypes
from qutebrowser.browser import webelem
+from qutebrowser.qt import QtWebKit, QtCore
if TYPE_CHECKING:
from qutebrowser.browser.webkit import webkittab
@@ -44,7 +42,7 @@ class WebKitElement(webelem.AbstractWebElement):
_tab: 'webkittab.WebKitTab'
- def __init__(self, elem: QWebElement, tab: 'webkittab.WebKitTab') -> None:
+ def __init__(self, elem: QtWebKit.QWebElement, tab: 'webkittab.WebKitTab') -> None:
super().__init__(tab)
if isinstance(elem, self.__class__):
raise TypeError("Trying to wrap a wrapper!")
@@ -99,7 +97,7 @@ class WebKitElement(webelem.AbstractWebElement):
self._check_vanished()
return self._elem.webFrame() is not None
- def geometry(self) -> QRect:
+ def geometry(self) -> QtCore.QRect:
self._check_vanished()
return self._elem.geometry()
@@ -179,13 +177,13 @@ class WebKitElement(webelem.AbstractWebElement):
def _parent(self) -> Optional['WebKitElement']:
"""Get the parent element of this element."""
self._check_vanished()
- elem = cast(Optional[QWebElement], self._elem.parent())
+ elem = cast(Optional[QtWebKit.QWebElement], self._elem.parent())
if elem is None or elem.isNull():
return None
return WebKitElement(elem, tab=self._tab)
- def _rect_on_view_js(self) -> Optional[QRect]:
+ def _rect_on_view_js(self) -> Optional[QtCore.QRect]:
"""Javascript implementation for rect_on_view."""
# FIXME:qtwebengine maybe we can reuse this?
rects = self._elem.evaluateJavaScript("this.getClientRects()")
@@ -212,10 +210,10 @@ class WebKitElement(webelem.AbstractWebElement):
rect["top"] *= zoom
width *= zoom
height *= zoom
- rect = QRect(int(rect["left"]), int(rect["top"]),
+ rect = QtCore.QRect(int(rect["left"]), int(rect["top"]),
int(width), int(height))
- frame = cast(Optional[QWebFrame], self._elem.webFrame())
+ frame = cast(Optional[QtWebKitWidgets.QWebFrame], self._elem.webFrame())
while frame is not None:
# Translate to parent frames' position (scroll position
# is taken care of inside getClientRects)
@@ -226,24 +224,24 @@ class WebKitElement(webelem.AbstractWebElement):
return None
- def _rect_on_view_python(self, elem_geometry: Optional[QRect]) -> QRect:
+ def _rect_on_view_python(self, elem_geometry: Optional[QtCore.QRect]) -> QtCore.QRect:
"""Python implementation for rect_on_view."""
if elem_geometry is None:
geometry = self._elem.geometry()
else:
geometry = elem_geometry
- rect = QRect(geometry)
+ rect = QtCore.QRect(geometry)
- frame = cast(Optional[QWebFrame], self._elem.webFrame())
+ frame = cast(Optional[QtWebKitWidgets.QWebFrame], self._elem.webFrame())
while frame is not None:
rect.translate(frame.geometry().topLeft())
rect.translate(frame.scrollPosition() * -1)
- frame = cast(Optional[QWebFrame], frame.parentFrame())
+ frame = cast(Optional[QtWebKitWidgets.QWebFrame], frame.parentFrame())
return rect
- def rect_on_view(self, *, elem_geometry: QRect = None,
- no_js: bool = False) -> QRect:
+ def rect_on_view(self, *, elem_geometry: QtCore.QRect = None,
+ no_js: bool = False) -> QtCore.QRect:
"""Get the geometry of the element relative to the webview.
Uses the getClientRects() JavaScript method to obtain the collection of
@@ -276,7 +274,7 @@ class WebKitElement(webelem.AbstractWebElement):
def _is_hidden_css(self) -> bool:
"""Check if the given element is hidden via CSS."""
attr_values = {
- attr: self._elem.styleProperty(attr, QWebElement.ComputedStyle)
+ attr: self._elem.styleProperty(attr, QtWebKit.QWebElement.ComputedStyle)
for attr in ['visibility', 'display', 'opacity']
}
invisible = attr_values['visibility'] == 'hidden'
@@ -287,7 +285,7 @@ class WebKitElement(webelem.AbstractWebElement):
'custom-control-input' in self.classes())
return invisible or none_display or (zero_opacity and not is_framework)
- def _is_visible(self, mainframe: QWebFrame) -> bool:
+ def _is_visible(self, mainframe: QtWebKitWidgets.QWebFrame) -> bool:
"""Check if the given element is visible in the given frame.
This is not public API because it can't be implemented easily here with
@@ -315,7 +313,7 @@ class WebKitElement(webelem.AbstractWebElement):
# Then check if it's visible in its frame if it's not in the main
# frame.
elem_frame = self._elem.webFrame()
- framegeom = QRect(elem_frame.geometry())
+ framegeom = QtCore.QRect(elem_frame.geometry())
if not framegeom.isValid():
visible_in_frame = False
elif elem_frame.parentFrame() is not None:
@@ -361,8 +359,8 @@ class WebKitElement(webelem.AbstractWebElement):
self._click_fake_event(click_target)
def _click_js(self, click_target: usertypes.ClickTarget) -> None:
- settings = QWebSettings.globalSettings()
- attribute = QWebSettings.JavascriptCanOpenWindows
+ settings = QtWebKit.QWebSettings.globalSettings()
+ attribute = QtWebKit.QWebSettings.JavascriptCanOpenWindows
could_open_windows = settings.testAttribute(attribute)
settings.setAttribute(attribute, True)
ok = self._elem.evaluateJavaScript('this.click(); true;')
@@ -372,12 +370,12 @@ class WebKitElement(webelem.AbstractWebElement):
self._click_fake_event(click_target)
def _click_fake_event(self, click_target: usertypes.ClickTarget,
- button: Qt.MouseButton = Qt.LeftButton) -> None:
+ button: QtCore.Qt.MouseButton = QtCore.Qt.LeftButton) -> None:
self._tab.data.override_target = click_target
super()._click_fake_event(click_target)
-def get_child_frames(startframe: QWebFrame) -> List[QWebFrame]:
+def get_child_frames(startframe: QtWebKitWidgets.QWebFrame) -> List[QtWebKitWidgets.QWebFrame]:
"""Get all children recursively of a given QWebFrame.
Loosely based on https://blog.nextgenetics.net/?e=64
@@ -391,7 +389,7 @@ def get_child_frames(startframe: QWebFrame) -> List[QWebFrame]:
results = []
frames = [startframe]
while frames:
- new_frames: List[QWebFrame] = []
+ new_frames: List[QtWebKitWidgets.QWebFrame] = []
for frame in frames:
results.append(frame)
new_frames += frame.childFrames()
diff --git a/qutebrowser/browser/webkit/webkithistory.py b/qutebrowser/browser/webkit/webkithistory.py
index 6ffe65193..ed33522f9 100644
--- a/qutebrowser/browser/webkit/webkithistory.py
+++ b/qutebrowser/browser/webkit/webkithistory.py
@@ -21,13 +21,13 @@
import functools
-from PyQt5.QtWebKit import QWebHistoryInterface
+from qutebrowser.qt import QtWebKit
from qutebrowser.utils import debug
from qutebrowser.misc import debugcachestats
-class WebHistoryInterface(QWebHistoryInterface):
+class WebHistoryInterface(QtWebKit.QWebHistoryInterface):
"""Glue code between WebHistory and Qt's QWebHistoryInterface.
@@ -65,4 +65,4 @@ def init(history):
history: The WebHistory object.
"""
interface = WebHistoryInterface(history, parent=history)
- QWebHistoryInterface.setDefaultInterface(interface)
+ QtWebKit.QWebHistoryInterface.setDefaultInterface(interface)
diff --git a/qutebrowser/browser/webkit/webkitinspector.py b/qutebrowser/browser/webkit/webkitinspector.py
index 57bcd40ea..a90673b2b 100644
--- a/qutebrowser/browser/webkit/webkitinspector.py
+++ b/qutebrowser/browser/webkit/webkitinspector.py
@@ -19,9 +19,7 @@
"""Customized QWebInspector for QtWebKit."""
-from PyQt5.QtWebKit import QWebSettings
-from PyQt5.QtWebKitWidgets import QWebInspector, QWebPage
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt import QtWidgets, QtWebKitWidgets, QtWebKit
from qutebrowser.browser import inspector
from qutebrowser.misc import miscwidgets
@@ -33,12 +31,12 @@ class WebKitInspector(inspector.AbstractWebInspector):
def __init__(self, splitter: miscwidgets.InspectorSplitter,
win_id: int,
- parent: QWidget = None) -> None:
+ parent: QtWidgets.QWidget = None) -> None:
super().__init__(splitter, win_id, parent)
- qwebinspector = QWebInspector()
+ qwebinspector = QtWebKitWidgets.QWebInspector()
self._set_widget(qwebinspector)
- def inspect(self, page: QWebPage) -> None: # type: ignore[override]
- settings = QWebSettings.globalSettings()
- settings.setAttribute(QWebSettings.DeveloperExtrasEnabled, True)
+ def inspect(self, page: QtWebKitWidgets.QWebPage) -> None: # type: ignore[override]
+ settings = QtWebKit.QWebSettings.globalSettings()
+ settings.setAttribute(QtWebKit.QWebSettings.DeveloperExtrasEnabled, True)
self._widget.setPage(page)
diff --git a/qutebrowser/browser/webkit/webkitsettings.py b/qutebrowser/browser/webkit/webkitsettings.py
index cac6236ce..083dd7aeb 100644
--- a/qutebrowser/browser/webkit/webkitsettings.py
+++ b/qutebrowser/browser/webkit/webkitsettings.py
@@ -27,10 +27,7 @@ Module attributes:
from typing import cast
import os.path
-from PyQt5.QtCore import QUrl
-from PyQt5.QtGui import QFont
-from PyQt5.QtWebKit import QWebSettings
-from PyQt5.QtWebKitWidgets import QWebPage
+from qutebrowser.qt import QtWebKitWidgets, QtWebKit, QtGui, QtCore
from qutebrowser.config import config, websettings
from qutebrowser.config.websettings import AttributeInfo as Attr
@@ -50,81 +47,81 @@ class WebKitSettings(websettings.AbstractSettings):
_ATTRIBUTES = {
'content.images':
- Attr(QWebSettings.AutoLoadImages),
+ Attr(QtWebKit.QWebSettings.AutoLoadImages),
'content.javascript.enabled':
- Attr(QWebSettings.JavascriptEnabled),
+ Attr(QtWebKit.QWebSettings.JavascriptEnabled),
'content.javascript.can_open_tabs_automatically':
- Attr(QWebSettings.JavascriptCanOpenWindows),
+ Attr(QtWebKit.QWebSettings.JavascriptCanOpenWindows),
'content.javascript.can_close_tabs':
- Attr(QWebSettings.JavascriptCanCloseWindows),
+ Attr(QtWebKit.QWebSettings.JavascriptCanCloseWindows),
'content.javascript.can_access_clipboard':
- Attr(QWebSettings.JavascriptCanAccessClipboard),
+ Attr(QtWebKit.QWebSettings.JavascriptCanAccessClipboard),
'content.plugins':
- Attr(QWebSettings.PluginsEnabled),
+ Attr(QtWebKit.QWebSettings.PluginsEnabled),
'content.webgl':
- Attr(QWebSettings.WebGLEnabled),
+ Attr(QtWebKit.QWebSettings.WebGLEnabled),
'content.hyperlink_auditing':
- Attr(QWebSettings.HyperlinkAuditingEnabled),
+ Attr(QtWebKit.QWebSettings.HyperlinkAuditingEnabled),
'content.local_content_can_access_remote_urls':
- Attr(QWebSettings.LocalContentCanAccessRemoteUrls),
+ Attr(QtWebKit.QWebSettings.LocalContentCanAccessRemoteUrls),
'content.local_content_can_access_file_urls':
- Attr(QWebSettings.LocalContentCanAccessFileUrls),
+ Attr(QtWebKit.QWebSettings.LocalContentCanAccessFileUrls),
'content.dns_prefetch':
- Attr(QWebSettings.DnsPrefetchEnabled),
+ Attr(QtWebKit.QWebSettings.DnsPrefetchEnabled),
'content.frame_flattening':
- Attr(QWebSettings.FrameFlatteningEnabled),
+ Attr(QtWebKit.QWebSettings.FrameFlatteningEnabled),
'content.cache.appcache':
- Attr(QWebSettings.OfflineWebApplicationCacheEnabled),
+ Attr(QtWebKit.QWebSettings.OfflineWebApplicationCacheEnabled),
'content.local_storage':
- Attr(QWebSettings.LocalStorageEnabled,
- QWebSettings.OfflineStorageDatabaseEnabled),
+ Attr(QtWebKit.QWebSettings.LocalStorageEnabled,
+ QtWebKit.QWebSettings.OfflineStorageDatabaseEnabled),
'content.print_element_backgrounds':
- Attr(QWebSettings.PrintElementBackgrounds),
+ Attr(QtWebKit.QWebSettings.PrintElementBackgrounds),
'content.xss_auditing':
- Attr(QWebSettings.XSSAuditingEnabled),
+ Attr(QtWebKit.QWebSettings.XSSAuditingEnabled),
'content.site_specific_quirks.enabled':
- Attr(QWebSettings.SiteSpecificQuirksEnabled),
+ Attr(QtWebKit.QWebSettings.SiteSpecificQuirksEnabled),
'input.spatial_navigation':
- Attr(QWebSettings.SpatialNavigationEnabled),
+ Attr(QtWebKit.QWebSettings.SpatialNavigationEnabled),
'input.links_included_in_focus_chain':
- Attr(QWebSettings.LinksIncludedInFocusChain),
+ Attr(QtWebKit.QWebSettings.LinksIncludedInFocusChain),
'zoom.text_only':
- Attr(QWebSettings.ZoomTextOnly),
+ Attr(QtWebKit.QWebSettings.ZoomTextOnly),
'scrolling.smooth':
- Attr(QWebSettings.ScrollAnimatorEnabled),
+ Attr(QtWebKit.QWebSettings.ScrollAnimatorEnabled),
}
_FONT_SIZES = {
'fonts.web.size.minimum':
- QWebSettings.MinimumFontSize,
+ QtWebKit.QWebSettings.MinimumFontSize,
'fonts.web.size.minimum_logical':
- QWebSettings.MinimumLogicalFontSize,
+ QtWebKit.QWebSettings.MinimumLogicalFontSize,
'fonts.web.size.default':
- QWebSettings.DefaultFontSize,
+ QtWebKit.QWebSettings.DefaultFontSize,
'fonts.web.size.default_fixed':
- QWebSettings.DefaultFixedFontSize,
+ QtWebKit.QWebSettings.DefaultFixedFontSize,
}
_FONT_FAMILIES = {
- 'fonts.web.family.standard': QWebSettings.StandardFont,
- 'fonts.web.family.fixed': QWebSettings.FixedFont,
- 'fonts.web.family.serif': QWebSettings.SerifFont,
- 'fonts.web.family.sans_serif': QWebSettings.SansSerifFont,
- 'fonts.web.family.cursive': QWebSettings.CursiveFont,
- 'fonts.web.family.fantasy': QWebSettings.FantasyFont,
+ 'fonts.web.family.standard': QtWebKit.QWebSettings.StandardFont,
+ 'fonts.web.family.fixed': QtWebKit.QWebSettings.FixedFont,
+ 'fonts.web.family.serif': QtWebKit.QWebSettings.SerifFont,
+ 'fonts.web.family.sans_serif': QtWebKit.QWebSettings.SansSerifFont,
+ 'fonts.web.family.cursive': QtWebKit.QWebSettings.CursiveFont,
+ 'fonts.web.family.fantasy': QtWebKit.QWebSettings.FantasyFont,
}
# Mapping from QWebSettings::QWebSettings() in
# qtwebkit/Source/WebKit/qt/Api/qwebsettings.cpp
_FONT_TO_QFONT = {
- QWebSettings.StandardFont: QFont.Serif,
- QWebSettings.FixedFont: QFont.Monospace,
- QWebSettings.SerifFont: QFont.Serif,
- QWebSettings.SansSerifFont: QFont.SansSerif,
- QWebSettings.CursiveFont: QFont.Cursive,
- QWebSettings.FantasyFont: QFont.Fantasy,
+ QtWebKit.QWebSettings.StandardFont: QtGui.QFont.Serif,
+ QtWebKit.QWebSettings.FixedFont: QtGui.QFont.Monospace,
+ QtWebKit.QWebSettings.SerifFont: QtGui.QFont.Serif,
+ QtWebKit.QWebSettings.SansSerifFont: QtGui.QFont.SansSerif,
+ QtWebKit.QWebSettings.CursiveFont: QtGui.QFont.Cursive,
+ QtWebKit.QWebSettings.FantasyFont: QtGui.QFont.Fantasy,
}
@@ -138,10 +135,10 @@ def _set_user_stylesheet(settings):
def _set_cookie_accept_policy(settings):
"""Update the content.cookies.accept setting."""
mapping = {
- 'all': QWebSettings.AlwaysAllowThirdPartyCookies,
- 'no-3rdparty': QWebSettings.AlwaysBlockThirdPartyCookies,
- 'never': QWebSettings.AlwaysBlockThirdPartyCookies,
- 'no-unknown-3rdparty': QWebSettings.AllowThirdPartyWithExistingCookies,
+ 'all': QtWebKit.QWebSettings.AlwaysAllowThirdPartyCookies,
+ 'no-3rdparty': QtWebKit.QWebSettings.AlwaysBlockThirdPartyCookies,
+ 'never': QtWebKit.QWebSettings.AlwaysBlockThirdPartyCookies,
+ 'no-unknown-3rdparty': QtWebKit.QWebSettings.AllowThirdPartyWithExistingCookies,
}
value = config.val.content.cookies.accept
settings.setThirdPartyCookiePolicy(mapping[value])
@@ -157,7 +154,7 @@ def _update_settings(option):
"""Update global settings when qwebsettings changed."""
global_settings.update_setting(option)
- settings = QWebSettings.globalSettings()
+ settings = QtWebKit.QWebSettings.globalSettings()
if option in ['scrollbar.hide', 'content.user_stylesheets']:
_set_user_stylesheet(settings)
elif option == 'content.cookies.accept':
@@ -168,7 +165,7 @@ def _update_settings(option):
def _init_user_agent():
global parsed_user_agent
- ua = QWebPage().userAgentForUrl(QUrl())
+ ua = QtWebKitWidgets.QWebPage().userAgentForUrl(QtCore.QUrl())
parsed_user_agent = websettings.UserAgent.parse(ua)
@@ -177,15 +174,15 @@ def init():
cache_path = standarddir.cache()
data_path = standarddir.data()
- QWebSettings.setIconDatabasePath(standarddir.cache())
- QWebSettings.setOfflineWebApplicationCachePath(
+ QtWebKit.QWebSettings.setIconDatabasePath(standarddir.cache())
+ QtWebKit.QWebSettings.setOfflineWebApplicationCachePath(
os.path.join(cache_path, 'application-cache'))
- QWebSettings.globalSettings().setLocalStoragePath(
+ QtWebKit.QWebSettings.globalSettings().setLocalStoragePath(
os.path.join(data_path, 'local-storage'))
- QWebSettings.setOfflineStoragePath(
+ QtWebKit.QWebSettings.setOfflineStoragePath(
os.path.join(data_path, 'offline-storage'))
- settings = QWebSettings.globalSettings()
+ settings = QtWebKit.QWebSettings.globalSettings()
_set_user_stylesheet(settings)
_set_cookie_accept_policy(settings)
_set_cache_maximum_pages(settings)
@@ -195,12 +192,12 @@ def init():
config.instance.changed.connect(_update_settings)
global global_settings
- global_settings = WebKitSettings(QWebSettings.globalSettings())
+ global_settings = WebKitSettings(QtWebKit.QWebSettings.globalSettings())
global_settings.init_settings()
def shutdown():
"""Disable storage so removing tmpdir will work."""
- QWebSettings.setIconDatabasePath('')
- QWebSettings.setOfflineWebApplicationCachePath('')
- QWebSettings.globalSettings().setLocalStoragePath('')
+ QtWebKit.QWebSettings.setIconDatabasePath('')
+ QtWebKit.QWebSettings.setOfflineWebApplicationCachePath('')
+ QtWebKit.QWebSettings.globalSettings().setLocalStoragePath('')
diff --git a/qutebrowser/browser/webkit/webkittab.py b/qutebrowser/browser/webkit/webkittab.py
index 7a41b995c..5839ccfb8 100644
--- a/qutebrowser/browser/webkit/webkittab.py
+++ b/qutebrowser/browser/webkit/webkittab.py
@@ -23,28 +23,22 @@ import re
import functools
import xml.etree.ElementTree
from typing import cast, Iterable, Optional
-
-from PyQt5.QtCore import pyqtSlot, Qt, QUrl, QPoint, QTimer, QSizeF, QSize
-from PyQt5.QtGui import QIcon
-from PyQt5.QtWidgets import QWidget
-from PyQt5.QtWebKitWidgets import QWebPage, QWebFrame
-from PyQt5.QtWebKit import QWebSettings, QWebHistory, QWebElement
-from PyQt5.QtPrintSupport import QPrinter
+from qutebrowser.qt import QtWidgets, QtWebKitWidgets, QtWebKit, QtPrintSupport, QtGui
from qutebrowser.browser import browsertab, shared
from qutebrowser.browser.webkit import (webview, tabhistory, webkitelem,
webkitsettings, webkitinspector)
from qutebrowser.utils import qtutils, usertypes, utils, log, debug, resources
from qutebrowser.keyinput import modeman
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
class WebKitAction(browsertab.AbstractAction):
"""QtWebKit implementations related to web actions."""
- action_class = QWebPage
- action_base = QWebPage.WebAction
+ action_class = QtWebKitWidgets.QWebPage
+ action_base = QtWebKitWidgets.QWebPage.WebAction
def exit_fullscreen(self):
raise browsertab.UnsupportedOperationError
@@ -64,9 +58,9 @@ class WebKitAction(browsertab.AbstractAction):
"""
new_actions = {
# https://github.com/qtwebkit/qtwebkit/commit/a96d9ef5d24b02d996ad14ff050d0e485c9ddc97
- 'RequestClose': QWebPage.ToggleVideoFullscreen + 1,
+ 'RequestClose': QtWebKitWidgets.QWebPage.ToggleVideoFullscreen + 1,
# https://github.com/qtwebkit/qtwebkit/commit/96b9ba6269a5be44343635a7aaca4a153ea0366b
- 'Unselect': QWebPage.ToggleVideoFullscreen + 2,
+ 'Unselect': QtWebKitWidgets.QWebPage.ToggleVideoFullscreen + 2,
}
if name in new_actions:
self._widget.triggerPageAction(new_actions[name])
@@ -86,7 +80,7 @@ class WebKitPrinting(browsertab.AbstractPrinting):
pass
def to_pdf(self, filename):
- printer = QPrinter()
+ printer = QtPrintSupport.QPrinter()
printer.setOutputFileName(filename)
self.to_printer(printer)
@@ -106,16 +100,16 @@ class WebKitSearch(browsertab.AbstractSearch):
self._flags = self._empty_flags()
def _empty_flags(self):
- return QWebPage.FindFlags(0) # type: ignore[call-overload]
+ return QtWebKitWidgets.QWebPage.FindFlags(0) # type: ignore[call-overload]
def _args_to_flags(self, reverse, ignore_case, wrap):
flags = self._empty_flags()
if self._is_case_sensitive(ignore_case):
- flags |= QWebPage.FindCaseSensitively
+ flags |= QtWebKitWidgets.QWebPage.FindCaseSensitively
if reverse:
- flags |= QWebPage.FindBackward
+ flags |= QtWebKitWidgets.QWebPage.FindBackward
if wrap:
- flags |= QWebPage.FindWrapsAroundDocument
+ flags |= QtWebKitWidgets.QWebPage.FindWrapsAroundDocument
return flags
def _call_cb(self, callback, found, text, flags, caller):
@@ -134,8 +128,8 @@ class WebKitSearch(browsertab.AbstractSearch):
# Removing FindWrapsAroundDocument to get the same logging as with
# QtWebEngine
debug_flags = debug.qflags_key(
- QWebPage, flags & ~QWebPage.FindWrapsAroundDocument,
- klass=QWebPage.FindFlag)
+ QtWebKitWidgets.QWebPage, flags & ~QtWebKitWidgets.QWebPage.FindWrapsAroundDocument,
+ klass=QtWebKitWidgets.QWebPage.FindFlag)
if debug_flags != '0x0000':
flag_text = 'with flags {}'.format(debug_flags)
else:
@@ -143,7 +137,7 @@ class WebKitSearch(browsertab.AbstractSearch):
log.webview.debug(' '.join([caller, found_text, text, flag_text])
.strip())
if callback is not None:
- QTimer.singleShot(0, functools.partial(callback, found))
+ QtCore.QTimer.singleShot(0, functools.partial(callback, found))
self.finished.emit(found)
@@ -153,7 +147,7 @@ class WebKitSearch(browsertab.AbstractSearch):
self.search_displayed = False
# We first clear the marked text, then the highlights
self._widget.findText('')
- self._widget.findText('', QWebPage.HighlightAllOccurrences)
+ self._widget.findText('', QtWebKitWidgets.QWebPage.HighlightAllOccurrences)
def search(self, text, *, ignore_case=usertypes.IgnoreCase.never,
reverse=False, wrap=True, result_cb=None):
@@ -174,7 +168,7 @@ class WebKitSearch(browsertab.AbstractSearch):
# to get a mark so we can navigate.
found = self._widget.findText(text, self._flags)
self._widget.findText(text,
- self._flags | QWebPage.HighlightAllOccurrences)
+ self._flags | QtWebKitWidgets.QWebPage.HighlightAllOccurrences)
self._call_cb(result_cb, found, text, self._flags, 'search')
def next_result(self, *, result_cb=None):
@@ -185,12 +179,12 @@ class WebKitSearch(browsertab.AbstractSearch):
def prev_result(self, *, result_cb=None):
self.search_displayed = True
# The int() here makes sure we get a copy of the flags.
- flags = QWebPage.FindFlags(
+ flags = QtWebKitWidgets.QWebPage.FindFlags(
int(self._flags)) # type: ignore[call-overload]
- if flags & QWebPage.FindBackward:
- flags &= ~QWebPage.FindBackward
+ if flags & QtWebKitWidgets.QWebPage.FindBackward:
+ flags &= ~QtWebKitWidgets.QWebPage.FindBackward
else:
- flags |= QWebPage.FindBackward
+ flags |= QtWebKitWidgets.QWebPage.FindBackward
found = self._widget.findText(self.text, flags)
self._call_cb(result_cb, found, self.text, flags, 'prev_result')
@@ -202,11 +196,11 @@ class WebKitCaret(browsertab.AbstractCaret):
def __init__(self,
tab: 'WebKitTab',
mode_manager: modeman.ModeManager,
- parent: QWidget = None) -> None:
+ parent: QtWidgets.QWidget = None) -> None:
super().__init__(tab, mode_manager, parent)
self._selection_state = browsertab.SelectionState.none
- @pyqtSlot(usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode)
def _on_mode_entered(self, mode):
if mode != usertypes.KeyMode.caret:
return
@@ -217,13 +211,13 @@ class WebKitCaret(browsertab.AbstractCaret):
self._selection_state = browsertab.SelectionState.none
self.selection_toggled.emit(self._selection_state)
settings = self._widget.settings()
- settings.setAttribute(QWebSettings.CaretBrowsingEnabled, True)
+ settings.setAttribute(QtWebKit.QWebSettings.CaretBrowsingEnabled, True)
if self._widget.isVisible():
# Sometimes the caret isn't immediately visible, but unfocusing
# and refocusing it fixes that.
self._widget.clearFocus()
- self._widget.setFocus(Qt.OtherFocusReason)
+ self._widget.setFocus(QtCore.Qt.OtherFocusReason)
# Move the caret to the first element in the viewport if there
# isn't any text which is already selected.
@@ -234,22 +228,22 @@ class WebKitCaret(browsertab.AbstractCaret):
self._widget.page().currentFrame().evaluateJavaScript(
resources.read_file('javascript/position_caret.js'))
- @pyqtSlot(usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode)
def _on_mode_left(self, _mode):
settings = self._widget.settings()
- if settings.testAttribute(QWebSettings.CaretBrowsingEnabled):
+ if settings.testAttribute(QtWebKit.QWebSettings.CaretBrowsingEnabled):
if (self._selection_state is not browsertab.SelectionState.none and
self._widget.hasSelection()):
# Remove selection if it exists
- self._widget.triggerPageAction(QWebPage.MoveToNextChar)
- settings.setAttribute(QWebSettings.CaretBrowsingEnabled, False)
+ self._widget.triggerPageAction(QtWebKitWidgets.QWebPage.MoveToNextChar)
+ settings.setAttribute(QtWebKit.QWebSettings.CaretBrowsingEnabled, False)
self._selection_state = browsertab.SelectionState.none
def move_to_next_line(self, count=1):
if self._selection_state is not browsertab.SelectionState.none:
- act = QWebPage.SelectNextLine
+ act = QtWebKitWidgets.QWebPage.SelectNextLine
else:
- act = QWebPage.MoveToNextLine
+ act = QtWebKitWidgets.QWebPage.MoveToNextLine
for _ in range(count):
self._widget.triggerPageAction(act)
if self._selection_state is browsertab.SelectionState.line:
@@ -257,9 +251,9 @@ class WebKitCaret(browsertab.AbstractCaret):
def move_to_prev_line(self, count=1):
if self._selection_state is not browsertab.SelectionState.none:
- act = QWebPage.SelectPreviousLine
+ act = QtWebKitWidgets.QWebPage.SelectPreviousLine
else:
- act = QWebPage.MoveToPreviousLine
+ act = QtWebKitWidgets.QWebPage.MoveToPreviousLine
for _ in range(count):
self._widget.triggerPageAction(act)
if self._selection_state is browsertab.SelectionState.line:
@@ -267,89 +261,89 @@ class WebKitCaret(browsertab.AbstractCaret):
def move_to_next_char(self, count=1):
if self._selection_state is browsertab.SelectionState.normal:
- act = QWebPage.SelectNextChar
+ act = QtWebKitWidgets.QWebPage.SelectNextChar
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = QWebPage.MoveToNextChar
+ act = QtWebKitWidgets.QWebPage.MoveToNextChar
for _ in range(count):
self._widget.triggerPageAction(act)
def move_to_prev_char(self, count=1):
if self._selection_state is browsertab.SelectionState.normal:
- act = QWebPage.SelectPreviousChar
+ act = QtWebKitWidgets.QWebPage.SelectPreviousChar
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = QWebPage.MoveToPreviousChar
+ act = QtWebKitWidgets.QWebPage.MoveToPreviousChar
for _ in range(count):
self._widget.triggerPageAction(act)
def move_to_end_of_word(self, count=1):
if self._selection_state is browsertab.SelectionState.normal:
- act = [QWebPage.SelectNextWord]
+ act = [QtWebKitWidgets.QWebPage.SelectNextWord]
if utils.is_windows: # pragma: no cover
- act.append(QWebPage.SelectPreviousChar)
+ act.append(QtWebKitWidgets.QWebPage.SelectPreviousChar)
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = [QWebPage.MoveToNextWord]
+ act = [QtWebKitWidgets.QWebPage.MoveToNextWord]
if utils.is_windows: # pragma: no cover
- act.append(QWebPage.MoveToPreviousChar)
+ act.append(QtWebKitWidgets.QWebPage.MoveToPreviousChar)
for _ in range(count):
for a in act:
self._widget.triggerPageAction(a)
def move_to_next_word(self, count=1):
if self._selection_state is browsertab.SelectionState.normal:
- act = [QWebPage.SelectNextWord]
+ act = [QtWebKitWidgets.QWebPage.SelectNextWord]
if not utils.is_windows: # pragma: no branch
- act.append(QWebPage.SelectNextChar)
+ act.append(QtWebKitWidgets.QWebPage.SelectNextChar)
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = [QWebPage.MoveToNextWord]
+ act = [QtWebKitWidgets.QWebPage.MoveToNextWord]
if not utils.is_windows: # pragma: no branch
- act.append(QWebPage.MoveToNextChar)
+ act.append(QtWebKitWidgets.QWebPage.MoveToNextChar)
for _ in range(count):
for a in act:
self._widget.triggerPageAction(a)
def move_to_prev_word(self, count=1):
if self._selection_state is browsertab.SelectionState.normal:
- act = QWebPage.SelectPreviousWord
+ act = QtWebKitWidgets.QWebPage.SelectPreviousWord
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = QWebPage.MoveToPreviousWord
+ act = QtWebKitWidgets.QWebPage.MoveToPreviousWord
for _ in range(count):
self._widget.triggerPageAction(act)
def move_to_start_of_line(self):
if self._selection_state is browsertab.SelectionState.normal:
- act = QWebPage.SelectStartOfLine
+ act = QtWebKitWidgets.QWebPage.SelectStartOfLine
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = QWebPage.MoveToStartOfLine
+ act = QtWebKitWidgets.QWebPage.MoveToStartOfLine
self._widget.triggerPageAction(act)
def move_to_end_of_line(self):
if self._selection_state is browsertab.SelectionState.normal:
- act = QWebPage.SelectEndOfLine
+ act = QtWebKitWidgets.QWebPage.SelectEndOfLine
elif self._selection_state is browsertab.SelectionState.line:
return
else:
- act = QWebPage.MoveToEndOfLine
+ act = QtWebKitWidgets.QWebPage.MoveToEndOfLine
self._widget.triggerPageAction(act)
def move_to_start_of_next_block(self, count=1):
if self._selection_state is not browsertab.SelectionState.none:
- act = [QWebPage.SelectNextLine,
- QWebPage.SelectStartOfBlock]
+ act = [QtWebKitWidgets.QWebPage.SelectNextLine,
+ QtWebKitWidgets.QWebPage.SelectStartOfBlock]
else:
- act = [QWebPage.MoveToNextLine,
- QWebPage.MoveToStartOfBlock]
+ act = [QtWebKitWidgets.QWebPage.MoveToNextLine,
+ QtWebKitWidgets.QWebPage.MoveToStartOfBlock]
for _ in range(count):
for a in act:
self._widget.triggerPageAction(a)
@@ -358,11 +352,11 @@ class WebKitCaret(browsertab.AbstractCaret):
def move_to_start_of_prev_block(self, count=1):
if self._selection_state is not browsertab.SelectionState.none:
- act = [QWebPage.SelectPreviousLine,
- QWebPage.SelectStartOfBlock]
+ act = [QtWebKitWidgets.QWebPage.SelectPreviousLine,
+ QtWebKitWidgets.QWebPage.SelectStartOfBlock]
else:
- act = [QWebPage.MoveToPreviousLine,
- QWebPage.MoveToStartOfBlock]
+ act = [QtWebKitWidgets.QWebPage.MoveToPreviousLine,
+ QtWebKitWidgets.QWebPage.MoveToStartOfBlock]
for _ in range(count):
for a in act:
self._widget.triggerPageAction(a)
@@ -371,11 +365,11 @@ class WebKitCaret(browsertab.AbstractCaret):
def move_to_end_of_next_block(self, count=1):
if self._selection_state is not browsertab.SelectionState.none:
- act = [QWebPage.SelectNextLine,
- QWebPage.SelectEndOfBlock]
+ act = [QtWebKitWidgets.QWebPage.SelectNextLine,
+ QtWebKitWidgets.QWebPage.SelectEndOfBlock]
else:
- act = [QWebPage.MoveToNextLine,
- QWebPage.MoveToEndOfBlock]
+ act = [QtWebKitWidgets.QWebPage.MoveToNextLine,
+ QtWebKitWidgets.QWebPage.MoveToEndOfBlock]
for _ in range(count):
for a in act:
self._widget.triggerPageAction(a)
@@ -384,9 +378,9 @@ class WebKitCaret(browsertab.AbstractCaret):
def move_to_end_of_prev_block(self, count=1):
if self._selection_state is not browsertab.SelectionState.none:
- act = [QWebPage.SelectPreviousLine, QWebPage.SelectEndOfBlock]
+ act = [QtWebKitWidgets.QWebPage.SelectPreviousLine, QtWebKitWidgets.QWebPage.SelectEndOfBlock]
else:
- act = [QWebPage.MoveToPreviousLine, QWebPage.MoveToEndOfBlock]
+ act = [QtWebKitWidgets.QWebPage.MoveToPreviousLine, QtWebKitWidgets.QWebPage.MoveToEndOfBlock]
for _ in range(count):
for a in act:
self._widget.triggerPageAction(a)
@@ -395,18 +389,18 @@ class WebKitCaret(browsertab.AbstractCaret):
def move_to_start_of_document(self):
if self._selection_state is not browsertab.SelectionState.none:
- act = QWebPage.SelectStartOfDocument
+ act = QtWebKitWidgets.QWebPage.SelectStartOfDocument
else:
- act = QWebPage.MoveToStartOfDocument
+ act = QtWebKitWidgets.QWebPage.MoveToStartOfDocument
self._widget.triggerPageAction(act)
if self._selection_state is browsertab.SelectionState.line:
self._select_line()
def move_to_end_of_document(self):
if self._selection_state is not browsertab.SelectionState.none:
- act = QWebPage.SelectEndOfDocument
+ act = QtWebKitWidgets.QWebPage.SelectEndOfDocument
else:
- act = QWebPage.MoveToEndOfDocument
+ act = QtWebKitWidgets.QWebPage.MoveToEndOfDocument
self._widget.triggerPageAction(act)
def toggle_selection(self, line=False):
@@ -423,7 +417,7 @@ class WebKitCaret(browsertab.AbstractCaret):
self.selection_toggled.emit(self._selection_state)
def drop_selection(self):
- self._widget.triggerPageAction(QWebPage.MoveToNextChar)
+ self._widget.triggerPageAction(QtWebKitWidgets.QWebPage.MoveToNextChar)
def selection(self, callback):
callback(self._widget.selectedText())
@@ -438,9 +432,9 @@ class WebKitCaret(browsertab.AbstractCaret):
}""")
def _select_line(self):
- self._widget.triggerPageAction(QWebPage.SelectStartOfLine)
+ self._widget.triggerPageAction(QtWebKitWidgets.QWebPage.SelectStartOfLine)
self.reverse_selection()
- self._widget.triggerPageAction(QWebPage.SelectEndOfLine)
+ self._widget.triggerPageAction(QtWebKitWidgets.QWebPage.SelectEndOfLine)
self.reverse_selection()
def _select_line_to_end(self):
@@ -448,11 +442,11 @@ class WebKitCaret(browsertab.AbstractCaret):
# of focus) has to be checked before moving selection
# to the end of line
if self._js_selection_left_to_right():
- self._widget.triggerPageAction(QWebPage.SelectEndOfLine)
+ self._widget.triggerPageAction(QtWebKitWidgets.QWebPage.SelectEndOfLine)
def _select_line_to_start(self):
if not self._js_selection_left_to_right():
- self._widget.triggerPageAction(QWebPage.SelectStartOfLine)
+ self._widget.triggerPageAction(QtWebKitWidgets.QWebPage.SelectStartOfLine)
def _js_selection_left_to_right(self):
"""Return True iff the selection's direction is left to right."""
@@ -464,8 +458,8 @@ class WebKitCaret(browsertab.AbstractCaret):
""")
def _follow_selected(self, *, tab=False):
- if QWebSettings.globalSettings().testAttribute(
- QWebSettings.JavascriptEnabled):
+ if QtWebKit.QWebSettings.globalSettings().testAttribute(
+ QtWebKit.QWebSettings.JavascriptEnabled):
if tab:
self._tab.data.override_target = usertypes.ClickTarget.tab
self._tab.run_js_async("""
@@ -498,7 +492,7 @@ class WebKitCaret(browsertab.AbstractCaret):
except KeyError:
raise browsertab.WebTabError('Anchor element without '
'href!')
- url = self._tab.url().resolved(QUrl(href))
+ url = self._tab.url().resolved(QtCore.QUrl(href))
if tab:
self._tab.new_tab_requested.emit(url)
else:
@@ -563,7 +557,7 @@ class WebKitScroller(browsertab.AbstractScroller):
elif x is None and y == 100:
self.bottom()
else:
- for val, orientation in [(x, Qt.Horizontal), (y, Qt.Vertical)]:
+ for val, orientation in [(x, QtCore.Qt.Horizontal), (y, QtCore.Qt.Vertical)]:
if val is not None:
frame = self._widget.page().mainFrame()
maximum = frame.scrollBarMaximum(orientation)
@@ -588,36 +582,36 @@ class WebKitScroller(browsertab.AbstractScroller):
self._tab.fake_key_press(key)
def up(self, count=1):
- self._key_press(Qt.Key_Up, count, 'scrollBarMinimum', Qt.Vertical)
+ self._key_press(QtCore.Qt.Key_Up, count, 'scrollBarMinimum', QtCore.Qt.Vertical)
def down(self, count=1):
- self._key_press(Qt.Key_Down, count, 'scrollBarMaximum', Qt.Vertical)
+ self._key_press(QtCore.Qt.Key_Down, count, 'scrollBarMaximum', QtCore.Qt.Vertical)
def left(self, count=1):
- self._key_press(Qt.Key_Left, count, 'scrollBarMinimum', Qt.Horizontal)
+ self._key_press(QtCore.Qt.Key_Left, count, 'scrollBarMinimum', QtCore.Qt.Horizontal)
def right(self, count=1):
- self._key_press(Qt.Key_Right, count, 'scrollBarMaximum', Qt.Horizontal)
+ self._key_press(QtCore.Qt.Key_Right, count, 'scrollBarMaximum', QtCore.Qt.Horizontal)
def top(self):
- self._key_press(Qt.Key_Home)
+ self._key_press(QtCore.Qt.Key_Home)
def bottom(self):
- self._key_press(Qt.Key_End)
+ self._key_press(QtCore.Qt.Key_End)
def page_up(self, count=1):
- self._key_press(Qt.Key_PageUp, count, 'scrollBarMinimum', Qt.Vertical)
+ self._key_press(QtCore.Qt.Key_PageUp, count, 'scrollBarMinimum', QtCore.Qt.Vertical)
def page_down(self, count=1):
- self._key_press(Qt.Key_PageDown, count, 'scrollBarMaximum',
- Qt.Vertical)
+ self._key_press(QtCore.Qt.Key_PageDown, count, 'scrollBarMaximum',
+ QtCore.Qt.Vertical)
def at_top(self):
return self.pos_px().y() == 0
def at_bottom(self):
frame = self._widget.page().currentFrame()
- return self.pos_px().y() >= frame.scrollBarMaximum(Qt.Vertical)
+ return self.pos_px().y() >= frame.scrollBarMaximum(QtCore.Qt.Vertical)
class WebKitHistoryPrivate(browsertab.AbstractHistoryPrivate):
@@ -626,7 +620,7 @@ class WebKitHistoryPrivate(browsertab.AbstractHistoryPrivate):
def __init__(self, tab: 'WebKitTab') -> None:
self._tab = tab
- self._history = cast(QWebHistory, None)
+ self._history = cast(QtWebKit.QWebHistory, None)
def serialize(self):
return qtutils.serialize(self._history)
@@ -648,8 +642,8 @@ class WebKitHistoryPrivate(browsertab.AbstractHistoryPrivate):
if 'zoom' in cur_data:
self._tab.zoom.set_factor(cur_data['zoom'])
if ('scroll-pos' in cur_data and
- self._tab.scroller.pos_px() == QPoint(0, 0)):
- QTimer.singleShot(0, functools.partial(
+ self._tab.scroller.pos_px() == QtCore.QPoint(0, 0)):
+ QtCore.QTimer.singleShot(0, functools.partial(
self._tab.scroller.to_point, cur_data['scroll-pos']))
@@ -705,7 +699,7 @@ class WebKitElements(browsertab.AbstractElements):
elems = []
frames = webkitelem.get_child_frames(mainframe)
for f in frames:
- frame_elems = cast(Iterable[QWebElement], f.findAllElements(selector))
+ frame_elems = cast(Iterable[QtWebKit.QWebElement], f.findAllElements(selector))
for elem in frame_elems:
elems.append(webkitelem.WebKitElement(elem, tab=self._tab))
@@ -853,7 +847,7 @@ class WebKitTab(browsertab.AbstractTab):
def _make_private(self, widget):
settings = widget.settings()
- settings.setAttribute(QWebSettings.PrivateBrowsingEnabled, True)
+ settings.setAttribute(QtWebKit.QWebSettings.PrivateBrowsingEnabled, True)
def load_url(self, url):
self._load_url_prepare(url)
@@ -885,9 +879,9 @@ class WebKitTab(browsertab.AbstractTab):
def reload(self, *, force=False):
if force:
- action = QWebPage.ReloadAndBypassCache
+ action = QtWebKitWidgets.QWebPage.ReloadAndBypassCache
else:
- action = QWebPage.Reload
+ action = QtWebKitWidgets.QWebPage.Reload
self._widget.triggerPageAction(action)
def stop(self):
@@ -899,29 +893,29 @@ class WebKitTab(browsertab.AbstractTab):
def renderer_process_pid(self) -> Optional[int]:
return None
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_history_trigger(self):
url = self.url()
requested_url = self.url(requested=True)
self.history_item_triggered.emit(url, requested_url, self.title())
- def set_html(self, html, base_url=QUrl()):
+ def set_html(self, html, base_url=QtCore.QUrl()):
self._widget.setHtml(html, base_url)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_load_started(self):
super()._on_load_started()
nam = self._widget.page().networkAccessManager()
nam.netrc_used = False
# Make sure the icon is cleared when navigating to a page without one.
- self.icon_changed.emit(QIcon())
+ self.icon_changed.emit(QtGui.QIcon())
- @pyqtSlot(bool)
+ @QtCore.pyqtSlot(bool)
def _on_load_finished(self, ok: bool) -> None:
super()._on_load_finished(ok)
self._update_load_status(ok)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_frame_load_finished(self):
"""Make sure we emit an appropriate status when loading finished.
@@ -931,7 +925,7 @@ class WebKitTab(browsertab.AbstractTab):
"""
self._on_load_finished(not self._widget.page().error_occurred)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_webkit_icon_changed(self):
"""Emit iconChanged with a QIcon like QWebEngineView does."""
if sip.isdeleted(self._widget):
@@ -939,7 +933,7 @@ class WebKitTab(browsertab.AbstractTab):
return
self.icon_changed.emit(self._widget.icon())
- @pyqtSlot(QWebFrame)
+ @QtCore.pyqtSlot(QtWebKitWidgets.QWebFrame)
def _on_frame_created(self, frame):
"""Connect the contentsSizeChanged signal of each frame."""
# FIXME:qtwebengine those could theoretically regress:
@@ -947,11 +941,11 @@ class WebKitTab(browsertab.AbstractTab):
# https://github.com/qutebrowser/qutebrowser/issues/263
frame.contentsSizeChanged.connect(self._on_contents_size_changed)
- @pyqtSlot(QSize)
+ @QtCore.pyqtSlot(QtCore.QSize)
def _on_contents_size_changed(self, size):
- self.contents_size_changed.emit(QSizeF(size))
+ self.contents_size_changed.emit(QtCore.QSizeF(size))
- @pyqtSlot(usertypes.NavigationRequest)
+ @QtCore.pyqtSlot(usertypes.NavigationRequest)
def _on_navigation_request(self, navigation):
super()._on_navigation_request(navigation)
if not navigation.accepted:
@@ -976,7 +970,7 @@ class WebKitTab(browsertab.AbstractTab):
if navigation.is_main_frame:
self.settings.update_for_url(navigation.url)
- @pyqtSlot('QNetworkReply*')
+ @QtCore.pyqtSlot('QNetworkReply*')
def _on_ssl_errors(self, reply):
self._insecure_hosts.add(reply.url().host())
diff --git a/qutebrowser/browser/webkit/webpage.py b/qutebrowser/browser/webkit/webpage.py
index ddbd78de2..90e30cb12 100644
--- a/qutebrowser/browser/webkit/webpage.py
+++ b/qutebrowser/browser/webkit/webpage.py
@@ -22,23 +22,17 @@
import html
import functools
from typing import cast
-
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QUrl, QPoint
-from PyQt5.QtGui import QDesktopServices
-from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
-from PyQt5.QtWidgets import QFileDialog
-from PyQt5.QtPrintSupport import QPrintDialog
-from PyQt5.QtWebKitWidgets import QWebPage, QWebFrame
+from qutebrowser.qt import QtWidgets, QtWebKitWidgets, QtPrintSupport, QtNetwork, QtGui
from qutebrowser.config import websettings, config
from qutebrowser.browser import pdfjs, shared, downloads, greasemonkey
from qutebrowser.browser.webkit import http
from qutebrowser.browser.webkit.network import networkmanager
from qutebrowser.utils import message, usertypes, log, jinja, objreg
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
-class BrowserPage(QWebPage):
+class BrowserPage(QtWebKitWidgets.QWebPage):
"""Our own QWebPage with advanced features.
@@ -58,9 +52,9 @@ class BrowserPage(QWebPage):
navigation_request: Emitted on acceptNavigationRequest.
"""
- shutting_down = pyqtSignal()
- reloading = pyqtSignal(QUrl)
- navigation_request = pyqtSignal(usertypes.NavigationRequest)
+ shutting_down = QtCore.pyqtSignal()
+ reloading = QtCore.pyqtSignal(QtCore.QUrl)
+ navigation_request = QtCore.pyqtSignal(usertypes.NavigationRequest)
def __init__(self, win_id, tab_id, tabdata, private, parent=None):
super().__init__(parent)
@@ -68,8 +62,8 @@ class BrowserPage(QWebPage):
self._tabdata = tabdata
self._is_shutting_down = False
self._extension_handlers = {
- QWebPage.ErrorPageExtension: self._handle_errorpage,
- QWebPage.ChooseMultipleFilesExtension: self._handle_multiple_files,
+ QtWebKitWidgets.QWebPage.ErrorPageExtension: self._handle_errorpage,
+ QtWebKitWidgets.QWebPage.ChooseMultipleFilesExtension: self._handle_multiple_files,
}
self._ignore_load_started = False
self.error_occurred = False
@@ -97,7 +91,7 @@ class BrowserPage(QWebPage):
self.frameCreated.connect( # type: ignore[attr-defined]
self._connect_userjs_signals)
- @pyqtSlot('QWebFrame*')
+ @QtCore.pyqtSlot('QWebFrame*')
def _connect_userjs_signals(self, frame):
"""Connect userjs related signals to `frame`.
@@ -135,27 +129,27 @@ class BrowserPage(QWebPage):
False if no error page should be displayed, True otherwise.
"""
ignored_errors = [
- (QWebPage.QtNetwork, QNetworkReply.OperationCanceledError),
+ (QtWebKitWidgets.QWebPage.QtNetwork, QtNetwork.QNetworkReply.OperationCanceledError),
# "Loading is handled by the media engine"
- (QWebPage.WebKit, 203),
+ (QtWebKitWidgets.QWebPage.WebKit, 203),
# "Frame load interrupted by policy change"
- (QWebPage.WebKit, 102),
+ (QtWebKitWidgets.QWebPage.WebKit, 102),
]
errpage.baseUrl = info.url
urlstr = info.url.toDisplayString()
- if (info.domain, info.error) == (QWebPage.QtNetwork,
- QNetworkReply.ProtocolUnknownError):
+ if (info.domain, info.error) == (QtWebKitWidgets.QWebPage.QtNetwork,
+ QtNetwork.QNetworkReply.ProtocolUnknownError):
# For some reason, we get a segfault when we use
# QDesktopServices::openUrl with info.url directly - however it
# works when we construct a copy of it.
- url = QUrl(info.url)
+ url = QtCore.QUrl(info.url)
scheme = url.scheme()
message.confirm_async(
title="Open external application for {}-link?".format(scheme),
text="URL: <b>{}</b>".format(
html.escape(url.toDisplayString())),
- yes_action=functools.partial(QDesktopServices.openUrl, url),
- url=info.url.toString(QUrl.RemovePassword | QUrl.FullyEncoded))
+ yes_action=functools.partial(QtGui.QDesktopServices.openUrl, url),
+ url=info.url.toString(QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded))
return True
elif (info.domain, info.error) in ignored_errors:
log.webview.debug("Ignored error on {}: {} (error domain: {}, "
@@ -174,7 +168,7 @@ class BrowserPage(QWebPage):
# any space. We can't hide the frame's documentElement
# directly though.
for elem in main_frame.documentElement().findAll('iframe'):
- if QUrl(elem.attribute('src')) == info.url:
+ if QtCore.QUrl(elem.attribute('src')) == info.url:
elem.setAttribute('style', 'display: none')
return False
else:
@@ -192,7 +186,7 @@ class BrowserPage(QWebPage):
errpage.encoding = 'utf-8'
return True
- def chooseFile(self, parent_frame: QWebFrame, suggested_file: str) -> str:
+ def chooseFile(self, parent_frame: QtWebKitWidgets.QWebFrame, suggested_file: str) -> str:
"""Override chooseFile to (optionally) invoke custom file uploader."""
handler = config.val.fileselect.handler
if handler == "default":
@@ -224,7 +218,7 @@ class BrowserPage(QWebPage):
if info.suggestedFileNames:
suggested_file = info.suggestedFileNames[0]
- files.fileNames, _ = QFileDialog.getOpenFileNames(
+ files.fileNames, _ = QtWidgets.QFileDialog.getOpenFileNames(
None, None, suggested_file) # type: ignore[arg-type]
return True
@@ -250,8 +244,8 @@ class BrowserPage(QWebPage):
def on_print_requested(self, frame):
"""Handle printing when requested via javascript."""
- printdiag = QPrintDialog()
- printdiag.setAttribute(Qt.WA_DeleteOnClose)
+ printdiag = QtPrintSupport.QPrintDialog()
+ printdiag.setAttribute(QtCore.Qt.WA_DeleteOnClose)
printdiag.open(lambda: frame.print(printdiag.printer()))
def on_download_requested(self, request):
@@ -262,11 +256,11 @@ class BrowserPage(QWebPage):
soon as the user has entered the filename, as Qt seems to delete it
after this slot returns.
"""
- req = QNetworkRequest(request)
+ req = QtNetwork.QNetworkRequest(request)
download_manager = objreg.get('qtnetwork-download-manager')
download_manager.get_request(req, qnam=self.networkAccessManager())
- @pyqtSlot('QNetworkReply*')
+ @QtCore.pyqtSlot('QNetworkReply*')
def on_unsupported_content(self, reply):
"""Handle an unsupportedContent signal.
@@ -303,7 +297,7 @@ class BrowserPage(QWebPage):
download_manager.fetch(reply,
suggested_filename=suggested_filename)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_load_started(self):
"""Reset error_occurred when loading of a new page started."""
if self._ignore_load_started:
@@ -346,10 +340,10 @@ class BrowserPage(QWebPage):
log.webview.debug(f'Running GM script: {script}')
frame.evaluateJavaScript(script.code())
- @pyqtSlot('QWebFrame*', 'QWebPage::Feature')
+ @QtCore.pyqtSlot('QWebFrame*', 'QWebPage::Feature')
def _on_feature_permission_requested(self, frame, feature):
"""Ask the user for approval for geolocation/notifications."""
- if not isinstance(frame, QWebFrame): # pragma: no cover
+ if not isinstance(frame, QtWebKitWidgets.QWebFrame): # pragma: no cover
# This makes no sense whatsoever, but someone reported this being
# called with a QBuffer...
log.misc.error("on_feature_permission_requested got called with "
@@ -357,25 +351,25 @@ class BrowserPage(QWebPage):
return
options = {
- QWebPage.Notifications: 'content.notifications.enabled',
- QWebPage.Geolocation: 'content.geolocation',
+ QtWebKitWidgets.QWebPage.Notifications: 'content.notifications.enabled',
+ QtWebKitWidgets.QWebPage.Geolocation: 'content.geolocation',
}
messages = {
- QWebPage.Notifications: 'show notifications',
- QWebPage.Geolocation: 'access your location',
+ QtWebKitWidgets.QWebPage.Notifications: 'show notifications',
+ QtWebKitWidgets.QWebPage.Geolocation: 'access your location',
}
yes_action = functools.partial(
self.setFeaturePermission, frame, feature,
- QWebPage.PermissionGrantedByUser)
+ QtWebKitWidgets.QWebPage.PermissionGrantedByUser)
no_action = functools.partial(
self.setFeaturePermission, frame, feature,
- QWebPage.PermissionDeniedByUser)
+ QtWebKitWidgets.QWebPage.PermissionDeniedByUser)
- url = frame.url().adjusted(cast(QUrl.FormattingOptions,
- QUrl.RemoveUserInfo |
- QUrl.RemovePath |
- QUrl.RemoveQuery |
- QUrl.RemoveFragment))
+ url = frame.url().adjusted(cast(QtCore.QUrl.FormattingOptions,
+ QtCore.QUrl.RemoveUserInfo |
+ QtCore.QUrl.RemovePath |
+ QtCore.QUrl.RemoveQuery |
+ QtCore.QUrl.RemoveFragment))
question = shared.feature_permission(
url=url,
option=options[feature], msg=messages[feature],
@@ -429,7 +423,7 @@ class BrowserPage(QWebPage):
return
if 'zoom' in data:
frame.page().view().tab.zoom.set_factor(data['zoom'])
- if 'scroll-pos' in data and frame.scrollPosition() == QPoint(0, 0):
+ if 'scroll-pos' in data and frame.scrollPosition() == QtCore.QPoint(0, 0):
frame.setScrollPosition(data['scroll-pos'])
def userAgentForUrl(self, url):
@@ -495,9 +489,9 @@ class BrowserPage(QWebPage):
source, line, msg)
def acceptNavigationRequest(self,
- frame: QWebFrame,
- request: QNetworkRequest,
- typ: QWebPage.NavigationType) -> bool:
+ frame: QtWebKitWidgets.QWebFrame,
+ request: QtNetwork.QNetworkRequest,
+ typ: QtWebKitWidgets.QWebPage.NavigationType) -> bool:
"""Override acceptNavigationRequest to handle clicked links.
Setting linkDelegationPolicy to DelegateAllLinks and using a slot bound
@@ -508,17 +502,17 @@ class BrowserPage(QWebPage):
and then conditionally opens the URL here or in another tab/window.
"""
type_map = {
- QWebPage.NavigationTypeLinkClicked:
+ QtWebKitWidgets.QWebPage.NavigationTypeLinkClicked:
usertypes.NavigationRequest.Type.link_clicked,
- QWebPage.NavigationTypeFormSubmitted:
+ QtWebKitWidgets.QWebPage.NavigationTypeFormSubmitted:
usertypes.NavigationRequest.Type.form_submitted,
- QWebPage.NavigationTypeFormResubmitted:
+ QtWebKitWidgets.QWebPage.NavigationTypeFormResubmitted:
usertypes.NavigationRequest.Type.form_resubmitted,
- QWebPage.NavigationTypeBackOrForward:
+ QtWebKitWidgets.QWebPage.NavigationTypeBackOrForward:
usertypes.NavigationRequest.Type.back_forward,
- QWebPage.NavigationTypeReload:
+ QtWebKitWidgets.QWebPage.NavigationTypeReload:
usertypes.NavigationRequest.Type.reloaded,
- QWebPage.NavigationTypeOther:
+ QtWebKitWidgets.QWebPage.NavigationTypeOther:
usertypes.NavigationRequest.Type.other,
}
is_main_frame = frame is self.mainFrame()
diff --git a/qutebrowser/browser/webkit/webview.py b/qutebrowser/browser/webkit/webview.py
index 289e29920..ab1c15dd0 100644
--- a/qutebrowser/browser/webkit/webview.py
+++ b/qutebrowser/browser/webkit/webview.py
@@ -18,18 +18,16 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
"""The main browser widgets."""
-
-from PyQt5.QtCore import pyqtSignal, Qt, QUrl
-from PyQt5.QtWebKit import QWebSettings
-from PyQt5.QtWebKitWidgets import QWebView, QWebPage
+from qutebrowser.qt import QtWebKitWidgets, QtWebKit
from qutebrowser.config import config, stylesheet
from qutebrowser.keyinput import modeman
from qutebrowser.utils import log, usertypes, utils, objreg, debug
from qutebrowser.browser.webkit import webpage
+from qutebrowser.qt import QtCore
-class WebView(QWebView):
+class WebView(QtWebKitWidgets.QWebView):
"""Custom QWebView subclass with qutebrowser-specific features.
@@ -56,8 +54,8 @@ class WebView(QWebView):
}
"""
- scroll_pos_changed = pyqtSignal(int, int)
- shutting_down = pyqtSignal()
+ scroll_pos_changed = QtCore.pyqtSignal(int, int)
+ shutting_down = QtCore.pyqtSignal()
def __init__(self, *, win_id, tab_id, tab, private, parent=None):
super().__init__(parent)
@@ -74,15 +72,15 @@ class WebView(QWebView):
tabdata=tab.data, private=private,
parent=self)
page.setVisibilityState(
- QWebPage.VisibilityStateVisible if self.isVisible()
- else QWebPage.VisibilityStateHidden)
+ QtWebKitWidgets.QWebPage.VisibilityStateVisible if self.isVisible()
+ else QtWebKitWidgets.QWebPage.VisibilityStateHidden)
self.setPage(page)
stylesheet.set_register(self)
def __repr__(self):
- flags = QUrl.EncodeUnicode
+ flags = QtCore.QUrl.EncodeUnicode
urlstr = self.url().toDisplayString(flags) # type: ignore[arg-type]
url = utils.elide(urlstr, 100)
return utils.get_repr(self, tab_id=self._tab_id, url=url)
@@ -107,7 +105,7 @@ class WebView(QWebView):
# quitting it seems.
log.destroy.debug("Shutting down {!r}.".format(self))
settings = self.settings()
- settings.setAttribute(QWebSettings.JavascriptEnabled, False)
+ settings.setAttribute(QtWebKit.QWebSettings.JavascriptEnabled, False)
self.stop()
self.page().shutdown()
@@ -130,9 +128,9 @@ class WebView(QWebView):
Return:
The new QWebView object.
"""
- debug_type = debug.qenum_key(QWebPage, wintype)
+ debug_type = debug.qenum_key(QtWebKitWidgets.QWebPage, wintype)
log.webview.debug("createWindow with type {}".format(debug_type))
- if wintype == QWebPage.WebModalDialog:
+ if wintype == QtWebKitWidgets.QWebPage.WebModalDialog:
log.webview.warning("WebModalDialog requested, but we don't "
"support that!")
tabbed_browser = objreg.get('tabbed-browser', scope='window',
@@ -154,12 +152,12 @@ class WebView(QWebView):
e: The QPaintEvent.
"""
frame = self.page().mainFrame()
- new_pos = (frame.scrollBarValue(Qt.Horizontal),
- frame.scrollBarValue(Qt.Vertical))
+ new_pos = (frame.scrollBarValue(QtCore.Qt.Horizontal),
+ frame.scrollBarValue(QtCore.Qt.Vertical))
if self._old_scroll_pos != new_pos:
self._old_scroll_pos = new_pos
- m = (frame.scrollBarMaximum(Qt.Horizontal),
- frame.scrollBarMaximum(Qt.Vertical))
+ m = (frame.scrollBarMaximum(QtCore.Qt.Horizontal),
+ frame.scrollBarMaximum(QtCore.Qt.Vertical))
perc = (round(100 * new_pos[0] / m[0]) if m[0] != 0 else 0,
round(100 * new_pos[1] / m[1]) if m[1] != 0 else 0)
self.scroll_pos = perc
@@ -185,7 +183,7 @@ class WebView(QWebView):
e: The QShowEvent.
"""
super().showEvent(e)
- self.page().setVisibilityState(QWebPage.VisibilityStateVisible)
+ self.page().setVisibilityState(QtWebKitWidgets.QWebPage.VisibilityStateVisible)
def hideEvent(self, e):
"""Extend hideEvent to set the page visibility state to hidden.
@@ -194,16 +192,16 @@ class WebView(QWebView):
e: The QHideEvent.
"""
super().hideEvent(e)
- self.page().setVisibilityState(QWebPage.VisibilityStateHidden)
+ self.page().setVisibilityState(QtWebKitWidgets.QWebPage.VisibilityStateHidden)
def mousePressEvent(self, e):
"""Set the tabdata ClickTarget on a mousepress.
This is implemented here as we don't need it for QtWebEngine.
"""
- if e.button() == Qt.MidButton or e.modifiers() & Qt.ControlModifier:
+ if e.button() == QtCore.Qt.MidButton or e.modifiers() & QtCore.Qt.ControlModifier:
background = config.val.tabs.background
- if e.modifiers() & Qt.ShiftModifier:
+ if e.modifiers() & QtCore.Qt.ShiftModifier:
background = not background
if background:
target = usertypes.ClickTarget.tab_bg
diff --git a/qutebrowser/commands/argparser.py b/qutebrowser/commands/argparser.py
index 2a11589f9..137e8216f 100644
--- a/qutebrowser/commands/argparser.py
+++ b/qutebrowser/commands/argparser.py
@@ -21,7 +21,7 @@
import argparse
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.commands import cmdexc
from qutebrowser.utils import utils, objreg, log
@@ -60,7 +60,7 @@ class HelpAction(argparse.Action):
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window='last-focused')
tabbed_browser.tabopen(
- QUrl('qute://help/commands.html#{}'.format(parser.name)))
+ QtCore.QUrl('qute://help/commands.html#{}'.format(parser.name)))
parser.exit()
diff --git a/qutebrowser/commands/runners.py b/qutebrowser/commands/runners.py
index 5fb054455..9a548a22e 100644
--- a/qutebrowser/commands/runners.py
+++ b/qutebrowser/commands/runners.py
@@ -24,12 +24,11 @@ import re
import contextlib
from typing import TYPE_CHECKING, Callable, Dict, Iterator, Mapping, MutableMapping
-from PyQt5.QtCore import pyqtSlot, QUrl, QObject
-
from qutebrowser.api import cmdutils
from qutebrowser.commands import cmdexc, parser
from qutebrowser.utils import message, objreg, qtutils, usertypes, utils
from qutebrowser.keyinput import macros, modeman
+from qutebrowser.qt import QtCore
if TYPE_CHECKING:
from qutebrowser.mainwindow import tabbedbrowser
@@ -55,9 +54,9 @@ def _init_variable_replacements() -> Mapping[str, _ReplacementFunction]:
"""Return a dict from variable replacements to fns processing them."""
replacements: Dict[str, _ReplacementFunction] = {
'url': lambda tb: _url(tb).toString(
- QUrl.FullyEncoded | QUrl.RemovePassword),
+ QtCore.QUrl.FullyEncoded | QtCore.QUrl.RemovePassword),
'url:pretty': lambda tb: _url(tb).toString(
- QUrl.DecodeReserved | QUrl.RemovePassword),
+ QtCore.QUrl.DecodeReserved | QtCore.QUrl.RemovePassword),
'url:domain': lambda tb: "{}://{}{}".format(
_url(tb).scheme(), _url(tb).host(),
":" + str(_url(tb).port()) if _url(tb).port() != -1 else ""),
@@ -116,15 +115,15 @@ def replace_variables(win_id, arglist):
return args
-class AbstractCommandRunner(QObject):
+class AbstractCommandRunner(QtCore.QObject):
"""Abstract base class for CommandRunner."""
def run(self, text, count=None, *, safely=False):
raise NotImplementedError
- @pyqtSlot(str, int)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str, int)
+ @QtCore.pyqtSlot(str)
def run_safely(self, text, count=None):
"""Run a command and display exceptions in the statusbar."""
self.run(text, count, safely=True)
diff --git a/qutebrowser/commands/userscripts.py b/qutebrowser/commands/userscripts.py
index 8282aa7c7..dc0783dab 100644
--- a/qutebrowser/commands/userscripts.py
+++ b/qutebrowser/commands/userscripts.py
@@ -24,18 +24,16 @@ import os.path
import tempfile
from typing import cast, Any, MutableMapping, Tuple
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QSocketNotifier
-
import qutebrowser
from qutebrowser.utils import message, log, objreg, standarddir, utils
from qutebrowser.commands import runners
from qutebrowser.config import websettings
from qutebrowser.misc import guiprocess
from qutebrowser.browser import downloads
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
-class _QtFIFOReader(QObject):
+class _QtFIFOReader(QtCore.QObject):
"""A FIFO reader based on a QSocketNotifier.
@@ -48,7 +46,7 @@ class _QtFIFOReader(QObject):
got_line: Emitted when a whole line arrived.
"""
- got_line = pyqtSignal(str)
+ got_line = QtCore.pyqtSignal(str)
def __init__(self, filepath, parent=None):
super().__init__(parent)
@@ -61,12 +59,12 @@ class _QtFIFOReader(QObject):
fd = os.open(filepath, os.O_RDWR | os.O_NONBLOCK)
# pylint: enable=no-member,useless-suppression
self._fifo = os.fdopen(fd, 'r')
- self._notifier = QSocketNotifier(cast(sip.voidptr, fd),
- QSocketNotifier.Read, self)
+ self._notifier = QtCore.QSocketNotifier(cast(sip.voidptr, fd),
+ QtCore.QSocketNotifier.Read, self)
self._notifier.activated.connect( # type: ignore[attr-defined]
self.read_line)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def read_line(self):
"""(Try to) read a line from the FIFO."""
log.procs.debug("QSocketNotifier triggered!")
@@ -92,7 +90,7 @@ class _QtFIFOReader(QObject):
self._fifo.close()
-class _BaseUserscriptRunner(QObject):
+class _BaseUserscriptRunner(QtCore.QObject):
"""Common part between the Windows and the POSIX userscript runners.
@@ -111,8 +109,8 @@ class _BaseUserscriptRunner(QObject):
arg: The finished GUIProcess object.
"""
- got_cmd = pyqtSignal(str)
- finished = pyqtSignal(guiprocess.GUIProcess)
+ got_cmd = QtCore.pyqtSignal(str)
+ finished = QtCore.pyqtSignal(guiprocess.GUIProcess)
def __init__(self, parent=None):
super().__init__(parent)
@@ -217,7 +215,7 @@ class _BaseUserscriptRunner(QObject):
"""
raise NotImplementedError
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_proc_finished(self):
"""Called when the process has finished.
@@ -225,7 +223,7 @@ class _BaseUserscriptRunner(QObject):
"""
raise NotImplementedError
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_proc_error(self):
"""Called when the process encountered an error.
@@ -271,11 +269,11 @@ class _POSIXUserscriptRunner(_BaseUserscriptRunner):
self._reader = _QtFIFOReader(self._filepath)
self._reader.got_line.connect(self.got_cmd)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_proc_finished(self):
self._cleanup()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_proc_error(self):
self._cleanup()
@@ -328,11 +326,11 @@ class _WindowsUserscriptRunner(_BaseUserscriptRunner):
super()._cleanup()
self.finished.emit(proc)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_proc_error(self):
self._cleanup()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_proc_finished(self):
"""Read back the commands when the process finished."""
self._cleanup()
diff --git a/qutebrowser/completion/completer.py b/qutebrowser/completion/completer.py
index 8b0de9d8a..fd3ebf4d6 100644
--- a/qutebrowser/completion/completer.py
+++ b/qutebrowser/completion/completer.py
@@ -22,13 +22,13 @@
import dataclasses
from typing import TYPE_CHECKING
-from PyQt5.QtCore import pyqtSlot, QObject, QTimer
-
from qutebrowser.config import config
from qutebrowser.commands import parser, cmdexc
from qutebrowser.misc import objects, split
from qutebrowser.utils import log, utils, debug, objreg
from qutebrowser.completion.models import miscmodels
+from qutebrowser.qt import QtCore
+
if TYPE_CHECKING:
from qutebrowser.browser import browsertab
@@ -44,7 +44,7 @@ class CompletionInfo:
cur_tab: 'browsertab.AbstractTab'
-class Completer(QObject):
+class Completer(QtCore.QObject):
"""Completer which manages completions in a CompletionView.
@@ -62,7 +62,7 @@ class Completer(QObject):
super().__init__(parent)
self._cmd = cmd
self._win_id = win_id
- self._timer = QTimer()
+ self._timer = QtCore.QTimer()
self._timer.setSingleShot(True)
self._timer.setInterval(0)
self._timer.timeout.connect(self._update_completion)
@@ -166,7 +166,7 @@ class Completer(QObject):
raise utils.Unreachable(f"Not all parts consumed: {parts}")
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def on_selection_changed(self, text):
"""Change the completed part if a new item was selected.
@@ -199,7 +199,7 @@ class Completer(QObject):
else:
self._change_completed_part(text, before, after)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def schedule_completion_update(self):
"""Schedule updating/enabling completion.
@@ -227,7 +227,7 @@ class Completer(QObject):
self._last_cursor_pos = self._cmd.cursorPosition()
self._last_text = self._cmd.text()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _update_completion(self):
"""Check if completions are available and activate them."""
completion = self.parent()
diff --git a/qutebrowser/completion/completiondelegate.py b/qutebrowser/completion/completiondelegate.py
index 9ea82e876..d5d85c60d 100644
--- a/qutebrowser/completion/completiondelegate.py
+++ b/qutebrowser/completion/completiondelegate.py
@@ -25,27 +25,22 @@ We use this to be able to highlight parts of the text.
import re
import html
-from PyQt5.QtWidgets import QStyle, QStyleOptionViewItem, QStyledItemDelegate
-from PyQt5.QtCore import QRectF, QRegularExpression, QSize, Qt
-from PyQt5.QtGui import (QIcon, QPalette, QTextDocument, QTextOption,
- QAbstractTextDocumentLayout, QSyntaxHighlighter,
- QTextCharFormat)
-
from qutebrowser.config import config
from qutebrowser.utils import qtutils
+from qutebrowser.qt import QtWidgets, QtGui, QtCore
-class _Highlighter(QSyntaxHighlighter):
+class _Highlighter(QtGui.QSyntaxHighlighter):
def __init__(self, doc, pattern, color):
super().__init__(doc)
- self._format = QTextCharFormat()
+ self._format = QtGui.QTextCharFormat()
self._format.setForeground(color)
words = pattern.split()
words.sort(key=len, reverse=True)
pat = "|".join(re.escape(word) for word in words)
- self._expression = QRegularExpression(
- pat, QRegularExpression.CaseInsensitiveOption
+ self._expression = QtCore.QRegularExpression(
+ pat, QtCore.QRegularExpression.CaseInsensitiveOption
)
qtutils.ensure_valid(self._expression)
@@ -61,7 +56,7 @@ class _Highlighter(QSyntaxHighlighter):
)
-class CompletionItemDelegate(QStyledItemDelegate):
+class CompletionItemDelegate(QtWidgets.QStyledItemDelegate):
"""Delegate used by CompletionView to draw individual items.
@@ -109,12 +104,12 @@ class CompletionItemDelegate(QStyledItemDelegate):
# be displayed.
return
- mode = QIcon.Normal
- if not self._opt.state & QStyle.State_Enabled:
- mode = QIcon.Disabled
- elif self._opt.state & QStyle.State_Selected:
- mode = QIcon.Selected
- state = QIcon.On if self._opt.state & QStyle.State_Open else QIcon.Off
+ mode = QtGui.QIcon.Normal
+ if not self._opt.state & QtWidgets.QStyle.State_Enabled:
+ mode = QtGui.QIcon.Disabled
+ elif self._opt.state & QtWidgets.QStyle.State_Selected:
+ mode = QtGui.QIcon.Selected
+ state = QtGui.QIcon.On if self._opt.state & QtWidgets.QStyle.State_Open else QtGui.QIcon.Off
self._opt.icon.paint(self._painter, icon_rect,
self._opt.decorationAlignment, mode, state)
@@ -136,7 +131,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
text_rect_ = self._style.subElementRect(
self._style.SE_ItemViewItemText, self._opt, self._opt.widget)
qtutils.ensure_valid(text_rect_)
- margin = self._style.pixelMetric(QStyle.PM_FocusFrameHMargin,
+ margin = self._style.pixelMetric(QtWidgets.QStyle.PM_FocusFrameHMargin,
self._opt, self._opt.widget) + 1
# remove width padding
text_rect = text_rect_.adjusted(margin, 0, -margin, 0)
@@ -148,24 +143,24 @@ class CompletionItemDelegate(QStyledItemDelegate):
text_rect.adjust(0, -2, 0, -2)
self._painter.save()
state = self._opt.state
- if state & QStyle.State_Enabled and state & QStyle.State_Active:
- cg = QPalette.Normal
- elif state & QStyle.State_Enabled:
- cg = QPalette.Inactive
+ if state & QtWidgets.QStyle.State_Enabled and state & QtWidgets.QStyle.State_Active:
+ cg = QtGui.QPalette.Normal
+ elif state & QtWidgets.QStyle.State_Enabled:
+ cg = QtGui.QPalette.Inactive
else:
- cg = QPalette.Disabled
+ cg = QtGui.QPalette.Disabled
- if state & QStyle.State_Selected:
+ if state & QtWidgets.QStyle.State_Selected:
self._painter.setPen(self._opt.palette.color(
- cg, QPalette.HighlightedText))
+ cg, QtGui.QPalette.HighlightedText))
# This is a dirty fix for the text jumping by one pixel for
# whatever reason.
text_rect.adjust(0, -1, 0, 0)
else:
- self._painter.setPen(self._opt.palette.color(cg, QPalette.Text))
+ self._painter.setPen(self._opt.palette.color(cg, QtGui.QPalette.Text))
- if state & QStyle.State_Editing:
- self._painter.setPen(self._opt.palette.color(cg, QPalette.Text))
+ if state & QtWidgets.QStyle.State_Editing:
+ self._painter.setPen(self._opt.palette.color(cg, QtGui.QPalette.Text))
self._painter.drawRect(text_rect_.adjusted(0, 0, -1, -1))
self._painter.translate(text_rect.left(), text_rect.top())
@@ -184,12 +179,12 @@ class CompletionItemDelegate(QStyledItemDelegate):
assert self._opt is not None
# We can't use drawContents because then the color would be ignored.
- clip = QRectF(0, 0, rect.width(), rect.height())
+ clip = QtCore.QRectF(0, 0, rect.width(), rect.height())
self._painter.save()
- if self._opt.state & QStyle.State_Selected:
+ if self._opt.state & QtWidgets.QStyle.State_Selected:
color = config.cache['colors.completion.item.selected.fg']
- elif not self._opt.state & QStyle.State_Enabled:
+ elif not self._opt.state & QtWidgets.QStyle.State_Enabled:
color = config.cache['colors.completion.category.fg']
else:
colors = config.cache['colors.completion.fg']
@@ -197,8 +192,8 @@ class CompletionItemDelegate(QStyledItemDelegate):
color = colors[col % len(colors)]
self._painter.setPen(color)
- ctx = QAbstractTextDocumentLayout.PaintContext()
- ctx.palette.setColor(QPalette.Text, self._painter.pen().color())
+ ctx = QtGui.QAbstractTextDocumentLayout.PaintContext()
+ ctx.palette.setColor(QtGui.QPalette.Text, self._painter.pen().color())
if clip.isValid():
self._painter.setClipRect(clip)
ctx.clip = clip
@@ -215,18 +210,18 @@ class CompletionItemDelegate(QStyledItemDelegate):
# FIXME we probably should do eliding here. See
# qcommonstyle.cpp:viewItemDrawText
# https://github.com/qutebrowser/qutebrowser/issues/118
- text_option = QTextOption()
- if self._opt.features & QStyleOptionViewItem.WrapText:
- text_option.setWrapMode(QTextOption.WordWrap)
+ text_option = QtGui.QTextOption()
+ if self._opt.features & QtWidgets.QStyleOptionViewItem.WrapText:
+ text_option.setWrapMode(QtGui.QTextOption.WordWrap)
else:
- text_option.setWrapMode(QTextOption.ManualWrap)
+ text_option.setWrapMode(QtGui.QTextOption.ManualWrap)
text_option.setTextDirection(self._opt.direction)
- text_option.setAlignment(QStyle.visualAlignment(
+ text_option.setAlignment(QtWidgets.QStyle.visualAlignment(
self._opt.direction, self._opt.displayAlignment))
if self._doc is not None:
self._doc.deleteLater()
- self._doc = QTextDocument(self)
+ self._doc = QtGui.QTextDocument(self)
self._doc.setDefaultFont(self._opt.font)
self._doc.setDefaultTextOption(text_option)
self._doc.setDocumentMargin(2)
@@ -236,7 +231,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
pattern = view.pattern
columns_to_filter = index.model().columns_to_filter(index)
if index.column() in columns_to_filter and pattern:
- if self._opt.state & QStyle.State_Selected:
+ if self._opt.state & QtWidgets.QStyle.State_Selected:
color = config.val.colors.completion.item.selected.match.fg
else:
color = config.val.colors.completion.match.fg
@@ -253,23 +248,23 @@ class CompletionItemDelegate(QStyledItemDelegate):
assert self._opt is not None
assert self._style is not None
state = self._opt.state
- if not state & QStyle.State_HasFocus:
+ if not state & QtWidgets.QStyle.State_HasFocus:
return
o = self._opt
o.rect = self._style.subElementRect(
self._style.SE_ItemViewItemFocusRect, self._opt, self._opt.widget)
- o.state |= int(QStyle.State_KeyboardFocusChange | QStyle.State_Item)
+ o.state |= int(QtWidgets.QStyle.State_KeyboardFocusChange | QtWidgets.QStyle.State_Item)
qtutils.ensure_valid(o.rect)
- if state & QStyle.State_Enabled:
- cg = QPalette.Normal
+ if state & QtWidgets.QStyle.State_Enabled:
+ cg = QtGui.QPalette.Normal
else:
- cg = QPalette.Disabled
- if state & QStyle.State_Selected:
- role = QPalette.Highlight
+ cg = QtGui.QPalette.Disabled
+ if state & QtWidgets.QStyle.State_Selected:
+ role = QtGui.QPalette.Highlight
else:
- role = QPalette.Window
+ role = QtGui.QPalette.Window
o.backgroundColor = self._opt.palette.color(cg, role)
- self._style.drawPrimitive(QStyle.PE_FrameFocusRect, o, self._painter,
+ self._style.drawPrimitive(QtWidgets.QStyle.PE_FrameFocusRect, o, self._painter,
self._opt.widget)
def sizeHint(self, option, index):
@@ -285,10 +280,10 @@ class CompletionItemDelegate(QStyledItemDelegate):
Return:
A QSize with the recommended size.
"""
- value = index.data(Qt.SizeHintRole)
+ value = index.data(QtCore.Qt.SizeHintRole)
if value is not None:
return value
- self._opt = QStyleOptionViewItem(option)
+ self._opt = QtWidgets.QStyleOptionViewItem(option)
self.initStyleOption(self._opt, index)
self._style = self._opt.widget.style()
@@ -296,10 +291,10 @@ class CompletionItemDelegate(QStyledItemDelegate):
assert self._doc is not None
docsize = self._doc.size().toSize()
- size = self._style.sizeFromContents(QStyle.CT_ItemViewItem, self._opt,
+ size = self._style.sizeFromContents(QtWidgets.QStyle.CT_ItemViewItem, self._opt,
docsize, self._opt.widget)
qtutils.ensure_valid(size)
- return size + QSize(10, 3) # type: ignore[operator]
+ return size + QtCore.QSize(10, 3) # type: ignore[operator]
def paint(self, painter, option, index):
"""Override the QStyledItemDelegate paint function.
@@ -311,7 +306,7 @@ class CompletionItemDelegate(QStyledItemDelegate):
"""
self._painter = painter
self._painter.save()
- self._opt = QStyleOptionViewItem(option)
+ self._opt = QtWidgets.QStyleOptionViewItem(option)
self.initStyleOption(self._opt, index)
self._style = self._opt.widget.style()
diff --git a/qutebrowser/completion/completionwidget.py b/qutebrowser/completion/completionwidget.py
index dd8e267fe..dd13122cf 100644
--- a/qutebrowser/completion/completionwidget.py
+++ b/qutebrowser/completion/completionwidget.py
@@ -25,18 +25,17 @@ subclasses to provide completions.
from typing import TYPE_CHECKING, Optional
-from PyQt5.QtWidgets import QTreeView, QSizePolicy, QStyleFactory, QWidget
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QItemSelectionModel, QSize
-
from qutebrowser.config import config, stylesheet
from qutebrowser.completion import completiondelegate
from qutebrowser.utils import utils, usertypes, debug, log, qtutils
from qutebrowser.api import cmdutils
+from qutebrowser.qt import QtWidgets, QtCore
+
if TYPE_CHECKING:
from qutebrowser.mainwindow.statusbar import command
-class CompletionView(QTreeView):
+class CompletionView(QtWidgets.QTreeView):
"""The view showing available completions.
@@ -107,13 +106,13 @@ class CompletionView(QTreeView):
}
"""
- update_geometry = pyqtSignal()
- selection_changed = pyqtSignal(str)
+ update_geometry = QtCore.pyqtSignal()
+ selection_changed = QtCore.pyqtSignal(str)
def __init__(self, *,
cmd: 'command.Command',
win_id: int,
- parent: QWidget = None) -> None:
+ parent: QtWidgets.QWidget = None) -> None:
super().__init__(parent)
self.pattern: Optional[str] = None
self._win_id = win_id
@@ -124,16 +123,16 @@ class CompletionView(QTreeView):
self._delegate = completiondelegate.CompletionItemDelegate(self)
self.setItemDelegate(self._delegate)
- self.setStyle(QStyleFactory.create('Fusion'))
+ self.setStyle(QtWidgets.QStyleFactory.create('Fusion'))
stylesheet.set_register(self)
- self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
+ self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
self.setHeaderHidden(True)
self.setAlternatingRowColors(True)
self.setIndentation(0)
self.setItemsExpandable(False)
self.setExpandsOnDoubleClick(False)
self.setAnimated(False)
- self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
+ self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
# WORKAROUND
# This is a workaround for weird race conditions with invalid
# item indexes leading to segfaults in Qt.
@@ -148,7 +147,7 @@ class CompletionView(QTreeView):
def __repr__(self):
return utils.get_repr(self)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _on_config_changed(self, option):
if option in ['completion.height', 'completion.shrink']:
self.update_geometry.emit()
@@ -327,8 +326,8 @@ class CompletionView(QTreeView):
selmodel.setCurrentIndex(
idx,
- QItemSelectionModel.ClearAndSelect | # type: ignore[arg-type]
- QItemSelectionModel.Rows)
+ QtCore.QItemSelectionModel.ClearAndSelect | # type: ignore[arg-type]
+ QtCore.QItemSelectionModel.Rows)
# if the last item is focused, try to fetch more
next_idx = self.indexBelow(idx)
@@ -399,7 +398,7 @@ class CompletionView(QTreeView):
if config.val.completion.shrink:
self.update_geometry.emit()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_clear_completion_selection(self):
"""Clear the selection model when an item is activated."""
self.hide()
@@ -425,7 +424,7 @@ class CompletionView(QTreeView):
if contents_height <= height:
height = contents_height
# The width isn't really relevant as we're expanding anyways.
- return QSize(-1, height)
+ return QtCore.QSize(-1, height)
def selectionChanged(self, selected, deselected):
"""Extend selectionChanged to call completers selection_changed."""
diff --git a/qutebrowser/completion/models/completionmodel.py b/qutebrowser/completion/models/completionmodel.py
index 236b25533..5b4d19ba3 100644
--- a/qutebrowser/completion/models/completionmodel.py
+++ b/qutebrowser/completion/models/completionmodel.py
@@ -21,13 +21,12 @@
from typing import MutableSequence
-from PyQt5.QtCore import Qt, QModelIndex, QAbstractItemModel
-
from qutebrowser.utils import log, qtutils, utils
from qutebrowser.api import cmdutils
+from qutebrowser.qt import QtCore
-class CompletionModel(QAbstractItemModel):
+class CompletionModel(QtCore.QAbstractItemModel):
"""A model that proxies access to one or more completion categories.
@@ -43,7 +42,7 @@ class CompletionModel(QAbstractItemModel):
def __init__(self, *, column_widths=(30, 70, 0), parent=None):
super().__init__(parent)
self.column_widths = column_widths
- self._categories: MutableSequence[QAbstractItemModel] = []
+ self._categories: MutableSequence[QtCore.QAbstractItemModel] = []
def _cat_from_idx(self, index):
"""Return the category pointed to by the given index.
@@ -63,7 +62,7 @@ class CompletionModel(QAbstractItemModel):
"""Add a completion category to the model."""
self._categories.append(cat)
- def data(self, index, role=Qt.DisplayRole):
+ def data(self, index, role=QtCore.Qt.DisplayRole):
"""Return the item data for index.
Override QAbstractItemModel::data.
@@ -74,7 +73,7 @@ class CompletionModel(QAbstractItemModel):
Return: The item data, or None on an invalid index.
"""
- if role != Qt.DisplayRole:
+ if role != QtCore.Qt.DisplayRole:
return None
cat = self._cat_from_idx(index)
if cat:
@@ -97,16 +96,16 @@ class CompletionModel(QAbstractItemModel):
Return: The item flags, or Qt.NoItemFlags on error.
"""
if not index.isValid():
- return Qt.NoItemFlags
+ return QtCore.Qt.NoItemFlags
if index.parent().isValid():
# item
- return (Qt.ItemIsEnabled | Qt.ItemIsSelectable |
- Qt.ItemNeverHasChildren)
+ return (QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable |
+ QtCore.Qt.ItemNeverHasChildren)
else:
# category
- return Qt.NoItemFlags
+ return QtCore.Qt.NoItemFlags
- def index(self, row, col, parent=QModelIndex()):
+ def index(self, row, col, parent=QtCore.QModelIndex()):
"""Get an index into the model.
Override QAbstractItemModel::index.
@@ -115,10 +114,10 @@ class CompletionModel(QAbstractItemModel):
"""
if (row < 0 or row >= self.rowCount(parent) or
col < 0 or col >= self.columnCount(parent)):
- return QModelIndex()
+ return QtCore.QModelIndex()
if parent.isValid():
if parent.column() != 0:
- return QModelIndex()
+ return QtCore.QModelIndex()
# store a pointer to the parent category in internalPointer
return self.createIndex(row, col, self._categories[parent.row()])
return self.createIndex(row, col, None)
@@ -134,11 +133,11 @@ class CompletionModel(QAbstractItemModel):
parent_cat = index.internalPointer()
if not parent_cat:
# categories have no parent
- return QModelIndex()
+ return QtCore.QModelIndex()
row = self._categories.index(parent_cat)
return self.createIndex(row, 0, None)
- def rowCount(self, parent=QModelIndex()):
+ def rowCount(self, parent=QtCore.QModelIndex()):
"""Override QAbstractItemModel::rowCount."""
if not parent.isValid():
# top-level
@@ -151,7 +150,7 @@ class CompletionModel(QAbstractItemModel):
# category
return cat.rowCount()
- def columnCount(self, parent=QModelIndex()):
+ def columnCount(self, parent=QtCore.QModelIndex()):
"""Override QAbstractItemModel::columnCount."""
utils.unused(parent)
return len(self.column_widths)
@@ -160,14 +159,14 @@ class CompletionModel(QAbstractItemModel):
"""Override to forward the call to the categories."""
cat = self._cat_from_idx(parent)
if cat:
- return cat.canFetchMore(QModelIndex())
+ return cat.canFetchMore(QtCore.QModelIndex())
return False
def fetchMore(self, parent):
"""Override to forward the call to the categories."""
cat = self._cat_from_idx(parent)
if cat:
- cat.fetchMore(QModelIndex())
+ cat.fetchMore(QtCore.QModelIndex())
def count(self):
"""Return the count of non-category items."""
@@ -193,7 +192,7 @@ class CompletionModel(QAbstractItemModel):
index = self.index(0, 0, parent)
qtutils.ensure_valid(index)
return index
- return QModelIndex()
+ return QtCore.QModelIndex()
def last_item(self):
"""Return the index of the last child (non-category) in the model."""
@@ -204,7 +203,7 @@ class CompletionModel(QAbstractItemModel):
index = self.index(childcount - 1, 0, parent)
qtutils.ensure_valid(index)
return index
- return QModelIndex()
+ return QtCore.QModelIndex()
def columns_to_filter(self, index):
"""Return the column indices the filter pattern applies to.
@@ -231,5 +230,5 @@ class CompletionModel(QAbstractItemModel):
cat.delete_func(data)
self.beginRemoveRows(parent, index.row(), index.row())
- cat.removeRow(index.row(), QModelIndex())
+ cat.removeRow(index.row(), QtCore.QModelIndex())
self.endRemoveRows()
diff --git a/qutebrowser/completion/models/filepathcategory.py b/qutebrowser/completion/models/filepathcategory.py
index fd2cb58ce..c1dea4c01 100644
--- a/qutebrowser/completion/models/filepathcategory.py
+++ b/qutebrowser/completion/models/filepathcategory.py
@@ -31,16 +31,15 @@ import os
import os.path
from typing import List, Optional, Iterable
-from PyQt5.QtCore import QAbstractListModel, QModelIndex, QObject, Qt, QUrl
-
from qutebrowser.config import config
from qutebrowser.utils import log
+from qutebrowser.qt import QtCore
-class FilePathCategory(QAbstractListModel):
+class FilePathCategory(QtCore.QAbstractListModel):
"""Represent filesystem paths matching a pattern."""
- def __init__(self, name: str, parent: QObject = None) -> None:
+ def __init__(self, name: str, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
self._paths: List[str] = []
self.name = name
@@ -71,7 +70,7 @@ class FilePathCategory(QAbstractListModel):
def _url_to_path(self, val: str) -> str:
"""Get a path from a file:/// URL."""
- url = QUrl(val)
+ url = QtCore.QUrl(val)
assert url.isValid(), url
assert url.scheme() == 'file', url
return url.toLocalFile()
@@ -87,7 +86,7 @@ class FilePathCategory(QAbstractListModel):
elif val.startswith('file:///'):
url_path = self._url_to_path(val)
self._paths = sorted(
- QUrl.fromLocalFile(path).toString()
+ QtCore.QUrl.fromLocalFile(path).toString()
for path in self._glob(url_path)
)
else:
@@ -100,13 +99,13 @@ class FilePathCategory(QAbstractListModel):
paths = self._glob(expanded)
self._paths = sorted(self._contract_user(val, path) for path in paths)
- def data(self, index: QModelIndex, role: int = Qt.DisplayRole) -> Optional[str]:
+ def data(self, index: QtCore.QModelIndex, role: int = QtCore.Qt.DisplayRole) -> Optional[str]:
"""Implement abstract method in QAbstractListModel."""
- if role == Qt.DisplayRole and index.column() == 0:
+ if role == QtCore.Qt.DisplayRole and index.column() == 0:
return self._paths[index.row()]
return None
- def rowCount(self, parent: QModelIndex = QModelIndex()) -> int:
+ def rowCount(self, parent: QtCore.QModelIndex = QtCore.QModelIndex()) -> int:
"""Implement abstract method in QAbstractListModel."""
if parent.isValid():
return 0
diff --git a/qutebrowser/completion/models/histcategory.py b/qutebrowser/completion/models/histcategory.py
index 8dd1be838..aa7edb59f 100644
--- a/qutebrowser/completion/models/histcategory.py
+++ b/qutebrowser/completion/models/histcategory.py
@@ -21,8 +21,7 @@
from typing import Optional
-from PyQt5.QtSql import QSqlQueryModel
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt import QtWidgets, QtSql
from qutebrowser.misc import sql
from qutebrowser.utils import debug, message, log
@@ -30,13 +29,13 @@ from qutebrowser.config import config
from qutebrowser.completion.models import util
-class HistoryCategory(QSqlQueryModel):
+class HistoryCategory(QtSql.QSqlQueryModel):
"""A completion category that queries the SQL history store."""
def __init__(self, *, database: sql.Database,
delete_func: util.DeleteFuncType = None,
- parent: QWidget = None) -> None:
+ parent: QtWidgets.QWidget = None) -> None:
"""Create a new History completion category."""
super().__init__(parent=parent)
self._database = database
diff --git a/qutebrowser/completion/models/listcategory.py b/qutebrowser/completion/models/listcategory.py
index 352151ebb..9d07bd13e 100644
--- a/qutebrowser/completion/models/listcategory.py
+++ b/qutebrowser/completion/models/listcategory.py
@@ -21,16 +21,14 @@
import re
from typing import Iterable, Tuple
-
-from PyQt5.QtCore import QSortFilterProxyModel, QRegularExpression
-from PyQt5.QtGui import QStandardItem, QStandardItemModel
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt import QtWidgets
from qutebrowser.completion.models import util
from qutebrowser.utils import qtutils, log
+from qutebrowser.qt import QtGui, QtCore
-class ListCategory(QSortFilterProxyModel):
+class ListCategory(QtCore.QSortFilterProxyModel):
"""Expose a list of items as a category for the CompletionModel."""
@@ -39,16 +37,16 @@ class ListCategory(QSortFilterProxyModel):
items: Iterable[Tuple[str, ...]],
sort: bool = True,
delete_func: util.DeleteFuncType = None,
- parent: QWidget = None):
+ parent: QtWidgets.QWidget = None):
super().__init__(parent)
self.name = name
- self.srcmodel = QStandardItemModel(parent=self)
+ self.srcmodel = QtGui.QStandardItemModel(parent=self)
self._pattern = ''
# ListCategory filters all columns
self.columns_to_filter = [0, 1, 2]
self.setFilterKeyColumn(-1)
for item in items:
- self.srcmodel.appendRow([QStandardItem(x) for x in item])
+ self.srcmodel.appendRow([QtGui.QStandardItem(x) for x in item])
self.setSourceModel(self.srcmodel)
self.delete_func = delete_func
self._sort = sort
@@ -66,7 +64,7 @@ class ListCategory(QSortFilterProxyModel):
val = re.sub(r' +', r' ', val) # See #1919
val = re.escape(val)
val = val.replace(r'\ ', '.*')
- rx = QRegularExpression(val, QRegularExpression.CaseInsensitiveOption)
+ rx = QtCore.QRegularExpression(val, QtCore.QRegularExpression.CaseInsensitiveOption)
qtutils.ensure_valid(rx)
self.setFilterRegularExpression(rx)
self.invalidate()
diff --git a/qutebrowser/completion/models/urlmodel.py b/qutebrowser/completion/models/urlmodel.py
index 56af1f7c7..7198bf864 100644
--- a/qutebrowser/completion/models/urlmodel.py
+++ b/qutebrowser/completion/models/urlmodel.py
@@ -21,7 +21,7 @@
from typing import Dict, Sequence
-from PyQt5.QtCore import QAbstractItemModel
+from qutebrowser.qt import QtCore
from qutebrowser.completion.models import (completionmodel, filepathcategory,
listcategory, histcategory)
@@ -74,7 +74,7 @@ def url(*, info):
in sorted(config.val.url.searchengines.items())
if k != 'DEFAULT']
categories = config.val.completion.open_categories
- models: Dict[str, QAbstractItemModel] = {}
+ models: Dict[str, QtCore.QAbstractItemModel] = {}
if searchengines and 'searchengines' in categories:
models['searchengines'] = listcategory.ListCategory(
diff --git a/qutebrowser/components/braveadblock.py b/qutebrowser/components/braveadblock.py
index 977aa3ef2..a10e6e95a 100644
--- a/qutebrowser/components/braveadblock.py
+++ b/qutebrowser/components/braveadblock.py
@@ -27,7 +27,7 @@ import contextlib
import subprocess
from typing import Optional, IO, Iterator
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.api import (
hook,
@@ -185,8 +185,8 @@ class BraveAdBlocker:
def _is_blocked(
self,
- request_url: QUrl,
- first_party_url: Optional[QUrl] = None,
+ request_url: QtCore.QUrl,
+ first_party_url: Optional[QtCore.QUrl] = None,
resource_type: Optional[interceptor.ResourceType] = None,
) -> bool:
"""Check whether the given request is blocked."""
diff --git a/qutebrowser/components/hostblock.py b/qutebrowser/components/hostblock.py
index 191719f10..0d3c5193e 100644
--- a/qutebrowser/components/hostblock.py
+++ b/qutebrowser/components/hostblock.py
@@ -26,7 +26,7 @@ import logging
import pathlib
from typing import cast, IO, Set
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.api import (
hook,
@@ -115,7 +115,7 @@ class HostBlocker:
self._config_hosts_file = str(config_dir / "blocked-hosts")
- def _is_blocked(self, request_url: QUrl, first_party_url: QUrl = None) -> bool:
+ def _is_blocked(self, request_url: QtCore.QUrl, first_party_url: QtCore.QUrl = None) -> bool:
"""Check whether the given request is blocked."""
if not self.enabled:
return False
diff --git a/qutebrowser/components/misccommands.py b/qutebrowser/components/misccommands.py
index fe908b7d2..95c5c078a 100644
--- a/qutebrowser/components/misccommands.py
+++ b/qutebrowser/components/misccommands.py
@@ -34,8 +34,7 @@ try:
except ImportError:
hunter = None
-from PyQt5.QtCore import Qt
-from PyQt5.QtPrintSupport import QPrintPreviewDialog
+from qutebrowser.qt import QtPrintSupport, QtCore
from qutebrowser.api import cmdutils, apitypes, message, config
@@ -80,12 +79,12 @@ def _print_preview(tab: apitypes.Tab) -> None:
message.error("Printing failed!")
tab.printing.check_preview_support()
- diag = QPrintPreviewDialog(tab)
- diag.setAttribute(Qt.WA_DeleteOnClose)
+ diag = QtPrintSupport.QPrintPreviewDialog(tab)
+ diag.setAttribute(QtCore.Qt.WA_DeleteOnClose)
diag.setWindowFlags(
diag.windowFlags() | # type: ignore[operator, arg-type]
- Qt.WindowMaximizeButtonHint |
- Qt.WindowMinimizeButtonHint)
+ QtCore.Qt.WindowMaximizeButtonHint |
+ QtCore.Qt.WindowMinimizeButtonHint)
diag.paintRequested.connect(functools.partial(
tab.printing.to_printer, callback=print_callback))
diag.exec()
diff --git a/qutebrowser/components/readlinecommands.py b/qutebrowser/components/readlinecommands.py
index 4ac03041c..30707699b 100644
--- a/qutebrowser/components/readlinecommands.py
+++ b/qutebrowser/components/readlinecommands.py
@@ -22,9 +22,8 @@
import os
from typing import Iterable, Optional, MutableMapping, Any, Callable
-from PyQt5.QtWidgets import QApplication, QLineEdit
-
from qutebrowser.api import cmdutils
+from qutebrowser.qt import QtWidgets
class _ReadlineBridge:
@@ -36,16 +35,16 @@ class _ReadlineBridge:
"""
def __init__(self) -> None:
- self._deleted: MutableMapping[QLineEdit, str] = {}
+ self._deleted: MutableMapping[QtWidgets.QLineEdit, str] = {}
- def _widget(self) -> Optional[QLineEdit]:
+ def _widget(self) -> Optional[QtWidgets.QLineEdit]:
"""Get the currently active QLineEdit."""
# FIXME add this to api.utils or so
- qapp = QApplication.instance()
+ qapp = QtWidgets.QApplication.instance()
assert qapp is not None
w = qapp.focusWidget()
- if isinstance(w, QLineEdit):
+ if isinstance(w, QtWidgets.QLineEdit):
return w
else:
return None
diff --git a/qutebrowser/components/utils/blockutils.py b/qutebrowser/components/utils/blockutils.py
index 98681a488..799ee862a 100644
--- a/qutebrowser/components/utils/blockutils.py
+++ b/qutebrowser/components/utils/blockutils.py
@@ -24,9 +24,8 @@ import os
import functools
from typing import IO, List, Optional
-from PyQt5.QtCore import QUrl, QObject, pyqtSignal
-
from qutebrowser.api import downloads, message, config
+from qutebrowser.qt import QtCore
class FakeDownload(downloads.TempDownload):
@@ -39,7 +38,7 @@ class FakeDownload(downloads.TempDownload):
self.successful = True
-class BlocklistDownloads(QObject):
+class BlocklistDownloads(QtCore.QObject):
"""Download blocklists from the given URLs.
Attributes:
@@ -60,10 +59,10 @@ class BlocklistDownloads(QObject):
_finished: Has `all_downloads_finished` been emitted?
"""
- single_download_finished = pyqtSignal(object) # arg: the file object
- all_downloads_finished = pyqtSignal(int) # arg: download count
+ single_download_finished = QtCore.pyqtSignal(object) # arg: the file object
+ all_downloads_finished = QtCore.pyqtSignal(int) # arg: download count
- def __init__(self, urls: List[QUrl], parent: Optional[QObject] = None) -> None:
+ def __init__(self, urls: List[QtCore.QUrl], parent: Optional[QtCore.QObject] = None) -> None:
super().__init__(parent)
self._urls = urls
@@ -95,7 +94,7 @@ class BlocklistDownloads(QObject):
self._finished = True
self.all_downloads_finished.emit(self._done_count)
- def _download_blocklist_url(self, url: QUrl) -> None:
+ def _download_blocklist_url(self, url: QtCore.QUrl) -> None:
"""Take a blocklist url and queue it for download.
Args:
@@ -156,7 +155,7 @@ class BlocklistDownloads(QObject):
self.all_downloads_finished.emit(self._done_count)
-def is_whitelisted_url(url: QUrl) -> bool:
+def is_whitelisted_url(url: QtCore.QUrl) -> bool:
"""Check if the given URL is on the adblock whitelist."""
whitelist = config.val.content.blocking.whitelist
return any(pattern.matches(url) for pattern in whitelist)
diff --git a/qutebrowser/config/config.py b/qutebrowser/config/config.py
index 834709ae6..320579ac7 100644
--- a/qutebrowser/config/config.py
+++ b/qutebrowser/config/config.py
@@ -25,13 +25,12 @@ import functools
from typing import (TYPE_CHECKING, Any, Callable, Dict, Iterator, List, Mapping,
MutableMapping, MutableSequence, Optional, Tuple, cast)
-from PyQt5.QtCore import pyqtSignal, QObject, QUrl
-
from qutebrowser.commands import cmdexc, parser
from qutebrowser.config import configdata, configexc, configutils
from qutebrowser.utils import utils, log, urlmatch
from qutebrowser.misc import objects
from qutebrowser.keyinput import keyutils
+from qutebrowser.qt import QtCore
if TYPE_CHECKING:
from qutebrowser.config import configcache, configfiles
@@ -282,7 +281,7 @@ class KeyConfig:
self._config.update_mutables(save_yaml=save_yaml)
-class Config(QObject):
+class Config(QtCore.QObject):
"""Main config object.
@@ -300,11 +299,11 @@ class Config(QObject):
"""
MUTABLE_TYPES = (dict, list)
- changed = pyqtSignal(str)
+ changed = QtCore.pyqtSignal(str)
def __init__(self,
yaml_config: 'configfiles.YamlConfig',
- parent: QObject = None) -> None:
+ parent: QtCore.QObject = None) -> None:
super().__init__(parent)
self._mutables: MutableMapping[str, Tuple[Any, Any]] = {}
self._yaml = yaml_config
@@ -382,7 +381,7 @@ class Config(QObject):
def get(self,
name: str,
- url: QUrl = None, *,
+ url: QtCore.QUrl = None, *,
fallback: bool = True) -> Any:
"""Get the given setting converted for Python code.
@@ -408,7 +407,7 @@ class Config(QObject):
def get_obj(self,
name: str, *,
- url: QUrl = None,
+ url: QtCore.QUrl = None,
fallback: bool = True) -> Any:
"""Get the given setting as object (for YAML/config.py).
diff --git a/qutebrowser/config/configcommands.py b/qutebrowser/config/configcommands.py
index 407c74214..ead03761f 100644
--- a/qutebrowser/config/configcommands.py
+++ b/qutebrowser/config/configcommands.py
@@ -23,7 +23,7 @@ import os.path
import contextlib
from typing import TYPE_CHECKING, Iterator, List, Optional, Any, Tuple
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.api import cmdutils
from qutebrowser.completion.models import configmodel
@@ -108,7 +108,7 @@ class ConfigCommands:
if option is None:
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=win_id)
- tabbed_browser.load_url(QUrl('qute://settings'), newtab=False)
+ tabbed_browser.load_url(QtCore.QUrl('qute://settings'), newtab=False)
return
if option.endswith('!'):
@@ -151,7 +151,7 @@ class ConfigCommands:
default: If given, restore a default binding.
"""
if key is None:
- url = QUrl('qute://bindings')
+ url = QtCore.QUrl('qute://bindings')
if mode != "normal":
url.setFragment(mode)
tabbed_browser = objreg.get('tabbed-browser', scope='window',
@@ -283,7 +283,7 @@ class ConfigCommands:
@cmdutils.argument('win_id', value=cmdutils.Value.win_id)
def config_diff(self, win_id: int) -> None:
"""Show all customized options."""
- url = QUrl('qute://configdiff')
+ url = QtCore.QUrl('qute://configdiff')
tabbed_browser = objreg.get('tabbed-browser',
scope='window', window=win_id)
tabbed_browser.load_url(url, newtab=False)
diff --git a/qutebrowser/config/configfiles.py b/qutebrowser/config/configfiles.py
index d97771fad..f86f47b07 100644
--- a/qutebrowser/config/configfiles.py
+++ b/qutebrowser/config/configfiles.py
@@ -33,13 +33,13 @@ from typing import (TYPE_CHECKING, Any, Dict, Iterable, Iterator, List, Mapping,
MutableMapping, Optional, Tuple, cast)
import yaml
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QSettings, qVersion
import qutebrowser
from qutebrowser.config import (configexc, config, configdata, configutils,
configtypes)
from qutebrowser.keyinput import keyutils
from qutebrowser.utils import standarddir, utils, qtutils, log, urlmatch, version
+from qutebrowser.qt import QtCore
if TYPE_CHECKING:
from qutebrowser.misc import savemanager
@@ -108,7 +108,7 @@ class StateConfig(configparser.ConfigParser):
for sect, key in deleted_keys:
self[sect].pop(key, None)
- self['general']['qt_version'] = qVersion()
+ self['general']['qt_version'] = QtCore.qVersion()
self['general']['qtwe_version'] = self._qtwe_version_str()
self['general']['version'] = qutebrowser.__version__
@@ -118,7 +118,7 @@ class StateConfig(configparser.ConfigParser):
Note that it's too early to use objects.backend here...
"""
try:
- import PyQt5.QtWebEngineWidgets # pylint: disable=unused-import
+ import qutebrowser.qt # pylint: disable=unused-import
except ImportError:
return 'no'
return str(version.qtwebengine_versions(avoid_init=True).webengine)
@@ -134,7 +134,7 @@ class StateConfig(configparser.ConfigParser):
return
old_qt_version = self['general'].get('qt_version', None)
- self.qt_version_changed = old_qt_version != qVersion()
+ self.qt_version_changed = old_qt_version != QtCore.qVersion()
old_qtwe_version = self['general'].get('qtwe_version', None)
self.qtwe_version_changed = old_qtwe_version != self._qtwe_version_str()
@@ -178,7 +178,7 @@ class StateConfig(configparser.ConfigParser):
self.write(f)
-class YamlConfig(QObject):
+class YamlConfig(QtCore.QObject):
"""A config stored on disk as YAML file.
@@ -187,9 +187,9 @@ class YamlConfig(QObject):
"""
VERSION = 2
- changed = pyqtSignal()
+ changed = QtCore.pyqtSignal()
- def __init__(self, parent: QObject = None) -> None:
+ def __init__(self, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
self._filename = os.path.join(standarddir.config(auto=True),
'autoconfig.yml')
@@ -212,7 +212,7 @@ class YamlConfig(QObject):
"""Iterate over configutils.Values items."""
yield from self._values.values()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _mark_changed(self) -> None:
"""Mark the YAML config as changed."""
self._dirty = True
@@ -378,14 +378,14 @@ class YamlConfig(QObject):
self._mark_changed()
-class YamlMigrations(QObject):
+class YamlMigrations(QtCore.QObject):
"""Automated migrations for autoconfig.yml."""
- changed = pyqtSignal()
+ changed = QtCore.pyqtSignal()
# Note: settings is Any because it's not validated yet.
- def __init__(self, settings: Any, parent: QObject = None) -> None:
+ def __init__(self, settings: Any, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
self._settings = settings
@@ -982,5 +982,5 @@ def init() -> None:
# https://github.com/qutebrowser/qutebrowser/issues/515
path = os.path.join(standarddir.config(auto=True), 'qsettings')
- for fmt in [QSettings.NativeFormat, QSettings.IniFormat]:
- QSettings.setPath(fmt, QSettings.UserScope, path)
+ for fmt in [QtCore.QSettings.NativeFormat, QtCore.QSettings.IniFormat]:
+ QtCore.QSettings.setPath(fmt, QtCore.QSettings.UserScope, path)
diff --git a/qutebrowser/config/configinit.py b/qutebrowser/config/configinit.py
index 15e587ea2..a0ad40cf2 100644
--- a/qutebrowser/config/configinit.py
+++ b/qutebrowser/config/configinit.py
@@ -23,7 +23,7 @@ import argparse
import os.path
import sys
-from PyQt5.QtWidgets import QMessageBox
+from qutebrowser.qt import QtWidgets
from qutebrowser.api import config as configapi
from qutebrowser.config import (config, configdata, configfiles, configtypes,
@@ -135,7 +135,7 @@ def late_init(save_manager: savemanager.SaveManager) -> None:
errbox = msgbox.msgbox(parent=None,
title="Error while reading config",
text=_init_errors.to_html(),
- icon=QMessageBox.Warning,
+ icon=QtWidgets.QMessageBox.Warning,
plain_text=False)
errbox.exec()
diff --git a/qutebrowser/config/configtypes.py b/qutebrowser/config/configtypes.py
index d3d5e3fb8..af60ec5c0 100644
--- a/qutebrowser/config/configtypes.py
+++ b/qutebrowser/config/configtypes.py
@@ -55,10 +55,7 @@ from typing import (Any, Callable, Dict as DictType, Iterable, Iterator,
List as ListType, Optional, Pattern, Sequence, Tuple, Union)
import yaml
-from PyQt5.QtCore import QUrl, Qt
-from PyQt5.QtGui import QColor
-from PyQt5.QtWidgets import QTabWidget, QTabBar
-from PyQt5.QtNetwork import QNetworkProxy
+from qutebrowser.qt import QtWidgets, QtNetwork, QtGui
from qutebrowser.misc import objects, debugcachestats
from qutebrowser.config import configexc, configutils
@@ -66,6 +63,7 @@ from qutebrowser.utils import (standarddir, utils, qtutils, urlutils, urlmatch,
usertypes, log)
from qutebrowser.keyinput import keyutils
from qutebrowser.browser.network import pac
+from qutebrowser.qt import QtCore
class _SystemProxy:
@@ -1058,9 +1056,9 @@ class ColorSystem(MappingType):
"""The color system to use for color interpolation."""
MAPPING = {
- 'rgb': (QColor.Rgb, "Interpolate in the RGB color system."),
- 'hsv': (QColor.Hsv, "Interpolate in the HSV color system."),
- 'hsl': (QColor.Hsl, "Interpolate in the HSL color system."),
+ 'rgb': (QtGui.QColor.Rgb, "Interpolate in the RGB color system."),
+ 'hsv': (QtGui.QColor.Hsv, "Interpolate in the HSV color system."),
+ 'hsl': (QtGui.QColor.Hsl, "Interpolate in the HSL color system."),
'none': (None, "Don't show a gradient."),
}
@@ -1109,7 +1107,7 @@ class QtColor(BaseType):
except ValueError:
raise configexc.ValidationError(val, "must be a valid color value")
- def to_py(self, value: _StrUnset) -> Union[_UnsetNone, QColor]:
+ def to_py(self, value: _StrUnset) -> Union[_UnsetNone, QtGui.QColor]:
self._basic_py_validation(value, str)
if isinstance(value, usertypes.Unset):
return value
@@ -1121,11 +1119,11 @@ class QtColor(BaseType):
kind = value[:openparen]
vals = value[openparen+1:-1].split(',')
- converters: DictType[str, Callable[..., QColor]] = {
- 'rgba': QColor.fromRgb,
- 'rgb': QColor.fromRgb,
- 'hsva': QColor.fromHsv,
- 'hsv': QColor.fromHsv,
+ converters: DictType[str, Callable[..., QtGui.QColor]] = {
+ 'rgba': QtGui.QColor.fromRgb,
+ 'rgb': QtGui.QColor.fromRgb,
+ 'hsva': QtGui.QColor.fromHsv,
+ 'hsv': QtGui.QColor.fromHsv,
}
conv = converters.get(kind)
@@ -1143,7 +1141,7 @@ class QtColor(BaseType):
for kind, val in zip(kind, vals)]
return conv(*int_vals)
- color = QColor(value)
+ color = QtGui.QColor(value)
if color.isValid():
return color
else:
@@ -1181,7 +1179,7 @@ class QssColor(BaseType):
# QColor doesn't handle these
return value
- if not QColor.isValidColor(value):
+ if not QtGui.QColor.isValidColor(value):
raise configexc.ValidationError(value, "must be a valid color")
return value
@@ -1643,7 +1641,7 @@ class Proxy(BaseType):
def to_py(
self,
value: _StrUnset
- ) -> Union[_UnsetNone, QNetworkProxy, _SystemProxy, pac.PACFetcher]:
+ ) -> Union[_UnsetNone, QtNetwork.QNetworkProxy, _SystemProxy, pac.PACFetcher]:
self._basic_py_validation(value, str)
if isinstance(value, usertypes.Unset):
return value
@@ -1655,13 +1653,13 @@ class Proxy(BaseType):
return SYSTEM_PROXY
if value == 'none':
- url = QUrl('direct://')
+ url = QtCore.QUrl('direct://')
else:
# If we add a special value to valid_values, we need to handle
# it here!
assert self.valid_values is not None
assert value not in self.valid_values, value
- url = QUrl(value)
+ url = QtCore.QUrl(value)
return urlutils.proxy_from_url(url)
except (urlutils.InvalidUrlError, urlutils.InvalidProxyTypeError) as e:
raise configexc.ValidationError(value, e)
@@ -1716,7 +1714,7 @@ class FuzzyUrl(BaseType):
"""A URL which gets interpreted as search if needed."""
- def to_py(self, value: _StrUnset) -> Union[QUrl, _UnsetNone]:
+ def to_py(self, value: _StrUnset) -> Union[QtCore.QUrl, _UnsetNone]:
self._basic_py_validation(value, str)
if isinstance(value, usertypes.Unset):
return value
@@ -1792,10 +1790,10 @@ class Position(MappingType):
"""The position of the tab bar."""
MAPPING = {
- 'top': (QTabWidget.North, None),
- 'bottom': (QTabWidget.South, None),
- 'left': (QTabWidget.West, None),
- 'right': (QTabWidget.East, None),
+ 'top': (QtWidgets.QTabWidget.North, None),
+ 'bottom': (QtWidgets.QTabWidget.South, None),
+ 'left': (QtWidgets.QTabWidget.West, None),
+ 'right': (QtWidgets.QTabWidget.East, None),
}
@@ -1804,9 +1802,9 @@ class TextAlignment(MappingType):
"""Alignment of text."""
MAPPING = {
- 'left': (Qt.AlignLeft, None),
- 'right': (Qt.AlignRight, None),
- 'center': (Qt.AlignCenter, None),
+ 'left': (QtCore.Qt.AlignLeft, None),
+ 'right': (QtCore.Qt.AlignRight, None),
+ 'center': (QtCore.Qt.AlignCenter, None),
}
@@ -1827,14 +1825,14 @@ class Url(BaseType):
"""A URL as a string."""
- def to_py(self, value: _StrUnset) -> Union[_UnsetNone, QUrl]:
+ def to_py(self, value: _StrUnset) -> Union[_UnsetNone, QtCore.QUrl]:
self._basic_py_validation(value, str)
if isinstance(value, usertypes.Unset):
return value
elif not value:
return None
- qurl = QUrl.fromUserInput(value)
+ qurl = QtCore.QUrl.fromUserInput(value)
if not qurl.isValid():
raise configexc.ValidationError(value, "invalid URL - "
"{}".format(qurl.errorString()))
@@ -1862,17 +1860,17 @@ class SelectOnRemove(MappingType):
MAPPING = {
'prev': (
- QTabBar.SelectLeftTab,
+ QtWidgets.QTabBar.SelectLeftTab,
("Select the tab which came before the closed one "
"(left in horizontal, above in vertical)."),
),
'next': (
- QTabBar.SelectRightTab,
+ QtWidgets.QTabBar.SelectRightTab,
("Select the tab which came after the closed one "
"(right in horizontal, below in vertical)."),
),
'last-used': (
- QTabBar.SelectPreviousTab,
+ QtWidgets.QTabBar.SelectPreviousTab,
"Select the previously selected tab.",
),
}
diff --git a/qutebrowser/config/configutils.py b/qutebrowser/config/configutils.py
index 480bbd85f..49933c89f 100644
--- a/qutebrowser/config/configutils.py
+++ b/qutebrowser/config/configutils.py
@@ -28,9 +28,7 @@ from typing import (
TYPE_CHECKING, Any, Dict, Iterator, List, Optional, Sequence, Set, Union,
MutableMapping)
-from PyQt5.QtCore import QUrl
-from PyQt5.QtGui import QFontDatabase
-from PyQt5.QtWidgets import QApplication
+from qutebrowser.qt import QtWidgets, QtGui, QtCore
from qutebrowser.utils import utils, urlmatch, urlutils, usertypes, qtutils
from qutebrowser.config import configexc
@@ -146,7 +144,7 @@ class Values:
return bool(self._vmap)
def _check_pattern_support(
- self, arg: Union[urlmatch.UrlPattern, QUrl, None]) -> None:
+ self, arg: Union[urlmatch.UrlPattern, QtCore.QUrl, None]) -> None:
"""Make sure patterns are supported if one was given."""
if arg is not None and not self.opt.supports_pattern:
raise configexc.NoPatternError(self.opt.name)
@@ -206,7 +204,7 @@ class Values:
else:
return usertypes.UNSET
- def get_for_url(self, url: QUrl = None, *, fallback: bool = True) -> Any:
+ def get_for_url(self, url: QtCore.QUrl = None, *, fallback: bool = True) -> Any:
"""Get a config value, falling back when needed.
This first tries to find a value matching the URL (if given).
@@ -294,7 +292,7 @@ class FontFamilies:
@classmethod
def from_system_default(
cls,
- font_type: QFontDatabase.SystemFont = QFontDatabase.FixedFont,
+ font_type: QtGui.QFontDatabase.SystemFont = QtGui.QFontDatabase.FixedFont,
) -> 'FontFamilies':
"""Get a FontFamilies object for the default system font.
@@ -338,8 +336,8 @@ class FontFamilies:
the "right" choice isn't really obvious. Thus, let's go for the
QFontDatabase approach here, since it's by far the simplest one.
"""
- assert QApplication.instance() is not None
- font = QFontDatabase.systemFont(font_type)
+ assert QtWidgets.QApplication.instance() is not None
+ font = QtGui.QFontDatabase.systemFont(font_type)
return cls([font.family()])
@classmethod
diff --git a/qutebrowser/config/qtargs.py b/qutebrowser/config/qtargs.py
index 9e7f2620d..540f334df 100644
--- a/qutebrowser/config/qtargs.py
+++ b/qutebrowser/config/qtargs.py
@@ -25,11 +25,10 @@ import argparse
import pathlib
from typing import Any, Dict, Iterator, List, Optional, Sequence, Tuple
-from PyQt5.QtCore import QLibraryInfo, QLocale
-
from qutebrowser.config import config
from qutebrowser.misc import objects
from qutebrowser.utils import usertypes, qtutils, utils, log, version
+from qutebrowser.qt import QtCore
_ENABLE_FEATURES = '--enable-features='
@@ -199,7 +198,7 @@ def _webengine_locales_path() -> pathlib.Path:
# not QtWebEngine.
base = pathlib.Path('/app/translations')
else:
- base = pathlib.Path(QLibraryInfo.location(QLibraryInfo.TranslationsPath))
+ base = pathlib.Path(QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.TranslationsPath))
return base / 'qtwebengine_locales'
@@ -265,7 +264,7 @@ def _qtwebengine_args(
lang_override = _get_lang_override(
webengine_version=versions.webengine,
- locale_name=QLocale().bcp47Name(),
+ locale_name=QtCore.QLocale().bcp47Name(),
)
if lang_override is not None:
yield f'--lang={lang_override}'
diff --git a/qutebrowser/config/stylesheet.py b/qutebrowser/config/stylesheet.py
index 2927aec08..9c893e0b1 100644
--- a/qutebrowser/config/stylesheet.py
+++ b/qutebrowser/config/stylesheet.py
@@ -22,14 +22,13 @@
import functools
from typing import Optional, FrozenSet
-from PyQt5.QtCore import pyqtSlot, QObject
-
from qutebrowser.config import config
from qutebrowser.misc import debugcachestats
from qutebrowser.utils import jinja, log
+from qutebrowser.qt import QtCore
-def set_register(obj: QObject,
+def set_register(obj: QtCore.QObject,
stylesheet: str = None, *,
update: bool = True) -> None:
"""Set the stylesheet for an object.
@@ -59,7 +58,7 @@ def init() -> None:
config.instance.changed.connect(_render_stylesheet.cache_clear)
-class _StyleSheetObserver(QObject):
+class _StyleSheetObserver(QtCore.QObject):
"""Set the stylesheet on the given object and update it on changes.
@@ -71,7 +70,7 @@ class _StyleSheetObserver(QObject):
None.
"""
- def __init__(self, obj: QObject,
+ def __init__(self, obj: QtCore.QObject,
stylesheet: Optional[str], update: bool) -> None:
super().__init__()
self._obj = obj
@@ -99,7 +98,7 @@ class _StyleSheetObserver(QObject):
"""
return _render_stylesheet(self._stylesheet)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _maybe_update_stylesheet(self, option: str) -> None:
"""Update the stylesheet for obj if the option changed affects it."""
assert self._options is not None
diff --git a/qutebrowser/config/websettings.py b/qutebrowser/config/websettings.py
index 41aeec6a3..cdddf6956 100644
--- a/qutebrowser/config/websettings.py
+++ b/qutebrowser/config/websettings.py
@@ -24,14 +24,13 @@ import argparse
import functools
import dataclasses
from typing import Any, Callable, Dict, Optional, Union
-
-from PyQt5.QtCore import QUrl, pyqtSlot, qVersion
-from PyQt5.QtGui import QFont
+from qutebrowser.qt import QtGui
import qutebrowser
from qutebrowser.config import config
from qutebrowser.utils import usertypes, urlmatch, qtutils, utils
from qutebrowser.misc import objects, debugcachestats
+from qutebrowser.qt import QtCore
UNSET = object()
@@ -104,7 +103,7 @@ class AbstractSettings:
_ATTRIBUTES: Dict[str, AttributeInfo] = {}
_FONT_SIZES: Dict[str, Any] = {}
_FONT_FAMILIES: Dict[str, Any] = {}
- _FONT_TO_QFONT: Dict[Any, QFont.StyleHint] = {}
+ _FONT_TO_QFONT: Dict[Any, QtGui.QFont.StyleHint] = {}
def __init__(self, settings: Any) -> None:
self._settings = settings
@@ -152,7 +151,7 @@ class AbstractSettings:
if value is usertypes.UNSET:
self._settings.resetFontFamily(family)
elif value is None:
- font = QFont()
+ font = QtGui.QFont()
font.setStyleHint(self._FONT_TO_QFONT[family])
value = font.defaultFamily()
self._settings.setFontFamily(family, value)
@@ -187,7 +186,7 @@ class AbstractSettings:
value = config.instance.get(setting)
self._update_setting(setting, value)
- def update_for_url(self, url: QUrl) -> None:
+ def update_for_url(self, url: QtCore.QUrl) -> None:
"""Update settings customized for the given tab."""
qtutils.ensure_valid(url)
for values in config.instance:
@@ -220,14 +219,14 @@ def _format_user_agent(template: str, backend: usertypes.Backend) -> str:
os_info=parsed.os_info,
webkit_version=parsed.webkit_version,
qt_key=parsed.qt_key,
- qt_version=qVersion(),
+ qt_version=QtCore.qVersion(),
upstream_browser_key=parsed.upstream_browser_key,
upstream_browser_version=parsed.upstream_browser_version,
qutebrowser_version=qutebrowser.__version__,
)
-def user_agent(url: QUrl = None) -> str:
+def user_agent(url: QtCore.QUrl = None) -> str:
"""Get the user agent for the given URL, or the global one if URL is None.
Note that the given URL should always be valid.
@@ -268,7 +267,7 @@ def clear_private_data() -> None:
raise utils.Unreachable(objects.backend)
-@pyqtSlot()
+@QtCore.pyqtSlot()
def shutdown() -> None:
"""Shut down QWeb(Engine)Settings."""
if objects.backend == usertypes.Backend.QtWebEngine:
diff --git a/qutebrowser/extensions/interceptors.py b/qutebrowser/extensions/interceptors.py
index dfafeb7e3..b927a5a99 100644
--- a/qutebrowser/extensions/interceptors.py
+++ b/qutebrowser/extensions/interceptors.py
@@ -23,7 +23,7 @@ import enum
import dataclasses
from typing import Callable, List, Optional
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
class ResourceType(enum.Enum):
@@ -67,10 +67,10 @@ class Request:
"""A request which can be intercepted/blocked."""
#: The URL of the page being shown.
- first_party_url: Optional[QUrl]
+ first_party_url: Optional[QtCore.QUrl]
#: The URL of the file being requested.
- request_url: QUrl
+ request_url: QtCore.QUrl
is_blocked: bool = False
@@ -81,7 +81,7 @@ class Request:
"""Block this request."""
self.is_blocked = True
- def redirect(self, url: QUrl, *, ignore_unsupported: bool = False) -> None:
+ def redirect(self, url: QtCore.QUrl, *, ignore_unsupported: bool = False) -> None:
"""Redirect this request.
Only some types of requests can be successfully redirected.
diff --git a/qutebrowser/extensions/loader.py b/qutebrowser/extensions/loader.py
index 793f131c8..623a665d7 100644
--- a/qutebrowser/extensions/loader.py
+++ b/qutebrowser/extensions/loader.py
@@ -27,7 +27,7 @@ import argparse
import dataclasses
from typing import Callable, Iterator, List, Optional, Tuple
-from PyQt5.QtCore import pyqtSlot
+from qutebrowser.qt import QtCore
from qutebrowser import components
from qutebrowser.config import config
@@ -140,7 +140,7 @@ def _load_component(info: ExtensionInfo, *,
return mod
-@pyqtSlot(str)
+@QtCore.pyqtSlot(str)
def _on_config_changed(changed_name: str) -> None:
"""Call config_changed hooks if the config changed."""
for mod_info in _module_infos:
diff --git a/qutebrowser/keyinput/basekeyparser.py b/qutebrowser/keyinput/basekeyparser.py
index 4db1d5d76..f9ed3e04d 100644
--- a/qutebrowser/keyinput/basekeyparser.py
+++ b/qutebrowser/keyinput/basekeyparser.py
@@ -24,12 +24,10 @@ import types
import dataclasses
from typing import Mapping, MutableMapping, Optional, Sequence
-from PyQt5.QtCore import pyqtSignal, QObject, Qt
-from PyQt5.QtGui import QKeySequence, QKeyEvent
-
from qutebrowser.config import config
from qutebrowser.utils import usertypes, log, utils
from qutebrowser.keyinput import keyutils
+from qutebrowser.qt import QtGui, QtCore
@dataclasses.dataclass(frozen=True)
@@ -37,12 +35,12 @@ class MatchResult:
"""The result of matching a keybinding."""
- match_type: QKeySequence.SequenceMatch
+ match_type: QtGui.QKeySequence.SequenceMatch
command: Optional[str]
sequence: keyutils.KeySequence
def __post_init__(self) -> None:
- if self.match_type == QKeySequence.ExactMatch:
+ if self.match_type == QtGui.QKeySequence.ExactMatch:
assert self.command is not None
else:
assert self.command is None
@@ -89,7 +87,7 @@ class BindingTrie:
node.command = command
def __contains__(self, sequence: keyutils.KeySequence) -> bool:
- return self.matches(sequence).match_type == QKeySequence.ExactMatch
+ return self.matches(sequence).match_type == QtGui.QKeySequence.ExactMatch
def __repr__(self) -> str:
return utils.get_repr(self, children=self.children,
@@ -131,25 +129,25 @@ class BindingTrie:
try:
node = node.children[key]
except KeyError:
- return MatchResult(match_type=QKeySequence.NoMatch,
+ return MatchResult(match_type=QtGui.QKeySequence.NoMatch,
command=None,
sequence=sequence)
if node.command is not None:
- return MatchResult(match_type=QKeySequence.ExactMatch,
+ return MatchResult(match_type=QtGui.QKeySequence.ExactMatch,
command=node.command,
sequence=sequence)
elif node.children:
- return MatchResult(match_type=QKeySequence.PartialMatch,
+ return MatchResult(match_type=QtGui.QKeySequence.PartialMatch,
command=None,
sequence=sequence)
else: # This can only happen when there are no bindings at all.
- return MatchResult(match_type=QKeySequence.NoMatch,
+ return MatchResult(match_type=QtGui.QKeySequence.NoMatch,
command=None,
sequence=sequence)
-class BaseKeyParser(QObject):
+class BaseKeyParser(QtCore.QObject):
"""Parser for vim-like key sequences and shortcuts.
@@ -176,12 +174,12 @@ class BaseKeyParser(QObject):
arg 2: Ignore the request if we're not in that mode
"""
- keystring_updated = pyqtSignal(str)
- request_leave = pyqtSignal(usertypes.KeyMode, str, bool)
+ keystring_updated = QtCore.pyqtSignal(str)
+ request_leave = QtCore.pyqtSignal(usertypes.KeyMode, str, bool)
def __init__(self, *, mode: usertypes.KeyMode,
win_id: int,
- parent: QObject = None,
+ parent: QtCore.QObject = None,
do_log: bool = True,
passthrough: bool = False,
supports_count: bool = True) -> None:
@@ -247,7 +245,7 @@ class BaseKeyParser(QObject):
self._debug_log("Mapped {} -> {}".format(
sequence, mapped))
return self._match_key(mapped)
- return MatchResult(match_type=QKeySequence.NoMatch,
+ return MatchResult(match_type=QtGui.QKeySequence.NoMatch,
command=None,
sequence=sequence)
@@ -268,8 +266,8 @@ class BaseKeyParser(QObject):
return True
return False
- def handle(self, e: QKeyEvent, *,
- dry_run: bool = False) -> QKeySequence.SequenceMatch:
+ def handle(self, e: QtGui.QKeyEvent, *,
+ dry_run: bool = False) -> QtGui.QKeySequence.SequenceMatch:
"""Handle a new keypress.
Separate the keypress into count/command, then check if it matches
@@ -284,7 +282,7 @@ class BaseKeyParser(QObject):
Return:
A QKeySequence match.
"""
- key = Qt.Key(e.key())
+ key = QtCore.Qt.Key(e.key())
txt = str(keyutils.KeyInfo.from_event(e))
self._debug_log("Got key: 0x{:x} / modifiers: 0x{:x} / text: '{}' / "
"dry_run {}".format(key, int(e.modifiers()), txt,
@@ -292,44 +290,44 @@ class BaseKeyParser(QObject):
if keyutils.is_modifier_key(key):
self._debug_log("Ignoring, only modifier")
- return QKeySequence.NoMatch
+ return QtGui.QKeySequence.NoMatch
try:
sequence = self._sequence.append_event(e)
except keyutils.KeyParseError as ex:
self._debug_log("{} Aborting keychain.".format(ex))
self.clear_keystring()
- return QKeySequence.NoMatch
+ return QtGui.QKeySequence.NoMatch
result = self._match_key(sequence)
del sequence # Enforce code below to use the modified result.sequence
- if result.match_type == QKeySequence.NoMatch:
+ if result.match_type == QtGui.QKeySequence.NoMatch:
result = self._match_without_modifiers(result.sequence)
- if result.match_type == QKeySequence.NoMatch:
+ if result.match_type == QtGui.QKeySequence.NoMatch:
result = self._match_key_mapping(result.sequence)
- if result.match_type == QKeySequence.NoMatch:
+ if result.match_type == QtGui.QKeySequence.NoMatch:
was_count = self._match_count(result.sequence, dry_run)
if was_count:
- return QKeySequence.ExactMatch
+ return QtGui.QKeySequence.ExactMatch
if dry_run:
return result.match_type
self._sequence = result.sequence
- if result.match_type == QKeySequence.ExactMatch:
+ if result.match_type == QtGui.QKeySequence.ExactMatch:
assert result.command is not None
self._debug_log("Definitive match for '{}'.".format(
result.sequence))
count = int(self._count) if self._count else None
self.clear_keystring()
self.execute(result.command, count)
- elif result.match_type == QKeySequence.PartialMatch:
+ elif result.match_type == QtGui.QKeySequence.PartialMatch:
self._debug_log("No match for '{}' (added {})".format(
result.sequence, txt))
self.keystring_updated.emit(self._count + str(result.sequence))
- elif result.match_type == QKeySequence.NoMatch:
+ elif result.match_type == QtGui.QKeySequence.NoMatch:
self._debug_log("Giving up with '{}', no matches".format(
result.sequence))
self.clear_keystring()
diff --git a/qutebrowser/keyinput/eventfilter.py b/qutebrowser/keyinput/eventfilter.py
index f0d85b0ec..d550a384e 100644
--- a/qutebrowser/keyinput/eventfilter.py
+++ b/qutebrowser/keyinput/eventfilter.py
@@ -21,15 +21,13 @@
from typing import cast
-from PyQt5.QtCore import pyqtSlot, QObject, QEvent
-from PyQt5.QtGui import QKeyEvent, QWindow
-
from qutebrowser.keyinput import modeman
from qutebrowser.misc import quitter, objects
from qutebrowser.utils import objreg
+from qutebrowser.qt import QtGui, QtCore
-class EventFilter(QObject):
+class EventFilter(QtCore.QObject):
"""Global Qt event filter.
@@ -39,23 +37,23 @@ class EventFilter(QObject):
event.
"""
- def __init__(self, parent: QObject = None) -> None:
+ def __init__(self, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
self._activated = True
self._handlers = {
- QEvent.KeyPress: self._handle_key_event,
- QEvent.KeyRelease: self._handle_key_event,
- QEvent.ShortcutOverride: self._handle_key_event,
+ QtCore.QEvent.KeyPress: self._handle_key_event,
+ QtCore.QEvent.KeyRelease: self._handle_key_event,
+ QtCore.QEvent.ShortcutOverride: self._handle_key_event,
}
def install(self) -> None:
objects.qapp.installEventFilter(self)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def shutdown(self) -> None:
objects.qapp.removeEventFilter(self)
- def _handle_key_event(self, event: QKeyEvent) -> bool:
+ def _handle_key_event(self, event: QtGui.QKeyEvent) -> bool:
"""Handle a key press/release event.
Args:
@@ -76,7 +74,7 @@ class EventFilter(QObject):
# No window available yet, or not a MainWindow
return False
- def eventFilter(self, obj: QObject, event: QEvent) -> bool:
+ def eventFilter(self, obj: QtCore.QObject, event: QtCore.QEvent) -> bool:
"""Handle an event.
Args:
@@ -86,7 +84,7 @@ class EventFilter(QObject):
Return:
True if the event should be filtered, False if it's passed through.
"""
- if not isinstance(obj, QWindow):
+ if not isinstance(obj, QtGui.QWindow):
# We already handled this same event at some point earlier, so
# we're not interested in it anymore.
return False
@@ -101,7 +99,7 @@ class EventFilter(QObject):
handler = self._handlers[typ]
try:
- return handler(cast(QKeyEvent, event))
+ return handler(cast(QtGui.QKeyEvent, event))
except:
# If there is an exception in here and we leave the eventfilter
# activated, we'll get an infinite loop and a stack overflow.
diff --git a/qutebrowser/keyinput/keyutils.py b/qutebrowser/keyinput/keyutils.py
index f74c59aa7..f1c0e8837 100644
--- a/qutebrowser/keyinput/keyutils.py
+++ b/qutebrowser/keyinput/keyutils.py
@@ -35,25 +35,23 @@ import itertools
import dataclasses
from typing import cast, overload, Iterable, Iterator, List, Mapping, Optional, Union
-from PyQt5.QtCore import Qt, QEvent
-from PyQt5.QtGui import QKeySequence, QKeyEvent
-
from qutebrowser.utils import utils
+from qutebrowser.qt import QtGui, QtCore
# Map Qt::Key values to their Qt::KeyboardModifier value.
_MODIFIER_MAP = {
- Qt.Key_Shift: Qt.ShiftModifier,
- Qt.Key_Control: Qt.ControlModifier,
- Qt.Key_Alt: Qt.AltModifier,
- Qt.Key_Meta: Qt.MetaModifier,
- Qt.Key_AltGr: Qt.GroupSwitchModifier,
- Qt.Key_Mode_switch: Qt.GroupSwitchModifier,
+ QtCore.Qt.Key_Shift: QtCore.Qt.ShiftModifier,
+ QtCore.Qt.Key_Control: QtCore.Qt.ControlModifier,
+ QtCore.Qt.Key_Alt: QtCore.Qt.AltModifier,
+ QtCore.Qt.Key_Meta: QtCore.Qt.MetaModifier,
+ QtCore.Qt.Key_AltGr: QtCore.Qt.GroupSwitchModifier,
+ QtCore.Qt.Key_Mode_switch: QtCore.Qt.GroupSwitchModifier,
}
-_NIL_KEY = Qt.Key(0)
+_NIL_KEY = QtCore.Qt.Key(0)
-_ModifierType = Union[Qt.KeyboardModifier, Qt.KeyboardModifiers]
+_ModifierType = Union[QtCore.Qt.KeyboardModifier, QtCore.Qt.KeyboardModifiers]
_SPECIAL_NAMES = {
@@ -63,116 +61,116 @@ _SPECIAL_NAMES = {
# For dead/combining keys, we return the corresponding non-combining
# key, as that's easier to add to the config.
- Qt.Key_Super_L: 'Super L',
- Qt.Key_Super_R: 'Super R',
- Qt.Key_Hyper_L: 'Hyper L',
- Qt.Key_Hyper_R: 'Hyper R',
- Qt.Key_Direction_L: 'Direction L',
- Qt.Key_Direction_R: 'Direction R',
-
- Qt.Key_Shift: 'Shift',
- Qt.Key_Control: 'Control',
- Qt.Key_Meta: 'Meta',
- Qt.Key_Alt: 'Alt',
-
- Qt.Key_AltGr: 'AltGr',
- Qt.Key_Multi_key: 'Multi key',
- Qt.Key_SingleCandidate: 'Single Candidate',
- Qt.Key_Mode_switch: 'Mode switch',
- Qt.Key_Dead_Grave: '`',
- Qt.Key_Dead_Acute: '´',
- Qt.Key_Dead_Circumflex: '^',
- Qt.Key_Dead_Tilde: '~',
- Qt.Key_Dead_Macron: '¯',
- Qt.Key_Dead_Breve: '˘',
- Qt.Key_Dead_Abovedot: '˙',
- Qt.Key_Dead_Diaeresis: '¨',
- Qt.Key_Dead_Abovering: '˚',
- Qt.Key_Dead_Doubleacute: '˝',
- Qt.Key_Dead_Caron: 'ˇ',
- Qt.Key_Dead_Cedilla: '¸',
- Qt.Key_Dead_Ogonek: '˛',
- Qt.Key_Dead_Iota: 'Iota',
- Qt.Key_Dead_Voiced_Sound: 'Voiced Sound',
- Qt.Key_Dead_Semivoiced_Sound: 'Semivoiced Sound',
- Qt.Key_Dead_Belowdot: 'Belowdot',
- Qt.Key_Dead_Hook: 'Hook',
- Qt.Key_Dead_Horn: 'Horn',
-
- Qt.Key_Dead_Stroke: '\u0335', # '̵'
- Qt.Key_Dead_Abovecomma: '\u0313', # '̓'
- Qt.Key_Dead_Abovereversedcomma: '\u0314', # '̔'
- Qt.Key_Dead_Doublegrave: '\u030f', # '̏'
- Qt.Key_Dead_Belowring: '\u0325', # '̥'
- Qt.Key_Dead_Belowmacron: '\u0331', # '̱'
- Qt.Key_Dead_Belowcircumflex: '\u032d', # '̭'
- Qt.Key_Dead_Belowtilde: '\u0330', # '̰'
- Qt.Key_Dead_Belowbreve: '\u032e', # '̮'
- Qt.Key_Dead_Belowdiaeresis: '\u0324', # '̤'
- Qt.Key_Dead_Invertedbreve: '\u0311', # '̑'
- Qt.Key_Dead_Belowcomma: '\u0326', # '̦'
- Qt.Key_Dead_Currency: '¤',
- Qt.Key_Dead_a: 'a',
- Qt.Key_Dead_A: 'A',
- Qt.Key_Dead_e: 'e',
- Qt.Key_Dead_E: 'E',
- Qt.Key_Dead_i: 'i',
- Qt.Key_Dead_I: 'I',
- Qt.Key_Dead_o: 'o',
- Qt.Key_Dead_O: 'O',
- Qt.Key_Dead_u: 'u',
- Qt.Key_Dead_U: 'U',
- Qt.Key_Dead_Small_Schwa: 'ə',
- Qt.Key_Dead_Capital_Schwa: 'Ə',
- Qt.Key_Dead_Greek: 'Greek',
- Qt.Key_Dead_Lowline: '\u0332', # '̲'
- Qt.Key_Dead_Aboveverticalline: '\u030d', # '̍'
- Qt.Key_Dead_Belowverticalline: '\u0329',
- Qt.Key_Dead_Longsolidusoverlay: '\u0338', # '̸'
-
- Qt.Key_Memo: 'Memo',
- Qt.Key_ToDoList: 'To Do List',
- Qt.Key_Calendar: 'Calendar',
- Qt.Key_ContrastAdjust: 'Contrast Adjust',
- Qt.Key_LaunchG: 'Launch (G)',
- Qt.Key_LaunchH: 'Launch (H)',
-
- Qt.Key_MediaLast: 'Media Last',
-
- Qt.Key_unknown: 'Unknown',
+ QtCore.Qt.Key_Super_L: 'Super L',
+ QtCore.Qt.Key_Super_R: 'Super R',
+ QtCore.Qt.Key_Hyper_L: 'Hyper L',
+ QtCore.Qt.Key_Hyper_R: 'Hyper R',
+ QtCore.Qt.Key_Direction_L: 'Direction L',
+ QtCore.Qt.Key_Direction_R: 'Direction R',
+
+ QtCore.Qt.Key_Shift: 'Shift',
+ QtCore.Qt.Key_Control: 'Control',
+ QtCore.Qt.Key_Meta: 'Meta',
+ QtCore.Qt.Key_Alt: 'Alt',
+
+ QtCore.Qt.Key_AltGr: 'AltGr',
+ QtCore.Qt.Key_Multi_key: 'Multi key',
+ QtCore.Qt.Key_SingleCandidate: 'Single Candidate',
+ QtCore.Qt.Key_Mode_switch: 'Mode switch',
+ QtCore.Qt.Key_Dead_Grave: '`',
+ QtCore.Qt.Key_Dead_Acute: '´',
+ QtCore.Qt.Key_Dead_Circumflex: '^',
+ QtCore.Qt.Key_Dead_Tilde: '~',
+ QtCore.Qt.Key_Dead_Macron: '¯',
+ QtCore.Qt.Key_Dead_Breve: '˘',
+ QtCore.Qt.Key_Dead_Abovedot: '˙',
+ QtCore.Qt.Key_Dead_Diaeresis: '¨',
+ QtCore.Qt.Key_Dead_Abovering: '˚',
+ QtCore.Qt.Key_Dead_Doubleacute: '˝',
+ QtCore.Qt.Key_Dead_Caron: 'ˇ',
+ QtCore.Qt.Key_Dead_Cedilla: '¸',
+ QtCore.Qt.Key_Dead_Ogonek: '˛',
+ QtCore.Qt.Key_Dead_Iota: 'Iota',
+ QtCore.Qt.Key_Dead_Voiced_Sound: 'Voiced Sound',
+ QtCore.Qt.Key_Dead_Semivoiced_Sound: 'Semivoiced Sound',
+ QtCore.Qt.Key_Dead_Belowdot: 'Belowdot',
+ QtCore.Qt.Key_Dead_Hook: 'Hook',
+ QtCore.Qt.Key_Dead_Horn: 'Horn',
+
+ QtCore.Qt.Key_Dead_Stroke: '\u0335', # '̵'
+ QtCore.Qt.Key_Dead_Abovecomma: '\u0313', # '̓'
+ QtCore.Qt.Key_Dead_Abovereversedcomma: '\u0314', # '̔'
+ QtCore.Qt.Key_Dead_Doublegrave: '\u030f', # '̏'
+ QtCore.Qt.Key_Dead_Belowring: '\u0325', # '̥'
+ QtCore.Qt.Key_Dead_Belowmacron: '\u0331', # '̱'
+ QtCore.Qt.Key_Dead_Belowcircumflex: '\u032d', # '̭'
+ QtCore.Qt.Key_Dead_Belowtilde: '\u0330', # '̰'
+ QtCore.Qt.Key_Dead_Belowbreve: '\u032e', # '̮'
+ QtCore.Qt.Key_Dead_Belowdiaeresis: '\u0324', # '̤'
+ QtCore.Qt.Key_Dead_Invertedbreve: '\u0311', # '̑'
+ QtCore.Qt.Key_Dead_Belowcomma: '\u0326', # '̦'
+ QtCore.Qt.Key_Dead_Currency: '¤',
+ QtCore.Qt.Key_Dead_a: 'a',
+ QtCore.Qt.Key_Dead_A: 'A',
+ QtCore.Qt.Key_Dead_e: 'e',
+ QtCore.Qt.Key_Dead_E: 'E',
+ QtCore.Qt.Key_Dead_i: 'i',
+ QtCore.Qt.Key_Dead_I: 'I',
+ QtCore.Qt.Key_Dead_o: 'o',
+ QtCore.Qt.Key_Dead_O: 'O',
+ QtCore.Qt.Key_Dead_u: 'u',
+ QtCore.Qt.Key_Dead_U: 'U',
+ QtCore.Qt.Key_Dead_Small_Schwa: 'ə',
+ QtCore.Qt.Key_Dead_Capital_Schwa: 'Ə',
+ QtCore.Qt.Key_Dead_Greek: 'Greek',
+ QtCore.Qt.Key_Dead_Lowline: '\u0332', # '̲'
+ QtCore.Qt.Key_Dead_Aboveverticalline: '\u030d', # '̍'
+ QtCore.Qt.Key_Dead_Belowverticalline: '\u0329',
+ QtCore.Qt.Key_Dead_Longsolidusoverlay: '\u0338', # '̸'
+
+ QtCore.Qt.Key_Memo: 'Memo',
+ QtCore.Qt.Key_ToDoList: 'To Do List',
+ QtCore.Qt.Key_Calendar: 'Calendar',
+ QtCore.Qt.Key_ContrastAdjust: 'Contrast Adjust',
+ QtCore.Qt.Key_LaunchG: 'Launch (G)',
+ QtCore.Qt.Key_LaunchH: 'Launch (H)',
+
+ QtCore.Qt.Key_MediaLast: 'Media Last',
+
+ QtCore.Qt.Key_unknown: 'Unknown',
# For some keys, we just want a different name
- Qt.Key_Escape: 'Escape',
+ QtCore.Qt.Key_Escape: 'Escape',
_NIL_KEY: 'nil',
}
-def _assert_plain_key(key: Qt.Key) -> None:
+def _assert_plain_key(key: QtCore.Qt.Key) -> None:
"""Make sure this is a key without KeyboardModifiers mixed in."""
- assert not key & Qt.KeyboardModifierMask, hex(key)
+ assert not key & QtCore.Qt.KeyboardModifierMask, hex(key)
def _assert_plain_modifier(key: _ModifierType) -> None:
"""Make sure this is a modifier without a key mixed in."""
- mask = Qt.KeyboardModifierMask
+ mask = QtCore.Qt.KeyboardModifierMask
assert not key & ~mask, hex(key) # type: ignore[operator]
-def _is_printable(key: Qt.Key) -> bool:
+def _is_printable(key: QtCore.Qt.Key) -> bool:
_assert_plain_key(key)
- return key <= 0xff and key not in [Qt.Key_Space, _NIL_KEY]
+ return key <= 0xff and key not in [QtCore.Qt.Key_Space, _NIL_KEY]
-def is_special(key: Qt.Key, modifiers: _ModifierType) -> bool:
+def is_special(key: QtCore.Qt.Key, modifiers: _ModifierType) -> bool:
"""Check whether this key requires special key syntax."""
_assert_plain_key(key)
_assert_plain_modifier(modifiers)
return not (_is_printable(key) and
- modifiers in [Qt.ShiftModifier, Qt.NoModifier])
+ modifiers in [QtCore.Qt.ShiftModifier, QtCore.Qt.NoModifier])
-def is_modifier_key(key: Qt.Key) -> bool:
+def is_modifier_key(key: QtCore.Qt.Key) -> bool:
"""Test whether the given key is a modifier.
This only considers keys which are part of Qt::KeyboardModifiers, i.e.
@@ -182,7 +180,7 @@ def is_modifier_key(key: Qt.Key) -> bool:
return key in _MODIFIER_MAP
-def _is_surrogate(key: Qt.Key) -> bool:
+def _is_surrogate(key: QtCore.Qt.Key) -> bool:
"""Check if a codepoint is a UTF-16 surrogate.
UTF-16 surrogates are a reserved range of Unicode from 0xd800
@@ -193,7 +191,7 @@ def _is_surrogate(key: Qt.Key) -> bool:
return 0xd800 <= key <= 0xdfff
-def _remap_unicode(key: Qt.Key, text: str) -> Qt.Key:
+def _remap_unicode(key: QtCore.Qt.Key, text: str) -> QtCore.Qt.Key:
"""Work around QtKeyEvent's bad values for high codepoints.
QKeyEvent handles higher unicode codepoints poorly. It uses UTF-16 to
@@ -211,11 +209,11 @@ def _remap_unicode(key: Qt.Key, text: str) -> Qt.Key:
if len(text) != 1:
raise KeyParseError(text, "Expected 1 character for surrogate, "
"but got {}!".format(len(text)))
- return Qt.Key(ord(text[0]))
+ return QtCore.Qt.Key(ord(text[0]))
return key
-def _check_valid_utf8(s: str, data: Union[Qt.Key, _ModifierType]) -> None:
+def _check_valid_utf8(s: str, data: Union[QtCore.Qt.Key, _ModifierType]) -> None:
"""Make sure the given string is valid UTF-8.
Makes sure there are no chars where Qt did fall back to weird UTF-16
@@ -228,7 +226,7 @@ def _check_valid_utf8(s: str, data: Union[Qt.Key, _ModifierType]) -> None:
.format(int(data), s, e))
-def _key_to_string(key: Qt.Key) -> str:
+def _key_to_string(key: QtCore.Qt.Key) -> str:
"""Convert a Qt::Key member to a meaningful name.
Args:
@@ -242,7 +240,7 @@ def _key_to_string(key: Qt.Key) -> str:
if key in _SPECIAL_NAMES:
return _SPECIAL_NAMES[key]
- result = QKeySequence(key).toString()
+ result = QtGui.QKeySequence(key).toString()
_check_valid_utf8(result, key)
return result
@@ -254,14 +252,14 @@ def _modifiers_to_string(modifiers: _ModifierType) -> str:
modifier.
"""
_assert_plain_modifier(modifiers)
- altgr = Qt.GroupSwitchModifier
+ altgr = QtCore.Qt.GroupSwitchModifier
if modifiers & altgr: # type: ignore[operator]
modifiers &= ~altgr # type: ignore[operator, assignment]
result = 'AltGr+'
else:
result = ''
- result += QKeySequence(modifiers).toString()
+ result += QtGui.QKeySequence(modifiers).toString()
_check_valid_utf8(result, modifiers)
return result
@@ -347,21 +345,21 @@ class KeyInfo:
modifiers: A Qt::KeyboardModifiers enum value.
"""
- key: Qt.Key
+ key: QtCore.Qt.Key
modifiers: _ModifierType
@classmethod
- def from_event(cls, e: QKeyEvent) -> 'KeyInfo':
+ def from_event(cls, e: QtGui.QKeyEvent) -> 'KeyInfo':
"""Get a KeyInfo object from a QKeyEvent.
This makes sure that key/modifiers are never mixed and also remaps
UTF-16 surrogates to work around QTBUG-72776.
"""
- key = _remap_unicode(Qt.Key(e.key()), e.text())
+ key = _remap_unicode(QtCore.Qt.Key(e.key()), e.text())
modifiers = e.modifiers()
_assert_plain_key(key)
_assert_plain_modifier(modifiers)
- return cls(key, cast(Qt.KeyboardModifier, modifiers))
+ return cls(key, cast(QtCore.Qt.KeyboardModifier, modifiers))
def __str__(self) -> str:
"""Convert this KeyInfo to a meaningful name.
@@ -382,17 +380,17 @@ class KeyInfo:
.format(self.key))
assert len(key_string) == 1, key_string
- if self.modifiers == Qt.ShiftModifier:
+ if self.modifiers == QtCore.Qt.ShiftModifier:
assert not is_special(self.key, self.modifiers)
return key_string.upper()
- elif self.modifiers == Qt.NoModifier:
+ elif self.modifiers == QtCore.Qt.NoModifier:
assert not is_special(self.key, self.modifiers)
return key_string.lower()
else:
# Use special binding syntax, but <Ctrl-a> instead of <Ctrl-A>
key_string = key_string.lower()
- modifiers = Qt.KeyboardModifier(modifiers)
+ modifiers = QtCore.Qt.KeyboardModifier(modifiers)
# "special" binding
assert is_special(self.key, self.modifiers)
@@ -402,12 +400,12 @@ class KeyInfo:
def text(self) -> str:
"""Get the text which would be displayed when pressing this key."""
control = {
- Qt.Key_Space: ' ',
- Qt.Key_Tab: '\t',
- Qt.Key_Backspace: '\b',
- Qt.Key_Return: '\r',
- Qt.Key_Enter: '\r',
- Qt.Key_Escape: '\x1b',
+ QtCore.Qt.Key_Space: ' ',
+ QtCore.Qt.Key_Tab: '\t',
+ QtCore.Qt.Key_Backspace: '\b',
+ QtCore.Qt.Key_Return: '\r',
+ QtCore.Qt.Key_Enter: '\r',
+ QtCore.Qt.Key_Escape: '\x1b',
}
if self.key in control:
@@ -415,14 +413,14 @@ class KeyInfo:
elif not _is_printable(self.key):
return ''
- text = QKeySequence(self.key).toString()
- if not self.modifiers & Qt.ShiftModifier: # type: ignore[operator]
+ text = QtGui.QKeySequence(self.key).toString()
+ if not self.modifiers & QtCore.Qt.ShiftModifier: # type: ignore[operator]
text = text.lower()
return text
- def to_event(self, typ: QEvent.Type = QEvent.KeyPress) -> QKeyEvent:
+ def to_event(self, typ: QtCore.QEvent.Type = QtCore.QEvent.KeyPress) -> QtGui.QKeyEvent:
"""Get a QKeyEvent from this KeyInfo."""
- return QKeyEvent(typ, self.key, self.modifiers, self.text())
+ return QtGui.QKeyEvent(typ, self.key, self.modifiers, self.text())
def to_int(self) -> int:
"""Get the key as an integer (with key/modifiers)."""
@@ -449,18 +447,18 @@ class KeySequence:
_MAX_LEN = 4
def __init__(self, *keys: int) -> None:
- self._sequences: List[QKeySequence] = []
+ self._sequences: List[QtGui.QKeySequence] = []
for sub in utils.chunk(keys, self._MAX_LEN):
args = [self._convert_key(key) for key in sub]
- sequence = QKeySequence(*args)
+ sequence = QtGui.QKeySequence(*args)
self._sequences.append(sequence)
if keys:
assert self
self._validate()
- def _convert_key(self, key: Union[int, Qt.KeyboardModifiers]) -> int:
+ def _convert_key(self, key: Union[int, QtCore.Qt.KeyboardModifiers]) -> int:
"""Convert a single key for QKeySequence."""
- assert isinstance(key, (int, Qt.KeyboardModifiers)), key
+ assert isinstance(key, (int, QtCore.Qt.KeyboardModifiers)), key
return int(key)
def __str__(self) -> str:
@@ -472,9 +470,9 @@ class KeySequence:
def __iter__(self) -> Iterator[KeyInfo]:
"""Iterate over KeyInfo objects."""
for key_and_modifiers in self._iter_keys():
- key = Qt.Key(int(key_and_modifiers) & ~Qt.KeyboardModifierMask)
- modifiers = Qt.KeyboardModifiers( # type: ignore[call-overload]
- int(key_and_modifiers) & Qt.KeyboardModifierMask)
+ key = QtCore.Qt.Key(int(key_and_modifiers) & ~QtCore.Qt.KeyboardModifierMask)
+ modifiers = QtCore.Qt.KeyboardModifiers( # type: ignore[call-overload]
+ int(key_and_modifiers) & QtCore.Qt.KeyboardModifierMask)
yield KeyInfo(key=key, modifiers=modifiers)
def __repr__(self) -> str:
@@ -533,14 +531,14 @@ class KeySequence:
def _validate(self, keystr: str = None) -> None:
for info in self:
- if info.key < Qt.Key_Space or info.key >= Qt.Key_unknown:
+ if info.key < QtCore.Qt.Key_Space or info.key >= QtCore.Qt.Key_unknown:
raise KeyParseError(keystr, "Got invalid key!")
for seq in self._sequences:
if not seq:
raise KeyParseError(keystr, "Got invalid key!")
- def matches(self, other: 'KeySequence') -> QKeySequence.SequenceMatch:
+ def matches(self, other: 'KeySequence') -> QtGui.QKeySequence.SequenceMatch:
"""Check whether the given KeySequence matches with this one.
We store multiple QKeySequences with <= 4 keys each, so we need to
@@ -552,12 +550,12 @@ class KeySequence:
if len(self._sequences) > len(other._sequences):
# If we entered more sequences than there are in the config,
# there's no way there can be a match.
- return QKeySequence.NoMatch
+ return QtGui.QKeySequence.NoMatch
for entered, configured in zip(self._sequences, other._sequences):
# If we get NoMatch/PartialMatch in a sequence, we can abort there.
match = entered.matches(configured)
- if match != QKeySequence.ExactMatch:
+ if match != QtGui.QKeySequence.ExactMatch:
return match
# We checked all common sequences and they had an ExactMatch.
@@ -569,15 +567,15 @@ class KeySequence:
# If there's the same amount of sequences configured and entered,
# that's an EqualMatch.
if len(self._sequences) == len(other._sequences):
- return QKeySequence.ExactMatch
+ return QtGui.QKeySequence.ExactMatch
elif len(self._sequences) < len(other._sequences):
- return QKeySequence.PartialMatch
+ return QtGui.QKeySequence.PartialMatch
else:
raise utils.Unreachable("self={!r} other={!r}".format(self, other))
- def append_event(self, ev: QKeyEvent) -> 'KeySequence':
+ def append_event(self, ev: QtGui.QKeyEvent) -> 'KeySequence':
"""Create a new KeySequence object with the given QKeyEvent added."""
- key = Qt.Key(ev.key())
+ key = QtCore.Qt.Key(ev.key())
_assert_plain_key(key)
_assert_plain_modifier(ev.modifiers())
@@ -590,12 +588,12 @@ class KeySequence:
# We always remove Qt.GroupSwitchModifier because QKeySequence has no
# way to mention that in a binding anyways...
- modifiers &= ~Qt.GroupSwitchModifier
+ modifiers &= ~QtCore.Qt.GroupSwitchModifier
# We change Qt.Key_Backtab to Key_Tab here because nobody would
# configure "Shift-Backtab" in their config.
- if modifiers & Qt.ShiftModifier and key == Qt.Key_Backtab:
- key = Qt.Key_Tab
+ if modifiers & QtCore.Qt.ShiftModifier and key == QtCore.Qt.Key_Backtab:
+ key = QtCore.Qt.Key_Tab
# We don't care about a shift modifier with symbols (Shift-: should
# match a : binding even though we typed it with a shift on an
@@ -607,10 +605,10 @@ class KeySequence:
#
# In addition, Shift also *is* relevant when other modifiers are
# involved. Shift-Ctrl-X should not be equivalent to Ctrl-X.
- if (modifiers == Qt.ShiftModifier and
+ if (modifiers == QtCore.Qt.ShiftModifier and
_is_printable(key) and
not ev.text().isupper()):
- modifiers = Qt.KeyboardModifiers() # type: ignore[assignment]
+ modifiers = QtCore.Qt.KeyboardModifiers() # type: ignore[assignment]
# On macOS, swap Ctrl and Meta back
#
@@ -619,14 +617,14 @@ class KeySequence:
# (or "Cmd") in a key binding name to actually represent what's on the
# keyboard.
if utils.is_mac:
- if modifiers & Qt.ControlModifier and modifiers & Qt.MetaModifier:
+ if modifiers & QtCore.Qt.ControlModifier and modifiers & QtCore.Qt.MetaModifier:
pass
- elif modifiers & Qt.ControlModifier:
- modifiers &= ~Qt.ControlModifier
- modifiers |= Qt.MetaModifier
- elif modifiers & Qt.MetaModifier:
- modifiers &= ~Qt.MetaModifier
- modifiers |= Qt.ControlModifier
+ elif modifiers & QtCore.Qt.ControlModifier:
+ modifiers &= ~QtCore.Qt.ControlModifier
+ modifiers |= QtCore.Qt.MetaModifier
+ elif modifiers & QtCore.Qt.MetaModifier:
+ modifiers &= ~QtCore.Qt.MetaModifier
+ modifiers |= QtCore.Qt.ControlModifier
keys = list(self._iter_keys())
keys.append(key | int(modifiers))
@@ -635,7 +633,7 @@ class KeySequence:
def strip_modifiers(self) -> 'KeySequence':
"""Strip optional modifiers from keys."""
- modifiers = Qt.KeypadModifier
+ modifiers = QtCore.Qt.KeypadModifier
keys = [key & ~modifiers for key in self._iter_keys()]
return self.__class__(*keys)
@@ -659,7 +657,7 @@ class KeySequence:
new = cls()
strings = list(_parse_keystring(keystr))
for sub in utils.chunk(strings, cls._MAX_LEN):
- sequence = QKeySequence(', '.join(sub))
+ sequence = QtGui.QKeySequence(', '.join(sub))
new._sequences.append(sequence)
if keystr:
diff --git a/qutebrowser/keyinput/modeman.py b/qutebrowser/keyinput/modeman.py
index 3c47fafe3..665e88556 100644
--- a/qutebrowser/keyinput/modeman.py
+++ b/qutebrowser/keyinput/modeman.py
@@ -22,9 +22,7 @@
import functools
import dataclasses
from typing import Mapping, Callable, MutableMapping, Union, Set, cast
-
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QObject, QEvent
-from PyQt5.QtGui import QKeyEvent
+from qutebrowser.qt import QtGui
from qutebrowser.commands import runners
from qutebrowser.keyinput import modeparsers, basekeyparser
@@ -33,6 +31,7 @@ from qutebrowser.api import cmdutils
from qutebrowser.utils import usertypes, log, objreg, utils
from qutebrowser.browser import hints
from qutebrowser.misc import objects
+from qutebrowser.qt import QtCore
INPUT_MODES = [usertypes.KeyMode.insert, usertypes.KeyMode.passthrough]
PROMPT_MODES = [usertypes.KeyMode.prompt, usertypes.KeyMode.yesno]
@@ -54,13 +53,13 @@ class KeyEvent:
text: A string (QKeyEvent::text).
"""
- key: Qt.Key
+ key: QtCore.Qt.Key
text: str
@classmethod
- def from_event(cls, event: QKeyEvent) -> 'KeyEvent':
+ def from_event(cls, event: QtGui.QKeyEvent) -> 'KeyEvent':
"""Initialize a KeyEvent from a QKeyEvent."""
- return cls(Qt.Key(event.key()), event.text())
+ return cls(QtCore.Qt.Key(event.key()), event.text())
class NotInModeError(Exception):
@@ -76,7 +75,7 @@ class UnavailableError(Exception):
"""
-def init(win_id: int, parent: QObject) -> 'ModeManager':
+def init(win_id: int, parent: QtCore.QObject) -> 'ModeManager':
"""Initialize the mode manager and the keyparsers for the given win_id."""
commandrunner = runners.CommandRunner(win_id)
@@ -224,7 +223,7 @@ def leave(win_id: int,
instance(win_id).leave(mode, reason, maybe=maybe)
-class ModeManager(QObject):
+class ModeManager(QtCore.QObject):
"""Manager for keyboard modes.
@@ -253,11 +252,11 @@ class ModeManager(QObject):
arg 2: The new key string.
"""
- entered = pyqtSignal(usertypes.KeyMode, int)
- left = pyqtSignal(usertypes.KeyMode, usertypes.KeyMode, int)
- keystring_updated = pyqtSignal(usertypes.KeyMode, str)
+ entered = QtCore.pyqtSignal(usertypes.KeyMode, int)
+ left = QtCore.pyqtSignal(usertypes.KeyMode, usertypes.KeyMode, int)
+ keystring_updated = QtCore.pyqtSignal(usertypes.KeyMode, str)
- def __init__(self, win_id: int, parent: QObject = None) -> None:
+ def __init__(self, win_id: int, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
self._win_id = win_id
self.parsers: ParserDictType = {}
@@ -270,7 +269,7 @@ class ModeManager(QObject):
def __repr__(self) -> str:
return utils.get_repr(self, mode=self.mode)
- def _handle_keypress(self, event: QKeyEvent, *,
+ def _handle_keypress(self, event: QtGui.QKeyEvent, *,
dry_run: bool = False) -> bool:
"""Handle filtering of KeyPress events.
@@ -289,8 +288,8 @@ class ModeManager(QObject):
match = parser.handle(event, dry_run=dry_run)
has_modifier = event.modifiers() not in [
- Qt.NoModifier,
- Qt.ShiftModifier,
+ QtCore.Qt.NoModifier,
+ QtCore.Qt.ShiftModifier,
] # type: ignore[comparison-overlap]
is_non_alnum = has_modifier or not event.text().strip()
@@ -317,7 +316,7 @@ class ModeManager(QObject):
filter_this, focus_widget))
return filter_this
- def _handle_keyrelease(self, event: QKeyEvent) -> bool:
+ def _handle_keyrelease(self, event: QtGui.QKeyEvent) -> bool:
"""Handle filtering of KeyRelease events.
Args:
@@ -408,7 +407,7 @@ class ModeManager(QObject):
self.enter(m, 'command')
- @pyqtSlot(usertypes.KeyMode, str, bool)
+ @QtCore.pyqtSlot(usertypes.KeyMode, str, bool)
def leave(self, mode: usertypes.KeyMode,
reason: str = None,
maybe: bool = False) -> None:
@@ -447,7 +446,7 @@ class ModeManager(QObject):
raise ValueError("Can't leave normal mode!")
self.leave(self.mode, 'leave current')
- def handle_event(self, event: QEvent) -> bool:
+ def handle_event(self, event: QtCore.QEvent) -> bool:
"""Filter all events based on the currently set mode.
Also calls the real keypress handler.
@@ -458,14 +457,14 @@ class ModeManager(QObject):
Return:
True if event should be filtered, False otherwise.
"""
- handlers: Mapping[QEvent.Type, Callable[[QKeyEvent], bool]] = {
- QEvent.KeyPress: self._handle_keypress,
- QEvent.KeyRelease: self._handle_keyrelease,
- QEvent.ShortcutOverride:
+ handlers: Mapping[QtCore.QEvent.Type, Callable[[QtGui.QKeyEvent], bool]] = {
+ QtCore.QEvent.KeyPress: self._handle_keypress,
+ QtCore.QEvent.KeyRelease: self._handle_keyrelease,
+ QtCore.QEvent.ShortcutOverride:
functools.partial(self._handle_keypress, dry_run=True),
}
handler = handlers[event.type()]
- return handler(cast(QKeyEvent, event))
+ return handler(cast(QtGui.QKeyEvent, event))
@cmdutils.register(instance='mode-manager', scope='window')
def clear_keychain(self) -> None:
diff --git a/qutebrowser/keyinput/modeparsers.py b/qutebrowser/keyinput/modeparsers.py
index bd5d4e801..53ec37c49 100644
--- a/qutebrowser/keyinput/modeparsers.py
+++ b/qutebrowser/keyinput/modeparsers.py
@@ -27,14 +27,13 @@ import traceback
import enum
from typing import TYPE_CHECKING, Sequence
-from PyQt5.QtCore import pyqtSlot, Qt, QObject
-from PyQt5.QtGui import QKeySequence, QKeyEvent
-
from qutebrowser.browser import hints
from qutebrowser.commands import cmdexc
from qutebrowser.config import config
from qutebrowser.keyinput import basekeyparser, keyutils, macros
from qutebrowser.utils import usertypes, log, message, objreg, utils
+from qutebrowser.qt import QtGui, QtCore
+
if TYPE_CHECKING:
from qutebrowser.commands import runners
@@ -62,7 +61,7 @@ class CommandKeyParser(basekeyparser.BaseKeyParser):
def __init__(self, *, mode: usertypes.KeyMode,
win_id: int,
commandrunner: 'runners.CommandRunner',
- parent: QObject = None,
+ parent: QtCore.QObject = None,
do_log: bool = True,
passthrough: bool = False,
supports_count: bool = True) -> None:
@@ -90,7 +89,7 @@ class NormalKeyParser(CommandKeyParser):
def __init__(self, *, win_id: int,
commandrunner: 'runners.CommandRunner',
- parent: QObject = None) -> None:
+ parent: QtCore.QObject = None) -> None:
super().__init__(mode=usertypes.KeyMode.normal, win_id=win_id,
commandrunner=commandrunner, parent=parent)
self._partial_timer = usertypes.Timer(self, 'partial-match')
@@ -103,18 +102,18 @@ class NormalKeyParser(CommandKeyParser):
def __repr__(self) -> str:
return utils.get_repr(self)
- def handle(self, e: QKeyEvent, *,
- dry_run: bool = False) -> QKeySequence.SequenceMatch:
+ def handle(self, e: QtGui.QKeyEvent, *,
+ dry_run: bool = False) -> QtGui.QKeySequence.SequenceMatch:
"""Override to abort if the key is a startchar."""
txt = e.text().strip()
if self._inhibited:
self._debug_log("Ignoring key '{}', because the normal mode is "
"currently inhibited.".format(txt))
- return QKeySequence.NoMatch
+ return QtGui.QKeySequence.NoMatch
match = super().handle(e, dry_run=dry_run)
- if match == QKeySequence.PartialMatch and not dry_run:
+ if match == QtGui.QKeySequence.PartialMatch and not dry_run:
timeout = config.val.input.partial_timeout
if timeout != 0:
self._partial_timer.setInterval(timeout)
@@ -131,7 +130,7 @@ class NormalKeyParser(CommandKeyParser):
self._inhibited_timer.timeout.connect(self._clear_inhibited)
self._inhibited_timer.start()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _clear_partial_match(self) -> None:
"""Clear a partial keystring after a timeout."""
self._debug_log("Clearing partial keystring {}".format(
@@ -139,7 +138,7 @@ class NormalKeyParser(CommandKeyParser):
self._sequence = keyutils.KeySequence()
self.keystring_updated.emit(str(self._sequence))
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _clear_inhibited(self) -> None:
"""Reset inhibition state after a timeout."""
self._debug_log("Releasing inhibition state of normal mode.")
@@ -161,7 +160,7 @@ class HintKeyParser(basekeyparser.BaseKeyParser):
def __init__(self, *, win_id: int,
commandrunner: 'runners.CommandRunner',
hintmanager: hints.HintManager,
- parent: QObject = None) -> None:
+ parent: QtCore.QObject = None) -> None:
super().__init__(mode=usertypes.KeyMode.hint, win_id=win_id,
parent=parent, supports_count=False)
self._command_parser = CommandKeyParser(mode=usertypes.KeyMode.hint,
@@ -174,11 +173,11 @@ class HintKeyParser(basekeyparser.BaseKeyParser):
self._last_press = LastPress.none
self.keystring_updated.connect(self._hintmanager.handle_partial_key)
- def _handle_filter_key(self, e: QKeyEvent) -> QKeySequence.SequenceMatch:
+ def _handle_filter_key(self, e: QtGui.QKeyEvent) -> QtGui.QKeySequence.SequenceMatch:
"""Handle keys for string filtering."""
log.keyboard.debug("Got filter key 0x{:x} text {}".format(
e.key(), e.text()))
- if e.key() == Qt.Key_Backspace:
+ if e.key() == QtCore.Qt.Key_Backspace:
log.keyboard.debug("Got backspace, mode {}, filtertext '{}', "
"sequence '{}'".format(self._last_press,
self._filtertext,
@@ -186,7 +185,7 @@ class HintKeyParser(basekeyparser.BaseKeyParser):
if self._last_press != LastPress.keystring and self._filtertext:
self._filtertext = self._filtertext[:-1]
self._hintmanager.filter_hints(self._filtertext)
- return QKeySequence.ExactMatch
+ return QtGui.QKeySequence.ExactMatch
elif self._last_press == LastPress.keystring and self._sequence:
self._sequence = self._sequence[:-1]
self.keystring_updated.emit(str(self._sequence))
@@ -195,21 +194,21 @@ class HintKeyParser(basekeyparser.BaseKeyParser):
# in numeric mode after the number has been deleted).
self._hintmanager.filter_hints(self._filtertext)
self._last_press = LastPress.filtertext
- return QKeySequence.ExactMatch
+ return QtGui.QKeySequence.ExactMatch
else:
- return QKeySequence.NoMatch
+ return QtGui.QKeySequence.NoMatch
elif self._hintmanager.current_mode() != 'number':
- return QKeySequence.NoMatch
+ return QtGui.QKeySequence.NoMatch
elif not e.text():
- return QKeySequence.NoMatch
+ return QtGui.QKeySequence.NoMatch
else:
self._filtertext += e.text()
self._hintmanager.filter_hints(self._filtertext)
self._last_press = LastPress.filtertext
- return QKeySequence.ExactMatch
+ return QtGui.QKeySequence.ExactMatch
- def handle(self, e: QKeyEvent, *,
- dry_run: bool = False) -> QKeySequence.SequenceMatch:
+ def handle(self, e: QtGui.QKeyEvent, *,
+ dry_run: bool = False) -> QtGui.QKeySequence.SequenceMatch:
"""Handle a new keypress and call the respective handlers."""
if dry_run:
return super().handle(e, dry_run=True)
@@ -217,18 +216,18 @@ class HintKeyParser(basekeyparser.BaseKeyParser):
assert not dry_run
if (self._command_parser.handle(e, dry_run=True) !=
- QKeySequence.NoMatch):
+ QtGui.QKeySequence.NoMatch):
log.keyboard.debug("Handling key via command parser")
self.clear_keystring()
return self._command_parser.handle(e)
match = super().handle(e)
- if match == QKeySequence.PartialMatch:
+ if match == QtGui.QKeySequence.PartialMatch:
self._last_press = LastPress.keystring
- elif match == QKeySequence.ExactMatch:
+ elif match == QtGui.QKeySequence.ExactMatch:
self._last_press = LastPress.none
- elif match == QKeySequence.NoMatch:
+ elif match == QtGui.QKeySequence.NoMatch:
# We couldn't find a keychain so we check if it's a special key.
return self._handle_filter_key(e)
else:
@@ -268,22 +267,22 @@ class RegisterKeyParser(CommandKeyParser):
def __init__(self, *, win_id: int,
mode: usertypes.KeyMode,
commandrunner: 'runners.CommandRunner',
- parent: QObject = None) -> None:
+ parent: QtCore.QObject = None) -> None:
super().__init__(mode=usertypes.KeyMode.register, win_id=win_id,
commandrunner=commandrunner, parent=parent,
supports_count=False)
self._register_mode = mode
- def handle(self, e: QKeyEvent, *,
- dry_run: bool = False) -> QKeySequence.SequenceMatch:
+ def handle(self, e: QtGui.QKeyEvent, *,
+ dry_run: bool = False) -> QtGui.QKeySequence.SequenceMatch:
"""Override to always match the next key and use the register."""
match = super().handle(e, dry_run=dry_run)
if match or dry_run:
return match
- if keyutils.is_special(Qt.Key(e.key()), e.modifiers()):
+ if keyutils.is_special(QtCore.Qt.Key(e.key()), e.modifiers()):
# this is not a proper register key, let it pass and keep going
- return QKeySequence.NoMatch
+ return QtGui.QKeySequence.NoMatch
key = e.text()
@@ -307,4 +306,4 @@ class RegisterKeyParser(CommandKeyParser):
self.request_leave.emit(
self._register_mode, "valid register key", True)
- return QKeySequence.ExactMatch
+ return QtGui.QKeySequence.ExactMatch
diff --git a/qutebrowser/mainwindow/mainwindow.py b/qutebrowser/mainwindow/mainwindow.py
index 7f62c2dc4..0efa8d5e0 100644
--- a/qutebrowser/mainwindow/mainwindow.py
+++ b/qutebrowser/mainwindow/mainwindow.py
@@ -24,11 +24,7 @@ import base64
import itertools
import functools
from typing import List, MutableSequence, Optional, Tuple, cast
-
-from PyQt5.QtCore import (pyqtBoundSignal, pyqtSlot, QRect, QPoint, QTimer, Qt,
- QCoreApplication, QEventLoop, QByteArray)
-from PyQt5.QtWidgets import QWidget, QVBoxLayout, QSizePolicy
-from PyQt5.QtGui import QPalette
+from qutebrowser.qt import QtWidgets, QtGui
from qutebrowser.commands import runners
from qutebrowser.api import cmdutils
@@ -40,7 +36,7 @@ from qutebrowser.completion import completionwidget, completer
from qutebrowser.keyinput import modeman
from qutebrowser.browser import downloadview, hints, downloads
from qutebrowser.misc import crashsignal, keyhintwidget, sessions, objects
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
win_id_gen = itertools.count(0)
@@ -88,12 +84,12 @@ def get_window(*, via_ipc: bool,
def raise_window(window, alert=True):
"""Raise the given MainWindow object."""
- window.setWindowState(window.windowState() & ~Qt.WindowMinimized)
- window.setWindowState(window.windowState() | Qt.WindowActive)
+ window.setWindowState(window.windowState() & ~QtCore.Qt.WindowMinimized)
+ window.setWindowState(window.windowState() | QtCore.Qt.WindowActive)
window.raise_()
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-69568
- QCoreApplication.processEvents( # type: ignore[call-overload]
- QEventLoop.ExcludeUserInputEvents | QEventLoop.ExcludeSocketNotifiers)
+ QtCore.QCoreApplication.processEvents( # type: ignore[call-overload]
+ QtCore.QEventLoop.ExcludeUserInputEvents | QtCore.QEventLoop.ExcludeSocketNotifiers)
if not sip.isdeleted(window):
# Could be deleted by the events run above
@@ -118,10 +114,10 @@ def get_target_window():
return None
-_OverlayInfoType = Tuple[QWidget, pyqtBoundSignal, bool, str]
+_OverlayInfoType = Tuple[QtWidgets.QWidget, QtCore.pyqtBoundSignal, bool, str]
-class MainWindow(QWidget):
+class MainWindow(QtWidgets.QWidget):
"""The main window of qutebrowser.
@@ -187,8 +183,8 @@ class MainWindow(QWidget):
def __init__(self, *,
private: bool,
- geometry: Optional[QByteArray] = None,
- parent: Optional[QWidget] = None) -> None:
+ geometry: Optional[QtCore.QByteArray] = None,
+ parent: Optional[QtWidgets.QWidget] = None) -> None:
"""Create a new main window.
Args:
@@ -202,10 +198,10 @@ class MainWindow(QWidget):
from qutebrowser.mainwindow import tabbedbrowser
from qutebrowser.mainwindow.statusbar import bar
- self.setAttribute(Qt.WA_DeleteOnClose)
+ self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
if config.val.window.transparent:
- self.setAttribute(Qt.WA_TranslucentBackground)
- self.palette().setColor(QPalette.Window, Qt.transparent)
+ self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
+ self.palette().setColor(QtGui.QPalette.Window, QtCore.Qt.transparent)
self._overlays: MutableSequence[_OverlayInfoType] = []
self.win_id = next(win_id_gen)
@@ -218,7 +214,7 @@ class MainWindow(QWidget):
window=self.win_id)
self.setWindowTitle('qutebrowser')
- self._vbox = QVBoxLayout(self)
+ self._vbox = QtWidgets.QVBoxLayout(self)
self._vbox.setContentsMargins(0, 0, 0, 0)
self._vbox.setSpacing(0)
@@ -272,7 +268,7 @@ class MainWindow(QWidget):
# When we're here the statusbar might not even really exist yet, so
# resizing will fail. Therefore, we use singleShot QTimers to make sure
# we defer this until everything else is initialized.
- QTimer.singleShot(0, self._connect_overlay_signals)
+ QtCore.QTimer.singleShot(0, self._connect_overlay_signals)
config.instance.changed.connect(self._on_config_changed)
objects.qapp.new_window.emit(self)
@@ -305,7 +301,7 @@ class MainWindow(QWidget):
if not widget.isVisible():
return
- if widget.sizePolicy().horizontalPolicy() == QSizePolicy.Expanding:
+ if widget.sizePolicy().horizontalPolicy() == QtWidgets.QSizePolicy.Expanding:
width = self.width() - 2 * padding
if widget.hasHeightForWidth():
height = widget.heightForWidth(width)
@@ -329,8 +325,8 @@ class MainWindow(QWidget):
bottom = self.height()
top = self.height() - status_height - height
top = qtutils.check_overflow(top, 'int', fatal=False)
- topleft = QPoint(left, max(height_padding, top))
- bottomright = QPoint(left + width, bottom)
+ topleft = QtCore.QPoint(left, max(height_padding, top))
+ bottomright = QtCore.QPoint(left + width, bottom)
elif status_position == 'top':
if self.status.isVisible():
status_height = self.status.height()
@@ -338,15 +334,15 @@ class MainWindow(QWidget):
else:
status_height = 0
top = 0
- topleft = QPoint(left, top)
+ topleft = QtCore.QPoint(left, top)
bottom = status_height + height
bottom = qtutils.check_overflow(bottom, 'int', fatal=False)
- bottomright = QPoint(left + width,
+ bottomright = QtCore.QPoint(left + width,
min(self.height() - height_padding, bottom))
else:
raise ValueError("Invalid position {}!".format(status_position))
- rect = QRect(topleft, bottomright)
+ rect = QtCore.QRect(topleft, bottomright)
log.misc.debug('new geometry for {!r}: {}'.format(widget, rect))
if rect.isValid():
widget.setGeometry(rect)
@@ -398,7 +394,7 @@ class MainWindow(QWidget):
def __repr__(self):
return utils.get_repr(self)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _on_config_changed(self, option):
"""Resize the completion if related config options changed."""
if option == 'statusbar.padding':
@@ -416,7 +412,7 @@ class MainWindow(QWidget):
self._vbox.removeWidget(self.tabbed_browser.widget)
self._vbox.removeWidget(self._downloadview)
self._vbox.removeWidget(self.status)
- widgets: List[QWidget] = [self.tabbed_browser.widget]
+ widgets: List[QtWidgets.QWidget] = [self.tabbed_browser.widget]
downloads_position = config.val.downloads.position
if downloads_position == 'top':
@@ -478,7 +474,7 @@ class MainWindow(QWidget):
def _set_default_geometry(self):
"""Set some sensible default geometry."""
- self.setGeometry(QRect(50, 50, 800, 600))
+ self.setGeometry(QtCore.QRect(50, 50, 800, 600))
def _connect_signals(self):
"""Connect all mainwindow signals."""
@@ -561,29 +557,29 @@ class MainWindow(QWidget):
def _set_decoration(self, hidden):
"""Set the visibility of the window decoration via Qt."""
- window_flags: int = Qt.Window
+ window_flags: int = QtCore.Qt.Window
refresh_window = self.isVisible()
if hidden:
- window_flags |= Qt.CustomizeWindowHint | Qt.NoDropShadowWindowHint
- self.setWindowFlags(cast(Qt.WindowFlags, window_flags))
+ window_flags |= QtCore.Qt.CustomizeWindowHint | QtCore.Qt.NoDropShadowWindowHint
+ self.setWindowFlags(cast(QtCore.Qt.WindowFlags, window_flags))
if refresh_window:
self.show()
- @pyqtSlot(bool)
+ @QtCore.pyqtSlot(bool)
def _on_fullscreen_requested(self, on):
if not config.val.content.fullscreen.window:
if on:
self.state_before_fullscreen = self.windowState()
self.setWindowState(
- Qt.WindowFullScreen | # type: ignore[arg-type]
+ QtCore.Qt.WindowFullScreen | # type: ignore[arg-type]
self.state_before_fullscreen) # type: ignore[operator]
elif self.isFullScreen():
self.setWindowState(self.state_before_fullscreen)
log.misc.debug('on: {}, state before fullscreen: {}'.format(
- on, debug.qflags_key(Qt, self.state_before_fullscreen)))
+ on, debug.qflags_key(QtCore.Qt, self.state_before_fullscreen)))
@cmdutils.register(instance='main-window', scope='window')
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def close(self):
"""Close the current window.
diff --git a/qutebrowser/mainwindow/messageview.py b/qutebrowser/mainwindow/messageview.py
index 58fcb3683..4c6ca0ec2 100644
--- a/qutebrowser/mainwindow/messageview.py
+++ b/qutebrowser/mainwindow/messageview.py
@@ -21,14 +21,12 @@
from typing import MutableSequence, Optional
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, QTimer, Qt
-from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QSizePolicy
-
from qutebrowser.config import config, stylesheet
from qutebrowser.utils import usertypes
+from qutebrowser.qt import QtWidgets, QtCore
-class Message(QLabel):
+class Message(QtWidgets.QLabel):
"""A single error/warning/info message."""
@@ -37,12 +35,12 @@ class Message(QLabel):
level: usertypes.MessageLevel,
text: str,
replace: Optional[str],
- parent: QWidget = None,
+ parent: QtWidgets.QWidget = None,
) -> None:
super().__init__(text, parent)
self.replace = replace
self.level = level
- self.setAttribute(Qt.WA_StyledBackground, True)
+ self.setAttribute(QtCore.Qt.WA_StyledBackground, True)
self.setWordWrap(True)
qss = """
padding-top: 2px;
@@ -75,21 +73,21 @@ class Message(QLabel):
stylesheet.set_register(self, qss, update=False)
-class MessageView(QWidget):
+class MessageView(QtWidgets.QWidget):
"""Widget which stacks error/warning/info messages."""
- update_geometry = pyqtSignal()
+ update_geometry = QtCore.pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self._messages: MutableSequence[Message] = []
- self._vbox = QVBoxLayout(self)
+ self._vbox = QtWidgets.QVBoxLayout(self)
self._vbox.setContentsMargins(0, 0, 0, 0)
self._vbox.setSpacing(0)
- self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
+ self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
- self._clear_timer = QTimer()
+ self._clear_timer = QtCore.QTimer()
self._clear_timer.timeout.connect(self.clear_messages)
config.instance.changed.connect(self._set_clear_timer_interval)
@@ -109,7 +107,7 @@ class MessageView(QWidget):
widget.hide()
widget.deleteLater()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def clear_messages(self):
"""Hide and delete all messages."""
for widget in self._messages:
@@ -119,7 +117,7 @@ class MessageView(QWidget):
self.hide()
self._clear_timer.stop()
- @pyqtSlot(usertypes.MessageLevel, str, str)
+ @QtCore.pyqtSlot(usertypes.MessageLevel, str, str)
def show_message(
self,
level: usertypes.MessageLevel,
@@ -152,5 +150,5 @@ class MessageView(QWidget):
def mousePressEvent(self, e):
"""Clear messages when they are clicked on."""
- if e.button() in [Qt.LeftButton, Qt.MiddleButton, Qt.RightButton]:
+ if e.button() in [QtCore.Qt.LeftButton, QtCore.Qt.MiddleButton, QtCore.Qt.RightButton]:
self.clear_messages()
diff --git a/qutebrowser/mainwindow/prompt.py b/qutebrowser/mainwindow/prompt.py
index 6fea16093..a73076dfb 100644
--- a/qutebrowser/mainwindow/prompt.py
+++ b/qutebrowser/mainwindow/prompt.py
@@ -26,18 +26,13 @@ import functools
import dataclasses
from typing import Deque, MutableSequence, Optional, cast
-from PyQt5.QtCore import (pyqtSlot, pyqtSignal, Qt, QTimer, QDir, QModelIndex,
- QItemSelectionModel, QObject, QEventLoop)
-from PyQt5.QtWidgets import (QWidget, QGridLayout, QVBoxLayout, QLineEdit,
- QLabel, QFileSystemModel, QTreeView, QSizePolicy,
- QSpacerItem)
-
from qutebrowser.browser import downloads
from qutebrowser.config import config, configtypes, configexc, stylesheet
from qutebrowser.utils import usertypes, log, utils, qtutils, objreg, message
from qutebrowser.keyinput import modeman
from qutebrowser.api import cmdutils
from qutebrowser.utils import urlmatch
+from qutebrowser.qt import QtWidgets, QtCore
prompt_queue = cast('PromptQueue', None)
@@ -62,7 +57,7 @@ class UnsupportedOperationError(Error):
"""Raised when the prompt class doesn't support the requested operation."""
-class PromptQueue(QObject):
+class PromptQueue(QtCore.QObject):
"""Global manager and queue for upcoming prompts.
@@ -96,7 +91,7 @@ class PromptQueue(QObject):
shown.
"""
- show_prompts = pyqtSignal(usertypes.Question)
+ show_prompts = QtCore.pyqtSignal(usertypes.Question)
def __init__(self, parent=None):
super().__init__(parent)
@@ -112,7 +107,7 @@ class PromptQueue(QObject):
def _pop_later(self):
"""Helper to call self._pop as soon as everything else is done."""
- QTimer.singleShot(0, self._pop)
+ QtCore.QTimer.singleShot(0, self._pop)
def _pop(self):
"""Pop a question from the queue and ask it, if there are any."""
@@ -145,7 +140,7 @@ class PromptQueue(QObject):
else:
return False
- @pyqtSlot(usertypes.Question, bool)
+ @QtCore.pyqtSlot(usertypes.Question, bool)
def ask_question(self, question, blocking):
"""Display a prompt for a given question.
@@ -195,8 +190,8 @@ class PromptQueue(QObject):
question.completed.connect(loop.quit)
question.completed.connect(loop.deleteLater)
log.prompt.debug("Starting loop.exec() for {}".format(question))
- flags = cast(QEventLoop.ProcessEventsFlags,
- QEventLoop.ExcludeSocketNotifiers)
+ flags = cast(QtCore.QEventLoop.ProcessEventsFlags,
+ QtCore.QEventLoop.ExcludeSocketNotifiers)
loop.exec(flags)
log.prompt.debug("Ending loop.exec() for {}".format(question))
@@ -214,7 +209,7 @@ class PromptQueue(QObject):
question.completed.connect(self._pop_later)
return None
- @pyqtSlot(usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode)
def _on_mode_left(self, mode):
"""Abort question when a prompt mode was left."""
if mode not in [usertypes.KeyMode.prompt, usertypes.KeyMode.yesno]:
@@ -232,7 +227,7 @@ class PromptQueue(QObject):
self._question = None
-class PromptContainer(QWidget):
+class PromptContainer(QtWidgets.QWidget):
"""Container for prompts to be shown above the statusbar.
@@ -283,17 +278,17 @@ class PromptContainer(QWidget):
background-color: {{ conf.colors.prompts.selected.bg }};
}
"""
- update_geometry = pyqtSignal()
+ update_geometry = QtCore.pyqtSignal()
def __init__(self, win_id, parent=None):
super().__init__(parent)
- self._layout = QVBoxLayout(self)
+ self._layout = QtWidgets.QVBoxLayout(self)
self._layout.setContentsMargins(10, 10, 10, 10)
self._win_id = win_id
self._prompt: Optional[_BasePrompt] = None
self.setObjectName('PromptContainer')
- self.setAttribute(Qt.WA_StyledBackground, True)
+ self.setAttribute(QtCore.Qt.WA_StyledBackground, True)
stylesheet.set_register(self)
message.global_bridge.prompt_done.connect(self._on_prompt_done)
@@ -303,7 +298,7 @@ class PromptContainer(QWidget):
def __repr__(self):
return utils.get_repr(self, win_id=self._win_id)
- @pyqtSlot(usertypes.Question)
+ @QtCore.pyqtSlot(usertypes.Question)
def _on_show_prompts(self, question):
"""Show a prompt for the given question.
@@ -349,7 +344,7 @@ class PromptContainer(QWidget):
prompt.setFocus()
self.update_geometry.emit()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_aborted(self, key_mode):
"""Leave KEY_MODE whenever a prompt is aborted."""
try:
@@ -358,12 +353,12 @@ class PromptContainer(QWidget):
# window was deleted: ignore
pass
- @pyqtSlot(usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode)
def _on_prompt_done(self, key_mode):
"""Leave the prompt mode in this window if a question was answered."""
modeman.leave(self._win_id, key_mode, ':prompt-accept', maybe=True)
- @pyqtSlot(usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode)
def _on_global_mode_left(self, mode):
"""Leave prompt/yesno mode in this window if it was left elsewhere.
@@ -468,7 +463,7 @@ class PromptContainer(QWidget):
message.info("Yanked to {}: {}".format(target, question.url))
-class LineEdit(QLineEdit):
+class LineEdit(QtWidgets.QLineEdit):
"""A line edit used in prompts."""
@@ -479,11 +474,11 @@ class LineEdit(QLineEdit):
background-color: transparent;
}
""")
- self.setAttribute(Qt.WA_MacShowFocusRect, False)
+ self.setAttribute(QtCore.Qt.WA_MacShowFocusRect, False)
def keyPressEvent(self, e):
"""Override keyPressEvent to paste primary selection on Shift + Ins."""
- if e.key() == Qt.Key_Insert and e.modifiers() == Qt.ShiftModifier:
+ if e.key() == QtCore.Qt.Key_Insert and e.modifiers() == QtCore.Qt.ShiftModifier:
try:
text = utils.get_clipboard(selection=True, fallback=True)
except utils.ClipboardError: # pragma: no cover
@@ -498,7 +493,7 @@ class LineEdit(QLineEdit):
return utils.get_repr(self)
-class _BasePrompt(QWidget):
+class _BasePrompt(QtWidgets.QWidget):
"""Base class for all prompts."""
@@ -507,7 +502,7 @@ class _BasePrompt(QWidget):
def __init__(self, question, parent=None):
super().__init__(parent)
self.question = question
- self._vbox = QVBoxLayout(self)
+ self._vbox = QtWidgets.QVBoxLayout(self)
self._vbox.setSpacing(15)
self._key_grid = None
@@ -518,18 +513,18 @@ class _BasePrompt(QWidget):
assert question.title is not None, question
title = '<font size="4"><b>{}</b></font>'.format(
html.escape(question.title))
- title_label = QLabel(title, self)
+ title_label = QtWidgets.QLabel(title, self)
self._vbox.addWidget(title_label)
if question.text is not None:
# Not doing any HTML escaping here as the text can be formatted
- text_label = QLabel(question.text)
+ text_label = QtWidgets.QLabel(question.text)
text_label.setWordWrap(True)
- text_label.setTextInteractionFlags(Qt.TextSelectableByMouse)
+ text_label.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
self._vbox.addWidget(text_label)
def _init_key_label(self):
assert self._key_grid is None, self._key_grid
- self._key_grid = QGridLayout()
+ self._key_grid = QtWidgets.QGridLayout()
self._key_grid.setVerticalSpacing(0)
all_bindings = config.key_instance.get_reverse_bindings_for(
@@ -548,24 +543,24 @@ class _BasePrompt(QWidget):
binding = pref
if binding is None:
binding = bindings[0]
- key_label = QLabel('<b>{}</b>'.format(html.escape(binding)))
+ key_label = QtWidgets.QLabel('<b>{}</b>'.format(html.escape(binding)))
else:
- key_label = QLabel(f'<b>unbound</b> (<tt>{html.escape(cmd)}</tt>)')
+ key_label = QtWidgets.QLabel(f'<b>unbound</b> (<tt>{html.escape(cmd)}</tt>)')
- text_label = QLabel(text)
+ text_label = QtWidgets.QLabel(text)
labels.append((key_label, text_label))
for i, (key_label, text_label) in enumerate(labels):
self._key_grid.addWidget(key_label, i, 0)
self._key_grid.addWidget(text_label, i, 1)
- spacer = QSpacerItem(0, 0, QSizePolicy.Expanding)
+ spacer = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding)
self._key_grid.addItem(spacer, 0, 2)
self._vbox.addLayout(self._key_grid)
if not has_bindings:
- label = QLabel(
+ label = QtWidgets.QLabel(
"<b>Note:</b> You seem to have unbound all keys for this prompt "
f"(<tt>{self.KEY_MODE.name}</tt> key mode)."
"<br/>Run <tt>qutebrowser :CMD</tt> with a command from above to "
@@ -641,10 +636,10 @@ class FilenamePrompt(_BasePrompt):
self._set_fileview_root(question.default)
if config.val.prompt.filebrowser:
- self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
+ self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
self._to_complete = ''
- self._root_index = QModelIndex()
+ self._root_index = QtCore.QModelIndex()
def _directories_hide_show_model(self):
"""Get rid of non-matching directories."""
@@ -655,7 +650,7 @@ class FilenamePrompt(_BasePrompt):
hidden = self._to_complete not in filename and filename != '..'
self._file_view.setRowHidden(index.row(), index.parent(), hidden)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _set_fileview_root(self, path, *, tabbed=False):
"""Set the root path for the file display."""
separators = os.sep
@@ -691,7 +686,7 @@ class FilenamePrompt(_BasePrompt):
self._directories_hide_show_model()
- @pyqtSlot(QModelIndex)
+ @QtCore.pyqtSlot(QtCore.QModelIndex)
def _insert_path(self, index, *, clicked=True):
"""Handle an element selection.
@@ -699,7 +694,7 @@ class FilenamePrompt(_BasePrompt):
index: The QModelIndex of the selected element.
clicked: Whether the element was clicked.
"""
- if index == QModelIndex():
+ if index == QtCore.QModelIndex():
path = os.path.join(self._file_model.rootPath(), self._to_complete)
else:
path = os.path.normpath(self._file_model.filePath(index))
@@ -716,11 +711,11 @@ class FilenamePrompt(_BasePrompt):
self._set_fileview_root(path, tabbed=True)
if clicked:
# Avoid having a ..-subtree highlighted
- self._file_view.setCurrentIndex(QModelIndex())
+ self._file_view.setCurrentIndex(QtCore.QModelIndex())
def _init_fileview(self):
- self._file_view = QTreeView(self)
- self._file_model = QFileSystemModel(self)
+ self._file_view = QtWidgets.QTreeView(self)
+ self._file_model = QtWidgets.QFileSystemModel(self)
self._file_view.setModel(self._file_model)
self._file_view.clicked.connect(self._insert_path)
@@ -734,7 +729,7 @@ class FilenamePrompt(_BasePrompt):
for col in range(1, 4):
self._file_view.setColumnHidden(col, True)
# Nothing selected initially
- self._file_view.setCurrentIndex(QModelIndex())
+ self._file_view.setCurrentIndex(QtCore.QModelIndex())
# The model needs to be sorted so we get the correct first/last index
self._file_model.directoryLoaded.connect(
lambda: self._file_model.sort(0))
@@ -784,8 +779,8 @@ class FilenamePrompt(_BasePrompt):
selmodel.setCurrentIndex(
idx,
- QItemSelectionModel.ClearAndSelect | # type: ignore[arg-type]
- QItemSelectionModel.Rows)
+ QtCore.QItemSelectionModel.ClearAndSelect | # type: ignore[arg-type]
+ QtCore.QItemSelectionModel.Rows)
self._insert_path(idx, clicked=False)
def _do_completion(self, idx, which):
@@ -808,7 +803,7 @@ class DownloadFilenamePrompt(FilenamePrompt):
def __init__(self, question, parent=None):
super().__init__(question, parent)
self._file_model.setFilter(
- QDir.AllDirs | QDir.Drives | QDir.NoDotAndDotDot) # type: ignore[arg-type]
+ QtCore.QDir.AllDirs | QtCore.QDir.Drives | QtCore.QDir.NoDotAndDotDot) # type: ignore[arg-type]
def accept(self, value=None, save=False):
done = super().accept(value, save)
@@ -847,14 +842,14 @@ class AuthenticationPrompt(_BasePrompt):
super().__init__(question, parent)
self._init_texts(question)
- user_label = QLabel("Username:", self)
+ user_label = QtWidgets.QLabel("Username:", self)
self._user_lineedit = LineEdit(self)
- password_label = QLabel("Password:", self)
+ password_label = QtWidgets.QLabel("Password:", self)
self._password_lineedit = LineEdit(self)
- self._password_lineedit.setEchoMode(QLineEdit.Password)
+ self._password_lineedit.setEchoMode(QtWidgets.QLineEdit.Password)
- grid = QGridLayout()
+ grid = QtWidgets.QGridLayout()
grid.addWidget(user_label, 1, 0)
grid.addWidget(self._user_lineedit, 1, 1)
grid.addWidget(password_label, 2, 0)
@@ -987,4 +982,4 @@ def init():
global prompt_queue
prompt_queue = PromptQueue()
message.global_bridge.ask_question.connect( # type: ignore[call-arg]
- prompt_queue.ask_question, Qt.DirectConnection)
+ prompt_queue.ask_question, QtCore.Qt.DirectConnection)
diff --git a/qutebrowser/mainwindow/statusbar/bar.py b/qutebrowser/mainwindow/statusbar/bar.py
index 8bad290be..0a050a1b4 100644
--- a/qutebrowser/mainwindow/statusbar/bar.py
+++ b/qutebrowser/mainwindow/statusbar/bar.py
@@ -22,10 +22,6 @@
import enum
import dataclasses
-from PyQt5.QtCore import (pyqtSignal, pyqtSlot, # type: ignore[attr-defined]
- pyqtProperty, Qt, QSize, QTimer)
-from PyQt5.QtWidgets import QWidget, QHBoxLayout, QStackedLayout, QSizePolicy
-
from qutebrowser.browser import browsertab
from qutebrowser.config import config, stylesheet
from qutebrowser.keyinput import modeman
@@ -33,6 +29,7 @@ from qutebrowser.utils import usertypes, log, objreg, utils
from qutebrowser.mainwindow.statusbar import (backforward, command, progress,
keystring, percentage, url,
tabindex, textbase)
+from qutebrowser.qt import QtWidgets, QtCore
@dataclasses.dataclass
@@ -133,7 +130,7 @@ def _generate_stylesheet():
return qss
-class StatusBar(QWidget):
+class StatusBar(QtWidgets.QWidget):
"""The statusbar at the bottom of the mainwindow.
@@ -157,28 +154,28 @@ class StatusBar(QWidget):
arg: The new position.
"""
- resized = pyqtSignal('QRect')
- moved = pyqtSignal('QPoint')
+ resized = QtCore.pyqtSignal('QRect')
+ moved = QtCore.pyqtSignal('QPoint')
STYLESHEET = _generate_stylesheet()
def __init__(self, *, win_id, private, parent=None):
super().__init__(parent)
self.setObjectName(self.__class__.__name__)
- self.setAttribute(Qt.WA_StyledBackground)
+ self.setAttribute(QtCore.Qt.WA_StyledBackground)
stylesheet.set_register(self)
- self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Fixed)
+ self.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.Fixed)
self._win_id = win_id
self._color_flags = ColorFlags()
self._color_flags.private = private
- self._hbox = QHBoxLayout(self)
+ self._hbox = QtWidgets.QHBoxLayout(self)
self._set_hbox_padding()
self._hbox.setSpacing(5)
- self._stack = QStackedLayout()
+ self._stack = QtWidgets.QStackedLayout()
self._hbox.addLayout(self._stack)
self._stack.setContentsMargins(0, 0, 0, 0)
@@ -204,12 +201,12 @@ class StatusBar(QWidget):
self._draw_widgets()
config.instance.changed.connect(self._on_config_changed)
- QTimer.singleShot(0, self.maybe_hide)
+ QtCore.QTimer.singleShot(0, self.maybe_hide)
def __repr__(self):
return utils.get_repr(self)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _on_config_changed(self, option):
if option == 'statusbar.show':
self.maybe_hide()
@@ -267,12 +264,12 @@ class StatusBar(QWidget):
for widget in [self.url, self.percentage,
self.backforward, self.tabindex,
self.keystring, self.prog, *self._text_widgets]:
- assert isinstance(widget, QWidget)
+ assert isinstance(widget, QtWidgets.QWidget)
widget.hide()
self._hbox.removeWidget(widget)
self._text_widgets.clear()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def maybe_hide(self):
"""Hide the statusbar if it's configured to do so."""
strategy = config.val.statusbar.show
@@ -300,7 +297,7 @@ class StatusBar(QWidget):
padding = config.val.statusbar.padding
self._hbox.setContentsMargins(padding.left, 0, padding.right, 0)
- @pyqtProperty('QStringList')
+ @QtCore.pyqtProperty('QStringList')
def color_flags(self):
"""Getter for self.color_flags, so it can be used as Qt property."""
return self._color_flags.to_stringlist()
@@ -362,13 +359,13 @@ class StatusBar(QWidget):
self._stack.setCurrentWidget(self.txt)
self.maybe_hide()
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def set_text(self, text):
"""Set a normal (persistent) text in the status bar."""
log.message.debug(text)
self.txt.setText(text)
- @pyqtSlot(usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode)
def on_mode_entered(self, mode):
"""Mark certain modes in the commandline."""
mode_manager = modeman.instance(self._win_id)
@@ -384,7 +381,7 @@ class StatusBar(QWidget):
usertypes.KeyMode.passthrough]:
self.set_mode_active(mode, True)
- @pyqtSlot(usertypes.KeyMode, usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode, usertypes.KeyMode)
def on_mode_left(self, old_mode, new_mode):
"""Clear marked mode."""
mode_manager = modeman.instance(self._win_id)
@@ -403,7 +400,7 @@ class StatusBar(QWidget):
usertypes.KeyMode.passthrough]:
self.set_mode_active(old_mode, False)
- @pyqtSlot(browsertab.AbstractTab)
+ @QtCore.pyqtSlot(browsertab.AbstractTab)
def on_tab_changed(self, tab):
"""Notify sub-widgets when the tab has been changed."""
self.url.on_tab_changed(tab)
@@ -413,7 +410,7 @@ class StatusBar(QWidget):
self.maybe_hide()
assert tab.is_private == self._color_flags.private
- @pyqtSlot(browsertab.SelectionState)
+ @QtCore.pyqtSlot(browsertab.SelectionState)
def on_caret_selection_toggled(self, selection_state):
"""Update the statusbar when entering/leaving caret selection mode."""
log.statusbar.debug("Setting caret selection {}"
@@ -452,4 +449,4 @@ class StatusBar(QWidget):
padding = config.cache['statusbar.padding']
width = super().minimumSizeHint().width()
height = self.fontMetrics().height() + padding.top + padding.bottom
- return QSize(width, height)
+ return QtCore.QSize(width, height)
diff --git a/qutebrowser/mainwindow/statusbar/command.py b/qutebrowser/mainwindow/statusbar/command.py
index 199f0a103..34400337d 100644
--- a/qutebrowser/mainwindow/statusbar/command.py
+++ b/qutebrowser/mainwindow/statusbar/command.py
@@ -18,11 +18,7 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
"""The commandline in the statusbar."""
-
-
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt, QSize
-from PyQt5.QtGui import QKeyEvent
-from PyQt5.QtWidgets import QSizePolicy, QWidget
+from qutebrowser.qt import QtWidgets, QtGui
from qutebrowser.keyinput import modeman, modeparsers
from qutebrowser.api import cmdutils
@@ -30,6 +26,7 @@ from qutebrowser.misc import cmdhistory, editor
from qutebrowser.misc import miscwidgets as misc
from qutebrowser.utils import usertypes, log, objreg, message, utils
from qutebrowser.config import config
+from qutebrowser.qt import QtCore
class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
@@ -51,17 +48,17 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
hide_cmd: Emitted when command input can be hidden.
"""
- got_cmd = pyqtSignal([str], [str, int])
- got_search = pyqtSignal(str, bool) # text, reverse
- clear_completion_selection = pyqtSignal()
- hide_completion = pyqtSignal()
- update_completion = pyqtSignal()
- show_cmd = pyqtSignal()
- hide_cmd = pyqtSignal()
+ got_cmd = QtCore.pyqtSignal([str], [str, int])
+ got_search = QtCore.pyqtSignal(str, bool) # text, reverse
+ clear_completion_selection = QtCore.pyqtSignal()
+ hide_completion = QtCore.pyqtSignal()
+ update_completion = QtCore.pyqtSignal()
+ show_cmd = QtCore.pyqtSignal()
+ hide_cmd = QtCore.pyqtSignal()
def __init__(self, *, win_id: int,
private: bool,
- parent: QWidget = None) -> None:
+ parent: QtWidgets.QWidget = None) -> None:
misc.CommandLineEdit.__init__(self, parent=parent)
misc.MinimalLineEditMixin.__init__(self)
self._win_id = win_id
@@ -69,7 +66,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
command_history = objreg.get('command-history')
self.history.history = command_history.data
self.history.changed.connect(command_history.changed)
- self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Ignored)
+ self.setSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Ignored)
self.cursorPositionChanged.connect(self.update_completion)
self.textChanged.connect(self.update_completion)
@@ -222,7 +219,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
ed.file_updated.connect(callback)
ed.edit(self.text())
- @pyqtSlot(usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode)
def on_mode_left(self, mode: usertypes.KeyMode) -> None:
"""Clear up when command mode was left.
@@ -251,7 +248,7 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
"'{}'!".format(text))
super().setText(text)
- def keyPressEvent(self, e: QKeyEvent) -> None:
+ def keyPressEvent(self, e: QtGui.QKeyEvent) -> None:
"""Override keyPressEvent to ignore Return key presses.
If this widget is focused, we are in passthrough key mode, and
@@ -259,27 +256,27 @@ class Command(misc.MinimalLineEditMixin, misc.CommandLineEdit):
without command_accept to be called.
"""
text = self.text()
- if text in modeparsers.STARTCHARS and e.key() == Qt.Key_Backspace:
+ if text in modeparsers.STARTCHARS and e.key() == QtCore.Qt.Key_Backspace:
e.accept()
modeman.leave(self._win_id, usertypes.KeyMode.command,
'prefix deleted')
return
- if e.key() == Qt.Key_Return:
+ if e.key() == QtCore.Qt.Key_Return:
e.ignore()
return
else:
super().keyPressEvent(e)
- def sizeHint(self) -> QSize:
+ def sizeHint(self) -> QtCore.QSize:
"""Dynamically calculate the needed size."""
height = super().sizeHint().height()
text = self.text()
if not text:
text = 'x'
width = self.fontMetrics().boundingRect(text).width()
- return QSize(width, height)
+ return QtCore.QSize(width, height)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _incremental_search(self) -> None:
if not config.val.search.incremental:
return
diff --git a/qutebrowser/mainwindow/statusbar/keystring.py b/qutebrowser/mainwindow/statusbar/keystring.py
index 590dbda93..472d6d5bc 100644
--- a/qutebrowser/mainwindow/statusbar/keystring.py
+++ b/qutebrowser/mainwindow/statusbar/keystring.py
@@ -19,7 +19,7 @@
"""Keychain string displayed in the statusbar."""
-from PyQt5.QtCore import pyqtSlot
+from qutebrowser.qt import QtCore
from qutebrowser.mainwindow.statusbar import textbase
from qutebrowser.utils import usertypes
@@ -29,6 +29,6 @@ class KeyString(textbase.TextBase):
"""Keychain string displayed in the statusbar."""
- @pyqtSlot(usertypes.KeyMode, str)
+ @QtCore.pyqtSlot(usertypes.KeyMode, str)
def on_keystring_updated(self, _mode, keystr):
self.setText(keystr)
diff --git a/qutebrowser/mainwindow/statusbar/percentage.py b/qutebrowser/mainwindow/statusbar/percentage.py
index 122a4d4b4..7c42330dc 100644
--- a/qutebrowser/mainwindow/statusbar/percentage.py
+++ b/qutebrowser/mainwindow/statusbar/percentage.py
@@ -19,11 +19,10 @@
"""Scroll percentage displayed in the statusbar."""
-from PyQt5.QtCore import pyqtSlot, Qt
-
from qutebrowser.mainwindow.statusbar import textbase
from qutebrowser.misc import throttle
from qutebrowser.utils import utils
+from qutebrowser.qt import QtCore
class Percentage(textbase.TextBase):
@@ -32,7 +31,7 @@ class Percentage(textbase.TextBase):
def __init__(self, parent=None):
"""Constructor. Set percentage to 0%."""
- super().__init__(parent, elidemode=Qt.ElideNone)
+ super().__init__(parent, elidemode=QtCore.Qt.ElideNone)
self._strings = self._calc_strings()
self._set_text = throttle.Throttle(self.setText, 100, parent=self)
self.set_perc(0, 0)
@@ -47,7 +46,7 @@ class Percentage(textbase.TextBase):
strings.update({0: '[top]', 100: '[bot]'})
return strings
- @pyqtSlot(int, int)
+ @QtCore.pyqtSlot(int, int)
def set_perc(self, x, y):
"""Setter to be used as a Qt slot.
diff --git a/qutebrowser/mainwindow/statusbar/progress.py b/qutebrowser/mainwindow/statusbar/progress.py
index 9d56cd03f..d8c327798 100644
--- a/qutebrowser/mainwindow/statusbar/progress.py
+++ b/qutebrowser/mainwindow/statusbar/progress.py
@@ -19,14 +19,12 @@
"""The progress bar in the statusbar."""
-from PyQt5.QtCore import pyqtSlot, QSize
-from PyQt5.QtWidgets import QProgressBar, QSizePolicy
-
from qutebrowser.config import stylesheet
from qutebrowser.utils import utils, usertypes
+from qutebrowser.qt import QtWidgets, QtCore
-class Progress(QProgressBar):
+class Progress(QtWidgets.QProgressBar):
"""The progress bar part of the status bar."""
@@ -47,20 +45,20 @@ class Progress(QProgressBar):
super().__init__(parent)
stylesheet.set_register(self)
self.enabled = False
- self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+ self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self.setTextVisible(False)
self.hide()
def __repr__(self):
return utils.get_repr(self, value=self.value())
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_load_started(self):
"""Clear old error and show progress, used as slot to loadStarted."""
self.setValue(0)
self.setVisible(self.enabled)
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def on_load_progress(self, value):
"""Hide the statusbar when loading finished.
@@ -85,7 +83,7 @@ class Progress(QProgressBar):
"""Set the height to the text height."""
width = super().sizeHint().width()
height = self.fontMetrics().height()
- return QSize(width, height)
+ return QtCore.QSize(width, height)
def minimumSizeHint(self):
return self.sizeHint()
diff --git a/qutebrowser/mainwindow/statusbar/tabindex.py b/qutebrowser/mainwindow/statusbar/tabindex.py
index 635d3817b..664870215 100644
--- a/qutebrowser/mainwindow/statusbar/tabindex.py
+++ b/qutebrowser/mainwindow/statusbar/tabindex.py
@@ -19,7 +19,7 @@
"""TabIndex displayed in the statusbar."""
-from PyQt5.QtCore import pyqtSlot
+from qutebrowser.qt import QtCore
from qutebrowser.mainwindow.statusbar import textbase
@@ -28,7 +28,7 @@ class TabIndex(textbase.TextBase):
"""Shows current tab index and number of tabs in the statusbar."""
- @pyqtSlot(int, int)
+ @QtCore.pyqtSlot(int, int)
def on_tab_index_changed(self, current, count):
"""Update tab index when tab changed."""
self.setText('[{}/{}]'.format(current + 1, count))
diff --git a/qutebrowser/mainwindow/statusbar/textbase.py b/qutebrowser/mainwindow/statusbar/textbase.py
index cb454b902..76d91f4c8 100644
--- a/qutebrowser/mainwindow/statusbar/textbase.py
+++ b/qutebrowser/mainwindow/statusbar/textbase.py
@@ -19,14 +19,12 @@
"""Base text widgets for statusbar."""
-from PyQt5.QtCore import Qt
-from PyQt5.QtWidgets import QLabel, QSizePolicy
-from PyQt5.QtGui import QPainter
+from qutebrowser.qt import QtWidgets, QtGui, QtCore
from qutebrowser.utils import qtutils, utils
-class TextBase(QLabel):
+class TextBase(QtWidgets.QLabel):
"""A text in the statusbar.
@@ -40,9 +38,9 @@ class TextBase(QLabel):
_elided_text: The current elided text.
"""
- def __init__(self, parent=None, elidemode=Qt.ElideRight):
+ def __init__(self, parent=None, elidemode=QtCore.Qt.ElideRight):
super().__init__(parent)
- self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)
+ self.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum)
self._elidemode = elidemode
self._elided_text = ''
@@ -57,7 +55,7 @@ class TextBase(QLabel):
"""
if self.text():
self._elided_text = self.fontMetrics().elidedText(
- self.text(), self._elidemode, width, Qt.TextShowMnemonic)
+ self.text(), self._elidemode, width, QtCore.Qt.TextShowMnemonic)
else:
self._elided_text = ''
@@ -68,7 +66,7 @@ class TextBase(QLabel):
txt: The text to set (string).
"""
super().setText(txt)
- if self._elidemode != Qt.ElideNone:
+ if self._elidemode != QtCore.Qt.ElideNone:
self._update_elided_text(self.geometry().width())
def resizeEvent(self, e):
@@ -80,11 +78,11 @@ class TextBase(QLabel):
def paintEvent(self, e):
"""Override QLabel::paintEvent to draw elided text."""
- if self._elidemode == Qt.ElideNone:
+ if self._elidemode == QtCore.Qt.ElideNone:
super().paintEvent(e)
else:
e.accept()
- painter = QPainter(self)
+ painter = QtGui.QPainter(self)
geom = self.geometry()
qtutils.ensure_valid(geom)
painter.drawText(0, 0, geom.width(), geom.height(),
diff --git a/qutebrowser/mainwindow/statusbar/url.py b/qutebrowser/mainwindow/statusbar/url.py
index 99818e284..5eec66f72 100644
--- a/qutebrowser/mainwindow/statusbar/url.py
+++ b/qutebrowser/mainwindow/statusbar/url.py
@@ -21,12 +21,10 @@
import enum
-from PyQt5.QtCore import (pyqtSlot, pyqtProperty, # type: ignore[attr-defined]
- QUrl)
-
from qutebrowser.mainwindow.statusbar import textbase
from qutebrowser.config import stylesheet
from qutebrowser.utils import usertypes, urlutils
+from qutebrowser.qt import QtCore
class UrlType(enum.Enum):
@@ -92,7 +90,7 @@ class UrlText(textbase.TextBase):
self._normal_url = None
self._normal_url_type = UrlType.normal
- @pyqtProperty(str)
+ @QtCore.pyqtProperty(str)
def urltype(self):
"""Getter for self.urltype, so it can be used as Qt property.
@@ -121,7 +119,7 @@ class UrlText(textbase.TextBase):
# always override the old one.
self.style().polish(self)
- @pyqtSlot(usertypes.LoadStatus)
+ @QtCore.pyqtSlot(usertypes.LoadStatus)
def on_load_status_changed(self, status):
"""Slot for load_status_changed. Sets URL color accordingly.
@@ -138,7 +136,7 @@ class UrlText(textbase.TextBase):
self._normal_url_type = UrlType.normal
self._update_url()
- @pyqtSlot(QUrl)
+ @QtCore.pyqtSlot(QtCore.QUrl)
def set_url(self, url):
"""Setter to be used as a Qt slot.
@@ -154,7 +152,7 @@ class UrlText(textbase.TextBase):
self._normal_url_type = UrlType.normal
self._update_url()
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def set_hover_url(self, link):
"""Setter to be used as a Qt slot.
@@ -165,7 +163,7 @@ class UrlText(textbase.TextBase):
link: The link which was hovered (string)
"""
if link:
- qurl = QUrl(link)
+ qurl = QtCore.QUrl(link)
if qurl.isValid():
self._hover_url = urlutils.safe_display_string(qurl)
else:
diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py
index a96f6d583..830f98120 100644
--- a/qutebrowser/mainwindow/tabbedbrowser.py
+++ b/qutebrowser/mainwindow/tabbedbrowser.py
@@ -27,9 +27,6 @@ import dataclasses
from typing import (
Any, Deque, List, Mapping, MutableMapping, MutableSequence, Optional, Tuple)
-from PyQt5.QtWidgets import QSizePolicy, QWidget, QApplication
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QTimer, QUrl
-
from qutebrowser.config import config
from qutebrowser.keyinput import modeman
from qutebrowser.mainwindow import tabwidget, mainwindow
@@ -37,6 +34,7 @@ from qutebrowser.browser import signalfilter, browsertab, history
from qutebrowser.utils import (log, usertypes, utils, qtutils, objreg,
urlutils, message, jinja, version)
from qutebrowser.misc import quitter
+from qutebrowser.qt import QtWidgets, QtCore
@dataclasses.dataclass
@@ -44,7 +42,7 @@ class _UndoEntry:
"""Information needed for :undo."""
- url: QUrl
+ url: QtCore.QUrl
history: bytes
index: int
pinned: bool
@@ -73,14 +71,14 @@ class TabDeque:
size = config.val.tabs.focus_stack_size
if size < 0:
size = None
- self._stack: Deque[weakref.ReferenceType[QWidget]] = collections.deque(
+ self._stack: Deque[weakref.ReferenceType[QtWidgets.QWidget]] = collections.deque(
maxlen=size)
# Items that have been removed from the primary stack.
- self._stack_deleted: List[weakref.ReferenceType[QWidget]] = []
+ self._stack_deleted: List[weakref.ReferenceType[QtWidgets.QWidget]] = []
self._ignore_next = False
self._keep_deleted_next = False
- def on_switch(self, old_tab: QWidget) -> None:
+ def on_switch(self, old_tab: QtWidgets.QWidget) -> None:
"""Record tab switch events."""
if self._ignore_next:
self._ignore_next = False
@@ -92,24 +90,24 @@ class TabDeque:
self._keep_deleted_next = False
self._stack.append(tab)
- def prev(self, cur_tab: QWidget) -> QWidget:
+ def prev(self, cur_tab: QtWidgets.QWidget) -> QtWidgets.QWidget:
"""Get the 'previous' tab in the stack.
Throws IndexError on failure.
"""
- tab: Optional[QWidget] = None
+ tab: Optional[QtWidgets.QWidget] = None
while tab is None or tab.pending_removal or tab is cur_tab:
tab = self._stack.pop()()
self._stack_deleted.append(weakref.ref(cur_tab))
self._ignore_next = True
return tab
- def next(self, cur_tab: QWidget, *, keep_overflow: bool = True) -> QWidget:
+ def next(self, cur_tab: QtWidgets.QWidget, *, keep_overflow: bool = True) -> QtWidgets.QWidget:
"""Get the 'next' tab in the stack.
Throws IndexError on failure.
"""
- tab: Optional[QWidget] = None
+ tab: Optional[QtWidgets.QWidget] = None
while tab is None or tab.pending_removal or tab is cur_tab:
tab = self._stack_deleted.pop()()
# On next tab-switch, current tab will be added to stack as normal.
@@ -118,7 +116,7 @@ class TabDeque:
self._keep_deleted_next = True
return tab
- def last(self, cur_tab: QWidget) -> QWidget:
+ def last(self, cur_tab: QtWidgets.QWidget) -> QtWidgets.QWidget:
"""Get the last tab.
Throws IndexError on failure.
@@ -142,7 +140,7 @@ class TabDeletedError(Exception):
"""Exception raised when _tab_index is called for a deleted tab."""
-class TabbedBrowser(QWidget):
+class TabbedBrowser(QtWidgets.QWidget):
"""A TabWidget with QWebViews inside.
@@ -189,20 +187,20 @@ class TabbedBrowser(QWidget):
shutting_down: This TabbedBrowser will be deleted soon.
"""
- cur_progress = pyqtSignal(int)
- cur_load_started = pyqtSignal()
- cur_load_finished = pyqtSignal(bool)
- cur_url_changed = pyqtSignal(QUrl)
- cur_link_hovered = pyqtSignal(str)
- cur_scroll_perc_changed = pyqtSignal(int, int)
- cur_load_status_changed = pyqtSignal(usertypes.LoadStatus)
- cur_fullscreen_requested = pyqtSignal(bool)
- cur_caret_selection_toggled = pyqtSignal(browsertab.SelectionState)
- close_window = pyqtSignal()
- resized = pyqtSignal('QRect')
- current_tab_changed = pyqtSignal(browsertab.AbstractTab)
- new_tab = pyqtSignal(browsertab.AbstractTab, int)
- shutting_down = pyqtSignal()
+ cur_progress = QtCore.pyqtSignal(int)
+ cur_load_started = QtCore.pyqtSignal()
+ cur_load_finished = QtCore.pyqtSignal(bool)
+ cur_url_changed = QtCore.pyqtSignal(QtCore.QUrl)
+ cur_link_hovered = QtCore.pyqtSignal(str)
+ cur_scroll_perc_changed = QtCore.pyqtSignal(int, int)
+ cur_load_status_changed = QtCore.pyqtSignal(usertypes.LoadStatus)
+ cur_fullscreen_requested = QtCore.pyqtSignal(bool)
+ cur_caret_selection_toggled = QtCore.pyqtSignal(browsertab.SelectionState)
+ close_window = QtCore.pyqtSignal()
+ resized = QtCore.pyqtSignal('QRect')
+ current_tab_changed = QtCore.pyqtSignal(browsertab.AbstractTab)
+ new_tab = QtCore.pyqtSignal(browsertab.AbstractTab, int)
+ shutting_down = QtCore.pyqtSignal()
def __init__(self, *, win_id, private, parent=None):
if private:
@@ -217,7 +215,7 @@ class TabbedBrowser(QWidget):
self.widget.new_tab_requested.connect(self.tabopen)
self.widget.currentChanged.connect(self._on_current_changed)
self.cur_fullscreen_requested.connect(self.widget.tabBar().maybe_hide)
- self.widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
+ self.widget.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
# load_finished instead of load_started as WORKAROUND for
# https://bugreports.qt.io/browse/QTBUG-65223
@@ -235,8 +233,8 @@ class TabbedBrowser(QWidget):
self._now_focused = None
self.search_text = None
self.search_options: Mapping[str, Any] = {}
- self._local_marks: MutableMapping[QUrl, MutableMapping[str, int]] = {}
- self._global_marks: MutableMapping[str, Tuple[int, QUrl]] = {}
+ self._local_marks: MutableMapping[QtCore.QUrl, MutableMapping[str, int]] = {}
+ self._global_marks: MutableMapping[str, Tuple[int, QtCore.QUrl]] = {}
self.default_window_icon = self.widget.window().windowIcon()
self.is_private = private
self.tab_deque = TabDeque()
@@ -253,7 +251,7 @@ class TabbedBrowser(QWidget):
def __repr__(self):
return utils.get_repr(self, count=self.widget.count())
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _on_config_changed(self, option):
if option == 'tabs.favicons.show':
self._update_favicons()
@@ -435,7 +433,7 @@ class TabbedBrowser(QWidget):
if last_close == 'close':
self.close_window.emit()
elif last_close == 'blank':
- self.load_url(QUrl('about:blank'), newtab=True)
+ self.load_url(QtCore.QUrl('about:blank'), newtab=True)
elif last_close == 'startpage':
for url in config.val.url.start_pages:
self.load_url(url, newtab=True)
@@ -505,7 +503,7 @@ class TabbedBrowser(QWidget):
if only_one_tab_open and last_close_replaces:
no_history = len(self.widget.widget(0).history) == 1
urls = {
- 'blank': QUrl('about:blank'),
+ 'blank': QtCore.QUrl('about:blank'),
'startpage': config.val.url.start_pages[0],
'default-page': config.val.url.default_page,
}
@@ -528,7 +526,7 @@ class TabbedBrowser(QWidget):
newtab.history.private_api.deserialize(entry.history)
newtab.set_pinned(entry.pinned)
- @pyqtSlot('QUrl', bool)
+ @QtCore.pyqtSlot('QUrl', bool)
def load_url(self, url, newtab):
"""Open a URL, used as a slot.
@@ -542,7 +540,7 @@ class TabbedBrowser(QWidget):
else:
self.widget.currentWidget().load_url(url)
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def on_tab_close_requested(self, idx):
"""Close a tab via an index."""
tab = self.widget.widget(idx)
@@ -553,7 +551,7 @@ class TabbedBrowser(QWidget):
self.tab_close_prompt_if_pinned(
tab, False, lambda: self.close_tab(tab))
- @pyqtSlot(browsertab.AbstractTab)
+ @QtCore.pyqtSlot(browsertab.AbstractTab)
def _on_window_close_requested(self, widget):
"""Close a tab with a widget given."""
try:
@@ -562,11 +560,11 @@ class TabbedBrowser(QWidget):
log.webview.debug("Requested to close {!r} which does not "
"exist!".format(widget))
- @pyqtSlot('QUrl')
- @pyqtSlot('QUrl', bool)
- @pyqtSlot('QUrl', bool, bool)
+ @QtCore.pyqtSlot('QUrl')
+ @QtCore.pyqtSlot('QUrl', bool)
+ @QtCore.pyqtSlot('QUrl', bool, bool)
def tabopen(
- self, url: QUrl = None,
+ self, url: QtCore.QUrl = None,
background: bool = None,
related: bool = True,
idx: int = None,
@@ -598,7 +596,7 @@ class TabbedBrowser(QWidget):
"related {}, idx {}".format(
url, background, related, idx))
- prev_focus = QApplication.focusWidget()
+ prev_focus = QtWidgets.QApplication.focusWidget()
if config.val.tabs.tabs_are_windows and self.widget.count() > 0:
window = mainwindow.MainWindow(private=self.is_private)
@@ -692,7 +690,7 @@ class TabbedBrowser(QWidget):
for tab in self.widgets():
self.widget.update_tab_favicon(tab)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_load_started(self, tab):
"""Clear icon and update title when a tab started loading.
@@ -705,7 +703,7 @@ class TabbedBrowser(QWidget):
tab.data.should_show_icon()):
self.widget.window().setWindowIcon(self.default_window_icon)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_load_status_changed(self, tab):
"""Update tab/window titles if the load status changed."""
try:
@@ -718,7 +716,7 @@ class TabbedBrowser(QWidget):
if idx == self.widget.currentIndex():
self._update_window_title()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _leave_modes_on_load(self):
"""Leave insert/hint mode when loading started."""
try:
@@ -739,7 +737,7 @@ class TabbedBrowser(QWidget):
else:
log.modes.debug("Ignoring leave_on_load request due to setting.")
- @pyqtSlot(browsertab.AbstractTab, str)
+ @QtCore.pyqtSlot(browsertab.AbstractTab, str)
def _on_title_changed(self, tab, text):
"""Set the title of a tab.
@@ -763,7 +761,7 @@ class TabbedBrowser(QWidget):
if idx == self.widget.currentIndex():
self._update_window_title()
- @pyqtSlot(browsertab.AbstractTab, QUrl)
+ @QtCore.pyqtSlot(browsertab.AbstractTab, QtCore.QUrl)
def _on_url_changed(self, tab, url):
"""Set the new URL as title if there's no title yet.
@@ -780,7 +778,7 @@ class TabbedBrowser(QWidget):
if not self.widget.page_title(idx):
self.widget.set_page_title(idx, url.toDisplayString())
- def _mode_override(self, url: QUrl) -> None:
+ def _mode_override(self, url: QtCore.QUrl) -> None:
"""Override mode if url matches pattern.
Args:
@@ -797,7 +795,7 @@ class TabbedBrowser(QWidget):
reason='mode_override',
)
- @pyqtSlot(browsertab.AbstractTab)
+ @QtCore.pyqtSlot(browsertab.AbstractTab)
def _on_icon_changed(self, tab):
"""Set the icon of a tab.
@@ -813,7 +811,7 @@ class TabbedBrowser(QWidget):
return
self.widget.update_tab_favicon(tab)
- @pyqtSlot(usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode)
def on_mode_entered(self, mode):
"""Save input mode when tabs.mode_on_change = restore."""
if (config.val.tabs.mode_on_change == 'restore' and
@@ -822,7 +820,7 @@ class TabbedBrowser(QWidget):
if tab is not None:
tab.data.input_mode = mode
- @pyqtSlot(usertypes.KeyMode)
+ @QtCore.pyqtSlot(usertypes.KeyMode)
def on_mode_left(self, mode):
"""Give focus to current tab if command mode was left."""
widget = self.widget.currentWidget()
@@ -835,7 +833,7 @@ class TabbedBrowser(QWidget):
if config.val.tabs.mode_on_change == 'restore':
widget.data.input_mode = usertypes.KeyMode.normal
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def _on_current_changed(self, idx):
"""Add prev tab to stack and leave hinting mode when focus changed."""
mode_on_change = config.val.tabs.mode_on_change
@@ -871,11 +869,11 @@ class TabbedBrowser(QWidget):
.format(current_mode.name, mode_on_change))
self._now_focused = tab
self.current_tab_changed.emit(tab)
- QTimer.singleShot(0, self._update_window_title)
+ QtCore.QTimer.singleShot(0, self._update_window_title)
self._tab_insert_idx_left = self.widget.currentIndex()
self._tab_insert_idx_right = self.widget.currentIndex() + 1
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_cmd_return_pressed(self):
"""Set focus when the commandline closes."""
log.modes.debug("Commandline closed, focusing {!r}".format(self))
@@ -914,7 +912,7 @@ class TabbedBrowser(QWidget):
if idx == self.widget.currentIndex():
tab.private_api.handle_auto_insert_mode(ok)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_scroll_pos_changed(self):
"""Update tab and window title when scroll position changed."""
idx = self.widget.currentIndex()
@@ -986,7 +984,7 @@ class TabbedBrowser(QWidget):
error_page = jinja.render(
'error.html', title="Error loading {}".format(url_string),
url=url_string, error=msg)
- QTimer.singleShot(100, lambda: show_error_page(error_page))
+ QtCore.QTimer.singleShot(100, lambda: show_error_page(error_page))
def resizeEvent(self, e):
"""Extend resizeEvent of QWidget to emit a resized signal afterwards.
@@ -1016,7 +1014,7 @@ class TabbedBrowser(QWidget):
"""
# strip the fragment as it may interfere with scrolling
try:
- url = self.current_url().adjusted(QUrl.RemoveFragment)
+ url = self.current_url().adjusted(QtCore.QUrl.RemoveFragment)
except qtutils.QtValueError:
# show an error only if the mark is not automatically set
if key != "'":
@@ -1039,7 +1037,7 @@ class TabbedBrowser(QWidget):
"""
try:
# consider urls that differ only in fragment to be identical
- urlkey = self.current_url().adjusted(QUrl.RemoveFragment)
+ urlkey = self.current_url().adjusted(QtCore.QUrl.RemoveFragment)
except qtutils.QtValueError:
urlkey = None
diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py
index 511c2c309..c41e7e44c 100644
--- a/qutebrowser/mainwindow/tabwidget.py
+++ b/qutebrowser/mainwindow/tabwidget.py
@@ -24,20 +24,14 @@ import contextlib
import dataclasses
from typing import Optional, cast
-from PyQt5.QtCore import (pyqtSignal, pyqtSlot, Qt, QSize, QRect, QPoint,
- QTimer, QUrl)
-from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle,
- QStyle, QStylePainter, QStyleOptionTab,
- QStyleFactory, QWidget)
-from PyQt5.QtGui import QIcon, QPalette, QColor
-
from qutebrowser.utils import qtutils, objreg, utils, usertypes, log
from qutebrowser.config import config, stylesheet
from qutebrowser.misc import objects, debugcachestats
from qutebrowser.browser import browsertab
+from qutebrowser.qt import QtWidgets, QtGui, QtCore
-class TabWidget(QTabWidget):
+class TabWidget(QtWidgets.QTabWidget):
"""The tab widget used for TabbedBrowser.
@@ -48,8 +42,8 @@ class TabWidget(QTabWidget):
new_tab_requested: Emitted when a new tab is requested.
"""
- tab_index_changed = pyqtSignal(int, int)
- new_tab_requested = pyqtSignal('QUrl', bool, bool)
+ tab_index_changed = QtCore.pyqtSignal(int, int)
+ new_tab_requested = QtCore.pyqtSignal('QUrl', bool, bool)
# Strings for controlling the mute/audible text
MUTE_STRING = '[M] '
@@ -62,12 +56,12 @@ class TabWidget(QTabWidget):
self.setTabBar(bar)
bar.tabCloseRequested.connect(self.tabCloseRequested)
bar.tabMoved.connect(functools.partial(
- QTimer.singleShot, 0, self.update_tab_titles))
+ QtCore.QTimer.singleShot, 0, self.update_tab_titles))
bar.currentChanged.connect(self._on_current_changed)
bar.new_tab_requested.connect(self._on_new_tab_requested)
- self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
+ self.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
self.setDocumentMode(True)
- self.setElideMode(Qt.ElideRight)
+ self.setElideMode(QtCore.Qt.ElideRight)
self.setUsesScrollButtons(True)
bar.setDrawBase(False)
self._init_config()
@@ -83,7 +77,7 @@ class TabWidget(QTabWidget):
selection_behavior = config.val.tabs.select_on_remove
self.setTabPosition(position)
tabbar.vertical = position in [ # type: ignore[attr-defined]
- QTabWidget.West, QTabWidget.East]
+ QtWidgets.QTabWidget.West, QtWidgets.QTabWidget.East]
tabbar.setSelectionBehaviorOnRemove(selection_behavior)
tabbar.refresh()
@@ -314,14 +308,14 @@ class TabWidget(QTabWidget):
self.set_page_title(new_idx, text)
return new_idx
- @pyqtSlot(int)
+ @QtCore.pyqtSlot(int)
def _on_current_changed(self, index):
"""Emit the tab_index_changed signal if the current tab changed."""
self.tabBar().on_current_changed()
self.update_tab_titles()
self.tab_index_changed.emit(index, self.count())
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_new_tab_requested(self):
"""Open a new tab."""
self.new_tab_requested.emit(config.val.url.default_page, False, False)
@@ -334,24 +328,24 @@ class TabWidget(QTabWidget):
"""
tab = self.widget(idx)
if tab is None:
- url = QUrl() # type: ignore[unreachable]
+ url = QtCore.QUrl() # type: ignore[unreachable]
else:
url = tab.url()
# It's possible for url to be invalid, but the caller will handle that.
qtutils.ensure_valid(url)
return url
- def update_tab_favicon(self, tab: QWidget) -> None:
+ def update_tab_favicon(self, tab: QtWidgets.QWidget) -> None:
"""Update favicon of the given tab."""
idx = self.indexOf(tab)
- icon = tab.icon() if tab.data.should_show_icon() else QIcon()
+ icon = tab.icon() if tab.data.should_show_icon() else QtGui.QIcon()
self.setTabIcon(idx, icon)
if config.val.tabs.tabs_are_windows:
self.window().setWindowIcon(tab.icon())
- def setTabIcon(self, idx: int, icon: QIcon) -> None:
+ def setTabIcon(self, idx: int, icon: QtGui.QIcon) -> None:
"""Always show tab icons for pinned tabs in some circumstances."""
tab = cast(Optional[browsertab.AbstractTab], self.widget(idx))
if (icon.isNull() and
@@ -359,11 +353,11 @@ class TabWidget(QTabWidget):
config.cache['tabs.pinned.shrink'] and
not self.tabBar().vertical and
tab is not None and tab.data.pinned):
- icon = self.style().standardIcon(QStyle.SP_FileIcon)
+ icon = self.style().standardIcon(QtWidgets.QStyle.SP_FileIcon)
super().setTabIcon(idx, icon)
-class TabBar(QTabBar):
+class TabBar(QtWidgets.QTabBar):
"""Custom tab bar with our own style.
@@ -392,14 +386,14 @@ class TabBar(QTabBar):
}
"""
- new_tab_requested = pyqtSignal()
+ new_tab_requested = QtCore.pyqtSignal()
def __init__(self, win_id, parent=None):
super().__init__(parent)
self._win_id = win_id
self.setStyle(TabBarStyle())
self.vertical = False
- self._auto_hide_timer = QTimer()
+ self._auto_hide_timer = QtCore.QTimer()
self._auto_hide_timer.setSingleShot(True)
self._auto_hide_timer.timeout.connect(self.maybe_hide)
self._on_show_switching_delay_changed()
@@ -409,7 +403,7 @@ class TabBar(QTabBar):
self.ensurePolished()
config.instance.changed.connect(self._on_config_changed)
self._set_icon_size()
- QTimer.singleShot(0, self.maybe_hide)
+ QtCore.QTimer.singleShot(0, self.maybe_hide)
self._minimum_tab_size_hint_helper = functools.lru_cache(maxsize=2**9)(
self._minimum_tab_size_hint_helper_uncached
)
@@ -427,7 +421,7 @@ class TabBar(QTabBar):
"""Get the current tab object."""
return self.parent().currentWidget()
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _on_config_changed(self, option: str) -> None:
if option.startswith('fonts.tabs.'):
self.ensurePolished()
@@ -464,7 +458,7 @@ class TabBar(QTabBar):
self.show()
self._auto_hide_timer.start()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def maybe_hide(self):
"""Hide the tab bar if needed."""
show = config.val.tabs.show
@@ -502,7 +496,7 @@ class TabBar(QTabBar):
try:
return self.tab_data(idx, 'indicator-color')
except KeyError:
- return QColor()
+ return QtGui.QColor()
def page_title(self, idx):
"""Get the tab title user data.
@@ -525,7 +519,7 @@ class TabBar(QTabBar):
"""Set the tab bar favicon size."""
size = self.fontMetrics().height() - 2
size = int(size * config.val.tabs.favicons.scale)
- self.setIconSize(QSize(size, size))
+ self.setIconSize(QtCore.QSize(size, size))
def mouseReleaseEvent(self, e):
"""Override mouseReleaseEvent to know when drags stop."""
@@ -538,8 +532,8 @@ class TabBar(QTabBar):
Also keep track of if we are currently in a drag."""
self.drag_in_progress = True
button = config.val.tabs.close_mouse_button
- if (e.button() == Qt.RightButton and button == 'right' or
- e.button() == Qt.MiddleButton and button == 'middle'):
+ if (e.button() == QtCore.Qt.RightButton and button == 'right' or
+ e.button() == QtCore.Qt.MiddleButton and button == 'middle'):
e.accept()
idx = self.tabAt(e.pos())
if idx == -1:
@@ -557,7 +551,7 @@ class TabBar(QTabBar):
return
super().mousePressEvent(e)
- def minimumTabSizeHint(self, index: int, ellipsis: bool = True) -> QSize:
+ def minimumTabSizeHint(self, index: int, ellipsis: bool = True) -> QtCore.QSize:
"""Set the minimum tab size to indicator/icon/... text.
Args:
@@ -586,7 +580,7 @@ class TabBar(QTabBar):
def _minimum_tab_size_hint_helper_uncached(self, tab_text: str,
icon_width: int,
- ellipsis: bool, pinned: bool) -> QSize:
+ ellipsis: bool, pinned: bool) -> QtCore.QSize:
"""Helper function to cache tab results.
Config values accessed in here should be added to _on_config_changed to
@@ -597,7 +591,7 @@ class TabBar(QTabBar):
def _text_to_width(text):
# Calculate text width taking into account qt mnemonics
- return self.fontMetrics().size(Qt.TextShowMnemonic, text).width()
+ return self.fontMetrics().size(QtCore.Qt.TextShowMnemonic, text).width()
text_width = min(_text_to_width(text),
_text_to_width(tab_text))
padding = config.cache['tabs.padding']
@@ -615,7 +609,7 @@ class TabBar(QTabBar):
if (not self.vertical and min_width > 0 and
not pinned or not config.cache['tabs.pinned.shrink']):
width = max(min_width, width)
- return QSize(width, height)
+ return QtCore.QSize(width, height)
def _minimum_tab_height_uncached(self):
padding = config.cache['tabs.padding']
@@ -634,7 +628,7 @@ class TabBar(QTabBar):
return False
return widget.data.pinned
- def tabSizeHint(self, index: int) -> QSize:
+ def tabSizeHint(self, index: int) -> QtCore.QSize:
"""Override tabSizeHint to customize qb's tab size.
https://wiki.python.org/moin/PyQt/Customising%20tab%20bars
@@ -649,7 +643,7 @@ class TabBar(QTabBar):
# This happens on startup on macOS.
# We return it directly rather than setting `size' because we don't
# want to ensure it's valid in this special case.
- return QSize()
+ return QtCore.QSize()
height = self._minimum_tab_height()
if self.vertical:
@@ -661,7 +655,7 @@ class TabBar(QTabBar):
width = main_window.width() * perc // 100
else:
width = int(confwidth)
- size = QSize(width, height)
+ size = QtCore.QSize(width, height)
else:
if config.cache['tabs.pinned.shrink'] and self._tab_pinned(index):
# Give pinned tabs the minimum size they need to display their
@@ -675,20 +669,20 @@ class TabBar(QTabBar):
max_width = config.cache['tabs.max_width']
if max_width > 0:
width = min(max_width, width)
- size = QSize(width, height)
+ size = QtCore.QSize(width, height)
qtutils.ensure_valid(size)
return size
def paintEvent(self, event):
"""Override paintEvent to draw the tabs like we want to."""
- p = QStylePainter(self)
+ p = QtWidgets.QStylePainter(self)
selected = self.currentIndex()
for idx in range(self.count()):
if not event.region().intersects(self.tabRect(idx)):
# Don't repaint if we are outside the requested region
continue
- tab = QStyleOptionTab()
+ tab = QtWidgets.QStyleOptionTab()
self.initStyleOption(tab, idx)
setting = 'colors.tabs'
@@ -698,14 +692,14 @@ class TabBar(QTabBar):
setting += '.selected'
setting += '.odd' if (idx + 1) % 2 else '.even'
- tab.palette.setColor(QPalette.Window,
+ tab.palette.setColor(QtGui.QPalette.Window,
config.cache[setting + '.bg'])
- tab.palette.setColor(QPalette.WindowText,
+ tab.palette.setColor(QtGui.QPalette.WindowText,
config.cache[setting + '.fg'])
indicator_color = self.tab_indicator_color(idx)
- tab.palette.setColor(QPalette.Base, indicator_color)
- p.drawControl(QStyle.CE_TabBarTab, tab)
+ tab.palette.setColor(QtGui.QPalette.Base, indicator_color)
+ p.drawControl(QtWidgets.QStyle.CE_TabBarTab, tab)
def tabInserted(self, idx):
"""Update visibility when a tab was inserted."""
@@ -753,12 +747,12 @@ class Layouts:
Used by TabBarStyle._tab_layout().
"""
- text: QRect
- icon: QRect
- indicator: QRect
+ text: QtCore.QRect
+ icon: QtCore.QRect
+ indicator: QtCore.QRect
-class TabBarStyle(QCommonStyle):
+class TabBarStyle(QtWidgets.QCommonStyle):
"""Qt style used by TabBar to fix some issues with the default one.
@@ -783,7 +777,7 @@ class TabBarStyle(QCommonStyle):
This simply calls the corresponding function in self._style.
"""
- self._style = QStyleFactory.create('Fusion')
+ self._style = QtWidgets.QStyleFactory.create('Fusion')
for method in ['drawComplexControl', 'drawItemPixmap',
'generatedIconPixmap', 'hitTestComplexControl',
'itemPixmapRect', 'itemTextRect', 'polish', 'styleHint',
@@ -815,12 +809,12 @@ class TabBarStyle(QCommonStyle):
p: QPainter
"""
qtutils.ensure_valid(layouts.icon)
- icon_mode = (QIcon.Normal if opt.state & QStyle.State_Enabled
- else QIcon.Disabled)
- icon_state = (QIcon.On if opt.state & QStyle.State_Selected
- else QIcon.Off)
+ icon_mode = (QtGui.QIcon.Normal if opt.state & QtWidgets.QStyle.State_Enabled
+ else QtGui.QIcon.Disabled)
+ icon_state = (QtGui.QIcon.On if opt.state & QtWidgets.QStyle.State_Selected
+ else QtGui.QIcon.Off)
icon = opt.icon.pixmap(opt.iconSize, icon_mode, icon_state)
- self._style.drawItemPixmap(p, layouts.icon, Qt.AlignCenter, icon)
+ self._style.drawItemPixmap(p, layouts.icon, QtCore.Qt.AlignCenter, icon)
def drawControl(self, element, opt, p, widget=None):
"""Override drawControl to draw odd tabs in a different color.
@@ -834,8 +828,8 @@ class TabBarStyle(QCommonStyle):
p: QPainter
widget: QWidget
"""
- if element not in [QStyle.CE_TabBarTab, QStyle.CE_TabBarTabShape,
- QStyle.CE_TabBarTabLabel]:
+ if element not in [QtWidgets.QStyle.CE_TabBarTab, QtWidgets.QStyle.CE_TabBarTabShape,
+ QtWidgets.QStyle.CE_TabBarTabLabel]:
# Let the real style draw it.
self._style.drawControl(element, opt, p, widget)
return
@@ -845,28 +839,28 @@ class TabBarStyle(QCommonStyle):
log.misc.warning("Could not get layouts for tab!")
return
- if element == QStyle.CE_TabBarTab:
+ if element == QtWidgets.QStyle.CE_TabBarTab:
# We override this so we can control TabBarTabShape/TabBarTabLabel.
- self.drawControl(QStyle.CE_TabBarTabShape, opt, p, widget)
- self.drawControl(QStyle.CE_TabBarTabLabel, opt, p, widget)
- elif element == QStyle.CE_TabBarTabShape:
+ self.drawControl(QtWidgets.QStyle.CE_TabBarTabShape, opt, p, widget)
+ self.drawControl(QtWidgets.QStyle.CE_TabBarTabLabel, opt, p, widget)
+ elif element == QtWidgets.QStyle.CE_TabBarTabShape:
p.fillRect(opt.rect, opt.palette.window())
self._draw_indicator(layouts, opt, p)
# We use super() rather than self._style here because we don't want
# any sophisticated drawing.
- super().drawControl(QStyle.CE_TabBarTabShape, opt, p, widget)
- elif element == QStyle.CE_TabBarTabLabel:
+ super().drawControl(QtWidgets.QStyle.CE_TabBarTabShape, opt, p, widget)
+ elif element == QtWidgets.QStyle.CE_TabBarTabLabel:
if not opt.icon.isNull() and layouts.icon.isValid():
self._draw_icon(layouts, opt, p)
alignment = (config.cache['tabs.title.alignment'] |
- Qt.AlignVCenter | Qt.TextHideMnemonic)
+ QtCore.Qt.AlignVCenter | QtCore.Qt.TextHideMnemonic)
self._style.drawItemText(p,
layouts.text,
int(alignment),
opt.palette,
- bool(opt.state & QStyle.State_Enabled),
+ bool(opt.state & QtWidgets.QStyle.State_Enabled),
opt.text,
- QPalette.WindowText)
+ QtGui.QPalette.WindowText)
else:
raise ValueError("Invalid element {!r}".format(element))
@@ -881,11 +875,11 @@ class TabBarStyle(QCommonStyle):
Return:
An int.
"""
- if metric in [QStyle.PM_TabBarTabShiftHorizontal,
- QStyle.PM_TabBarTabShiftVertical,
- QStyle.PM_TabBarTabHSpace,
- QStyle.PM_TabBarTabVSpace,
- QStyle.PM_TabBarScrollButtonWidth]:
+ if metric in [QtWidgets.QStyle.PM_TabBarTabShiftHorizontal,
+ QtWidgets.QStyle.PM_TabBarTabShiftVertical,
+ QtWidgets.QStyle.PM_TabBarTabHSpace,
+ QtWidgets.QStyle.PM_TabBarTabVSpace,
+ QtWidgets.QStyle.PM_TabBarScrollButtonWidth]:
return 0
else:
return self._style.pixelMetric(metric, option, widget)
@@ -901,14 +895,14 @@ class TabBarStyle(QCommonStyle):
Return:
A QRect.
"""
- if sr == QStyle.SE_TabBarTabText:
+ if sr == QtWidgets.QStyle.SE_TabBarTabText:
layouts = self._tab_layout(opt)
if layouts is None:
log.misc.warning("Could not get layouts for tab!")
- return QRect()
+ return QtCore.QRect()
return layouts.text
- elif sr in [QStyle.SE_TabWidgetTabBar,
- QStyle.SE_TabBarScrollLeftButton]:
+ elif sr in [QtWidgets.QStyle.SE_TabWidgetTabBar,
+ QtWidgets.QStyle.SE_TabBarScrollLeftButton]:
# Handling SE_TabBarScrollLeftButton so the left scroll button is
# aligned properly. Otherwise, empty space will be shown after the
# last tab even though the button width is set to 0
@@ -936,7 +930,7 @@ class TabBarStyle(QCommonStyle):
padding = config.cache['tabs.padding']
indicator_padding = config.cache['tabs.indicator.padding']
- text_rect = QRect(opt.rect)
+ text_rect = QtCore.QRect(opt.rect)
if not text_rect.isValid():
# This happens sometimes according to crash reports, but no idea
# why...
@@ -947,9 +941,9 @@ class TabBarStyle(QCommonStyle):
indicator_width = config.cache['tabs.indicator.width']
if indicator_width == 0:
- indicator_rect = QRect()
+ indicator_rect = QtCore.QRect()
else:
- indicator_rect = QRect(opt.rect)
+ indicator_rect = QtCore.QRect(opt.rect)
qtutils.ensure_valid(indicator_rect)
indicator_rect.adjust(padding.left + indicator_padding.left,
padding.top + indicator_padding.top,
@@ -981,24 +975,24 @@ class TabBarStyle(QCommonStyle):
"""
icon_size = opt.iconSize
if not icon_size.isValid():
- icon_extent = self.pixelMetric(QStyle.PM_SmallIconSize)
- icon_size = QSize(icon_extent, icon_extent)
- icon_mode = (QIcon.Normal if opt.state & QStyle.State_Enabled
- else QIcon.Disabled)
- icon_state = (QIcon.On if opt.state & QStyle.State_Selected
- else QIcon.Off)
+ icon_extent = self.pixelMetric(QtWidgets.QStyle.PM_SmallIconSize)
+ icon_size = QtCore.QSize(icon_extent, icon_extent)
+ icon_mode = (QtGui.QIcon.Normal if opt.state & QtWidgets.QStyle.State_Enabled
+ else QtGui.QIcon.Disabled)
+ icon_state = (QtGui.QIcon.On if opt.state & QtWidgets.QStyle.State_Selected
+ else QtGui.QIcon.Off)
# reserve space for favicon when tab bar is vertical (issue #1968)
position = config.cache['tabs.position']
- if (position in [QTabWidget.East, QTabWidget.West] and
+ if (position in [QtWidgets.QTabWidget.East, QtWidgets.QTabWidget.West] and
config.cache['tabs.favicons.show'] != 'never'):
tab_icon_size = icon_size
else:
actual_size = opt.icon.actualSize(icon_size, icon_mode, icon_state)
- tab_icon_size = QSize(
+ tab_icon_size = QtCore.QSize(
min(actual_size.width(), icon_size.width()),
min(actual_size.height(), icon_size.height()))
icon_top = text_rect.center().y() + 1 - tab_icon_size.height() // 2
- icon_rect = QRect(QPoint(text_rect.left(), icon_top), tab_icon_size)
+ icon_rect = QtCore.QRect(QtCore.QPoint(text_rect.left(), icon_top), tab_icon_size)
icon_rect = self._style.visualRect(opt.direction, opt.rect, icon_rect)
return icon_rect
diff --git a/qutebrowser/mainwindow/windowundo.py b/qutebrowser/mainwindow/windowundo.py
index ea7e1a987..632a4d491 100644
--- a/qutebrowser/mainwindow/windowundo.py
+++ b/qutebrowser/mainwindow/windowundo.py
@@ -23,11 +23,11 @@ import collections
import dataclasses
from typing import MutableSequence, cast, TYPE_CHECKING
-from PyQt5.QtCore import QObject, QByteArray
-
from qutebrowser.config import config
from qutebrowser.mainwindow import mainwindow
from qutebrowser.misc import objects
+from qutebrowser.qt import QtCore
+
if TYPE_CHECKING:
from qutebrowser.mainwindow import tabbedbrowser
@@ -40,11 +40,11 @@ class _WindowUndoEntry:
"""Information needed for :undo -w."""
- geometry: QByteArray
+ geometry: QtCore.QByteArray
tab_stack: 'tabbedbrowser.UndoStackType'
-class WindowUndoManager(QObject):
+class WindowUndoManager(QtCore.QObject):
"""Manager which saves/restores windows."""
diff --git a/qutebrowser/misc/autoupdate.py b/qutebrowser/misc/autoupdate.py
index 73afdde54..183e4d750 100644
--- a/qutebrowser/misc/autoupdate.py
+++ b/qutebrowser/misc/autoupdate.py
@@ -21,12 +21,11 @@
import json
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl
-
from qutebrowser.misc import httpclient
+from qutebrowser.qt import QtCore
-class PyPIVersionClient(QObject):
+class PyPIVersionClient(QtCore.QObject):
"""A client for the PyPI API using HTTPClient.
@@ -46,8 +45,8 @@ class PyPIVersionClient(QObject):
"""
API_URL = 'https://pypi.org/pypi/{}/json'
- success = pyqtSignal(str)
- error = pyqtSignal(str)
+ success = QtCore.pyqtSignal(str)
+ error = QtCore.pyqtSignal(str)
def __init__(self, parent=None, client=None):
super().__init__(parent)
@@ -66,10 +65,10 @@ class PyPIVersionClient(QObject):
Args:
package: The name of the package to check.
"""
- url = QUrl(self.API_URL.format(package))
+ url = QtCore.QUrl(self.API_URL.format(package))
self._client.get(url)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def on_client_success(self, data):
"""Process the data and finish when the client finished.
diff --git a/qutebrowser/misc/backendproblem.py b/qutebrowser/misc/backendproblem.py
index 3e14719e0..7cd292294 100644
--- a/qutebrowser/misc/backendproblem.py
+++ b/qutebrowser/misc/backendproblem.py
@@ -29,10 +29,7 @@ import argparse
import dataclasses
from typing import Any, List, Sequence, Tuple, Optional
-from PyQt5.QtCore import Qt
-from PyQt5.QtWidgets import (QDialog, QPushButton, QHBoxLayout, QVBoxLayout, QLabel,
- QMessageBox, QWidget)
-from PyQt5.QtNetwork import QSslSocket
+from qutebrowser.qt import QtWidgets, QtWebKitWidgets, QtWebKit, QtWebEngineWidgets, QtNetwork, QtCore
from qutebrowser.config import config, configfiles
from qutebrowser.utils import (usertypes, version, qtutils, log, utils,
@@ -44,10 +41,10 @@ class _Result(enum.IntEnum):
"""The result code returned by the backend problem dialog."""
- quit = QDialog.Accepted + 1
- restart = QDialog.Accepted + 2
- restart_webkit = QDialog.Accepted + 3
- restart_webengine = QDialog.Accepted + 4
+ quit = QtWidgets.QDialog.Accepted + 1
+ restart = QtWidgets.QDialog.Accepted + 2
+ restart_webkit = QtWidgets.QDialog.Accepted + 3
+ restart_webengine = QtWidgets.QDialog.Accepted + 4
@dataclasses.dataclass
@@ -94,7 +91,7 @@ def _error_text(because: str, text: str, backend: usertypes.Backend) -> str:
warning=warning, suffix=suffix))
-class _Dialog(QDialog):
+class _Dialog(QtWidgets.QDialog):
"""A dialog which gets shown if there are issues with the backend."""
@@ -102,35 +99,35 @@ class _Dialog(QDialog):
text: str,
backend: usertypes.Backend,
buttons: Sequence[_Button] = None,
- parent: QWidget = None) -> None:
+ parent: QtWidgets.QWidget = None) -> None:
super().__init__(parent)
- vbox = QVBoxLayout(self)
+ vbox = QtWidgets.QVBoxLayout(self)
other_backend, other_setting = _other_backend(backend)
text = _error_text(because, text, backend)
- label = QLabel(text)
+ label = QtWidgets.QLabel(text)
label.setWordWrap(True)
- label.setTextFormat(Qt.RichText)
+ label.setTextFormat(QtCore.Qt.RichText)
vbox.addWidget(label)
- hbox = QHBoxLayout()
+ hbox = QtWidgets.QHBoxLayout()
buttons = [] if buttons is None else buttons
- quit_button = QPushButton("Quit")
+ quit_button = QtWidgets.QPushButton("Quit")
quit_button.clicked.connect(lambda: self.done(_Result.quit))
hbox.addWidget(quit_button)
backend_text = "Force {} backend".format(other_backend.name)
if other_backend == usertypes.Backend.QtWebKit:
backend_text += ' (not recommended)'
- backend_button = QPushButton(backend_text)
+ backend_button = QtWidgets.QPushButton(backend_text)
backend_button.clicked.connect(functools.partial(
self._change_setting, 'backend', other_setting))
hbox.addWidget(backend_button)
for button in buttons:
- btn = QPushButton(button.text)
+ btn = QtWidgets.QPushButton(button.text)
btn.setDefault(button.default)
btn.clicked.connect(functools.partial(
self._change_setting, button.setting, button.value))
@@ -181,7 +178,7 @@ class _BackendProblemChecker:
status = dialog.exec()
self._save_manager.save_all(is_exit=True)
- if status in [_Result.quit, QDialog.Rejected]:
+ if status in [_Result.quit, QtWidgets.QDialog.Rejected]:
pass
elif status == _Result.restart_webkit:
quitter.instance.restart(override_args={'backend': 'webkit'})
@@ -270,9 +267,7 @@ class _BackendProblemChecker:
results = _BackendImports()
try:
- from PyQt5 import QtWebKit
- from PyQt5.QtWebKit import qWebKitVersion
- from PyQt5 import QtWebKitWidgets
+ pass
except (ImportError, ValueError) as e:
results.webkit_error = str(e)
else:
@@ -280,7 +275,7 @@ class _BackendProblemChecker:
results.webkit_error = "Unsupported legacy QtWebKit found"
try:
- from PyQt5 import QtWebEngineWidgets
+ pass
except (ImportError, ValueError) as e:
results.webengine_error = str(e)
@@ -291,7 +286,7 @@ class _BackendProblemChecker:
If "fatal" is given, show an error and exit.
"""
- if QSslSocket.supportsSsl():
+ if QtNetwork.QSslSocket.supportsSsl():
return
if qtutils.version_check('5.12.4'):
@@ -312,7 +307,7 @@ class _BackendProblemChecker:
errbox = msgbox.msgbox(parent=None,
title="SSL error",
text="Could not initialize SSL support.",
- icon=QMessageBox.Critical,
+ icon=QtWidgets.QMessageBox.Critical,
plain_text=False)
errbox.exec()
sys.exit(usertypes.Exit.err_init)
@@ -338,7 +333,7 @@ class _BackendProblemChecker:
errbox = msgbox.msgbox(parent=None,
title="No backend library found!",
text=text,
- icon=QMessageBox.Critical,
+ icon=QtWidgets.QMessageBox.Critical,
plain_text=False)
errbox.exec()
sys.exit(usertypes.Exit.err_init)
diff --git a/qutebrowser/misc/cmdhistory.py b/qutebrowser/misc/cmdhistory.py
index e4218832c..9eceb0159 100644
--- a/qutebrowser/misc/cmdhistory.py
+++ b/qutebrowser/misc/cmdhistory.py
@@ -21,10 +21,9 @@
from typing import MutableSequence
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
-
from qutebrowser.utils import usertypes, log, standarddir, objreg
from qutebrowser.misc import lineparser
+from qutebrowser.qt import QtCore
class HistoryEmptyError(Exception):
@@ -37,7 +36,7 @@ class HistoryEndReachedError(Exception):
"""Raised when the end of the history is reached."""
-class History(QObject):
+class History(QtCore.QObject):
"""Command history.
@@ -49,7 +48,7 @@ class History(QObject):
changed: Emitted when an entry was added to the history.
"""
- changed = pyqtSignal()
+ changed = QtCore.pyqtSignal()
def __init__(self, *, history=None, parent=None):
"""Constructor.
@@ -92,7 +91,7 @@ class History(QObject):
self._tmphist = usertypes.NeighborList(items)
return self._tmphist.lastitem()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def stop(self):
"""Stop browsing the history."""
self._tmphist = None
diff --git a/qutebrowser/misc/consolewidget.py b/qutebrowser/misc/consolewidget.py
index a826a4ed8..951e630b8 100644
--- a/qutebrowser/misc/consolewidget.py
+++ b/qutebrowser/misc/consolewidget.py
@@ -22,14 +22,12 @@
import sys
import code
from typing import MutableSequence
-
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, Qt
-from PyQt5.QtWidgets import QTextEdit, QWidget, QVBoxLayout, QApplication
-from PyQt5.QtGui import QTextCursor
+from qutebrowser.qt import QtWidgets, QtGui
from qutebrowser.config import stylesheet
from qutebrowser.misc import cmdhistory, miscwidgets
from qutebrowser.utils import utils, objreg
+from qutebrowser.qt import QtCore
console_widget = None
@@ -46,7 +44,7 @@ class ConsoleLineEdit(miscwidgets.CommandLineEdit):
execute: Emitted when a commandline should be executed.
"""
- execute = pyqtSignal(str)
+ execute = QtCore.pyqtSignal(str)
def __init__(self, _namespace, parent):
"""Constructor.
@@ -58,7 +56,7 @@ class ConsoleLineEdit(miscwidgets.CommandLineEdit):
self._history = cmdhistory.History(parent=self)
self.returnPressed.connect(self.on_return_pressed)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_return_pressed(self):
"""Execute the line of code which was entered."""
self._history.stop()
@@ -92,20 +90,20 @@ class ConsoleLineEdit(miscwidgets.CommandLineEdit):
def keyPressEvent(self, e):
"""Override keyPressEvent to handle special keypresses."""
- if e.key() == Qt.Key_Up:
+ if e.key() == QtCore.Qt.Key_Up:
self.history_prev()
e.accept()
- elif e.key() == Qt.Key_Down:
+ elif e.key() == QtCore.Qt.Key_Down:
self.history_next()
e.accept()
- elif e.modifiers() & Qt.ControlModifier and e.key() == Qt.Key_C:
+ elif e.modifiers() & QtCore.Qt.ControlModifier and e.key() == QtCore.Qt.Key_C:
self.setText('')
e.accept()
else:
super().keyPressEvent(e)
-class ConsoleTextEdit(QTextEdit):
+class ConsoleTextEdit(QtWidgets.QTextEdit):
"""Custom QTextEdit for console output."""
@@ -113,7 +111,7 @@ class ConsoleTextEdit(QTextEdit):
super().__init__(parent)
self.setAcceptRichText(False)
self.setReadOnly(True)
- self.setFocusPolicy(Qt.ClickFocus)
+ self.setFocusPolicy(QtCore.Qt.ClickFocus)
def __repr__(self):
return utils.get_repr(self)
@@ -124,13 +122,13 @@ class ConsoleTextEdit(QTextEdit):
We can't use Qt's way to append stuff because that inserts weird
newlines.
"""
- self.moveCursor(QTextCursor.End)
+ self.moveCursor(QtGui.QTextCursor.End)
self.insertPlainText(text)
scrollbar = self.verticalScrollBar()
scrollbar.setValue(scrollbar.maximum())
-class ConsoleWidget(QWidget):
+class ConsoleWidget(QtWidgets.QWidget):
"""A widget with an interactive Python console.
@@ -158,7 +156,7 @@ class ConsoleWidget(QWidget):
namespace = {
'__name__': '__console__',
'__doc__': None,
- 'q_app': QApplication.instance(),
+ 'q_app': QtWidgets.QApplication.instance(),
# We use parent as self here because the user "feels" the whole
# console, not just the line edit.
'self': parent,
@@ -170,7 +168,7 @@ class ConsoleWidget(QWidget):
self._lineedit.execute.connect(self.push)
self._output = ConsoleTextEdit()
self.write(self._curprompt())
- self._vbox = QVBoxLayout()
+ self._vbox = QtWidgets.QVBoxLayout()
self._vbox.setSpacing(0)
self._vbox.addWidget(self._output)
self._vbox.addWidget(self._lineedit)
@@ -186,7 +184,7 @@ class ConsoleWidget(QWidget):
"""Write a line of text (without added newline) to the output."""
self._output.append_text(line)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def push(self, line):
"""Push a line to the interpreter."""
self._buffer.append(line)
diff --git a/qutebrowser/misc/crashdialog.py b/qutebrowser/misc/crashdialog.py
index 430553433..bc484ea87 100644
--- a/qutebrowser/misc/crashdialog.py
+++ b/qutebrowser/misc/crashdialog.py
@@ -30,25 +30,21 @@ import datetime
import enum
from typing import List, Tuple
-from PyQt5.QtCore import pyqtSlot, Qt, QSize
-from PyQt5.QtWidgets import (QDialog, QLabel, QTextEdit, QPushButton,
- QVBoxLayout, QHBoxLayout, QCheckBox,
- QDialogButtonBox, QMessageBox)
-
import qutebrowser
from qutebrowser.utils import version, log, utils
from qutebrowser.misc import (miscwidgets, autoupdate, msgbox, httpclient,
pastebin, objects)
from qutebrowser.config import config, configfiles
from qutebrowser.browser import history
+from qutebrowser.qt import QtWidgets, QtCore
class Result(enum.IntEnum):
"""The result code returned by the crash dialog."""
- restore = QDialog.Accepted + 1
- no_restore = QDialog.Accepted + 2
+ restore = QtWidgets.QDialog.Accepted + 1
+ no_restore = QtWidgets.QDialog.Accepted + 2
def parse_fatal_stacktrace(text):
@@ -92,7 +88,7 @@ def _get_environment_vars():
return '\n'.join(sorted(info))
-class _CrashDialog(QDialog):
+class _CrashDialog(QtWidgets.QDialog):
"""Dialog which gets shown after there was a crash.
@@ -122,8 +118,8 @@ class _CrashDialog(QDialog):
self._btn_box = None
self._paste_text = None
self.setWindowTitle("Whoops!")
- self.resize(QSize(640, 600))
- self._vbox = QVBoxLayout(self)
+ self.resize(QtCore.QSize(640, 600))
+ self._vbox = QtWidgets.QVBoxLayout(self)
http_client = httpclient.HTTPClient()
self._paste_client = pastebin.PastebinClient(http_client, self)
@@ -135,9 +131,9 @@ class _CrashDialog(QDialog):
self._init_contact_input()
- info = QLabel("What were you doing when this crash/bug happened?")
+ info = QtWidgets.QLabel("What were you doing when this crash/bug happened?")
self._vbox.addWidget(info)
- self._info = QTextEdit()
+ self._info = QtWidgets.QTextEdit()
self._info.setTabChangesFocus(True)
self._info.setAcceptRichText(False)
self._info.setPlaceholderText("- Opened http://www.example.com/\n"
@@ -146,10 +142,10 @@ class _CrashDialog(QDialog):
self._vbox.addWidget(self._info, 5)
self._vbox.addSpacing(15)
- self._debug_log = QTextEdit()
+ self._debug_log = QtWidgets.QTextEdit()
self._debug_log.setTabChangesFocus(True)
self._debug_log.setAcceptRichText(False)
- self._debug_log.setLineWrapMode(QTextEdit.NoWrap)
+ self._debug_log.setLineWrapMode(QtWidgets.QTextEdit.NoWrap)
self._debug_log.hide()
self._fold = miscwidgets.DetailFold("Show log", self)
self._fold.toggled.connect(self._debug_log.setVisible)
@@ -165,7 +161,7 @@ class _CrashDialog(QDialog):
def keyPressEvent(self, e):
"""Prevent closing :report dialogs when pressing <Escape>."""
- if config.val.input.escape_quits_reporter or e.key() != Qt.Key_Escape:
+ if config.val.input.escape_quits_reporter or e.key() != QtCore.Qt.Key_Escape:
super().keyPressEvent(e)
def __repr__(self):
@@ -173,12 +169,12 @@ class _CrashDialog(QDialog):
def _init_contact_input(self):
"""Initialize the widget asking for contact info."""
- contact = QLabel("I'd like to be able to follow up with you, to keep "
+ contact = QtWidgets.QLabel("I'd like to be able to follow up with you, to keep "
"you posted on the status of this crash and get more "
"information if I need it - how can I contact you?")
contact.setWordWrap(True)
self._vbox.addWidget(contact)
- self._contact = QTextEdit()
+ self._contact = QtWidgets.QTextEdit()
self._contact.setTabChangesFocus(True)
self._contact.setAcceptRichText(False)
try:
@@ -198,10 +194,10 @@ class _CrashDialog(QDialog):
Should be extended by subclasses to set the actual text.
"""
- self._lbl = QLabel()
+ self._lbl = QtWidgets.QLabel()
self._lbl.setWordWrap(True)
self._lbl.setOpenExternalLinks(True)
- self._lbl.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
+ self._lbl.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse)
self._vbox.addWidget(self._lbl)
def _init_checkboxes(self):
@@ -209,22 +205,22 @@ class _CrashDialog(QDialog):
def _init_buttons(self):
"""Initialize the buttons."""
- self._btn_box = QDialogButtonBox()
+ self._btn_box = QtWidgets.QDialogButtonBox()
self._vbox.addWidget(self._btn_box)
- self._btn_report = QPushButton("Report")
+ self._btn_report = QtWidgets.QPushButton("Report")
self._btn_report.setDefault(True)
self._btn_report.clicked.connect(self.on_report_clicked)
- self._btn_box.addButton(self._btn_report, QDialogButtonBox.AcceptRole)
+ self._btn_box.addButton(self._btn_report, QtWidgets.QDialogButtonBox.AcceptRole)
- self._btn_cancel = QPushButton("Don't report")
+ self._btn_cancel = QtWidgets.QPushButton("Don't report")
self._btn_cancel.setAutoDefault(False)
self._btn_cancel.clicked.connect(self.finish)
- self._btn_box.addButton(self._btn_cancel, QDialogButtonBox.RejectRole)
+ self._btn_box.addButton(self._btn_cancel, QtWidgets.QDialogButtonBox.RejectRole)
def _init_info_text(self):
"""Add an info text encouraging the user to report crashes."""
- info_label = QLabel("<br/>There is currently a big backlog of crash "
+ info_label = QtWidgets.QLabel("<br/>There is currently a big backlog of crash "
"reports. Thus, it might take a while until your "
"report is seen.<br/>A new tool allowing for more "
"automation will fix this, but is not ready yet "
@@ -326,7 +322,7 @@ class _CrashDialog(QDialog):
exc_text = '{}: {}'.format(e.__class__.__name__, e)
self.show_error(exc_text)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_report_clicked(self):
"""Report and close dialog if report button was clicked."""
self._btn_report.setEnabled(False)
@@ -334,14 +330,14 @@ class _CrashDialog(QDialog):
self._btn_report.setText("Reporting...")
self.report()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_paste_success(self):
"""Get the newest version from PyPI when the paste is done."""
self._pypi_client.success.connect(self.on_version_success)
self._pypi_client.error.connect(self.on_version_error)
self._pypi_client.get_version()
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def show_error(self, text):
"""Show a paste error dialog.
@@ -352,7 +348,7 @@ class _CrashDialog(QDialog):
error_dlg.finished.connect(self.finish)
error_dlg.show()
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def on_version_success(self, newest):
"""Called when the version was obtained from self._pypi_client.
@@ -370,7 +366,7 @@ class _CrashDialog(QDialog):
msgbox.information(self, "Report successfully sent!", text,
on_finished=self.finish, plain_text=False)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def on_version_error(self, msg):
"""Called when the version was not obtained from self._pypi_client.
@@ -386,7 +382,7 @@ class _CrashDialog(QDialog):
msgbox.information(self, "Report successfully sent!", text,
on_finished=self.finish, plain_text=False)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def finish(self):
"""Save contact info and close the dialog."""
self._save_contact_info()
@@ -421,10 +417,10 @@ class ExceptionCrashDialog(_CrashDialog):
def _init_checkboxes(self):
"""Add checkboxes to the dialog."""
super()._init_checkboxes()
- self._chk_restore = QCheckBox("Restore open pages")
+ self._chk_restore = QtWidgets.QCheckBox("Restore open pages")
self._chk_restore.setChecked(True)
self._vbox.addWidget(self._chk_restore)
- self._chk_log = QCheckBox("Include a debug log in the report")
+ self._chk_log = QtWidgets.QCheckBox("Include a debug log in the report")
self._chk_log.setChecked(True)
try:
if config.val.content.private_browsing:
@@ -433,7 +429,7 @@ class ExceptionCrashDialog(_CrashDialog):
log.misc.exception("Error while checking private browsing mode")
self._chk_log.toggled.connect(self._set_crash_info)
self._vbox.addWidget(self._chk_log)
- info_label = QLabel("This makes it a lot easier to diagnose the "
+ info_label = QtWidgets.QLabel("This makes it a lot easier to diagnose the "
"crash.<br/><b>Note that the log might contain "
"sensitive information such as which pages you "
"visited or keyboard input.</b><br/>You can show "
@@ -468,7 +464,7 @@ class ExceptionCrashDialog(_CrashDialog):
except Exception:
self._crash_info.append(("Debug log", traceback.format_exc()))
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def finish(self):
self._save_contact_info()
if self._chk_restore.isChecked():
@@ -492,7 +488,7 @@ class FatalCrashDialog(_CrashDialog):
def __init__(self, debug, text, parent=None):
super().__init__(debug, parent)
self._log = text
- self.setAttribute(Qt.WA_DeleteOnClose)
+ self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self._set_crash_info()
self._type, self._func = parse_fatal_stacktrace(self._log)
@@ -519,7 +515,7 @@ class FatalCrashDialog(_CrashDialog):
def _init_checkboxes(self):
"""Add checkboxes to the dialog."""
super()._init_checkboxes()
- self._chk_history = QCheckBox("Include a history of the last "
+ self._chk_history = QtWidgets.QCheckBox("Include a history of the last "
"accessed pages in the report.")
self._chk_history.setChecked(True)
try:
@@ -544,7 +540,7 @@ class FatalCrashDialog(_CrashDialog):
history_data = traceback.format_exc()
self._crash_info.append(("History", history_data))
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_report_clicked(self):
"""Prevent empty reports."""
if (not self._info.toPlainText().strip() and
@@ -557,7 +553,7 @@ class FatalCrashDialog(_CrashDialog):
"spend on developing qutebrowser instead.\n\nPlease "
"help making qutebrowser better by providing more "
"information, or don't report this.",
- icon=QMessageBox.Critical)
+ icon=QtWidgets.QMessageBox.Critical)
else:
super().on_report_clicked()
@@ -574,7 +570,7 @@ class ReportDialog(_CrashDialog):
def __init__(self, pages, cmdhist, qobjects, parent=None):
super().__init__(False, parent)
- self.setAttribute(Qt.WA_DeleteOnClose)
+ self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self._pages = pages
self._cmdhist = cmdhist
self._qobjects = qobjects
@@ -608,21 +604,21 @@ class ReportDialog(_CrashDialog):
self._crash_info.append(("Debug log", traceback.format_exc()))
-class ReportErrorDialog(QDialog):
+class ReportErrorDialog(QtWidgets.QDialog):
"""An error dialog shown on unsuccessful reports."""
def __init__(self, exc_text, text, parent=None):
super().__init__(parent)
- vbox = QVBoxLayout(self)
- label = QLabel("<b>There was an error while reporting the crash</b>:"
+ vbox = QtWidgets.QVBoxLayout(self)
+ label = QtWidgets.QLabel("<b>There was an error while reporting the crash</b>:"
"<br/>{}<br/><br/>"
"Please copy the text below and send a mail to "
"<a href='mailto:crash@qutebrowser.org'>"
"crash@qutebrowser.org</a> - Thanks!".format(
html.escape(exc_text)))
vbox.addWidget(label)
- txt = QTextEdit()
+ txt = QtWidgets.QTextEdit()
txt.setReadOnly(True)
txt.setTabChangesFocus(True)
txt.setAcceptRichText(False)
@@ -630,9 +626,9 @@ class ReportErrorDialog(QDialog):
txt.selectAll()
vbox.addWidget(txt)
- hbox = QHBoxLayout()
+ hbox = QtWidgets.QHBoxLayout()
hbox.addStretch()
- btn = QPushButton("Close")
+ btn = QtWidgets.QPushButton("Close")
btn.clicked.connect(self.close)
hbox.addWidget(btn)
vbox.addLayout(hbox)
diff --git a/qutebrowser/misc/crashsignal.py b/qutebrowser/misc/crashsignal.py
index d94d3ec54..ccfd51276 100644
--- a/qutebrowser/misc/crashsignal.py
+++ b/qutebrowser/misc/crashsignal.py
@@ -31,15 +31,12 @@ import threading
import faulthandler
import dataclasses
from typing import TYPE_CHECKING, Optional, MutableMapping, cast, List
-
-from PyQt5.QtCore import (pyqtSlot, qInstallMessageHandler, QObject,
- QSocketNotifier, QTimer, QUrl)
-from PyQt5.QtWidgets import QApplication
+from qutebrowser.qt import QtWidgets
from qutebrowser.api import cmdutils
from qutebrowser.misc import earlyinit, crashdialog, ipc, objects
from qutebrowser.utils import usertypes, standarddir, log, objreg, debug, utils
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
if TYPE_CHECKING:
from qutebrowser.misc import quitter
@@ -57,7 +54,7 @@ class ExceptionInfo:
crash_handler = cast('CrashHandler', None)
-class CrashHandler(QObject):
+class CrashHandler(QtCore.QObject):
"""Handler for crashes, reports and exceptions.
@@ -135,7 +132,7 @@ class CrashHandler(QObject):
for tab in tabbed_browser.widgets():
try:
urlstr = tab.url().toString(
- QUrl.RemovePassword | QUrl.FullyEncoded)
+ QtCore.QUrl.RemovePassword | QtCore.QUrl.FullyEncoded)
if urlstr:
win_pages.append(urlstr)
except Exception:
@@ -178,7 +175,7 @@ class CrashHandler(QObject):
else:
self._crash_dialog.report(info=info, contact=contact)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def shutdown(self):
self.destroy_crashlogfile()
@@ -303,7 +300,7 @@ class CrashHandler(QObject):
# We might risk a segfault here, but that's better than continuing to
# run in some undefined state, so we only do the most needed shutdown
# here.
- qInstallMessageHandler(None)
+ QtCore.qInstallMessageHandler(None)
self.destroy_crashlogfile()
sys.exit(usertypes.Exit.exception)
@@ -313,7 +310,7 @@ class CrashHandler(QObject):
self._crash_dialog.raise_()
-class SignalHandler(QObject):
+class SignalHandler(QtCore.QObject):
"""Handler responsible for handling OS signals (SIGINT, SIGTERM, etc.).
@@ -358,8 +355,8 @@ class SignalHandler(QObject):
for fd in [read_fd, write_fd]:
flags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
- self._notifier = QSocketNotifier(cast(sip.voidptr, read_fd),
- QSocketNotifier.Read,
+ self._notifier = QtCore.QSocketNotifier(cast(sip.voidptr, read_fd),
+ QtCore.QSocketNotifier.Read,
self)
self._notifier.activated.connect( # type: ignore[attr-defined]
self.handle_signal_wakeup)
@@ -386,7 +383,7 @@ class SignalHandler(QObject):
self._timer.stop()
self._activated = False
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def handle_signal_wakeup(self):
"""Handle a newly arrived signal.
@@ -407,7 +404,7 @@ class SignalHandler(QObject):
def _log_later(self, *lines):
"""Log the given text line-wise with a QTimer."""
for line in lines:
- QTimer.singleShot(0, functools.partial(log.destroy.info, line))
+ QtCore.QTimer.singleShot(0, functools.partial(log.destroy.info, line))
def interrupt(self, signum, _frame):
"""Handler for signals to gracefully shutdown (SIGINT/SIGTERM).
@@ -420,7 +417,7 @@ class SignalHandler(QObject):
# Signals can arrive anywhere, so we do this in the main thread
self._log_later("SIGINT/SIGTERM received, shutting down!",
"Do the same again to forcefully quit.")
- QTimer.singleShot(0, functools.partial(
+ QtCore.QTimer.singleShot(0, functools.partial(
self._quitter.shutdown, 128 + signum))
def interrupt_forcefully(self, signum, _frame):
@@ -435,7 +432,7 @@ class SignalHandler(QObject):
# Signals can arrive anywhere, so we do this in the main thread
self._log_later("Forceful quit requested, goodbye cruel world!",
"Do the same again to quit with even more force.")
- QTimer.singleShot(0, functools.partial(self._app.exit, 128 + signum))
+ QtCore.QTimer.singleShot(0, functools.partial(self._app.exit, 128 + signum))
def interrupt_really_forcefully(self, signum, _frame):
"""Interrupt with even more force on the third SIGINT/SIGTERM request.
@@ -447,7 +444,7 @@ class SignalHandler(QObject):
sys.exit(128 + signum)
-def init(q_app: QApplication,
+def init(q_app: QtWidgets.QApplication,
args: argparse.Namespace,
quitter: 'quitter.Quitter') -> None:
"""Initialize crash/signal handlers."""
diff --git a/qutebrowser/misc/earlyinit.py b/qutebrowser/misc/earlyinit.py
index 4b3df4db2..fe174991f 100644
--- a/qutebrowser/misc/earlyinit.py
+++ b/qutebrowser/misc/earlyinit.py
@@ -78,22 +78,21 @@ def _die(message, exception=None):
message: The message to display.
exception: The exception object if we're handling an exception.
"""
- from PyQt5.QtWidgets import QApplication, QMessageBox
- from PyQt5.QtCore import Qt
+ from qutebrowser.qt import QtWidgets, QtWebEngineWidgets, QtNetwork, QtCore
if (('--debug' in sys.argv or '--no-err-windows' in sys.argv) and
exception is not None):
print(file=sys.stderr)
traceback.print_exc()
- app = QApplication(sys.argv)
+ app = QtWidgets.QApplication(sys.argv)
if '--no-err-windows' in sys.argv:
print(message, file=sys.stderr)
print("Exiting because of --no-err-windows.", file=sys.stderr)
else:
if exception is not None:
message = message.replace('%ERROR%', str(exception))
- msgbox = QMessageBox(QMessageBox.Critical, "qutebrowser: Fatal error!",
+ msgbox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, "qutebrowser: Fatal error!",
message)
- msgbox.setTextFormat(Qt.RichText)
+ msgbox.setTextFormat(QtCore.Qt.RichText)
msgbox.resize(msgbox.sizeHint())
msgbox.exec()
app.quit()
@@ -162,11 +161,9 @@ def check_pyqt():
def qt_version(qversion=None, qt_version_str=None):
"""Get a Qt version string based on the runtime/compiled versions."""
if qversion is None:
- from PyQt5.QtCore import qVersion
- qversion = qVersion()
+ qversion = QtCore.qVersion()
if qt_version_str is None:
- from PyQt5.QtCore import QT_VERSION_STR
- qt_version_str = QT_VERSION_STR
+ qt_version_str = QtCore.QT_VERSION_STR
if qversion != qt_version_str:
return '{} (compiled {})'.format(qversion, qt_version_str)
@@ -176,22 +173,20 @@ def qt_version(qversion=None, qt_version_str=None):
def check_qt_version():
"""Check if the Qt version is recent enough."""
- from PyQt5.QtCore import QT_VERSION, PYQT_VERSION, PYQT_VERSION_STR
try:
- from PyQt5.QtCore import QVersionNumber, QLibraryInfo
- qt_ver = QLibraryInfo.version().normalized()
- recent_qt_runtime = qt_ver >= QVersionNumber(5, 12) # type: ignore[operator]
+ qt_ver = QtCore.QLibraryInfo.version().normalized()
+ recent_qt_runtime = qt_ver >= QtCore.QVersionNumber(5, 12) # type: ignore[operator]
except (ImportError, AttributeError):
# QVersionNumber was added in Qt 5.6, QLibraryInfo.version() in 5.8
recent_qt_runtime = False
- if QT_VERSION < 0x050C00 or PYQT_VERSION < 0x050C00 or not recent_qt_runtime:
+ if QtCore.QT_VERSION < 0x050C00 or QtCore.PYQT_VERSION < 0x050C00 or not recent_qt_runtime:
text = ("Fatal error: Qt >= 5.12.0 and PyQt >= 5.12.0 are required, "
"but Qt {} / PyQt {} is installed.".format(qt_version(),
- PYQT_VERSION_STR))
+ QtCore.PYQT_VERSION_STR))
_die(text)
- if qt_ver == QVersionNumber(5, 12, 0):
+ if qt_ver == QtCore.QVersionNumber(5, 12, 0):
from qutebrowser.utils import log
log.init.warning("Running on Qt 5.12.0. Doing so is unsupported "
"(newer 5.12.x versions are fine).")
@@ -200,7 +195,7 @@ def check_qt_version():
def check_ssl_support():
"""Check if SSL support is available."""
try:
- from PyQt5.QtNetwork import QSslSocket # pylint: disable=unused-import
+ pass
except ImportError:
_die("Fatal error: Your Qt is built without SSL support.")
@@ -293,7 +288,7 @@ def webengine_early_import():
error messages in backendproblem.py are accurate.
"""
try:
- from PyQt5 import QtWebEngineWidgets # pylint: disable=unused-import
+ pass
except ImportError:
pass
diff --git a/qutebrowser/misc/editor.py b/qutebrowser/misc/editor.py
index 3ef84284d..a80be1669 100644
--- a/qutebrowser/misc/editor.py
+++ b/qutebrowser/misc/editor.py
@@ -22,16 +22,13 @@
import os
import tempfile
-from PyQt5.QtCore import (pyqtSignal, pyqtSlot, QObject, QProcess,
- QFileSystemWatcher)
-
from qutebrowser.config import config
from qutebrowser.utils import message, log
from qutebrowser.misc import guiprocess
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
-class ExternalEditor(QObject):
+class ExternalEditor(QtCore.QObject):
"""Class to simplify editing a text in an external editor.
@@ -51,15 +48,15 @@ class ExternalEditor(QObject):
editing_finished: The editor process was closed.
"""
- file_updated = pyqtSignal(str)
- editing_finished = pyqtSignal()
+ file_updated = QtCore.pyqtSignal(str)
+ editing_finished = QtCore.pyqtSignal()
def __init__(self, parent=None, watch=False):
super().__init__(parent)
self._filename = None
self._proc = None
self._remove_file = None
- self._watcher = QFileSystemWatcher(parent=self) if watch else None
+ self._watcher = QtCore.QFileSystemWatcher(parent=self) if watch else None
self._content = None
def _cleanup(self, *, successful):
@@ -94,7 +91,7 @@ class ExternalEditor(QObject):
message.info(f"Keeping file {self._filename} as the editor process exited "
"abnormally")
- @pyqtSlot(int, QProcess.ExitStatus)
+ @QtCore.pyqtSlot(int, QtCore.QProcess.ExitStatus)
def _on_proc_closed(self, _exitcode, exitstatus):
"""Write the editor text into the form field and clean up tempfile.
@@ -105,7 +102,7 @@ class ExternalEditor(QObject):
return
log.procs.debug("Editor closed")
- if exitstatus != QProcess.NormalExit:
+ if exitstatus != QtCore.QProcess.NormalExit:
# No error/cleanup here, since we already handle this in
# on_proc_error.
return
@@ -116,7 +113,7 @@ class ExternalEditor(QObject):
self.editing_finished.emit()
self._cleanup(successful=self._proc.outcome.was_successful())
- @pyqtSlot(QProcess.ProcessError)
+ @QtCore.pyqtSlot(QtCore.QProcess.ProcessError)
def _on_proc_error(self, _err):
self._cleanup(successful=False)
@@ -164,7 +161,7 @@ class ExternalEditor(QObject):
fobj.write(text)
return fobj.name
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _on_file_changed(self, path):
try:
with open(path, 'r', encoding=config.val.editor.encoding) as f:
diff --git a/qutebrowser/misc/elf.py b/qutebrowser/misc/elf.py
index bf824880a..42442ff5f 100644
--- a/qutebrowser/misc/elf.py
+++ b/qutebrowser/misc/elf.py
@@ -67,7 +67,7 @@ import mmap
import pathlib
from typing import Any, IO, ClassVar, Dict, Optional, Tuple, cast
-from PyQt5.QtCore import QLibraryInfo
+from qutebrowser.qt import QtCore
from qutebrowser.utils import log, version
@@ -314,7 +314,7 @@ def parse_webenginecore() -> Optional[Versions]:
# Flatpak has Qt in /usr/lib/x86_64-linux-gnu, but QtWebEngine in /app/lib.
library_path = pathlib.Path("/app/lib")
else:
- library_path = pathlib.Path(QLibraryInfo.location(QLibraryInfo.LibrariesPath))
+ library_path = pathlib.Path(QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.LibrariesPath))
library_name = sorted(library_path.glob('libQt5WebEngineCore.so*'))
if not library_name:
diff --git a/qutebrowser/misc/guiprocess.py b/qutebrowser/misc/guiprocess.py
index e14169f93..e417b6de8 100644
--- a/qutebrowser/misc/guiprocess.py
+++ b/qutebrowser/misc/guiprocess.py
@@ -25,12 +25,10 @@ import shlex
import shutil
from typing import Mapping, Sequence, Dict, Optional
-from PyQt5.QtCore import (pyqtSlot, pyqtSignal, QObject, QProcess,
- QProcessEnvironment, QByteArray, QUrl, Qt)
-
from qutebrowser.utils import message, log, utils, usertypes, version
from qutebrowser.api import cmdutils, apitypes
from qutebrowser.completion.models import miscmodels
+from qutebrowser.qt import QtCore
all_processes: Dict[int, Optional['GUIProcess']] = {}
@@ -68,7 +66,7 @@ def process(tab: apitypes.Tab, pid: int = None, action: str = 'show') -> None:
raise cmdutils.CommandError(f"Data for process {pid} got cleaned up")
if action == 'show':
- tab.load_url(QUrl(f'qute://process/{pid}'))
+ tab.load_url(QtCore.QUrl(f'qute://process/{pid}'))
elif action == 'terminate':
proc.terminate()
elif action == 'kill':
@@ -84,7 +82,7 @@ class ProcessOutcome:
what: str
running: bool = False
- status: Optional[QProcess.ExitStatus] = None
+ status: Optional[QtCore.QProcess.ExitStatus] = None
code: Optional[int] = None
def was_successful(self) -> bool:
@@ -94,7 +92,7 @@ class ProcessOutcome:
"""
assert self.status is not None, "Process didn't finish yet"
assert self.code is not None
- return self.status == QProcess.NormalExit and self.code == 0
+ return self.status == QtCore.QProcess.NormalExit and self.code == 0
def __str__(self) -> str:
if self.running:
@@ -105,12 +103,12 @@ class ProcessOutcome:
assert self.status is not None
assert self.code is not None
- if self.status == QProcess.CrashExit:
+ if self.status == QtCore.QProcess.CrashExit:
return f"{self.what.capitalize()} crashed."
elif self.was_successful():
return f"{self.what.capitalize()} exited successfully."
- assert self.status == QProcess.NormalExit
+ assert self.status == QtCore.QProcess.NormalExit
# We call this 'status' here as it makes more sense to the user -
# it's actually 'code'.
return f"{self.what.capitalize()} exited with status {self.code}."
@@ -124,7 +122,7 @@ class ProcessOutcome:
return 'running'
elif self.status is None:
return 'not started'
- elif self.status == QProcess.CrashExit:
+ elif self.status == QtCore.QProcess.CrashExit:
return 'crashed'
elif self.was_successful():
return 'successful'
@@ -132,7 +130,7 @@ class ProcessOutcome:
return 'unsuccessful'
-class GUIProcess(QObject):
+class GUIProcess(QtCore.QObject):
"""An external process which shows notifications in the GUI.
@@ -150,9 +148,9 @@ class GUIProcess(QObject):
error/finished/started signals proxied from QProcess.
"""
- error = pyqtSignal(QProcess.ProcessError)
- finished = pyqtSignal(int, QProcess.ExitStatus)
- started = pyqtSignal()
+ error = QtCore.pyqtSignal(QtCore.QProcess.ProcessError)
+ finished = QtCore.pyqtSignal(int, QtCore.QProcess.ExitStatus)
+ started = QtCore.pyqtSignal()
def __init__(
self,
@@ -161,7 +159,7 @@ class GUIProcess(QObject):
verbose: bool = False,
additional_env: Mapping[str, str] = None,
output_messages: bool = False,
- parent: QObject = None,
+ parent: QtCore.QObject = None,
):
super().__init__(parent)
self.what = what
@@ -177,12 +175,12 @@ class GUIProcess(QObject):
self.stderr: str = ""
self._cleanup_timer = usertypes.Timer(self, 'process-cleanup')
- self._cleanup_timer.setTimerType(Qt.VeryCoarseTimer)
+ self._cleanup_timer.setTimerType(QtCore.Qt.VeryCoarseTimer)
self._cleanup_timer.setInterval(3600 * 1000) # 1h
self._cleanup_timer.timeout.connect(self._on_cleanup_timer)
self._cleanup_timer.setSingleShot(True)
- self._proc = QProcess(self)
+ self._proc = QtCore.QProcess(self)
self._proc.errorOccurred.connect(self._on_error)
self._proc.errorOccurred.connect(self.error)
self._proc.finished.connect(self._on_finished)
@@ -193,7 +191,7 @@ class GUIProcess(QObject):
self._proc.readyReadStandardError.connect(self._on_ready_read_stderr)
if additional_env is not None:
- procenv = QProcessEnvironment.systemEnvironment()
+ procenv = QtCore.QProcessEnvironment.systemEnvironment()
for k, v in additional_env.items():
procenv.insert(k, v)
self._proc.setProcessEnvironment(procenv)
@@ -203,12 +201,12 @@ class GUIProcess(QObject):
return f'<unknown {self.what} command>'
return ' '.join(shlex.quote(e) for e in [self.cmd] + list(self.args))
- def _decode_data(self, qba: QByteArray) -> str:
+ def _decode_data(self, qba: QtCore.QByteArray) -> str:
"""Decode data coming from a process."""
encoding = locale.getpreferredencoding(do_setlocale=False)
return qba.data().decode(encoding, 'replace')
- def _process_text(self, data: QByteArray, attr: str) -> None:
+ def _process_text(self, data: QtCore.QByteArray, attr: str) -> None:
"""Process new stdout/stderr text.
Arguments:
@@ -236,7 +234,7 @@ class GUIProcess(QObject):
else:
raise utils.Unreachable(attr)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_ready_read_stdout(self) -> None:
if not self._output_messages:
return
@@ -244,27 +242,27 @@ class GUIProcess(QObject):
self._process_text(self._proc.readAllStandardOutput(), 'stdout')
message.info(self._elide_output(self.stdout), replace=f"stdout-{self.pid}")
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_ready_read_stderr(self) -> None:
if not self._output_messages:
return
self._process_text(self._proc.readAllStandardError(), 'stderr')
message.error(self._elide_output(self.stderr), replace=f"stderr-{self.pid}")
- @pyqtSlot(QProcess.ProcessError)
- def _on_error(self, error: QProcess.ProcessError) -> None:
+ @QtCore.pyqtSlot(QtCore.QProcess.ProcessError)
+ def _on_error(self, error: QtCore.QProcess.ProcessError) -> None:
"""Show a message if there was an error while spawning."""
- if error == QProcess.Crashed and not utils.is_windows:
+ if error == QtCore.QProcess.Crashed and not utils.is_windows:
# Already handled via ExitStatus in _on_finished
return
what = f"{self.what} {self.cmd!r}"
error_descriptions = {
- QProcess.FailedToStart: f"{what.capitalize()} failed to start",
- QProcess.Crashed: f"{what.capitalize()} crashed",
- QProcess.Timedout: f"{what.capitalize()} timed out",
- QProcess.WriteError: f"Write error for {what}",
- QProcess.ReadError: f"Read error for {what}",
+ QtCore.QProcess.FailedToStart: f"{what.capitalize()} failed to start",
+ QtCore.QProcess.Crashed: f"{what.capitalize()} crashed",
+ QtCore.QProcess.Timedout: f"{what.capitalize()} timed out",
+ QtCore.QProcess.WriteError: f"Write error for {what}",
+ QtCore.QProcess.ReadError: f"Read error for {what}",
}
error_string = self._proc.errorString()
msg = ': '.join([error_descriptions[error], error_string])
@@ -295,8 +293,8 @@ class GUIProcess(QObject):
return output
- @pyqtSlot(int, QProcess.ExitStatus)
- def _on_finished(self, code: int, status: QProcess.ExitStatus) -> None:
+ @QtCore.pyqtSlot(int, QtCore.QProcess.ExitStatus)
+ def _on_finished(self, code: int, status: QtCore.QProcess.ExitStatus) -> None:
"""Show a message when the process finished."""
log.procs.debug("Process finished with code {}, status {}.".format(
code, status))
@@ -327,7 +325,7 @@ class GUIProcess(QObject):
log.procs.error("Process stderr:\n" + self.stderr.strip())
message.error(str(self.outcome) + " See :process for details.")
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_started(self) -> None:
"""Called when the process started successfully."""
log.procs.debug("Process started.")
@@ -394,7 +392,7 @@ class GUIProcess(QObject):
global last_pid
last_pid = self.pid
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_cleanup_timer(self) -> None:
"""Remove the process from all registered processes."""
log.procs.debug(f"Cleaning up data for {self.pid}")
diff --git a/qutebrowser/misc/httpclient.py b/qutebrowser/misc/httpclient.py
index d4a8e7673..d401c83c1 100644
--- a/qutebrowser/misc/httpclient.py
+++ b/qutebrowser/misc/httpclient.py
@@ -23,23 +23,20 @@ import functools
import urllib.parse
from typing import MutableMapping
-from PyQt5.QtCore import pyqtSignal, QObject, QTimer
-from PyQt5.QtNetwork import (QNetworkAccessManager, QNetworkRequest,
- QNetworkReply)
-
from qutebrowser.utils import log
+from qutebrowser.qt import QtNetwork, QtCore
-class HTTPRequest(QNetworkRequest):
+class HTTPRequest(QtNetwork.QNetworkRequest):
"""A QNetworkRquest that follows (secure) redirects by default."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
- self.setAttribute(QNetworkRequest.RedirectPolicyAttribute,
- QNetworkRequest.NoLessSafeRedirectPolicy)
+ self.setAttribute(QtNetwork.QNetworkRequest.RedirectPolicyAttribute,
+ QtNetwork.QNetworkRequest.NoLessSafeRedirectPolicy)
-class HTTPClient(QObject):
+class HTTPClient(QtCore.QObject):
"""An HTTP client based on QNetworkAccessManager.
@@ -56,16 +53,16 @@ class HTTPClient(QObject):
arg: The error message, as string.
"""
- success = pyqtSignal(str)
- error = pyqtSignal(str)
+ success = QtCore.pyqtSignal(str)
+ error = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
with log.disable_qt_msghandler():
# WORKAROUND for a hang when messages are printed, see our
# NetworkAccessManager subclass for details.
- self._nam = QNetworkAccessManager(self)
- self._timers: MutableMapping[QNetworkReply, QTimer] = {}
+ self._nam = QtNetwork.QNetworkAccessManager(self)
+ self._timers: MutableMapping[QtNetwork.QNetworkReply, QtCore.QTimer] = {}
def post(self, url, data=None):
"""Create a new POST request.
@@ -78,7 +75,7 @@ class HTTPClient(QObject):
data = {}
encoded_data = urllib.parse.urlencode(data).encode('utf-8')
request = HTTPRequest(url)
- request.setHeader(QNetworkRequest.ContentTypeHeader,
+ request.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader,
'application/x-www-form-urlencoded;charset=utf-8')
reply = self._nam.post(request, encoded_data)
self._handle_reply(reply)
@@ -100,7 +97,7 @@ class HTTPClient(QObject):
if reply.isFinished():
self.on_reply_finished(reply)
else:
- timer = QTimer(self)
+ timer = QtCore.QTimer(self)
timer.setInterval(10000)
timer.timeout.connect(reply.abort)
timer.start()
@@ -118,7 +115,7 @@ class HTTPClient(QObject):
if timer is not None:
timer.stop()
timer.deleteLater()
- if reply.error() != QNetworkReply.NoError:
+ if reply.error() != QtNetwork.QNetworkReply.NoError:
self.error.emit(reply.errorString())
return
try:
diff --git a/qutebrowser/misc/ipc.py b/qutebrowser/misc/ipc.py
index 77b9e8f6c..8ecd6213b 100644
--- a/qutebrowser/misc/ipc.py
+++ b/qutebrowser/misc/ipc.py
@@ -26,12 +26,9 @@ import getpass
import binascii
import hashlib
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, Qt
-from PyQt5.QtNetwork import QLocalSocket, QLocalServer, QAbstractSocket
-
import qutebrowser
from qutebrowser.utils import log, usertypes, error, standarddir, utils
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtNetwork, QtCore, sip
CONNECT_TIMEOUT = 100 # timeout for connecting/disconnecting
@@ -144,7 +141,7 @@ class AddressInUseError(ListenError):
"""Emitted when the server address is already in use."""
-class IPCServer(QObject):
+class IPCServer(QtCore.QObject):
"""IPC server to which clients connect to.
@@ -163,9 +160,9 @@ class IPCServer(QObject):
got_invalid_data: Emitted when there was invalid incoming data.
"""
- got_args = pyqtSignal(list, str, str)
- got_raw = pyqtSignal(bytes)
- got_invalid_data = pyqtSignal()
+ got_args = QtCore.pyqtSignal(list, str, str)
+ got_raw = QtCore.pyqtSignal(bytes)
+ got_invalid_data = QtCore.pyqtSignal()
def __init__(self, socketname, parent=None):
"""Start the IPC server and listen to commands.
@@ -188,9 +185,9 @@ class IPCServer(QObject):
self._atime_timer = usertypes.Timer(self, 'ipc-atime')
self._atime_timer.setInterval(ATIME_INTERVAL)
self._atime_timer.timeout.connect(self.update_atime)
- self._atime_timer.setTimerType(Qt.VeryCoarseTimer)
+ self._atime_timer.setTimerType(QtCore.Qt.VeryCoarseTimer)
- self._server = QLocalServer(self)
+ self._server = QtNetwork.QLocalServer(self)
self._server.newConnection.connect( # type: ignore[attr-defined]
self.handle_connection)
@@ -205,13 +202,13 @@ class IPCServer(QObject):
# Thus, we only do so on Windows, and handle permissions manually in
# listen() on Linux.
log.ipc.debug("Calling setSocketOptions")
- self._server.setSocketOptions(QLocalServer.UserAccessOption)
+ self._server.setSocketOptions(QtNetwork.QLocalServer.UserAccessOption)
else: # pragma: no cover
log.ipc.debug("Not calling setSocketOptions")
def _remove_server(self):
"""Remove an existing server."""
- ok = QLocalServer.removeServer(self._socketname)
+ ok = QtNetwork.QLocalServer.removeServer(self._socketname)
if not ok:
raise Error("Error while removing server {}!".format(
self._socketname))
@@ -224,7 +221,7 @@ class IPCServer(QObject):
self._remove_server()
ok = self._server.listen(self._socketname)
if not ok:
- if self._server.serverError() == QAbstractSocket.AddressInUseError:
+ if self._server.serverError() == QtNetwork.QAbstractSocket.AddressInUseError:
raise AddressInUseError(self._server)
raise ListenError(self._server)
@@ -238,7 +235,7 @@ class IPCServer(QObject):
# True, so report this as an error.
raise ListenError(self._server)
- @pyqtSlot('QLocalSocket::LocalSocketError')
+ @QtCore.pyqtSlot('QLocalSocket::LocalSocketError')
def on_error(self, err):
"""Raise SocketError on fatal errors."""
if self._socket is None:
@@ -249,10 +246,10 @@ class IPCServer(QObject):
log.ipc.debug("Socket 0x{:x}: error {}: {}".format(
id(self._socket), self._socket.error(),
self._socket.errorString()))
- if err != QLocalSocket.PeerClosedError:
+ if err != QtNetwork.QLocalSocket.PeerClosedError:
raise SocketError("handling IPC connection", self._socket)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def handle_connection(self):
"""Handle a new connection to the server."""
if self.ignored:
@@ -276,17 +273,17 @@ class IPCServer(QObject):
log.ipc.debug("We can read a line immediately.")
self.on_ready_read()
socket.error.connect(self.on_error) # type: ignore[attr-defined]
- if socket.error() not in [QLocalSocket.UnknownSocketError,
- QLocalSocket.PeerClosedError]:
+ if socket.error() not in [QtNetwork.QLocalSocket.UnknownSocketError,
+ QtNetwork.QLocalSocket.PeerClosedError]:
log.ipc.debug("We got an error immediately.")
self.on_error(socket.error())
socket.disconnected.connect( # type: ignore[attr-defined]
self.on_disconnected)
- if socket.state() == QLocalSocket.UnconnectedState:
+ if socket.state() == QtNetwork.QLocalSocket.UnconnectedState:
log.ipc.debug("Socket was disconnected immediately.")
self.on_disconnected()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_disconnected(self):
"""Clean up socket when the client disconnected."""
log.ipc.debug("Client disconnected from socket 0x{:x}.".format(
@@ -380,7 +377,7 @@ class IPCServer(QObject):
return socket
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_ready_read(self):
"""Read json data from the client."""
self._timer.stop()
@@ -397,7 +394,7 @@ class IPCServer(QObject):
if self._socket is not None:
self._timer.start()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def on_timeout(self):
"""Cancel the current connection if it was idle for too long."""
assert self._socket is not None
@@ -411,7 +408,7 @@ class IPCServer(QObject):
# on_socket_disconnected sets it to None
self._socket.abort()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def update_atime(self):
"""Update the atime of the socket file all few hours.
@@ -436,7 +433,7 @@ class IPCServer(QObject):
self._server.close()
self.listen()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def shutdown(self):
"""Shut down the IPC server cleanly."""
log.ipc.debug("Shutting down IPC (socket 0x{:x})".format(
@@ -471,7 +468,7 @@ def send_to_running_instance(socketname, command, target_arg, *, socket=None):
True if connecting was successful, False if no connection was made.
"""
if socket is None:
- socket = QLocalSocket()
+ socket = QtNetwork.QLocalSocket()
log.ipc.debug("Connecting to {}".format(socketname))
socket.connectToServer(socketname)
@@ -493,15 +490,15 @@ def send_to_running_instance(socketname, command, target_arg, *, socket=None):
log.ipc.debug("Writing: {!r}".format(data))
socket.writeData(data)
socket.waitForBytesWritten(WRITE_TIMEOUT)
- if socket.error() != QLocalSocket.UnknownSocketError:
+ if socket.error() != QtNetwork.QLocalSocket.UnknownSocketError:
raise SocketError("writing to running instance", socket)
socket.disconnectFromServer()
- if socket.state() != QLocalSocket.UnconnectedState:
+ if socket.state() != QtNetwork.QLocalSocket.UnconnectedState:
socket.waitForDisconnected(CONNECT_TIMEOUT)
return True
else:
- if socket.error() not in [QLocalSocket.ConnectionRefusedError,
- QLocalSocket.ServerNotFoundError]:
+ if socket.error() not in [QtNetwork.QLocalSocket.ConnectionRefusedError,
+ QtNetwork.QLocalSocket.ServerNotFoundError]:
raise SocketError("connecting to running instance", socket)
log.ipc.debug("No existing instance present (error {})".format(
socket.error()))
diff --git a/qutebrowser/misc/keyhintwidget.py b/qutebrowser/misc/keyhintwidget.py
index 93d9af09d..ae2b22720 100644
--- a/qutebrowser/misc/keyhintwidget.py
+++ b/qutebrowser/misc/keyhintwidget.py
@@ -28,16 +28,14 @@ import html
import fnmatch
import re
-from PyQt5.QtWidgets import QLabel, QSizePolicy
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt
-
from qutebrowser.config import config, stylesheet
from qutebrowser.utils import utils, usertypes
from qutebrowser.misc import objects
from qutebrowser.keyinput import keyutils
+from qutebrowser.qt import QtWidgets, QtCore
-class KeyHintView(QLabel):
+class KeyHintView(QtWidgets.QLabel):
"""The view showing hints for key bindings based on the current key string.
@@ -61,13 +59,13 @@ class KeyHintView(QLabel):
{% endif %}
}
"""
- update_geometry = pyqtSignal()
+ update_geometry = QtCore.pyqtSignal()
def __init__(self, win_id, parent=None):
super().__init__(parent)
- self.setTextFormat(Qt.RichText)
+ self.setTextFormat(QtCore.Qt.RichText)
self._win_id = win_id
- self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Minimum)
+ self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
self.hide()
self._show_timer = usertypes.Timer(self, 'keyhint_show')
self._show_timer.timeout.connect(self.show)
@@ -82,7 +80,7 @@ class KeyHintView(QLabel):
self.update_geometry.emit()
super().showEvent(e)
- @pyqtSlot(usertypes.KeyMode, str)
+ @QtCore.pyqtSlot(usertypes.KeyMode, str)
def update_keyhint(self, mode, prefix):
"""Show hints for the given prefix (or hide if prefix is empty).
diff --git a/qutebrowser/misc/lineparser.py b/qutebrowser/misc/lineparser.py
index fee87354f..09e3c3af2 100644
--- a/qutebrowser/misc/lineparser.py
+++ b/qutebrowser/misc/lineparser.py
@@ -24,13 +24,12 @@ import os.path
import contextlib
from typing import Sequence
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
-
from qutebrowser.utils import log, utils, qtutils
from qutebrowser.config import config
+from qutebrowser.qt import QtCore
-class BaseLineParser(QObject):
+class BaseLineParser(QtCore.QObject):
"""A LineParser without any real data.
@@ -44,7 +43,7 @@ class BaseLineParser(QObject):
changed: Emitted when the history was changed.
"""
- changed = pyqtSignal()
+ changed = QtCore.pyqtSignal()
def __init__(self, configdir, fname, *, binary=False, parent=None):
"""Constructor.
@@ -218,7 +217,7 @@ class LimitLineParser(LineParser):
configdir=self._configdir, fname=self._fname,
limit=self._limit, binary=self._binary)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def _cleanup_file(self, option):
"""Delete the file if the limit was changed to 0."""
assert self._configfile is not None
diff --git a/qutebrowser/misc/miscwidgets.py b/qutebrowser/misc/miscwidgets.py
index 4354ed2ab..1e046caa8 100644
--- a/qutebrowser/misc/miscwidgets.py
+++ b/qutebrowser/misc/miscwidgets.py
@@ -21,17 +21,12 @@
from typing import Optional
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QSize, QTimer
-from PyQt5.QtWidgets import (QLineEdit, QWidget, QHBoxLayout, QLabel,
- QStyleOption, QStyle, QLayout, QApplication,
- QSplitter)
-from PyQt5.QtGui import QValidator, QPainter, QResizeEvent
-
from qutebrowser.config import config, configfiles
from qutebrowser.utils import utils, log, usertypes
from qutebrowser.misc import cmdhistory
from qutebrowser.browser import inspector
from qutebrowser.keyinput import keyutils, modeman
+from qutebrowser.qt import QtWidgets, QtGui, QtCore
class MinimalLineEditMixin:
@@ -49,11 +44,11 @@ class MinimalLineEditMixin:
"""
)
self.setAttribute( # type: ignore[attr-defined]
- Qt.WA_MacShowFocusRect, False)
+ QtCore.Qt.WA_MacShowFocusRect, False)
def keyPressEvent(self, e):
"""Override keyPressEvent to paste primary selection on Shift + Ins."""
- if e.key() == Qt.Key_Insert and e.modifiers() == Qt.ShiftModifier:
+ if e.key() == QtCore.Qt.Key_Insert and e.modifiers() == QtCore.Qt.ShiftModifier:
try:
text = utils.get_clipboard(selection=True, fallback=True)
except utils.ClipboardError:
@@ -68,7 +63,7 @@ class MinimalLineEditMixin:
return utils.get_repr(self)
-class CommandLineEdit(QLineEdit):
+class CommandLineEdit(QtWidgets.QLineEdit):
"""A QLineEdit with a history and prompt chars.
@@ -90,12 +85,12 @@ class CommandLineEdit(QLineEdit):
def __repr__(self):
return utils.get_repr(self, text=self.text())
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def on_text_edited(self, _text):
"""Slot for textEdited. Stop history browsing."""
self.history.stop()
- @pyqtSlot(int, int)
+ @QtCore.pyqtSlot(int, int)
def __on_cursor_position_changed(self, _old, new):
"""Prevent the cursor moving to the prompt.
@@ -114,7 +109,7 @@ class CommandLineEdit(QLineEdit):
self._promptlen = len(text)
-class _CommandValidator(QValidator):
+class _CommandValidator(QtGui.QValidator):
"""Validator to prevent the : from getting deleted.
@@ -137,12 +132,12 @@ class _CommandValidator(QValidator):
A tuple (status, string, pos) as a QValidator should.
"""
if self.prompt is None or string.startswith(self.prompt):
- return (QValidator.Acceptable, string, pos)
+ return (QtGui.QValidator.Acceptable, string, pos)
else:
- return (QValidator.Invalid, string, pos)
+ return (QtGui.QValidator.Invalid, string, pos)
-class DetailFold(QWidget):
+class DetailFold(QtWidgets.QWidget):
"""A "fold" widget with an arrow to show/hide details.
@@ -156,16 +151,16 @@ class DetailFold(QWidget):
arg 0: bool, if the contents are currently visible.
"""
- toggled = pyqtSignal(bool)
+ toggled = QtCore.pyqtSignal(bool)
def __init__(self, text, parent=None):
super().__init__(parent)
self._folded = True
- self._hbox = QHBoxLayout(self)
+ self._hbox = QtWidgets.QHBoxLayout(self)
self._hbox.setContentsMargins(0, 0, 0, 0)
self._arrow = _FoldArrow()
self._hbox.addWidget(self._arrow)
- label = QLabel(text)
+ label = QtWidgets.QLabel(text)
self._hbox.addWidget(label)
self._hbox.addStretch()
@@ -181,14 +176,14 @@ class DetailFold(QWidget):
Args:
e: The QMouseEvent.
"""
- if e.button() == Qt.LeftButton:
+ if e.button() == QtCore.Qt.LeftButton:
e.accept()
self.toggle()
else:
super().mousePressEvent(e)
-class _FoldArrow(QWidget):
+class _FoldArrow(QtWidgets.QWidget):
"""The arrow shown for the DetailFold widget.
@@ -215,21 +210,21 @@ class _FoldArrow(QWidget):
Args:
_event: The QPaintEvent (unused).
"""
- opt = QStyleOption()
+ opt = QtWidgets.QStyleOption()
opt.initFrom(self)
- painter = QPainter(self)
+ painter = QtGui.QPainter(self)
if self._folded:
- elem = QStyle.PE_IndicatorArrowRight
+ elem = QtWidgets.QStyle.PE_IndicatorArrowRight
else:
- elem = QStyle.PE_IndicatorArrowDown
+ elem = QtWidgets.QStyle.PE_IndicatorArrowDown
self.style().drawPrimitive(elem, opt, painter, self)
def minimumSizeHint(self):
"""Return a sensible size."""
- return QSize(8, 8)
+ return QtCore.QSize(8, 8)
-class WrapperLayout(QLayout):
+class WrapperLayout(QtWidgets.QLayout):
"""A Qt layout which simply wraps a single widget.
@@ -239,8 +234,8 @@ class WrapperLayout(QLayout):
def __init__(self, parent=None):
super().__init__(parent)
- self._widget: Optional[QWidget] = None
- self._container: Optional[QWidget] = None
+ self._widget: Optional[QtWidgets.QWidget] = None
+ self._container: Optional[QtWidgets.QWidget] = None
def addItem(self, _widget):
raise utils.Unreachable
@@ -248,7 +243,7 @@ class WrapperLayout(QLayout):
def sizeHint(self):
"""Get the size of the underlying widget."""
if self._widget is None:
- return QSize()
+ return QtCore.QSize()
return self._widget.sizeHint()
def itemAt(self, _index):
@@ -284,7 +279,7 @@ class WrapperLayout(QLayout):
self._container.setFocusProxy(None) # type: ignore[arg-type]
-class FullscreenNotification(QLabel):
+class FullscreenNotification(QtWidgets.QLabel):
"""A label telling the user this page is now fullscreen."""
@@ -309,21 +304,21 @@ class FullscreenNotification(QLabel):
if config.val.content.fullscreen.window:
geom = self.parentWidget().geometry()
else:
- geom = QApplication.desktop().screenGeometry(self)
+ geom = QtWidgets.QApplication.desktop().screenGeometry(self)
self.move((geom.width() - self.sizeHint().width()) // 2, 30)
def set_timeout(self, timeout):
"""Hide the widget after the given timeout."""
- QTimer.singleShot(timeout, self._on_timeout)
+ QtCore.QTimer.singleShot(timeout, self._on_timeout)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_timeout(self):
"""Hide and delete the widget."""
self.hide()
self.deleteLater()
-class InspectorSplitter(QSplitter):
+class InspectorSplitter(QtWidgets.QSplitter):
"""Allows putting an inspector inside the tab.
@@ -342,8 +337,8 @@ class InspectorSplitter(QSplitter):
_PROTECTED_MAIN_SIZE = 150
_SMALL_SIZE_THRESHOLD = 300
- def __init__(self, win_id: int, main_webview: QWidget,
- parent: QWidget = None) -> None:
+ def __init__(self, win_id: int, main_webview: QtWidgets.QWidget,
+ parent: QtWidgets.QWidget = None) -> None:
super().__init__(parent)
self._win_id = win_id
self.addWidget(main_webview)
@@ -387,10 +382,10 @@ class InspectorSplitter(QSplitter):
self._inspector_idx = 0
self._main_idx = 1
- self.setOrientation(Qt.Horizontal
+ self.setOrientation(QtCore.Qt.Horizontal
if position in [inspector.Position.left,
inspector.Position.right]
- else Qt.Vertical)
+ else QtCore.Qt.Vertical)
self.insertWidget(self._inspector_idx, inspector_widget)
self._position = position
self._load_preferred_size()
@@ -405,7 +400,7 @@ class InspectorSplitter(QSplitter):
def _load_preferred_size(self) -> None:
"""Load the preferred size of the inspector widget."""
assert self._position is not None
- full = (self.width() if self.orientation() == Qt.Horizontal
+ full = (self.width() if self.orientation() == QtCore.Qt.Horizontal
else self.height())
# If we first open the inspector with a window size of < 300px
@@ -469,29 +464,29 @@ class InspectorSplitter(QSplitter):
# Case 3 above
pass
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _on_splitter_moved(self) -> None:
assert self._inspector_idx is not None
sizes = self.sizes()
self._preferred_size = sizes[self._inspector_idx]
self._save_preferred_size()
- def resizeEvent(self, e: QResizeEvent) -> None:
+ def resizeEvent(self, e: QtGui.QResizeEvent) -> None:
"""Window resize event."""
super().resizeEvent(e)
if self.count() == 2:
self._adjust_size()
-class KeyTesterWidget(QWidget):
+class KeyTesterWidget(QtWidgets.QWidget):
"""Widget displaying key presses."""
def __init__(self, parent=None):
super().__init__(parent)
- self.setAttribute(Qt.WA_DeleteOnClose)
- self._layout = QHBoxLayout(self)
- self._label = QLabel(text="Waiting for keypress...")
+ self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
+ self._layout = QtWidgets.QHBoxLayout(self)
+ self._label = QtWidgets.QLabel(text="Waiting for keypress...")
self._layout.addWidget(self._label)
def keyPressEvent(self, e):
diff --git a/qutebrowser/misc/msgbox.py b/qutebrowser/misc/msgbox.py
index 4271c2639..a56b4fee8 100644
--- a/qutebrowser/misc/msgbox.py
+++ b/qutebrowser/misc/msgbox.py
@@ -19,8 +19,7 @@
"""Convenience functions to show message boxes."""
-from PyQt5.QtCore import Qt
-from PyQt5.QtWidgets import QMessageBox
+from qutebrowser.qt import QtWidgets, QtCore
from qutebrowser.misc import objects
from qutebrowser.utils import log
@@ -34,7 +33,7 @@ class DummyBox:
pass
-def msgbox(parent, title, text, *, icon, buttons=QMessageBox.Ok,
+def msgbox(parent, title, text, *, icon, buttons=QtWidgets.QMessageBox.Ok,
on_finished=None, plain_text=None):
"""Display a QMessageBox with the given icon.
@@ -55,16 +54,16 @@ def msgbox(parent, title, text, *, icon, buttons=QMessageBox.Ok,
log.misc.info(f'{title}\n\n{text}')
return DummyBox()
- box = QMessageBox(parent)
- box.setAttribute(Qt.WA_DeleteOnClose)
+ box = QtWidgets.QMessageBox(parent)
+ box.setAttribute(QtCore.Qt.WA_DeleteOnClose)
box.setIcon(icon)
box.setStandardButtons(buttons)
if on_finished is not None:
box.finished.connect(on_finished)
if plain_text:
- box.setTextFormat(Qt.PlainText)
+ box.setTextFormat(QtCore.Qt.PlainText)
elif plain_text is not None:
- box.setTextFormat(Qt.RichText)
+ box.setTextFormat(QtCore.Qt.RichText)
box.setWindowTitle(title)
box.setText(text)
box.show()
@@ -81,4 +80,4 @@ def information(*args, **kwargs):
Return:
A new QMessageBox.
"""
- return msgbox(*args, icon=QMessageBox.Information, **kwargs)
+ return msgbox(*args, icon=QtWidgets.QMessageBox.Information, **kwargs)
diff --git a/qutebrowser/misc/objects.py b/qutebrowser/misc/objects.py
index 00a1ef35d..c20b547a2 100644
--- a/qutebrowser/misc/objects.py
+++ b/qutebrowser/misc/objects.py
@@ -26,7 +26,7 @@ import argparse
from typing import TYPE_CHECKING, Any, Dict, Set, Union, cast
if TYPE_CHECKING:
- from PyQt5.QtWidgets import QApplication
+ from qutebrowser.qt import QtWidgets, QApplication
from qutebrowser.utils import usertypes
from qutebrowser.commands import command
diff --git a/qutebrowser/misc/pastebin.py b/qutebrowser/misc/pastebin.py
index a4e0a196f..f24af9ead 100644
--- a/qutebrowser/misc/pastebin.py
+++ b/qutebrowser/misc/pastebin.py
@@ -20,11 +20,10 @@
"""Client for the pastebin."""
import urllib.parse
+from qutebrowser.qt import QtCore
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl
-
-class PastebinClient(QObject):
+class PastebinClient(QtCore.QObject):
"""A client for Stikked pastebins using HTTPClient.
@@ -43,8 +42,8 @@ class PastebinClient(QObject):
API_URL = 'https://crashes.qutebrowser.org/api/'
MISC_API_URL = 'https://paste.the-compiler.org/api/'
- success = pyqtSignal(str)
- error = pyqtSignal(str)
+ success = QtCore.pyqtSignal(str)
+ error = QtCore.pyqtSignal(str)
def __init__(self, client, parent=None, api_url=API_URL):
"""Constructor.
@@ -81,10 +80,10 @@ class PastebinClient(QObject):
if private:
data['private'] = '1'
- url = QUrl(urllib.parse.urljoin(self._api_url, 'create'))
+ url = QtCore.QUrl(urllib.parse.urljoin(self._api_url, 'create'))
self._client.post(url, data)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def on_client_success(self, data):
"""Process the data and finish when the client finished.
diff --git a/qutebrowser/misc/quitter.py b/qutebrowser/misc/quitter.py
index 905429989..2eb7a7a36 100644
--- a/qutebrowser/misc/quitter.py
+++ b/qutebrowser/misc/quitter.py
@@ -30,8 +30,6 @@ import tokenize
import functools
import subprocess
from typing import Iterable, Mapping, MutableSequence, Sequence, cast
-
-from PyQt5.QtCore import QObject, pyqtSignal, QTimer
try:
import hunter
except ImportError:
@@ -43,12 +41,13 @@ from qutebrowser.utils import log
from qutebrowser.misc import sessions, ipc, objects
from qutebrowser.mainwindow import prompt
from qutebrowser.completion.models import miscmodels
+from qutebrowser.qt import QtCore
instance = cast('Quitter', None)
-class Quitter(QObject):
+class Quitter(QtCore.QObject):
"""Utility class to quit/restart the QApplication.
@@ -58,11 +57,11 @@ class Quitter(QObject):
_args: The argparse namespace.
"""
- shutting_down = pyqtSignal() # Emitted immediately before shut down
+ shutting_down = QtCore.pyqtSignal() # Emitted immediately before shut down
def __init__(self, *,
args: argparse.Namespace,
- parent: QObject = None) -> None:
+ parent: QtCore.QObject = None) -> None:
super().__init__(parent)
self.quit_status = {
'crash': True,
@@ -230,7 +229,7 @@ class Quitter(QObject):
# in the real main event loop, or we'll get a segfault.
log.destroy.debug("Deferring real shutdown because question was "
"active.")
- QTimer.singleShot(0, functools.partial(self._shutdown_2, status,
+ QtCore.QTimer.singleShot(0, functools.partial(self._shutdown_2, status,
is_restart=is_restart))
else:
# If we have no questions to shut down, we are already in the real
@@ -254,7 +253,7 @@ class Quitter(QObject):
log.destroy.debug("Deferring QApplication::exit...")
# We use a singleshot timer to exit here to minimize the likelihood of
# segfaults.
- QTimer.singleShot(0, functools.partial(self._shutdown_3, status))
+ QtCore.QTimer.singleShot(0, functools.partial(self._shutdown_3, status))
def _shutdown_3(self, status: int) -> None:
"""Finally shut down the QApplication."""
diff --git a/qutebrowser/misc/savemanager.py b/qutebrowser/misc/savemanager.py
index 1b72734cb..920ee4982 100644
--- a/qutebrowser/misc/savemanager.py
+++ b/qutebrowser/misc/savemanager.py
@@ -23,12 +23,11 @@ import os.path
import collections
from typing import MutableMapping
-from PyQt5.QtCore import pyqtSlot, QObject, QTimer
-
from qutebrowser.config import config
from qutebrowser.api import cmdutils
from qutebrowser.utils import utils, log, message, usertypes, error
from qutebrowser.misc import objects
+from qutebrowser.qt import QtCore
class Saveable:
@@ -101,7 +100,7 @@ class Saveable:
self._dirty = False
-class SaveManager(QObject):
+class SaveManager(QtCore.QObject):
"""Responsible to save 'saveables' periodically and on exit.
@@ -150,7 +149,7 @@ class SaveManager(QObject):
self.saveables[name] = saveable
if dirty:
saveable.mark_dirty()
- QTimer.singleShot(0, saveable.save)
+ QtCore.QTimer.singleShot(0, saveable.save)
def save(self, name, is_exit=False, explicit=False, silent=False,
force=False):
@@ -172,7 +171,7 @@ class SaveManager(QObject):
for saveable in self.saveables:
self.save(saveable, *args, **kwargs)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def autosave(self):
"""Slot used when the configs are auto-saved."""
for (key, saveable) in self.saveables.items():
@@ -205,7 +204,7 @@ class SaveManager(QObject):
message.error("Could not save {}: {}".format(key, e))
log.save.debug(":save saved {}".format(', '.join(what)))
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def shutdown(self):
"""Save all saveables when shutting down."""
for key in self.saveables:
diff --git a/qutebrowser/misc/sessions.py b/qutebrowser/misc/sessions.py
index a28f3a848..0a07a0cd3 100644
--- a/qutebrowser/misc/sessions.py
+++ b/qutebrowser/misc/sessions.py
@@ -26,8 +26,6 @@ import urllib
import shutil
import pathlib
from typing import Any, Iterable, MutableMapping, MutableSequence, Optional, Union, cast
-
-from PyQt5.QtCore import Qt, QUrl, QObject, QPoint, QTimer, QDateTime
import yaml
from qutebrowser.utils import (standarddir, objreg, qtutils, log, message,
@@ -36,7 +34,7 @@ from qutebrowser.api import cmdutils
from qutebrowser.config import config, configfiles
from qutebrowser.completion.models import miscmodels
from qutebrowser.mainwindow import mainwindow
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
from qutebrowser.misc import objects, throttle
@@ -141,7 +139,7 @@ class TabHistoryItem:
last_visited=self.last_visited)
-class SessionManager(QObject):
+class SessionManager(QtCore.QObject):
"""Manager for sessions.
@@ -225,7 +223,7 @@ class SessionManager(QObject):
# QtWebEngine
user_data = None
- data['last_visited'] = item.lastVisited().toString(Qt.ISODate)
+ data['last_visited'] = item.lastVisited().toString(QtCore.Qt.ISODate)
if tab.history.current_idx() == idx:
pos = tab.scroller.pos_px()
@@ -409,10 +407,10 @@ class SessionManager(QObject):
# of per-tab earlier.
# See https://github.com/qutebrowser/qutebrowser/issues/728
pos = data['scroll-pos']
- user_data['scroll-pos'] = QPoint(pos['x'], pos['y'])
+ user_data['scroll-pos'] = QtCore.QPoint(pos['x'], pos['y'])
elif 'scroll-pos' in histentry:
pos = histentry['scroll-pos']
- user_data['scroll-pos'] = QPoint(pos['x'], pos['y'])
+ user_data['scroll-pos'] = QtCore.QPoint(pos['x'], pos['y'])
if 'pinned' in histentry:
new_tab.data.pinned = histentry['pinned']
@@ -432,18 +430,18 @@ class SessionManager(QObject):
histentry['active'] = False
active = histentry.get('active', False)
- url = QUrl.fromEncoded(histentry['url'].encode('ascii'))
+ url = QtCore.QUrl.fromEncoded(histentry['url'].encode('ascii'))
if 'original-url' in histentry:
- orig_url = QUrl.fromEncoded(
+ orig_url = QtCore.QUrl.fromEncoded(
histentry['original-url'].encode('ascii'))
else:
orig_url = url
if histentry.get("last_visited"):
- last_visited: Optional[QDateTime] = QDateTime.fromString(
+ last_visited: Optional[QtCore.QDateTime] = QtCore.QDateTime.fromString(
histentry.get("last_visited"),
- Qt.ISODate,
+ QtCore.Qt.ISODate,
)
else:
last_visited = None
@@ -479,7 +477,7 @@ class SessionManager(QObject):
if tab_to_focus is not None:
tabbed_browser.widget.setCurrentIndex(tab_to_focus)
if win.get('active', False):
- QTimer.singleShot(0, tabbed_browser.widget.activateWindow)
+ QtCore.QTimer.singleShot(0, tabbed_browser.widget.activateWindow)
def load(self, name, temp=False):
"""Load a named session.
diff --git a/qutebrowser/misc/sql.py b/qutebrowser/misc/sql.py
index 8f3282a2f..03de94a33 100644
--- a/qutebrowser/misc/sql.py
+++ b/qutebrowser/misc/sql.py
@@ -25,10 +25,7 @@ import dataclasses
import types
from typing import Any, Dict, Iterator, List, Mapping, MutableSequence, Optional, Type
-from PyQt5.QtCore import QObject, pyqtSignal
-from PyQt5.QtSql import QSqlDatabase, QSqlError, QSqlQuery
-
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtSql, QtCore, sip
from qutebrowser.utils import debug, log
@@ -93,7 +90,7 @@ class Error(Exception):
"""Base class for all SQL related errors."""
- def __init__(self, msg: str, error: Optional[QSqlError] = None) -> None:
+ def __init__(self, msg: str, error: Optional[QtSql.QSqlError] = None) -> None:
super().__init__(msg)
self.error = error
@@ -125,14 +122,14 @@ class BugError(Error):
"""
-def raise_sqlite_error(msg: str, error: QSqlError) -> None:
+def raise_sqlite_error(msg: str, error: QtSql.QSqlError) -> None:
"""Raise either a BugError or KnownError."""
error_code = error.nativeErrorCode()
database_text = error.databaseText()
driver_text = error.driverText()
log.sql.debug("SQL error:")
- log.sql.debug(f"type: {debug.qenum_key(QSqlError, error.type())}")
+ log.sql.debug(f"type: {debug.qenum_key(QtSql.QSqlError, error.type())}")
log.sql.debug(f"database text: {database_text}")
log.sql.debug(f"driver text: {driver_text}")
log.sql.debug(f"error code: {error_code}")
@@ -169,11 +166,11 @@ class Database:
_USER_VERSION = UserVersion(0, 4) # The current / newest user version
def __init__(self, path: str) -> None:
- if QSqlDatabase.database(path).isValid():
+ if QtSql.QSqlDatabase.database(path).isValid():
raise BugError(f'A connection to the database at "{path}" already exists')
self._path = path
- database = QSqlDatabase.addDatabase('QSQLITE', path)
+ database = QtSql.QSqlDatabase.addDatabase('QSQLITE', path)
if not database.isValid():
raise KnownError('Failed to add database. Are sqlite and Qt sqlite '
'support installed?')
@@ -200,9 +197,9 @@ class Database:
self.query("PRAGMA journal_mode=WAL").run()
self.query("PRAGMA synchronous=NORMAL").run()
- def qt_database(self) -> QSqlDatabase:
+ def qt_database(self) -> QtSql.QSqlDatabase:
"""Return the wrapped QSqlDatabase instance."""
- database = QSqlDatabase.database(self._path, open=True)
+ database = QtSql.QSqlDatabase.database(self._path, open=True)
if not database.isValid():
raise BugError('Failed to get connection. Did you close() this Database '
'instance?')
@@ -214,7 +211,7 @@ class Database:
def table(self, name: str, fields: List[str],
constraints: Optional[Dict[str, str]] = None,
- parent: Optional[QObject] = None) -> 'SqlTable':
+ parent: Optional[QtCore.QObject] = None) -> 'SqlTable':
"""Return a SqlTable instance linked to this Database."""
return SqlTable(self, name, fields, constraints, parent)
@@ -238,7 +235,7 @@ class Database:
database = self.qt_database()
database.close()
sip.delete(database)
- QSqlDatabase.removeDatabase(self._path)
+ QtSql.QSqlDatabase.removeDatabase(self._path)
def transaction(self) -> 'Transaction':
"""Return a Transaction object linked to this Database."""
@@ -293,7 +290,7 @@ class Query:
Must be false for completion queries.
"""
self._database = database
- self.query = QSqlQuery(database.qt_database())
+ self.query = QtSql.QSqlQuery(database.qt_database())
log.sql.vdebug(f'Preparing: {querystr}') # type: ignore[attr-defined]
ok = self.query.prepare(querystr)
@@ -381,7 +378,7 @@ class Query:
return self.query.boundValues()
-class SqlTable(QObject):
+class SqlTable(QtCore.QObject):
"""Interface to a SQL table.
@@ -393,12 +390,12 @@ class SqlTable(QObject):
changed: Emitted when the table is modified.
"""
- changed = pyqtSignal()
+ changed = QtCore.pyqtSignal()
database: Database
def __init__(self, database: Database, name: str, fields: List[str],
constraints: Optional[Dict[str, str]] = None,
- parent: Optional[QObject] = None) -> None:
+ parent: Optional[QtCore.QObject] = None) -> None:
"""Wrapper over a table in the SQL database.
Args:
diff --git a/qutebrowser/misc/throttle.py b/qutebrowser/misc/throttle.py
index ac565b68d..567951878 100644
--- a/qutebrowser/misc/throttle.py
+++ b/qutebrowser/misc/throttle.py
@@ -23,7 +23,7 @@ import dataclasses
import time
from typing import Any, Callable, Mapping, Optional, Sequence
-from PyQt5.QtCore import QObject
+from qutebrowser.qt import QtCore
from qutebrowser.utils import usertypes
@@ -35,7 +35,7 @@ class _CallArgs:
kwargs: Mapping[str, Any]
-class Throttle(QObject):
+class Throttle(QtCore.QObject):
"""A throttle to throttle calls.
@@ -47,7 +47,7 @@ class Throttle(QObject):
def __init__(self,
func: Callable[..., None],
delay_ms: int,
- parent: QObject = None) -> None:
+ parent: QtCore.QObject = None) -> None:
"""Constructor.
Args:
diff --git a/qutebrowser/misc/utilcmds.py b/qutebrowser/misc/utilcmds.py
index 14c02864e..d57c71d41 100644
--- a/qutebrowser/misc/utilcmds.py
+++ b/qutebrowser/misc/utilcmds.py
@@ -27,8 +27,7 @@ import sys
import traceback
from typing import Optional
-from PyQt5.QtCore import QUrl
-from PyQt5.QtWidgets import QApplication
+from qutebrowser.qt import QtWidgets, QtCore
from qutebrowser.browser import qutescheme
from qutebrowser.utils import log, objreg, usertypes, message, debug, utils
@@ -55,7 +54,7 @@ def later(duration: str, command: str, win_id: int) -> None:
except ValueError as e:
raise cmdutils.CommandError(e)
commandrunner = runners.CommandRunner(win_id)
- timer = usertypes.Timer(name='later', parent=QApplication.instance())
+ timer = usertypes.Timer(name='later', parent=QtWidgets.QApplication.instance())
try:
timer.setSingleShot(True)
try:
@@ -183,7 +182,7 @@ def debug_pyeval(s: str, file: bool = False, quiet: bool = False) -> None:
else:
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window='last-focused')
- tabbed_browser.load_url(QUrl('qute://pyeval'), newtab=True)
+ tabbed_browser.load_url(QtCore.QUrl('qute://pyeval'), newtab=True)
@cmdutils.register(debug=True)
@@ -273,7 +272,7 @@ def version(win_id: int, paste: bool = False) -> None:
"""
tabbed_browser = objreg.get('tabbed-browser', scope='window',
window=win_id)
- tabbed_browser.load_url(QUrl('qute://version/'), newtab=True)
+ tabbed_browser.load_url(QtCore.QUrl('qute://version/'), newtab=True)
if paste:
pastebin_version()
diff --git a/qutebrowser/utils/debug.py b/qutebrowser/utils/debug.py
index 0fa74f4e7..b52220730 100644
--- a/qutebrowser/utils/debug.py
+++ b/qutebrowser/utils/debug.py
@@ -28,34 +28,32 @@ import types
from typing import (
Any, Callable, List, Mapping, MutableSequence, Optional, Sequence, Type, Union)
-from PyQt5.QtCore import Qt, QEvent, QMetaMethod, QObject, pyqtBoundSignal
-
from qutebrowser.utils import log, utils, qtutils, objreg
from qutebrowser.misc import objects
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
-def log_events(klass: Type[QObject]) -> Type[QObject]:
+def log_events(klass: Type[QtCore.QObject]) -> Type[QtCore.QObject]:
"""Class decorator to log Qt events."""
old_event = klass.event
@functools.wraps(old_event)
- def new_event(self: Any, e: QEvent) -> bool:
+ def new_event(self: Any, e: QtCore.QEvent) -> bool:
"""Wrapper for event() which logs events."""
log.misc.debug("Event in {}: {}".format(utils.qualname(klass),
- qenum_key(QEvent, e.type())))
+ qenum_key(QtCore.QEvent, e.type())))
return old_event(self, e)
klass.event = new_event # type: ignore[assignment]
return klass
-def log_signals(obj: QObject) -> QObject:
+def log_signals(obj: QtCore.QObject) -> QtCore.QObject:
"""Log all signals of an object or class.
Can be used as class decorator.
"""
- def log_slot(obj: QObject, signal: pyqtBoundSignal, *args: Any) -> None:
+ def log_slot(obj: QtCore.QObject, signal: QtCore.pyqtBoundSignal, *args: Any) -> None:
"""Slot connected to a signal to log it."""
dbg = dbg_signal(signal, args)
try:
@@ -64,13 +62,13 @@ def log_signals(obj: QObject) -> QObject:
r = '<deleted>'
log.signals.debug("Signal in {}: {}".format(r, dbg))
- def connect_log_slot(obj: QObject) -> None:
+ def connect_log_slot(obj: QtCore.QObject) -> None:
"""Helper function to connect all signals to a logging slot."""
metaobj = obj.metaObject()
for i in range(metaobj.methodCount()):
meta_method = metaobj.method(i)
qtutils.ensure_valid(meta_method)
- if meta_method.methodType() == QMetaMethod.Signal:
+ if meta_method.methodType() == QtCore.QMetaMethod.Signal:
name = meta_method.name().data().decode('ascii')
if name != 'destroyed':
signal = getattr(obj, name)
@@ -191,7 +189,7 @@ def qflags_key(base: Type[_EnumValueType],
return '|'.join(names)
-def signal_name(sig: pyqtBoundSignal) -> str:
+def signal_name(sig: QtCore.pyqtBoundSignal) -> str:
"""Get a cleaned up name of a signal.
Unfortunately, the way to get the name of a signal differs based on
@@ -236,7 +234,7 @@ def format_args(args: Sequence[Any] = None, kwargs: Mapping[str, Any] = None) ->
return ', '.join(arglist)
-def dbg_signal(sig: pyqtBoundSignal, args: Any) -> str:
+def dbg_signal(sig: QtCore.pyqtBoundSignal, args: Any) -> str:
"""Get a string representation of a signal for debugging.
Args:
@@ -324,15 +322,15 @@ def _get_widgets() -> Sequence[str]:
def _get_pyqt_objects(lines: MutableSequence[str],
- obj: QObject,
+ obj: QtCore.QObject,
depth: int = 0) -> None:
"""Recursive method for get_all_objects to get Qt objects."""
- for kid in obj.findChildren(QObject, '', Qt.FindDirectChildrenOnly):
+ for kid in obj.findChildren(QtCore.QObject, '', QtCore.Qt.FindDirectChildrenOnly):
lines.append(' ' * depth + repr(kid))
_get_pyqt_objects(lines, kid, depth + 1)
-def get_all_objects(start_obj: QObject = None) -> str:
+def get_all_objects(start_obj: QtCore.QObject = None) -> str:
"""Get all children of an object recursively as a string."""
output = ['']
widget_lines = _get_widgets()
diff --git a/qutebrowser/utils/error.py b/qutebrowser/utils/error.py
index a5889f977..dcb401a7f 100644
--- a/qutebrowser/utils/error.py
+++ b/qutebrowser/utils/error.py
@@ -19,7 +19,7 @@
"""Tools related to error printing/displaying."""
-from PyQt5.QtWidgets import QMessageBox
+from qutebrowser.qt import QtWidgets
from qutebrowser.utils import log, utils
@@ -70,5 +70,5 @@ def handle_fatal_exc(exc: BaseException,
msg_text = str(exc)
if post_text:
msg_text += '\n\n{}'.format(post_text)
- msgbox = QMessageBox(QMessageBox.Critical, title, msg_text)
+ msgbox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, title, msg_text)
msgbox.exec()
diff --git a/qutebrowser/utils/jinja.py b/qutebrowser/utils/jinja.py
index a44a0235e..8d1d8ae64 100644
--- a/qutebrowser/utils/jinja.py
+++ b/qutebrowser/utils/jinja.py
@@ -29,7 +29,7 @@ from typing import Any, Callable, FrozenSet, Iterator, List, Set, Tuple
import jinja2
import jinja2.nodes
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.utils import utils, urlutils, log, qtutils, resources
from qutebrowser.misc import debugcachestats
@@ -111,10 +111,10 @@ class Environment(jinja2.Environment):
path: The relative path to the resource.
"""
assert not posixpath.isabs(path), path
- url = QUrl('qute://resource')
+ url = QtCore.QUrl('qute://resource')
url.setPath('/' + path)
urlutils.ensure_valid(url)
- urlstr = url.toString(QUrl.FullyEncoded) # type: ignore[arg-type]
+ urlstr = url.toString(QtCore.QUrl.FullyEncoded) # type: ignore[arg-type]
return urlstr
def _data_url(self, path: str) -> str:
diff --git a/qutebrowser/utils/log.py b/qutebrowser/utils/log.py
index 22035e074..dd11e3fb1 100644
--- a/qutebrowser/utils/log.py
+++ b/qutebrowser/utils/log.py
@@ -36,6 +36,8 @@ from typing import (TYPE_CHECKING, Any, Iterator, Mapping, MutableSequence,
Optional, Set, Tuple, Union)
from PyQt5 import QtCore
+from qutebrowser.qt import QtCore
+
# Optional imports
try:
import colorama
diff --git a/qutebrowser/utils/message.py b/qutebrowser/utils/message.py
index c490aa4e8..5a3e4ba00 100644
--- a/qutebrowser/utils/message.py
+++ b/qutebrowser/utils/message.py
@@ -26,9 +26,8 @@
import traceback
from typing import Any, Callable, Iterable, List, Tuple, Union, Optional
-from PyQt5.QtCore import pyqtSignal, pyqtBoundSignal, QObject
-
from qutebrowser.utils import usertypes, log
+from qutebrowser.qt import QtCore
def _log_stack(typ: str, stack: str) -> None:
@@ -88,7 +87,7 @@ def _build_question(title: str,
text: str = None, *,
mode: usertypes.PromptMode,
default: Union[None, bool, str] = None,
- abort_on: Iterable[pyqtBoundSignal] = (),
+ abort_on: Iterable[QtCore.pyqtBoundSignal] = (),
url: str = None,
option: bool = None) -> usertypes.Question:
"""Common function for ask/ask_async."""
@@ -187,7 +186,7 @@ def confirm_async(*, yes_action: _ActionType,
return question
-class GlobalMessageBridge(QObject):
+class GlobalMessageBridge(QtCore.QObject):
"""Global (not per-window) message bridge for errors/infos/warnings.
@@ -210,13 +209,13 @@ class GlobalMessageBridge(QObject):
mode_left: Emitted when a keymode was left in any window.
"""
- show_message = pyqtSignal(usertypes.MessageLevel, str, str)
- prompt_done = pyqtSignal(usertypes.KeyMode)
- ask_question = pyqtSignal(usertypes.Question, bool)
- mode_left = pyqtSignal(usertypes.KeyMode)
- clear_messages = pyqtSignal()
+ show_message = QtCore.pyqtSignal(usertypes.MessageLevel, str, str)
+ prompt_done = QtCore.pyqtSignal(usertypes.KeyMode)
+ ask_question = QtCore.pyqtSignal(usertypes.Question, bool)
+ mode_left = QtCore.pyqtSignal(usertypes.KeyMode)
+ clear_messages = QtCore.pyqtSignal()
- def __init__(self, parent: QObject = None) -> None:
+ def __init__(self, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
self._connected = False
self._cache: List[Tuple[usertypes.MessageLevel, str, Optional[str]]] = []
diff --git a/qutebrowser/utils/objreg.py b/qutebrowser/utils/objreg.py
index 0819a5d0a..9f794a5e8 100644
--- a/qutebrowser/utils/objreg.py
+++ b/qutebrowser/utils/objreg.py
@@ -24,12 +24,11 @@ import collections
import functools
from typing import (TYPE_CHECKING, Any, Callable, MutableMapping, MutableSequence,
Optional, Sequence, Union)
-
-from PyQt5.QtCore import QObject, QTimer
-from PyQt5.QtWidgets import QApplication
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt import QtWidgets
from qutebrowser.utils import log, usertypes, utils
+from qutebrowser.qt import QtCore
+
if TYPE_CHECKING:
from qutebrowser.mainwindow import mainwindow
@@ -85,7 +84,7 @@ class ObjectRegistry(collections.UserDict): # type: ignore[type-arg]
self._disconnect_destroyed(name)
- if isinstance(obj, QObject):
+ if isinstance(obj, QtCore.QObject):
func = functools.partial(self.on_destroyed, name)
obj.destroyed.connect(func)
self._partial_objs[name] = func
@@ -124,7 +123,7 @@ class ObjectRegistry(collections.UserDict): # type: ignore[type-arg]
registry.
"""
log.destroy.debug("schedule removal: {}".format(name))
- QTimer.singleShot(0, functools.partial(self._on_destroyed, name))
+ QtCore.QTimer.singleShot(0, functools.partial(self._on_destroyed, name))
def _on_destroyed(self, name: str) -> None:
"""Remove a destroyed QObject."""
@@ -167,7 +166,7 @@ def _get_tab_registry(win_id: _WindowTab,
if tab_id is None:
raise ValueError("Got tab_id None (win_id {})".format(win_id))
if tab_id == 'current' and win_id is None:
- window: Optional[QWidget] = QApplication.activeWindow()
+ window: Optional[QtWidgets.QWidget] = QtWidgets.QApplication.activeWindow()
if window is None or not hasattr(window, 'win_id'):
raise RegistryUnavailableError('tab')
win_id = window.win_id
@@ -193,7 +192,7 @@ def _get_window_registry(window: _WindowTab) -> ObjectRegistry:
raise TypeError("window is None with scope window!")
try:
if window == 'current':
- win: Optional[QWidget] = QApplication.activeWindow()
+ win: Optional[QtWidgets.QWidget] = QtWidgets.QApplication.activeWindow()
elif window == 'last-focused':
win = last_focused_window()
else:
diff --git a/qutebrowser/utils/qtutils.py b/qutebrowser/utils/qtutils.py
index ff8983c50..8c0f8a6be 100644
--- a/qutebrowser/utils/qtutils.py
+++ b/qutebrowser/utils/qtutils.py
@@ -33,21 +33,18 @@ import operator
import contextlib
from typing import (Any, AnyStr, TYPE_CHECKING, BinaryIO, IO, Iterator,
Optional, Union, Tuple, cast)
-
-from PyQt5.QtCore import (qVersion, QEventLoop, QDataStream, QByteArray,
- QIODevice, QFileDevice, QSaveFile, QT_VERSION_STR,
- PYQT_VERSION_STR, QObject, QUrl)
-from PyQt5.QtGui import QColor
+from qutebrowser.qt import QtWebKit, QtWebEngineWidgets, QtGui
try:
- from PyQt5.QtWebKit import qWebKitVersion
+ pass
except ImportError: # pragma: no cover
qWebKitVersion = None # type: ignore[assignment] # noqa: N816
if TYPE_CHECKING:
- from PyQt5.QtWebKit import QWebHistory
- from PyQt5.QtWebEngineWidgets import QWebEngineHistory
+ from qutebrowser.qt import QWebHistory
+ from qutebrowser.qt import QWebEngineHistory
from qutebrowser.misc import objects
from qutebrowser.utils import usertypes, utils
+from qutebrowser.qt import QtCore
MAXVALS = {
@@ -69,17 +66,17 @@ class QtOSError(OSError):
qt_errno: The error attribute of the given QFileDevice, if applicable.
"""
- def __init__(self, dev: QIODevice, msg: str = None) -> None:
+ def __init__(self, dev: QtCore.QIODevice, msg: str = None) -> None:
if msg is None:
msg = dev.errorString()
- self.qt_errno: Optional[QFileDevice.FileError] = None
- if isinstance(dev, QFileDevice):
+ self.qt_errno: Optional[QtCore.QFileDevice.FileError] = None
+ if isinstance(dev, QtCore.QFileDevice):
msg = self._init_filedev(dev, msg)
super().__init__(msg)
- def _init_filedev(self, dev: QFileDevice, msg: str) -> str:
+ def _init_filedev(self, dev: QtCore.QFileDevice, msg: str) -> str:
self.qt_errno = dev.error()
filename = dev.fileName()
msg += ": {!r}".format(filename)
@@ -101,13 +98,13 @@ def version_check(version: str,
parsed = utils.VersionNumber.parse(version)
op = operator.eq if exact else operator.ge
- result = op(utils.VersionNumber.parse(qVersion()), parsed)
+ result = op(utils.VersionNumber.parse(QtCore.qVersion()), parsed)
if compiled and result:
# qVersion() ==/>= parsed, now check if QT_VERSION_STR ==/>= parsed.
- result = op(utils.VersionNumber.parse(QT_VERSION_STR), parsed)
+ result = op(utils.VersionNumber.parse(QtCore.QT_VERSION_STR), parsed)
if compiled and result:
# Finally, check PYQT_VERSION_STR as well.
- result = op(utils.VersionNumber.parse(PYQT_VERSION_STR), parsed)
+ result = op(utils.VersionNumber.parse(QtCore.PYQT_VERSION_STR), parsed)
return result
@@ -116,8 +113,8 @@ MAX_WORLD_ID = 256
def is_new_qtwebkit() -> bool:
"""Check if the given version is a new QtWebKit."""
- assert qWebKitVersion is not None
- return (utils.VersionNumber.parse(qWebKitVersion()) >
+ assert QtWebKit.qWebKitVersion is not None
+ return (utils.VersionNumber.parse(QtWebKit.qWebKitVersion()) >
utils.VersionNumber.parse('538.1'))
@@ -170,44 +167,44 @@ def ensure_valid(obj: Validatable) -> None:
raise QtValueError(obj)
-def check_qdatastream(stream: QDataStream) -> None:
+def check_qdatastream(stream: QtCore.QDataStream) -> None:
"""Check the status of a QDataStream and raise OSError if it's not ok."""
status_to_str = {
- QDataStream.Ok: "The data stream is operating normally.",
- QDataStream.ReadPastEnd: ("The data stream has read past the end of "
+ QtCore.QDataStream.Ok: "The data stream is operating normally.",
+ QtCore.QDataStream.ReadPastEnd: ("The data stream has read past the end of "
"the data in the underlying device."),
- QDataStream.ReadCorruptData: "The data stream has read corrupt data.",
- QDataStream.WriteFailed: ("The data stream cannot write to the "
+ QtCore.QDataStream.ReadCorruptData: "The data stream has read corrupt data.",
+ QtCore.QDataStream.WriteFailed: ("The data stream cannot write to the "
"underlying device."),
}
- if stream.status() != QDataStream.Ok:
+ if stream.status() != QtCore.QDataStream.Ok:
raise OSError(status_to_str[stream.status()])
_QtSerializableType = Union[
- QObject,
- QByteArray,
- QUrl,
+ QtCore.QObject,
+ QtCore.QByteArray,
+ QtCore.QUrl,
'QWebEngineHistory',
'QWebHistory'
]
-def serialize(obj: _QtSerializableType) -> QByteArray:
+def serialize(obj: _QtSerializableType) -> QtCore.QByteArray:
"""Serialize an object into a QByteArray."""
- data = QByteArray()
- stream = QDataStream(data, QIODevice.WriteOnly)
+ data = QtCore.QByteArray()
+ stream = QtCore.QDataStream(data, QtCore.QIODevice.WriteOnly)
serialize_stream(stream, obj)
return data
-def deserialize(data: QByteArray, obj: _QtSerializableType) -> None:
+def deserialize(data: QtCore.QByteArray, obj: _QtSerializableType) -> None:
"""Deserialize an object from a QByteArray."""
- stream = QDataStream(data, QIODevice.ReadOnly)
+ stream = QtCore.QDataStream(data, QtCore.QIODevice.ReadOnly)
deserialize_stream(stream, obj)
-def serialize_stream(stream: QDataStream, obj: _QtSerializableType) -> None:
+def serialize_stream(stream: QtCore.QDataStream, obj: _QtSerializableType) -> None:
"""Serialize an object into a QDataStream."""
# pylint: disable=pointless-statement
check_qdatastream(stream)
@@ -215,7 +212,7 @@ def serialize_stream(stream: QDataStream, obj: _QtSerializableType) -> None:
check_qdatastream(stream)
-def deserialize_stream(stream: QDataStream, obj: _QtSerializableType) -> None:
+def deserialize_stream(stream: QtCore.QDataStream, obj: _QtSerializableType) -> None:
"""Deserialize a QDataStream into an object."""
# pylint: disable=pointless-statement
check_qdatastream(stream)
@@ -230,10 +227,10 @@ def savefile_open(
encoding: str = 'utf-8'
) -> Iterator[IO[AnyStr]]:
"""Context manager to easily use a QSaveFile."""
- f = QSaveFile(filename)
+ f = QtCore.QSaveFile(filename)
cancelled = False
try:
- open_ok = f.open(QIODevice.WriteOnly)
+ open_ok = f.open(QtCore.QIODevice.WriteOnly)
if not open_ok:
raise QtOSError(f)
@@ -257,7 +254,7 @@ def savefile_open(
raise QtOSError(f, msg="Commit failed!")
-def qcolor_to_qsscolor(c: QColor) -> str:
+def qcolor_to_qsscolor(c: QtGui.QColor) -> str:
"""Convert a QColor to a string that can be used in a QStyleSheet."""
ensure_valid(c)
return "rgba({}, {}, {}, {})".format(
@@ -272,7 +269,7 @@ class PyQIODevice(io.BufferedIOBase):
dev: The underlying QIODevice.
"""
- def __init__(self, dev: QIODevice) -> None:
+ def __init__(self, dev: QtCore.QIODevice) -> None:
super().__init__()
self.dev = dev
@@ -302,7 +299,7 @@ class PyQIODevice(io.BufferedIOBase):
# contextlib.closing is only generic in Python 3.9+
def open(
self,
- mode: QIODevice.OpenMode,
+ mode: QtCore.QIODevice.OpenMode,
) -> contextlib.closing: # type: ignore[type-arg]
"""Open the underlying device and ensure opening succeeded.
@@ -373,7 +370,7 @@ class PyQIODevice(io.BufferedIOBase):
else:
qt_size = size + 1 # Qt also counts the NUL byte
- buf: Union[QByteArray, bytes, None] = None
+ buf: Union[QtCore.QByteArray, bytes, None] = None
if self.dev.canReadLine():
buf = self.dev.readLine(qt_size)
elif size is None or size < 0:
@@ -384,7 +381,7 @@ class PyQIODevice(io.BufferedIOBase):
if buf is None:
raise QtOSError(self.dev)
- if isinstance(buf, QByteArray):
+ if isinstance(buf, QtCore.QByteArray):
# The type (bytes or QByteArray) seems to depend on what data we
# feed in...
buf = buf.data()
@@ -417,7 +414,7 @@ class PyQIODevice(io.BufferedIOBase):
self._check_open()
self._check_readable()
- buf: Union[QByteArray, bytes, None] = None
+ buf: Union[QtCore.QByteArray, bytes, None] = None
if size in [None, -1]:
buf = self.dev.readAll()
else:
@@ -427,7 +424,7 @@ class PyQIODevice(io.BufferedIOBase):
if buf is None:
raise QtOSError(self.dev)
- if isinstance(buf, QByteArray):
+ if isinstance(buf, QtCore.QByteArray):
# The type (bytes or QByteArray) seems to depend on what data we
# feed in...
buf = buf.data()
@@ -450,21 +447,21 @@ class QtValueError(ValueError):
super().__init__(err)
-class EventLoop(QEventLoop):
+class EventLoop(QtCore.QEventLoop):
"""A thin wrapper around QEventLoop.
Raises an exception when doing exec() multiple times.
"""
- def __init__(self, parent: QObject = None) -> None:
+ def __init__(self, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
self._executing = False
def exec(
self,
- flags: QEventLoop.ProcessEventsFlags =
- cast(QEventLoop.ProcessEventsFlags, QEventLoop.AllEvents)
+ flags: QtCore.QEventLoop.ProcessEventsFlags =
+ cast(QtCore.QEventLoop.ProcessEventsFlags, QtCore.QEventLoop.AllEvents)
) -> int:
"""Override exec_ to raise an exception when re-running."""
if self._executing:
@@ -500,11 +497,11 @@ def _get_color_percentage(x1: int, y1: int, z1: int, a1: int,
def interpolate_color(
- start: QColor,
- end: QColor,
+ start: QtGui.QColor,
+ end: QtGui.QColor,
percent: int,
- colorspace: Optional[QColor.Spec] = QColor.Rgb
-) -> QColor:
+ colorspace: Optional[QtGui.QColor.Spec] = QtGui.QColor.Rgb
+) -> QtGui.QColor:
"""Get an interpolated color value.
Args:
@@ -523,22 +520,22 @@ def interpolate_color(
if colorspace is None:
if percent == 100:
- return QColor(*end.getRgb())
+ return QtGui.QColor(*end.getRgb())
else:
- return QColor(*start.getRgb())
+ return QtGui.QColor(*start.getRgb())
- out = QColor()
- if colorspace == QColor.Rgb:
+ out = QtGui.QColor()
+ if colorspace == QtGui.QColor.Rgb:
r1, g1, b1, a1 = start.getRgb()
r2, g2, b2, a2 = end.getRgb()
components = _get_color_percentage(r1, g1, b1, a1, r2, g2, b2, a2, percent)
out.setRgb(*components)
- elif colorspace == QColor.Hsv:
+ elif colorspace == QtGui.QColor.Hsv:
h1, s1, v1, a1 = start.getHsv()
h2, s2, v2, a2 = end.getHsv()
components = _get_color_percentage(h1, s1, v1, a1, h2, s2, v2, a2, percent)
out.setHsv(*components)
- elif colorspace == QColor.Hsl:
+ elif colorspace == QtGui.QColor.Hsl:
h1, s1, l1, a1 = start.getHsl()
h2, s2, l2, a2 = end.getHsl()
components = _get_color_percentage(h1, s1, l1, a1, h2, s2, l2, a2, percent)
diff --git a/qutebrowser/utils/standarddir.py b/qutebrowser/utils/standarddir.py
index c753e9de6..205e62f3d 100644
--- a/qutebrowser/utils/standarddir.py
+++ b/qutebrowser/utils/standarddir.py
@@ -27,8 +27,7 @@ import enum
import argparse
from typing import Iterator, Optional
-from PyQt5.QtCore import QStandardPaths
-from PyQt5.QtWidgets import QApplication
+from qutebrowser.qt import QtWidgets, QtCore
from qutebrowser.utils import log, debug, utils, version
@@ -64,7 +63,7 @@ def _unset_organization() -> Iterator[None]:
This is primarily needed in config.py.
"""
- qapp = QApplication.instance()
+ qapp = QtWidgets.QApplication.instance()
if qapp is not None:
orgname = qapp.organizationName()
qapp.setOrganizationName(None) # type: ignore[arg-type]
@@ -77,12 +76,12 @@ def _unset_organization() -> Iterator[None]:
def _init_config(args: Optional[argparse.Namespace]) -> None:
"""Initialize the location for configs."""
- typ = QStandardPaths.ConfigLocation
+ typ = QtCore.QStandardPaths.ConfigLocation
path = _from_args(typ, args)
if path is None:
if utils.is_windows:
app_data_path = _writable_location(
- QStandardPaths.AppDataLocation)
+ QtCore.QStandardPaths.AppDataLocation)
path = os.path.join(app_data_path, 'config')
else:
path = _writable_location(typ)
@@ -128,7 +127,7 @@ def config_py() -> str:
def _init_data(args: Optional[argparse.Namespace]) -> None:
"""Initialize the location for data."""
- typ = QStandardPaths.AppDataLocation
+ typ = QtCore.QStandardPaths.AppDataLocation
path = _from_args(typ, args)
if path is None:
if utils.is_windows:
@@ -136,7 +135,7 @@ def _init_data(args: Optional[argparse.Namespace]) -> None:
path = os.path.join(app_data_path, 'data')
elif sys.platform.startswith('haiku'):
# HaikuOS returns an empty value for AppDataLocation
- config_path = _writable_location(QStandardPaths.ConfigLocation)
+ config_path = _writable_location(QtCore.QStandardPaths.ConfigLocation)
path = os.path.join(config_path, 'data')
else:
path = _writable_location(typ)
@@ -169,12 +168,12 @@ def data(system: bool = False) -> str:
def _init_cache(args: Optional[argparse.Namespace]) -> None:
"""Initialize the location for the cache."""
- typ = QStandardPaths.CacheLocation
+ typ = QtCore.QStandardPaths.CacheLocation
path = _from_args(typ, args)
if path is None:
if utils.is_windows:
# Local, not Roaming!
- data_path = _writable_location(QStandardPaths.AppLocalDataLocation)
+ data_path = _writable_location(QtCore.QStandardPaths.AppLocalDataLocation)
path = os.path.join(data_path, 'cache')
else:
path = _writable_location(typ)
@@ -193,7 +192,7 @@ def _init_download(args: Optional[argparse.Namespace]) -> None:
Note this is only the default directory as found by Qt.
Therefore, we also don't create it.
"""
- typ = QStandardPaths.DownloadLocation
+ typ = QtCore.QStandardPaths.DownloadLocation
path = _from_args(typ, args)
if path is None:
path = _writable_location(typ)
@@ -208,9 +207,9 @@ def _init_runtime(args: Optional[argparse.Namespace]) -> None:
"""Initialize location for runtime data."""
if utils.is_mac or utils.is_windows:
# RuntimeLocation is a weird path on macOS and Windows.
- typ = QStandardPaths.TempLocation
+ typ = QtCore.QStandardPaths.TempLocation
else:
- typ = QStandardPaths.RuntimeLocation
+ typ = QtCore.QStandardPaths.RuntimeLocation
path = _from_args(typ, args)
if path is None:
@@ -218,10 +217,10 @@ def _init_runtime(args: Optional[argparse.Namespace]) -> None:
path = _writable_location(typ)
except EmptyValueError:
# Fall back to TempLocation when RuntimeLocation is misconfigured
- if typ == QStandardPaths.TempLocation:
+ if typ == QtCore.QStandardPaths.TempLocation:
raise
path = _writable_location( # pragma: no cover
- QStandardPaths.TempLocation)
+ QtCore.QStandardPaths.TempLocation)
# This is generic, but per-user.
# _writable_location makes sure we have a qutebrowser-specific subdir.
@@ -253,23 +252,23 @@ def runtime() -> str:
return _locations[_Location.runtime]
-def _writable_location(typ: QStandardPaths.StandardLocation) -> str:
+def _writable_location(typ: QtCore.QStandardPaths.StandardLocation) -> str:
"""Wrapper around QStandardPaths.writableLocation.
Arguments:
typ: A QStandardPaths::StandardLocation member.
"""
- typ_str = debug.qenum_key(QStandardPaths, typ)
+ typ_str = debug.qenum_key(QtCore.QStandardPaths, typ)
# Types we are sure we handle correctly below.
assert typ in [
- QStandardPaths.ConfigLocation, QStandardPaths.AppLocalDataLocation,
- QStandardPaths.CacheLocation, QStandardPaths.DownloadLocation,
- QStandardPaths.RuntimeLocation, QStandardPaths.TempLocation,
- QStandardPaths.AppDataLocation], typ_str
+ QtCore.QStandardPaths.ConfigLocation, QtCore.QStandardPaths.AppLocalDataLocation,
+ QtCore.QStandardPaths.CacheLocation, QtCore.QStandardPaths.DownloadLocation,
+ QtCore.QStandardPaths.RuntimeLocation, QtCore.QStandardPaths.TempLocation,
+ QtCore.QStandardPaths.AppDataLocation], typ_str
with _unset_organization():
- path = QStandardPaths.writableLocation(typ)
+ path = QtCore.QStandardPaths.writableLocation(typ)
log.misc.debug("writable location for {}: {}".format(typ_str, path))
if not path:
@@ -281,7 +280,7 @@ def _writable_location(typ: QStandardPaths.StandardLocation) -> str:
# Add the application name to the given path if needed.
# This is in order for this to work without a QApplication (and thus
# QStandardsPaths not knowing the application name).
- if (typ != QStandardPaths.DownloadLocation and
+ if (typ != QtCore.QStandardPaths.DownloadLocation and
path.split(os.sep)[-1] != APPNAME):
path = os.path.join(path, APPNAME)
@@ -289,7 +288,7 @@ def _writable_location(typ: QStandardPaths.StandardLocation) -> str:
def _from_args(
- typ: QStandardPaths.StandardLocation,
+ typ: QtCore.QStandardPaths.StandardLocation,
args: Optional[argparse.Namespace]
) -> Optional[str]:
"""Get the standard directory from an argparse namespace.
@@ -298,12 +297,12 @@ def _from_args(
The overridden path, or None if there is no override.
"""
basedir_suffix = {
- QStandardPaths.ConfigLocation: 'config',
- QStandardPaths.AppDataLocation: 'data',
- QStandardPaths.AppLocalDataLocation: 'data',
- QStandardPaths.CacheLocation: 'cache',
- QStandardPaths.DownloadLocation: 'download',
- QStandardPaths.RuntimeLocation: 'runtime',
+ QtCore.QStandardPaths.ConfigLocation: 'config',
+ QtCore.QStandardPaths.AppDataLocation: 'data',
+ QtCore.QStandardPaths.AppLocalDataLocation: 'data',
+ QtCore.QStandardPaths.CacheLocation: 'cache',
+ QtCore.QStandardPaths.DownloadLocation: 'download',
+ QtCore.QStandardPaths.RuntimeLocation: 'runtime',
}
if getattr(args, 'basedir', None) is None:
diff --git a/qutebrowser/utils/urlmatch.py b/qutebrowser/utils/urlmatch.py
index f14c2083d..f307b91c5 100644
--- a/qutebrowser/utils/urlmatch.py
+++ b/qutebrowser/utils/urlmatch.py
@@ -34,7 +34,7 @@ import fnmatch
import urllib.parse
from typing import Any, Optional, Tuple
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.utils import utils, qtutils
@@ -196,7 +196,7 @@ class UrlPattern:
if parsed.netloc.startswith('['):
# Using QUrl parsing to minimize ipv6 addresses
- url = QUrl()
+ url = QtCore.QUrl()
url.setHost(parsed.hostname)
if not url.isValid():
raise ParseError(url.errorString())
@@ -309,7 +309,7 @@ class UrlPattern:
# doesn't rely on regexes. Do we need that too?
return fnmatch.fnmatchcase(path, self._path)
- def matches(self, qurl: QUrl) -> bool:
+ def matches(self, qurl: QtCore.QUrl) -> bool:
"""Check if the pattern matches the given QUrl."""
qtutils.ensure_valid(qurl)
diff --git a/qutebrowser/utils/urlutils.py b/qutebrowser/utils/urlutils.py
index cfba2c1d8..2a6b55db7 100644
--- a/qutebrowser/utils/urlutils.py
+++ b/qutebrowser/utils/urlutils.py
@@ -28,8 +28,7 @@ import urllib.parse
import mimetypes
from typing import Optional, Tuple, Union, Iterable
-from PyQt5.QtCore import QUrl
-from PyQt5.QtNetwork import QHostInfo, QHostAddress, QNetworkProxy
+from qutebrowser.qt import QtNetwork, QtCore
from qutebrowser.api import cmdutils
from qutebrowser.config import config
@@ -65,7 +64,7 @@ class InvalidUrlError(Error):
"""Error raised if a function got an invalid URL."""
- def __init__(self, url: QUrl) -> None:
+ def __init__(self, url: QtCore.QUrl) -> None:
if url.isValid():
raise ValueError("Got valid URL {}!".format(url.toDisplayString()))
self.url = url
@@ -107,7 +106,7 @@ def _parse_search_term(s: str) -> Tuple[Optional[str], Optional[str]]:
return (engine, term)
-def _get_search_url(txt: str) -> QUrl:
+def _get_search_url(txt: str) -> QtCore.QUrl:
"""Get a search engine URL for a text.
Args:
@@ -128,9 +127,9 @@ def _get_search_url(txt: str) -> QUrl:
unquoted=term,
quoted=quoted_term,
semiquoted=semiquoted_term)
- url = QUrl.fromUserInput(evaluated)
+ url = QtCore.QUrl.fromUserInput(evaluated)
else:
- url = QUrl.fromUserInput(config.val.url.searchengines[engine])
+ url = QtCore.QUrl.fromUserInput(config.val.url.searchengines[engine])
url.setPath(None) # type: ignore[arg-type]
url.setFragment(None) # type: ignore[arg-type]
url.setQuery(None) # type: ignore[call-overload]
@@ -147,7 +146,7 @@ def _is_url_naive(urlstr: str) -> bool:
Return:
True if the URL really is a URL, False otherwise.
"""
- url = QUrl.fromUserInput(urlstr)
+ url = QtCore.QUrl.fromUserInput(urlstr)
assert url.isValid()
host = url.host()
@@ -172,11 +171,11 @@ def _is_url_dns(urlstr: str) -> bool:
Return:
True if the URL really is a URL, False otherwise.
"""
- url = QUrl.fromUserInput(urlstr)
+ url = QtCore.QUrl.fromUserInput(urlstr)
assert url.isValid()
if (utils.raises(ValueError, ipaddress.ip_address, urlstr) and
- not QHostAddress(urlstr).isNull()):
+ not QtNetwork.QHostAddress(urlstr).isNull()):
log.url.debug("Bogus IP URL -> False")
# Qt treats things like "23.42" or "1337" or "0xDEAD" as valid URLs
# which we don't want to.
@@ -187,7 +186,7 @@ def _is_url_dns(urlstr: str) -> bool:
log.url.debug("URL has no host -> False")
return False
log.url.debug("Doing DNS request for {}".format(host))
- info = QHostInfo.fromName(host)
+ info = QtNetwork.QHostInfo.fromName(host)
return not info.error()
@@ -195,7 +194,7 @@ def fuzzy_url(urlstr: str,
cwd: str = None,
relative: bool = False,
do_search: bool = True,
- force_search: bool = False) -> QUrl:
+ force_search: bool = False) -> QtCore.QUrl:
"""Get a QUrl based on a user input which is URL or search term.
Args:
@@ -214,24 +213,24 @@ def fuzzy_url(urlstr: str,
check_exists=True)
if not force_search and path is not None:
- url = QUrl.fromLocalFile(path)
+ url = QtCore.QUrl.fromLocalFile(path)
elif force_search or (do_search and not is_url(urlstr)):
# probably a search term
log.url.debug("URL is a fuzzy search term")
try:
url = _get_search_url(urlstr)
except ValueError: # invalid search engine
- url = QUrl.fromUserInput(urlstr)
+ url = QtCore.QUrl.fromUserInput(urlstr)
else: # probably an address
log.url.debug("URL is a fuzzy address")
- url = QUrl.fromUserInput(urlstr)
+ url = QtCore.QUrl.fromUserInput(urlstr)
log.url.debug("Converting fuzzy term {!r} to URL -> {}".format(
urlstr, url.toDisplayString()))
ensure_valid(url)
return url
-def _has_explicit_scheme(url: QUrl) -> bool:
+def _has_explicit_scheme(url: QtCore.QUrl) -> bool:
"""Check if a url has an explicit scheme given.
Args:
@@ -246,7 +245,7 @@ def _has_explicit_scheme(url: QUrl) -> bool:
not url.path().startswith(':'))
-def is_special_url(url: QUrl) -> bool:
+def is_special_url(url: QtCore.QUrl) -> bool:
"""Return True if url is an about:... or other special URL.
Args:
@@ -273,8 +272,8 @@ def is_url(urlstr: str) -> bool:
urlstr, autosearch))
urlstr = urlstr.strip()
- qurl = QUrl(urlstr)
- qurl_userinput = QUrl.fromUserInput(urlstr)
+ qurl = QtCore.QUrl(urlstr)
+ qurl_userinput = QtCore.QUrl.fromUserInput(urlstr)
if autosearch == 'never':
# no autosearch, so everything is a URL unless it has an explicit
@@ -320,12 +319,12 @@ def is_url(urlstr: str) -> bool:
return url
-def ensure_valid(url: QUrl) -> None:
+def ensure_valid(url: QtCore.QUrl) -> None:
if not url.isValid():
raise InvalidUrlError(url)
-def invalid_url_error(url: QUrl, action: str) -> None:
+def invalid_url_error(url: QtCore.QUrl, action: str) -> None:
"""Display an error message for a URL.
Args:
@@ -340,7 +339,7 @@ def invalid_url_error(url: QUrl, action: str) -> None:
message.error(errstring)
-def raise_cmdexc_if_invalid(url: QUrl) -> None:
+def raise_cmdexc_if_invalid(url: QtCore.QUrl) -> None:
"""Check if the given QUrl is invalid, and if so, raise a CommandError."""
try:
ensure_valid(url)
@@ -396,7 +395,7 @@ def get_path_if_valid(pathstr: str,
return path
-def filename_from_url(url: QUrl, fallback: str = None) -> Optional[str]:
+def filename_from_url(url: QtCore.QUrl, fallback: str = None) -> Optional[str]:
"""Get a suitable filename from a URL.
Args:
@@ -429,7 +428,7 @@ def filename_from_url(url: QUrl, fallback: str = None) -> Optional[str]:
HostTupleType = Tuple[str, str, int]
-def host_tuple(url: QUrl) -> HostTupleType:
+def host_tuple(url: QtCore.QUrl) -> HostTupleType:
"""Get a (scheme, host, port) tuple from a QUrl.
This is suitable to identify a connection, e.g. for SSL errors.
@@ -454,7 +453,7 @@ def host_tuple(url: QUrl) -> HostTupleType:
return scheme, host, port
-def get_errstring(url: QUrl, base: str = "Invalid URL") -> str:
+def get_errstring(url: QtCore.QUrl, base: str = "Invalid URL") -> str:
"""Get an error string for a URL.
Args:
@@ -471,7 +470,7 @@ def get_errstring(url: QUrl, base: str = "Invalid URL") -> str:
return base
-def same_domain(url1: QUrl, url2: QUrl) -> bool:
+def same_domain(url1: QtCore.QUrl, url2: QtCore.QUrl) -> bool:
"""Check if url1 and url2 belong to the same website.
This will use a "public suffix list" to determine what a "top level domain"
@@ -506,7 +505,7 @@ def same_domain(url1: QUrl, url2: QUrl) -> bool:
return domain1 == domain2
-def encoded_url(url: QUrl) -> str:
+def encoded_url(url: QtCore.QUrl) -> str:
"""Return the fully encoded url as string.
Args:
@@ -521,19 +520,19 @@ def file_url(path: str) -> str:
Arguments:
path: The absolute path to the local file
"""
- url = QUrl.fromLocalFile(path)
- return url.toString(QUrl.FullyEncoded) # type: ignore[arg-type]
+ url = QtCore.QUrl.fromLocalFile(path)
+ return url.toString(QtCore.QUrl.FullyEncoded) # type: ignore[arg-type]
-def data_url(mimetype: str, data: bytes) -> QUrl:
+def data_url(mimetype: str, data: bytes) -> QtCore.QUrl:
"""Get a data: QUrl for the given data."""
b64 = base64.b64encode(data).decode('ascii')
- url = QUrl('data:{};base64,{}'.format(mimetype, b64))
+ url = QtCore.QUrl('data:{};base64,{}'.format(mimetype, b64))
qtutils.ensure_valid(url)
return url
-def safe_display_string(qurl: QUrl) -> str:
+def safe_display_string(qurl: QtCore.QUrl) -> str:
"""Get a IDN-homograph phishing safe form of the given QUrl.
If we're dealing with a Punycode-encoded URL, this prepends the hostname in
@@ -544,11 +543,11 @@ def safe_display_string(qurl: QUrl) -> str:
"""
ensure_valid(qurl)
- host = qurl.host(QUrl.FullyEncoded)
+ host = qurl.host(QtCore.QUrl.FullyEncoded)
assert '..' not in host, qurl # https://bugreports.qt.io/browse/QTBUG-60364
for part in host.split('.'):
- url_host = qurl.host(QUrl.FullyDecoded)
+ url_host = qurl.host(QtCore.QUrl.FullyDecoded)
if part.startswith('xn--') and host != url_host:
return '({}) {}'.format(host, qurl.toDisplayString())
@@ -563,7 +562,7 @@ class InvalidProxyTypeError(Exception):
super().__init__("Invalid proxy type {}!".format(typ))
-def proxy_from_url(url: QUrl) -> Union[QNetworkProxy, pac.PACFetcher]:
+def proxy_from_url(url: QtCore.QUrl) -> Union[QtNetwork.QNetworkProxy, pac.PACFetcher]:
"""Create a QNetworkProxy from QUrl and a proxy type.
Args:
@@ -581,15 +580,15 @@ def proxy_from_url(url: QUrl) -> Union[QNetworkProxy, pac.PACFetcher]:
return fetcher
types = {
- 'http': QNetworkProxy.HttpProxy,
- 'socks': QNetworkProxy.Socks5Proxy,
- 'socks5': QNetworkProxy.Socks5Proxy,
- 'direct': QNetworkProxy.NoProxy,
+ 'http': QtNetwork.QNetworkProxy.HttpProxy,
+ 'socks': QtNetwork.QNetworkProxy.Socks5Proxy,
+ 'socks5': QtNetwork.QNetworkProxy.Socks5Proxy,
+ 'direct': QtNetwork.QNetworkProxy.NoProxy,
}
if scheme not in types:
raise InvalidProxyTypeError(scheme)
- proxy = QNetworkProxy(types[scheme], url.host())
+ proxy = QtNetwork.QNetworkProxy(types[scheme], url.host())
if url.port() != -1:
proxy.setPort(url.port())
@@ -600,7 +599,7 @@ def proxy_from_url(url: QUrl) -> Union[QNetworkProxy, pac.PACFetcher]:
return proxy
-def parse_javascript_url(url: QUrl) -> str:
+def parse_javascript_url(url: QtCore.QUrl) -> str:
"""Get JavaScript source from the given URL.
See https://wiki.whatwg.org/wiki/URL_schemes#javascript:_URLs
@@ -613,7 +612,7 @@ def parse_javascript_url(url: QUrl) -> str:
raise Error("URL contains unexpected components: {}"
.format(url.authority()))
- urlstr = url.toString(QUrl.FullyEncoded) # type: ignore[arg-type]
+ urlstr = url.toString(QtCore.QUrl.FullyEncoded) # type: ignore[arg-type]
urlstr = urllib.parse.unquote(urlstr)
code = urlstr[len('javascript:'):]
diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py
index 56c29899d..0d825aedf 100644
--- a/qutebrowser/utils/usertypes.py
+++ b/qutebrowser/utils/usertypes.py
@@ -24,9 +24,7 @@ import operator
import enum
import dataclasses
from typing import Optional, Sequence, TypeVar, Union
-
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QTimer
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.utils import log, qtutils, utils
@@ -358,7 +356,7 @@ class CommandValue(enum.Enum):
count_tab = enum.auto()
-class Question(QObject):
+class Question(QtCore.QObject):
"""A question asked to the user, e.g. via the status bar.
@@ -396,14 +394,14 @@ class Question(QObject):
completed: Emitted when the question was completed in any way.
"""
- answered = pyqtSignal(object)
- cancelled = pyqtSignal()
- aborted = pyqtSignal()
- answered_yes = pyqtSignal()
- answered_no = pyqtSignal()
- completed = pyqtSignal()
+ answered = QtCore.pyqtSignal(object)
+ cancelled = QtCore.pyqtSignal()
+ aborted = QtCore.pyqtSignal()
+ answered_yes = QtCore.pyqtSignal()
+ answered_no = QtCore.pyqtSignal()
+ completed = QtCore.pyqtSignal()
- def __init__(self, parent: QObject = None) -> None:
+ def __init__(self, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
self.mode: Optional[PromptMode] = None
self.default: Union[bool, str, None] = None
@@ -420,7 +418,7 @@ class Question(QObject):
mode=self.mode, default=self.default,
option=self.option)
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def done(self) -> None:
"""Must be called when the question was answered completely."""
self.answered.emit(self.answer)
@@ -431,13 +429,13 @@ class Question(QObject):
self.answered_no.emit()
self.completed.emit()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def cancel(self) -> None:
"""Cancel the question (resulting from user-input)."""
self.cancelled.emit()
self.completed.emit()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def abort(self) -> None:
"""Abort the question."""
if self.is_aborted:
@@ -448,7 +446,7 @@ class Question(QObject):
self.completed.emit()
-class Timer(QTimer):
+class Timer(QtCore.QTimer):
"""A timer which has a name to show in __repr__ and checks for overflows.
@@ -456,7 +454,7 @@ class Timer(QTimer):
_name: The name of the timer.
"""
- def __init__(self, parent: QObject = None, name: str = None) -> None:
+ def __init__(self, parent: QtCore.QObject = None, name: str = None) -> None:
super().__init__(parent)
if name is None:
self._name = "unnamed"
@@ -528,7 +526,7 @@ class NavigationRequest:
#: None of the above.
other = 8
- url: QUrl
+ url: QtCore.QUrl
navigation_type: Type
is_main_frame: bool
accepted: bool = True
diff --git a/qutebrowser/utils/utils.py b/qutebrowser/utils/utils.py
index a28d662b3..748278db8 100644
--- a/qutebrowser/utils/utils.py
+++ b/qutebrowser/utils/utils.py
@@ -43,10 +43,7 @@ except ImportError: # pragma: no cover
class Protocol:
"""Empty stub at runtime."""
-
-from PyQt5.QtCore import QUrl, QVersionNumber, QRect
-from PyQt5.QtGui import QClipboard, QDesktopServices
-from PyQt5.QtWidgets import QApplication
+from qutebrowser.qt import QtWidgets
import yaml
try:
@@ -59,6 +56,7 @@ except ImportError: # pragma: no cover
YAML_C_EXT = False
from qutebrowser.utils import log
+from qutebrowser.qt import QtGui, QtCore
fake_clipboard = None
log_clipboard = False
@@ -87,7 +85,7 @@ class VersionNumber:
"""A representation of a version number."""
def __init__(self, *args: int) -> None:
- self._ver = QVersionNumber(args) # not *args, to support >3 components
+ self._ver = QtCore.QVersionNumber(args) # not *args, to support >3 components
if self._ver.isNull():
raise ValueError("Can't construct a null version")
@@ -116,7 +114,7 @@ class VersionNumber:
@classmethod
def parse(cls, s: str) -> 'VersionNumber':
"""Parse a version number from a string."""
- ver, _suffix = QVersionNumber.fromString(s)
+ ver, _suffix = QtCore.QVersionNumber.fromString(s)
# FIXME: Should we support a suffix?
if ver.isNull():
@@ -535,8 +533,8 @@ def set_clipboard(data: str, selection: bool = False) -> None:
log.misc.debug("Setting fake {}: {}".format(what, json.dumps(data)))
fake_clipboard = data
else:
- mode = QClipboard.Selection if selection else QClipboard.Clipboard
- QApplication.clipboard().setText(data, mode=mode)
+ mode = QtGui.QClipboard.Selection if selection else QtGui.QClipboard.Clipboard
+ QtWidgets.QApplication.clipboard().setText(data, mode=mode)
def get_clipboard(selection: bool = False, fallback: bool = False) -> str:
@@ -561,8 +559,8 @@ def get_clipboard(selection: bool = False, fallback: bool = False) -> str:
data = fake_clipboard
fake_clipboard = None
else:
- mode = QClipboard.Selection if selection else QClipboard.Clipboard
- data = QApplication.clipboard().text(mode=mode)
+ mode = QtGui.QClipboard.Selection if selection else QtGui.QClipboard.Clipboard
+ data = QtWidgets.QApplication.clipboard().text(mode=mode)
target = "Primary selection" if selection else "Clipboard"
if not data.strip():
@@ -574,7 +572,7 @@ def get_clipboard(selection: bool = False, fallback: bool = False) -> str:
def supports_selection() -> bool:
"""Check if the OS supports primary selection."""
- return QApplication.clipboard().supportsSelection()
+ return QtWidgets.QApplication.clipboard().supportsSelection()
def open_file(filename: str, cmdline: str = None) -> None:
@@ -616,8 +614,8 @@ def open_file(filename: str, cmdline: str = None) -> None:
if cmdline is None and not override:
log.misc.debug("Opening {} with the system application"
.format(filename))
- url = QUrl.fromLocalFile(filename)
- QDesktopServices.openUrl(url)
+ url = QtCore.QUrl.fromLocalFile(filename)
+ QtGui.QDesktopServices.openUrl(url)
return
if cmdline is None and override:
@@ -816,7 +814,7 @@ def cleanup_file(filepath: str) -> Iterator[None]:
_RECT_PATTERN = re.compile(r'(?P<w>\d+)x(?P<h>\d+)\+(?P<x>\d+)\+(?P<y>\d+)')
-def parse_rect(s: str) -> QRect:
+def parse_rect(s: str) -> QtCore.QRect:
"""Parse a rectangle string like 20x20+5+3.
Negative offsets aren't supported, and neither is leaving off parts of the string.
@@ -831,7 +829,7 @@ def parse_rect(s: str) -> QRect:
y = int(match.group('y'))
try:
- rect = QRect(x, y, w, h)
+ rect = QtCore.QRect(x, y, w, h)
except OverflowError as e:
raise ValueError(e)
diff --git a/qutebrowser/utils/version.py b/qutebrowser/utils/version.py
index bf6b49fa6..6049b0708 100644
--- a/qutebrowser/utils/version.py
+++ b/qutebrowser/utils/version.py
@@ -36,20 +36,14 @@ import functools
import dataclasses
from typing import (Mapping, Optional, Sequence, Tuple, ClassVar, Dict, cast,
TYPE_CHECKING)
-
-
-from PyQt5.QtCore import PYQT_VERSION_STR, QLibraryInfo, qVersion
-from PyQt5.QtNetwork import QSslSocket
-from PyQt5.QtGui import (QOpenGLContext, QOpenGLVersionProfile,
- QOffscreenSurface)
-from PyQt5.QtWidgets import QApplication
+from qutebrowser.qt import QtWidgets, QtWebKit, QtWebEngine, QtNetwork
try:
- from PyQt5.QtWebKit import qWebKitVersion
+ pass
except ImportError: # pragma: no cover
qWebKitVersion = None # type: ignore[assignment] # noqa: N816
try:
- from PyQt5.QtWebEngine import PYQT_WEBENGINE_VERSION_STR
+ pass
except ImportError: # pragma: no cover
# Added in PyQt 5.13
PYQT_WEBENGINE_VERSION_STR = None # type: ignore[assignment]
@@ -60,6 +54,8 @@ from qutebrowser.utils import log, utils, standarddir, usertypes, message, resou
from qutebrowser.misc import objects, earlyinit, sql, httpclient, pastebin, elf
from qutebrowser.browser import pdfjs
from qutebrowser.config import config
+from qutebrowser.qt import QtGui, QtCore
+
if TYPE_CHECKING:
from qutebrowser.config import websettings
@@ -762,16 +758,16 @@ def qtwebengine_versions(*, avoid_init: bool = False) -> WebEngineVersions:
if pyqt_webengine_qt_version is not None:
return WebEngineVersions.from_importlib(pyqt_webengine_qt_version)
- if PYQT_WEBENGINE_VERSION_STR is not None:
- return WebEngineVersions.from_pyqt(PYQT_WEBENGINE_VERSION_STR)
+ if QtWebEngine.PYQT_WEBENGINE_VERSION_STR is not None:
+ return WebEngineVersions.from_pyqt(QtWebEngine.PYQT_WEBENGINE_VERSION_STR)
- return WebEngineVersions.from_qt(qVersion()) # type: ignore[unreachable]
+ return WebEngineVersions.from_qt(QtCore.qVersion()) # type: ignore[unreachable]
def _backend() -> str:
"""Get the backend line with relevant information."""
if objects.backend == usertypes.Backend.QtWebKit:
- return 'new QtWebKit (WebKit {})'.format(qWebKitVersion())
+ return 'new QtWebKit (WebKit {})'.format(QtWebKit.qWebKitVersion())
elif objects.backend == usertypes.Backend.QtWebEngine:
return str(qtwebengine_versions(
avoid_init='avoid-chromium-init' in objects.debug_flags))
@@ -812,7 +808,7 @@ def version_info() -> str:
'',
'{}: {}'.format(platform.python_implementation(),
platform.python_version()),
- 'PyQt: {}'.format(PYQT_VERSION_STR),
+ 'PyQt: {}'.format(QtCore.PYQT_VERSION_STR),
'',
]
@@ -821,8 +817,8 @@ def version_info() -> str:
lines += [
'pdf.js: {}'.format(_pdfjs_version()),
'sqlite: {}'.format(sql.version()),
- 'QtNetwork SSL: {}\n'.format(QSslSocket.sslLibraryVersionString()
- if QSslSocket.supportsSsl() else 'no'),
+ 'QtNetwork SSL: {}\n'.format(QtNetwork.QSslSocket.sslLibraryVersionString()
+ if QtNetwork.QSslSocket.supportsSsl() else 'no'),
]
if objects.qapp:
@@ -848,8 +844,8 @@ def version_info() -> str:
"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)
+ QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.LibraryExecutablesPath),
+ QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.DataPath)
)
]
@@ -938,7 +934,7 @@ def opengl_info() -> Optional[OpenGLInfo]: # pragma: no cover
'Intel Open Source Technology Center'; or None if the vendor can't be
determined.
"""
- assert QApplication.instance()
+ assert QtWidgets.QApplication.instance()
override = os.environ.get('QUTE_FAKE_OPENGL')
if override is not None:
@@ -946,13 +942,13 @@ def opengl_info() -> Optional[OpenGLInfo]: # pragma: no cover
vendor, version = override.split(', ', maxsplit=1)
return OpenGLInfo.parse(vendor=vendor, version=version)
- old_context = cast(Optional[QOpenGLContext], QOpenGLContext.currentContext())
+ old_context = cast(Optional[QtGui.QOpenGLContext], QtGui.QOpenGLContext.currentContext())
old_surface = None if old_context is None else old_context.surface()
- surface = QOffscreenSurface()
+ surface = QtGui.QOffscreenSurface()
surface.create()
- ctx = QOpenGLContext()
+ ctx = QtGui.QOpenGLContext()
ok = ctx.create()
if not ok:
log.init.debug("Creating context failed!")
@@ -968,7 +964,7 @@ def opengl_info() -> Optional[OpenGLInfo]: # pragma: no cover
# Can't use versionFunctions there
return OpenGLInfo(gles=True)
- vp = QOpenGLVersionProfile()
+ vp = QtGui.QOpenGLVersionProfile()
vp.setVersion(2, 0)
try:
@@ -1015,7 +1011,7 @@ def pastebin_version(pbclient: pastebin.PastebinClient = None) -> None:
_yank_url(pastebin_url)
return
- app = QApplication.instance()
+ app = QtWidgets.QApplication.instance()
http_client = httpclient.HTTPClient()
misc_api = pastebin.PastebinClient.MISC_API_URL
diff --git a/tests/conftest.py b/tests/conftest.py
index 84cae784b..0b8a6cd3a 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -250,9 +250,9 @@ def _select_backend(config):
# Fail early if selected backend is not available
# pylint: disable=unused-import
if backend == 'webkit':
- import PyQt5.QtWebKitWidgets
+ import qutebrowser.qt
elif backend == 'webengine':
- import PyQt5.QtWebEngineWidgets
+ import qutebrowser.qt
else:
raise utils.Unreachable(backend)
@@ -263,12 +263,12 @@ def _auto_select_backend():
# pylint: disable=unused-import
try:
# Try to use QtWebKit as the default backend
- import PyQt5.QtWebKitWidgets
+ import qutebrowser.qt
return 'webkit'
except ImportError:
# Try to use QtWebEngine as a fallback and fail early
# if that's also not available
- import PyQt5.QtWebEngineWidgets
+ import qutebrowser.qt
return 'webengine'
diff --git a/tests/end2end/conftest.py b/tests/end2end/conftest.py
index 5241ab4c3..6e14495e2 100644
--- a/tests/end2end/conftest.py
+++ b/tests/end2end/conftest.py
@@ -27,7 +27,6 @@ import pstats
import operator
import pytest
-from PyQt5.QtCore import PYQT_VERSION, QCoreApplication
pytest.register_assert_rewrite('end2end.fixtures')
@@ -39,6 +38,7 @@ from end2end.fixtures.quteprocess import (quteproc_process, quteproc,
from end2end.fixtures.testprocess import pytest_runtest_makereport
# pylint: enable=unused-import
from qutebrowser.utils import qtutils, utils
+from qutebrowser.qt import QtWebEngine, QtCore
def pytest_configure(config):
@@ -111,7 +111,7 @@ def _get_version_tag(tag):
return pytest.mark.skipif(
not _check_version(
op_str=match.group('operator'),
- running_version=PYQT_VERSION,
+ running_version=QtCore.PYQT_VERSION,
version_str=version,
as_hex=True,
),
@@ -119,11 +119,11 @@ def _get_version_tag(tag):
)
elif package == 'pyqtwebengine':
try:
- from PyQt5.QtWebEngine import PYQT_WEBENGINE_VERSION
+ pass
except ImportError:
- running_version = PYQT_VERSION
+ running_version = QtCore.PYQT_VERSION
else:
- running_version = PYQT_WEBENGINE_VERSION
+ running_version = QtWebEngine.PYQT_WEBENGINE_VERSION
return pytest.mark.skipif(
not _check_version(
op_str=match.group('operator'),
@@ -183,7 +183,7 @@ def pytest_collection_modifyitems(config, items):
# (note this isn't actually fixed properly before Qt 5.15)
header_bug_fixed = qtutils.version_check('5.15', compiled=False)
- lib_path = pathlib.Path(QCoreApplication.libraryPaths()[0])
+ lib_path = pathlib.Path(QtCore.QCoreApplication.libraryPaths()[0])
qpdf_image_plugin = lib_path / 'imageformats' / 'libqpdf.so'
markers = [
diff --git a/tests/end2end/features/test_downloads_bdd.py b/tests/end2end/features/test_downloads_bdd.py
index 804ed40fe..b870cdc6a 100644
--- a/tests/end2end/features/test_downloads_bdd.py
+++ b/tests/end2end/features/test_downloads_bdd.py
@@ -23,7 +23,7 @@ import shlex
import pytest
import pytest_bdd as bdd
-from PyQt5.QtNetwork import QSslSocket
+from qutebrowser.qt import QtNetwork
bdd.scenarios('downloads.feature')
@@ -65,7 +65,7 @@ def clean_old_downloads(quteproc):
@bdd.when("SSL is supported")
def check_ssl():
- if not QSslSocket.supportsSsl():
+ if not QtNetwork.QSslSocket.supportsSsl():
pytest.skip("QtNetwork SSL not supported")
diff --git a/tests/end2end/features/test_editor_bdd.py b/tests/end2end/features/test_editor_bdd.py
index 40f77a0f7..ce073ad3d 100644
--- a/tests/end2end/features/test_editor_bdd.py
+++ b/tests/end2end/features/test_editor_bdd.py
@@ -26,10 +26,10 @@ import time
import pytest
import pytest_bdd as bdd
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QFileSystemWatcher
bdd.scenarios('editor.feature')
from qutebrowser.utils import utils
+from qutebrowser.qt import QtCore
@bdd.when(bdd.parsers.parse('I setup a fake editor replacing "{text}" by '
@@ -73,20 +73,20 @@ def set_up_editor_empty(quteproc, tmpdir):
set_up_editor(quteproc, tmpdir, "")
-class EditorPidWatcher(QObject):
+class EditorPidWatcher(QtCore.QObject):
- appeared = pyqtSignal()
+ appeared = QtCore.pyqtSignal()
def __init__(self, directory, parent=None):
super().__init__(parent)
self._pidfile = directory / 'editor_pid'
- self._watcher = QFileSystemWatcher(self)
+ self._watcher = QtCore.QFileSystemWatcher(self)
self._watcher.addPath(str(directory))
self._watcher.directoryChanged.connect(self._check_update)
self.has_pidfile = False
self._check_update()
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def _check_update(self):
if self.has_pidfile:
return
diff --git a/tests/end2end/fixtures/notificationserver.py b/tests/end2end/fixtures/notificationserver.py
index b643e848b..d05e62aeb 100644
--- a/tests/end2end/fixtures/notificationserver.py
+++ b/tests/end2end/fixtures/notificationserver.py
@@ -20,15 +20,13 @@
import dataclasses
import itertools
from typing import Dict, List
-
-from PyQt5.QtCore import QObject, QByteArray, QUrl, pyqtSlot
-from PyQt5.QtGui import QImage
-from PyQt5.QtDBus import QDBusConnection, QDBusArgument, QDBusMessage
+from qutebrowser.qt import QtGui
import pytest
from qutebrowser.browser.webengine import notification
from qutebrowser.utils import utils
from tests.helpers import testutils
+from qutebrowser.qt import QtDBus, QtCore
@dataclasses.dataclass
@@ -42,7 +40,7 @@ class NotificationProperties:
closed_via_web: bool = False
-class TestNotificationServer(QObject):
+class TestNotificationServer(QtCore.QObject):
"""A libnotify notification server used for testing."""
def __init__(self, service: str):
@@ -55,7 +53,7 @@ class TestNotificationServer(QObject):
super().__init__()
self._service = service
# Trying to connect to the bus doesn't fail if there's no bus.
- self._bus = QDBusConnection.sessionBus()
+ self._bus = QtDBus.QDBusConnection.sessionBus()
self._message_id_gen = itertools.count(1)
# A dict mapping notification IDs to currently-displayed notifications.
self.messages: Dict[int, NotificationProperties] = {}
@@ -82,7 +80,7 @@ class TestNotificationServer(QObject):
notification.DBusNotificationAdapter.PATH,
notification.DBusNotificationAdapter.INTERFACE,
self,
- QDBusConnection.ExportAllSlots,
+ QtDBus.QDBusConnection.ExportAllSlots,
)
return True
@@ -110,7 +108,7 @@ class TestNotificationServer(QObject):
}
for key in 'x-qutebrowser-origin', 'x-kde-origin-name':
value = hints[key]
- url = QUrl(value)
+ url = QtCore.QUrl(value)
assert url.isValid(), value
assert url.scheme() == 'http', value
assert url.host() == 'localhost', value
@@ -133,8 +131,8 @@ class TestNotificationServer(QObject):
has_alpha: bool,
bits_per_color: int,
channel_count: int,
- data: QByteArray,
- ) -> QImage:
+ data: QtCore.QByteArray,
+ ) -> QtGui.QImage:
"""Make sure the given image data is valid and return a QImage."""
# Chromium limit?
assert 0 < width <= 320
@@ -151,8 +149,8 @@ class TestNotificationServer(QObject):
assert channel_count == (4 if has_alpha else 3)
assert bytes_per_line >= width * channel_count
- qimage_format = QImage.Format_RGBA8888 if has_alpha else QImage.Format_RGB888
- img = QImage(data, width, height, bytes_per_line, qimage_format)
+ qimage_format = QtGui.QImage.Format_RGBA8888 if has_alpha else QtGui.QImage.Format_RGB888
+ img = QtGui.QImage(data, width, height, bytes_per_line, qimage_format)
assert not img.isNull()
assert img.width() == width
assert img.height() == height
@@ -161,7 +159,7 @@ class TestNotificationServer(QObject):
def close(self, notification_id: int) -> None:
"""Sends a close notification for the given ID."""
- message = QDBusMessage.createSignal(
+ message = QtDBus.QDBusMessage.createSignal(
notification.DBusNotificationAdapter.PATH,
notification.DBusNotificationAdapter.INTERFACE,
"NotificationClosed")
@@ -181,7 +179,7 @@ class TestNotificationServer(QObject):
def action(self, notification_id: int, name: str) -> None:
"""Sends an action notification for the given ID."""
- message = QDBusMessage.createSignal(
+ message = QtDBus.QDBusMessage.createSignal(
notification.DBusNotificationAdapter.PATH,
notification.DBusNotificationAdapter.INTERFACE,
"ActionInvoked")
@@ -193,10 +191,10 @@ class TestNotificationServer(QObject):
# Everything below is exposed via DBus
# pylint: disable=invalid-name
- @pyqtSlot(QDBusMessage, result="uint")
- def Notify(self, dbus_message: QDBusMessage) -> QDBusArgument:
+ @QtCore.pyqtSlot(QtDBus.QDBusMessage, result="uint")
+ def Notify(self, dbus_message: QtDBus.QDBusMessage) -> QtDBus.QDBusArgument:
assert dbus_message.signature() == 'susssasa{sv}i'
- assert dbus_message.type() == QDBusMessage.MethodCallMessage
+ assert dbus_message.type() == QtDBus.QDBusMessage.MethodCallMessage
message = self._parse_notify_args(*dbus_message.arguments())
@@ -209,11 +207,11 @@ class TestNotificationServer(QObject):
self.last_id = message_id
return message_id
- @pyqtSlot(QDBusMessage, result="QStringList")
- def GetCapabilities(self, message: QDBusMessage) -> List[str]:
+ @QtCore.pyqtSlot(QtDBus.QDBusMessage, result="QStringList")
+ def GetCapabilities(self, message: QtDBus.QDBusMessage) -> List[str]:
assert not message.signature()
assert not message.arguments()
- assert message.type() == QDBusMessage.MethodCallMessage
+ assert message.type() == QtDBus.QDBusMessage.MethodCallMessage
capabilities = ["actions", "x-kde-origin-name"]
if self.supports_body_markup:
@@ -221,10 +219,10 @@ class TestNotificationServer(QObject):
return capabilities
- @pyqtSlot(QDBusMessage)
- def CloseNotification(self, dbus_message: QDBusMessage) -> None:
+ @QtCore.pyqtSlot(QtDBus.QDBusMessage)
+ def CloseNotification(self, dbus_message: QtDBus.QDBusMessage) -> None:
assert dbus_message.signature() == 'u'
- assert dbus_message.type() == QDBusMessage.MethodCallMessage
+ assert dbus_message.type() == QtDBus.QDBusMessage.MethodCallMessage
message_id = dbus_message.arguments()[0]
self.messages[message_id].closed_via_web = True
diff --git a/tests/end2end/fixtures/quteprocess.py b/tests/end2end/fixtures/quteprocess.py
index ab8f28d26..311bbbb4e 100644
--- a/tests/end2end/fixtures/quteprocess.py
+++ b/tests/end2end/fixtures/quteprocess.py
@@ -33,13 +33,12 @@ import json
import yaml
import pytest
-from PyQt5.QtCore import pyqtSignal, QUrl, QPoint
-from PyQt5.QtGui import QImage, QColor
from qutebrowser.misc import ipc
from qutebrowser.utils import log, utils, javascript
from helpers import testutils
from end2end.fixtures import testprocess
+from qutebrowser.qt import QtGui, QtCore
instance_counter = itertools.count()
@@ -462,7 +461,7 @@ class QuteProc(testprocess.Process):
got_error: Emitted when there was an error log line.
"""
- got_error = pyqtSignal()
+ got_error = QtCore.pyqtSignal()
KEYS = ['timestamp', 'loglevel', 'category', 'module', 'function', 'line',
'message']
@@ -842,14 +841,14 @@ class QuteProc(testprocess.Process):
else:
timeout = 5000
- qurl = QUrl(url)
+ qurl = QtCore.QUrl(url)
if not qurl.isValid():
raise ValueError("Invalid URL {}: {}".format(url,
qurl.errorString()))
# We really need the same representation that the webview uses in
# its __repr__
- url = utils.elide(qurl.toDisplayString(QUrl.EncodeUnicode), 100)
+ url = utils.elide(qurl.toDisplayString(QtCore.QUrl.EncodeUnicode), 100)
assert url
pattern = re.compile(
@@ -903,9 +902,9 @@ class QuteProc(testprocess.Process):
def get_screenshot(
self,
*,
- probe_pos: QPoint = None,
- probe_color: QColor = testutils.Color(0, 0, 0),
- ) -> QImage:
+ probe_pos: QtCore.QPoint = None,
+ probe_color: QtGui.QColor = testutils.Color(0, 0, 0),
+ ) -> QtGui.QImage:
"""Get a screenshot of the current page.
Arguments:
@@ -923,7 +922,7 @@ class QuteProc(testprocess.Process):
self.wait_for(message=screenshot_msg)
print(screenshot_msg)
- img = QImage(str(path))
+ img = QtGui.QImage(str(path))
assert not img.isNull()
if probe_pos is None:
diff --git a/tests/end2end/fixtures/test_testprocess.py b/tests/end2end/fixtures/test_testprocess.py
index aa6f19c67..730ec74ba 100644
--- a/tests/end2end/fixtures/test_testprocess.py
+++ b/tests/end2end/fixtures/test_testprocess.py
@@ -25,7 +25,7 @@ import contextlib
import datetime
import pytest
-from PyQt5.QtCore import QProcess
+from qutebrowser.qt import QtCore
from end2end.fixtures import testprocess
@@ -53,7 +53,7 @@ class PythonProcess(testprocess.Process):
def __init__(self, request):
super().__init__(request)
- self.proc.setReadChannel(QProcess.StandardOutput)
+ self.proc.setReadChannel(QtCore.QProcess.StandardOutput)
self.code = None
def _parse_line(self, line):
diff --git a/tests/end2end/fixtures/testprocess.py b/tests/end2end/fixtures/testprocess.py
index 96e700390..e9cede84d 100644
--- a/tests/end2end/fixtures/testprocess.py
+++ b/tests/end2end/fixtures/testprocess.py
@@ -26,13 +26,12 @@ import dataclasses
import pytest
import pytestqt.wait_signal
-from PyQt5.QtCore import (pyqtSlot, pyqtSignal, QProcess, QObject,
- QElapsedTimer, QProcessEnvironment)
from PyQt5.QtTest import QSignalSpy
from helpers import testutils
from qutebrowser.utils import utils as quteutils
+from qutebrowser.qt import QtCore
class InvalidLine(Exception):
@@ -120,7 +119,7 @@ def pytest_runtest_makereport(item, call):
f"{name} output", _render_log(content, verbose=verbose))
-class Process(QObject):
+class Process(QtCore.QObject):
"""Abstraction over a running test subprocess process.
@@ -139,8 +138,8 @@ class Process(QObject):
new_data: Emitted when a new line was parsed.
"""
- ready = pyqtSignal()
- new_data = pyqtSignal(object)
+ ready = QtCore.pyqtSignal()
+ new_data = QtCore.pyqtSignal(object)
KEYS = ['data']
def __init__(self, request, parent=None):
@@ -150,8 +149,8 @@ class Process(QObject):
self._started = False
self._invalid = []
self._data = []
- self.proc = QProcess()
- self.proc.setReadChannel(QProcess.StandardError)
+ self.proc = QtCore.QProcess()
+ self.proc.setReadChannel(QtCore.QProcess.StandardError)
self.exit_expected = None # Not started at all yet
def _log(self, line):
@@ -202,7 +201,7 @@ class Process(QObject):
blocker.connect(signal)
return blocker
- @pyqtSlot()
+ @QtCore.pyqtSlot()
def read_log(self):
"""Read the log from the process' stdout."""
if not hasattr(self, 'proc'):
@@ -259,7 +258,7 @@ class Process(QObject):
if args is None:
args = self._default_args()
- procenv = QProcessEnvironment.systemEnvironment()
+ procenv = QtCore.QProcessEnvironment.systemEnvironment()
if env is not None:
for k, v in env.items():
procenv.insert(k, v)
@@ -325,7 +324,7 @@ class Process(QObject):
def is_running(self):
"""Check if the process is currently running."""
- return self.proc.state() == QProcess.Running
+ return self.proc.state() == QtCore.QProcess.Running
def _match_data(self, value, expected):
"""Helper for wait_for to match a given value.
@@ -395,7 +394,7 @@ class Process(QObject):
self._log("\n----> Waiting for {} in the log".format(elided))
spy = QSignalSpy(self.new_data)
- elapsed_timer = QElapsedTimer()
+ elapsed_timer = QtCore.QElapsedTimer()
elapsed_timer.start()
while True:
diff --git a/tests/end2end/fixtures/webserver.py b/tests/end2end/fixtures/webserver.py
index 2c2eab930..5a37d8174 100644
--- a/tests/end2end/fixtures/webserver.py
+++ b/tests/end2end/fixtures/webserver.py
@@ -28,9 +28,9 @@ import dataclasses
from http import HTTPStatus
import pytest
-from PyQt5.QtCore import pyqtSignal, QUrl
from end2end.fixtures import testprocess
+from qutebrowser.qt import QtCore
class Request(testprocess.Line):
@@ -93,7 +93,7 @@ class Request(testprocess.Line):
default_statuses = [HTTPStatus.OK, HTTPStatus.NOT_MODIFIED]
- sanitized = QUrl('http://localhost' + self.path).path() # Remove ?foo
+ sanitized = QtCore.QUrl('http://localhost' + self.path).path() # Remove ?foo
expected_statuses = path_to_statuses.get(sanitized, default_statuses)
if self.status not in expected_statuses:
raise AssertionError(
@@ -135,7 +135,7 @@ class WebserverProcess(testprocess.Process):
new_request: Emitted when there's a new request received.
"""
- new_request = pyqtSignal(Request)
+ new_request = QtCore.pyqtSignal(Request)
Request = Request # So it can be used from the fixture easily.
ExpectedRequest = ExpectedRequest
diff --git a/tests/end2end/test_dirbrowser.py b/tests/end2end/test_dirbrowser.py
index c2aa19233..13ecd7426 100644
--- a/tests/end2end/test_dirbrowser.py
+++ b/tests/end2end/test_dirbrowser.py
@@ -27,7 +27,7 @@ from typing import List
import pytest
import bs4
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.utils import urlutils
from helpers import testutils
@@ -147,14 +147,14 @@ def parse(quteproc):
if not parent_elem:
parent = None
else:
- parent = pathlib.Path(QUrl(parent_elem[0].li.a['href']).toLocalFile())
+ parent = pathlib.Path(QtCore.QUrl(parent_elem[0].li.a['href']).toLocalFile())
folders = []
files = []
for css_class, list_ in [('folders', folders), ('files', files)]:
for li in container('ul', class_=css_class)[0]('li'):
- item_path = pathlib.Path(QUrl(li.a['href']).toLocalFile())
+ item_path = pathlib.Path(QtCore.QUrl(li.a['href']).toLocalFile())
list_.append(Item(path=item_path, link=li.a['href'],
text=str(li.a.string)))
diff --git a/tests/end2end/test_invocations.py b/tests/end2end/test_invocations.py
index 0d49ff109..43cd6995f 100644
--- a/tests/end2end/test_invocations.py
+++ b/tests/end2end/test_invocations.py
@@ -29,10 +29,10 @@ import json
import platform
import pytest
-from PyQt5.QtCore import QProcess, QPoint
from helpers import testutils
from qutebrowser.utils import qtutils, utils
+from qutebrowser.qt import QtCore
ascii_locale = pytest.mark.skipif(sys.hexversion >= 0x03070000,
@@ -261,8 +261,8 @@ def test_version(request):
args = ['-m', 'qutebrowser', '--version'] + _base_args(request.config)
# can't use quteproc_new here because it's confused by
# early process termination
- proc = QProcess()
- proc.setProcessChannelMode(QProcess.SeparateChannels)
+ proc = QtCore.QProcess()
+ proc.setProcessChannelMode(QtCore.QProcess.SeparateChannels)
proc.start(sys.executable, args)
ok = proc.waitForStarted(2000)
@@ -275,7 +275,7 @@ def test_version(request):
print(stderr)
assert ok
- assert proc.exitStatus() == QProcess.NormalExit
+ assert proc.exitStatus() == QtCore.QProcess.NormalExit
match = re.search(r'^qutebrowser\s+v\d+(\.\d+)', stdout, re.MULTILINE)
assert match is not None
@@ -543,7 +543,7 @@ def test_preferred_colorscheme_with_dark_mode(
else testutils.Color(34, 34, 34)) # dark website color
xfail = False
- pos = QPoint(0, 0)
+ pos = QtCore.QPoint(0, 0)
img = quteproc_new.get_screenshot(probe_pos=pos, probe_color=expected_color)
color = testutils.Color(img.pixelColor(pos))
@@ -718,7 +718,7 @@ def test_dark_mode(webengine_versions, quteproc_new, request,
# Position chosen by fair dice roll.
# https://xkcd.com/221/
quteproc_new.get_screenshot(
- probe_pos=QPoint(4, 4),
+ probe_pos=QtCore.QPoint(4, 4),
probe_color=expected,
)
@@ -741,13 +741,13 @@ def test_dark_mode_mathml(quteproc_new, request, qtbot):
expected = testutils.Color(0, 0, 206) if IS_ARM else testutils.Color(0, 0, 204)
quteproc_new.get_screenshot(
- probe_pos=QPoint(105, 0),
+ probe_pos=QtCore.QPoint(105, 0),
probe_color=expected,
)
# Then get the actual formula color, probing again in case it's not displayed yet...
quteproc_new.get_screenshot(
- probe_pos=QPoint(4, 4),
+ probe_pos=QtCore.QPoint(4, 4),
probe_color=testutils.Color(255, 255, 255),
)
diff --git a/tests/helpers/fixtures.py b/tests/helpers/fixtures.py
index cc362290f..5225577fe 100644
--- a/tests/helpers/fixtures.py
+++ b/tests/helpers/fixtures.py
@@ -37,9 +37,7 @@ import dataclasses
import pytest
import py.path # pylint: disable=no-name-in-module
-from PyQt5.QtCore import QSize, Qt
-from PyQt5.QtWidgets import QWidget, QHBoxLayout, QVBoxLayout
-from PyQt5.QtNetwork import QNetworkCookieJar
+from qutebrowser.qt import QtWidgets, QtWebEngineWidgets, QtNetwork
import helpers.stubs as stubsmod
import qutebrowser
@@ -51,20 +49,20 @@ from qutebrowser.browser import greasemonkey, history, qutescheme
from qutebrowser.browser.webkit import cookies, cache
from qutebrowser.misc import savemanager, sql, objects, sessions
from qutebrowser.keyinput import modeman
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
_qute_scheme_handler = None
-class WidgetContainer(QWidget):
+class WidgetContainer(QtWidgets.QWidget):
"""Container for another widget."""
def __init__(self, qtbot, parent=None):
super().__init__(parent)
self._qtbot = qtbot
- self.vbox = QVBoxLayout(self)
+ self.vbox = QtWidgets.QVBoxLayout(self)
qtbot.add_widget(self)
self._widget = None
@@ -117,20 +115,20 @@ class WinRegistryHelper:
del objreg.window_registry[win_id]
-class FakeStatusBar(QWidget):
+class FakeStatusBar(QtWidgets.QWidget):
"""Fake statusbar to test progressbar sizing."""
def __init__(self, parent=None):
super().__init__(parent)
- self.hbox = QHBoxLayout(self)
+ self.hbox = QtWidgets.QHBoxLayout(self)
self.hbox.addStretch()
self.hbox.setContentsMargins(0, 0, 0, 0)
- self.setAttribute(Qt.WA_StyledBackground, True)
+ self.setAttribute(QtCore.Qt.WA_StyledBackground, True)
self.setStyleSheet('background-color: red;')
def minimumSizeHint(self):
- return QSize(1, self.fontMetrics().height())
+ return QtCore.QSize(1, self.fontMetrics().height())
@pytest.fixture
@@ -177,11 +175,10 @@ def testdata_scheme(qapp):
try:
global _qute_scheme_handler
from qutebrowser.browser.webengine import webenginequtescheme
- from PyQt5.QtWebEngineWidgets import QWebEngineProfile
webenginequtescheme.init()
_qute_scheme_handler = webenginequtescheme.QuteSchemeHandler(
parent=qapp)
- _qute_scheme_handler.install(QWebEngineProfile.defaultProfile())
+ _qute_scheme_handler.install(QtWebEngineWidgets.QWebEngineProfile.defaultProfile())
except ImportError:
pass
@@ -432,9 +429,8 @@ def unicode_encode_err():
@pytest.fixture(scope='session')
def qnam(qapp):
"""Session-wide QNetworkAccessManager."""
- from PyQt5.QtNetwork import QNetworkAccessManager
- nam = QNetworkAccessManager()
- nam.setNetworkAccessible(QNetworkAccessManager.NotAccessible)
+ nam = QtNetwork.QNetworkAccessManager()
+ nam.setNetworkAccessible(QtNetwork.QNetworkAccessManager.NotAccessible)
return nam
@@ -498,7 +494,7 @@ def webframe(webpage):
@pytest.fixture
def cookiejar_and_cache(stubs, monkeypatch):
"""Fixture providing a fake cookie jar and cache."""
- monkeypatch.setattr(cookies, 'cookie_jar', QNetworkCookieJar())
+ monkeypatch.setattr(cookies, 'cookie_jar', QtNetwork.QNetworkCookieJar())
monkeypatch.setattr(cookies, 'ram_cookie_jar', cookies.RAMCookieJar())
monkeypatch.setattr(cache, 'diskcache', stubs.FakeNetworkCache())
@@ -693,7 +689,7 @@ def web_history(fake_save_manager, tmpdir, database, config_stub, stubs,
@pytest.fixture
def blue_widget(qtbot):
- widget = QWidget()
+ widget = QtWidgets.QWidget()
widget.setStyleSheet('background-color: blue;')
qtbot.add_widget(widget)
return widget
@@ -701,7 +697,7 @@ def blue_widget(qtbot):
@pytest.fixture
def red_widget(qtbot):
- widget = QWidget()
+ widget = QtWidgets.QWidget()
widget.setStyleSheet('background-color: red;')
qtbot.add_widget(widget)
return widget
diff --git a/tests/helpers/messagemock.py b/tests/helpers/messagemock.py
index 41f0bac64..d90de5595 100644
--- a/tests/helpers/messagemock.py
+++ b/tests/helpers/messagemock.py
@@ -23,9 +23,9 @@ import logging
import dataclasses
import pytest
-from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
from qutebrowser.utils import usertypes, message
+from qutebrowser.qt import QtCore
@dataclasses.dataclass
@@ -37,7 +37,7 @@ class Message:
text: str
-class MessageMock(QObject):
+class MessageMock(QtCore.QObject):
"""Helper object for message_mock.
@@ -47,8 +47,8 @@ class MessageMock(QObject):
_logger: The logger to use for messages/questions.
"""
- got_message = pyqtSignal(usertypes.MessageLevel, str)
- got_question = pyqtSignal(usertypes.Question)
+ got_message = QtCore.pyqtSignal(usertypes.MessageLevel, str)
+ got_question = QtCore.pyqtSignal(usertypes.Question)
def __init__(self, parent=None):
super().__init__(parent)
@@ -56,7 +56,7 @@ class MessageMock(QObject):
self.questions = []
self._logger = logging.getLogger('messagemock')
- @pyqtSlot(usertypes.MessageLevel, str)
+ @QtCore.pyqtSlot(usertypes.MessageLevel, str)
def _record_message(self, level, text):
self.got_message.emit(level, text)
log_levels = {
@@ -69,7 +69,7 @@ class MessageMock(QObject):
self._logger.log(log_level, text)
self.messages.append(Message(level, text))
- @pyqtSlot(usertypes.Question)
+ @QtCore.pyqtSlot(usertypes.Question)
def _record_question(self, question):
self.got_question.emit(question)
self._logger.debug(question)
diff --git a/tests/helpers/stubs.py b/tests/helpers/stubs.py
index 6998958b8..6c8d75335 100644
--- a/tests/helpers/stubs.py
+++ b/tests/helpers/stubs.py
@@ -29,19 +29,15 @@ import dataclasses
import builtins
import importlib
import types
-
-from PyQt5.QtCore import pyqtSignal, QPoint, QProcess, QObject, QUrl, QByteArray
-from PyQt5.QtGui import QIcon
-from PyQt5.QtNetwork import (QNetworkRequest, QAbstractNetworkCache,
- QNetworkCacheMetaData)
-from PyQt5.QtWidgets import QCommonStyle, QLineEdit, QWidget, QTabBar
+from qutebrowser.qt import QtWidgets, QtNetwork, QtGui
from qutebrowser.browser import browsertab, downloads
from qutebrowser.utils import usertypes
from qutebrowser.commands import runners
+from qutebrowser.qt import QtCore
-class FakeNetworkCache(QAbstractNetworkCache):
+class FakeNetworkCache(QtNetwork.QAbstractNetworkCache):
"""Fake cache with no data."""
@@ -55,7 +51,7 @@ class FakeNetworkCache(QAbstractNetworkCache):
pass
def metaData(self, _url):
- return QNetworkCacheMetaData()
+ return QtNetwork.QNetworkCacheMetaData()
def prepare(self, _metadata):
return None
@@ -94,7 +90,7 @@ class FakeWebFrame:
parent: The parent frame.
"""
if scroll is None:
- scroll = QPoint(0, 0)
+ scroll = QtCore.QPoint(0, 0)
self.geometry = mock.Mock(return_value=geometry)
self.scrollPosition = mock.Mock(return_value=scroll)
self.parentFrame = mock.Mock(return_value=parent)
@@ -121,7 +117,7 @@ class FakeQApplication:
def __init__(self, *, style=None, all_widgets=None, active_window=None,
arguments=None, platform_name=None):
- self.style = mock.Mock(spec=QCommonStyle)
+ self.style = mock.Mock(spec=QtWidgets.QCommonStyle)
self.style().metaObject().className.return_value = style
self.allWidgets = lambda: all_widgets
@@ -135,12 +131,12 @@ class FakeNetworkReply:
"""QNetworkReply stub which provides a Content-Disposition header."""
KNOWN_HEADERS = {
- QNetworkRequest.ContentTypeHeader: 'Content-Type',
+ QtNetwork.QNetworkRequest.ContentTypeHeader: 'Content-Type',
}
def __init__(self, headers=None, url=None):
if url is None:
- url = QUrl()
+ url = QtCore.QUrl()
if headers is None:
self.headers = {}
else:
@@ -193,18 +189,18 @@ class FakeNetworkReply:
self.headers[key] = value
-class FakeProcess(QProcess):
+class FakeProcess(QtCore.QProcess):
- def __init__(self, parent: QObject = None) -> None:
+ def __init__(self, parent: QtCore.QObject = None) -> None:
super().__init__(parent)
- self.start = mock.Mock(spec=QProcess.start)
- self.startDetached = mock.Mock(spec=QProcess.startDetached)
+ self.start = mock.Mock(spec=QtCore.QProcess.start)
+ self.startDetached = mock.Mock(spec=QtCore.QProcess.startDetached)
self.readAllStandardOutput = mock.Mock(
- spec=QProcess.readAllStandardOutput, return_value=QByteArray(b''))
+ spec=QtCore.QProcess.readAllStandardOutput, return_value=QtCore.QByteArray(b''))
self.readAllStandardError = mock.Mock(
- spec=QProcess.readAllStandardError, return_value=QByteArray(b''))
- self.terminate = mock.Mock(spec=QProcess.terminate)
- self.kill = mock.Mock(spec=QProcess.kill)
+ spec=QtCore.QProcess.readAllStandardError, return_value=QtCore.QByteArray(b''))
+ self.terminate = mock.Mock(spec=QtCore.QProcess.terminate)
+ self.kill = mock.Mock(spec=QtCore.QProcess.kill)
class FakeWebTabScroller(browsertab.AbstractScroller):
@@ -256,7 +252,7 @@ class FakeWebTab(browsertab.AbstractTab):
"""Fake AbstractTab to use in tests."""
- def __init__(self, url=QUrl(), title='', tab_id=0, *,
+ def __init__(self, url=QtCore.QUrl(), title='', tab_id=0, *,
scroll_pos_perc=(0, 0),
load_status=usertypes.LoadStatus.success,
progress=0, can_go_back=None, can_go_forward=None):
@@ -270,7 +266,7 @@ class FakeWebTab(browsertab.AbstractTab):
self.scroller = FakeWebTabScroller(self, scroll_pos_perc)
self.audio = FakeWebTabAudio(self)
self.private_api = FakeWebTabPrivate(tab=self, mode_manager=None)
- wrapped = QWidget()
+ wrapped = QtWidgets.QWidget()
self._layout.wrap(self, wrapped)
def url(self, *, requested=False):
@@ -287,7 +283,7 @@ class FakeWebTab(browsertab.AbstractTab):
return self._load_status
def icon(self):
- return QIcon()
+ return QtGui.QIcon()
def renderer_process_pid(self):
return None
@@ -352,11 +348,11 @@ class FakeCommand:
modes: Tuple[usertypes.KeyMode] = (usertypes.KeyMode.normal, )
-class FakeTimer(QObject):
+class FakeTimer(QtCore.QObject):
"""Stub for a usertypes.Timer."""
- timeout_signal = pyqtSignal()
+ timeout_signal = QtCore.pyqtSignal()
def __init__(self, parent=None, name=None):
super().__init__(parent)
@@ -402,14 +398,14 @@ class FakeTimer(QObject):
return self._started
-class InstaTimer(QObject):
+class InstaTimer(QtCore.QObject):
"""Stub for a QTimer that fires instantly on start().
Useful to test a time-based event without inserting an artificial delay.
"""
- timeout = pyqtSignal()
+ timeout = QtCore.pyqtSignal()
def start(self, interval=None):
self.timeout.emit()
@@ -425,27 +421,27 @@ class InstaTimer(QObject):
fun()
-class StatusBarCommandStub(QLineEdit):
+class StatusBarCommandStub(QtWidgets.QLineEdit):
"""Stub for the statusbar command prompt."""
- got_cmd = pyqtSignal(str)
- clear_completion_selection = pyqtSignal()
- hide_completion = pyqtSignal()
- update_completion = pyqtSignal()
- show_cmd = pyqtSignal()
- hide_cmd = pyqtSignal()
+ got_cmd = QtCore.pyqtSignal(str)
+ clear_completion_selection = QtCore.pyqtSignal()
+ hide_completion = QtCore.pyqtSignal()
+ update_completion = QtCore.pyqtSignal()
+ show_cmd = QtCore.pyqtSignal()
+ hide_cmd = QtCore.pyqtSignal()
def prefix(self):
return self.text()[0]
-class UrlMarkManagerStub(QObject):
+class UrlMarkManagerStub(QtCore.QObject):
"""Stub for the quickmark-manager or bookmark-manager object."""
- added = pyqtSignal(str, str)
- removed = pyqtSignal(str)
+ added = QtCore.pyqtSignal(str, str)
+ removed = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
@@ -483,7 +479,7 @@ class SessionManagerStub:
pass
-class TabbedBrowserStub(QObject):
+class TabbedBrowserStub(QtCore.QObject):
"""Stub for the tabbed-browser object."""
@@ -513,16 +509,16 @@ class TabbedBrowserStub(QObject):
return self.cur_url
-class TabWidgetStub(QObject):
+class TabWidgetStub(QtCore.QObject):
"""Stub for the tab-widget object."""
- new_tab = pyqtSignal(browsertab.AbstractTab, int)
+ new_tab = QtCore.pyqtSignal(browsertab.AbstractTab, int)
def __init__(self, parent=None):
super().__init__(parent)
self.tabs = []
- self._qtabbar = QTabBar()
+ self._qtabbar = QtWidgets.QTabBar()
self.index_of = None
self.current_index = None
@@ -558,7 +554,7 @@ class TabWidgetStub(QObject):
return self.tabs[idx - 1]
-class HTTPPostStub(QObject):
+class HTTPPostStub(QtCore.QObject):
"""A stub class for HTTPClient.
@@ -567,8 +563,8 @@ class HTTPPostStub(QObject):
data: the last data send by post()
"""
- success = pyqtSignal(str)
- error = pyqtSignal(str)
+ success = QtCore.pyqtSignal(str)
+ error = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
@@ -580,11 +576,11 @@ class HTTPPostStub(QObject):
self.data = data
-class FakeDownloadItem(QObject):
+class FakeDownloadItem(QtCore.QObject):
"""Mock browser.downloads.DownloadItem."""
- finished = pyqtSignal()
+ finished = QtCore.pyqtSignal()
def __init__(self, fileobj, name, parent=None):
super().__init__(parent)
diff --git a/tests/helpers/testutils.py b/tests/helpers/testutils.py
index c607718ab..44a299de6 100644
--- a/tests/helpers/testutils.py
+++ b/tests/helpers/testutils.py
@@ -31,7 +31,7 @@ import importlib.machinery
import pytest
-from PyQt5.QtGui import QColor
+from qutebrowser.qt import QtWebEngine, QtGui
from qutebrowser.utils import qtutils, log, utils, version
@@ -43,7 +43,7 @@ qt514 = pytest.mark.skipif(
not qtutils.version_check('5.14'), reason="Needs Qt 5.14 or newer")
-class Color(QColor):
+class Color(QtGui.QColor):
"""A QColor with a nicer repr()."""
@@ -273,7 +273,7 @@ def disable_seccomp_bpf_sandbox():
newer kernels.
"""
try:
- from PyQt5 import QtWebEngine # pylint: disable=unused-import
+ pass
except ImportError:
# no QtWebEngine available
return False
diff --git a/tests/unit/browser/test_caret.py b/tests/unit/browser/test_caret.py
index 86014040d..40cd0b398 100644
--- a/tests/unit/browser/test_caret.py
+++ b/tests/unit/browser/test_caret.py
@@ -22,7 +22,7 @@
import textwrap
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.utils import usertypes
from qutebrowser.browser import browsertab
@@ -33,7 +33,7 @@ def caret(web_tab, qtbot, mode_manager):
web_tab.container.expose()
with qtbot.wait_signal(web_tab.load_finished, timeout=10000):
- web_tab.load_url(QUrl('qute://testdata/data/caret.html'))
+ web_tab.load_url(QtCore.QUrl('qute://testdata/data/caret.html'))
with qtbot.wait_signal(web_tab.caret.selection_toggled):
mode_manager.enter(usertypes.KeyMode.caret)
diff --git a/tests/unit/browser/test_downloadview.py b/tests/unit/browser/test_downloadview.py
index 84b50fad2..7ccb45f99 100644
--- a/tests/unit/browser/test_downloadview.py
+++ b/tests/unit/browser/test_downloadview.py
@@ -20,7 +20,7 @@
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.browser import downloads, qtnetworkdownloads, downloadview
@@ -35,8 +35,8 @@ class FakeDownload(downloads.AbstractDownloadItem):
self.done = done
self.successful = successful
- def url(self) -> QUrl:
- return QUrl('https://example.org/')
+ def url(self) -> QtCore.QUrl:
+ return QtCore.QUrl('https://example.org/')
@pytest.fixture
diff --git a/tests/unit/browser/test_hints.py b/tests/unit/browser/test_hints.py
index 85c0a642c..03d9a83e7 100644
--- a/tests/unit/browser/test_hints.py
+++ b/tests/unit/browser/test_hints.py
@@ -23,7 +23,7 @@ import itertools
import operator
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.utils import usertypes
import qutebrowser.browser.hints
@@ -39,7 +39,7 @@ def tabbed_browser(tabbed_browser_stubs, web_tab):
tb = tabbed_browser_stubs[0]
tb.widget.tabs = [web_tab]
tb.widget.current_index = 1
- tb.widget.cur_url = QUrl('https://www.example.com/')
+ tb.widget.cur_url = QtCore.QUrl('https://www.example.com/')
web_tab.container.expose() # No elements found if we don't do this.
return tb
@@ -49,7 +49,7 @@ def test_show_benchmark(benchmark, tabbed_browser, qtbot, mode_manager):
tab = tabbed_browser.widget.tabs[0]
with qtbot.wait_signal(tab.load_finished):
- tab.load_url(QUrl('qute://testdata/data/hints/benchmark.html'))
+ tab.load_url(QtCore.QUrl('qute://testdata/data/hints/benchmark.html'))
manager = qutebrowser.browser.hints.HintManager(win_id=0)
@@ -69,7 +69,7 @@ def test_match_benchmark(benchmark, tabbed_browser, qtbot, mode_manager, qapp,
tab = tabbed_browser.widget.tabs[0]
with qtbot.wait_signal(tab.load_finished):
- tab.load_url(QUrl('qute://testdata/data/hints/benchmark.html'))
+ tab.load_url(QtCore.QUrl('qute://testdata/data/hints/benchmark.html'))
config_stub.val.hints.scatter = False
manager = qutebrowser.browser.hints.HintManager(win_id=0)
diff --git a/tests/unit/browser/test_history.py b/tests/unit/browser/test_history.py
index 51a9effb8..d757d16ba 100644
--- a/tests/unit/browser/test_history.py
+++ b/tests/unit/browser/test_history.py
@@ -22,7 +22,7 @@
import logging
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtWebKit, QtCore
from qutebrowser.browser import history
from qutebrowser.utils import urlutils, usertypes
@@ -40,7 +40,7 @@ class TestSpecialMethods:
def test_iter(self, web_history):
urlstr = 'http://www.example.com/'
- url = QUrl(urlstr)
+ url = QtCore.QUrl(urlstr)
web_history.add_url(url, atime=12345)
assert list(web_history) == [(urlstr, '', 12345, False)]
@@ -48,13 +48,13 @@ class TestSpecialMethods:
def test_len(self, web_history):
assert len(web_history) == 0
- url = QUrl('http://www.example.com/')
+ url = QtCore.QUrl('http://www.example.com/')
web_history.add_url(url)
assert len(web_history) == 1
def test_contains(self, web_history):
- web_history.add_url(QUrl('http://www.example.com/'),
+ web_history.add_url(QtCore.QUrl('http://www.example.com/'),
title='Title', atime=12345)
assert 'http://www.example.com/' in web_history
assert 'www.example.com' not in web_history
@@ -65,34 +65,34 @@ class TestSpecialMethods:
class TestGetting:
def test_get_recent(self, web_history):
- web_history.add_url(QUrl('http://www.qutebrowser.org/'), atime=67890)
- web_history.add_url(QUrl('http://example.com/'), atime=12345)
+ web_history.add_url(QtCore.QUrl('http://www.qutebrowser.org/'), atime=67890)
+ web_history.add_url(QtCore.QUrl('http://example.com/'), atime=12345)
assert list(web_history.get_recent()) == [
('http://www.qutebrowser.org/', '', 67890, False),
('http://example.com/', '', 12345, False),
]
def test_entries_between(self, web_history):
- web_history.add_url(QUrl('http://www.example.com/1'), atime=12345)
- web_history.add_url(QUrl('http://www.example.com/2'), atime=12346)
- web_history.add_url(QUrl('http://www.example.com/3'), atime=12347)
- web_history.add_url(QUrl('http://www.example.com/4'), atime=12348)
- web_history.add_url(QUrl('http://www.example.com/5'), atime=12348)
- web_history.add_url(QUrl('http://www.example.com/6'), atime=12349)
- web_history.add_url(QUrl('http://www.example.com/7'), atime=12350)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/1'), atime=12345)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/2'), atime=12346)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/3'), atime=12347)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/4'), atime=12348)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/5'), atime=12348)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/6'), atime=12349)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/7'), atime=12350)
times = [x.atime for x in web_history.entries_between(12346, 12349)]
assert times == [12349, 12348, 12348, 12347]
def test_entries_before(self, web_history):
- web_history.add_url(QUrl('http://www.example.com/1'), atime=12346)
- web_history.add_url(QUrl('http://www.example.com/2'), atime=12346)
- web_history.add_url(QUrl('http://www.example.com/3'), atime=12347)
- web_history.add_url(QUrl('http://www.example.com/4'), atime=12348)
- web_history.add_url(QUrl('http://www.example.com/5'), atime=12348)
- web_history.add_url(QUrl('http://www.example.com/6'), atime=12348)
- web_history.add_url(QUrl('http://www.example.com/7'), atime=12349)
- web_history.add_url(QUrl('http://www.example.com/8'), atime=12349)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/1'), atime=12346)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/2'), atime=12346)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/3'), atime=12347)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/4'), atime=12348)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/5'), atime=12348)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/6'), atime=12348)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/7'), atime=12349)
+ web_history.add_url(QtCore.QUrl('http://www.example.com/8'), atime=12349)
times = [x.atime for x in
web_history.entries_before(12348, limit=3, offset=2)]
@@ -102,8 +102,8 @@ class TestGetting:
class TestDelete:
def test_clear(self, qtbot, tmpdir, web_history, mocker):
- web_history.add_url(QUrl('http://example.com/'))
- web_history.add_url(QUrl('http://www.qutebrowser.org/'))
+ web_history.add_url(QtCore.QUrl('http://example.com/'))
+ web_history.add_url(QtCore.QUrl('http://www.qutebrowser.org/'))
m = mocker.patch('qutebrowser.browser.history.message.confirm_async',
new=mocker.Mock, spec=[])
@@ -111,8 +111,8 @@ class TestDelete:
assert m.called
def test_clear_force(self, qtbot, tmpdir, web_history):
- web_history.add_url(QUrl('http://example.com/'))
- web_history.add_url(QUrl('http://www.qutebrowser.org/'))
+ web_history.add_url(QtCore.QUrl('http://example.com/'))
+ web_history.add_url(QtCore.QUrl('http://www.qutebrowser.org/'))
history.history_clear(force=True)
assert not len(web_history)
assert not len(web_history.completion)
@@ -122,14 +122,14 @@ class TestDelete:
('http://example.com/1 2', 'http://example.com/1%202'),
])
def test_delete_url(self, web_history, raw, escaped):
- web_history.add_url(QUrl('http://example.com/'), atime=0)
- web_history.add_url(QUrl(escaped), atime=0)
- web_history.add_url(QUrl('http://example.com/2'), atime=0)
+ web_history.add_url(QtCore.QUrl('http://example.com/'), atime=0)
+ web_history.add_url(QtCore.QUrl(escaped), atime=0)
+ web_history.add_url(QtCore.QUrl('http://example.com/2'), atime=0)
before = set(web_history)
completion_before = set(web_history.completion)
- web_history.delete_url(QUrl(raw))
+ web_history.delete_url(QtCore.QUrl(raw))
diff = before.difference(set(web_history))
assert diff == {(escaped, '', 0, False)}
@@ -161,7 +161,7 @@ class TestAdd:
)
def test_add_url(self, qtbot, web_history,
url, atime, title, redirect, history_url, completion_url):
- web_history.add_url(QUrl(url), atime=atime, title=title,
+ web_history.add_url(QtCore.QUrl(url), atime=atime, title=title,
redirect=redirect)
assert list(web_history) == [(history_url, title, atime, redirect)]
if completion_url is None:
@@ -172,13 +172,13 @@ class TestAdd:
def test_no_sql_web_history(self, web_history, monkeypatch):
monkeypatch.setattr(objects, 'debug_flags', {'no-sql-history'})
- web_history.add_url(QUrl('https://www.example.com/'), atime=12346,
+ web_history.add_url(QtCore.QUrl('https://www.example.com/'), atime=12346,
title='Hello World', redirect=False)
assert not list(web_history)
def test_invalid(self, qtbot, web_history, caplog):
with caplog.at_level(logging.WARNING):
- web_history.add_url(QUrl())
+ web_history.add_url(QtCore.QUrl())
assert not list(web_history)
assert not list(web_history.completion)
@@ -198,12 +198,12 @@ class TestAdd:
if known_error:
with caplog.at_level(logging.ERROR):
- web_history.add_url(QUrl('https://www.example.org/'))
+ web_history.add_url(QtCore.QUrl('https://www.example.org/'))
msg = message_mock.getmsg(usertypes.MessageLevel.error)
assert msg.text == "Failed to write history: Error message"
else:
with pytest.raises(sql.BugError):
- web_history.add_url(QUrl('https://www.example.org/'))
+ web_history.add_url(QtCore.QUrl('https://www.example.org/'))
@pytest.mark.parametrize('level, url, req_url, expected', [
(logging.DEBUG, 'a.com', 'a.com', [('a.com', 'title', 12345, False)]),
@@ -228,46 +228,46 @@ class TestAdd:
def test_from_tab(self, web_history, caplog, mock_time,
level, url, req_url, expected):
with caplog.at_level(level):
- web_history.add_from_tab(QUrl(url), QUrl(req_url), 'title')
+ web_history.add_from_tab(QtCore.QUrl(url), QtCore.QUrl(req_url), 'title')
assert set(web_history) == set(expected)
def test_exclude(self, web_history, config_stub):
"""Excluded URLs should be in the history but not completion."""
config_stub.val.completion.web_history.exclude = ['*.example.org']
- url = QUrl('http://www.example.org/')
+ url = QtCore.QUrl('http://www.example.org/')
web_history.add_from_tab(url, url, 'title')
assert list(web_history)
assert not list(web_history.completion)
def test_no_immedate_duplicates(self, web_history, mock_time):
- url = QUrl("http://example.com")
- url2 = QUrl("http://example2.com")
- web_history.add_from_tab(QUrl(url), QUrl(url), 'title')
+ url = QtCore.QUrl("http://example.com")
+ url2 = QtCore.QUrl("http://example2.com")
+ web_history.add_from_tab(QtCore.QUrl(url), QtCore.QUrl(url), 'title')
hist = list(web_history)
assert hist
- web_history.add_from_tab(QUrl(url), QUrl(url), 'title')
+ web_history.add_from_tab(QtCore.QUrl(url), QtCore.QUrl(url), 'title')
assert list(web_history) == hist
- web_history.add_from_tab(QUrl(url2), QUrl(url2), 'title')
+ web_history.add_from_tab(QtCore.QUrl(url2), QtCore.QUrl(url2), 'title')
assert list(web_history) != hist
def test_delete_add_tab(self, web_history, mock_time):
- url = QUrl("http://example.com")
- web_history.add_from_tab(QUrl(url), QUrl(url), 'title')
+ url = QtCore.QUrl("http://example.com")
+ web_history.add_from_tab(QtCore.QUrl(url), QtCore.QUrl(url), 'title')
hist = list(web_history)
assert hist
- web_history.delete_url(QUrl(url))
+ web_history.delete_url(QtCore.QUrl(url))
assert len(web_history) == 0
- web_history.add_from_tab(QUrl(url), QUrl(url), 'title')
+ web_history.add_from_tab(QtCore.QUrl(url), QtCore.QUrl(url), 'title')
assert list(web_history) == hist
def test_clear_add_tab(self, web_history, mock_time):
- url = QUrl("http://example.com")
- web_history.add_from_tab(QUrl(url), QUrl(url), 'title')
+ url = QtCore.QUrl("http://example.com")
+ web_history.add_from_tab(QtCore.QUrl(url), QtCore.QUrl(url), 'title')
hist = list(web_history)
assert hist
history.history_clear(force=True)
assert len(web_history) == 0
- web_history.add_from_tab(QUrl(url), QUrl(url), 'title')
+ web_history.add_from_tab(QtCore.QUrl(url), QtCore.QUrl(url), 'title')
assert list(web_history) == hist
@@ -280,7 +280,7 @@ class TestHistoryInterface:
from qutebrowser.browser.webkit import webkithistory
QWebHistoryInterface = QtWebKit.QWebHistoryInterface
# pylint: enable=invalid-name
- web_history.add_url(url=QUrl('http://www.example.com/'),
+ web_history.add_url(url=QtCore.QUrl('http://www.example.com/'),
title='example')
interface = webkithistory.WebHistoryInterface(web_history)
QWebHistoryInterface.setDefaultInterface(interface)
@@ -304,8 +304,7 @@ class TestInit:
history.web_history.setParent(None)
history.web_history = None
try:
- from PyQt5.QtWebKit import QWebHistoryInterface
- QWebHistoryInterface.setDefaultInterface(None)
+ QtWebKit.QWebHistoryInterface.setDefaultInterface(None)
except ImportError:
pass
@@ -322,19 +321,19 @@ class TestInit:
assert history.web_history.parent() is qapp
try:
- from PyQt5.QtWebKit import QWebHistoryInterface
+ pass
except ImportError:
QWebHistoryInterface = None
if backend == usertypes.Backend.QtWebKit:
- default_interface = QWebHistoryInterface.defaultInterface()
+ default_interface = QtWebKit.QWebHistoryInterface.defaultInterface()
assert default_interface._history is history.web_history
else:
assert backend == usertypes.Backend.QtWebEngine
- if QWebHistoryInterface is None:
+ if QtWebKit.QWebHistoryInterface is None:
default_interface = None
else:
- default_interface = QWebHistoryInterface.defaultInterface()
+ default_interface = QtWebKit.QWebHistoryInterface.defaultInterface()
# For this to work, nothing can ever have called
# setDefaultInterface before (so we need to test webengine before
# webkit)
@@ -344,13 +343,13 @@ class TestInit:
class TestDump:
def test_debug_dump_history(self, web_history, tmpdir):
- web_history.add_url(QUrl('http://example.com/1'),
+ web_history.add_url(QtCore.QUrl('http://example.com/1'),
title="Title1", atime=12345)
- web_history.add_url(QUrl('http://example.com/2'),
+ web_history.add_url(QtCore.QUrl('http://example.com/2'),
title="Title2", atime=12346)
- web_history.add_url(QUrl('http://example.com/3'),
+ web_history.add_url(QtCore.QUrl('http://example.com/3'),
title="Title3", atime=12347)
- web_history.add_url(QUrl('http://example.com/4'),
+ web_history.add_url(QtCore.QUrl('http://example.com/4'),
title="Title4", atime=12348, redirect=True)
histfile = tmpdir / 'history'
history.debug_dump_history(str(histfile))
@@ -371,8 +370,8 @@ class TestRebuild:
def test_user_version(self, database, stubs, monkeypatch):
"""Ensure that completion is regenerated if user_version changes."""
web_history = history.WebHistory(database, stubs.FakeHistoryProgress())
- web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1)
- web_history.add_url(QUrl('example.com/2'), redirect=False, atime=2)
+ web_history.add_url(QtCore.QUrl('example.com/1'), redirect=False, atime=1)
+ web_history.add_url(QtCore.QUrl('example.com/2'), redirect=False, atime=2)
web_history.completion.delete('url', 'example.com/2')
hist2 = history.WebHistory(database, progress=stubs.FakeHistoryProgress())
@@ -391,8 +390,8 @@ class TestRebuild:
def test_force_rebuild(self, database, stubs):
"""Ensure that completion is regenerated if we force a rebuild."""
web_history = history.WebHistory(database, stubs.FakeHistoryProgress())
- web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1)
- web_history.add_url(QUrl('example.com/2'), redirect=False, atime=2)
+ web_history.add_url(QtCore.QUrl('example.com/1'), redirect=False, atime=1)
+ web_history.add_url(QtCore.QUrl('example.com/2'), redirect=False, atime=2)
web_history.completion.delete('url', 'example.com/2')
hist2 = history.WebHistory(web_history.database,
@@ -415,9 +414,9 @@ class TestRebuild:
"""
config_stub.val.completion.web_history.exclude = ['*.example.org']
- web_history.add_url(QUrl('http://example.com'),
+ web_history.add_url(QtCore.QUrl('http://example.com'),
redirect=False, atime=1)
- web_history.add_url(QUrl('http://example.org'),
+ web_history.add_url(QtCore.QUrl('http://example.org'),
redirect=False, atime=2)
hist2 = history.WebHistory(web_history.database,
@@ -428,9 +427,9 @@ class TestRebuild:
"""Ensure that completion is rebuilt when exclude patterns change."""
config_stub.val.completion.web_history.exclude = ['*.example.org']
- web_history.add_url(QUrl('http://example.com'),
+ web_history.add_url(QtCore.QUrl('http://example.com'),
redirect=False, atime=1)
- web_history.add_url(QUrl('http://example.org'),
+ web_history.add_url(QtCore.QUrl('http://example.org'),
redirect=False, atime=2)
hist2 = history.WebHistory(web_history.database,
@@ -449,8 +448,8 @@ class TestRebuild:
]
def test_progress(self, monkeypatch, web_history, config_stub, stubs):
- web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1)
- web_history.add_url(QUrl('example.com/2'), redirect=False, atime=2)
+ web_history.add_url(QtCore.QUrl('example.com/1'), redirect=False, atime=1)
+ web_history.add_url(QtCore.QUrl('example.com/2'), redirect=False, atime=2)
# Trigger a completion rebuild
monkeypatch.setattr(web_history.database, 'user_version_changed', lambda: True)
@@ -464,7 +463,7 @@ class TestRebuild:
def test_interrupted(self, stubs, database, monkeypatch):
"""If we interrupt the rebuilding process, force_rebuild should still be set."""
web_history = history.WebHistory(database, stubs.FakeHistoryProgress())
- web_history.add_url(QUrl('example.com/1'), redirect=False, atime=1)
+ web_history.add_url(QtCore.QUrl('example.com/1'), redirect=False, atime=1)
web_history.completion.delete('url', 'example.com/1')
progress = stubs.FakeHistoryProgress(raise_on_tick=True)
diff --git a/tests/unit/browser/test_inspector.py b/tests/unit/browser/test_inspector.py
index 61ac9510d..433afacf9 100644
--- a/tests/unit/browser/test_inspector.py
+++ b/tests/unit/browser/test_inspector.py
@@ -19,7 +19,7 @@
import pytest
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt import QtWidgets
from qutebrowser.browser import inspector
from qutebrowser.misc import miscwidgets
@@ -28,10 +28,10 @@ from qutebrowser.misc import miscwidgets
class FakeInspector(inspector.AbstractWebInspector):
def __init__(self,
- inspector_widget: QWidget,
+ inspector_widget: QtWidgets.QWidget,
splitter: miscwidgets.InspectorSplitter,
win_id: int,
- parent: QWidget = None) -> None:
+ parent: QtWidgets.QWidget = None) -> None:
super().__init__(splitter, win_id, parent)
self._set_widget(inspector_widget)
self._inspected_page = None
diff --git a/tests/unit/browser/test_navigate.py b/tests/unit/browser/test_navigate.py
index 9813705ca..9308b64ba 100644
--- a/tests/unit/browser/test_navigate.py
+++ b/tests/unit/browser/test_navigate.py
@@ -20,7 +20,7 @@
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.browser import navigate
from qutebrowser.utils import urlutils
@@ -69,23 +69,23 @@ class TestIncDec:
else:
expected_value = value.format(19)
- base_url = QUrl(url.format(base_value))
- expected_url = QUrl(url.format(expected_value))
+ base_url = QtCore.QUrl(url.format(base_value))
+ expected_url = QtCore.QUrl(url.format(expected_value))
assert navigate.incdec(base_url, 1, incdec) == expected_url
def test_port(self, config_stub):
config_stub.val.url.incdec_segments = ['port']
- base_url = QUrl('http://localhost:8000')
+ base_url = QtCore.QUrl('http://localhost:8000')
new_url = navigate.incdec(base_url, 1, 'increment')
- assert new_url == QUrl('http://localhost:8001')
+ assert new_url == QtCore.QUrl('http://localhost:8001')
new_url = navigate.incdec(base_url, 1, 'decrement')
- assert new_url == QUrl('http://localhost:7999')
+ assert new_url == QtCore.QUrl('http://localhost:7999')
def test_port_default(self, config_stub):
"""Test that a default port (with url.port() == -1) is not touched."""
config_stub.val.url.incdec_segments = ['port']
- base_url = QUrl('http://localhost')
+ base_url = QtCore.QUrl('http://localhost')
with pytest.raises(navigate.Error):
navigate.incdec(base_url, 1, 'increment')
@@ -112,8 +112,8 @@ class TestIncDec:
return
expected_value = value.format(20 - count)
- base_url = QUrl(url.format(base_value))
- expected_url = QUrl(url.format(expected_value))
+ base_url = QtCore.QUrl(url.format(base_value))
+ expected_url = QtCore.QUrl(url.format(expected_value))
new_url = navigate.incdec(base_url, count, inc_or_dec)
assert new_url == expected_url
@@ -129,8 +129,8 @@ class TestIncDec:
def test_leading_zeroes(self, number, expected, inc_or_dec, config_stub):
config_stub.val.url.incdec_segments = ['path']
url = 'http://example.com/{}'
- base_url = QUrl(url.format(number))
- expected_url = QUrl(url.format(expected))
+ base_url = QtCore.QUrl(url.format(number))
+ expected_url = QtCore.QUrl(url.format(expected))
new_url = navigate.incdec(base_url, 1, inc_or_dec)
assert new_url == expected_url
@@ -144,8 +144,8 @@ class TestIncDec:
])
def test_segment_ignored(self, url, segments, expected, config_stub):
config_stub.val.url.incdec_segments = segments
- new_url = navigate.incdec(QUrl(url), 1, 'increment')
- assert new_url == QUrl(expected)
+ new_url = navigate.incdec(QtCore.QUrl(url), 1, 'increment')
+ assert new_url == QtCore.QUrl(expected)
@pytest.mark.parametrize('url', [
"http://example.com/long/path/but/no/number",
@@ -160,7 +160,7 @@ class TestIncDec:
])
def test_no_number(self, url):
with pytest.raises(navigate.Error):
- navigate.incdec(QUrl(url), 1, "increment")
+ navigate.incdec(QtCore.QUrl(url), 1, "increment")
@pytest.mark.parametrize('url, count', [
('http://example.com/page_0.html', 1),
@@ -168,15 +168,15 @@ class TestIncDec:
])
def test_number_below_0(self, url, count):
with pytest.raises(navigate.Error):
- navigate.incdec(QUrl(url), count, 'decrement')
+ navigate.incdec(QtCore.QUrl(url), count, 'decrement')
def test_invalid_url(self):
with pytest.raises(urlutils.InvalidUrlError):
- navigate.incdec(QUrl(), 1, "increment")
+ navigate.incdec(QtCore.QUrl(), 1, "increment")
def test_wrong_mode(self):
"""Test if incdec rejects a wrong parameter for inc_or_dec."""
- valid_url = QUrl("http://example.com/0")
+ valid_url = QtCore.QUrl("http://example.com/0")
with pytest.raises(ValueError):
navigate.incdec(valid_url, 1, "foobar")
@@ -192,15 +192,15 @@ class TestUp:
])
def test_up(self, url_suffix, count, expected_suffix):
url_base = 'https://example.com'
- url = QUrl(url_base + url_suffix)
+ url = QtCore.QUrl(url_base + url_suffix)
assert url.isValid()
new = navigate.path_up(url, count)
- assert new == QUrl(url_base + expected_suffix)
+ assert new == QtCore.QUrl(url_base + expected_suffix)
def test_invalid_url(self):
with pytest.raises(urlutils.InvalidUrlError):
- navigate.path_up(QUrl(), count=1)
+ navigate.path_up(QtCore.QUrl(), count=1)
class TestStrip:
@@ -212,17 +212,17 @@ class TestStrip:
])
def test_strip(self, url_suffix):
url_base = 'https://example.com/test'
- url = QUrl(url_base + url_suffix)
+ url = QtCore.QUrl(url_base + url_suffix)
assert url.isValid()
stripped = navigate.strip(url, count=1)
assert stripped.isValid()
- assert stripped == QUrl(url_base)
+ assert stripped == QtCore.QUrl(url_base)
def test_count(self):
with pytest.raises(navigate.Error, match='Count is not supported'):
- navigate.strip(QUrl('https://example.com/'), count=2)
+ navigate.strip(QtCore.QUrl('https://example.com/'), count=2)
def test_invalid_url(self):
with pytest.raises(urlutils.InvalidUrlError):
- navigate.strip(QUrl(), count=1)
+ navigate.strip(QtCore.QUrl(), count=1)
diff --git a/tests/unit/browser/test_pdfjs.py b/tests/unit/browser/test_pdfjs.py
index 86b875be5..7d7f0ecd4 100644
--- a/tests/unit/browser/test_pdfjs.py
+++ b/tests/unit/browser/test_pdfjs.py
@@ -21,7 +21,7 @@ import logging
import os.path
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.browser import pdfjs
from qutebrowser.utils import urlmatch
@@ -47,7 +47,7 @@ def test_generate_pdfjs_page(available, snippet, monkeypatch):
else:
monkeypatch.setattr(pdfjs, 'is_available', lambda: False)
- content = pdfjs.generate_pdfjs_page('example.pdf', QUrl())
+ content = pdfjs.generate_pdfjs_page('example.pdf', QtCore.QUrl())
print(content)
assert snippet in content
@@ -137,7 +137,7 @@ class TestResources:
(data_tmpdir / 'pdfjs' / 'pdf.js').ensure() # But no viewer.html
- content = pdfjs.generate_pdfjs_page('example.pdf', QUrl())
+ content = pdfjs.generate_pdfjs_page('example.pdf', QtCore.QUrl())
assert '<h1>No pdf.js installation found</h1>' in content
@@ -221,7 +221,7 @@ def test_is_available(available, mocker):
])
def test_should_use_pdfjs(mimetype, url, enabled, expected, config_stub):
config_stub.val.content.pdfjs = enabled
- assert pdfjs.should_use_pdfjs(mimetype, QUrl(url)) == expected
+ assert pdfjs.should_use_pdfjs(mimetype, QtCore.QUrl(url)) == expected
@pytest.mark.parametrize('url, expected', [
@@ -232,11 +232,11 @@ def test_should_use_pdfjs_url_pattern(config_stub, url, expected):
config_stub.val.content.pdfjs = False
pattern = urlmatch.UrlPattern('http://example.com')
config_stub.set_obj('content.pdfjs', True, pattern=pattern)
- assert pdfjs.should_use_pdfjs('application/pdf', QUrl(url)) == expected
+ assert pdfjs.should_use_pdfjs('application/pdf', QtCore.QUrl(url)) == expected
def test_get_main_url():
- expected = QUrl('qute://pdfjs/web/viewer.html?filename=hello?world.pdf&'
+ expected = QtCore.QUrl('qute://pdfjs/web/viewer.html?filename=hello?world.pdf&'
'file=&source=http://a.com/hello?world.pdf')
- original_url = QUrl('http://a.com/hello?world.pdf')
+ original_url = QtCore.QUrl('http://a.com/hello?world.pdf')
assert pdfjs.get_main_url('hello?world.pdf', original_url) == expected
diff --git a/tests/unit/browser/test_qutescheme.py b/tests/unit/browser/test_qutescheme.py
index 45474102d..8b384a2fc 100644
--- a/tests/unit/browser/test_qutescheme.py
+++ b/tests/unit/browser/test_qutescheme.py
@@ -24,12 +24,12 @@ import time
import logging
import py.path # pylint: disable=no-name-in-module
-from PyQt5.QtCore import QUrl, QUrlQuery
import pytest
from qutebrowser.browser import qutescheme, pdfjs, downloads
from qutebrowser.utils import resources
from qutebrowser.misc import guiprocess
+from qutebrowser.qt import QtCore
class TestJavascriptHandler:
@@ -56,19 +56,19 @@ class TestJavascriptHandler:
@pytest.mark.parametrize("filename, content", js_files)
def test_qutejavascript(self, filename, content):
- url = QUrl("qute://javascript/{}".format(filename))
+ url = QtCore.QUrl("qute://javascript/{}".format(filename))
_mimetype, data = qutescheme.qute_javascript(url)
assert data == content
def test_qutejavascript_404(self):
- url = QUrl("qute://javascript/404.js")
+ url = QtCore.QUrl("qute://javascript/404.js")
with pytest.raises(qutescheme.SchemeOSError):
qutescheme.data_for_url(url)
def test_qutejavascript_empty_query(self):
- url = QUrl("qute://javascript")
+ url = QtCore.QUrl("qute://javascript")
with pytest.raises(qutescheme.UrlInvalidError):
qutescheme.qute_javascript(url)
@@ -80,12 +80,12 @@ class TestProcessHandler:
def test_invalid_pid(self):
with pytest.raises(qutescheme.UrlInvalidError, match='Invalid PID blah'):
- qutescheme.qute_process(QUrl('qute://process/blah'))
+ qutescheme.qute_process(QtCore.QUrl('qute://process/blah'))
def test_missing_process(self, monkeypatch):
monkeypatch.setattr(guiprocess, 'all_processes', {})
with pytest.raises(qutescheme.NotFoundError, match='No process 1234'):
- qutescheme.qute_process(QUrl('qute://process/1234'))
+ qutescheme.qute_process(QtCore.QUrl('qute://process/1234'))
def test_existing_process(self, qtbot, py_proc):
proc = guiprocess.GUIProcess('testprocess')
@@ -93,7 +93,7 @@ class TestProcessHandler:
with qtbot.wait_signal(proc.finished, timeout=5000):
proc.start(*py_proc("print('AT&T')"))
- _mimetype, data = qutescheme.qute_process(QUrl(f'qute://process/{proc.pid}'))
+ _mimetype, data = qutescheme.qute_process(QtCore.QUrl(f'qute://process/{proc.pid}'))
print(data)
assert f'<title>Process {proc.pid}</title>' in data
@@ -122,7 +122,7 @@ class TestHistoryHandler:
for i in range(entry_count):
entry_atime = now - i * interval
entry = {"atime": str(entry_atime),
- "url": QUrl("http://www.x.com/" + str(i)),
+ "url": QtCore.QUrl("http://www.x.com/" + str(i)),
"title": "Page " + str(i)}
items.insert(0, entry)
@@ -144,7 +144,7 @@ class TestHistoryHandler:
now):
"""Ensure qute://history/data returns correct items."""
start_time = now - start_time_offset
- url = QUrl("qute://history/data?start_time=" + str(start_time))
+ url = QtCore.QUrl("qute://history/data?start_time=" + str(start_time))
_mimetype, data = qutescheme.qute_history(url)
items = json.loads(data)
@@ -160,7 +160,7 @@ class TestHistoryHandler:
"""Make sure the completion.web_history.exclude setting is not used."""
config_stub.val.completion.web_history.exclude = ['www.x.com']
- url = QUrl("qute://history/data?start_time={}".format(now))
+ url = QtCore.QUrl("qute://history/data?start_time={}".format(now))
_mimetype, data = qutescheme.qute_history(url)
items = json.loads(data)
assert items
@@ -175,7 +175,7 @@ class TestHistoryHandler:
}
web_history.insert_batch(entries)
- url = QUrl("qute://history/data?start_time={}".format(now))
+ url = QtCore.QUrl("qute://history/data?start_time={}".format(now))
_mimetype, data = benchmark(qutescheme.qute_history, url)
assert len(json.loads(data)) > 1
@@ -202,7 +202,7 @@ class TestHelpHandler:
def test_unknown_file_type(self, data_patcher):
data_patcher('html/doc/foo.bin', b'\xff')
- mimetype, data = qutescheme.qute_help(QUrl('qute://help/foo.bin'))
+ mimetype, data = qutescheme.qute_help(QtCore.QUrl('qute://help/foo.bin'))
assert mimetype == 'application/octet-stream'
assert data == b'\xff'
@@ -229,14 +229,14 @@ class TestPDFJSHandler:
def test_existing_resource(self):
"""Test with a resource that exists."""
_mimetype, data = qutescheme.data_for_url(
- QUrl('qute://pdfjs/existing/file.html'))
+ QtCore.QUrl('qute://pdfjs/existing/file.html'))
assert data == b'foobar'
def test_nonexisting_resource(self, caplog):
"""Test with a resource that does not exist."""
with caplog.at_level(logging.WARNING, 'misc'):
with pytest.raises(qutescheme.NotFoundError):
- qutescheme.data_for_url(QUrl('qute://pdfjs/no/file.html'))
+ qutescheme.data_for_url(QtCore.QUrl('qute://pdfjs/no/file.html'))
expected = 'pdfjs resource requested but not found: /no/file.html'
assert caplog.messages == [expected]
@@ -253,40 +253,40 @@ class TestPDFJSHandler:
f.write('<pdf content>')
_mimetype, data = qutescheme.data_for_url(
- QUrl('qute://pdfjs/web/viewer.html?filename=' + filename))
+ QtCore.QUrl('qute://pdfjs/web/viewer.html?filename=' + filename))
assert b'PDF.js' in data
def test_viewer_no_filename(self):
with pytest.raises(qutescheme.UrlInvalidError,
match='Missing filename'):
- qutescheme.data_for_url(QUrl('qute://pdfjs/web/viewer.html'))
+ qutescheme.data_for_url(QtCore.QUrl('qute://pdfjs/web/viewer.html'))
def test_viewer_inexistent_file(self):
with pytest.raises(qutescheme.Redirect):
- qutescheme.data_for_url(QUrl('qute://pdfjs/web/viewer.html?'
+ qutescheme.data_for_url(QtCore.QUrl('qute://pdfjs/web/viewer.html?'
'filename=foobar&source=example.org'))
def test_viewer_inexistent_file_no_source(self):
with pytest.raises(qutescheme.UrlInvalidError,
match='Missing source'):
qutescheme.data_for_url(
- QUrl('qute://pdfjs/web/viewer.html?filename=foobar'))
+ QtCore.QUrl('qute://pdfjs/web/viewer.html?filename=foobar'))
def test_file(self, download_tmpdir):
"""Load a file via qute://pdfjs/file."""
(download_tmpdir / 'testfile').write_binary(b'foo')
_mimetype, data = qutescheme.data_for_url(
- QUrl('qute://pdfjs/file?filename=testfile'))
+ QtCore.QUrl('qute://pdfjs/file?filename=testfile'))
assert data == b'foo'
def test_file_no_filename(self):
with pytest.raises(qutescheme.UrlInvalidError):
- qutescheme.data_for_url(QUrl('qute://pdfjs/file'))
+ qutescheme.data_for_url(QtCore.QUrl('qute://pdfjs/file'))
@pytest.mark.parametrize('sep', ['/', os.sep])
def test_file_pathsep(self, sep):
- url = QUrl('qute://pdfjs/file')
- query = QUrlQuery()
+ url = QtCore.QUrl('qute://pdfjs/file')
+ query = QtCore.QUrlQuery()
query.addQueryItem('filename', 'foo{}bar'.format(sep))
url.setQuery(query)
with pytest.raises(qutescheme.RequestDeniedError):
diff --git a/tests/unit/browser/test_signalfilter.py b/tests/unit/browser/test_signalfilter.py
index 35c7f3557..5055b9c31 100644
--- a/tests/unit/browser/test_signalfilter.py
+++ b/tests/unit/browser/test_signalfilter.py
@@ -23,25 +23,25 @@ import logging
import dataclasses
import pytest
-from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject
from qutebrowser.browser import signalfilter
+from qutebrowser.qt import QtCore
-class Signaller(QObject):
+class Signaller(QtCore.QObject):
- signal = pyqtSignal(str)
- link_hovered = pyqtSignal(str)
+ signal = QtCore.pyqtSignal(str)
+ link_hovered = QtCore.pyqtSignal(str)
- filtered_signal = pyqtSignal(str)
- cur_link_hovered = pyqtSignal(str)
+ filtered_signal = QtCore.pyqtSignal(str)
+ cur_link_hovered = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
self.filtered_signal_arg = None
self.filtered_signal.connect(self.filtered_signal_slot)
- @pyqtSlot(str)
+ @QtCore.pyqtSlot(str)
def filtered_signal_slot(self, s):
self.filtered_signal_arg = s
diff --git a/tests/unit/browser/test_urlmarks.py b/tests/unit/browser/test_urlmarks.py
index 6b8d429a9..16d6c4db2 100644
--- a/tests/unit/browser/test_urlmarks.py
+++ b/tests/unit/browser/test_urlmarks.py
@@ -22,7 +22,7 @@
import unittest.mock
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.browser import urlmarks
@@ -63,13 +63,13 @@ def test_add(bm_file, fake_save_manager, qtbot):
bm = urlmarks.BookmarkManager()
with qtbot.wait_signal(bm.changed):
- bm.add(QUrl('http://example.com'), 'Example Site')
+ bm.add(QtCore.QUrl('http://example.com'), 'Example Site')
assert list(bm.marks.items()) == [
('http://example.com', 'Example Site'),
]
with qtbot.wait_signal(bm.changed):
- bm.add(QUrl('http://example.com/notitle'), '')
+ bm.add(QtCore.QUrl('http://example.com/notitle'), '')
assert list(bm.marks.items()) == [
('http://example.com', 'Example Site'),
('http://example.com/notitle', ''),
@@ -80,32 +80,32 @@ def test_add_toggle(bm_file, fake_save_manager, qtbot):
bm = urlmarks.BookmarkManager()
with qtbot.wait_signal(bm.changed):
- bm.add(QUrl('http://example.com'), '', toggle=True)
+ bm.add(QtCore.QUrl('http://example.com'), '', toggle=True)
assert 'http://example.com' in bm.marks
with qtbot.wait_signal(bm.changed):
- bm.add(QUrl('http://example.com'), '', toggle=True)
+ bm.add(QtCore.QUrl('http://example.com'), '', toggle=True)
assert 'http://example.com' not in bm.marks
with qtbot.wait_signal(bm.changed):
- bm.add(QUrl('http://example.com'), '', toggle=True)
+ bm.add(QtCore.QUrl('http://example.com'), '', toggle=True)
assert 'http://example.com' in bm.marks
def test_add_dupe(bm_file, fake_save_manager, qtbot):
bm = urlmarks.BookmarkManager()
- bm.add(QUrl('http://example.com'), '')
+ bm.add(QtCore.QUrl('http://example.com'), '')
with pytest.raises(urlmarks.AlreadyExistsError):
- bm.add(QUrl('http://example.com'), '')
+ bm.add(QtCore.QUrl('http://example.com'), '')
def test_delete(bm_file, fake_save_manager, qtbot):
bm = urlmarks.BookmarkManager()
- bm.add(QUrl('http://example.com/foo'), 'Foo')
- bm.add(QUrl('http://example.com/bar'), 'Bar')
- bm.add(QUrl('http://example.com/baz'), 'Baz')
+ bm.add(QtCore.QUrl('http://example.com/foo'), 'Foo')
+ bm.add(QtCore.QUrl('http://example.com/bar'), 'Bar')
+ bm.add(QtCore.QUrl('http://example.com/baz'), 'Baz')
bm.save()
with qtbot.wait_signal(bm.changed):
@@ -119,8 +119,8 @@ def test_delete(bm_file, fake_save_manager, qtbot):
def test_save(bm_file, fake_save_manager, qtbot):
bm = urlmarks.BookmarkManager()
- bm.add(QUrl('http://example.com'), 'Example Site')
- bm.add(QUrl('http://example.com/notitle'), '')
+ bm.add(QtCore.QUrl('http://example.com'), 'Example Site')
+ bm.add(QtCore.QUrl('http://example.com/notitle'), '')
bm.save()
assert bm_file.read().splitlines() == [
'http://example.com Example Site',
diff --git a/tests/unit/browser/webengine/test_webengine_cookies.py b/tests/unit/browser/webengine/test_webengine_cookies.py
index 1a74dfb3e..db50729c7 100644
--- a/tests/unit/browser/webengine/test_webengine_cookies.py
+++ b/tests/unit/browser/webengine/test_webengine_cookies.py
@@ -18,10 +18,8 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtWebEngineWidgets, QtWebEngineCore, QtCore
pytest.importorskip('PyQt5.QtWebEngineCore')
-from PyQt5.QtWebEngineCore import QWebEngineCookieStore
-from PyQt5.QtWebEngineWidgets import QWebEngineProfile
from qutebrowser.browser.webengine import cookies
from qutebrowser.utils import urlmatch
@@ -29,8 +27,8 @@ from qutebrowser.utils import urlmatch
@pytest.fixture
def filter_request():
- request = QWebEngineCookieStore.FilterRequest()
- request.firstPartyUrl = QUrl('https://example.com')
+ request = QtWebEngineCore.QWebEngineCookieStore.FilterRequest()
+ request.firstPartyUrl = QtCore.QUrl('https://example.com')
return request
@@ -77,7 +75,7 @@ def test_invalid_url(config_stub, filter_request, global_value):
https://developers.google.com/youtube/youtube_player_demo
"""
config_stub.val.content.cookies.accept = global_value
- filter_request.firstPartyUrl = QUrl()
+ filter_request.firstPartyUrl = QtCore.QUrl()
accepted = global_value == 'all'
assert cookies._accept_cookie(filter_request) == accepted
@@ -102,7 +100,7 @@ def test_logging(monkeypatch, config_stub, filter_request, caplog, enabled):
class TestInstall:
def test_real_profile(self):
- profile = QWebEngineProfile()
+ profile = QtWebEngineWidgets.QWebEngineProfile()
cookies.install_filter(profile)
def test_fake_profile(self, stubs):
diff --git a/tests/unit/browser/webengine/test_webenginedownloads.py b/tests/unit/browser/webengine/test_webenginedownloads.py
index 877af3c9a..546216c0e 100644
--- a/tests/unit/browser/webengine/test_webenginedownloads.py
+++ b/tests/unit/browser/webengine/test_webenginedownloads.py
@@ -23,7 +23,7 @@ import dataclasses
import pytest
pytest.importorskip('PyQt5.QtWebEngineWidgets')
-from PyQt5.QtWebEngineWidgets import QWebEngineProfile
+from qutebrowser.qt import QtWebEngineWidgets
from qutebrowser.utils import urlutils, usertypes, utils
from qutebrowser.browser.webengine import webenginedownloads
@@ -104,7 +104,7 @@ class TestDataUrlWorkaround:
@pytest.fixture
def webengine_profile(self, qapp):
- profile = QWebEngineProfile.defaultProfile()
+ profile = QtWebEngineWidgets.QWebEngineProfile.defaultProfile()
profile.setParent(qapp)
return profile
diff --git a/tests/unit/browser/webengine/test_webengineinterceptor.py b/tests/unit/browser/webengine/test_webengineinterceptor.py
index eb71e0c6e..9c15c7d5c 100644
--- a/tests/unit/browser/webengine/test_webengineinterceptor.py
+++ b/tests/unit/browser/webengine/test_webengineinterceptor.py
@@ -24,7 +24,7 @@ import pytest
pytest.importorskip('PyQt5.QtWebEngineWidgets')
-from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInfo
+from qutebrowser.qt import QtWebEngineCore
from qutebrowser.browser.webengine import interceptor
@@ -32,8 +32,8 @@ from qutebrowser.browser.webengine import interceptor
def test_no_missing_resource_types():
request_interceptor = interceptor.RequestInterceptor()
qb_keys = request_interceptor._resource_types.keys()
- qt_keys = {i for i in vars(QWebEngineUrlRequestInfo).values()
- if isinstance(i, QWebEngineUrlRequestInfo.ResourceType)}
+ qt_keys = {i for i in vars(QtWebEngineCore.QWebEngineUrlRequestInfo).values()
+ if isinstance(i, QtWebEngineCore.QWebEngineUrlRequestInfo.ResourceType)}
assert qt_keys == qb_keys
diff --git a/tests/unit/browser/webkit/http/test_http.py b/tests/unit/browser/webkit/http/test_http.py
index 4db78f4ff..75d70e0da 100644
--- a/tests/unit/browser/webkit/http/test_http.py
+++ b/tests/unit/browser/webkit/http/test_http.py
@@ -24,7 +24,7 @@ import logging
import pytest
import hypothesis
from hypothesis import strategies
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.browser.webkit import http
@@ -38,7 +38,7 @@ from qutebrowser.browser.webkit import http
('http://example.com/', 'qutebrowser-download'),
])
def test_no_content_disposition(stubs, url, expected):
- reply = stubs.FakeNetworkReply(url=QUrl(url))
+ reply = stubs.FakeNetworkReply(url=QtCore.QUrl(url))
inline, filename = http.parse_content_disposition(reply)
assert inline
assert filename == expected
diff --git a/tests/unit/browser/webkit/network/test_filescheme.py b/tests/unit/browser/webkit/network/test_filescheme.py
index 12cacb5a2..17b45cd57 100644
--- a/tests/unit/browser/webkit/network/test_filescheme.py
+++ b/tests/unit/browser/webkit/network/test_filescheme.py
@@ -24,8 +24,7 @@ from typing import List
import pytest
import bs4
-from PyQt5.QtCore import QUrl
-from PyQt5.QtNetwork import QNetworkRequest
+from qutebrowser.qt import QtNetwork, QtCore
from qutebrowser.browser.webkit.network import filescheme
from qutebrowser.utils import urlutils, utils
@@ -257,8 +256,8 @@ class TestDirbrowserHtml:
class TestFileSchemeHandler:
def test_dir(self, tmpdir):
- url = QUrl.fromLocalFile(str(tmpdir))
- req = QNetworkRequest(url)
+ url = QtCore.QUrl.fromLocalFile(str(tmpdir))
+ req = QtNetwork.QNetworkRequest(url)
reply = filescheme.handler(req, None, None)
# The URL will always use /, even on Windows - so we force this here
# too.
@@ -268,14 +267,14 @@ class TestFileSchemeHandler:
def test_file(self, tmpdir):
filename = tmpdir / 'foo'
filename.ensure()
- url = QUrl.fromLocalFile(str(filename))
- req = QNetworkRequest(url)
+ url = QtCore.QUrl.fromLocalFile(str(filename))
+ req = QtNetwork.QNetworkRequest(url)
reply = filescheme.handler(req, None, None)
assert reply is None
def test_unicode_encode_error(self, mocker):
- url = QUrl('file:///tmp/foo')
- req = QNetworkRequest(url)
+ url = QtCore.QUrl('file:///tmp/foo')
+ req = QtNetwork.QNetworkRequest(url)
err = UnicodeEncodeError('ascii', '', 0, 2, 'foo')
mocker.patch('os.path.isdir', side_effect=err)
diff --git a/tests/unit/browser/webkit/network/test_networkreply.py b/tests/unit/browser/webkit/network/test_networkreply.py
index 3cffb2fd7..8682ff33d 100644
--- a/tests/unit/browser/webkit/network/test_networkreply.py
+++ b/tests/unit/browser/webkit/network/test_networkreply.py
@@ -21,15 +21,13 @@
import pytest
-from PyQt5.QtCore import QUrl, QIODevice
-from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply
-
from qutebrowser.browser.webkit.network import networkreply
+from qutebrowser.qt import QtNetwork, QtCore
@pytest.fixture
def req():
- return QNetworkRequest(QUrl('http://www.qutebrowser.org/'))
+ return QtNetwork.QNetworkRequest(QtCore.QUrl('http://www.qutebrowser.org/'))
class TestFixedDataNetworkReply:
@@ -38,11 +36,11 @@ class TestFixedDataNetworkReply:
reply = networkreply.FixedDataNetworkReply(req, b'', 'test/foo')
assert reply.request() == req
assert reply.url() == req.url()
- assert reply.openMode() == QIODevice.ReadOnly
- assert reply.header(QNetworkRequest.ContentTypeHeader) == 'test/foo'
- http_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute)
+ assert reply.openMode() == QtCore.QIODevice.ReadOnly
+ assert reply.header(QtNetwork.QNetworkRequest.ContentTypeHeader) == 'test/foo'
+ http_code = reply.attribute(QtNetwork.QNetworkRequest.HttpStatusCodeAttribute)
http_reason = reply.attribute(
- QNetworkRequest.HttpReasonPhraseAttribute)
+ QtNetwork.QNetworkRequest.HttpReasonPhraseAttribute)
assert http_code == 200
assert http_reason == 'OK'
assert reply.isFinished()
@@ -76,7 +74,7 @@ class TestFixedDataNetworkReply:
def test_error_network_reply(qtbot, req):
reply = networkreply.ErrorNetworkReply(
- req, "This is an error", QNetworkReply.UnknownNetworkError)
+ req, "This is an error", QtNetwork.QNetworkReply.UnknownNetworkError)
with qtbot.wait_signals([reply.error, reply.finished], order='strict'):
pass
@@ -84,18 +82,18 @@ def test_error_network_reply(qtbot, req):
reply.abort() # shouldn't do anything
assert reply.request() == req
assert reply.url() == req.url()
- assert reply.openMode() == QIODevice.ReadOnly
+ assert reply.openMode() == QtCore.QIODevice.ReadOnly
assert reply.isFinished()
assert not reply.isRunning()
assert reply.bytesAvailable() == 0
assert reply.readData(1) == b''
- assert reply.error() == QNetworkReply.UnknownNetworkError
+ assert reply.error() == QtNetwork.QNetworkReply.UnknownNetworkError
assert reply.errorString() == "This is an error"
def test_redirect_network_reply():
- url = QUrl('https://www.example.com/')
+ url = QtCore.QUrl('https://www.example.com/')
reply = networkreply.RedirectNetworkReply(url)
assert reply.readData(1) == b''
- assert reply.attribute(QNetworkRequest.RedirectionTargetAttribute) == url
+ assert reply.attribute(QtNetwork.QNetworkRequest.RedirectionTargetAttribute) == url
reply.abort() # shouldn't do anything
diff --git a/tests/unit/browser/webkit/network/test_pac.py b/tests/unit/browser/webkit/network/test_pac.py
index 79b34be9a..9187e0d03 100644
--- a/tests/unit/browser/webkit/network/test_pac.py
+++ b/tests/unit/browser/webkit/network/test_pac.py
@@ -22,9 +22,7 @@ import threading
import logging
import pytest
-from PyQt5.QtCore import QUrl
-from PyQt5.QtNetwork import (QNetworkProxy, QNetworkProxyQuery, QHostInfo,
- QHostAddress)
+from qutebrowser.qt import QtNetwork, QtCore
from qutebrowser.browser.network import pac
@@ -42,13 +40,13 @@ def _pac_common_test(test_str):
fun_str = fun_str_f.format(test_str)
res = pac.PACResolver(fun_str)
- proxies = res.resolve(QNetworkProxyQuery(QUrl("https://example.com/test")))
+ proxies = res.resolve(QtNetwork.QNetworkProxyQuery(QtCore.QUrl("https://example.com/test")))
assert len(proxies) == 3
- assert proxies[0].type() == QNetworkProxy.NoProxy
- assert proxies[1].type() == QNetworkProxy.HttpProxy
+ assert proxies[0].type() == QtNetwork.QNetworkProxy.NoProxy
+ assert proxies[1].type() == QtNetwork.QNetworkProxy.HttpProxy
assert proxies[1].hostName() == "127.0.0.1"
assert proxies[1].port() == 8080
- assert proxies[2].type() == QNetworkProxy.Socks5Proxy
+ assert proxies[2].type() == QtNetwork.QNetworkProxy.Socks5Proxy
assert proxies[2].hostName() == "192.168.1.1"
assert proxies[2].port() == 4444
@@ -96,11 +94,11 @@ def _pac_noexcept_test(call):
])
def test_dnsResolve(monkeypatch, domain, expected):
def mock_fromName(host):
- info = QHostInfo()
+ info = QtNetwork.QHostInfo()
if host == "known.domain":
- info.setAddresses([QHostAddress("1.2.3.4")])
+ info.setAddresses([QtNetwork.QHostAddress("1.2.3.4")])
return info
- monkeypatch.setattr(QHostInfo, 'fromName', mock_fromName)
+ monkeypatch.setattr(QtNetwork.QHostInfo, 'fromName', mock_fromName)
_pac_equality_test("dnsResolve('{}')".format(domain), expected)
@@ -130,7 +128,7 @@ def test_invalid_port():
res = pac.PACResolver(test_str)
with pytest.raises(pac.ParseProxyError):
- res.resolve(QNetworkProxyQuery(QUrl("https://example.com/test")))
+ res.resolve(QtNetwork.QNetworkProxyQuery(QtCore.QUrl("https://example.com/test")))
@pytest.mark.parametrize('string', ["", "{"])
@@ -155,7 +153,7 @@ def test_fail_parse(value):
res = pac.PACResolver(test_str_f.format(value))
with pytest.raises(pac.ParseProxyError):
- res.resolve(QNetworkProxyQuery(QUrl("https://example.com/test")))
+ res.resolve(QtNetwork.QNetworkProxyQuery(QtCore.QUrl("https://example.com/test")))
def test_fail_return():
@@ -167,7 +165,7 @@ def test_fail_return():
res = pac.PACResolver(test_str)
with pytest.raises(pac.EvalProxyError):
- res.resolve(QNetworkProxyQuery(QUrl("https://example.com/test")))
+ res.resolve(QtNetwork.QNetworkProxyQuery(QtCore.QUrl("https://example.com/test")))
@pytest.mark.parametrize('url, has_secret', [
@@ -202,7 +200,7 @@ def test_secret_url(url, has_secret, from_file):
}}
""".format('true' if (has_secret or from_file) else 'false')
res = pac.PACResolver(test_str)
- res.resolve(QNetworkProxyQuery(QUrl(url)), from_file=from_file)
+ res.resolve(QtNetwork.QNetworkProxyQuery(QtCore.QUrl(url)), from_file=from_file)
def test_logging(qtlog):
@@ -214,7 +212,7 @@ def test_logging(qtlog):
}
"""
res = pac.PACResolver(test_str)
- res.resolve(QNetworkProxyQuery(QUrl("https://example.com/test")))
+ res.resolve(QtNetwork.QNetworkProxyQuery(QtCore.QUrl("https://example.com/test")))
assert len(qtlog.records) == 1
assert qtlog.records[0].message == 'logging test'
@@ -241,7 +239,7 @@ def fetcher_test(test_str):
serve_thread.start()
try:
ready_event.wait()
- fetcher = pac.PACFetcher(QUrl("pac+http://127.0.0.1:8081"))
+ fetcher = pac.PACFetcher(QtCore.QUrl("pac+http://127.0.0.1:8081"))
fetcher.fetch()
assert fetcher.fetch_error() is None
finally:
@@ -257,7 +255,7 @@ def test_fetch_success():
"""
res = fetcher_test(test_str)
- proxies = res.resolve(QNetworkProxyQuery(QUrl("https://example.com/test")))
+ proxies = res.resolve(QtNetwork.QNetworkProxyQuery(QtCore.QUrl("https://example.com/test")))
assert len(proxies) == 3
@@ -270,6 +268,6 @@ def test_fetch_evalerror(caplog):
res = fetcher_test(test_str)
with caplog.at_level(logging.ERROR):
- proxies = res.resolve(QNetworkProxyQuery(QUrl("https://example.com/test")))
+ proxies = res.resolve(QtNetwork.QNetworkProxyQuery(QtCore.QUrl("https://example.com/test")))
assert len(proxies) == 1
assert proxies[0].port() == 9
diff --git a/tests/unit/browser/webkit/test_cache.py b/tests/unit/browser/webkit/test_cache.py
index 83d5054d7..ecf022c93 100644
--- a/tests/unit/browser/webkit/test_cache.py
+++ b/tests/unit/browser/webkit/test_cache.py
@@ -19,10 +19,9 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
import pytest
-from PyQt5.QtCore import QUrl, QDateTime
-from PyQt5.QtNetwork import QNetworkDiskCache, QNetworkCacheMetaData
from qutebrowser.browser.webkit import cache
+from qutebrowser.qt import QtNetwork, QtCore
@pytest.fixture
@@ -31,8 +30,8 @@ def disk_cache(tmpdir, config_stub):
def preload_cache(cache, url='http://www.example.com/', content=b'foobar'):
- metadata = QNetworkCacheMetaData()
- metadata.setUrl(QUrl(url))
+ metadata = QtNetwork.QNetworkCacheMetaData()
+ metadata.setUrl(QtCore.QUrl(url))
assert metadata.isValid()
device = cache.prepare(metadata)
assert device is not None
@@ -74,8 +73,8 @@ def test_cache_existing_metadata_file(tmpdir, disk_cache):
url = 'http://qutebrowser.org'
content = b'foobar'
- metadata = QNetworkCacheMetaData()
- metadata.setUrl(QUrl(url))
+ metadata = QtNetwork.QNetworkCacheMetaData()
+ metadata.setUrl(QtCore.QUrl(url))
assert metadata.isValid()
device = disk_cache.prepare(metadata)
@@ -99,7 +98,7 @@ def test_cache_get_nonexistent_data(disk_cache):
"""Test querying some data that was never inserted."""
preload_cache(disk_cache, 'https://qutebrowser.org')
- assert disk_cache.data(QUrl('http://qutebrowser.org')) is None
+ assert disk_cache.data(QtCore.QUrl('http://qutebrowser.org')) is None
def test_cache_insert_data(disk_cache):
@@ -111,7 +110,7 @@ def test_cache_insert_data(disk_cache):
preload_cache(disk_cache, url, content)
assert disk_cache.cacheSize() != 0
- assert disk_cache.data(QUrl(url)).readAll() == content
+ assert disk_cache.data(QtCore.QUrl(url)).readAll() == content
def test_cache_remove_data(disk_cache):
@@ -120,7 +119,7 @@ def test_cache_remove_data(disk_cache):
preload_cache(disk_cache, url)
assert disk_cache.cacheSize() > 0
- assert disk_cache.remove(QUrl(url))
+ assert disk_cache.remove(QtCore.QUrl(url))
assert disk_cache.cacheSize() == 0
@@ -138,14 +137,14 @@ def test_cache_clear_activated(disk_cache):
def test_cache_metadata(disk_cache):
"""Ensure that DiskCache.metaData() returns exactly what was inserted."""
url = 'http://qutebrowser.org'
- metadata = QNetworkCacheMetaData()
- metadata.setUrl(QUrl(url))
+ metadata = QtNetwork.QNetworkCacheMetaData()
+ metadata.setUrl(QtCore.QUrl(url))
assert metadata.isValid()
device = disk_cache.prepare(metadata)
device.write(b'foobar')
disk_cache.insert(device)
- assert disk_cache.metaData(QUrl(url)) == metadata
+ assert disk_cache.metaData(QtCore.QUrl(url)) == metadata
def test_cache_update_metadata(disk_cache):
@@ -154,16 +153,16 @@ def test_cache_update_metadata(disk_cache):
preload_cache(disk_cache, url, b'foo')
assert disk_cache.cacheSize() > 0
- metadata = QNetworkCacheMetaData()
- metadata.setUrl(QUrl(url))
+ metadata = QtNetwork.QNetworkCacheMetaData()
+ metadata.setUrl(QtCore.QUrl(url))
assert metadata.isValid()
disk_cache.updateMetaData(metadata)
- assert disk_cache.metaData(QUrl(url)) == metadata
+ assert disk_cache.metaData(QtCore.QUrl(url)) == metadata
def test_cache_full(tmpdir):
"""Do a sanity test involving everything."""
- disk_cache = QNetworkDiskCache()
+ disk_cache = QtNetwork.QNetworkDiskCache()
disk_cache.setCacheDirectory(str(tmpdir))
url = 'http://qutebrowser.org'
@@ -173,14 +172,14 @@ def test_cache_full(tmpdir):
content2 = b'ohmycert'
preload_cache(disk_cache, url2, content2)
- metadata = QNetworkCacheMetaData()
- metadata.setUrl(QUrl(url))
- soon = QDateTime.currentDateTime().addMonths(4)
+ metadata = QtNetwork.QNetworkCacheMetaData()
+ metadata.setUrl(QtCore.QUrl(url))
+ soon = QtCore.QDateTime.currentDateTime().addMonths(4)
assert soon.isValid()
metadata.setLastModified(soon)
assert metadata.isValid()
disk_cache.updateMetaData(metadata)
- disk_cache.remove(QUrl(url2))
+ disk_cache.remove(QtCore.QUrl(url2))
- assert disk_cache.metaData(QUrl(url)).lastModified() == soon
- assert disk_cache.data(QUrl(url)).readAll() == content
+ assert disk_cache.metaData(QtCore.QUrl(url)).lastModified() == soon
+ assert disk_cache.data(QtCore.QUrl(url)).readAll() == content
diff --git a/tests/unit/browser/webkit/test_certificateerror.py b/tests/unit/browser/webkit/test_certificateerror.py
index e615854ca..26bdb1b3b 100644
--- a/tests/unit/browser/webkit/test_certificateerror.py
+++ b/tests/unit/browser/webkit/test_certificateerror.py
@@ -18,7 +18,7 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
import pytest
-from PyQt5.QtNetwork import QSslError
+from qutebrowser.qt import QtNetwork
from qutebrowser.browser.webkit import certificateerror
@@ -34,13 +34,13 @@ class FakeError:
@pytest.mark.parametrize('errors, expected', [
(
- [QSslError(QSslError.UnableToGetIssuerCertificate)],
+ [QtNetwork.QSslError(QtNetwork.QSslError.UnableToGetIssuerCertificate)],
['<p>The issuer certificate could not be found</p>'],
),
(
[
- QSslError(QSslError.UnableToGetIssuerCertificate),
- QSslError(QSslError.UnableToDecryptCertificateSignature),
+ QtNetwork.QSslError(QtNetwork.QSslError.UnableToGetIssuerCertificate),
+ QtNetwork.QSslError(QtNetwork.QSslError.UnableToDecryptCertificateSignature),
],
[
'<ul>',
diff --git a/tests/unit/browser/webkit/test_cookies.py b/tests/unit/browser/webkit/test_cookies.py
index 81da561ce..1a2fa0ad9 100644
--- a/tests/unit/browser/webkit/test_cookies.py
+++ b/tests/unit/browser/webkit/test_cookies.py
@@ -18,8 +18,8 @@
# You should have received a copy of the GNU General Public License
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
-from PyQt5.QtNetwork import QNetworkCookie
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtNetwork
+from qutebrowser.qt import QtCore
import pytest
from qutebrowser.browser.webkit import cookies
@@ -66,7 +66,7 @@ class TestSetCookies:
@pytest.fixture
def cookie(self):
- return QNetworkCookie(b'foo', b'bar')
+ return QtNetwork.QNetworkCookie(b'foo', b'bar')
@pytest.fixture
def ram_jar(self):
@@ -74,7 +74,7 @@ class TestSetCookies:
@pytest.fixture
def url(self):
- return QUrl('http://example.com/')
+ return QtCore.QUrl('http://example.com/')
@pytest.fixture(autouse=True)
def set_webkit_backend(self, monkeypatch):
@@ -110,7 +110,7 @@ class TestSetCookies:
config_stub.set_str('content.cookies.accept', 'never',
pattern=urlmatch.UrlPattern('http://example.com'))
- org_url = QUrl('http://example.org/')
+ org_url = QtCore.QUrl('http://example.org/')
with qtbot.wait_signal(ram_jar.changed):
assert ram_jar.setCookiesFromUrl([cookie], org_url)
diff --git a/tests/unit/browser/webkit/test_tabhistory.py b/tests/unit/browser/webkit/test_tabhistory.py
index d1c4a25a4..3616c8fb2 100644
--- a/tests/unit/browser/webkit/test_tabhistory.py
+++ b/tests/unit/browser/webkit/test_tabhistory.py
@@ -24,40 +24,40 @@ from typing import Any
import pytest
pytest.importorskip('PyQt5.QtWebKit')
-from PyQt5.QtCore import QUrl, QPoint
-from PyQt5.QtWebKit import QWebHistory
+from qutebrowser.qt import QtWebKit
from qutebrowser.browser.webkit import tabhistory
from qutebrowser.misc.sessions import TabHistoryItem as Item
from qutebrowser.utils import qtutils
+from qutebrowser.qt import QtCore
pytestmark = pytest.mark.qt_log_ignore('QIODevice::read.*: device not open')
ITEMS = [
- Item(QUrl('https://www.heise.de/'), 'heise'),
- Item(QUrl('about:blank'), 'blank', active=True),
- Item(QUrl('http://example.com/%E2%80%A6'), 'percent'),
- Item(QUrl('http://example.com/?foo=bar'), 'arg',
- original_url=QUrl('http://original.url.example.com/'),
+ Item(QtCore.QUrl('https://www.heise.de/'), 'heise'),
+ Item(QtCore.QUrl('about:blank'), 'blank', active=True),
+ Item(QtCore.QUrl('http://example.com/%E2%80%A6'), 'percent'),
+ Item(QtCore.QUrl('http://example.com/?foo=bar'), 'arg',
+ original_url=QtCore.QUrl('http://original.url.example.com/'),
user_data={'foo': 23, 'bar': 42}),
# From https://github.com/OtterBrowser/otter-browser/issues/709#issuecomment-74749471
- Item(QUrl('http://github.com/OtterBrowser/24/134/2344/otter-browser/'
+ Item(QtCore.QUrl('http://github.com/OtterBrowser/24/134/2344/otter-browser/'
'issues/709/'),
'Page not found | github',
- user_data={'zoom': 149, 'scroll-pos': QPoint(0, 0)}),
- Item(QUrl('https://mail.google.com/mail/u/0/#label/some+label/'
+ user_data={'zoom': 149, 'scroll-pos': QtCore.QPoint(0, 0)}),
+ Item(QtCore.QUrl('https://mail.google.com/mail/u/0/#label/some+label/'
'234lkjsd0932lkjf884jqwerdf4'),
'"some label" - email@gmail.com - Gmail"',
- user_data={'zoom': 120, 'scroll-pos': QPoint(0, 0)}),
+ user_data={'zoom': 120, 'scroll-pos': QtCore.QPoint(0, 0)}),
]
@dataclasses.dataclass
class Objects:
- history: QWebHistory
+ history: QtWebKit.QWebHistory
user_data: Any
@@ -125,16 +125,16 @@ def test_titles(objects, i, item):
def test_no_active_item():
"""Check tabhistory.serialize with no active item."""
- items = [Item(QUrl(), '')]
+ items = [Item(QtCore.QUrl(), '')]
with pytest.raises(ValueError):
tabhistory.serialize(items)
def test_two_active_items():
"""Check tabhistory.serialize with two active items."""
- items = [Item(QUrl(), '', active=True),
- Item(QUrl(), ''),
- Item(QUrl(), '', active=True)]
+ items = [Item(QtCore.QUrl(), '', active=True),
+ Item(QtCore.QUrl(), ''),
+ Item(QtCore.QUrl(), '', active=True)]
with pytest.raises(ValueError):
tabhistory.serialize(items)
diff --git a/tests/unit/browser/webkit/test_webkitelem.py b/tests/unit/browser/webkit/test_webkitelem.py
index f7cc3e8c2..4c3a30b11 100644
--- a/tests/unit/browser/webkit/test_webkitelem.py
+++ b/tests/unit/browser/webkit/test_webkitelem.py
@@ -27,13 +27,14 @@ import itertools
import dataclasses
import pytest
-from PyQt5.QtCore import QRect, QPoint, QUrl
QWebElement = pytest.importorskip('PyQt5.QtWebKit').QWebElement
from qutebrowser.browser import browsertab
from qutebrowser.browser.webkit import webkitelem
from qutebrowser.misc import objects
from qutebrowser.utils import usertypes
+from qutebrowser.qt import QtCore
+
if TYPE_CHECKING:
from helpers import stubs
@@ -487,19 +488,19 @@ class TestIsVisible:
@pytest.fixture
def frame(self, stubs):
- return stubs.FakeWebFrame(QRect(0, 0, 100, 100))
+ return stubs.FakeWebFrame(QtCore.QRect(0, 0, 100, 100))
def test_invalid_frame_geometry(self, stubs):
"""Test with an invalid frame geometry."""
- rect = QRect(0, 0, 0, 0)
+ rect = QtCore.QRect(0, 0, 0, 0)
assert not rect.isValid()
frame = stubs.FakeWebFrame(rect)
- elem = get_webelem(QRect(0, 0, 10, 10), frame)
+ elem = get_webelem(QtCore.QRect(0, 0, 10, 10), frame)
assert not elem._is_visible(frame)
def test_invalid_invisible(self, frame):
"""Test elements with an invalid geometry which are invisible."""
- elem = get_webelem(QRect(0, 0, 0, 0), frame)
+ elem = get_webelem(QtCore.QRect(0, 0, 0, 0), frame)
assert not elem.geometry().isValid()
assert elem.geometry().x() == 0
assert not elem._is_visible(frame)
@@ -510,17 +511,17 @@ class TestIsVisible:
This seems to happen sometimes in the real world, with real elements
which *are* visible, but don't have a valid geometry.
"""
- elem = get_webelem(QRect(10, 10, 0, 0), frame)
+ elem = get_webelem(QtCore.QRect(10, 10, 0, 0), frame)
assert not elem.geometry().isValid()
assert elem._is_visible(frame)
@pytest.mark.parametrize('geometry, visible', [
- (QRect(5, 5, 4, 4), False),
- (QRect(10, 10, 1, 1), True),
+ (QtCore.QRect(5, 5, 4, 4), False),
+ (QtCore.QRect(10, 10, 1, 1), True),
])
def test_scrolled(self, geometry, visible, stubs):
- scrolled_frame = stubs.FakeWebFrame(QRect(0, 0, 100, 100),
- scroll=QPoint(10, 10))
+ scrolled_frame = stubs.FakeWebFrame(QtCore.QRect(0, 0, 100, 100),
+ scroll=QtCore.QPoint(10, 10))
elem = get_webelem(geometry, scrolled_frame)
assert elem._is_visible(scrolled_frame) == visible
@@ -533,7 +534,7 @@ class TestIsVisible:
({'visibility': 'hidden', 'display': 'inline'}, False),
])
def test_css_attributes(self, frame, style, visible):
- elem = get_webelem(QRect(0, 0, 10, 10), frame, style=style)
+ elem = get_webelem(QtCore.QRect(0, 0, 10, 10), frame, style=style)
assert elem._is_visible(frame) == visible
@@ -579,14 +580,14 @@ class TestIsVisibleIframe:
Returns an Objects object with frame/iframe/elems attributes.
"""
- frame = stubs.FakeWebFrame(QRect(0, 0, 300, 300))
- iframe = stubs.FakeWebFrame(QRect(0, 10, 100, 100), parent=frame)
+ frame = stubs.FakeWebFrame(QtCore.QRect(0, 0, 300, 300))
+ iframe = stubs.FakeWebFrame(QtCore.QRect(0, 10, 100, 100), parent=frame)
assert frame.geometry().contains(iframe.geometry())
elems = [
- get_webelem(QRect(0, 0, 10, 10), iframe),
- get_webelem(QRect(20, 90, 10, 10), iframe),
- get_webelem(QRect(20, 150, 10, 10), iframe),
- get_webelem(QRect(30, 180, 10, 10), frame),
+ get_webelem(QtCore.QRect(0, 0, 10, 10), iframe),
+ get_webelem(QtCore.QRect(20, 90, 10, 10), iframe),
+ get_webelem(QtCore.QRect(20, 150, 10, 10), iframe),
+ get_webelem(QtCore.QRect(30, 180, 10, 10), frame),
]
assert elems[0]._is_visible(frame)
@@ -598,7 +599,7 @@ class TestIsVisibleIframe:
def test_iframe_scrolled(self, objects):
"""Scroll iframe down so elem3 gets visible and elem1/elem2 not."""
- objects.iframe.scrollPosition.return_value = QPoint(0, 100)
+ objects.iframe.scrollPosition.return_value = QtCore.QPoint(0, 100)
assert not objects.elems[0]._is_visible(objects.frame)
assert not objects.elems[1]._is_visible(objects.frame)
assert objects.elems[2]._is_visible(objects.frame)
@@ -606,7 +607,7 @@ class TestIsVisibleIframe:
def test_mainframe_scrolled_iframe_visible(self, objects):
"""Scroll mainframe down so iframe is partly visible but elem1 not."""
- objects.frame.scrollPosition.return_value = QPoint(0, 50)
+ objects.frame.scrollPosition.return_value = QtCore.QPoint(0, 50)
geom = objects.frame.geometry().translated(
objects.frame.scrollPosition())
assert not geom.contains(objects.iframe.geometry())
@@ -618,7 +619,7 @@ class TestIsVisibleIframe:
def test_mainframe_scrolled_iframe_invisible(self, objects):
"""Scroll mainframe down so iframe is invisible."""
- objects.frame.scrollPosition.return_value = QPoint(0, 110)
+ objects.frame.scrollPosition.return_value = QtCore.QPoint(0, 110)
geom = objects.frame.geometry().translated(
objects.frame.scrollPosition())
assert not geom.contains(objects.iframe.geometry())
@@ -650,13 +651,13 @@ class TestIsVisibleIframe:
Returns an Objects object with frame/iframe/elems attributes.
"""
- frame = stubs.FakeWebFrame(QRect(0, 0, 300, 300))
- iframe = stubs.FakeWebFrame(QRect(0, 10, 100, 100), parent=frame)
+ frame = stubs.FakeWebFrame(QtCore.QRect(0, 0, 300, 300))
+ iframe = stubs.FakeWebFrame(QtCore.QRect(0, 10, 100, 100), parent=frame)
assert frame.geometry().contains(iframe.geometry())
elems = [
- get_webelem(QRect(10, 10, 0, 0), iframe),
- get_webelem(QRect(20, 150, 0, 0), iframe),
+ get_webelem(QtCore.QRect(10, 10, 0, 0), iframe),
+ get_webelem(QtCore.QRect(20, 150, 0, 0), iframe),
]
for e in elems:
assert not e.geometry().isValid()
@@ -688,18 +689,18 @@ class TestRectOnView:
{'length': '1', '0': {'width': 0, 'height': 0, 'x': 0, 'y': 0}},
])
def test_simple(self, stubs, js_rect):
- geometry = QRect(5, 5, 4, 4)
- frame = stubs.FakeWebFrame(QRect(0, 0, 100, 100))
+ geometry = QtCore.QRect(5, 5, 4, 4)
+ frame = stubs.FakeWebFrame(QtCore.QRect(0, 0, 100, 100))
elem = get_webelem(geometry, frame, js_rect_return=js_rect)
- assert elem.rect_on_view() == QRect(5, 5, 4, 4)
+ assert elem.rect_on_view() == QtCore.QRect(5, 5, 4, 4)
@pytest.mark.parametrize('js_rect', [None, {}])
def test_scrolled(self, stubs, js_rect):
- geometry = QRect(20, 20, 4, 4)
- frame = stubs.FakeWebFrame(QRect(0, 0, 100, 100),
- scroll=QPoint(10, 10))
+ geometry = QtCore.QRect(20, 20, 4, 4)
+ frame = stubs.FakeWebFrame(QtCore.QRect(0, 0, 100, 100),
+ scroll=QtCore.QPoint(10, 10))
elem = get_webelem(geometry, frame, js_rect_return=js_rect)
- assert elem.rect_on_view() == QRect(20 - 10, 20 - 10, 4, 4)
+ assert elem.rect_on_view() == QtCore.QRect(20 - 10, 20 - 10, 4, 4)
@pytest.mark.parametrize('js_rect', [None, {}])
def test_iframe(self, stubs, js_rect):
@@ -718,19 +719,19 @@ class TestRectOnView:
##############################
200, 0 200, 200
"""
- frame = stubs.FakeWebFrame(QRect(0, 0, 200, 200))
- iframe = stubs.FakeWebFrame(QRect(0, 10, 100, 100), parent=frame)
+ frame = stubs.FakeWebFrame(QtCore.QRect(0, 0, 200, 200))
+ iframe = stubs.FakeWebFrame(QtCore.QRect(0, 10, 100, 100), parent=frame)
assert frame.geometry().contains(iframe.geometry())
- elem = get_webelem(QRect(20, 90, 10, 10), iframe,
+ elem = get_webelem(QtCore.QRect(20, 90, 10, 10), iframe,
js_rect_return=js_rect)
- assert elem.rect_on_view() == QRect(20, 10 + 90, 10, 10)
+ assert elem.rect_on_view() == QtCore.QRect(20, 10 + 90, 10, 10)
@pytest.mark.parametrize('js_rect', [None, {}])
def test_passed_geometry(self, stubs, js_rect):
"""Make sure geometry isn't called when a geometry is passed."""
- frame = stubs.FakeWebFrame(QRect(0, 0, 200, 200))
+ frame = stubs.FakeWebFrame(QtCore.QRect(0, 0, 200, 200))
elem = get_webelem(frame=frame, js_rect_return=js_rect)
- rect = QRect(10, 20, 30, 40)
+ rect = QtCore.QRect(10, 20, 30, 40)
assert elem.rect_on_view(elem_geometry=rect) == rect
assert not elem._elem.geometry.called
@@ -741,11 +742,11 @@ class TestRectOnView:
"""Make sure the coordinates are adjusted when zoomed."""
monkeypatch.setattr(objects, 'backend', usertypes.Backend.QtWebKit)
config_stub.val.zoom.text_only = zoom_text_only
- geometry = QRect(10, 10, 4, 4)
- frame = stubs.FakeWebFrame(QRect(0, 0, 100, 100), zoom=0.5)
+ geometry = QtCore.QRect(10, 10, 4, 4)
+ frame = stubs.FakeWebFrame(QtCore.QRect(0, 0, 100, 100), zoom=0.5)
elem = get_webelem(geometry, frame, js_rect_return=js_rect,
zoom_text_only=zoom_text_only)
- assert elem.rect_on_view() == QRect(10, 10, 4, 4)
+ assert elem.rect_on_view() == QtCore.QRect(10, 10, 4, 4)
class TestGetChildFrames:
@@ -885,20 +886,20 @@ class TestIsEditable:
@pytest.mark.parametrize('attributes, expected', [
# No attributes
({}, None),
- ({'href': 'foo'}, QUrl('http://www.example.com/foo')),
- ({'src': 'foo'}, QUrl('http://www.example.com/foo')),
- ({'href': 'foo', 'src': 'bar'}, QUrl('http://www.example.com/foo')),
+ ({'href': 'foo'}, QtCore.QUrl('http://www.example.com/foo')),
+ ({'src': 'foo'}, QtCore.QUrl('http://www.example.com/foo')),
+ ({'href': 'foo', 'src': 'bar'}, QtCore.QUrl('http://www.example.com/foo')),
({'href': '::garbage::'}, None),
- ({'href': 'http://www.example.org/'}, QUrl('http://www.example.org/')),
- ({'href': ' foo '}, QUrl('http://www.example.com/foo')),
+ ({'href': 'http://www.example.org/'}, QtCore.QUrl('http://www.example.org/')),
+ ({'href': ' foo '}, QtCore.QUrl('http://www.example.com/foo')),
])
def test_resolve_url(attributes, expected):
elem = get_webelem(attributes=attributes)
- baseurl = QUrl('http://www.example.com/')
+ baseurl = QtCore.QUrl('http://www.example.com/')
assert elem.resolve_url(baseurl) == expected
def test_resolve_url_relative_base():
elem = get_webelem(attributes={'href': 'foo'})
with pytest.raises(ValueError):
- elem.resolve_url(QUrl('base'))
+ elem.resolve_url(QtCore.QUrl('base'))
diff --git a/tests/unit/commands/test_argparser.py b/tests/unit/commands/test_argparser.py
index cfa94c552..8ce0ea6f1 100644
--- a/tests/unit/commands/test_argparser.py
+++ b/tests/unit/commands/test_argparser.py
@@ -23,7 +23,7 @@ import inspect
import enum
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.commands import argparser, cmdexc
@@ -62,7 +62,7 @@ class TestArgumentParser:
with pytest.raises(argparser.ArgumentParserExit):
parser.parse_args(['--help'])
- expected_url = QUrl('qute://help/commands.html#foo')
+ expected_url = QtCore.QUrl('qute://help/commands.html#foo')
assert tabbed_browser_stubs[1].loaded_url == expected_url
diff --git a/tests/unit/commands/test_userscripts.py b/tests/unit/commands/test_userscripts.py
index 436e9e2a7..4ff2dd393 100644
--- a/tests/unit/commands/test_userscripts.py
+++ b/tests/unit/commands/test_userscripts.py
@@ -25,7 +25,7 @@ import logging
import signal
import pytest
-from PyQt5.QtCore import QFileSystemWatcher
+from qutebrowser.qt import QtCore
from qutebrowser.commands import userscripts
from qutebrowser.utils import utils
@@ -171,7 +171,7 @@ def test_command_with_error(qtbot, py_proc, runner, caplog):
def test_killed_command(qtbot, tmp_path, py_proc, runner, caplog):
data_file = tmp_path / 'data'
- watcher = QFileSystemWatcher()
+ watcher = QtCore.QFileSystemWatcher()
watcher.addPath(str(tmp_path))
cmd, args = py_proc(r"""
diff --git a/tests/unit/completion/test_completer.py b/tests/unit/completion/test_completer.py
index 467357d32..637c154b7 100644
--- a/tests/unit/completion/test_completer.py
+++ b/tests/unit/completion/test_completer.py
@@ -22,8 +22,7 @@
import unittest.mock
import pytest
-from PyQt5.QtCore import QObject
-from PyQt5.QtGui import QStandardItemModel
+from qutebrowser.qt import QtGui, QtCore
from qutebrowser.completion import completer
from qutebrowser.commands import command
@@ -37,7 +36,7 @@ def setup_cur_tab(tabbed_browser_stubs, fake_web_tab):
tabbed_browser_stubs[0].widget.current_index = 0
-class FakeCompletionModel(QStandardItemModel):
+class FakeCompletionModel(QtGui.QStandardItemModel):
"""Stub for a completion model."""
@@ -48,7 +47,7 @@ class FakeCompletionModel(QStandardItemModel):
self.info = info
-class CompletionWidgetStub(QObject):
+class CompletionWidgetStub(QtCore.QObject):
"""Stub for the CompletionView."""
diff --git a/tests/unit/completion/test_completiondelegate.py b/tests/unit/completion/test_completiondelegate.py
index ad081ccbf..8ed09b9a6 100644
--- a/tests/unit/completion/test_completiondelegate.py
+++ b/tests/unit/completion/test_completiondelegate.py
@@ -21,9 +21,7 @@ from unittest import mock
import hypothesis
import hypothesis.strategies
import pytest
-from PyQt5.QtCore import Qt
-from PyQt5.QtGui import QTextDocument, QColor
-from PyQt5.QtWidgets import QTextEdit
+from qutebrowser.qt import QtWidgets, QtGui, QtCore
from qutebrowser.completion import completiondelegate
@@ -50,8 +48,8 @@ from qutebrowser.completion import completiondelegate
('an anomaly', 'an anomaly', [(0, 2), (3, 7)]),
])
def test_highlight(pat, txt, segments):
- doc = QTextDocument(txt)
- highlighter = completiondelegate._Highlighter(doc, pat, Qt.red)
+ doc = QtGui.QTextDocument(txt)
+ highlighter = completiondelegate._Highlighter(doc, pat, QtCore.Qt.red)
highlighter.setFormat = mock.Mock()
highlighter.highlightBlock(txt)
highlighter.setFormat.assert_has_calls([
@@ -62,10 +60,10 @@ def test_highlight(pat, txt, segments):
def test_benchmark_highlight(benchmark):
txt = 'boofoobar'
pat = 'foo bar'
- doc = QTextDocument(txt)
+ doc = QtGui.QTextDocument(txt)
def bench():
- highlighter = completiondelegate._Highlighter(doc, pat, Qt.red)
+ highlighter = completiondelegate._Highlighter(doc, pat, QtCore.Qt.red)
highlighter.highlightBlock(txt)
benchmark(bench)
@@ -74,8 +72,8 @@ def test_benchmark_highlight(benchmark):
@hypothesis.given(text=hypothesis.strategies.text())
def test_pattern_hypothesis(text):
"""Make sure we can't produce invalid patterns."""
- doc = QTextDocument()
- completiondelegate._Highlighter(doc, text, Qt.red)
+ doc = QtGui.QTextDocument()
+ completiondelegate._Highlighter(doc, text, QtCore.Qt.red)
def test_highlighted(qtbot):
@@ -86,14 +84,14 @@ def test_highlighted(qtbot):
whether CompletionItemDelegate._get_textdoc() works properly, but testing
that is kind of hard, so we just test it in isolation here.
"""
- doc = QTextDocument()
- completiondelegate._Highlighter(doc, 'Hello', Qt.red)
+ doc = QtGui.QTextDocument()
+ completiondelegate._Highlighter(doc, 'Hello', QtCore.Qt.red)
doc.setPlainText('Hello World')
# Needed so the highlighting actually works.
- edit = QTextEdit()
+ edit = QtWidgets.QTextEdit()
qtbot.add_widget(edit)
edit.setDocument(doc)
colors = [f.foreground().color() for f in doc.allFormats()]
- assert QColor('red') in colors
+ assert QtGui.QColor('red') in colors
diff --git a/tests/unit/completion/test_completionmodel.py b/tests/unit/completion/test_completionmodel.py
index 2130f1f1c..55b70e0ef 100644
--- a/tests/unit/completion/test_completionmodel.py
+++ b/tests/unit/completion/test_completionmodel.py
@@ -24,7 +24,7 @@ import hypothesis
from hypothesis import strategies
import pytest
-from PyQt5.QtCore import QModelIndex
+from qutebrowser.qt import QtCore
from qutebrowser.completion.models import completionmodel, listcategory
from qutebrowser.utils import qtutils
@@ -114,5 +114,5 @@ def test_delete_cur_item_no_cat():
model.rowsAboutToBeRemoved.connect(callback)
model.rowsRemoved.connect(callback)
with pytest.raises(qtutils.QtValueError):
- model.delete_cur_item(QModelIndex())
+ model.delete_cur_item(QtCore.QModelIndex())
callback.assert_not_called()
diff --git a/tests/unit/completion/test_completionwidget.py b/tests/unit/completion/test_completionwidget.py
index 074228332..5103a5a1e 100644
--- a/tests/unit/completion/test_completionwidget.py
+++ b/tests/unit/completion/test_completionwidget.py
@@ -22,7 +22,7 @@
from unittest import mock
import pytest
-from PyQt5.QtCore import QRect
+from qutebrowser.qt import QtCore
from qutebrowser.completion import completionwidget
from qutebrowser.completion.models import completionmodel, listcategory
@@ -192,7 +192,7 @@ class TestCompletionItemFocusPage:
def patch_heights(self, monkeypatch, completionview):
"""Patch the item/widget heights so that 10 items are always visible."""
monkeypatch.setattr(completionview, 'visualRect',
- lambda _idx: QRect(0, 0, 100, 20))
+ lambda _idx: QtCore.QRect(0, 0, 100, 20))
monkeypatch.setattr(completionview, 'height', lambda: 200)
@pytest.mark.parametrize('which, expected', [
diff --git a/tests/unit/completion/test_models.py b/tests/unit/completion/test_models.py
index 2c00acf68..360ee9f8a 100644
--- a/tests/unit/completion/test_models.py
+++ b/tests/unit/completion/test_models.py
@@ -31,11 +31,8 @@ from unittest import mock
import hypothesis
import hypothesis.strategies as hst
import pytest
-from PyQt5.QtCore import QUrl, QDateTime, QProcess
try:
- from PyQt5.QtWebEngineWidgets import (
- QWebEngineHistory, QWebEngineHistoryItem
- )
+ pass
except ImportError:
pass
@@ -46,6 +43,7 @@ from qutebrowser.completion.models import (
from qutebrowser.config import configdata, configtypes
from qutebrowser.utils import usertypes
from qutebrowser.mainwindow import tabbedbrowser
+from qutebrowser.qt import QtWebEngineWidgets, QtCore
def _check_completions(model, expected):
@@ -211,17 +209,17 @@ def local_files_path(tmp_path):
def web_history_populated(web_history):
"""Pre-populate the web-history database."""
web_history.add_url(
- url=QUrl('http://qutebrowser.org'),
+ url=QtCore.QUrl('http://qutebrowser.org'),
title='qutebrowser',
atime=datetime(2015, 9, 5).timestamp()
)
web_history.add_url(
- url=QUrl('https://python.org'),
+ url=QtCore.QUrl('https://python.org'),
title='Welcome to Python.org',
atime=datetime(2016, 3, 8).timestamp()
)
web_history.add_url(
- url=QUrl('https://github.com'),
+ url=QtCore.QUrl('https://github.com'),
title='https://github.com',
atime=datetime(2016, 5, 1).timestamp()
)
@@ -711,7 +709,7 @@ def test_url_completion_pattern(web_history, quickmark_manager_stub,
bookmark_manager_stub, info,
url, title, pattern, rowcount):
"""Test that url completion filters by url and title."""
- web_history.add_url(QUrl(url), title)
+ web_history.add_url(QtCore.QUrl(url), title)
model = urlmodel.url(info=info)
model.set_pattern(pattern)
# 2, 0 is History
@@ -816,12 +814,12 @@ def test_session_completion(qtmodeltester, session_manager_stub):
def test_tab_completion(qtmodeltester, fake_web_tab, win_registry,
tabbed_browser_stubs):
tabbed_browser_stubs[0].widget.tabs = [
- fake_web_tab(QUrl('https://github.com'), 'GitHub', 0),
- fake_web_tab(QUrl('https://wikipedia.org'), 'Wikipedia', 1),
- fake_web_tab(QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2),
+ fake_web_tab(QtCore.QUrl('https://github.com'), 'GitHub', 0),
+ fake_web_tab(QtCore.QUrl('https://wikipedia.org'), 'Wikipedia', 1),
+ fake_web_tab(QtCore.QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2),
]
tabbed_browser_stubs[1].widget.tabs = [
- fake_web_tab(QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
+ fake_web_tab(QtCore.QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
]
model = miscmodels.tabs()
model.set_pattern('')
@@ -843,12 +841,12 @@ def test_tab_completion_delete(qtmodeltester, fake_web_tab, win_registry,
tabbed_browser_stubs):
"""Verify closing a tab by deleting it from the completion widget."""
tabbed_browser_stubs[0].widget.tabs = [
- fake_web_tab(QUrl('https://github.com'), 'GitHub', 0),
- fake_web_tab(QUrl('https://wikipedia.org'), 'Wikipedia', 1),
- fake_web_tab(QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2)
+ fake_web_tab(QtCore.QUrl('https://github.com'), 'GitHub', 0),
+ fake_web_tab(QtCore.QUrl('https://wikipedia.org'), 'Wikipedia', 1),
+ fake_web_tab(QtCore.QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2)
]
tabbed_browser_stubs[1].widget.tabs = [
- fake_web_tab(QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
+ fake_web_tab(QtCore.QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
]
model = miscmodels.tabs()
model.set_pattern('')
@@ -863,20 +861,20 @@ def test_tab_completion_delete(qtmodeltester, fake_web_tab, win_registry,
model.delete_cur_item(idx)
actual = [tab.url() for tab in tabbed_browser_stubs[0].widget.tabs]
- assert actual == [QUrl('https://github.com'),
- QUrl('https://duckduckgo.com')]
+ assert actual == [QtCore.QUrl('https://github.com'),
+ QtCore.QUrl('https://duckduckgo.com')]
def test_tab_focus_completion_delete(qtmodeltester, fake_web_tab, win_registry,
tabbed_browser_stubs, info):
"""Verify closing a tab by deleting it from the completion widget."""
tabbed_browser_stubs[0].widget.tabs = [
- fake_web_tab(QUrl('https://github.com'), 'GitHub', 0),
- fake_web_tab(QUrl('https://wikipedia.org'), 'Wikipedia', 1),
- fake_web_tab(QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2)
+ fake_web_tab(QtCore.QUrl('https://github.com'), 'GitHub', 0),
+ fake_web_tab(QtCore.QUrl('https://wikipedia.org'), 'Wikipedia', 1),
+ fake_web_tab(QtCore.QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2)
]
tabbed_browser_stubs[1].widget.tabs = [
- fake_web_tab(QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
+ fake_web_tab(QtCore.QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
]
model = miscmodels.tab_focus(info=info)
model.set_pattern('')
@@ -891,8 +889,8 @@ def test_tab_focus_completion_delete(qtmodeltester, fake_web_tab, win_registry,
model.delete_cur_item(idx)
actual = [tab.url() for tab in tabbed_browser_stubs[0].widget.tabs]
- assert actual == [QUrl('https://github.com'),
- QUrl('https://duckduckgo.com')]
+ assert actual == [QtCore.QUrl('https://github.com'),
+ QtCore.QUrl('https://duckduckgo.com')]
def test_tab_completion_not_sorted(qtmodeltester, fake_web_tab, win_registry,
@@ -909,7 +907,7 @@ def test_tab_completion_not_sorted(qtmodeltester, fake_web_tab, win_registry,
expected.append(("0/{}".format(idx), url, title))
tabbed_browser_stubs[0].widget.tabs = [
- fake_web_tab(QUrl(tab[1]), tab[2], idx)
+ fake_web_tab(QtCore.QUrl(tab[1]), tab[2], idx)
for idx, tab in enumerate(expected)
]
model = miscmodels.tabs()
@@ -927,12 +925,12 @@ def test_tab_completion_tabs_are_windows(qtmodeltester, fake_web_tab,
config_stub):
"""Verify tabs across all windows are listed under a single category."""
tabbed_browser_stubs[0].widget.tabs = [
- fake_web_tab(QUrl('https://github.com'), 'GitHub', 0),
- fake_web_tab(QUrl('https://wikipedia.org'), 'Wikipedia', 1),
- fake_web_tab(QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2),
+ fake_web_tab(QtCore.QUrl('https://github.com'), 'GitHub', 0),
+ fake_web_tab(QtCore.QUrl('https://wikipedia.org'), 'Wikipedia', 1),
+ fake_web_tab(QtCore.QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2),
]
tabbed_browser_stubs[1].widget.tabs = [
- fake_web_tab(QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
+ fake_web_tab(QtCore.QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
]
config_stub.val.tabs.tabs_are_windows = True
@@ -953,12 +951,12 @@ def test_tab_completion_tabs_are_windows(qtmodeltester, fake_web_tab,
def test_other_tabs_completion(qtmodeltester, fake_web_tab, win_registry,
tabbed_browser_stubs, info):
tabbed_browser_stubs[0].widget.tabs = [
- fake_web_tab(QUrl('https://github.com'), 'GitHub', 0),
- fake_web_tab(QUrl('https://wikipedia.org'), 'Wikipedia', 1),
- fake_web_tab(QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2),
+ fake_web_tab(QtCore.QUrl('https://github.com'), 'GitHub', 0),
+ fake_web_tab(QtCore.QUrl('https://wikipedia.org'), 'Wikipedia', 1),
+ fake_web_tab(QtCore.QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2),
]
tabbed_browser_stubs[1].widget.tabs = [
- fake_web_tab(QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
+ fake_web_tab(QtCore.QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
]
info.win_id = 1
model = miscmodels.other_tabs(info=info)
@@ -977,12 +975,12 @@ def test_other_tabs_completion(qtmodeltester, fake_web_tab, win_registry,
def test_other_tabs_completion_id0(qtmodeltester, fake_web_tab,
win_registry, tabbed_browser_stubs, info):
tabbed_browser_stubs[0].widget.tabs = [
- fake_web_tab(QUrl('https://github.com'), 'GitHub', 0),
- fake_web_tab(QUrl('https://wikipedia.org'), 'Wikipedia', 1),
- fake_web_tab(QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2),
+ fake_web_tab(QtCore.QUrl('https://github.com'), 'GitHub', 0),
+ fake_web_tab(QtCore.QUrl('https://wikipedia.org'), 'Wikipedia', 1),
+ fake_web_tab(QtCore.QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2),
]
tabbed_browser_stubs[1].widget.tabs = [
- fake_web_tab(QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
+ fake_web_tab(QtCore.QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
]
info.win_id = 0
model = miscmodels.other_tabs(info=info)
@@ -999,12 +997,12 @@ def test_other_tabs_completion_id0(qtmodeltester, fake_web_tab,
def test_tab_focus_completion(qtmodeltester, fake_web_tab, win_registry,
tabbed_browser_stubs, info):
tabbed_browser_stubs[0].widget.tabs = [
- fake_web_tab(QUrl('https://github.com'), 'GitHub', 0),
- fake_web_tab(QUrl('https://wikipedia.org'), 'Wikipedia', 1),
- fake_web_tab(QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2),
+ fake_web_tab(QtCore.QUrl('https://github.com'), 'GitHub', 0),
+ fake_web_tab(QtCore.QUrl('https://wikipedia.org'), 'Wikipedia', 1),
+ fake_web_tab(QtCore.QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2),
]
tabbed_browser_stubs[1].widget.tabs = [
- fake_web_tab(QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
+ fake_web_tab(QtCore.QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0),
]
info.win_id = 1
model = miscmodels.tab_focus(info=info)
@@ -1034,12 +1032,12 @@ def test_tab_focus_completion(qtmodeltester, fake_web_tab, win_registry,
def test_window_completion(qtmodeltester, fake_web_tab, tabbed_browser_stubs,
info):
tabbed_browser_stubs[0].widget.tabs = [
- fake_web_tab(QUrl('https://github.com'), 'GitHub', 0),
- fake_web_tab(QUrl('https://wikipedia.org'), 'Wikipedia', 1),
- fake_web_tab(QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2)
+ fake_web_tab(QtCore.QUrl('https://github.com'), 'GitHub', 0),
+ fake_web_tab(QtCore.QUrl('https://wikipedia.org'), 'Wikipedia', 1),
+ fake_web_tab(QtCore.QUrl('https://duckduckgo.com'), 'DuckDuckGo', 2)
]
tabbed_browser_stubs[1].widget.tabs = [
- fake_web_tab(QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0)
+ fake_web_tab(QtCore.QUrl('https://wiki.archlinux.org'), 'ArchWiki', 0)
]
info.win_id = 1
@@ -1349,7 +1347,7 @@ def test_url_completion_benchmark(benchmark, info,
def tab_with_history(fake_web_tab, tabbed_browser_stubs, info, monkeypatch):
"""Returns a fake tab with some fake history items."""
pytest.importorskip('PyQt5.QtWebEngineWidgets')
- tab = fake_web_tab(QUrl('https://github.com'), 'GitHub', 0)
+ tab = fake_web_tab(QtCore.QUrl('https://github.com'), 'GitHub', 0)
current_idx = 2
monkeypatch.setattr(
tab.history, 'current_idx',
@@ -1365,13 +1363,13 @@ def tab_with_history(fake_web_tab, tabbed_browser_stubs, info, monkeypatch):
("http://example.com/thing3", "thing3 detail", now+15),
("http://example.com/thing4", "thing4 detail", now+20),
]:
- entry = mock.Mock(spec=QWebEngineHistoryItem)
- entry.url.return_value = QUrl(url)
+ entry = mock.Mock(spec=QtWebEngineWidgets.QWebEngineHistoryItem)
+ entry.url.return_value = QtCore.QUrl(url)
entry.title.return_value = title
- dt = QDateTime.fromMSecsSinceEpoch(int(ts * 1000))
+ dt = QtCore.QDateTime.fromMSecsSinceEpoch(int(ts * 1000))
entry.lastVisited.return_value = dt
history.append(entry)
- tab.history._history = mock.Mock(spec=QWebEngineHistory)
+ tab.history._history = mock.Mock(spec=QtWebEngineWidgets.QWebEngineHistory)
tab.history._history.items.return_value = history
monkeypatch.setattr(
tab.history, 'back_items',
@@ -1423,13 +1421,13 @@ def test_forward_completion(tab_with_history, info):
def test_undo_completion(tabbed_browser_stubs, info):
"""Test :undo completion."""
- entry1 = tabbedbrowser._UndoEntry(url=QUrl('https://example.org/'),
+ entry1 = tabbedbrowser._UndoEntry(url=QtCore.QUrl('https://example.org/'),
history=None, index=None, pinned=None,
created_at=datetime(2020, 1, 1))
- entry2 = tabbedbrowser._UndoEntry(url=QUrl('https://example.com/'),
+ entry2 = tabbedbrowser._UndoEntry(url=QtCore.QUrl('https://example.com/'),
history=None, index=None, pinned=None,
created_at=datetime(2020, 1, 2))
- entry3 = tabbedbrowser._UndoEntry(url=QUrl('https://example.net/'),
+ entry3 = tabbedbrowser._UndoEntry(url=QtCore.QUrl('https://example.net/'),
history=None, index=None, pinned=None,
created_at=datetime(2020, 1, 2))
@@ -1463,7 +1461,7 @@ def undo_completion_retains_sort_order(tabbed_browser_stubs, info):
tabbed_browser_stubs[0].undo_stack = [
tabbedbrowser._UndoEntry(
- url=QUrl(f'https://example.org/{idx}'),
+ url=QtCore.QUrl(f'https://example.org/{idx}'),
history=None, index=None, pinned=None,
created_at=created_dt,
)
@@ -1490,7 +1488,7 @@ def test_process_completion(monkeypatch, stubs, info):
p1.cmd = 'cmd1'
p1.args = []
p1.outcome.running = False
- p1.outcome.status = QProcess.NormalExit
+ p1.outcome.status = QtCore.QProcess.NormalExit
p1.outcome.code = 0
p2.pid = 1002
@@ -1502,7 +1500,7 @@ def test_process_completion(monkeypatch, stubs, info):
p3.cmd = 'cmd3'
p3.args = []
p3.outcome.running = False
- p3.outcome.status = QProcess.NormalExit
+ p3.outcome.status = QtCore.QProcess.NormalExit
p3.outcome.code = 1
monkeypatch.setattr(guiprocess, 'all_processes', {
diff --git a/tests/unit/components/test_blockutils.py b/tests/unit/components/test_blockutils.py
index 08d8cee60..7ee941b71 100644
--- a/tests/unit/components/test_blockutils.py
+++ b/tests/unit/components/test_blockutils.py
@@ -21,7 +21,7 @@
import io
from typing import IO
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
import pytest
@@ -50,7 +50,7 @@ def pretend_blocklists(tmp_path):
bl_dst_path = bl_dst_dir / filename
bl_dst_path.write_text("\n".join(blocklist_lines), encoding="utf-8")
assert bl_dst_path.is_file()
- urls.append(QUrl.fromLocalFile(str(bl_dst_path)).toString())
+ urls.append(QtCore.QUrl.fromLocalFile(str(bl_dst_path)).toString())
return urls, bl_dst_dir
@@ -69,7 +69,7 @@ def test_blocklist_dl(qtbot, pretend_blocklists):
num_lines += 1
assert num_lines >= 1
- list_qurls = [QUrl(blocklist) for blocklist in pretend_blocklists[0]]
+ list_qurls = [QtCore.QUrl(blocklist) for blocklist in pretend_blocklists[0]]
dl = blockutils.BlocklistDownloads(list_qurls)
dl.single_download_finished.connect(on_single_download)
diff --git a/tests/unit/components/test_braveadblock.py b/tests/unit/components/test_braveadblock.py
index fc50cb595..c6af31a23 100644
--- a/tests/unit/components/test_braveadblock.py
+++ b/tests/unit/components/test_braveadblock.py
@@ -22,7 +22,7 @@ import logging
import csv
from typing import Iterable, Tuple
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
import pytest
@@ -110,8 +110,8 @@ def run_function_on_dataset(given_function):
dataset = testutils.adblock_dataset_tsv()
reader = csv.DictReader(dataset, delimiter="\t")
for row in reader:
- url = QUrl(row["url"])
- source_url = QUrl(row["source_url"])
+ url = QtCore.QUrl(row["url"])
+ source_url = QtCore.QUrl(row["source_url"])
resource_type = ResourceType[row["type"]]
given_function(url, source_url, resource_type)
@@ -130,7 +130,7 @@ def assert_none_blocked(ad_blocker):
def blocklist_invalid_utf8(tmp_path):
dest_path = tmp_path / "invalid_utf8.txt"
dest_path.write_bytes(b"invalidutf8\xa0")
- return QUrl.fromLocalFile(str(dest_path)).toString()
+ return QtCore.QUrl.fromLocalFile(str(dest_path)).toString()
@pytest.fixture
@@ -150,7 +150,7 @@ def easylist_easyprivacy_both(tmp_path):
bl_dst_path = bl_dst_dir / filename
bl_dst_path.write_text("\n".join(list(blocklist)), encoding="utf-8")
assert bl_dst_path.is_file()
- urls.append(QUrl.fromLocalFile(str(bl_dst_path)).toString())
+ urls.append(QtCore.QUrl.fromLocalFile(str(bl_dst_path)).toString())
return urls, bl_dst_dir
@@ -184,8 +184,8 @@ def assert_urls(
should_be_blocked: bool,
) -> None:
for (str_url, source_str_url, request_type) in urls:
- url = QUrl(str_url)
- source_url = QUrl(source_str_url)
+ url = QtCore.QUrl(str_url)
+ source_url = QtCore.QUrl(source_str_url)
is_blocked = ad_blocker._is_blocked(url, source_url, request_type)
assert is_blocked == should_be_blocked
@@ -327,7 +327,7 @@ def test_whitelist_on_dataset(config_stub, easylist_easyprivacy):
assert not blockutils.is_whitelisted_url(url)
config_stub.val.content.blocking.whitelist = []
assert not blockutils.is_whitelisted_url(url)
- whitelist_url = url.toString(QUrl.RemovePath) + "/*"
+ whitelist_url = url.toString(QtCore.QUrl.RemovePath) + "/*"
config_stub.val.content.blocking.whitelist = [whitelist_url]
assert blockutils.is_whitelisted_url(url)
@@ -342,7 +342,7 @@ def test_update_easylist_easyprivacy_directory(
lists_directory = easylist_easyprivacy_both[1]
config_stub.val.content.blocking.adblock.lists = [
- QUrl.fromLocalFile(str(lists_directory)).toString()
+ QtCore.QUrl.fromLocalFile(str(lists_directory)).toString()
]
config_stub.val.content.blocking.enabled = True
config_stub.val.content.blocking.whitelist = None
@@ -359,7 +359,7 @@ def test_update_easylist_easyprivacy_directory(
def test_update_empty_directory_blocklist(ad_blocker, config_stub, empty_dir, caplog):
- tmpdir_url = QUrl.fromLocalFile(str(empty_dir)).toString()
+ tmpdir_url = QtCore.QUrl.fromLocalFile(str(empty_dir)).toString()
config_stub.val.content.blocking.adblock.lists = [tmpdir_url]
config_stub.val.content.blocking.enabled = True
config_stub.val.content.blocking.whitelist = None
@@ -386,12 +386,12 @@ def test_buggy_url_workaround(ad_blocker, config_stub, easylist_easyprivacy,
config_stub.val.content.blocking.adblock.lists = easylist_easyprivacy
ad_blocker.adblock_update()
- url = QUrl(url_str)
+ url = QtCore.QUrl(url_str)
assert url.isValid()
if source_url_str is None:
source_url = None
else:
- source_url = QUrl(source_url_str)
+ source_url = QtCore.QUrl(source_url_str)
assert source_url.isValid()
assert not ad_blocker._is_blocked(url, source_url, resource_type)
diff --git a/tests/unit/components/test_hostblock.py b/tests/unit/components/test_hostblock.py
index 5949f92f8..8178daf5e 100644
--- a/tests/unit/components/test_hostblock.py
+++ b/tests/unit/components/test_hostblock.py
@@ -24,7 +24,7 @@ import logging
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.components import hostblock
from qutebrowser.utils import urlmatch
@@ -130,7 +130,7 @@ def assert_urls(
"""
whitelisted = list(whitelisted) + ["localhost"]
for str_url in urls_to_check:
- url = QUrl(str_url)
+ url = QtCore.QUrl(str_url)
host = url.host()
if host in blocked and host not in whitelisted:
assert host_blocker._is_blocked(url)
@@ -141,7 +141,7 @@ def assert_urls(
def blocklist_to_url(path):
"""Get an example.com-URL with the given filename as path."""
assert not path.is_absolute(), path
- url = QUrl("http://example.com/")
+ url = QtCore.QUrl("http://example.com/")
url.setPath("/" + str(path))
assert url.isValid(), url.errorString()
return url
@@ -204,7 +204,7 @@ def generic_blocklists(directory):
blocklist3 = blocklist_to_url(create_zipfile(directory, [file1], "block3"))
# local text file with valid hosts
- blocklist4 = QUrl.fromLocalFile(
+ blocklist4 = QtCore.QUrl.fromLocalFile(
str(
directory
/ create_blocklist(
@@ -268,7 +268,7 @@ def test_disabled_blocking_update(
current_download.finished.emit()
host_blocker.read_hosts()
for str_url in URLS_TO_CHECK:
- assert not host_blocker._is_blocked(QUrl(str_url))
+ assert not host_blocker._is_blocked(QtCore.QUrl(str_url))
def test_disabled_blocking_per_url(config_stub, host_blocker_factory):
@@ -279,13 +279,13 @@ def test_disabled_blocking_per_url(config_stub, host_blocker_factory):
pattern = urlmatch.UrlPattern(example_com)
config_stub.set_obj("content.blocking.enabled", False, pattern=pattern)
- url = QUrl("https://blocked.example.com")
+ url = QtCore.QUrl("https://blocked.example.com")
host_blocker = host_blocker_factory()
host_blocker._blocked_hosts.add(url.host())
assert host_blocker._is_blocked(url)
- assert not host_blocker._is_blocked(url, first_party_url=QUrl(example_com))
+ assert not host_blocker._is_blocked(url, first_party_url=QtCore.QUrl(example_com))
def test_no_blocklist_update(config_stub, download_stub, host_blocker_factory):
@@ -300,7 +300,7 @@ def test_no_blocklist_update(config_stub, download_stub, host_blocker_factory):
for dl in download_stub.downloads:
dl.successful = True
for str_url in URLS_TO_CHECK:
- assert not host_blocker._is_blocked(QUrl(str_url))
+ assert not host_blocker._is_blocked(QtCore.QUrl(str_url))
def test_successful_update(config_stub, tmp_path, caplog, host_blocker_factory):
@@ -499,7 +499,7 @@ def test_config_change_initial(config_stub, tmp_path, host_blocker_factory):
host_blocker = host_blocker_factory()
host_blocker.read_hosts()
for str_url in URLS_TO_CHECK:
- assert not host_blocker._is_blocked(QUrl(str_url))
+ assert not host_blocker._is_blocked(QtCore.QUrl(str_url))
def test_config_change(config_stub, tmp_path, host_blocker_factory):
@@ -523,7 +523,7 @@ def test_config_change(config_stub, tmp_path, host_blocker_factory):
config_stub.val.content.blocking.hosts.lists = None
host_blocker.read_hosts()
for str_url in URLS_TO_CHECK:
- assert not host_blocker._is_blocked(QUrl(str_url))
+ assert not host_blocker._is_blocked(QtCore.QUrl(str_url))
def test_add_directory(config_stub, tmp_path, host_blocker_factory):
@@ -557,7 +557,7 @@ def test_adblock_benchmark(data_tmpdir, benchmark, host_blocker_factory):
blocked_hosts = data_tmpdir / "blocked-hosts"
blocked_hosts.write_text("\n".join(testutils.blocked_hosts()), encoding="utf-8")
- url = QUrl("https://www.example.org/")
+ url = QtCore.QUrl("https://www.example.org/")
blocker = host_blocker_factory()
blocker.read_hosts()
assert blocker._blocked_hosts
@@ -572,6 +572,6 @@ def test_subdomain_blocking(config_stub, host_blocker_factory, block_subdomains)
config_stub.val.content.blocking.hosts.block_subdomains = block_subdomains
host_blocker = host_blocker_factory()
host_blocker._blocked_hosts.add("example.com")
- is_blocked = host_blocker._is_blocked(QUrl("https://subdomain.example.com"))
+ is_blocked = host_blocker._is_blocked(QtCore.QUrl("https://subdomain.example.com"))
# block_subdomains is also expected result of is_blocked
assert is_blocked == block_subdomains
diff --git a/tests/unit/components/test_readlinecommands.py b/tests/unit/components/test_readlinecommands.py
index af815b075..35fef45a1 100644
--- a/tests/unit/components/test_readlinecommands.py
+++ b/tests/unit/components/test_readlinecommands.py
@@ -20,11 +20,10 @@
import os
import re
import inspect
-
-from PyQt5.QtWidgets import QLineEdit, QApplication
import pytest
from qutebrowser.components import readlinecommands
+from qutebrowser.qt import QtWidgets
# Some functions aren't 100% readline compatible:
@@ -35,7 +34,7 @@ from qutebrowser.components import readlinecommands
fixme = pytest.mark.xfail(reason='readline compatibility - see #678')
-class LineEdit(QLineEdit):
+class LineEdit(QtWidgets.QLineEdit):
"""QLineEdit with some methods to make testing easier."""
@@ -120,13 +119,13 @@ def lineedit(qtbot, monkeypatch):
"""Fixture providing a LineEdit."""
le = LineEdit()
qtbot.add_widget(le)
- monkeypatch.setattr(QApplication.instance(), 'focusWidget', lambda: le)
+ monkeypatch.setattr(QtWidgets.QApplication.instance(), 'focusWidget', lambda: le)
return le
def test_none(qtbot):
"""Call each rl_* method with a None focusWidget."""
- assert QApplication.instance().focusWidget() is None
+ assert QtWidgets.QApplication.instance().focusWidget() is None
for name, method in inspect.getmembers(readlinecommands,
inspect.isfunction):
if name == "rl_rubout":
diff --git a/tests/unit/config/test_config.py b/tests/unit/config/test_config.py
index b88bc2f8d..a8bdaecbe 100644
--- a/tests/unit/config/test_config.py
+++ b/tests/unit/config/test_config.py
@@ -23,8 +23,7 @@ import unittest.mock
import functools
import pytest
-from PyQt5.QtCore import QUrl
-from PyQt5.QtGui import QColor
+from qutebrowser.qt import QtGui, QtCore
from qutebrowser.config import config, configdata, configexc
from qutebrowser.utils import usertypes, urlmatch
@@ -494,14 +493,14 @@ class TestConfig:
def test_get(self, conf):
"""Test conf.get() with a QColor (where get/get_obj is different)."""
- assert conf.get('colors.completion.category.fg') == QColor('white')
+ assert conf.get('colors.completion.category.fg') == QtGui.QColor('white')
def test_get_for_url(self, conf):
"""Test conf.get() with a URL/pattern."""
pattern = urlmatch.UrlPattern('*://example.com/')
name = 'content.javascript.enabled'
conf.set_obj(name, False, pattern=pattern)
- assert conf.get(name, url=QUrl('https://example.com/')) is False
+ assert conf.get(name, url=QtCore.QUrl('https://example.com/')) is False
@pytest.mark.parametrize('fallback, expected', [
(True, True),
@@ -510,7 +509,7 @@ class TestConfig:
def test_get_for_url_fallback(self, conf, fallback, expected):
"""Test conf.get() with a URL and fallback."""
value = conf.get('content.javascript.enabled',
- url=QUrl('https://example.com/'),
+ url=QtCore.QUrl('https://example.com/'),
fallback=fallback)
assert value is expected
@@ -758,7 +757,7 @@ class TestContainer:
@pytest.mark.parametrize('configapi, expected', [
(object(), 'rgb'),
- (None, QColor.Rgb),
+ (None, QtGui.QColor.Rgb),
])
def test_getattr_option(self, container, configapi, expected):
container._configapi = configapi
diff --git a/tests/unit/config/test_configcommands.py b/tests/unit/config/test_configcommands.py
index 6dd09cee3..82354bc32 100644
--- a/tests/unit/config/test_configcommands.py
+++ b/tests/unit/config/test_configcommands.py
@@ -23,7 +23,7 @@ import functools
import unittest.mock
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.config import configcommands
from qutebrowser.api import cmdutils
@@ -59,7 +59,7 @@ class TestSet:
Should open qute://settings."""
commands.set(win_id=0)
- assert tabbed_browser_stubs[0].loaded_url == QUrl('qute://settings')
+ assert tabbed_browser_stubs[0].loaded_url == QtCore.QUrl('qute://settings')
@pytest.mark.parametrize('option', ['url.auto_search?', 'url.auto_search'])
def test_get(self, config_stub, commands, message_mock, option):
@@ -217,7 +217,7 @@ def test_diff(commands, tabbed_browser_stubs):
Should open qute://configdiff."""
commands.config_diff(win_id=0)
- assert tabbed_browser_stubs[0].loaded_url == QUrl('qute://configdiff')
+ assert tabbed_browser_stubs[0].loaded_url == QtCore.QUrl('qute://configdiff')
class TestCycle:
@@ -468,7 +468,7 @@ class TestUnsetAndClear:
def test_unset_pattern(self, commands, config_stub, set_global):
name = 'content.javascript.enabled'
pattern = urlmatch.UrlPattern('*://example.com')
- url = QUrl('https://example.com')
+ url = QtCore.QUrl('https://example.com')
if set_global:
config_stub.set_obj(name, False)
@@ -726,8 +726,8 @@ class TestBind:
return {'normal': {}}
@pytest.mark.parametrize("mode, url", [
- ("normal", QUrl("qute://bindings")),
- ("passthrough", QUrl("qute://bindings#passthrough")),
+ ("normal", QtCore.QUrl("qute://bindings")),
+ ("passthrough", QtCore.QUrl("qute://bindings#passthrough")),
])
def test_bind_no_args(self, commands, config_stub, no_bindings,
tabbed_browser_stubs, mode, url):
diff --git a/tests/unit/config/test_configfiles.py b/tests/unit/config/test_configfiles.py
index 760992e15..460a512fa 100644
--- a/tests/unit/config/test_configfiles.py
+++ b/tests/unit/config/test_configfiles.py
@@ -25,7 +25,7 @@ import textwrap
import logging
import pytest
-from PyQt5.QtCore import QSettings
+from qutebrowser.qt import QtWebEngineWidgets, QtCore
from qutebrowser.config import (config, configfiles, configexc, configdata,
configtypes)
@@ -167,7 +167,7 @@ def state_writer(data_tmpdir):
@pytest.fixture
def qtwe_version_patcher(monkeypatch):
try:
- from PyQt5 import QtWebEngineWidgets # pylint: disable=unused-import
+ pass
except ImportError:
pytest.skip("QtWebEngine not available")
@@ -1488,7 +1488,7 @@ def test_init(init_patch, config_tmpdir):
# Make sure qsettings land in a subdir
if utils.is_linux:
- settings = QSettings()
+ settings = QtCore.QSettings()
settings.setValue("hello", "world")
settings.sync()
assert (config_tmpdir / 'qsettings').exists()
diff --git a/tests/unit/config/test_configtypes.py b/tests/unit/config/test_configtypes.py
index c34efce54..37a077775 100644
--- a/tests/unit/config/test_configtypes.py
+++ b/tests/unit/config/test_configtypes.py
@@ -29,9 +29,7 @@ import dataclasses
import pytest
import hypothesis
from hypothesis import strategies
-from PyQt5.QtCore import QUrl
-from PyQt5.QtGui import QColor, QFont
-from PyQt5.QtNetwork import QNetworkProxy
+from qutebrowser.qt import QtNetwork, QtGui, QtCore
from qutebrowser.misc import objects
from qutebrowser.config import configtypes, configexc
@@ -41,13 +39,13 @@ from qutebrowser.keyinput import keyutils
from helpers import testutils
-class Font(QFont):
+class Font(QtGui.QFont):
"""A QFont with a nicer repr()."""
def __repr__(self):
- weight = debug.qenum_key(QFont, self.weight(), add_base=True,
- klass=QFont.Weight)
+ weight = debug.qenum_key(QtGui.QFont, self.weight(), add_base=True,
+ klass=QtGui.QFont.Weight)
kwargs = {
'family': self.family(),
'pt': self.pointSize(),
@@ -1274,20 +1272,20 @@ class TestQtColor:
return configtypes.QtColor
@pytest.mark.parametrize('val, expected', [
- ('#123', QColor('#123')),
- ('#112233', QColor('#112233')),
- ('#44112233', QColor('#44112233')),
- ('#111222333', QColor('#111222333')),
- ('#111122223333', QColor('#111122223333')),
- ('red', QColor('red')),
+ ('#123', QtGui.QColor('#123')),
+ ('#112233', QtGui.QColor('#112233')),
+ ('#44112233', QtGui.QColor('#44112233')),
+ ('#111222333', QtGui.QColor('#111222333')),
+ ('#111122223333', QtGui.QColor('#111122223333')),
+ ('red', QtGui.QColor('red')),
- ('rgb(0, 0, 0)', QColor.fromRgb(0, 0, 0)),
- ('rgb(0,0,0)', QColor.fromRgb(0, 0, 0)),
+ ('rgb(0, 0, 0)', QtGui.QColor.fromRgb(0, 0, 0)),
+ ('rgb(0,0,0)', QtGui.QColor.fromRgb(0, 0, 0)),
- ('rgba(255, 255, 255, 1.0)', QColor.fromRgb(255, 255, 255, 255)),
+ ('rgba(255, 255, 255, 1.0)', QtGui.QColor.fromRgb(255, 255, 255, 255)),
- ('hsv(10%,10%,10%)', QColor.fromHsv(35, 25, 25)),
- ('hsva(10%,20%,30%,40%)', QColor.fromHsv(35, 51, 76, 102)),
+ ('hsv(10%,10%,10%)', QtGui.QColor.fromHsv(35, 25, 25)),
+ ('hsva(10%,20%,30%,40%)', QtGui.QColor.fromHsv(35, 51, 76, 102)),
])
def test_valid(self, klass, val, expected):
assert klass().to_py(val) == expected
@@ -1363,8 +1361,8 @@ class TestQssColor:
@dataclasses.dataclass
class FontDesc:
- style: QFont.Style
- weight: QFont.Weight
+ style: QtGui.QFont.Style
+ weight: QtGui.QFont.Weight
pt: int
px: int
family: str
@@ -1375,46 +1373,46 @@ class TestFont:
TESTS = {
# (style, weight, pointsize, pixelsize, family
'"Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Normal, -1, -1, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleNormal, QtGui.QFont.Normal, -1, -1, 'Foobar Neue'),
'inconsolatazi4':
- FontDesc(QFont.StyleNormal, QFont.Normal, -1, -1,
+ FontDesc(QtGui.QFont.StyleNormal, QtGui.QFont.Normal, -1, -1,
'inconsolatazi4'),
'Terminus (TTF)':
- FontDesc(QFont.StyleNormal, QFont.Normal, -1, -1,
+ FontDesc(QtGui.QFont.StyleNormal, QtGui.QFont.Normal, -1, -1,
'Terminus (TTF)'),
'10pt "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Normal, 10, None, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleNormal, QtGui.QFont.Normal, 10, None, 'Foobar Neue'),
'10PT "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Normal, 10, None, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleNormal, QtGui.QFont.Normal, 10, None, 'Foobar Neue'),
'10px "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Normal, None, 10, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleNormal, QtGui.QFont.Normal, None, 10, 'Foobar Neue'),
'10PX "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Normal, None, 10, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleNormal, QtGui.QFont.Normal, None, 10, 'Foobar Neue'),
'bold "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Bold, -1, -1, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleNormal, QtGui.QFont.Bold, -1, -1, 'Foobar Neue'),
'italic "Foobar Neue"':
- FontDesc(QFont.StyleItalic, QFont.Normal, -1, -1, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleItalic, QtGui.QFont.Normal, -1, -1, 'Foobar Neue'),
'oblique "Foobar Neue"':
- FontDesc(QFont.StyleOblique, QFont.Normal, -1, -1, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleOblique, QtGui.QFont.Normal, -1, -1, 'Foobar Neue'),
'normal bold "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Bold, -1, -1, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleNormal, QtGui.QFont.Bold, -1, -1, 'Foobar Neue'),
'bold italic "Foobar Neue"':
- FontDesc(QFont.StyleItalic, QFont.Bold, -1, -1, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleItalic, QtGui.QFont.Bold, -1, -1, 'Foobar Neue'),
'bold 10pt "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Bold, 10, None, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleNormal, QtGui.QFont.Bold, 10, None, 'Foobar Neue'),
'italic 10pt "Foobar Neue"':
- FontDesc(QFont.StyleItalic, QFont.Normal, 10, None, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleItalic, QtGui.QFont.Normal, 10, None, 'Foobar Neue'),
'oblique 10pt "Foobar Neue"':
- FontDesc(QFont.StyleOblique, QFont.Normal, 10, None,
+ FontDesc(QtGui.QFont.StyleOblique, QtGui.QFont.Normal, 10, None,
'Foobar Neue'),
'normal bold 10pt "Foobar Neue"':
- FontDesc(QFont.StyleNormal, QFont.Bold, 10, None, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleNormal, QtGui.QFont.Bold, 10, None, 'Foobar Neue'),
'bold italic 10pt "Foobar Neue"':
- FontDesc(QFont.StyleItalic, QFont.Bold, 10, None, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleItalic, QtGui.QFont.Bold, 10, None, 'Foobar Neue'),
'normal 300 10pt "Foobar Neue"':
- FontDesc(QFont.StyleNormal, 37, 10, None, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleNormal, 37, 10, None, 'Foobar Neue'),
'normal 800 10pt "Foobar Neue"':
- FontDesc(QFont.StyleNormal, 99, 10, None, 'Foobar Neue'),
+ FontDesc(QtGui.QFont.StyleNormal, 99, 10, None, 'Foobar Neue'),
}
font_xfail = pytest.mark.xfail(reason='FIXME: #103')
@@ -1891,21 +1889,21 @@ class TestProxy:
@pytest.mark.parametrize('val, expected', [
('system', configtypes.SYSTEM_PROXY),
- ('none', QNetworkProxy(QNetworkProxy.NoProxy)),
+ ('none', QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.NoProxy)),
('socks://example.com/',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com')),
+ QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.Socks5Proxy, 'example.com')),
('socks5://foo:bar@example.com:2323',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com', 2323,
+ QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.Socks5Proxy, 'example.com', 2323,
'foo', 'bar')),
('pac+http://example.com/proxy.pac',
- pac.PACFetcher(QUrl('pac+http://example.com/proxy.pac'))),
+ pac.PACFetcher(QtCore.QUrl('pac+http://example.com/proxy.pac'))),
('pac+file:///tmp/proxy.pac',
- pac.PACFetcher(QUrl('pac+file:///tmp/proxy.pac'))),
+ pac.PACFetcher(QtCore.QUrl('pac+file:///tmp/proxy.pac'))),
])
def test_to_py_valid(self, klass, val, expected):
actual = klass().to_py(val)
- if isinstance(actual, QNetworkProxy):
- actual = QNetworkProxy(actual)
+ if isinstance(actual, QtNetwork.QNetworkProxy):
+ actual = QtNetwork.QNetworkProxy(actual)
assert actual == expected
@pytest.mark.parametrize('val', [
@@ -1958,8 +1956,8 @@ class TestFuzzyUrl:
return configtypes.FuzzyUrl
@pytest.mark.parametrize('val, expected', [
- ('http://example.com/?q={}', QUrl('http://example.com/?q={}')),
- ('example.com', QUrl('http://example.com')),
+ ('http://example.com/?q={}', QtCore.QUrl('http://example.com/?q={}')),
+ ('example.com', QtCore.QUrl('http://example.com')),
])
def test_to_py_valid(self, klass, val, expected):
assert klass().to_py(val) == expected
@@ -2014,8 +2012,8 @@ class TestEncoding:
class TestUrl:
TESTS = {
- 'http://qutebrowser.org/': QUrl('http://qutebrowser.org/'),
- 'http://heise.de/': QUrl('http://heise.de/'),
+ 'http://qutebrowser.org/': QtCore.QUrl('http://qutebrowser.org/'),
+ 'http://heise.de/': QtCore.QUrl('http://heise.de/'),
}
@pytest.fixture
diff --git a/tests/unit/config/test_configutils.py b/tests/unit/config/test_configutils.py
index 3fc5cd561..539524f2a 100644
--- a/tests/unit/config/test_configutils.py
+++ b/tests/unit/config/test_configutils.py
@@ -20,8 +20,7 @@
import hypothesis
from hypothesis import strategies
import pytest
-from PyQt5.QtCore import QUrl
-from PyQt5.QtWidgets import QLabel
+from qutebrowser.qt import QtWidgets, QtCore
from qutebrowser.config import configutils, configdata, configtypes, configexc
from qutebrowser.utils import urlmatch, usertypes, qtutils
@@ -112,8 +111,8 @@ def test_add_existing(values):
def test_add_new(values, other_pattern):
values.add('example.org value', other_pattern)
assert values.get_for_url() == 'global value'
- example_com = QUrl('https://www.example.com/')
- example_org = QUrl('https://www.example.org/')
+ example_com = QtCore.QUrl('https://www.example.com/')
+ example_org = QtCore.QUrl('https://www.example.org/')
assert values.get_for_url(example_com) == 'example value'
assert values.get_for_url(example_org) == 'example.org value'
@@ -122,7 +121,7 @@ def test_remove_existing(values, pattern):
removed = values.remove(pattern)
assert removed
- url = QUrl('https://www.example.com/')
+ url = QtCore.QUrl('https://www.example.com/')
assert values.get_for_url(url) == 'global value'
@@ -130,7 +129,7 @@ def test_remove_non_existing(values, other_pattern):
removed = values.remove(other_pattern)
assert not removed
- url = QUrl('https://www.example.com/')
+ url = QtCore.QUrl('https://www.example.com/')
assert values.get_for_url(url) == 'example value'
@@ -142,13 +141,13 @@ def test_clear(values):
def test_get_matching(values):
- url = QUrl('https://www.example.com/')
+ url = QtCore.QUrl('https://www.example.com/')
assert values.get_for_url(url, fallback=False) == 'example value'
def test_get_invalid(values):
with pytest.raises(qtutils.QtValueError):
- values.get_for_url(QUrl())
+ values.get_for_url(QtCore.QUrl())
def test_get_unset(empty_values):
@@ -165,12 +164,12 @@ def test_get_unset_fallback(empty_values):
def test_get_non_matching(values):
- url = QUrl('https://www.example.ch/')
+ url = QtCore.QUrl('https://www.example.ch/')
assert values.get_for_url(url, fallback=False) is usertypes.UNSET
def test_get_non_matching_fallback(values):
- url = QUrl('https://www.example.ch/')
+ url = QtCore.QUrl('https://www.example.ch/')
assert values.get_for_url(url) == 'global value'
@@ -178,7 +177,7 @@ def test_get_multiple_matches(values):
"""With multiple matching pattern, the last added should win."""
all_pattern = urlmatch.UrlPattern('*://*/')
values.add('new value', all_pattern)
- url = QUrl('https://www.example.com/')
+ url = QtCore.QUrl('https://www.example.com/')
assert values.get_for_url(url) == 'new value'
@@ -188,7 +187,7 @@ def test_get_non_domain_patterns(empty_values):
empty_values.add('fallback')
empty_values.add('value', pat1)
- assert empty_values.get_for_url(QUrl("http://qutebrowser.org")) == 'value'
+ assert empty_values.get_for_url(QtCore.QUrl("http://qutebrowser.org")) == 'value'
assert empty_values.get_for_url() == 'fallback'
@@ -245,9 +244,9 @@ def test_get_trailing_dot(values):
other_pattern = urlmatch.UrlPattern('https://www.example.org./')
values.add('example.org value', other_pattern)
assert values.get_for_url() == 'global value'
- example_com = QUrl('https://www.example.com/')
- example_org = QUrl('https://www.example.org./')
- example_org_2 = QUrl('https://www.example.org/')
+ example_com = QtCore.QUrl('https://www.example.com/')
+ example_org = QtCore.QUrl('https://www.example.org./')
+ example_org_2 = QtCore.QUrl('https://www.example.org/')
assert values.get_for_url(example_com) == 'example value'
assert (values.get_for_url(example_org) ==
values.get_for_url(example_org_2) ==
@@ -262,7 +261,7 @@ def test_get_trailing_dot(values):
values.remove(pattern),
id='remove'),
pytest.param(lambda values, pattern:
- values.get_for_url(QUrl('https://example.org/')),
+ values.get_for_url(QtCore.QUrl('https://example.org/')),
id='get_for_url'),
pytest.param(lambda values, pattern:
values.get_for_pattern(pattern),
@@ -292,7 +291,7 @@ def test_add_url_benchmark(values, benchmark):
'http://bop.foo.bar.baz/',
])
def test_domain_lookup_sparse_benchmark(url, values, benchmark):
- url = QUrl(url)
+ url = QtCore.QUrl(url)
values.add(False, urlmatch.UrlPattern("*.foo.bar.baz"))
for line in testutils.blocked_hosts():
values.add(False, urlmatch.UrlPattern(line))
@@ -349,7 +348,7 @@ class TestFontFamilies:
def test_system_default_rendering(self, qtbot):
families = configutils.FontFamilies.from_system_default()
- label = QLabel()
+ label = QtWidgets.QLabel()
qtbot.add_widget(label)
label.setText("Hello World")
@@ -371,7 +370,7 @@ class TestFontFamilies:
# Try to find out whether the monospace font did a fallback on a non-monospace
# font...
- fallback_label = QLabel() # pylint: disable=unreachable
+ fallback_label = QtWidgets.QLabel() # pylint: disable=unreachable
qtbot.add_widget(label)
fallback_label.setText("fallback")
diff --git a/tests/unit/config/test_qtargs_locale_workaround.py b/tests/unit/config/test_qtargs_locale_workaround.py
index 4a4152b80..96d619243 100644
--- a/tests/unit/config/test_qtargs_locale_workaround.py
+++ b/tests/unit/config/test_qtargs_locale_workaround.py
@@ -20,7 +20,7 @@ import os
import pathlib
import pytest
-from PyQt5.QtCore import QLocale
+from qutebrowser.qt import QtCore
from qutebrowser.utils import utils
from qutebrowser.config import qtargs
@@ -406,7 +406,7 @@ def qtwe_version():
])
@pytest.mark.linux
def test_lang_workaround_all_locales(lang, expected, qtwe_version):
- locale_name = QLocale(lang).bcp47Name()
+ locale_name = QtCore.QLocale(lang).bcp47Name()
print(locale_name)
override = qtargs._get_lang_override(
diff --git a/tests/unit/config/test_stylesheet.py b/tests/unit/config/test_stylesheet.py
index 4ffa107ed..29811dcdd 100644
--- a/tests/unit/config/test_stylesheet.py
+++ b/tests/unit/config/test_stylesheet.py
@@ -18,12 +18,12 @@
import pytest
-from PyQt5.QtCore import QObject
+from qutebrowser.qt import QtCore
from qutebrowser.config import stylesheet
-class StyleObj(QObject):
+class StyleObj(QtCore.QObject):
def __init__(self, stylesheet=None, parent=None):
super().__init__(parent)
diff --git a/tests/unit/javascript/conftest.py b/tests/unit/javascript/conftest.py
index 4a7f09204..13f78eee0 100644
--- a/tests/unit/javascript/conftest.py
+++ b/tests/unit/javascript/conftest.py
@@ -23,7 +23,7 @@ import pathlib
import pytest
import jinja2
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
import qutebrowser
from qutebrowser.utils import usertypes
@@ -54,7 +54,7 @@ class JSTester:
'warning': 'error'
}
- def load(self, path, base_url=QUrl(), **kwargs):
+ def load(self, path, base_url=QtCore.QUrl(), **kwargs):
"""Load and display the given jinja test data.
Args:
@@ -86,10 +86,10 @@ class JSTester:
path: The string path from disk to load (relative to this file)
force: Whether to force loading even if the file is invalid.
"""
- self.load_url(QUrl.fromLocalFile(
+ self.load_url(QtCore.QUrl.fromLocalFile(
str(JS_DIR / path)), force)
- def load_url(self, url: QUrl, force: bool = False):
+ def load_url(self, url: QtCore.QUrl, force: bool = False):
"""Load a given QUrl.
Args:
diff --git a/tests/unit/javascript/test_greasemonkey.py b/tests/unit/javascript/test_greasemonkey.py
index 17847816d..24ff4f4d8 100644
--- a/tests/unit/javascript/test_greasemonkey.py
+++ b/tests/unit/javascript/test_greasemonkey.py
@@ -23,7 +23,7 @@ import textwrap
import pytest
import py.path # pylint: disable=no-name-in-module
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.utils import usertypes, version
from qutebrowser.browser import greasemonkey
@@ -76,7 +76,7 @@ def test_get_scripts_by_url(url, expected_matches):
_save_script(test_gm_script, 'test.user.js')
gm_manager = greasemonkey.GreasemonkeyManager()
- scripts = gm_manager.scripts_for(QUrl(url))
+ scripts = gm_manager.scripts_for(QtCore.QUrl(url))
assert len(scripts.start + scripts.end + scripts.idle) == expected_matches
@@ -100,7 +100,7 @@ def test_regex_includes_scripts_for(url, expected_matches):
_save_script(gh_dark_example, 'test.user.js')
gm_manager = greasemonkey.GreasemonkeyManager()
- scripts = gm_manager.scripts_for(QUrl(url))
+ scripts = gm_manager.scripts_for(QtCore.QUrl(url))
assert len(scripts.start + scripts.end + scripts.idle) == expected_matches
@@ -111,7 +111,7 @@ def test_no_metadata(caplog):
with caplog.at_level(logging.WARNING):
gm_manager = greasemonkey.GreasemonkeyManager()
- scripts = gm_manager.scripts_for(QUrl('http://notamatch.invalid/'))
+ scripts = gm_manager.scripts_for(QtCore.QUrl('http://notamatch.invalid/'))
assert len(scripts.start + scripts.end + scripts.idle) == 1
assert len(scripts.end) == 1
@@ -152,7 +152,7 @@ def test_bad_scheme(caplog):
with caplog.at_level(logging.WARNING):
gm_manager = greasemonkey.GreasemonkeyManager()
- scripts = gm_manager.scripts_for(QUrl('qute://settings'))
+ scripts = gm_manager.scripts_for(QtCore.QUrl('qute://settings'))
assert len(scripts.start + scripts.end + scripts.idle) == 0
diff --git a/tests/unit/javascript/test_js_execution.py b/tests/unit/javascript/test_js_execution.py
index e371e0f36..e7212085f 100644
--- a/tests/unit/javascript/test_js_execution.py
+++ b/tests/unit/javascript/test_js_execution.py
@@ -21,15 +21,13 @@
import pytest
+from qutebrowser.qt import QtWebKit, QtWebEngineWidgets
@pytest.mark.parametrize('js_enabled, expected', [(True, 2.0), (False, None)])
def test_simple_js_webkit(webview, js_enabled, expected):
"""With QtWebKit, evaluateJavaScript works when JS is on."""
- # If we get there (because of the webview fixture) we can be certain
- # QtWebKit is available
- from PyQt5.QtWebKit import QWebSettings
- webview.settings().setAttribute(QWebSettings.JavascriptEnabled, js_enabled)
+ webview.settings().setAttribute(QtWebKit.QWebSettings.JavascriptEnabled, js_enabled)
result = webview.page().mainFrame().evaluateJavaScript('1 + 1')
assert result == expected
@@ -37,10 +35,7 @@ def test_simple_js_webkit(webview, js_enabled, expected):
@pytest.mark.parametrize('js_enabled, expected', [(True, 2.0), (False, 2.0)])
def test_element_js_webkit(webview, js_enabled, expected):
"""With QtWebKit, evaluateJavaScript on an element works with JS off."""
- # If we get there (because of the webview fixture) we can be certain
- # QtWebKit is available
- from PyQt5.QtWebKit import QWebSettings
- webview.settings().setAttribute(QWebSettings.JavascriptEnabled, js_enabled)
+ webview.settings().setAttribute(QtWebKit.QWebSettings.JavascriptEnabled, js_enabled)
elem = webview.page().mainFrame().documentElement()
result = elem.evaluateJavaScript('1 + 1')
assert result == expected
@@ -61,16 +56,13 @@ def test_element_js_webkit(webview, js_enabled, expected):
def test_simple_js_webengine(qtbot, webengineview, qapp,
js_enabled, world, expected):
"""With QtWebEngine, runJavaScript works even when JS is off."""
- # If we get there (because of the webengineview fixture) we can be certain
- # QtWebEngine is available
- from PyQt5.QtWebEngineWidgets import QWebEngineSettings, QWebEngineScript
- assert world in [QWebEngineScript.MainWorld,
- QWebEngineScript.ApplicationWorld,
- QWebEngineScript.UserWorld]
+ assert world in [QtWebEngineWidgets.QWebEngineScript.MainWorld,
+ QtWebEngineWidgets.QWebEngineScript.ApplicationWorld,
+ QtWebEngineWidgets.QWebEngineScript.UserWorld]
settings = webengineview.settings()
- settings.setAttribute(QWebEngineSettings.JavascriptEnabled, js_enabled)
+ settings.setAttribute(QtWebEngineWidgets.QWebEngineSettings.JavascriptEnabled, js_enabled)
qapp.processEvents()
page = webengineview.page()
diff --git a/tests/unit/javascript/test_js_quirks.py b/tests/unit/javascript/test_js_quirks.py
index 7036dcfc9..b65b03273 100644
--- a/tests/unit/javascript/test_js_quirks.py
+++ b/tests/unit/javascript/test_js_quirks.py
@@ -26,37 +26,37 @@ the native functionality exists.
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.utils import usertypes
@pytest.mark.parametrize('base_url, source, expected', [
pytest.param(
- QUrl(),
+ QtCore.QUrl(),
'"This is a test".replaceAll("test", "fest")',
"This is a fest",
id='replace-all',
),
pytest.param(
- QUrl(),
+ QtCore.QUrl(),
'"This is a test".replaceAll(/[tr]est/g, "fest")',
"This is a fest",
id='replace-all-regex',
),
pytest.param(
- QUrl(),
+ QtCore.QUrl(),
'"This is a [test[".replaceAll("[", "<")',
"This is a <test<",
id='replace-all-reserved-string',
),
pytest.param(
- QUrl('https://test.qutebrowser.org/test'),
+ QtCore.QUrl('https://test.qutebrowser.org/test'),
'typeof globalThis.setTimeout === "function"',
True,
id='global-this',
),
pytest.param(
- QUrl(),
+ QtCore.QUrl(),
'Object.fromEntries([["0", "a"], ["1", "b"]])',
{'0': 'a', '1': 'b'},
id='object-fromentries',
diff --git a/tests/unit/keyinput/key_data.py b/tests/unit/keyinput/key_data.py
index c451d2534..4f4413b0b 100644
--- a/tests/unit/keyinput/key_data.py
+++ b/tests/unit/keyinput/key_data.py
@@ -25,7 +25,7 @@
import dataclasses
from typing import Optional
-from PyQt5.QtCore import Qt
+from qutebrowser.qt import QtCore
@dataclasses.dataclass(order=True)
@@ -50,7 +50,7 @@ class Key:
def __post_init__(self):
if self.attribute:
- self.member = getattr(Qt, 'Key_' + self.attribute, None)
+ self.member = getattr(QtCore.Qt, 'Key_' + self.attribute, None)
if self.name is None:
self.name = self.attribute
@@ -72,7 +72,7 @@ class Modifier:
member: Optional[int] = None
def __post_init__(self):
- self.member = getattr(Qt, self.attribute + 'Modifier')
+ self.member = getattr(QtCore.Qt, self.attribute + 'Modifier')
if self.name is None:
self.name = self.attribute
diff --git a/tests/unit/keyinput/test_basekeyparser.py b/tests/unit/keyinput/test_basekeyparser.py
index 84068bf47..5a787cea5 100644
--- a/tests/unit/keyinput/test_basekeyparser.py
+++ b/tests/unit/keyinput/test_basekeyparser.py
@@ -21,7 +21,7 @@
from unittest import mock
-from PyQt5.QtCore import Qt
+from qutebrowser.qt import QtCore
import pytest
from qutebrowser.keyinput import basekeyparser, keyutils
@@ -54,7 +54,7 @@ def handle_text():
"""Helper function to handle multiple fake keypresses."""
def func(kp, *args):
for key in args:
- info = keyutils.KeyInfo(key, Qt.NoModifier)
+ info = keyutils.KeyInfo(key, QtCore.Qt.NoModifier)
kp.handle(info.to_event())
return func
@@ -119,11 +119,11 @@ def test_read_config(keyparser, key_config_stub, changed_mode, expected):
class TestHandle:
def test_valid_key(self, prompt_keyparser, handle_text):
- modifier = Qt.MetaModifier if utils.is_mac else Qt.ControlModifier
+ modifier = QtCore.Qt.MetaModifier if utils.is_mac else QtCore.Qt.ControlModifier
infos = [
- keyutils.KeyInfo(Qt.Key_A, modifier),
- keyutils.KeyInfo(Qt.Key_X, modifier),
+ keyutils.KeyInfo(QtCore.Qt.Key_A, modifier),
+ keyutils.KeyInfo(QtCore.Qt.Key_X, modifier),
]
for info in infos:
prompt_keyparser.handle(info.to_event())
@@ -133,11 +133,11 @@ class TestHandle:
assert not prompt_keyparser._sequence
def test_valid_key_count(self, prompt_keyparser):
- modifier = Qt.MetaModifier if utils.is_mac else Qt.ControlModifier
+ modifier = QtCore.Qt.MetaModifier if utils.is_mac else QtCore.Qt.ControlModifier
infos = [
- keyutils.KeyInfo(Qt.Key_5, Qt.NoModifier),
- keyutils.KeyInfo(Qt.Key_A, modifier),
+ keyutils.KeyInfo(QtCore.Qt.Key_5, QtCore.Qt.NoModifier),
+ keyutils.KeyInfo(QtCore.Qt.Key_A, modifier),
]
for info in infos:
prompt_keyparser.handle(info.to_event())
@@ -145,10 +145,10 @@ class TestHandle:
'message-info ctrla', 5)
@pytest.mark.parametrize('keys', [
- [(Qt.Key_B, Qt.NoModifier), (Qt.Key_C, Qt.NoModifier)],
- [(Qt.Key_A, Qt.ControlModifier | Qt.AltModifier)],
+ [(QtCore.Qt.Key_B, QtCore.Qt.NoModifier), (QtCore.Qt.Key_C, QtCore.Qt.NoModifier)],
+ [(QtCore.Qt.Key_A, QtCore.Qt.ControlModifier | QtCore.Qt.AltModifier)],
# Only modifier
- [(Qt.Key_Shift, Qt.ShiftModifier)],
+ [(QtCore.Qt.Key_Shift, QtCore.Qt.ShiftModifier)],
])
def test_invalid_keys(self, prompt_keyparser, keys):
for key, modifiers in keys:
@@ -158,40 +158,40 @@ class TestHandle:
assert not prompt_keyparser._sequence
def test_dry_run(self, prompt_keyparser):
- b_info = keyutils.KeyInfo(Qt.Key_B, Qt.NoModifier)
+ b_info = keyutils.KeyInfo(QtCore.Qt.Key_B, QtCore.Qt.NoModifier)
prompt_keyparser.handle(b_info.to_event())
- a_info = keyutils.KeyInfo(Qt.Key_A, Qt.NoModifier)
+ a_info = keyutils.KeyInfo(QtCore.Qt.Key_A, QtCore.Qt.NoModifier)
prompt_keyparser.handle(a_info.to_event(), dry_run=True)
assert not prompt_keyparser.execute.called
assert prompt_keyparser._sequence
def test_dry_run_count(self, prompt_keyparser):
- info = keyutils.KeyInfo(Qt.Key_9, Qt.NoModifier)
+ info = keyutils.KeyInfo(QtCore.Qt.Key_9, QtCore.Qt.NoModifier)
prompt_keyparser.handle(info.to_event(), dry_run=True)
assert not prompt_keyparser._count
def test_invalid_key(self, prompt_keyparser):
- keys = [Qt.Key_B, 0x0]
+ keys = [QtCore.Qt.Key_B, 0x0]
for key in keys:
- info = keyutils.KeyInfo(key, Qt.NoModifier)
+ info = keyutils.KeyInfo(key, QtCore.Qt.NoModifier)
prompt_keyparser.handle(info.to_event())
assert not prompt_keyparser._sequence
def test_valid_keychain(self, handle_text, prompt_keyparser):
handle_text(prompt_keyparser,
# Press 'x' which is ignored because of no match
- Qt.Key_X,
+ QtCore.Qt.Key_X,
# Then start the real chain
- Qt.Key_B, Qt.Key_A)
+ QtCore.Qt.Key_B, QtCore.Qt.Key_A)
prompt_keyparser.execute.assert_called_with('message-info ba', None)
assert not prompt_keyparser._sequence
@pytest.mark.parametrize('key, modifiers, number', [
- (Qt.Key_0, Qt.NoModifier, 0),
- (Qt.Key_1, Qt.NoModifier, 1),
- (Qt.Key_1, Qt.KeypadModifier, 1),
+ (QtCore.Qt.Key_0, QtCore.Qt.NoModifier, 0),
+ (QtCore.Qt.Key_1, QtCore.Qt.NoModifier, 1),
+ (QtCore.Qt.Key_1, QtCore.Qt.KeypadModifier, 1),
])
def test_number_press(self, prompt_keyparser,
key, modifiers, number):
@@ -201,8 +201,8 @@ class TestHandle:
assert not prompt_keyparser._sequence
@pytest.mark.parametrize('modifiers, text', [
- (Qt.NoModifier, '2'),
- (Qt.KeypadModifier, 'num-2'),
+ (QtCore.Qt.NoModifier, '2'),
+ (QtCore.Qt.KeypadModifier, 'num-2'),
])
def test_number_press_keypad(self, keyparser, config_stub,
modifiers, text):
@@ -210,18 +210,18 @@ class TestHandle:
config_stub.val.bindings.commands = {'normal': {
'2': 'message-info 2',
'<Num+2>': 'message-info num-2'}}
- keyparser.handle(keyutils.KeyInfo(Qt.Key_2, modifiers).to_event())
+ keyparser.handle(keyutils.KeyInfo(QtCore.Qt.Key_2, modifiers).to_event())
command = 'message-info {}'.format(text)
keyparser.execute.assert_called_once_with(command, None)
assert not keyparser._sequence
def test_umlauts(self, handle_text, keyparser, config_stub):
config_stub.val.bindings.commands = {'normal': {'ü': 'message-info ü'}}
- handle_text(keyparser, Qt.Key_Udiaeresis)
+ handle_text(keyparser, QtCore.Qt.Key_Udiaeresis)
keyparser.execute.assert_called_once_with('message-info ü', None)
def test_mapping(self, config_stub, handle_text, prompt_keyparser):
- handle_text(prompt_keyparser, Qt.Key_X)
+ handle_text(prompt_keyparser, QtCore.Qt.Key_X)
prompt_keyparser.execute.assert_called_once_with(
'message-info a', None)
@@ -230,27 +230,27 @@ class TestHandle:
config_stub.val.bindings.commands = {'normal': {'a': 'nop'}}
config_stub.val.bindings.key_mappings = {'1': 'a'}
- info = keyutils.KeyInfo(Qt.Key_1, Qt.KeypadModifier)
+ info = keyutils.KeyInfo(QtCore.Qt.Key_1, QtCore.Qt.KeypadModifier)
keyparser.handle(info.to_event())
keyparser.execute.assert_called_once_with('nop', None)
def test_binding_and_mapping(self, config_stub, handle_text, prompt_keyparser):
"""with a conflicting binding/mapping, the binding should win."""
- handle_text(prompt_keyparser, Qt.Key_B)
+ handle_text(prompt_keyparser, QtCore.Qt.Key_B)
assert not prompt_keyparser.execute.called
def test_mapping_in_key_chain(self, config_stub, handle_text, keyparser):
"""A mapping should work even as part of a keychain."""
config_stub.val.bindings.commands = {'normal':
{'aa': 'message-info aa'}}
- handle_text(keyparser, Qt.Key_A, Qt.Key_X)
+ handle_text(keyparser, QtCore.Qt.Key_A, QtCore.Qt.Key_X)
keyparser.execute.assert_called_once_with('message-info aa', None)
def test_binding_with_shift(self, prompt_keyparser):
"""Simulate a binding which involves shift."""
- for key, modifiers in [(Qt.Key_Y, Qt.NoModifier),
- (Qt.Key_Shift, Qt.ShiftModifier),
- (Qt.Key_Y, Qt.ShiftModifier)]:
+ for key, modifiers in [(QtCore.Qt.Key_Y, QtCore.Qt.NoModifier),
+ (QtCore.Qt.Key_Shift, QtCore.Qt.ShiftModifier),
+ (QtCore.Qt.Key_Y, QtCore.Qt.ShiftModifier)]:
info = keyutils.KeyInfo(key, modifiers)
prompt_keyparser.handle(info.to_event())
@@ -264,7 +264,7 @@ class TestHandle:
'a': 'message-info foo'
}
}
- info = keyutils.KeyInfo(Qt.Key_A, Qt.NoModifier)
+ info = keyutils.KeyInfo(QtCore.Qt.Key_A, QtCore.Qt.NoModifier)
keyparser.handle(info.to_event())
keyparser.execute.assert_called_once_with('message-info foo', None)
@@ -275,39 +275,39 @@ class TestCount:
def test_no_count(self, handle_text, prompt_keyparser):
"""Test with no count added."""
- handle_text(prompt_keyparser, Qt.Key_B, Qt.Key_A)
+ handle_text(prompt_keyparser, QtCore.Qt.Key_B, QtCore.Qt.Key_A)
prompt_keyparser.execute.assert_called_once_with(
'message-info ba', None)
assert not prompt_keyparser._sequence
def test_count_0(self, handle_text, prompt_keyparser):
- handle_text(prompt_keyparser, Qt.Key_0, Qt.Key_B, Qt.Key_A)
+ handle_text(prompt_keyparser, QtCore.Qt.Key_0, QtCore.Qt.Key_B, QtCore.Qt.Key_A)
calls = [mock.call('message-info 0', None),
mock.call('message-info ba', None)]
prompt_keyparser.execute.assert_has_calls(calls)
assert not prompt_keyparser._sequence
def test_count_42(self, handle_text, prompt_keyparser):
- handle_text(prompt_keyparser, Qt.Key_4, Qt.Key_2, Qt.Key_B, Qt.Key_A)
+ handle_text(prompt_keyparser, QtCore.Qt.Key_4, QtCore.Qt.Key_2, QtCore.Qt.Key_B, QtCore.Qt.Key_A)
prompt_keyparser.execute.assert_called_once_with('message-info ba', 42)
assert not prompt_keyparser._sequence
def test_count_42_invalid(self, handle_text, prompt_keyparser):
# Invalid call with ccx gets ignored
handle_text(prompt_keyparser,
- Qt.Key_4, Qt.Key_2, Qt.Key_C, Qt.Key_C, Qt.Key_X)
+ QtCore.Qt.Key_4, QtCore.Qt.Key_2, QtCore.Qt.Key_C, QtCore.Qt.Key_C, QtCore.Qt.Key_X)
assert not prompt_keyparser.execute.called
assert not prompt_keyparser._sequence
# Valid call with ccc gets the correct count
handle_text(prompt_keyparser,
- Qt.Key_2, Qt.Key_3, Qt.Key_C, Qt.Key_C, Qt.Key_C)
+ QtCore.Qt.Key_2, QtCore.Qt.Key_3, QtCore.Qt.Key_C, QtCore.Qt.Key_C, QtCore.Qt.Key_C)
prompt_keyparser.execute.assert_called_once_with(
'message-info ccc', 23)
assert not prompt_keyparser._sequence
def test_superscript(self, handle_text, prompt_keyparser):
# https://github.com/qutebrowser/qutebrowser/issues/3743
- handle_text(prompt_keyparser, Qt.Key_twosuperior, Qt.Key_B, Qt.Key_A)
+ handle_text(prompt_keyparser, QtCore.Qt.Key_twosuperior, QtCore.Qt.Key_B, QtCore.Qt.Key_A)
def test_count_keystring_update(self, qtbot,
handle_text, prompt_keyparser):
@@ -315,17 +315,17 @@ class TestCount:
with qtbot.wait_signals([
prompt_keyparser.keystring_updated,
prompt_keyparser.keystring_updated]) as blocker:
- handle_text(prompt_keyparser, Qt.Key_4, Qt.Key_2)
+ handle_text(prompt_keyparser, QtCore.Qt.Key_4, QtCore.Qt.Key_2)
sig1, sig2 = blocker.all_signals_and_args
assert sig1.args == ('4',)
assert sig2.args == ('42',)
def test_numpad(self, prompt_keyparser):
"""Make sure we can enter a count via numpad."""
- for key, modifiers in [(Qt.Key_4, Qt.KeypadModifier),
- (Qt.Key_2, Qt.KeypadModifier),
- (Qt.Key_B, Qt.NoModifier),
- (Qt.Key_A, Qt.NoModifier)]:
+ for key, modifiers in [(QtCore.Qt.Key_4, QtCore.Qt.KeypadModifier),
+ (QtCore.Qt.Key_2, QtCore.Qt.KeypadModifier),
+ (QtCore.Qt.Key_B, QtCore.Qt.NoModifier),
+ (QtCore.Qt.Key_A, QtCore.Qt.NoModifier)]:
info = keyutils.KeyInfo(key, modifiers)
prompt_keyparser.handle(info.to_event())
prompt_keyparser.execute.assert_called_once_with('message-info ba', 42)
@@ -352,7 +352,7 @@ def test_respect_config_when_matching_counts(keyparser, config_stub):
"""Don't match counts if disabled in the config."""
config_stub.val.input.match_counts = False
- info = keyutils.KeyInfo(Qt.Key_1, Qt.NoModifier)
+ info = keyutils.KeyInfo(QtCore.Qt.Key_1, QtCore.Qt.NoModifier)
keyparser.handle(info.to_event())
assert not keyparser._sequence
diff --git a/tests/unit/keyinput/test_bindingtrie.py b/tests/unit/keyinput/test_bindingtrie.py
index c769386c0..0a45a03c4 100644
--- a/tests/unit/keyinput/test_bindingtrie.py
+++ b/tests/unit/keyinput/test_bindingtrie.py
@@ -25,7 +25,7 @@ import textwrap
import pytest
-from PyQt5.QtGui import QKeySequence
+from qutebrowser.qt import QtGui
from qutebrowser.keyinput import basekeyparser
from qutebrowser.keyinput import keyutils
@@ -39,7 +39,7 @@ def test_matches_single(entered, configured, match_type):
configured = keyutils.KeySequence.parse(configured)
trie = basekeyparser.BindingTrie()
trie[configured] = "eeloo"
- command = "eeloo" if match_type == QKeySequence.ExactMatch else None
+ command = "eeloo" if match_type == QtGui.QKeySequence.ExactMatch else None
result = basekeyparser.MatchResult(match_type=match_type,
command=command,
sequence=entered)
@@ -82,22 +82,22 @@ def test_str():
@pytest.mark.parametrize('configured, expected', [
([],
# null match
- [('a', QKeySequence.NoMatch),
- ('', QKeySequence.NoMatch)]),
+ [('a', QtGui.QKeySequence.NoMatch),
+ ('', QtGui.QKeySequence.NoMatch)]),
(['abcd'],
- [('abcd', QKeySequence.ExactMatch),
- ('abc', QKeySequence.PartialMatch)]),
+ [('abcd', QtGui.QKeySequence.ExactMatch),
+ ('abc', QtGui.QKeySequence.PartialMatch)]),
(['aa', 'ab', 'ac', 'ad'],
- [('ac', QKeySequence.ExactMatch),
- ('a', QKeySequence.PartialMatch),
- ('f', QKeySequence.NoMatch),
- ('acd', QKeySequence.NoMatch)]),
+ [('ac', QtGui.QKeySequence.ExactMatch),
+ ('a', QtGui.QKeySequence.PartialMatch),
+ ('f', QtGui.QKeySequence.NoMatch),
+ ('acd', QtGui.QKeySequence.NoMatch)]),
(['aaaaaaab', 'aaaaaaac', 'aaaaaaad'],
- [('aaaaaaab', QKeySequence.ExactMatch),
- ('z', QKeySequence.NoMatch)]),
+ [('aaaaaaab', QtGui.QKeySequence.ExactMatch),
+ ('z', QtGui.QKeySequence.NoMatch)]),
(string.ascii_letters,
- [('a', QKeySequence.ExactMatch),
- ('!', QKeySequence.NoMatch)]),
+ [('a', QtGui.QKeySequence.ExactMatch),
+ ('!', QtGui.QKeySequence.NoMatch)]),
])
def test_matches_tree(configured, expected, benchmark):
trie = basekeyparser.BindingTrie()
@@ -107,7 +107,7 @@ def test_matches_tree(configured, expected, benchmark):
def run():
for entered, match_type in expected:
sequence = keyutils.KeySequence.parse(entered)
- command = ("eeloo" if match_type == QKeySequence.ExactMatch
+ command = ("eeloo" if match_type == QtGui.QKeySequence.ExactMatch
else None)
result = basekeyparser.MatchResult(match_type=match_type,
command=command,
diff --git a/tests/unit/keyinput/test_keyutils.py b/tests/unit/keyinput/test_keyutils.py
index 195518127..70d7f4aa2 100644
--- a/tests/unit/keyinput/test_keyutils.py
+++ b/tests/unit/keyinput/test_keyutils.py
@@ -22,13 +22,12 @@ import operator
import hypothesis
from hypothesis import strategies
import pytest
-from PyQt5.QtCore import Qt, QEvent, pyqtSignal
-from PyQt5.QtGui import QKeyEvent, QKeySequence
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt import QtWidgets
from unit.keyinput import key_data
from qutebrowser.keyinput import keyutils
from qutebrowser.utils import utils
+from qutebrowser.qt import QtGui, QtCore
@pytest.fixture(params=key_data.KEYS, ids=lambda k: k.attribute)
@@ -61,8 +60,8 @@ def qtest_key(request):
def test_key_data_keys():
"""Make sure all possible keys are in key_data.KEYS."""
key_names = {name[len("Key_"):]
- for name, value in sorted(vars(Qt).items())
- if isinstance(value, Qt.Key)}
+ for name, value in sorted(vars(QtCore.Qt).items())
+ if isinstance(value, QtCore.Qt.Key)}
key_data_names = {key.attribute for key in sorted(key_data.KEYS)}
diff = key_names - key_data_names
assert not diff
@@ -71,15 +70,15 @@ def test_key_data_keys():
def test_key_data_modifiers():
"""Make sure all possible modifiers are in key_data.MODIFIERS."""
mod_names = {name[:-len("Modifier")]
- for name, value in sorted(vars(Qt).items())
- if isinstance(value, Qt.KeyboardModifier) and
- value not in [Qt.NoModifier, Qt.KeyboardModifierMask]}
+ for name, value in sorted(vars(QtCore.Qt).items())
+ if isinstance(value, QtCore.Qt.KeyboardModifier) and
+ value not in [QtCore.Qt.NoModifier, QtCore.Qt.KeyboardModifierMask]}
mod_data_names = {mod.attribute for mod in sorted(key_data.MODIFIERS)}
diff = mod_names - mod_data_names
assert not diff
-class KeyTesterWidget(QWidget):
+class KeyTesterWidget(QtWidgets.QWidget):
"""Widget to get the text of QKeyPressEvents.
@@ -87,7 +86,7 @@ class KeyTesterWidget(QWidget):
call that directly, only via QTest::keyPress.
"""
- got_text = pyqtSignal()
+ got_text = QtCore.pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
@@ -106,7 +105,7 @@ class TestKeyInfoText:
See key_data.py for inputs and expected values.
"""
- modifiers = Qt.ShiftModifier if upper else Qt.KeyboardModifiers()
+ modifiers = QtCore.Qt.ShiftModifier if upper else QtCore.Qt.KeyboardModifiers()
info = keyutils.KeyInfo(qt_key.member, modifiers=modifiers)
expected = qt_key.uppertext if upper else qt_key.text
assert info.text() == expected
@@ -126,7 +125,7 @@ class TestKeyInfoText:
qtbot.keyPress(key_tester, qtest_key.member)
info = keyutils.KeyInfo(qtest_key.member,
- modifiers=Qt.KeyboardModifiers())
+ modifiers=QtCore.Qt.KeyboardModifiers())
assert info.text() == key_tester.text.lower()
@@ -143,45 +142,45 @@ class TestKeyToString:
monkeypatch.delattr(keyutils.Qt, 'Key_AltGr')
# We don't want to test the key which is actually missing - we only
# want to know if the mapping still behaves properly.
- assert keyutils._key_to_string(Qt.Key_A) == 'A'
+ assert keyutils._key_to_string(QtCore.Qt.Key_A) == 'A'
@pytest.mark.parametrize('key, modifiers, expected', [
- (Qt.Key_A, Qt.NoModifier, 'a'),
- (Qt.Key_A, Qt.ShiftModifier, 'A'),
-
- (Qt.Key_Space, Qt.NoModifier, '<Space>'),
- (Qt.Key_Space, Qt.ShiftModifier, '<Shift+Space>'),
- (Qt.Key_Tab, Qt.ShiftModifier, '<Shift+Tab>'),
- (Qt.Key_A, Qt.ControlModifier, '<Ctrl+a>'),
- (Qt.Key_A, Qt.ControlModifier | Qt.ShiftModifier, '<Ctrl+Shift+a>'),
- (Qt.Key_A,
- Qt.ControlModifier | Qt.AltModifier | Qt.MetaModifier | Qt.ShiftModifier,
+ (QtCore.Qt.Key_A, QtCore.Qt.NoModifier, 'a'),
+ (QtCore.Qt.Key_A, QtCore.Qt.ShiftModifier, 'A'),
+
+ (QtCore.Qt.Key_Space, QtCore.Qt.NoModifier, '<Space>'),
+ (QtCore.Qt.Key_Space, QtCore.Qt.ShiftModifier, '<Shift+Space>'),
+ (QtCore.Qt.Key_Tab, QtCore.Qt.ShiftModifier, '<Shift+Tab>'),
+ (QtCore.Qt.Key_A, QtCore.Qt.ControlModifier, '<Ctrl+a>'),
+ (QtCore.Qt.Key_A, QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier, '<Ctrl+Shift+a>'),
+ (QtCore.Qt.Key_A,
+ QtCore.Qt.ControlModifier | QtCore.Qt.AltModifier | QtCore.Qt.MetaModifier | QtCore.Qt.ShiftModifier,
'<Meta+Ctrl+Alt+Shift+a>'),
- (ord('Œ'), Qt.NoModifier, '<Œ>'),
- (ord('Œ'), Qt.ShiftModifier, '<Shift+Œ>'),
- (ord('Œ'), Qt.GroupSwitchModifier, '<AltGr+Œ>'),
- (ord('Œ'), Qt.GroupSwitchModifier | Qt.ShiftModifier, '<AltGr+Shift+Œ>'),
-
- (Qt.Key_Shift, Qt.ShiftModifier, '<Shift>'),
- (Qt.Key_Shift, Qt.ShiftModifier | Qt.ControlModifier, '<Ctrl+Shift>'),
- (Qt.Key_Alt, Qt.AltModifier, '<Alt>'),
- (Qt.Key_Shift, Qt.GroupSwitchModifier | Qt.ShiftModifier, '<AltGr+Shift>'),
- (Qt.Key_AltGr, Qt.GroupSwitchModifier, '<AltGr>'),
+ (ord('Œ'), QtCore.Qt.NoModifier, '<Œ>'),
+ (ord('Œ'), QtCore.Qt.ShiftModifier, '<Shift+Œ>'),
+ (ord('Œ'), QtCore.Qt.GroupSwitchModifier, '<AltGr+Œ>'),
+ (ord('Œ'), QtCore.Qt.GroupSwitchModifier | QtCore.Qt.ShiftModifier, '<AltGr+Shift+Œ>'),
+
+ (QtCore.Qt.Key_Shift, QtCore.Qt.ShiftModifier, '<Shift>'),
+ (QtCore.Qt.Key_Shift, QtCore.Qt.ShiftModifier | QtCore.Qt.ControlModifier, '<Ctrl+Shift>'),
+ (QtCore.Qt.Key_Alt, QtCore.Qt.AltModifier, '<Alt>'),
+ (QtCore.Qt.Key_Shift, QtCore.Qt.GroupSwitchModifier | QtCore.Qt.ShiftModifier, '<AltGr+Shift>'),
+ (QtCore.Qt.Key_AltGr, QtCore.Qt.GroupSwitchModifier, '<AltGr>'),
])
def test_key_info_str(key, modifiers, expected):
assert str(keyutils.KeyInfo(key, modifiers)) == expected
@pytest.mark.parametrize('info1, info2, equal', [
- (keyutils.KeyInfo(Qt.Key_A, Qt.NoModifier),
- keyutils.KeyInfo(Qt.Key_A, Qt.NoModifier),
+ (keyutils.KeyInfo(QtCore.Qt.Key_A, QtCore.Qt.NoModifier),
+ keyutils.KeyInfo(QtCore.Qt.Key_A, QtCore.Qt.NoModifier),
True),
- (keyutils.KeyInfo(Qt.Key_A, Qt.NoModifier),
- keyutils.KeyInfo(Qt.Key_B, Qt.NoModifier),
+ (keyutils.KeyInfo(QtCore.Qt.Key_A, QtCore.Qt.NoModifier),
+ keyutils.KeyInfo(QtCore.Qt.Key_B, QtCore.Qt.NoModifier),
False),
- (keyutils.KeyInfo(Qt.Key_A, Qt.NoModifier),
- keyutils.KeyInfo(Qt.Key_B, Qt.ControlModifier),
+ (keyutils.KeyInfo(QtCore.Qt.Key_A, QtCore.Qt.NoModifier),
+ keyutils.KeyInfo(QtCore.Qt.Key_B, QtCore.Qt.ControlModifier),
False),
])
def test_hash(info1, info2, equal):
@@ -189,19 +188,19 @@ def test_hash(info1, info2, equal):
@pytest.mark.parametrize('key, modifiers, text, expected', [
- (0xd83c, Qt.NoModifier, '🏻', '<🏻>'),
- (0xd867, Qt.NoModifier, '𩷶', '<𩷶>'),
- (0xd867, Qt.ShiftModifier, '𩷶', '<Shift+𩷶>'),
+ (0xd83c, QtCore.Qt.NoModifier, '🏻', '<🏻>'),
+ (0xd867, QtCore.Qt.NoModifier, '𩷶', '<𩷶>'),
+ (0xd867, QtCore.Qt.ShiftModifier, '𩷶', '<Shift+𩷶>'),
])
def test_surrogates(key, modifiers, text, expected):
- evt = QKeyEvent(QKeyEvent.KeyPress, key, modifiers, text)
+ evt = QtGui.QKeyEvent(QtGui.QKeyEvent.KeyPress, key, modifiers, text)
assert str(keyutils.KeyInfo.from_event(evt)) == expected
@pytest.mark.parametrize('keys, expected', [
([0x1f3fb], '<🏻>'),
([0x29df6], '<𩷶>'),
- ([Qt.Key_Shift, 0x29df6], '<Shift><𩷶>'),
+ ([QtCore.Qt.Key_Shift, 0x29df6], '<Shift><𩷶>'),
([0x1f468, 0x200d, 0x1f468, 0x200d, 0x1f466], '<👨><‍><👨><‍><👦>'),
])
def test_surrogate_sequences(keys, expected):
@@ -211,7 +210,7 @@ def test_surrogate_sequences(keys, expected):
# This shouldn't happen, but if it does we should handle it well
def test_surrogate_error():
- evt = QKeyEvent(QKeyEvent.KeyPress, 0xd83e, Qt.NoModifier, '🤞🏻')
+ evt = QtGui.QKeyEvent(QtGui.QKeyEvent.KeyPress, 0xd83e, QtCore.Qt.NoModifier, '🤞🏻')
with pytest.raises(keyutils.KeyParseError):
keyutils.KeyInfo.from_event(evt)
@@ -246,8 +245,8 @@ def test_parse_keystr(keystr, parts):
class TestKeySequence:
def test_init(self):
- seq = keyutils.KeySequence(Qt.Key_A, Qt.Key_B, Qt.Key_C, Qt.Key_D,
- Qt.Key_E)
+ seq = keyutils.KeySequence(QtCore.Qt.Key_A, QtCore.Qt.Key_B, QtCore.Qt.Key_C, QtCore.Qt.Key_D,
+ QtCore.Qt.Key_E)
assert len(seq._sequences) == 2
assert len(seq._sequences[0]) == 4
assert len(seq._sequences[1]) == 1
@@ -256,7 +255,7 @@ class TestKeySequence:
seq = keyutils.KeySequence()
assert not seq
- @pytest.mark.parametrize('key', [Qt.Key_unknown, -1, 0])
+ @pytest.mark.parametrize('key', [QtCore.Qt.Key_unknown, -1, 0])
def test_init_unknown(self, key):
with pytest.raises(keyutils.KeyParseError):
keyutils.KeySequence(key)
@@ -283,21 +282,21 @@ class TestKeySequence:
assert str(keyutils.KeySequence.parse(orig)) == normalized
def test_iter(self):
- seq = keyutils.KeySequence(Qt.Key_A | Qt.ControlModifier,
- Qt.Key_B | Qt.ShiftModifier,
- Qt.Key_C,
- Qt.Key_D,
- Qt.Key_E)
- expected = [keyutils.KeyInfo(Qt.Key_A, Qt.ControlModifier),
- keyutils.KeyInfo(Qt.Key_B, Qt.ShiftModifier),
- keyutils.KeyInfo(Qt.Key_C, Qt.NoModifier),
- keyutils.KeyInfo(Qt.Key_D, Qt.NoModifier),
- keyutils.KeyInfo(Qt.Key_E, Qt.NoModifier)]
+ seq = keyutils.KeySequence(QtCore.Qt.Key_A | QtCore.Qt.ControlModifier,
+ QtCore.Qt.Key_B | QtCore.Qt.ShiftModifier,
+ QtCore.Qt.Key_C,
+ QtCore.Qt.Key_D,
+ QtCore.Qt.Key_E)
+ expected = [keyutils.KeyInfo(QtCore.Qt.Key_A, QtCore.Qt.ControlModifier),
+ keyutils.KeyInfo(QtCore.Qt.Key_B, QtCore.Qt.ShiftModifier),
+ keyutils.KeyInfo(QtCore.Qt.Key_C, QtCore.Qt.NoModifier),
+ keyutils.KeyInfo(QtCore.Qt.Key_D, QtCore.Qt.NoModifier),
+ keyutils.KeyInfo(QtCore.Qt.Key_E, QtCore.Qt.NoModifier)]
assert list(seq) == expected
def test_repr(self):
- seq = keyutils.KeySequence(Qt.Key_A | Qt.ControlModifier,
- Qt.Key_B | Qt.ShiftModifier)
+ seq = keyutils.KeySequence(QtCore.Qt.Key_A | QtCore.Qt.ControlModifier,
+ QtCore.Qt.Key_B | QtCore.Qt.ShiftModifier)
assert repr(seq) == ("<qutebrowser.keyinput.keyutils.KeySequence "
"keys='<Ctrl+a>B'>")
@@ -369,7 +368,7 @@ class TestKeySequence:
def test_getitem(self):
seq = keyutils.KeySequence.parse('ab')
- expected = keyutils.KeyInfo(Qt.Key_B, Qt.NoModifier)
+ expected = keyutils.KeyInfo(QtCore.Qt.Key_B, QtCore.Qt.NoModifier)
assert seq[1] == expected
def test_getitem_slice(self):
@@ -382,27 +381,27 @@ class TestKeySequence:
MATCH_TESTS = [
# config: abcd
- ('abc', 'abcd', QKeySequence.PartialMatch),
- ('abcd', 'abcd', QKeySequence.ExactMatch),
- ('ax', 'abcd', QKeySequence.NoMatch),
- ('abcdef', 'abcd', QKeySequence.NoMatch),
+ ('abc', 'abcd', QtGui.QKeySequence.PartialMatch),
+ ('abcd', 'abcd', QtGui.QKeySequence.ExactMatch),
+ ('ax', 'abcd', QtGui.QKeySequence.NoMatch),
+ ('abcdef', 'abcd', QtGui.QKeySequence.NoMatch),
# config: abcd ef
- ('abc', 'abcdef', QKeySequence.PartialMatch),
- ('abcde', 'abcdef', QKeySequence.PartialMatch),
- ('abcd', 'abcdef', QKeySequence.PartialMatch),
- ('abcdx', 'abcdef', QKeySequence.NoMatch),
- ('ax', 'abcdef', QKeySequence.NoMatch),
- ('abcdefg', 'abcdef', QKeySequence.NoMatch),
- ('abcdef', 'abcdef', QKeySequence.ExactMatch),
+ ('abc', 'abcdef', QtGui.QKeySequence.PartialMatch),
+ ('abcde', 'abcdef', QtGui.QKeySequence.PartialMatch),
+ ('abcd', 'abcdef', QtGui.QKeySequence.PartialMatch),
+ ('abcdx', 'abcdef', QtGui.QKeySequence.NoMatch),
+ ('ax', 'abcdef', QtGui.QKeySequence.NoMatch),
+ ('abcdefg', 'abcdef', QtGui.QKeySequence.NoMatch),
+ ('abcdef', 'abcdef', QtGui.QKeySequence.ExactMatch),
# other examples
- ('ab', 'a', QKeySequence.NoMatch),
+ ('ab', 'a', QtGui.QKeySequence.NoMatch),
# empty strings
- ('', '', QKeySequence.ExactMatch),
- ('', 'a', QKeySequence.PartialMatch),
- ('a', '', QKeySequence.NoMatch)]
+ ('', '', QtGui.QKeySequence.ExactMatch),
+ ('', 'a', QtGui.QKeySequence.PartialMatch),
+ ('a', '', QtGui.QKeySequence.NoMatch)]
@pytest.mark.parametrize('entered, configured, match_type', MATCH_TESTS)
def test_matches(self, entered, configured, match_type):
@@ -411,75 +410,75 @@ class TestKeySequence:
assert entered.matches(configured) == match_type
@pytest.mark.parametrize('old, key, modifiers, text, expected', [
- ('a', Qt.Key_B, Qt.NoModifier, 'b', 'ab'),
- ('a', Qt.Key_B, Qt.ShiftModifier, 'B', 'aB'),
- ('a', Qt.Key_B, Qt.AltModifier | Qt.ShiftModifier, 'B',
+ ('a', QtCore.Qt.Key_B, QtCore.Qt.NoModifier, 'b', 'ab'),
+ ('a', QtCore.Qt.Key_B, QtCore.Qt.ShiftModifier, 'B', 'aB'),
+ ('a', QtCore.Qt.Key_B, QtCore.Qt.AltModifier | QtCore.Qt.ShiftModifier, 'B',
'a<Alt+Shift+b>'),
# Modifier stripping with symbols
- ('', Qt.Key_Colon, Qt.NoModifier, ':', ':'),
- ('', Qt.Key_Colon, Qt.ShiftModifier, ':', ':'),
- ('', Qt.Key_Colon, Qt.AltModifier | Qt.ShiftModifier, ':',
+ ('', QtCore.Qt.Key_Colon, QtCore.Qt.NoModifier, ':', ':'),
+ ('', QtCore.Qt.Key_Colon, QtCore.Qt.ShiftModifier, ':', ':'),
+ ('', QtCore.Qt.Key_Colon, QtCore.Qt.AltModifier | QtCore.Qt.ShiftModifier, ':',
'<Alt+Shift+:>'),
# Swapping Control/Meta on macOS
- ('', Qt.Key_A, Qt.ControlModifier, '',
+ ('', QtCore.Qt.Key_A, QtCore.Qt.ControlModifier, '',
'<Meta+A>' if utils.is_mac else '<Ctrl+A>'),
- ('', Qt.Key_A, Qt.ControlModifier | Qt.ShiftModifier, '',
+ ('', QtCore.Qt.Key_A, QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier, '',
'<Meta+Shift+A>' if utils.is_mac else '<Ctrl+Shift+A>'),
- ('', Qt.Key_A, Qt.MetaModifier, '',
+ ('', QtCore.Qt.Key_A, QtCore.Qt.MetaModifier, '',
'<Ctrl+A>' if utils.is_mac else '<Meta+A>'),
# Handling of Backtab
- ('', Qt.Key_Backtab, Qt.NoModifier, '', '<Backtab>'),
- ('', Qt.Key_Backtab, Qt.ShiftModifier, '', '<Shift+Tab>'),
- ('', Qt.Key_Backtab, Qt.AltModifier | Qt.ShiftModifier, '',
+ ('', QtCore.Qt.Key_Backtab, QtCore.Qt.NoModifier, '', '<Backtab>'),
+ ('', QtCore.Qt.Key_Backtab, QtCore.Qt.ShiftModifier, '', '<Shift+Tab>'),
+ ('', QtCore.Qt.Key_Backtab, QtCore.Qt.AltModifier | QtCore.Qt.ShiftModifier, '',
'<Alt+Shift+Tab>'),
# Stripping of Qt.GroupSwitchModifier
- ('', Qt.Key_A, Qt.GroupSwitchModifier, 'a', 'a'),
+ ('', QtCore.Qt.Key_A, QtCore.Qt.GroupSwitchModifier, 'a', 'a'),
])
def test_append_event(self, old, key, modifiers, text, expected):
seq = keyutils.KeySequence.parse(old)
- event = QKeyEvent(QKeyEvent.KeyPress, key, modifiers, text)
+ event = QtGui.QKeyEvent(QtGui.QKeyEvent.KeyPress, key, modifiers, text)
new = seq.append_event(event)
assert new == keyutils.KeySequence.parse(expected)
@pytest.mark.fake_os('mac')
@pytest.mark.parametrize('modifiers, expected', [
- (Qt.ControlModifier,
- Qt.MetaModifier),
- (Qt.MetaModifier,
- Qt.ControlModifier),
- (Qt.ControlModifier | Qt.MetaModifier,
- Qt.ControlModifier | Qt.MetaModifier),
- (Qt.ControlModifier | Qt.ShiftModifier,
- Qt.MetaModifier | Qt.ShiftModifier),
- (Qt.MetaModifier | Qt.ShiftModifier,
- Qt.ControlModifier | Qt.ShiftModifier),
- (Qt.ShiftModifier, Qt.ShiftModifier),
+ (QtCore.Qt.ControlModifier,
+ QtCore.Qt.MetaModifier),
+ (QtCore.Qt.MetaModifier,
+ QtCore.Qt.ControlModifier),
+ (QtCore.Qt.ControlModifier | QtCore.Qt.MetaModifier,
+ QtCore.Qt.ControlModifier | QtCore.Qt.MetaModifier),
+ (QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier,
+ QtCore.Qt.MetaModifier | QtCore.Qt.ShiftModifier),
+ (QtCore.Qt.MetaModifier | QtCore.Qt.ShiftModifier,
+ QtCore.Qt.ControlModifier | QtCore.Qt.ShiftModifier),
+ (QtCore.Qt.ShiftModifier, QtCore.Qt.ShiftModifier),
])
def test_fake_mac(self, modifiers, expected):
"""Make sure Control/Meta are swapped with a simulated Mac."""
seq = keyutils.KeySequence()
- info = keyutils.KeyInfo(key=Qt.Key_A, modifiers=modifiers)
+ info = keyutils.KeyInfo(key=QtCore.Qt.Key_A, modifiers=modifiers)
new = seq.append_event(info.to_event())
- assert new[0] == keyutils.KeyInfo(Qt.Key_A, expected)
+ assert new[0] == keyutils.KeyInfo(QtCore.Qt.Key_A, expected)
- @pytest.mark.parametrize('key', [Qt.Key_unknown, 0x0])
+ @pytest.mark.parametrize('key', [QtCore.Qt.Key_unknown, 0x0])
def test_append_event_invalid(self, key):
seq = keyutils.KeySequence()
- event = QKeyEvent(QKeyEvent.KeyPress, key, Qt.NoModifier, '')
+ event = QtGui.QKeyEvent(QtGui.QKeyEvent.KeyPress, key, QtCore.Qt.NoModifier, '')
with pytest.raises(keyutils.KeyParseError):
seq.append_event(event)
def test_strip_modifiers(self):
- seq = keyutils.KeySequence(Qt.Key_0,
- Qt.Key_1 | Qt.KeypadModifier,
- Qt.Key_A | Qt.ControlModifier)
- expected = keyutils.KeySequence(Qt.Key_0,
- Qt.Key_1,
- Qt.Key_A | Qt.ControlModifier)
+ seq = keyutils.KeySequence(QtCore.Qt.Key_0,
+ QtCore.Qt.Key_1 | QtCore.Qt.KeypadModifier,
+ QtCore.Qt.Key_A | QtCore.Qt.ControlModifier)
+ expected = keyutils.KeySequence(QtCore.Qt.Key_0,
+ QtCore.Qt.Key_1,
+ QtCore.Qt.Key_A | QtCore.Qt.ControlModifier)
assert seq.strip_modifiers() == expected
@pytest.mark.parametrize('inp, mappings, expected', [
@@ -497,31 +496,31 @@ class TestKeySequence:
@pytest.mark.parametrize('keystr, expected', [
('<Ctrl-Alt-y>',
- keyutils.KeySequence(Qt.ControlModifier | Qt.AltModifier | Qt.Key_Y)),
- ('x', keyutils.KeySequence(Qt.Key_X)),
- ('X', keyutils.KeySequence(Qt.ShiftModifier | Qt.Key_X)),
- ('<Escape>', keyutils.KeySequence(Qt.Key_Escape)),
- ('xyz', keyutils.KeySequence(Qt.Key_X, Qt.Key_Y, Qt.Key_Z)),
+ keyutils.KeySequence(QtCore.Qt.ControlModifier | QtCore.Qt.AltModifier | QtCore.Qt.Key_Y)),
+ ('x', keyutils.KeySequence(QtCore.Qt.Key_X)),
+ ('X', keyutils.KeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_X)),
+ ('<Escape>', keyutils.KeySequence(QtCore.Qt.Key_Escape)),
+ ('xyz', keyutils.KeySequence(QtCore.Qt.Key_X, QtCore.Qt.Key_Y, QtCore.Qt.Key_Z)),
('<Control-x><Meta-y>',
- keyutils.KeySequence(Qt.ControlModifier | Qt.Key_X,
- Qt.MetaModifier | Qt.Key_Y)),
-
- ('<Shift-x>', keyutils.KeySequence(Qt.ShiftModifier | Qt.Key_X)),
- ('<Alt-x>', keyutils.KeySequence(Qt.AltModifier | Qt.Key_X)),
- ('<Control-x>', keyutils.KeySequence(Qt.ControlModifier | Qt.Key_X)),
- ('<Meta-x>', keyutils.KeySequence(Qt.MetaModifier | Qt.Key_X)),
- ('<Num-x>', keyutils.KeySequence(Qt.KeypadModifier | Qt.Key_X)),
-
- ('>', keyutils.KeySequence(Qt.Key_Greater)),
- ('<', keyutils.KeySequence(Qt.Key_Less)),
- ('a>', keyutils.KeySequence(Qt.Key_A, Qt.Key_Greater)),
- ('a<', keyutils.KeySequence(Qt.Key_A, Qt.Key_Less)),
- ('>a', keyutils.KeySequence(Qt.Key_Greater, Qt.Key_A)),
- ('<a', keyutils.KeySequence(Qt.Key_Less, Qt.Key_A)),
+ keyutils.KeySequence(QtCore.Qt.ControlModifier | QtCore.Qt.Key_X,
+ QtCore.Qt.MetaModifier | QtCore.Qt.Key_Y)),
+
+ ('<Shift-x>', keyutils.KeySequence(QtCore.Qt.ShiftModifier | QtCore.Qt.Key_X)),
+ ('<Alt-x>', keyutils.KeySequence(QtCore.Qt.AltModifier | QtCore.Qt.Key_X)),
+ ('<Control-x>', keyutils.KeySequence(QtCore.Qt.ControlModifier | QtCore.Qt.Key_X)),
+ ('<Meta-x>', keyutils.KeySequence(QtCore.Qt.MetaModifier | QtCore.Qt.Key_X)),
+ ('<Num-x>', keyutils.KeySequence(QtCore.Qt.KeypadModifier | QtCore.Qt.Key_X)),
+
+ ('>', keyutils.KeySequence(QtCore.Qt.Key_Greater)),
+ ('<', keyutils.KeySequence(QtCore.Qt.Key_Less)),
+ ('a>', keyutils.KeySequence(QtCore.Qt.Key_A, QtCore.Qt.Key_Greater)),
+ ('a<', keyutils.KeySequence(QtCore.Qt.Key_A, QtCore.Qt.Key_Less)),
+ ('>a', keyutils.KeySequence(QtCore.Qt.Key_Greater, QtCore.Qt.Key_A)),
+ ('<a', keyutils.KeySequence(QtCore.Qt.Key_Less, QtCore.Qt.Key_A)),
('<alt+greater>',
- keyutils.KeySequence(Qt.Key_Greater | Qt.AltModifier)),
+ keyutils.KeySequence(QtCore.Qt.Key_Greater | QtCore.Qt.AltModifier)),
('<alt+less>',
- keyutils.KeySequence(Qt.Key_Less | Qt.AltModifier)),
+ keyutils.KeySequence(QtCore.Qt.Key_Less | QtCore.Qt.AltModifier)),
('<alt+<>', keyutils.KeyParseError),
('<alt+>>', keyutils.KeyParseError),
@@ -547,66 +546,66 @@ class TestKeySequence:
def test_key_info_from_event():
- ev = QKeyEvent(QEvent.KeyPress, Qt.Key_A, Qt.ShiftModifier, 'A')
+ ev = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, QtCore.Qt.Key_A, QtCore.Qt.ShiftModifier, 'A')
info = keyutils.KeyInfo.from_event(ev)
- assert info.key == Qt.Key_A
- assert info.modifiers == Qt.ShiftModifier
+ assert info.key == QtCore.Qt.Key_A
+ assert info.modifiers == QtCore.Qt.ShiftModifier
def test_key_info_to_event():
- info = keyutils.KeyInfo(Qt.Key_A, Qt.ShiftModifier)
+ info = keyutils.KeyInfo(QtCore.Qt.Key_A, QtCore.Qt.ShiftModifier)
ev = info.to_event()
- assert ev.key() == Qt.Key_A
- assert ev.modifiers() == Qt.ShiftModifier
+ assert ev.key() == QtCore.Qt.Key_A
+ assert ev.modifiers() == QtCore.Qt.ShiftModifier
assert ev.text() == 'A'
def test_key_info_to_int():
- info = keyutils.KeyInfo(Qt.Key_A, Qt.ShiftModifier)
- assert info.to_int() == Qt.Key_A | Qt.ShiftModifier
+ info = keyutils.KeyInfo(QtCore.Qt.Key_A, QtCore.Qt.ShiftModifier)
+ assert info.to_int() == QtCore.Qt.Key_A | QtCore.Qt.ShiftModifier
@pytest.mark.parametrize('key, printable', [
- (Qt.Key_Control, False),
- (Qt.Key_Escape, False),
- (Qt.Key_Tab, False),
- (Qt.Key_Backtab, False),
- (Qt.Key_Backspace, False),
- (Qt.Key_Return, False),
- (Qt.Key_Enter, False),
- (Qt.Key_Space, False),
+ (QtCore.Qt.Key_Control, False),
+ (QtCore.Qt.Key_Escape, False),
+ (QtCore.Qt.Key_Tab, False),
+ (QtCore.Qt.Key_Backtab, False),
+ (QtCore.Qt.Key_Backspace, False),
+ (QtCore.Qt.Key_Return, False),
+ (QtCore.Qt.Key_Enter, False),
+ (QtCore.Qt.Key_Space, False),
(0x0, False), # Used by Qt for unknown keys
- (Qt.Key_ydiaeresis, True),
- (Qt.Key_X, True),
+ (QtCore.Qt.Key_ydiaeresis, True),
+ (QtCore.Qt.Key_X, True),
])
def test_is_printable(key, printable):
assert keyutils._is_printable(key) == printable
- assert keyutils.is_special(key, Qt.NoModifier) != printable
+ assert keyutils.is_special(key, QtCore.Qt.NoModifier) != printable
@pytest.mark.parametrize('key, modifiers, special', [
- (Qt.Key_Escape, Qt.NoModifier, True),
- (Qt.Key_Escape, Qt.ShiftModifier, True),
- (Qt.Key_Escape, Qt.ControlModifier, True),
- (Qt.Key_X, Qt.ControlModifier, True),
- (Qt.Key_X, Qt.NoModifier, False),
- (Qt.Key_2, Qt.KeypadModifier, True),
- (Qt.Key_2, Qt.NoModifier, False),
- (Qt.Key_Shift, Qt.ShiftModifier, True),
- (Qt.Key_Control, Qt.ControlModifier, True),
- (Qt.Key_Alt, Qt.AltModifier, True),
- (Qt.Key_Meta, Qt.MetaModifier, True),
- (Qt.Key_Mode_switch, Qt.GroupSwitchModifier, True),
+ (QtCore.Qt.Key_Escape, QtCore.Qt.NoModifier, True),
+ (QtCore.Qt.Key_Escape, QtCore.Qt.ShiftModifier, True),
+ (QtCore.Qt.Key_Escape, QtCore.Qt.ControlModifier, True),
+ (QtCore.Qt.Key_X, QtCore.Qt.ControlModifier, True),
+ (QtCore.Qt.Key_X, QtCore.Qt.NoModifier, False),
+ (QtCore.Qt.Key_2, QtCore.Qt.KeypadModifier, True),
+ (QtCore.Qt.Key_2, QtCore.Qt.NoModifier, False),
+ (QtCore.Qt.Key_Shift, QtCore.Qt.ShiftModifier, True),
+ (QtCore.Qt.Key_Control, QtCore.Qt.ControlModifier, True),
+ (QtCore.Qt.Key_Alt, QtCore.Qt.AltModifier, True),
+ (QtCore.Qt.Key_Meta, QtCore.Qt.MetaModifier, True),
+ (QtCore.Qt.Key_Mode_switch, QtCore.Qt.GroupSwitchModifier, True),
])
def test_is_special(key, modifiers, special):
assert keyutils.is_special(key, modifiers) == special
@pytest.mark.parametrize('key, ismodifier', [
- (Qt.Key_Control, True),
- (Qt.Key_X, False),
- (Qt.Key_Super_L, False), # Modifier but not in _MODIFIER_MAP
+ (QtCore.Qt.Key_Control, True),
+ (QtCore.Qt.Key_X, False),
+ (QtCore.Qt.Key_Super_L, False), # Modifier but not in _MODIFIER_MAP
])
def test_is_modifier_key(key, ismodifier):
assert keyutils.is_modifier_key(key) == ismodifier
@@ -622,4 +621,4 @@ def test_is_modifier_key(key, ismodifier):
])
def test_non_plain(func):
with pytest.raises(AssertionError):
- func(Qt.Key_X | Qt.ControlModifier)
+ func(QtCore.Qt.Key_X | QtCore.Qt.ControlModifier)
diff --git a/tests/unit/keyinput/test_modeman.py b/tests/unit/keyinput/test_modeman.py
index 8cc298f87..d160ad19f 100644
--- a/tests/unit/keyinput/test_modeman.py
+++ b/tests/unit/keyinput/test_modeman.py
@@ -19,19 +19,18 @@
import pytest
-from PyQt5.QtCore import Qt, QObject, pyqtSignal
-
from qutebrowser.utils import usertypes
from qutebrowser.keyinput import keyutils
from qutebrowser.misc import objects
+from qutebrowser.qt import QtCore
-class FakeKeyparser(QObject):
+class FakeKeyparser(QtCore.QObject):
"""A fake BaseKeyParser which doesn't handle anything."""
- keystring_updated = pyqtSignal(str)
- request_leave = pyqtSignal(usertypes.KeyMode, str, bool)
+ keystring_updated = QtCore.pyqtSignal(str)
+ request_leave = QtCore.pyqtSignal(usertypes.KeyMode, str, bool)
def __init__(self):
super().__init__()
@@ -53,11 +52,11 @@ def set_qapp(monkeypatch, qapp):
@pytest.mark.parametrize('key, modifiers, filtered', [
- (Qt.Key_A, Qt.NoModifier, True),
- (Qt.Key_Up, Qt.NoModifier, False),
+ (QtCore.Qt.Key_A, QtCore.Qt.NoModifier, True),
+ (QtCore.Qt.Key_Up, QtCore.Qt.NoModifier, False),
# https://github.com/qutebrowser/qutebrowser/issues/1207
- (Qt.Key_A, Qt.ShiftModifier, True),
- (Qt.Key_A, Qt.ShiftModifier | Qt.ControlModifier, False),
+ (QtCore.Qt.Key_A, QtCore.Qt.ShiftModifier, True),
+ (QtCore.Qt.Key_A, QtCore.Qt.ShiftModifier | QtCore.Qt.ControlModifier, False),
])
def test_non_alphanumeric(key, modifiers, filtered, modeman):
"""Make sure non-alphanumeric keys are passed through correctly."""
diff --git a/tests/unit/keyinput/test_modeparsers.py b/tests/unit/keyinput/test_modeparsers.py
index ff3758362..ac91d14c7 100644
--- a/tests/unit/keyinput/test_modeparsers.py
+++ b/tests/unit/keyinput/test_modeparsers.py
@@ -19,8 +19,7 @@
"""Tests for mode parsers."""
-from PyQt5.QtCore import Qt
-from PyQt5.QtGui import QKeySequence
+from qutebrowser.qt import QtGui, QtCore
import pytest
@@ -65,7 +64,7 @@ class TestsNormalKeyParser:
# Press 'b' for a partial match.
# Then we check if the timer has been set up correctly
- keyparser.handle(keyutils.KeyInfo(Qt.Key_B, Qt.NoModifier).to_event())
+ keyparser.handle(keyutils.KeyInfo(QtCore.Qt.Key_B, QtCore.Qt.NoModifier).to_event())
assert timer.isSingleShot()
assert timer.interval() == 100
assert timer.isActive()
@@ -129,11 +128,11 @@ class TestHintKeyParser:
assert len(seq) == 2
match = keyparser.handle(seq[0].to_event())
- assert match == QKeySequence.PartialMatch
+ assert match == QtGui.QKeySequence.PartialMatch
assert hintmanager.keystr == prefix
match = keyparser.handle(seq[1].to_event())
- assert match == QKeySequence.ExactMatch
+ assert match == QtGui.QKeySequence.ExactMatch
assert hintmanager.keystr == hint
def test_match_key_mappings(self, config_stub, keyparser, hintmanager):
@@ -144,11 +143,11 @@ class TestHintKeyParser:
assert len(seq) == 2
match = keyparser.handle(seq[0].to_event())
- assert match == QKeySequence.PartialMatch
+ assert match == QtGui.QKeySequence.PartialMatch
assert hintmanager.keystr == 'a'
match = keyparser.handle(seq[1].to_event())
- assert match == QKeySequence.ExactMatch
+ assert match == QtGui.QKeySequence.ExactMatch
assert hintmanager.keystr == 'as'
def test_command(self, keyparser, config_stub, hintmanager, commandrunner):
@@ -159,17 +158,17 @@ class TestHintKeyParser:
keyparser.update_bindings(['xabcy'])
steps = [
- (Qt.Key_X, QKeySequence.PartialMatch, 'x'),
- (Qt.Key_A, QKeySequence.PartialMatch, ''),
- (Qt.Key_B, QKeySequence.PartialMatch, ''),
- (Qt.Key_C, QKeySequence.ExactMatch, ''),
+ (QtCore.Qt.Key_X, QtGui.QKeySequence.PartialMatch, 'x'),
+ (QtCore.Qt.Key_A, QtGui.QKeySequence.PartialMatch, ''),
+ (QtCore.Qt.Key_B, QtGui.QKeySequence.PartialMatch, ''),
+ (QtCore.Qt.Key_C, QtGui.QKeySequence.ExactMatch, ''),
]
for key, expected_match, keystr in steps:
- info = keyutils.KeyInfo(key, Qt.NoModifier)
+ info = keyutils.KeyInfo(key, QtCore.Qt.NoModifier)
match = keyparser.handle(info.to_event())
assert match == expected_match
assert hintmanager.keystr == keystr
- if key != Qt.Key_C:
+ if key != QtCore.Qt.Key_C:
assert not commandrunner.commands
assert commandrunner.commands == [('message-info abc', None)]
diff --git a/tests/unit/mainwindow/statusbar/test_textbase.py b/tests/unit/mainwindow/statusbar/test_textbase.py
index 33c4ffd76..fbf1688e9 100644
--- a/tests/unit/mainwindow/statusbar/test_textbase.py
+++ b/tests/unit/mainwindow/statusbar/test_textbase.py
@@ -19,17 +19,17 @@
"""Test TextBase widget."""
-from PyQt5.QtCore import Qt
+from qutebrowser.qt import QtCore
import pytest
from qutebrowser.mainwindow.statusbar.textbase import TextBase
@pytest.mark.parametrize('elidemode, check', [
- (Qt.ElideRight, lambda s: s.endswith('…') or s.endswith('...')),
- (Qt.ElideLeft, lambda s: s.startswith('…') or s.startswith('...')),
- (Qt.ElideMiddle, lambda s: '…' in s or '...' in s),
- (Qt.ElideNone, lambda s: '…' not in s and '...' not in s),
+ (QtCore.Qt.ElideRight, lambda s: s.endswith('…') or s.endswith('...')),
+ (QtCore.Qt.ElideLeft, lambda s: s.startswith('…') or s.startswith('...')),
+ (QtCore.Qt.ElideMiddle, lambda s: '…' in s or '...' in s),
+ (QtCore.Qt.ElideNone, lambda s: '…' not in s and '...' not in s),
])
def test_elided_text(fake_statusbar, qtbot, elidemode, check):
"""Ensure that a widget too small to hold the entire label text will elide.
diff --git a/tests/unit/mainwindow/statusbar/test_url.py b/tests/unit/mainwindow/statusbar/test_url.py
index efe4d6f93..5bc16f6e0 100644
--- a/tests/unit/mainwindow/statusbar/test_url.py
+++ b/tests/unit/mainwindow/statusbar/test_url.py
@@ -22,7 +22,7 @@
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.utils import usertypes, urlutils
from qutebrowser.mainwindow.statusbar import url
@@ -58,7 +58,7 @@ def test_set_url(url_widget, url_text, expected, which):
if url_text is None:
qurl = None
else:
- qurl = QUrl(url_text)
+ qurl = QtCore.QUrl(url_text)
if not qurl.isValid():
# Special case for the invalid URL above
expected = "Invalid URL!"
@@ -84,28 +84,28 @@ def test_set_url(url_widget, url_text, expected, which):
])
def test_on_load_status_changed(url_widget, status, expected):
"""Test text when status is changed."""
- url_widget.set_url(QUrl('www.example.com'))
+ url_widget.set_url(QtCore.QUrl('www.example.com'))
url_widget.on_load_status_changed(status)
assert url_widget._urltype == expected
@pytest.mark.parametrize('load_status, qurl', [
(usertypes.LoadStatus.success,
- QUrl('http://abc123.com/this/awesome/url.html')),
+ QtCore.QUrl('http://abc123.com/this/awesome/url.html')),
(usertypes.LoadStatus.success,
- QUrl('http://reddit.com/r/linux')),
+ QtCore.QUrl('http://reddit.com/r/linux')),
(usertypes.LoadStatus.success,
- QUrl('http://ä.com/')),
+ QtCore.QUrl('http://ä.com/')),
(usertypes.LoadStatus.success_https,
- QUrl('www.google.com')),
+ QtCore.QUrl('www.google.com')),
(usertypes.LoadStatus.success_https,
- QUrl('https://supersecret.gov/nsa/files.txt')),
+ QtCore.QUrl('https://supersecret.gov/nsa/files.txt')),
(usertypes.LoadStatus.warn,
- QUrl('www.shadysite.org/some/file/with/issues.htm')),
+ QtCore.QUrl('www.shadysite.org/some/file/with/issues.htm')),
(usertypes.LoadStatus.error,
- QUrl('invalid::/url')),
+ QtCore.QUrl('invalid::/url')),
(usertypes.LoadStatus.error,
- QUrl()),
+ QtCore.QUrl()),
])
def test_on_tab_changed(url_widget, fake_web_tab, load_status, qurl):
tab_widget = fake_web_tab(load_status=load_status, url=qurl)
@@ -121,22 +121,22 @@ def test_on_tab_changed(url_widget, fake_web_tab, load_status, qurl):
@pytest.mark.parametrize('qurl, load_status, expected_status', [
(
- QUrl('http://abc123.com/this/awesome/url.html'),
+ QtCore.QUrl('http://abc123.com/this/awesome/url.html'),
usertypes.LoadStatus.success,
url.UrlType.success
),
(
- QUrl('https://supersecret.gov/nsa/files.txt'),
+ QtCore.QUrl('https://supersecret.gov/nsa/files.txt'),
usertypes.LoadStatus.success_https,
url.UrlType.success_https
),
(
- QUrl('http://www.qutebrowser.org/CONTRIBUTING.html'),
+ QtCore.QUrl('http://www.qutebrowser.org/CONTRIBUTING.html'),
usertypes.LoadStatus.loading,
url.UrlType.normal
),
(
- QUrl('www.whatisthisurl.com'),
+ QtCore.QUrl('www.whatisthisurl.com'),
usertypes.LoadStatus.warn,
url.UrlType.warn
),
diff --git a/tests/unit/mainwindow/test_messageview.py b/tests/unit/mainwindow/test_messageview.py
index 9e7627635..f4a4def60 100644
--- a/tests/unit/mainwindow/test_messageview.py
+++ b/tests/unit/mainwindow/test_messageview.py
@@ -18,7 +18,7 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
import pytest
-from PyQt5.QtCore import Qt
+from qutebrowser.qt import QtCore
from qutebrowser.mainwindow import messageview
from qutebrowser.utils import usertypes
@@ -155,10 +155,10 @@ def test_replacing_geometry(qtbot, view):
@pytest.mark.parametrize('button, count', [
- (Qt.LeftButton, 0),
- (Qt.MiddleButton, 0),
- (Qt.RightButton, 0),
- (Qt.BackButton, 2),
+ (QtCore.Qt.LeftButton, 0),
+ (QtCore.Qt.MiddleButton, 0),
+ (QtCore.Qt.RightButton, 0),
+ (QtCore.Qt.BackButton, 2),
])
def test_click_messages(qtbot, view, button, count):
"""Messages should disappear when we click on them."""
diff --git a/tests/unit/mainwindow/test_prompt.py b/tests/unit/mainwindow/test_prompt.py
index 3218959a5..223943148 100644
--- a/tests/unit/mainwindow/test_prompt.py
+++ b/tests/unit/mainwindow/test_prompt.py
@@ -20,7 +20,7 @@
import os
import pytest
-from PyQt5.QtCore import Qt
+from qutebrowser.qt import QtCore
from qutebrowser.mainwindow import prompt as promptmod
from qutebrowser.utils import usertypes
@@ -79,7 +79,7 @@ class TestFileCompletion:
# Deleting /f[oo/]
with qtbot.wait_signal(prompt._file_model.directoryLoaded):
for _ in range(3):
- qtbot.keyPress(prompt._lineedit, Qt.Key_Backspace)
+ qtbot.keyPress(prompt._lineedit, QtCore.Qt.Key_Backspace)
# For some reason, this isn't always called when using qtbot.keyPress.
prompt._set_fileview_root(prompt._lineedit.text())
@@ -90,7 +90,7 @@ class TestFileCompletion:
# Deleting /[foo]
for _ in range(3):
- qtbot.keyPress(prompt._lineedit, Qt.Key_Backspace)
+ qtbot.keyPress(prompt._lineedit, QtCore.Qt.Key_Backspace)
# We should now show / again, so tabbing twice gives us bar -> foo
prompt.item_focus('next')
@@ -99,8 +99,8 @@ class TestFileCompletion:
@pytest.mark.parametrize("keys, expected", [
([], ['bar', 'bat', 'foo']),
- ([Qt.Key_F], ['foo']),
- ([Qt.Key_A], ['bar', 'bat']),
+ ([QtCore.Qt.Key_F], ['foo']),
+ ([QtCore.Qt.Key_A], ['bar', 'bat']),
])
def test_filtering_path(self, qtbot, tmp_path, get_prompt, keys, expected):
testdir = tmp_path / 'test'
diff --git a/tests/unit/mainwindow/test_tabwidget.py b/tests/unit/mainwindow/test_tabwidget.py
index 564ca1b38..22efc525b 100644
--- a/tests/unit/mainwindow/test_tabwidget.py
+++ b/tests/unit/mainwindow/test_tabwidget.py
@@ -23,10 +23,10 @@
import functools
import pytest
-from PyQt5.QtGui import QIcon, QPixmap
from qutebrowser.mainwindow import tabwidget
from qutebrowser.utils import usertypes
+from qutebrowser.qt import QtGui
class TestTabWidget:
@@ -48,8 +48,8 @@ class TestTabWidget:
Regression test for #1015.
"""
# Size taken from issue report
- pixmap = QPixmap(72, 1)
- icon = QIcon(pixmap)
+ pixmap = QtGui.QPixmap(72, 1)
+ icon = QtGui.QIcon(pixmap)
tab = fake_web_tab()
widget.addTab(tab, icon, 'foobar')
diff --git a/tests/unit/misc/test_autoupdate.py b/tests/unit/misc/test_autoupdate.py
index f7cf78248..1457d5034 100644
--- a/tests/unit/misc/test_autoupdate.py
+++ b/tests/unit/misc/test_autoupdate.py
@@ -21,7 +21,7 @@
"""Tests for qutebrowser.misc.autoupdate."""
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.misc import autoupdate, httpclient
@@ -68,7 +68,7 @@ def test_get_version_success(qtbot):
with qtbot.wait_signal(client.success):
client.get_version('test')
- assert http_stub.url == QUrl(client.API_URL.format('test'))
+ assert http_stub.url == QtCore.QUrl(client.API_URL.format('test'))
def test_get_version_error(qtbot):
diff --git a/tests/unit/misc/test_editor.py b/tests/unit/misc/test_editor.py
index 91bdce26b..ded4c5a8f 100644
--- a/tests/unit/misc/test_editor.py
+++ b/tests/unit/misc/test_editor.py
@@ -26,7 +26,7 @@ import os
import logging
import pytest
-from PyQt5.QtCore import QProcess
+from qutebrowser.qt import QtCore
from qutebrowser.misc import editor as editormod
from qutebrowser.utils import usertypes
@@ -81,7 +81,7 @@ class TestFileHandling:
filename = pathlib.Path(editor._filename)
assert filename.exists()
assert filename.name.startswith('qutebrowser-editor-')
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QtCore.QProcess.NormalExit)
assert filename.exists() != config_stub.val.editor.remove_file
@pytest.mark.parametrize('touch', [True, False])
@@ -92,7 +92,7 @@ class TestFileHandling:
path.touch()
editor.edit_file(str(path))
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QtCore.QProcess.NormalExit)
assert path.exists()
@@ -103,7 +103,7 @@ class TestFileHandling:
assert filename.exists()
with caplog.at_level(logging.ERROR):
- editor._proc._proc.finished.emit(1, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(1, QtCore.QProcess.NormalExit)
assert filename.exists()
@@ -115,9 +115,9 @@ class TestFileHandling:
filename = pathlib.Path(editor._filename)
assert filename.exists()
- editor._proc.error.emit(QProcess.Crashed)
+ editor._proc.error.emit(QtCore.QProcess.Crashed)
with caplog.at_level(logging.ERROR):
- editor._proc._proc.finished.emit(0, QProcess.CrashExit)
+ editor._proc._proc.finished.emit(0, QtCore.QProcess.CrashExit)
assert filename.exists()
filename.unlink()
@@ -133,7 +133,7 @@ class TestFileHandling:
pytest.skip("File was still readable")
with caplog.at_level(logging.ERROR):
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QtCore.QProcess.NormalExit)
assert not filename.exists()
msg = message_mock.getmsg(usertypes.MessageLevel.error)
assert msg.text.startswith("Failed to read back edited file: ")
@@ -181,7 +181,7 @@ class TestFileHandling:
fname = msg.text[len(prefix):]
with qtbot.wait_signal(editor.editing_finished):
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QtCore.QProcess.NormalExit)
with open(fname, 'r', encoding='utf-8') as f:
assert f.read() == 'bar'
@@ -224,7 +224,7 @@ def test_modify(qtbot, editor, initial_text, edited_text):
f.write(edited_text)
with qtbot.wait_signal(editor.file_updated) as blocker:
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QtCore.QProcess.NormalExit)
assert blocker.args == [edited_text]
@@ -258,7 +258,7 @@ def test_modify_watch(qtbot):
assert blocker.args == ['baz']
with qtbot.assert_not_emitted(editor.file_updated):
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QtCore.QProcess.NormalExit)
def test_failing_watch(qtbot, caplog, monkeypatch):
@@ -276,7 +276,7 @@ def test_failing_watch(qtbot, caplog, monkeypatch):
_update_file(editor._filename, 'bar')
with qtbot.wait_signal(editor.file_updated) as blocker:
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QtCore.QProcess.NormalExit)
assert blocker.args == ['bar']
message = 'Failed to watch path: {}'.format(editor._filename)
@@ -293,7 +293,7 @@ def test_failing_unwatch(qtbot, caplog, monkeypatch):
editor.edit('foo')
with caplog.at_level(logging.ERROR):
- editor._proc._proc.finished.emit(0, QProcess.NormalExit)
+ editor._proc._proc.finished.emit(0, QtCore.QProcess.NormalExit)
message = 'Failed to unwatch paths: [{!r}]'.format(editor._filename)
assert caplog.messages[-1] == message
diff --git a/tests/unit/misc/test_guiprocess.py b/tests/unit/misc/test_guiprocess.py
index aaff5154e..3157287e0 100644
--- a/tests/unit/misc/test_guiprocess.py
+++ b/tests/unit/misc/test_guiprocess.py
@@ -23,12 +23,11 @@ import sys
import logging
import pytest
-from PyQt5.QtCore import QProcess, QUrl
from qutebrowser.misc import guiprocess
from qutebrowser.utils import usertypes, utils, version
from qutebrowser.api import cmdutils
-from qutebrowser.qt import sip
+from qutebrowser.qt import QtCore, sip
@pytest.fixture
@@ -36,7 +35,7 @@ def proc(qtbot, caplog):
"""A fixture providing a GUIProcess and cleaning it up after the test."""
p = guiprocess.GUIProcess('testprocess')
yield p
- if not sip.isdeleted(p._proc) and p._proc.state() != QProcess.NotRunning:
+ if not sip.isdeleted(p._proc) and p._proc.state() != QtCore.QProcess.NotRunning:
with caplog.at_level(logging.ERROR):
with qtbot.wait_signal(p.finished, timeout=10000,
raising=False) as blocker:
@@ -70,14 +69,14 @@ class TestProcessCommand:
monkeypatch.setitem(guiprocess.all_processes, 1234, fake_proc)
guiprocess.process(tab)
- assert tab.url() == QUrl('qute://process/1234')
+ assert tab.url() == QtCore.QUrl('qute://process/1234')
def test_explicit_pid(self, tab, monkeypatch, fake_proc):
monkeypatch.setattr(guiprocess, 'last_pid', 1234)
monkeypatch.setitem(guiprocess.all_processes, 5678, fake_proc)
guiprocess.process(tab, 5678)
- assert tab.url() == QUrl('qute://process/5678')
+ assert tab.url() == QtCore.QUrl('qute://process/5678')
def test_inexistent_pid(self, tab):
with pytest.raises(
@@ -126,7 +125,7 @@ def test_start(proc, qtbot, message_mock, py_proc):
assert not message_mock.messages
assert not proc.outcome.running
- assert proc.outcome.status == QProcess.NormalExit
+ assert proc.outcome.status == QtCore.QProcess.NormalExit
assert proc.outcome.code == 0
assert str(proc.outcome) == 'Testprocess exited successfully.'
assert proc.outcome.state_str() == 'successful'
@@ -434,7 +433,7 @@ def test_exit_unsuccessful(qtbot, proc, message_mock, py_proc, caplog):
assert msg.text == expected
assert not proc.outcome.running
- assert proc.outcome.status == QProcess.NormalExit
+ assert proc.outcome.status == QtCore.QProcess.NormalExit
assert proc.outcome.code == 1
assert str(proc.outcome) == 'Testprocess exited with status 1.'
assert proc.outcome.state_str() == 'unsuccessful'
@@ -454,7 +453,7 @@ def test_exit_crash(qtbot, proc, message_mock, py_proc, caplog):
assert msg.text == "Testprocess crashed. See :process for details."
assert not proc.outcome.running
- assert proc.outcome.status == QProcess.CrashExit
+ assert proc.outcome.status == QtCore.QProcess.CrashExit
assert str(proc.outcome) == 'Testprocess crashed.'
assert proc.outcome.state_str() == 'crashed'
assert not proc.outcome.was_successful()
diff --git a/tests/unit/misc/test_ipc.py b/tests/unit/misc/test_ipc.py
index 51d7c6343..2c720ceed 100644
--- a/tests/unit/misc/test_ipc.py
+++ b/tests/unit/misc/test_ipc.py
@@ -30,14 +30,13 @@ from unittest import mock
from typing import Optional, List
import pytest
-from PyQt5.QtCore import pyqtSignal, QObject
-from PyQt5.QtNetwork import QLocalServer, QLocalSocket, QAbstractSocket
from PyQt5.QtTest import QSignalSpy
import qutebrowser
from qutebrowser.misc import ipc
from qutebrowser.utils import standarddir, utils, version
from helpers import stubs, testutils
+from qutebrowser.qt import QtNetwork, QtCore
pytestmark = pytest.mark.usefixtures('qapp')
@@ -56,7 +55,7 @@ def ipc_server(qapp, qtbot):
server = ipc.IPCServer('qute-test')
yield server
if (server._socket is not None and
- server._socket.state() != QLocalSocket.UnconnectedState):
+ server._socket.state() != QtNetwork.QLocalSocket.UnconnectedState):
with qtbot.wait_signal(server._socket.disconnected, raising=False):
server._socket.abort()
try:
@@ -67,7 +66,7 @@ def ipc_server(qapp, qtbot):
@pytest.fixture
def qlocalserver(qapp):
- server = QLocalServer()
+ server = QtNetwork.QLocalServer()
yield server
server.close()
server.deleteLater()
@@ -75,10 +74,10 @@ def qlocalserver(qapp):
@pytest.fixture
def qlocalsocket(qapp):
- socket = QLocalSocket()
+ socket = QtNetwork.QLocalSocket()
yield socket
socket.disconnectFromServer()
- if socket.state() != QLocalSocket.UnconnectedState:
+ if socket.state() != QtNetwork.QLocalSocket.UnconnectedState:
socket.waitForDisconnected(1000)
@@ -89,7 +88,7 @@ def fake_runtime_dir(monkeypatch, short_tmpdir):
return short_tmpdir
-class FakeSocket(QObject):
+class FakeSocket(QtCore.QObject):
"""A stub for a QLocalSocket.
@@ -100,10 +99,10 @@ class FakeSocket(QObject):
_connect_successful: The value returned for waitForConnected().
"""
- readyRead = pyqtSignal() # noqa: N815
- disconnected = pyqtSignal()
+ readyRead = QtCore.pyqtSignal() # noqa: N815
+ disconnected = QtCore.pyqtSignal()
- def __init__(self, *, error=QLocalSocket.UnknownSocketError, state=None,
+ def __init__(self, *, error=QtNetwork.QLocalSocket.UnknownSocketError, state=None,
data=None, connect_successful=True, parent=None):
super().__init__(parent)
self._error_val = error
@@ -280,9 +279,9 @@ class TestExceptions:
raise exc
def test_socket_error(self, qlocalserver):
- socket = FakeSocket(error=QLocalSocket.ConnectionRefusedError)
+ socket = FakeSocket(error=QtNetwork.QLocalSocket.ConnectionRefusedError)
exc = ipc.SocketError("testing", socket)
- assert exc.code == QLocalSocket.ConnectionRefusedError
+ assert exc.code == QtNetwork.QLocalSocket.ConnectionRefusedError
assert exc.message == "Error string"
assert str(exc) == "Error while testing: Error string (error 0)"
@@ -322,7 +321,7 @@ class TestListen:
@pytest.mark.windows
def test_permissions_windows(self, ipc_server):
opts = ipc_server._server.socketOptions()
- assert opts == QLocalServer.UserAccessOption
+ assert opts == QtNetwork.QLocalServer.UserAccessOption
@pytest.mark.posix
def test_permissions_posix(self, ipc_server):
@@ -403,24 +402,24 @@ class TestListen:
class TestOnError:
def test_closed(self, ipc_server):
- ipc_server._socket = QLocalSocket()
+ ipc_server._socket = QtNetwork.QLocalSocket()
ipc_server._timer.timeout.disconnect()
ipc_server._timer.start()
- ipc_server.on_error(QLocalSocket.PeerClosedError)
+ ipc_server.on_error(QtNetwork.QLocalSocket.PeerClosedError)
assert not ipc_server._timer.isActive()
def test_other_error(self, ipc_server, monkeypatch):
- socket = QLocalSocket()
+ socket = QtNetwork.QLocalSocket()
ipc_server._socket = socket
monkeypatch.setattr(socket, 'error',
- lambda: QLocalSocket.ConnectionRefusedError)
+ lambda: QtNetwork.QLocalSocket.ConnectionRefusedError)
monkeypatch.setattr(socket, 'errorString',
lambda: "Connection refused")
socket.setErrorString("Connection refused.")
with pytest.raises(ipc.Error, match=r"Error while handling IPC "
r"connection: Connection refused \(error 0\)"):
- ipc_server.on_error(QLocalSocket.ConnectionRefusedError)
+ ipc_server.on_error(QtNetwork.QLocalSocket.ConnectionRefusedError)
class TestHandleConnection:
@@ -444,13 +443,13 @@ class TestHandleConnection:
assert any(message.startswith(msg) for message in caplog.messages)
def test_disconnected_immediately(self, ipc_server, caplog):
- socket = FakeSocket(state=QLocalSocket.UnconnectedState)
+ socket = FakeSocket(state=QtNetwork.QLocalSocket.UnconnectedState)
ipc_server._server = FakeServer(socket)
ipc_server.handle_connection()
assert "Socket was disconnected immediately." in caplog.messages
def test_error_immediately(self, ipc_server, caplog):
- socket = FakeSocket(error=QLocalSocket.ConnectionError)
+ socket = FakeSocket(error=QtNetwork.QLocalSocket.ConnectionError)
ipc_server._server = FakeServer(socket)
with pytest.raises(ipc.Error, match=r"Error while handling IPC "
@@ -588,7 +587,7 @@ class TestSendToRunningInstance:
assert parsed == raw_expected
def test_socket_error(self):
- socket = FakeSocket(error=QLocalSocket.ConnectionError)
+ socket = FakeSocket(error=QtNetwork.QLocalSocket.ConnectionError)
with pytest.raises(ipc.Error, match=r"Error while writing to running "
r"instance: Error string \(error 7\)"):
ipc.send_to_running_instance('qute-test', [], None, socket=socket)
@@ -598,7 +597,7 @@ class TestSendToRunningInstance:
ipc.send_to_running_instance('qute-test', [], None, socket=socket)
def test_socket_error_no_server(self):
- socket = FakeSocket(error=QLocalSocket.ConnectionError,
+ socket = FakeSocket(error=QtNetwork.QLocalSocket.ConnectionError,
connect_successful=False)
with pytest.raises(ipc.Error, match=r"Error while connecting to "
r"running instance: Error string \(error 7\)"):
@@ -667,7 +666,7 @@ class TestSendOrListen:
for name in ['UnknownSocketError', 'UnconnectedState',
'ConnectionRefusedError', 'ServerNotFoundError',
'PeerClosedError']:
- setattr(m, name, getattr(QLocalSocket, name))
+ setattr(m, name, getattr(QtNetwork.QLocalSocket, name))
return m
@pytest.mark.linux(reason="Flaky on Windows and macOS")
@@ -701,14 +700,14 @@ class TestSendOrListen:
-> success
"""
qlocalserver_mock().listen.return_value = False
- err = QAbstractSocket.AddressInUseError
+ err = QtNetwork.QAbstractSocket.AddressInUseError
qlocalserver_mock().serverError.return_value = err
qlocalsocket_mock().waitForConnected.side_effect = [False, True]
qlocalsocket_mock().error.side_effect = [
- QLocalSocket.ServerNotFoundError,
- QLocalSocket.UnknownSocketError,
- QLocalSocket.UnknownSocketError, # error() gets called twice
+ QtNetwork.QLocalSocket.ServerNotFoundError,
+ QtNetwork.QLocalSocket.UnknownSocketError,
+ QtNetwork.QLocalSocket.UnknownSocketError, # error() gets called twice
]
ret = ipc.send_or_listen(args)
@@ -734,17 +733,17 @@ class TestSendOrListen:
-> not sent / error
"""
qlocalserver_mock().listen.return_value = False
- err = QAbstractSocket.AddressInUseError
+ err = QtNetwork.QAbstractSocket.AddressInUseError
qlocalserver_mock().serverError.return_value = err
# If the second connection succeeds, we will have an error later.
# If it fails, that's the "not sent" case above.
qlocalsocket_mock().waitForConnected.side_effect = [False, has_error]
qlocalsocket_mock().error.side_effect = [
- QLocalSocket.ServerNotFoundError,
- QLocalSocket.ServerNotFoundError,
- QLocalSocket.ConnectionRefusedError,
- QLocalSocket.ConnectionRefusedError, # error() gets called twice
+ QtNetwork.QLocalSocket.ServerNotFoundError,
+ QtNetwork.QLocalSocket.ServerNotFoundError,
+ QtNetwork.QLocalSocket.ConnectionRefusedError,
+ QtNetwork.QLocalSocket.ConnectionRefusedError, # error() gets called twice
]
with caplog.at_level(logging.ERROR):
@@ -766,7 +765,7 @@ class TestSendOrListen:
def test_error_while_listening(self, qlocalserver_mock, caplog, args):
"""Test an error with the first listen call."""
qlocalserver_mock().listen.return_value = False
- err = QAbstractSocket.SocketResourceError
+ err = QtNetwork.QAbstractSocket.SocketResourceError
qlocalserver_mock().serverError.return_value = err
with caplog.at_level(logging.ERROR):
@@ -809,7 +808,7 @@ def test_connect_inexistent(qlocalsocket):
would not work properly.
"""
qlocalsocket.connectToServer('qute-test-inexistent')
- assert qlocalsocket.error() == QLocalSocket.ServerNotFoundError
+ assert qlocalsocket.error() == QtNetwork.QLocalSocket.ServerNotFoundError
@pytest.mark.posix
@@ -821,12 +820,12 @@ def test_socket_options_address_in_use_problem(qlocalserver, short_tmpdir):
"""
servername = str(short_tmpdir / 'x')
- s1 = QLocalServer()
+ s1 = QtNetwork.QLocalServer()
ok = s1.listen(servername)
assert ok
- s2 = QLocalServer()
- s2.setSocketOptions(QLocalServer.UserAccessOption)
+ s2 = QtNetwork.QLocalServer()
+ s2.setSocketOptions(QtNetwork.QLocalServer.UserAccessOption)
ok = s2.listen(servername)
print(s2.errorString())
# We actually would expect ok == False here - but we want the test to fail
diff --git a/tests/unit/misc/test_miscwidgets.py b/tests/unit/misc/test_miscwidgets.py
index 3c5c1eef1..cd2cd64ed 100644
--- a/tests/unit/misc/test_miscwidgets.py
+++ b/tests/unit/misc/test_miscwidgets.py
@@ -18,13 +18,12 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
import logging
-
-from PyQt5.QtCore import Qt, QSize
-from PyQt5.QtWidgets import QWidget
+from qutebrowser.qt import QtWidgets
import pytest
from qutebrowser.misc import miscwidgets
from qutebrowser.browser import inspector
+from qutebrowser.qt import QtCore
class TestCommandLineEdit:
@@ -48,9 +47,9 @@ class TestCommandLineEdit:
cmd_edit.home(True)
assert cmd_edit.cursorPosition() == len(':')
- qtbot.keyClick(cmd_edit, Qt.Key_Delete)
+ qtbot.keyClick(cmd_edit, QtCore.Qt.Key_Delete)
assert cmd_edit.text() == ':'
- qtbot.keyClick(cmd_edit, Qt.Key_Backspace)
+ qtbot.keyClick(cmd_edit, QtCore.Qt.Key_Backspace)
assert cmd_edit.text() == ':'
qtbot.keyClicks(cmd_edit, 'hey again')
@@ -76,15 +75,15 @@ class TestCommandLineEdit:
assert cmd_edit.text() == ':hello'
assert cmd_edit.cursorPosition() == len(':hello')
for _ in ':hello':
- qtbot.keyClick(cmd_edit, Qt.Key_Left, modifier=Qt.ShiftModifier)
+ qtbot.keyClick(cmd_edit, QtCore.Qt.Key_Left, modifier=QtCore.Qt.ShiftModifier)
assert cmd_edit.cursorPosition() == len(':')
assert cmd_edit.selectionStart() == len(':')
-class WrappedWidget(QWidget):
+class WrappedWidget(QtWidgets.QWidget):
def sizeHint(self):
- return QSize(23, 42)
+ return QtCore.QSize(23, 42)
class TestWrapperLayout:
@@ -92,7 +91,7 @@ class TestWrapperLayout:
@pytest.fixture
def container(self, qtbot):
wrapped = WrappedWidget()
- parent = QWidget()
+ parent = QtWidgets.QWidget()
qtbot.add_widget(wrapped)
qtbot.add_widget(parent)
layout = miscwidgets.WrapperLayout(parent)
@@ -101,7 +100,7 @@ class TestWrapperLayout:
return parent
def test_size_hint(self, container):
- assert container.sizeHint() == QSize(23, 42)
+ assert container.sizeHint() == QtCore.QSize(23, 42)
def test_wrapped(self, container):
assert container.wrapped.parent() is container
@@ -165,10 +164,10 @@ class TestInspectorSplitter:
@pytest.mark.parametrize(
'position, orientation, inspector_idx, webview_idx', [
- (inspector.Position.left, Qt.Horizontal, 0, 1),
- (inspector.Position.right, Qt.Horizontal, 1, 0),
- (inspector.Position.top, Qt.Vertical, 0, 1),
- (inspector.Position.bottom, Qt.Vertical, 1, 0),
+ (inspector.Position.left, QtCore.Qt.Horizontal, 0, 1),
+ (inspector.Position.right, QtCore.Qt.Horizontal, 1, 0),
+ (inspector.Position.top, QtCore.Qt.Vertical, 0, 1),
+ (inspector.Position.bottom, QtCore.Qt.Vertical, 1, 0),
]
)
def test_set_inspector(self, position, orientation,
@@ -212,7 +211,7 @@ class TestInspectorSplitter:
state_config['inspector'] = {position.name: config}
splitter.resize(width, height)
- assert splitter.size() == QSize(width, height)
+ assert splitter.size() == QtCore.QSize(width, height)
with caplog.at_level(logging.ERROR):
splitter.set_inspector(fake_inspector, position)
@@ -260,8 +259,8 @@ class TestInspectorSplitter:
new_window_size, exp_inspector_size,
position, splitter, fake_inspector, qtbot):
def resize(dim):
- size = (QSize(dim, 666) if splitter.orientation() == Qt.Horizontal
- else QSize(666, dim))
+ size = (QtCore.QSize(dim, 666) if splitter.orientation() == QtCore.Qt.Horizontal
+ else QtCore.QSize(666, dim))
splitter.resize(size)
if splitter.size() != size:
pytest.skip("Resizing window failed")
diff --git a/tests/unit/misc/test_msgbox.py b/tests/unit/misc/test_msgbox.py
index c5c23639a..8544ac6ff 100644
--- a/tests/unit/misc/test_msgbox.py
+++ b/tests/unit/misc/test_msgbox.py
@@ -20,8 +20,7 @@
import pytest
-from PyQt5.QtCore import Qt
-from PyQt5.QtWidgets import QMessageBox, QWidget
+from qutebrowser.qt import QtWidgets, QtCore
from qutebrowser.misc import msgbox
from qutebrowser.utils import utils
@@ -36,10 +35,10 @@ def test_attributes(qtbot):
"""Test basic QMessageBox attributes."""
title = 'title'
text = 'text'
- parent = QWidget()
+ parent = QtWidgets.QWidget()
qtbot.add_widget(parent)
- icon = QMessageBox.Critical
- buttons = QMessageBox.Ok | QMessageBox.Cancel
+ icon = QtWidgets.QMessageBox.Critical
+ buttons = QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel
box = msgbox.msgbox(parent=parent, title=title, text=text, icon=icon,
buttons=buttons)
@@ -53,13 +52,13 @@ def test_attributes(qtbot):
@pytest.mark.parametrize('plain_text, expected', [
- (True, Qt.PlainText),
- (False, Qt.RichText),
- (None, Qt.AutoText),
+ (True, QtCore.Qt.PlainText),
+ (False, QtCore.Qt.RichText),
+ (None, QtCore.Qt.AutoText),
])
def test_plain_text(qtbot, plain_text, expected):
box = msgbox.msgbox(parent=None, title='foo', text='foo',
- icon=QMessageBox.Information, plain_text=plain_text)
+ icon=QtWidgets.QMessageBox.Information, plain_text=plain_text)
qtbot.add_widget(box)
assert box.textFormat() == expected
@@ -73,7 +72,7 @@ def test_finished_signal(qtbot):
signal_triggered = True
box = msgbox.msgbox(parent=None, title='foo', text='foo',
- icon=QMessageBox.Information, on_finished=on_finished)
+ icon=QtWidgets.QMessageBox.Information, on_finished=on_finished)
qtbot.add_widget(box)
@@ -89,7 +88,7 @@ def test_information(qtbot):
if not utils.is_mac:
assert box.windowTitle() == 'foo'
assert box.text() == 'bar'
- assert box.icon() == QMessageBox.Information
+ assert box.icon() == QtWidgets.QMessageBox.Information
def test_no_err_windows(fake_args, caplog):
diff --git a/tests/unit/misc/test_pastebin.py b/tests/unit/misc/test_pastebin.py
index 7a47e723c..1c72a1d3d 100644
--- a/tests/unit/misc/test_pastebin.py
+++ b/tests/unit/misc/test_pastebin.py
@@ -19,7 +19,7 @@
# along with qutebrowser. If not, see <https://www.gnu.org/licenses/>.
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.misc import httpclient, pastebin
@@ -56,7 +56,7 @@ def test_paste_with_parent(data, pbclient):
http_stub = pbclient._client
pbclient.paste(data["name"], data["title"], data["text"], data["reply"])
assert http_stub.data == data
- assert http_stub.url == QUrl('https://crashes.qutebrowser.org/api/create')
+ assert http_stub.url == QtCore.QUrl('https://crashes.qutebrowser.org/api/create')
@pytest.mark.parametrize('data', [
@@ -77,7 +77,7 @@ def test_paste_without_parent(data, pbclient):
http_stub = pbclient._client
pbclient.paste(data["name"], data["title"], data["text"])
assert pbclient._client.data == data
- assert http_stub.url == QUrl('https://crashes.qutebrowser.org/api/create')
+ assert http_stub.url == QtCore.QUrl('https://crashes.qutebrowser.org/api/create')
def test_paste_private(pbclient):
@@ -91,7 +91,7 @@ def test_paste_private(pbclient):
http_stub = pbclient._client
pbclient.paste(data["name"], data["title"], data["text"], private=True)
assert pbclient._client.data == data
- assert http_stub.url == QUrl('https://crashes.qutebrowser.org/api/create')
+ assert http_stub.url == QtCore.QUrl('https://crashes.qutebrowser.org/api/create')
@pytest.mark.parametrize('http', [
diff --git a/tests/unit/misc/test_sessions.py b/tests/unit/misc/test_sessions.py
index f77982e5f..ddbb0703a 100644
--- a/tests/unit/misc/test_sessions.py
+++ b/tests/unit/misc/test_sessions.py
@@ -23,13 +23,13 @@ import logging
import pytest
import yaml
-from PyQt5.QtCore import QUrl, QPoint, QByteArray, QObject
QWebView = pytest.importorskip('PyQt5.QtWebKitWidgets').QWebView
from qutebrowser.misc import sessions
from qutebrowser.misc.sessions import TabHistoryItem as Item
from qutebrowser.utils import objreg, qtutils
from qutebrowser.browser.webkit import tabhistory
+from qutebrowser.qt import QtCore
pytestmark = pytest.mark.qt_log_ignore('QIODevice::read.*: device not open')
@@ -123,7 +123,7 @@ class TestSaveTab:
assert not data['history']
-class FakeMainWindow(QObject):
+class FakeMainWindow(QtCore.QObject):
"""Helper class for the fake_main_window fixture.
@@ -134,7 +134,7 @@ class FakeMainWindow(QObject):
def __init__(self, geometry, win_id, parent=None):
super().__init__(parent)
- self._geometry = QByteArray(geometry)
+ self._geometry = QtCore.QByteArray(geometry)
self.win_id = win_id
def saveGeometry(self):
@@ -245,7 +245,7 @@ class TestSave:
def test_utf_8_invalid(self, tmp_path, sess_man, fake_history):
"""Make sure data containing invalid UTF8 raises SessionError."""
session_path = tmp_path / 'foo.yml'
- fake_history([Item(QUrl('http://www.qutebrowser.org/'), '\ud800',
+ fake_history([Item(QtCore.QUrl('http://www.qutebrowser.org/'), '\ud800',
active=True)])
try:
@@ -308,7 +308,7 @@ class TestLoadTab:
@pytest.mark.parametrize('key, val, expected', [
('zoom', 1.23, 1.23),
- ('scroll-pos', {'x': 23, 'y': 42}, QPoint(23, 42)),
+ ('scroll-pos', {'x': 23, 'y': 42}, QtCore.QPoint(23, 42)),
])
@pytest.mark.parametrize('in_main_data', [True, False])
def test_user_data(self, sess_man, fake_webview, key, val, expected,
@@ -335,17 +335,17 @@ class TestLoadTab:
item = {'url': url, 'title': 'foo'}
if original_url is None:
- expected = QUrl(url)
+ expected = QtCore.QUrl(url)
else:
item['original-url'] = original_url
- expected = QUrl(original_url)
+ expected = QtCore.QUrl(original_url)
d = {'history': [item]}
sess_man._load_tab(fake_webview, d)
assert len(fake_webview.loaded_history) == 1
loaded_item = fake_webview.loaded_history[0]
- assert loaded_item.url == QUrl(url)
+ assert loaded_item.url == QtCore.QUrl(url)
assert loaded_item.original_url == expected
diff --git a/tests/unit/misc/test_sql.py b/tests/unit/misc/test_sql.py
index 80ab7513c..3ea32dab9 100644
--- a/tests/unit/misc/test_sql.py
+++ b/tests/unit/misc/test_sql.py
@@ -23,9 +23,9 @@ import pytest
import hypothesis
from hypothesis import strategies
-from PyQt5.QtSql import QSqlDatabase, QSqlError, QSqlQuery
from qutebrowser.misc import sql
+from qutebrowser.qt import QtSql
pytestmark = pytest.mark.usefixtures('data_tmpdir')
@@ -95,13 +95,13 @@ class TestSqlError:
(sql.SqliteErrorCode.CONSTRAINT, sql.BugError),
])
def test_known(self, error_code, exception):
- sql_err = QSqlError("driver text", "db text", QSqlError.UnknownError,
+ sql_err = QtSql.QSqlError("driver text", "db text", QtSql.QSqlError.UnknownError,
error_code)
with pytest.raises(exception):
sql.raise_sqlite_error("Message", sql_err)
def test_logging(self, caplog):
- sql_err = QSqlError("driver text", "db text", QSqlError.UnknownError, '23')
+ sql_err = QtSql.QSqlError("driver text", "db text", QtSql.QSqlError.UnknownError, '23')
with pytest.raises(sql.BugError):
sql.raise_sqlite_error("Message", sql_err)
@@ -115,7 +115,7 @@ class TestSqlError:
@pytest.mark.parametrize('klass', [sql.KnownError, sql.BugError])
def test_text(self, klass):
- sql_err = QSqlError("driver text", "db text")
+ sql_err = QtSql.QSqlError("driver text", "db text")
err = klass("Message", sql_err)
assert err.text() == "db text"
@@ -391,10 +391,10 @@ class TestTransaction:
my_table.insert({'column': 1})
my_table.insert({'column': 2})
- db2 = QSqlDatabase.addDatabase('QSQLITE', 'db2')
+ db2 = QtSql.QSqlDatabase.addDatabase('QSQLITE', 'db2')
db2.setDatabaseName(database.qt_database().databaseName())
db2.open()
- query = QSqlQuery(db2)
+ query = QtSql.QSqlQuery(db2)
query.exec('select count(*) from my_table')
query.next()
assert query.record().value(0) == 0
diff --git a/tests/unit/misc/test_throttle.py b/tests/unit/misc/test_throttle.py
index 33e9949f2..675a48ec6 100644
--- a/tests/unit/misc/test_throttle.py
+++ b/tests/unit/misc/test_throttle.py
@@ -23,7 +23,7 @@ from unittest import mock
import sip
import pytest
-from PyQt5.QtCore import QObject
+from qutebrowser.qt import QtCore
from helpers import testutils
from qutebrowser.misc import throttle
@@ -145,7 +145,7 @@ def test_set(func, qtbot):
def test_deleted_object(qtbot):
- class Obj(QObject):
+ class Obj(QtCore.QObject):
def func(self):
self.setObjectName("test")
diff --git a/tests/unit/misc/test_utilcmds.py b/tests/unit/misc/test_utilcmds.py
index 76bc015d2..98d19c3b8 100644
--- a/tests/unit/misc/test_utilcmds.py
+++ b/tests/unit/misc/test_utilcmds.py
@@ -20,7 +20,7 @@
"""Tests for qutebrowser.misc.utilcmds."""
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.misc import utilcmds
from qutebrowser.api import cmdutils
@@ -76,4 +76,4 @@ def tabbed_browser(stubs, win_registry):
def test_version(tabbed_browser, qapp):
utilcmds.version(win_id=0)
- assert tabbed_browser.loaded_url == QUrl('qute://version/')
+ assert tabbed_browser.loaded_url == QtCore.QUrl('qute://version/')
diff --git a/tests/unit/test_app.py b/tests/unit/test_app.py
index e359f2136..96a938ce0 100644
--- a/tests/unit/test_app.py
+++ b/tests/unit/test_app.py
@@ -19,7 +19,7 @@
"""Tests for the qutebrowser.app module."""
-from PyQt5.QtCore import QBuffer
+from qutebrowser.qt import QtCore
from qutebrowser.misc import objects
from qutebrowser import app
@@ -33,7 +33,7 @@ def test_on_focus_changed_issue1484(monkeypatch, qapp, caplog):
"""
monkeypatch.setattr(objects, 'qapp', qapp)
- buf = QBuffer()
+ buf = QtCore.QBuffer()
app.on_focus_changed(buf, buf)
expected = "on_focus_changed called with non-QWidget {!r}".format(buf)
diff --git a/tests/unit/utils/test_debug.py b/tests/unit/utils/test_debug.py
index 62d0f4a7b..4a24d0c44 100644
--- a/tests/unit/utils/test_debug.py
+++ b/tests/unit/utils/test_debug.py
@@ -25,30 +25,29 @@ import time
import textwrap
import pytest
-from PyQt5.QtCore import pyqtSignal, Qt, QEvent, QObject, QTimer
-from PyQt5.QtWidgets import QStyle, QFrame, QSpinBox
from qutebrowser.utils import debug
from qutebrowser.misc import objects
+from qutebrowser.qt import QtWidgets, QtCore
@debug.log_events
-class EventObject(QObject):
+class EventObject(QtCore.QObject):
pass
def test_log_events(qapp, caplog):
obj = EventObject()
- qapp.sendEvent(obj, QEvent(QEvent.User))
+ qapp.sendEvent(obj, QtCore.QEvent(QtCore.QEvent.User))
qapp.processEvents()
assert caplog.messages == ['Event in test_debug.EventObject: User']
-class SignalObject(QObject):
+class SignalObject(QtCore.QObject):
- signal1 = pyqtSignal()
- signal2 = pyqtSignal(str, str)
+ signal1 = QtCore.pyqtSignal()
+ signal2 = QtCore.pyqtSignal(str, str)
def __repr__(self):
"""This is not a nice thing to do, but it makes our tests easier."""
@@ -129,28 +128,28 @@ class TestQEnumKey:
If Qt/PyQt even changes and our tests wouldn't test the full
functionality of qenum_key because of that, this test will tell us.
"""
- assert not hasattr(QStyle.PrimitiveElement, 'staticMetaObject')
- assert hasattr(QFrame, 'staticMetaObject')
+ assert not hasattr(QtWidgets.QStyle.PrimitiveElement, 'staticMetaObject')
+ assert hasattr(QtWidgets.QFrame, 'staticMetaObject')
@pytest.mark.parametrize('base, value, klass, expected', [
- (QStyle, QStyle.PE_PanelButtonCommand, None, 'PE_PanelButtonCommand'),
- (QFrame, QFrame.Sunken, None, 'Sunken'),
- (QFrame, 0x0030, QFrame.Shadow, 'Sunken'),
- (QFrame, 0x1337, QFrame.Shadow, '0x1337'),
- (Qt, Qt.AnchorLeft, None, 'AnchorLeft'),
+ (QtWidgets.QStyle, QtWidgets.QStyle.PE_PanelButtonCommand, None, 'PE_PanelButtonCommand'),
+ (QtWidgets.QFrame, QtWidgets.QFrame.Sunken, None, 'Sunken'),
+ (QtWidgets.QFrame, 0x0030, QtWidgets.QFrame.Shadow, 'Sunken'),
+ (QtWidgets.QFrame, 0x1337, QtWidgets.QFrame.Shadow, '0x1337'),
+ (QtCore.Qt, QtCore.Qt.AnchorLeft, None, 'AnchorLeft'),
])
def test_qenum_key(self, base, value, klass, expected):
key = debug.qenum_key(base, value, klass=klass)
assert key == expected
def test_add_base(self):
- key = debug.qenum_key(QFrame, QFrame.Sunken, add_base=True)
+ key = debug.qenum_key(QtWidgets.QFrame, QtWidgets.QFrame.Sunken, add_base=True)
assert key == 'QFrame.Sunken'
def test_int_noklass(self):
"""Test passing an int without explicit klass given."""
with pytest.raises(TypeError):
- debug.qenum_key(QFrame, 42)
+ debug.qenum_key(QtWidgets.QFrame, 42)
class TestQFlagsKey:
@@ -163,15 +162,15 @@ class TestQFlagsKey:
fixme = pytest.mark.xfail(reason="See issue #42", raises=AssertionError)
@pytest.mark.parametrize('base, value, klass, expected', [
- (Qt, Qt.AlignTop, None, 'AlignTop'),
- pytest.param(Qt, Qt.AlignLeft | Qt.AlignTop, None,
+ (QtCore.Qt, QtCore.Qt.AlignTop, None, 'AlignTop'),
+ pytest.param(QtCore.Qt, QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop, None,
'AlignLeft|AlignTop', marks=fixme),
- (Qt, Qt.AlignCenter, None, 'AlignHCenter|AlignVCenter'),
- pytest.param(Qt, 0x0021, Qt.Alignment, 'AlignLeft|AlignTop',
+ (QtCore.Qt, QtCore.Qt.AlignCenter, None, 'AlignHCenter|AlignVCenter'),
+ pytest.param(QtCore.Qt, 0x0021, QtCore.Qt.Alignment, 'AlignLeft|AlignTop',
marks=fixme),
- (Qt, 0x1100, Qt.Alignment, '0x0100|0x1000'),
- (Qt, Qt.DockWidgetAreas(0), Qt.DockWidgetArea, 'NoDockWidgetArea'),
- (Qt, Qt.DockWidgetAreas(0), None, '0x0000'),
+ (QtCore.Qt, 0x1100, QtCore.Qt.Alignment, '0x0100|0x1000'),
+ (QtCore.Qt, QtCore.Qt.DockWidgetAreas(0), QtCore.Qt.DockWidgetArea, 'NoDockWidgetArea'),
+ (QtCore.Qt, QtCore.Qt.DockWidgetAreas(0), None, '0x0000'),
])
def test_qflags_key(self, base, value, klass, expected):
flags = debug.qflags_key(base, value, klass=klass)
@@ -199,20 +198,20 @@ class TestQFlagsKey:
def test_add_base(self):
"""Test with add_base=True."""
- flags = debug.qflags_key(Qt, Qt.AlignTop, add_base=True)
+ flags = debug.qflags_key(QtCore.Qt, QtCore.Qt.AlignTop, add_base=True)
assert flags == 'Qt.AlignTop'
def test_int_noklass(self):
"""Test passing an int without explicit klass given."""
with pytest.raises(TypeError):
- debug.qflags_key(Qt, 42)
+ debug.qflags_key(QtCore.Qt, 42)
@pytest.mark.parametrize('cls, signal', [
(SignalObject, 'signal1'),
(SignalObject, 'signal2'),
- (QTimer, 'timeout'),
- (QSpinBox, 'valueChanged'), # Overloaded signal
+ (QtCore.QTimer, 'timeout'),
+ (QtWidgets.QSpinBox, 'valueChanged'), # Overloaded signal
])
@pytest.mark.parametrize('bound', [True, False])
def test_signal_name(cls, signal, bound):
@@ -259,7 +258,7 @@ def test_dbg_signal(stubs, args, expected):
class TestGetAllObjects:
- class Object(QObject):
+ class Object(QtCore.QObject):
def __init__(self, name, parent=None):
self._name = name
@@ -274,7 +273,7 @@ class TestGetAllObjects:
app = stubs.FakeQApplication(all_widgets=widgets)
monkeypatch.setattr(objects, 'qapp', app)
- root = QObject()
+ root = QtCore.QObject()
o1 = self.Object('Object 1', root)
o2 = self.Object('Object 2', o1) # noqa: F841
o3 = self.Object('Object 3', root) # noqa: F841
diff --git a/tests/unit/utils/test_error.py b/tests/unit/utils/test_error.py
index b59a7150b..5cc2017b0 100644
--- a/tests/unit/utils/test_error.py
+++ b/tests/unit/utils/test_error.py
@@ -21,8 +21,7 @@
import logging
import pytest
-from PyQt5.QtCore import QTimer
-from PyQt5.QtWidgets import QMessageBox
+from qutebrowser.qt import QtWidgets, QtCore
from qutebrowser.utils import error, utils
from qutebrowser.misc import ipc
@@ -82,13 +81,13 @@ def test_err_windows(qtbot, qapp, pre_text, post_text, expected, caplog):
qtbot.add_widget(w)
if not utils.is_mac:
assert w.windowTitle() == 'title'
- assert w.icon() == QMessageBox.Critical
- assert w.standardButtons() == QMessageBox.Ok
+ assert w.icon() == QtWidgets.QMessageBox.Critical
+ assert w.standardButtons() == QtWidgets.QMessageBox.Ok
assert w.text() == expected
finally:
w.close()
- QTimer.singleShot(10, err_window_check)
+ QtCore.QTimer.singleShot(10, err_window_check)
with caplog.at_level(logging.ERROR):
error.handle_fatal_exc(ValueError("exception"), 'title',
diff --git a/tests/unit/utils/test_jinja.py b/tests/unit/utils/test_jinja.py
index 85be8a6e3..1537ecd5c 100644
--- a/tests/unit/utils/test_jinja.py
+++ b/tests/unit/utils/test_jinja.py
@@ -24,7 +24,7 @@ import logging
import jinja2.exceptions
import pytest
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.utils import jinja
from qutebrowser.config import configexc
@@ -70,7 +70,7 @@ def test_resource_url():
"""Test resource_url() which can be used from templates."""
data = jinja.render('test2.html')
print(data)
- url = QUrl(data)
+ url = QtCore.QUrl(data)
assert url.isValid()
assert url.toDisplayString() == 'qute://resource/utils/testfile'
@@ -79,7 +79,7 @@ def test_data_url():
"""Test data_url() which can be used from templates."""
data = jinja.render('test3.html')
print(data)
- url = QUrl(data)
+ url = QtCore.QUrl(data)
assert url.isValid()
assert data == 'data:text/plain;base64,Zm9v' # 'foo'
diff --git a/tests/unit/utils/test_log.py b/tests/unit/utils/test_log.py
index bbc6b02db..5ebd633a8 100644
--- a/tests/unit/utils/test_log.py
+++ b/tests/unit/utils/test_log.py
@@ -34,6 +34,7 @@ from qutebrowser import qutebrowser
from qutebrowser.utils import log
from qutebrowser.misc import utilcmds
from qutebrowser.api import cmdutils
+from qutebrowser.qt import QtCore
@pytest.fixture(autouse=True)
diff --git a/tests/unit/utils/test_qtutils.py b/tests/unit/utils/test_qtutils.py
index ad9adf032..6b298831b 100644
--- a/tests/unit/utils/test_qtutils.py
+++ b/tests/unit/utils/test_qtutils.py
@@ -28,13 +28,12 @@ import unittest
import unittest.mock
import pytest
-from PyQt5.QtCore import (QDataStream, QPoint, QUrl, QByteArray, QIODevice,
- QTimer, QBuffer, QFile, QProcess, QFileDevice)
-from PyQt5.QtGui import QColor
+from qutebrowser.qt import QtGui
from qutebrowser.utils import qtutils, utils, usertypes
import overflow_test_cases
from helpers import testutils
+from qutebrowser.qt import QtCore
if utils.is_linux:
# Those are not run on macOS because that seems to cause a hang sometimes.
@@ -205,12 +204,12 @@ def test_ensure_valid(obj, raising, exc_reason, exc_str):
@pytest.mark.parametrize('status, raising, message', [
- (QDataStream.Ok, False, None),
- (QDataStream.ReadPastEnd, True, "The data stream has read past the end of "
+ (QtCore.QDataStream.Ok, False, None),
+ (QtCore.QDataStream.ReadPastEnd, True, "The data stream has read past the end of "
"the data in the underlying device."),
- (QDataStream.ReadCorruptData, True, "The data stream has read corrupt "
+ (QtCore.QDataStream.ReadCorruptData, True, "The data stream has read corrupt "
"data."),
- (QDataStream.WriteFailed, True, "The data stream cannot write to the "
+ (QtCore.QDataStream.WriteFailed, True, "The data stream cannot write to the "
"underlying device."),
])
def test_check_qdatastream(status, raising, message):
@@ -221,7 +220,7 @@ def test_check_qdatastream(status, raising, message):
raising: Whether check_qdatastream is expected to raise OSError.
message: The expected exception string.
"""
- stream = QDataStream()
+ stream = QtCore.QDataStream()
stream.setStatus(status)
if raising:
with pytest.raises(OSError, match=message):
@@ -232,15 +231,15 @@ def test_check_qdatastream(status, raising, message):
def test_qdatastream_status_count():
"""Make sure no new members are added to QDataStream.Status."""
- values = vars(QDataStream).values()
- status_vals = [e for e in values if isinstance(e, QDataStream.Status)]
+ values = vars(QtCore.QDataStream).values()
+ status_vals = [e for e in values if isinstance(e, QtCore.QDataStream.Status)]
assert len(status_vals) == 4
@pytest.mark.parametrize('color, expected', [
- (QColor('red'), 'rgba(255, 0, 0, 255)'),
- (QColor('blue'), 'rgba(0, 0, 255, 255)'),
- (QColor(1, 3, 5, 7), 'rgba(1, 3, 5, 7)'),
+ (QtGui.QColor('red'), 'rgba(255, 0, 0, 255)'),
+ (QtGui.QColor('blue'), 'rgba(0, 0, 255, 255)'),
+ (QtGui.QColor(1, 3, 5, 7), 'rgba(1, 3, 5, 7)'),
])
def test_qcolor_to_qsscolor(color, expected):
assert qtutils.qcolor_to_qsscolor(color) == expected
@@ -248,12 +247,12 @@ def test_qcolor_to_qsscolor(color, expected):
def test_qcolor_to_qsscolor_invalid():
with pytest.raises(qtutils.QtValueError):
- qtutils.qcolor_to_qsscolor(QColor())
+ qtutils.qcolor_to_qsscolor(QtGui.QColor())
@pytest.mark.parametrize('obj', [
- QPoint(23, 42),
- QUrl('http://www.qutebrowser.org/'),
+ QtCore.QPoint(23, 42),
+ QtCore.QUrl('http://www.qutebrowser.org/'),
])
def test_serialize(obj):
"""Test a serialize/deserialize round trip.
@@ -277,25 +276,25 @@ class TestSerializeStream:
@pytest.fixture
def stream_mock(self):
"""Fixture providing a QDataStream-like mock."""
- m = unittest.mock.MagicMock(spec=QDataStream)
- m.status.return_value = QDataStream.Ok
+ m = unittest.mock.MagicMock(spec=QtCore.QDataStream)
+ m.status.return_value = QtCore.QDataStream.Ok
return m
def test_serialize_pre_error_mock(self, stream_mock):
"""Test serialize_stream with an error already set."""
- stream_mock.status.return_value = QDataStream.ReadCorruptData
+ stream_mock.status.return_value = QtCore.QDataStream.ReadCorruptData
with pytest.raises(OSError, match="The data stream has read corrupt "
"data."):
- qtutils.serialize_stream(stream_mock, QPoint())
+ qtutils.serialize_stream(stream_mock, QtCore.QPoint())
assert not stream_mock.__lshift__.called
def test_serialize_post_error_mock(self, stream_mock):
"""Test serialize_stream with an error while serializing."""
- obj = QPoint()
+ obj = QtCore.QPoint()
stream_mock.__lshift__.side_effect = lambda _other: self._set_status(
- stream_mock, QDataStream.ReadCorruptData)
+ stream_mock, QtCore.QDataStream.ReadCorruptData)
with pytest.raises(OSError, match="The data stream has read corrupt "
"data."):
@@ -305,19 +304,19 @@ class TestSerializeStream:
def test_deserialize_pre_error_mock(self, stream_mock):
"""Test deserialize_stream with an error already set."""
- stream_mock.status.return_value = QDataStream.ReadCorruptData
+ stream_mock.status.return_value = QtCore.QDataStream.ReadCorruptData
with pytest.raises(OSError, match="The data stream has read corrupt "
"data."):
- qtutils.deserialize_stream(stream_mock, QPoint())
+ qtutils.deserialize_stream(stream_mock, QtCore.QPoint())
assert not stream_mock.__rshift__.called
def test_deserialize_post_error_mock(self, stream_mock):
"""Test deserialize_stream with an error while deserializing."""
- obj = QPoint()
+ obj = QtCore.QPoint()
stream_mock.__rshift__.side_effect = lambda _other: self._set_status(
- stream_mock, QDataStream.ReadCorruptData)
+ stream_mock, QtCore.QDataStream.ReadCorruptData)
with pytest.raises(OSError, match="The data stream has read corrupt "
"data."):
@@ -327,14 +326,14 @@ class TestSerializeStream:
def test_round_trip_real_stream(self):
"""Test a round trip with a real QDataStream."""
- src_obj = QPoint(23, 42)
- dest_obj = QPoint()
- data = QByteArray()
+ src_obj = QtCore.QPoint(23, 42)
+ dest_obj = QtCore.QPoint()
+ data = QtCore.QByteArray()
- write_stream = QDataStream(data, QIODevice.WriteOnly)
+ write_stream = QtCore.QDataStream(data, QtCore.QIODevice.WriteOnly)
qtutils.serialize_stream(write_stream, src_obj)
- read_stream = QDataStream(data, QIODevice.ReadOnly)
+ read_stream = QtCore.QDataStream(data, QtCore.QIODevice.ReadOnly)
qtutils.deserialize_stream(read_stream, dest_obj)
assert src_obj == dest_obj
@@ -342,18 +341,18 @@ class TestSerializeStream:
@pytest.mark.qt_log_ignore('^QIODevice::write.*: ReadOnly device')
def test_serialize_readonly_stream(self):
"""Test serialize_stream with a read-only stream."""
- data = QByteArray()
- stream = QDataStream(data, QIODevice.ReadOnly)
+ data = QtCore.QByteArray()
+ stream = QtCore.QDataStream(data, QtCore.QIODevice.ReadOnly)
with pytest.raises(OSError, match="The data stream cannot write to "
"the underlying device."):
- qtutils.serialize_stream(stream, QPoint())
+ qtutils.serialize_stream(stream, QtCore.QPoint())
@pytest.mark.qt_log_ignore('QIODevice::read.*: WriteOnly device')
def test_deserialize_writeonly_stream(self):
"""Test deserialize_stream with a write-only stream."""
- data = QByteArray()
- obj = QPoint()
- stream = QDataStream(data, QIODevice.WriteOnly)
+ data = QtCore.QByteArray()
+ obj = QtCore.QPoint()
+ stream = QtCore.QDataStream(data, QtCore.QIODevice.WriteOnly)
with pytest.raises(OSError, match="The data stream has read past the "
"end of the data in the underlying device."):
qtutils.deserialize_stream(stream, obj)
@@ -388,7 +387,7 @@ class TestSavefileOpen:
with qtutils.savefile_open('filename'):
pass
- qsavefile_mock.open.assert_called_once_with(QIODevice.WriteOnly)
+ qsavefile_mock.open.assert_called_once_with(QtCore.QIODevice.WriteOnly)
qsavefile_mock.cancelWriting.assert_called_once_with()
def test_mock_exception(self, qsavefile_mock):
@@ -399,7 +398,7 @@ class TestSavefileOpen:
with qtutils.savefile_open('filename'):
raise SavefileTestException
- qsavefile_mock.open.assert_called_once_with(QIODevice.WriteOnly)
+ qsavefile_mock.open.assert_called_once_with(QtCore.QIODevice.WriteOnly)
qsavefile_mock.cancelWriting.assert_called_once_with()
def test_mock_commit_failed(self, qsavefile_mock):
@@ -411,7 +410,7 @@ class TestSavefileOpen:
with qtutils.savefile_open('filename'):
pass
- qsavefile_mock.open.assert_called_once_with(QIODevice.WriteOnly)
+ qsavefile_mock.open.assert_called_once_with(QtCore.QIODevice.WriteOnly)
assert not qsavefile_mock.cancelWriting.called
assert not qsavefile_mock.errorString.called
@@ -426,7 +425,7 @@ class TestSavefileOpen:
with qtutils.savefile_open('filename') as f:
f.write("Hello World")
- qsavefile_mock.open.assert_called_once_with(QIODevice.WriteOnly)
+ qsavefile_mock.open.assert_called_once_with(QtCore.QIODevice.WriteOnly)
assert not qsavefile_mock.cancelWriting.called
qsavefile_mock.write.assert_called_once_with(b"Hello World")
@@ -533,22 +532,22 @@ if test_file is not None:
def setUp(self):
"""Set up self.f using a PyQIODevice instead of a real file."""
- self._data = QByteArray()
+ self._data = QtCore.QByteArray()
self.f = self.open(test_file.TESTFN, 'wb')
def open(self, _fname, mode):
"""Open an in-memory PyQIODevice instead of a real file."""
modes = {
- 'wb': QIODevice.WriteOnly | QIODevice.Truncate,
- 'w': QIODevice.WriteOnly | QIODevice.Text | QIODevice.Truncate,
- 'rb': QIODevice.ReadOnly,
- 'r': QIODevice.ReadOnly | QIODevice.Text,
+ 'wb': QtCore.QIODevice.WriteOnly | QtCore.QIODevice.Truncate,
+ 'w': QtCore.QIODevice.WriteOnly | QtCore.QIODevice.Text | QtCore.QIODevice.Truncate,
+ 'rb': QtCore.QIODevice.ReadOnly,
+ 'r': QtCore.QIODevice.ReadOnly | QtCore.QIODevice.Text,
}
try:
qt_mode = modes[mode]
except KeyError:
raise ValueError("Invalid mode {}!".format(mode))
- f = QBuffer(self._data)
+ f = QtCore.QBuffer(self._data)
f.open(qt_mode)
qiodev = qtutils.PyQIODevice(f)
# Make sure tests using name/mode don't blow up.
@@ -580,7 +579,7 @@ if test_file is not None:
"""Skip this test truncating is unsupported."""
-class FailingQIODevice(QIODevice):
+class FailingQIODevice(QtCore.QIODevice):
"""A fake QIODevice where reads/writes fail."""
@@ -617,8 +616,8 @@ class TestPyQIODevice:
@pytest.fixture
def pyqiodev(self):
"""Fixture providing a PyQIODevice with a QByteArray to test."""
- data = QByteArray()
- f = QBuffer(data)
+ data = QtCore.QByteArray()
+ f = QtCore.QBuffer(data)
qiodev = qtutils.PyQIODevice(f)
yield qiodev
qiodev.close()
@@ -656,14 +655,14 @@ class TestPyQIODevice:
Args:
method: The name of the method to call.
"""
- pyqiodev.open(QIODevice.WriteOnly)
+ pyqiodev.open(QtCore.QIODevice.WriteOnly)
func = getattr(pyqiodev, method)
with pytest.raises(OSError, match="Trying to read unreadable file!"):
func()
def test_unwritable(self, pyqiodev):
"""Test writing with a read-only device."""
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QtCore.QIODevice.ReadOnly)
with pytest.raises(OSError, match="Trying to write to unwritable "
"file!"):
pyqiodev.write(b'')
@@ -676,17 +675,17 @@ class TestPyQIODevice:
data: The data to write before checking if the length equals
len(data).
"""
- pyqiodev.open(QIODevice.WriteOnly)
+ pyqiodev.open(QtCore.QIODevice.WriteOnly)
pyqiodev.write(data)
assert len(pyqiodev) == len(data)
def test_failing_open(self, tmp_path):
"""Test open() which fails (because it's an existent directory)."""
- qf = QFile(str(tmp_path))
+ qf = QtCore.QFile(str(tmp_path))
dev = qtutils.PyQIODevice(qf)
with pytest.raises(qtutils.QtOSError) as excinfo:
- dev.open(QIODevice.WriteOnly)
- assert excinfo.value.qt_errno == QFileDevice.OpenError
+ dev.open(QtCore.QIODevice.WriteOnly)
+ assert excinfo.value.qt_errno == QtCore.QFileDevice.OpenError
assert dev.closed
def test_fileno(self, pyqiodev):
@@ -715,9 +714,9 @@ class TestPyQIODevice:
data: The expected data to read after seeking.
raising: Whether seeking should raise OSError.
"""
- with pyqiodev.open(QIODevice.WriteOnly) as f:
+ with pyqiodev.open(QtCore.QIODevice.WriteOnly) as f:
f.write(b'1234567890')
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QtCore.QIODevice.ReadOnly)
if raising:
with pytest.raises(OSError, match="seek failed!"):
pyqiodev.seek(offset, whence)
@@ -736,7 +735,7 @@ class TestPyQIODevice:
# pylint: enable=no-member,useless-suppression
else:
pytest.skip("Needs os.SEEK_HOLE or os.SEEK_DATA available.")
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QtCore.QIODevice.ReadOnly)
with pytest.raises(io.UnsupportedOperation):
pyqiodev.seek(0, whence)
@@ -746,7 +745,7 @@ class TestPyQIODevice:
This also verifies seek() and tell() behave as expected.
"""
- proc = QProcess()
+ proc = QtCore.QProcess()
proc.start(*py_proc('print("Hello World")'))
dev = qtutils.PyQIODevice(proc)
assert not dev.closed
@@ -765,7 +764,7 @@ class TestPyQIODevice:
def test_closed(self, pyqiodev):
"""Test the closed attribute."""
assert pyqiodev.closed
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QtCore.QIODevice.ReadOnly)
assert not pyqiodev.closed
pyqiodev.close()
assert pyqiodev.closed
@@ -773,14 +772,14 @@ class TestPyQIODevice:
def test_contextmanager(self, pyqiodev):
"""Make sure using the PyQIODevice as context manager works."""
assert pyqiodev.closed
- with pyqiodev.open(QIODevice.ReadOnly) as f:
+ with pyqiodev.open(QtCore.QIODevice.ReadOnly) as f:
assert not f.closed
assert f is pyqiodev
assert pyqiodev.closed
def test_flush(self, pyqiodev):
"""Make sure flushing doesn't raise an exception."""
- pyqiodev.open(QIODevice.WriteOnly)
+ pyqiodev.open(QtCore.QIODevice.WriteOnly)
pyqiodev.write(b'test')
pyqiodev.flush()
@@ -795,14 +794,14 @@ class TestPyQIODevice:
method: The name of the method to call.
ret: The return value we expect.
"""
- pyqiodev.open(QIODevice.WriteOnly)
+ pyqiodev.open(QtCore.QIODevice.WriteOnly)
func = getattr(pyqiodev, method)
assert func() == ret
@pytest.mark.parametrize('mode, readable, writable', [
- (QIODevice.ReadOnly, True, False),
- (QIODevice.ReadWrite, True, True),
- (QIODevice.WriteOnly, False, True),
+ (QtCore.QIODevice.ReadOnly, True, False),
+ (QtCore.QIODevice.ReadWrite, True, True),
+ (QtCore.QIODevice.WriteOnly, False, True),
])
def test_readable_writable(self, mode, readable, writable, pyqiodev):
"""Test readable() and writable().
@@ -831,19 +830,19 @@ class TestPyQIODevice:
size: The size to pass to readline()
chunks: A list of expected chunks to read.
"""
- with pyqiodev.open(QIODevice.WriteOnly) as f:
+ with pyqiodev.open(QtCore.QIODevice.WriteOnly) as f:
f.write(b'one\ntwo\nthree')
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QtCore.QIODevice.ReadOnly)
for i, chunk in enumerate(chunks, start=1):
print("Expecting chunk {}: {!r}".format(i, chunk))
assert pyqiodev.readline(size) == chunk
def test_write(self, pyqiodev):
"""Make sure writing and re-reading works."""
- with pyqiodev.open(QIODevice.WriteOnly) as f:
+ with pyqiodev.open(QtCore.QIODevice.WriteOnly) as f:
f.write(b'foo\n')
f.write(b'bar\n')
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QtCore.QIODevice.ReadOnly)
assert pyqiodev.read() == b'foo\nbar\n'
def test_write_error(self, pyqiodev_failing):
@@ -856,8 +855,8 @@ class TestPyQIODevice:
reason="Needs /dev/full.")
def test_write_error_real(self):
"""Test a real write error with /dev/full on supported systems."""
- qf = QFile('/dev/full')
- qf.open(QIODevice.WriteOnly | QIODevice.Unbuffered)
+ qf = QtCore.QFile('/dev/full')
+ qf.open(QtCore.QIODevice.WriteOnly | QtCore.QIODevice.Unbuffered)
dev = qtutils.PyQIODevice(qf)
with pytest.raises(OSError, match='No space left on device'):
dev.write(b'foo')
@@ -876,9 +875,9 @@ class TestPyQIODevice:
size: The size to pass to read()
chunks: A list of expected data chunks.
"""
- with pyqiodev.open(QIODevice.WriteOnly) as f:
+ with pyqiodev.open(QtCore.QIODevice.WriteOnly) as f:
f.write(b'1234567890')
- pyqiodev.open(QIODevice.ReadOnly)
+ pyqiodev.open(QtCore.QIODevice.ReadOnly)
for i, chunk in enumerate(chunks):
print("Expecting chunk {}: {!r}".format(i, chunk))
assert pyqiodev.read(size) == chunk
@@ -924,18 +923,18 @@ class TestEventLoop:
def test_normal_exec(self):
"""Test exec_ without double-executing."""
self.loop = qtutils.EventLoop()
- QTimer.singleShot(100, self._assert_executing)
- QTimer.singleShot(200, self.loop.quit)
+ QtCore.QTimer.singleShot(100, self._assert_executing)
+ QtCore.QTimer.singleShot(200, self.loop.quit)
self.loop.exec()
assert not self.loop._executing
def test_double_exec(self):
"""Test double-executing."""
self.loop = qtutils.EventLoop()
- QTimer.singleShot(100, self._assert_executing)
- QTimer.singleShot(200, self._double_exec)
- QTimer.singleShot(300, self._assert_executing)
- QTimer.singleShot(400, self.loop.quit)
+ QtCore.QTimer.singleShot(100, self._assert_executing)
+ QtCore.QTimer.singleShot(200, self._double_exec)
+ QtCore.QTimer.singleShot(300, self._assert_executing)
+ QtCore.QTimer.singleShot(400, self.loop.quit)
self.loop.exec()
assert not self.loop._executing
@@ -972,9 +971,9 @@ class TestInterpolateColor:
def test_invalid_colorspace(self, colors):
"""Test an invalid colorspace."""
with pytest.raises(ValueError):
- qtutils.interpolate_color(colors.white, colors.black, 10, QColor.Cmyk)
+ qtutils.interpolate_color(colors.white, colors.black, 10, QtGui.QColor.Cmyk)
- @pytest.mark.parametrize('colorspace', [QColor.Rgb, QColor.Hsv, QColor.Hsl])
+ @pytest.mark.parametrize('colorspace', [QtGui.QColor.Rgb, QtGui.QColor.Hsv, QtGui.QColor.Hsl])
def test_0_100(self, colors, colorspace):
"""Test 0% and 100% in different colorspaces."""
white = qtutils.interpolate_color(colors.white, colors.black, 0, colorspace)
@@ -985,7 +984,7 @@ class TestInterpolateColor:
def test_interpolation_rgb(self):
"""Test an interpolation in the RGB colorspace."""
color = qtutils.interpolate_color(
- testutils.Color(0, 40, 100), testutils.Color(0, 20, 200), 50, QColor.Rgb)
+ testutils.Color(0, 40, 100), testutils.Color(0, 20, 200), 50, QtGui.QColor.Rgb)
assert testutils.Color(color) == testutils.Color(0, 30, 150)
def test_interpolation_hsv(self):
@@ -994,7 +993,7 @@ class TestInterpolateColor:
stop = testutils.Color()
start.setHsv(0, 40, 100)
stop.setHsv(0, 20, 200)
- color = qtutils.interpolate_color(start, stop, 50, QColor.Hsv)
+ color = qtutils.interpolate_color(start, stop, 50, QtGui.QColor.Hsv)
expected = testutils.Color()
expected.setHsv(0, 30, 150)
assert testutils.Color(color) == expected
@@ -1005,12 +1004,12 @@ class TestInterpolateColor:
stop = testutils.Color()
start.setHsl(0, 40, 100)
stop.setHsl(0, 20, 200)
- color = qtutils.interpolate_color(start, stop, 50, QColor.Hsl)
+ color = qtutils.interpolate_color(start, stop, 50, QtGui.QColor.Hsl)
expected = testutils.Color()
expected.setHsl(0, 30, 150)
assert testutils.Color(color) == expected
- @pytest.mark.parametrize('colorspace', [QColor.Rgb, QColor.Hsv, QColor.Hsl])
+ @pytest.mark.parametrize('colorspace', [QtGui.QColor.Rgb, QtGui.QColor.Hsv, QtGui.QColor.Hsl])
def test_interpolation_alpha(self, colorspace):
"""Test interpolation of colorspace's alpha."""
start = testutils.Color(0, 0, 0, 30)
@@ -1028,5 +1027,5 @@ class TestInterpolateColor:
"""Test an interpolation with a gradient turned off."""
color = qtutils.interpolate_color(
testutils.Color(0, 0, 0), testutils.Color(255, 255, 255), percentage, None)
- assert isinstance(color, QColor)
+ assert isinstance(color, QtGui.QColor)
assert testutils.Color(color) == testutils.Color(*expected)
diff --git a/tests/unit/utils/test_standarddir.py b/tests/unit/utils/test_standarddir.py
index 0ca635ae2..44d7f53d2 100644
--- a/tests/unit/utils/test_standarddir.py
+++ b/tests/unit/utils/test_standarddir.py
@@ -28,7 +28,7 @@ import textwrap
import logging
import subprocess
-from PyQt5.QtCore import QStandardPaths
+from qutebrowser.qt import QtCore
import pytest
from qutebrowser.utils import standarddir, utils, qtutils, version
@@ -114,8 +114,8 @@ def test_fake_windows(tmpdir, monkeypatch, what):
def test_fake_haiku(tmpdir, monkeypatch):
"""Test getting data dir on HaikuOS."""
locations = {
- QStandardPaths.AppDataLocation: '',
- QStandardPaths.ConfigLocation: str(tmpdir / 'config' / APPNAME),
+ QtCore.QStandardPaths.AppDataLocation: '',
+ QtCore.QStandardPaths.ConfigLocation: str(tmpdir / 'config' / APPNAME),
}
monkeypatch.setattr(standarddir.QStandardPaths, 'writableLocation',
locations.get)
@@ -135,14 +135,14 @@ class TestWritableLocation:
'qutebrowser.utils.standarddir.QStandardPaths.writableLocation',
lambda typ: '')
with pytest.raises(standarddir.EmptyValueError):
- standarddir._writable_location(QStandardPaths.AppDataLocation)
+ standarddir._writable_location(QtCore.QStandardPaths.AppDataLocation)
def test_sep(self, monkeypatch):
"""Make sure the right kind of separator is used."""
monkeypatch.setattr(standarddir.os, 'sep', '\\')
monkeypatch.setattr(standarddir.os.path, 'join',
lambda *parts: '\\'.join(parts))
- loc = standarddir._writable_location(QStandardPaths.AppDataLocation)
+ loc = standarddir._writable_location(QtCore.QStandardPaths.AppDataLocation)
assert '/' not in loc
assert '\\' in loc
diff --git a/tests/unit/utils/test_urlmatch.py b/tests/unit/utils/test_urlmatch.py
index caf52c76d..1fe70917f 100644
--- a/tests/unit/utils/test_urlmatch.py
+++ b/tests/unit/utils/test_urlmatch.py
@@ -33,7 +33,7 @@ import string
import pytest
import hypothesis
import hypothesis.strategies as hst
-from PyQt5.QtCore import QUrl
+from qutebrowser.qt import QtCore
from qutebrowser.utils import urlmatch
@@ -203,7 +203,7 @@ def test_whitespace_hosts(host):
This is a deviation from Chromium.
"""
template = 'https://{}/*'
- url = QUrl(template.format(host))
+ url = QtCore.QUrl(template.format(host))
assert not url.isValid()
with pytest.raises(urlmatch.ParseError,
@@ -288,7 +288,7 @@ class TestMatchAllPagesForGivenScheme:
("http://[::1]/bar", True),
])
def test_urls(self, up, url, expected):
- assert up.matches(QUrl(url)) == expected
+ assert up.matches(QtCore.QUrl(url)) == expected
class TestMatchAllDomains:
@@ -313,7 +313,7 @@ class TestMatchAllDomains:
("https://google.com/", False),
])
def test_urls(self, up, url, expected):
- assert up.matches(QUrl(url)) == expected
+ assert up.matches(QtCore.QUrl(url)) == expected
class TestMatchSubdomains:
@@ -340,7 +340,7 @@ class TestMatchSubdomains:
("http://yahoo.com/foobar", False),
])
def test_urls(self, up, url, expected):
- assert up.matches(QUrl(url)) == expected
+ assert up.matches(QtCore.QUrl(url)) == expected
class TestMatchGlobEscaping:
@@ -365,7 +365,7 @@ class TestMatchGlobEscaping:
(r"file:///fooXbar\hellobaz", False),
])
def test_urls(self, up, url, expected):
- assert up.matches(QUrl(url)) == expected
+ assert up.matches(QtCore.QUrl(url)) == expected
class TestMatchIpAddresses:
@@ -396,7 +396,7 @@ class TestMatchIpAddresses:
])
def test_urls(self, pattern, expected):
up = urlmatch.UrlPattern(pattern)
- assert up.matches(QUrl("http://127.0.0.1")) == expected
+ assert up.matches(QtCore.QUrl("http://127.0.0.1")) == expected
## FIXME Missing TEST(ExtensionURLPatternTest, Match8) (unicode)?
@@ -423,7 +423,7 @@ class TestMatchChromeUrls:
("chrome://history", False),
])
def test_urls(self, up, url, expected):
- assert up.matches(QUrl(url)) == expected
+ assert up.matches(QtCore.QUrl(url)) == expected
class TestMatchAnything:
@@ -461,7 +461,7 @@ class TestMatchAnything:
"javascript:",
])
def test_urls(self, up, url):
- assert up.matches(QUrl(url))
+ assert up.matches(QtCore.QUrl(url))
@pytest.mark.parametrize('pattern, url, expected', [
@@ -474,7 +474,7 @@ class TestMatchAnything:
])
def test_special_schemes(pattern, url, expected):
"""Based on TEST(ExtensionURLPatternTest, Match13)."""
- assert urlmatch.UrlPattern(pattern).matches(QUrl(url)) == expected
+ assert urlmatch.UrlPattern(pattern).matches(QtCore.QUrl(url)) == expected
class TestFileScheme:
@@ -506,7 +506,7 @@ class TestFileScheme:
("file://localhost/foo", True),
])
def test_urls(self, up, url, expected):
- assert up.matches(QUrl(url)) == expected
+ assert up.matches(QtCore.QUrl(url)) == expected
class TestMatchSpecificPort:
@@ -531,7 +531,7 @@ class TestMatchSpecificPort:
("http://www.example.com:8080/foo", False),
])
def test_urls(self, up, url, expected):
- assert up.matches(QUrl(url)) == expected
+ assert up.matches(QtCore.QUrl(url)) == expected
class TestExplicitPortWildcard:
@@ -556,15 +556,15 @@ class TestExplicitPortWildcard:
("http://www.example.com:8080/foo", True),
])
def test_urls(self, up, url, expected):
- assert up.matches(QUrl(url)) == expected
+ assert up.matches(QtCore.QUrl(url)) == expected
def test_ignore_missing_slashes():
"""Based on TEST(ExtensionURLPatternTest, IgnoreMissingBackslashes)."""
pattern1 = urlmatch.UrlPattern("http://www.example.com/example")
pattern2 = urlmatch.UrlPattern("http://www.example.com/example/*")
- url1 = QUrl('http://www.example.com/example')
- url2 = QUrl('http://www.example.com/example/')
+ url1 = QtCore.QUrl('http://www.example.com/example')
+ url2 = QtCore.QUrl('http://www.example.com/example/')
# Same patterns should match same URLs.
assert pattern1.matches(url1)
@@ -577,7 +577,7 @@ def test_ignore_missing_slashes():
def test_trailing_slash():
"""Contrary to Chromium, we allow to leave off a trailing slash."""
- url = QUrl('http://www.example.com/')
+ url = QtCore.QUrl('http://www.example.com/')
pattern = urlmatch.UrlPattern('http://www.example.com')
assert pattern.matches(url)
@@ -603,7 +603,7 @@ def test_trailing_dot_domain(pattern, url):
[1] http://www.dns-sd.org./TrailingDotsInDomainNames.html
[2] http://www.ietf.org/rfc/rfc1738.txt
"""
- assert urlmatch.UrlPattern(pattern).matches(QUrl(url))
+ assert urlmatch.UrlPattern(pattern).matches(QtCore.QUrl(url))
class TestUncanonicalizedUrl:
@@ -624,7 +624,7 @@ class TestUncanonicalizedUrl:
practice.
"""
pattern = urlmatch.UrlPattern('*://*.gOoGle.com/*')
- assert pattern.matches(QUrl(url))
+ assert pattern.matches(QtCore.QUrl(url))
@pytest.mark.parametrize('url', [
'https://ɡoogle.com',
@@ -636,7 +636,7 @@ class TestUncanonicalizedUrl:
The first 'g' isn't actually a 'g'.
"""
pattern = urlmatch.UrlPattern('https://*.ɡoogle.com/*')
- assert pattern.matches(QUrl(url))
+ assert pattern.matches(QtCore.QUrl(url))
@pytest.mark.xfail(reason="Gets accepted by urllib.parse")
def test_failing_canonicalization(self):
@@ -671,7 +671,7 @@ class TestUncanonicalizedUrl:
def test_urlpattern_benchmark(benchmark):
- url = QUrl('https://www.example.com/barfoobar')
+ url = QtCore.QUrl('https://www.example.com/barfoobar')
def run():
up = urlmatch.UrlPattern('https://*.example.com/*foo*')
@@ -707,7 +707,7 @@ def test_urlpattern_hypothesis(pattern):
up = urlmatch.UrlPattern(pattern)
except urlmatch.ParseError:
return
- up.matches(QUrl('https://www.example.com/'))
+ up.matches(QtCore.QUrl('https://www.example.com/'))
@pytest.mark.parametrize('text1, text2, equal', [
diff --git a/tests/unit/utils/test_urlutils.py b/tests/unit/utils/test_urlutils.py
index e5773e25e..6a3060573 100644
--- a/tests/unit/utils/test_urlutils.py
+++ b/tests/unit/utils/test_urlutils.py
@@ -24,8 +24,7 @@ import logging
import dataclasses
import urllib.parse
-from PyQt5.QtCore import QUrl
-from PyQt5.QtNetwork import QNetworkProxy
+from qutebrowser.qt import QtNetwork, QtCore
import pytest
import hypothesis
import hypothesis.strategies
@@ -135,7 +134,7 @@ class TestFuzzyUrl:
url = urlutils.fuzzy_url('foo', cwd='cwd', relative=True)
os_mock.path.exists.assert_called_once_with('cwd/foo')
- assert url == QUrl('file:cwd/foo')
+ assert url == QtCore.QUrl('file:cwd/foo')
def test_file_relative(self, os_mock):
"""Test with relative=True and cwd unset."""
@@ -146,7 +145,7 @@ class TestFuzzyUrl:
url = urlutils.fuzzy_url('foo', relative=True)
os_mock.path.exists.assert_called_once_with('abs_path')
- assert url == QUrl('file:abs_path')
+ assert url == QtCore.QUrl('file:abs_path')
def test_file_relative_os_error(self, os_mock, is_url_mock):
"""Test with relative=True, cwd unset and abspath raising OSError."""
@@ -157,11 +156,11 @@ class TestFuzzyUrl:
url = urlutils.fuzzy_url('foo', relative=True)
assert not os_mock.path.exists.called
- assert url == QUrl('http://foo')
+ assert url == QtCore.QUrl('http://foo')
@pytest.mark.parametrize('path, expected', [
- ('/foo', QUrl('file:///foo')),
- ('/bar\n', QUrl('file:///bar')),
+ ('/foo', QtCore.QUrl('file:///foo')),
+ ('/bar\n', QtCore.QUrl('file:///bar')),
])
def test_file_absolute(self, path, expected, os_mock):
"""Test with an absolute path."""
@@ -178,7 +177,7 @@ class TestFuzzyUrl:
os_mock.path.isabs.return_value = True
url = urlutils.fuzzy_url('~/foo')
- assert url == QUrl('file://' + os.path.expanduser('~/foo'))
+ assert url == QtCore.QUrl('file://' + os.path.expanduser('~/foo'))
def test_address(self, os_mock, is_url_mock):
"""Test passing something with relative=False."""
@@ -186,16 +185,16 @@ class TestFuzzyUrl:
is_url_mock.return_value = True
url = urlutils.fuzzy_url('foo')
- assert url == QUrl('http://foo')
+ assert url == QtCore.QUrl('http://foo')
def test_search_term(self, os_mock, is_url_mock, get_search_url_mock):
"""Test passing something with do_search=True."""
os_mock.path.isabs.return_value = False
is_url_mock.return_value = False
- get_search_url_mock.return_value = QUrl('search_url')
+ get_search_url_mock.return_value = QtCore.QUrl('search_url')
url = urlutils.fuzzy_url('foo', do_search=True)
- assert url == QUrl('search_url')
+ assert url == QtCore.QUrl('search_url')
def test_search_term_value_error(self, os_mock, is_url_mock,
get_search_url_mock):
@@ -205,14 +204,14 @@ class TestFuzzyUrl:
get_search_url_mock.side_effect = ValueError
url = urlutils.fuzzy_url('foo', do_search=True)
- assert url == QUrl('http://foo')
+ assert url == QtCore.QUrl('http://foo')
def test_no_do_search(self, is_url_mock):
"""Test with do_search = False."""
is_url_mock.return_value = False
url = urlutils.fuzzy_url('foo', do_search=False)
- assert url == QUrl('http://foo')
+ assert url == QtCore.QUrl('http://foo')
@pytest.mark.parametrize('do_search', [True, False])
def test_invalid_url(self, do_search, caplog):
@@ -233,11 +232,11 @@ class TestFuzzyUrl:
])
def test_force_search(self, urlstring, get_search_url_mock):
"""Test the force search option."""
- get_search_url_mock.return_value = QUrl('search_url')
+ get_search_url_mock.return_value = QtCore.QUrl('search_url')
url = urlutils.fuzzy_url(urlstring, force_search=True)
- assert url == QUrl('search_url')
+ assert url == QtCore.QUrl('search_url')
@pytest.mark.parametrize('path, check_exists', [
('/foo', False),
@@ -273,7 +272,7 @@ class TestFuzzyUrl:
('www.qutebrowser.org', False),
])
def test_special_urls(url, special):
- assert urlutils.is_special_url(QUrl(url)) == special
+ assert urlutils.is_special_url(QtCore.QUrl(url)) == special
@pytest.mark.parametrize('open_base_url', [True, False])
@@ -321,7 +320,7 @@ def test_get_search_url_for_path_search(config_stub, url, host, path, open_base_
config_stub.val.url.open_base_url = open_base_url
url = urlutils._get_search_url(url)
assert url.host() == host
- assert url.path(options=QUrl.PrettyDecoded) == '/' + path
+ assert url.path(options=QtCore.QUrl.PrettyDecoded) == '/' + path
@pytest.mark.parametrize('url, host', [
@@ -352,7 +351,7 @@ def test_get_search_url_invalid(url):
@dataclasses.dataclass
class UrlParams:
- url: QUrl
+ url: QtCore.QUrl
is_url: bool = True
is_url_no_autosearch: bool = True
use_dns: bool = True
@@ -497,7 +496,7 @@ def test_invalid_url_error(message_mock, caplog, url, valid, has_err_string):
valid: Whether the QUrl is valid (isValid() == True).
has_err_string: Whether the QUrl is expected to have errorString set.
"""
- qurl = QUrl(url)
+ qurl = QtCore.QUrl(url)
assert qurl.isValid() == valid
if valid:
with pytest.raises(ValueError):
@@ -530,7 +529,7 @@ def test_raise_cmdexc_if_invalid(url, valid, has_err_string):
valid: Whether the QUrl is valid (isValid() == True).
has_err_string: Whether the QUrl is expected to have errorString set.
"""
- qurl = QUrl(url)
+ qurl = QtCore.QUrl(url)
assert qurl.isValid() == valid
if valid:
urlutils.raise_cmdexc_if_invalid(qurl)
@@ -545,36 +544,36 @@ def test_raise_cmdexc_if_invalid(url, valid, has_err_string):
@pytest.mark.parametrize('qurl, output', [
- (QUrl(), None),
- (QUrl('http://qutebrowser.org/test.html'), 'test.html'),
- (QUrl('http://qutebrowser.org/foo.html#bar'), 'foo.html'),
- (QUrl('http://user:password@qutebrowser.org/foo?bar=baz#fish'), 'foo'),
- (QUrl('http://qutebrowser.org/'), 'qutebrowser.org.html'),
- (QUrl('qute://'), None),
+ (QtCore.QUrl(), None),
+ (QtCore.QUrl('http://qutebrowser.org/test.html'), 'test.html'),
+ (QtCore.QUrl('http://qutebrowser.org/foo.html#bar'), 'foo.html'),
+ (QtCore.QUrl('http://user:password@qutebrowser.org/foo?bar=baz#fish'), 'foo'),
+ (QtCore.QUrl('http://qutebrowser.org/'), 'qutebrowser.org.html'),
+ (QtCore.QUrl('qute://'), None),
# data URL support
- (QUrl('data:text/plain,'), 'download.txt'),
- (QUrl('data:application/pdf,'), 'download.pdf'),
- (QUrl('data:foo/bar,'), 'download'), # unknown extension
- (QUrl('data:text/xul,'), 'download.xul'), # strict=False
- (QUrl('data:'), None), # invalid data URL
+ (QtCore.QUrl('data:text/plain,'), 'download.txt'),
+ (QtCore.QUrl('data:application/pdf,'), 'download.pdf'),
+ (QtCore.QUrl('data:foo/bar,'), 'download'), # unknown extension
+ (QtCore.QUrl('data:text/xul,'), 'download.xul'), # strict=False
+ (QtCore.QUrl('data:'), None), # invalid data URL
])
def test_filename_from_url(qurl, output):
assert urlutils.filename_from_url(qurl) == output
-@pytest.mark.parametrize('qurl', [QUrl(), QUrl('qute://'), QUrl('data:')])
+@pytest.mark.parametrize('qurl', [QtCore.QUrl(), QtCore.QUrl('qute://'), QtCore.QUrl('data:')])
def test_filename_from_url_fallback(qurl):
assert urlutils.filename_from_url(qurl, fallback='fallback') == 'fallback'
@pytest.mark.parametrize('qurl, expected', [
- (QUrl('ftp://example.com/'), ('ftp', 'example.com', 21)),
- (QUrl('ftp://example.com:2121/'), ('ftp', 'example.com', 2121)),
- (QUrl('http://qutebrowser.org:8010/waterfall'),
+ (QtCore.QUrl('ftp://example.com/'), ('ftp', 'example.com', 21)),
+ (QtCore.QUrl('ftp://example.com:2121/'), ('ftp', 'example.com', 2121)),
+ (QtCore.QUrl('http://qutebrowser.org:8010/waterfall'),
('http', 'qutebrowser.org', 8010)),
- (QUrl('https://example.com/'), ('https', 'example.com', 443)),
- (QUrl('https://example.com:4343/'), ('https', 'example.com', 4343)),
- (QUrl('http://user:password@qutebrowser.org/foo?bar=baz#fish'),
+ (QtCore.QUrl('https://example.com/'), ('https', 'example.com', 443)),
+ (QtCore.QUrl('https://example.com:4343/'), ('https', 'example.com', 4343)),
+ (QtCore.QUrl('http://user:password@qutebrowser.org/foo?bar=baz#fish'),
('http', 'qutebrowser.org', 80)),
])
def test_host_tuple_valid(qurl, expected):
@@ -582,10 +581,10 @@ def test_host_tuple_valid(qurl, expected):
@pytest.mark.parametrize('qurl, expected', [
- (QUrl(), urlutils.InvalidUrlError),
- (QUrl('qute://'), ValueError),
- (QUrl('qute://foobar'), ValueError),
- (QUrl('mailto:nobody'), ValueError),
+ (QtCore.QUrl(), urlutils.InvalidUrlError),
+ (QtCore.QUrl('qute://'), ValueError),
+ (QtCore.QUrl('qute://foobar'), ValueError),
+ (QtCore.QUrl('mailto:nobody'), ValueError),
])
def test_host_tuple_invalid(qurl, expected):
with pytest.raises(expected):
@@ -595,9 +594,9 @@ def test_host_tuple_invalid(qurl, expected):
class TestInvalidUrlError:
@pytest.mark.parametrize('url, raising, has_err_string', [
- (QUrl(), False, False),
- (QUrl('http://www.example.com/'), True, False),
- (QUrl('://'), False, True),
+ (QtCore.QUrl(), False, False),
+ (QtCore.QUrl('http://www.example.com/'), True, False),
+ (QtCore.QUrl('://'), False, True),
])
def test_invalid_url_error(self, url, raising, has_err_string):
"""Test InvalidUrlError.
@@ -640,8 +639,8 @@ class TestInvalidUrlError:
])
def test_same_domain(are_same, url1, url2):
"""Test same_domain."""
- assert urlutils.same_domain(QUrl(url1), QUrl(url2)) == are_same
- assert urlutils.same_domain(QUrl(url2), QUrl(url1)) == are_same
+ assert urlutils.same_domain(QtCore.QUrl(url1), QtCore.QUrl(url2)) == are_same
+ assert urlutils.same_domain(QtCore.QUrl(url2), QtCore.QUrl(url1)) == are_same
@pytest.mark.parametrize('url1, url2', [
@@ -651,7 +650,7 @@ def test_same_domain(are_same, url1, url2):
def test_same_domain_invalid_url(url1, url2):
"""Test same_domain with invalid URLs."""
with pytest.raises(urlutils.InvalidUrlError):
- urlutils.same_domain(QUrl(url1), QUrl(url2))
+ urlutils.same_domain(QtCore.QUrl(url1), QtCore.QUrl(url2))
@pytest.mark.parametrize('url, expected', [
@@ -661,7 +660,7 @@ def test_same_domain_invalid_url(url1, url2):
'http://foo.bar/?header=text/pl%C3%A4in'),
])
def test_encoded_url(url, expected):
- url = QUrl(url)
+ url = QtCore.QUrl(url)
assert urlutils.encoded_url(url) == expected
@@ -671,23 +670,23 @@ def test_file_url():
def test_data_url():
url = urlutils.data_url('text/plain', b'foo')
- assert url == QUrl('data:text/plain;base64,Zm9v')
+ assert url == QtCore.QUrl('data:text/plain;base64,Zm9v')
@pytest.mark.parametrize('url, expected', [
# No IDN
- (QUrl('http://www.example.com'), 'http://www.example.com'),
+ (QtCore.QUrl('http://www.example.com'), 'http://www.example.com'),
# IDN in domain
- (QUrl('http://www.ä.com'), '(www.xn--4ca.com) http://www.ä.com'),
+ (QtCore.QUrl('http://www.ä.com'), '(www.xn--4ca.com) http://www.ä.com'),
# IDN with non-whitelisted TLD
- (QUrl('http://www.ä.foo'), 'http://www.xn--4ca.foo'),
+ (QtCore.QUrl('http://www.ä.foo'), 'http://www.xn--4ca.foo'),
# Unicode only in path
- (QUrl('http://www.example.com/ä'), 'http://www.example.com/ä'),
+ (QtCore.QUrl('http://www.example.com/ä'), 'http://www.example.com/ä'),
# Unicode only in TLD (looks like Qt shows Punycode with рф...)
- (QUrl('http://www.example.xn--p1ai'),
+ (QtCore.QUrl('http://www.example.xn--p1ai'),
'(www.example.xn--p1ai) http://www.example.рф'),
# https://bugreports.qt.io/browse/QTBUG-60364
- (QUrl('http://www.xn--80ak6aa92e.com'),
+ (QtCore.QUrl('http://www.xn--80ak6aa92e.com'),
'http://www.xn--80ak6aa92e.com'),
])
def test_safe_display_string(url, expected):
@@ -696,34 +695,34 @@ def test_safe_display_string(url, expected):
def test_safe_display_string_invalid():
with pytest.raises(urlutils.InvalidUrlError):
- urlutils.safe_display_string(QUrl())
+ urlutils.safe_display_string(QtCore.QUrl())
class TestProxyFromUrl:
@pytest.mark.parametrize('url, expected', [
('socks://example.com/',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com')),
+ QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.Socks5Proxy, 'example.com')),
('socks5://example.com',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com')),
+ QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.Socks5Proxy, 'example.com')),
('socks5://example.com:2342',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com', 2342)),
+ QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.Socks5Proxy, 'example.com', 2342)),
('socks5://foo@example.com',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com', 0, 'foo')),
+ QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.Socks5Proxy, 'example.com', 0, 'foo')),
('socks5://foo:bar@example.com',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com', 0, 'foo',
+ QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.Socks5Proxy, 'example.com', 0, 'foo',
'bar')),
('socks5://foo:bar@example.com:2323',
- QNetworkProxy(QNetworkProxy.Socks5Proxy, 'example.com', 2323,
+ QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.Socks5Proxy, 'example.com', 2323,
'foo', 'bar')),
- ('direct://', QNetworkProxy(QNetworkProxy.NoProxy)),
+ ('direct://', QtNetwork.QNetworkProxy(QtNetwork.QNetworkProxy.NoProxy)),
])
def test_proxy_from_url_valid(self, url, expected):
- assert urlutils.proxy_from_url(QUrl(url)) == expected
+ assert urlutils.proxy_from_url(QtCore.QUrl(url)) == expected
@pytest.mark.parametrize('scheme', ['pac+http', 'pac+https'])
def test_proxy_from_url_pac(self, scheme, qapp):
- fetcher = urlutils.proxy_from_url(QUrl('{}://foo'.format(scheme)))
+ fetcher = urlutils.proxy_from_url(QtCore.QUrl('{}://foo'.format(scheme)))
assert isinstance(fetcher, pac.PACFetcher)
@pytest.mark.parametrize('url, exception', [
@@ -735,17 +734,17 @@ class TestProxyFromUrl:
])
def test_invalid(self, url, exception):
with pytest.raises(exception):
- urlutils.proxy_from_url(QUrl(url))
+ urlutils.proxy_from_url(QtCore.QUrl(url))
class TestParseJavascriptUrl:
@pytest.mark.parametrize('url, message', [
- (QUrl(), ""),
- (QUrl('https://example.com'), "Expected a javascript:... URL"),
- (QUrl('javascript://example.com'),
+ (QtCore.QUrl(), ""),
+ (QtCore.QUrl('https://example.com'), "Expected a javascript:... URL"),
+ (QtCore.QUrl('javascript://example.com'),
"URL contains unexpected components: example.com"),
- (QUrl('javascript://foo:bar@example.com:1234'),
+ (QtCore.QUrl('javascript://foo:bar@example.com:1234'),
"URL contains unexpected components: foo:bar@example.com:1234"),
])
def test_invalid(self, url, message):
@@ -753,13 +752,13 @@ class TestParseJavascriptUrl:
urlutils.parse_javascript_url(url)
@pytest.mark.parametrize('url, source', [
- (QUrl('javascript:"hello" %0a "world"'), '"hello" \n "world"'),
- (QUrl('javascript:/'), '/'),
- (QUrl('javascript:///'), '///'),
+ (QtCore.QUrl('javascript:"hello" %0a "world"'), '"hello" \n "world"'),
+ (QtCore.QUrl('javascript:/'), '/'),
+ (QtCore.QUrl('javascript:///'), '///'),
# https://github.com/web-platform-tests/wpt/blob/master/html/browsers/browsing-the-web/navigating-across-documents/javascript-url-query-fragment-components.html
- (QUrl('javascript:"nope" ? "yep" : "what";'), '"nope" ? "yep" : "what";'),
- (QUrl('javascript:"wrong"; // # %0a "ok";'), '"wrong"; // # \n "ok";'),
- (QUrl('javascript:"%252525 ? %252525 # %252525"'),
+ (QtCore.QUrl('javascript:"nope" ? "yep" : "what";'), '"nope" ? "yep" : "what";'),
+ (QtCore.QUrl('javascript:"wrong"; // # %0a "ok";'), '"wrong"; // # \n "ok";'),
+ (QtCore.QUrl('javascript:"%252525 ? %252525 # %252525"'),
'"%2525 ? %2525 # %2525"'),
])
def test_valid(self, url, source):
@@ -768,7 +767,7 @@ class TestParseJavascriptUrl:
@hypothesis.given(source=hypothesis.strategies.text())
def test_hypothesis(self, source):
scheme = 'javascript:'
- url = QUrl(scheme + urllib.parse.quote(source))
+ url = QtCore.QUrl(scheme + urllib.parse.quote(source))
hypothesis.assume(url.isValid())
try:
diff --git a/tests/unit/utils/test_utils.py b/tests/unit/utils/test_utils.py
index 4620c2198..c60758a3b 100644
--- a/tests/unit/utils/test_utils.py
+++ b/tests/unit/utils/test_utils.py
@@ -29,9 +29,7 @@ import re
import shlex
import math
import operator
-
-from PyQt5.QtCore import QUrl, QRect
-from PyQt5.QtGui import QClipboard
+from qutebrowser.qt import QtGui
import pytest
import hypothesis
from hypothesis import strategies
@@ -41,6 +39,7 @@ import qutebrowser
import qutebrowser.utils # for test_qualname
from qutebrowser.utils import utils, usertypes
from qutebrowser.utils.utils import VersionNumber
+from qutebrowser.qt import QtCore
class TestVersionNumber:
@@ -659,7 +658,7 @@ class TestGetSetClipboard:
def test_set(self, clipboard_mock, caplog):
utils.set_clipboard('Hello World')
clipboard_mock.setText.assert_called_with('Hello World',
- mode=QClipboard.Clipboard)
+ mode=QtGui.QClipboard.Clipboard)
assert not caplog.records
def test_set_unsupported_selection(self, clipboard_mock):
@@ -759,7 +758,7 @@ class TestOpenFile:
result = caplog.messages[0]
assert re.fullmatch(
r"Opening /foo/bar with the system application", result)
- openurl_mock.assert_called_with(QUrl('file:///foo/bar'))
+ openurl_mock.assert_called_with(QtCore.QUrl('file:///foo/bar'))
def test_cmdline_sandboxed(self, fake_flatpak,
config_stub, message_mock, caplog):
@@ -778,12 +777,12 @@ class TestOpenFile:
assert caplog.messages[1] == ('Ignoring download dispatcher from '
'config in sandbox environment')
- openurl_mock.assert_called_with(QUrl('file:///foo/bar'))
+ openurl_mock.assert_called_with(QtCore.QUrl('file:///foo/bar'))
def test_system_default_sandboxed(self, config_stub, openurl_mock,
fake_flatpak):
utils.open_file('/foo/bar')
- openurl_mock.assert_called_with(QUrl('file:///foo/bar'))
+ openurl_mock.assert_called_with(QtCore.QUrl('file:///foo/bar'))
def test_unused():
@@ -981,8 +980,8 @@ class TestCleanupFileContext:
class TestParseRect:
@pytest.mark.parametrize('value, expected', [
- ('1x1+0+0', QRect(0, 0, 1, 1)),
- ('123x789+12+34', QRect(12, 34, 123, 789)),
+ ('1x1+0+0', QtCore.QRect(0, 0, 1, 1)),
+ ('123x789+12+34', QtCore.QRect(12, 34, 123, 789)),
])
def test_valid(self, value, expected):
assert utils.parse_rect(value) == expected
diff --git a/tests/unit/utils/test_version.py b/tests/unit/utils/test_version.py
index 7b616d8b7..d7a46ae07 100644
--- a/tests/unit/utils/test_version.py
+++ b/tests/unit/utils/test_version.py
@@ -33,7 +33,7 @@ import dataclasses
import pytest
import hypothesis
import hypothesis.strategies
-from PyQt5.QtCore import PYQT_VERSION_STR
+from qutebrowser.qt import QtWebEngine, QtCore
import qutebrowser
from qutebrowser.config import config, websettings
@@ -1004,21 +1004,20 @@ class TestWebEngineVersions:
"""Compare the inferred Chromium version with the real one."""
pyqt_webengine_version = version._get_pyqt_webengine_qt_version()
if pyqt_webengine_version is None:
- if '.dev' in PYQT_VERSION_STR:
+ if '.dev' in QtCore.PYQT_VERSION_STR:
pytest.skip("dev version of PyQt5")
try:
- from PyQt5.QtWebEngine import (
- PYQT_WEBENGINE_VERSION_STR, PYQT_WEBENGINE_VERSION)
+ pass
except ImportError as e:
# QtWebKit or QtWebEngine < 5.13
pytest.skip(str(e))
- if PYQT_WEBENGINE_VERSION >= 0x050F02:
+ if QtWebEngine.PYQT_WEBENGINE_VERSION >= 0x050F02:
# Starting with Qt 5.15.2, we can only do bad guessing anyways...
pytest.skip("Could be QtWebEngine 5.15.2 or 5.15.3")
- pyqt_webengine_version = PYQT_WEBENGINE_VERSION_STR
+ pyqt_webengine_version = QtWebEngine.PYQT_WEBENGINE_VERSION_STR
versions = version.WebEngineVersions.from_pyqt(pyqt_webengine_version)
inferred = versions.chromium
diff --git a/tests/unit/utils/usertypes/test_timer.py b/tests/unit/utils/usertypes/test_timer.py
index 4dc85b06f..0fab35528 100644
--- a/tests/unit/utils/usertypes/test_timer.py
+++ b/tests/unit/utils/usertypes/test_timer.py
@@ -20,12 +20,12 @@
"""Tests for Timer."""
import pytest
-from PyQt5.QtCore import QObject
+from qutebrowser.qt import QtCore
from qutebrowser.utils import usertypes
-class Parent(QObject):
+class Parent(QtCore.QObject):
"""Class for test_parent()."""