From 115021b8eadecdddfff24a4d25d65bb6033290d5 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 13 Jun 2016 15:32:19 +0200 Subject: [PATCH] Get QtWebEngine to start and work somewhat --- qutebrowser/browser/tab.py | 3 +- qutebrowser/browser/webengine/__init__.py | 20 ++++++ qutebrowser/browser/webengine/webenginetab.py | 70 +++++++++++++++++++ qutebrowser/browser/webkit/webview.py | 18 ++--- qutebrowser/mainwindow/statusbar/progress.py | 4 +- qutebrowser/mainwindow/statusbar/url.py | 10 +-- qutebrowser/mainwindow/tabbedbrowser.py | 8 ++- qutebrowser/mainwindow/tabwidget.py | 2 +- qutebrowser/qutebrowser.py | 3 + qutebrowser/utils/usertypes.py | 7 ++ tests/helpers/stubs.py | 3 +- 11 files changed, 126 insertions(+), 22 deletions(-) create mode 100644 qutebrowser/browser/webengine/__init__.py create mode 100644 qutebrowser/browser/webengine/webenginetab.py diff --git a/qutebrowser/browser/tab.py b/qutebrowser/browser/tab.py index e280d6c43..b5492b0d2 100644 --- a/qutebrowser/browser/tab.py +++ b/qutebrowser/browser/tab.py @@ -43,7 +43,8 @@ class WrapperLayout(QLayout): return self._widget.sizeHint() def itemAt(self, i): - raise AssertionError("Should never be called!") + # FIXME why does this get called? + return None def takeAt(self, i): raise AssertionError("Should never be called!") diff --git a/qutebrowser/browser/webengine/__init__.py b/qutebrowser/browser/webengine/__init__.py new file mode 100644 index 000000000..d7c910b36 --- /dev/null +++ b/qutebrowser/browser/webengine/__init__.py @@ -0,0 +1,20 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2014-2016 Florian Bruhin (The Compiler) +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""Classes related to the browser widgets for QtWebEngine.""" diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py new file mode 100644 index 000000000..89ee76d82 --- /dev/null +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -0,0 +1,70 @@ +# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et: + +# Copyright 2016 Florian Bruhin (The Compiler) +# +# This file is part of qutebrowser. +# +# qutebrowser is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# qutebrowser is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with qutebrowser. If not, see . + +"""Wrapper over a QWebEngineView.""" + +from PyQt5.QtCore import pyqtSlot +from PyQt5.QtWebEngineWidgets import QWebEngineView + +from qutebrowser.browser.tab import AbstractTab +from qutebrowser.browser.webkit.webview import WebView +from qutebrowser.utils import usertypes + + +class WebEngineViewTab(AbstractTab): + + def __init__(self, win_id, parent=None): + super().__init__() + widget = QWebEngineView() + self._set_widget(widget) + self._connect_signals() + + def openurl(self, url): + self._widget.load(url) + + @property + def cur_url(self): + return self._widget.url() + + @property + def progress(self): + return 0 # FIXME:refactor + + @property + def load_status(self): + return usertypes.LoadStatus.success + + @property + def scroll_pos(self): + return (0, 0) + + def _connect_signals(self): + view = self._widget + page = view.page() + page.windowCloseRequested.connect(self.window_close_requested) + page.linkHovered.connect(self.link_hovered) + page.loadProgress.connect(self.load_progress) + page.loadStarted.connect(self.load_started) + view.titleChanged.connect(self.title_changed) + page.loadFinished.connect(self.load_finished) + # FIXME:refactor + # view.iconChanged.connect(self.icon_changed) + # view.scroll_pos_changed.connect(self.scroll_pos_changed) + # view.url_text_changed.connect(self.url_text_changed) + # view.load_status_changed.connect(self.load_status_changed) diff --git a/qutebrowser/browser/webkit/webview.py b/qutebrowser/browser/webkit/webview.py index f759d0f45..44dc233b9 100644 --- a/qutebrowser/browser/webkit/webview.py +++ b/qutebrowser/browser/webkit/webview.py @@ -36,10 +36,6 @@ from qutebrowser.browser import hints from qutebrowser.browser.webkit import webpage, webelem -LoadStatus = usertypes.enum('LoadStatus', ['none', 'success', 'success_https', - 'error', 'warn', 'loading']) - - class WebView(QWebView): """One browser tab in TabbedBrowser. @@ -92,7 +88,7 @@ class WebView(QWebView): # See https://github.com/The-Compiler/qutebrowser/issues/462 self.setStyle(QStyleFactory.create('Fusion')) self.win_id = win_id - self.load_status = LoadStatus.none + self.load_status = usertypes.LoadStatus.none self._check_insertmode = False self.inspector = None self.scroll_pos = (-1, -1) @@ -189,7 +185,7 @@ class WebView(QWebView): def _set_load_status(self, val): """Setter for load_status.""" - if not isinstance(val, LoadStatus): + if not isinstance(val, usertypes.LoadStatus): raise TypeError("Type {} is no LoadStatus member!".format(val)) log.webview.debug("load status for {}: {}".format(repr(self), val)) self.load_status = val @@ -429,7 +425,7 @@ class WebView(QWebView): self.progress = 0 self.viewing_source = False self._has_ssl_errors = False - self._set_load_status(LoadStatus.loading) + self._set_load_status(usertypes.LoadStatus.loading) @pyqtSlot() def on_load_finished(self): @@ -442,14 +438,14 @@ class WebView(QWebView): ok = not self.page().error_occurred if ok and not self._has_ssl_errors: if self.cur_url.scheme() == 'https': - self._set_load_status(LoadStatus.success_https) + self._set_load_status(usertypes.LoadStatus.success_https) else: - self._set_load_status(LoadStatus.success) + self._set_load_status(usertypes.LoadStatus.success) elif ok: - self._set_load_status(LoadStatus.warn) + self._set_load_status(usertypes.LoadStatus.warn) else: - self._set_load_status(LoadStatus.error) + self._set_load_status(usertypes.LoadStatus.error) if not self.title(): self.titleChanged.emit(self.url().toDisplayString()) self._handle_auto_insert_mode(ok) diff --git a/qutebrowser/mainwindow/statusbar/progress.py b/qutebrowser/mainwindow/statusbar/progress.py index ded74ce1a..a082e5a7a 100644 --- a/qutebrowser/mainwindow/statusbar/progress.py +++ b/qutebrowser/mainwindow/statusbar/progress.py @@ -24,7 +24,7 @@ from PyQt5.QtWidgets import QProgressBar, QSizePolicy from qutebrowser.browser.webkit import webview from qutebrowser.config import style -from qutebrowser.utils import utils +from qutebrowser.utils import utils, usertypes class Progress(QProgressBar): @@ -67,7 +67,7 @@ class Progress(QProgressBar): # sometimes. return # pragma: no cover self.setValue(tab.progress) - if tab.load_status == webview.LoadStatus.loading: + if tab.load_status == usertypes.LoadStatus.loading: self.show() else: self.hide() diff --git a/qutebrowser/mainwindow/statusbar/url.py b/qutebrowser/mainwindow/statusbar/url.py index c308fceda..a71d3429f 100644 --- a/qutebrowser/mainwindow/statusbar/url.py +++ b/qutebrowser/mainwindow/statusbar/url.py @@ -119,11 +119,11 @@ class UrlText(textbase.TextBase): Args: status_str: The LoadStatus as string. """ - status = webview.LoadStatus[status_str] - if status in (webview.LoadStatus.success, - webview.LoadStatus.success_https, - webview.LoadStatus.error, - webview.LoadStatus.warn): + status = usertypes.LoadStatus[status_str] + if status in (usertypes.LoadStatus.success, + usertypes.LoadStatus.success_https, + usertypes.LoadStatus.error, + usertypes.LoadStatus.warn): self._normal_url_type = UrlType[status_str] else: self._normal_url_type = UrlType.normal diff --git a/qutebrowser/mainwindow/tabbedbrowser.py b/qutebrowser/mainwindow/tabbedbrowser.py index 0ed8ba6b2..b31672ded 100644 --- a/qutebrowser/mainwindow/tabbedbrowser.py +++ b/qutebrowser/mainwindow/tabbedbrowser.py @@ -31,6 +31,7 @@ from qutebrowser.keyinput import modeman from qutebrowser.mainwindow import tabwidget from qutebrowser.browser import signalfilter from qutebrowser.browser.webkit import webview, webkittab +from qutebrowser.browser.webengine import webenginetab from qutebrowser.utils import (log, usertypes, utils, qtutils, objreg, urlutils, message) @@ -377,7 +378,12 @@ class TabbedBrowser(tabwidget.TabWidget): tabbed_browser = objreg.get('tabbed-browser', scope='window', window=window.win_id) return tabbed_browser.tabopen(url, background, explicit) - tab = webkittab.WebViewTab(self._win_id, self) + + if objreg.get('args').backend == 'webengine': + tab = webenginetab.WebEngineViewTab(self._win_id, self) + else: + tab = webkittab.WebViewTab(self._win_id, self) + self._connect_tab_signals(tab) idx = self._get_new_tab_idx(explicit) self.insertTab(idx, tab, "") diff --git a/qutebrowser/mainwindow/tabwidget.py b/qutebrowser/mainwindow/tabwidget.py index 2c1ab850c..706bc8982 100644 --- a/qutebrowser/mainwindow/tabwidget.py +++ b/qutebrowser/mainwindow/tabwidget.py @@ -117,7 +117,7 @@ class TabWidget(QTabWidget): fields['title_sep'] = ' - ' if page_title else '' fields['perc_raw'] = widget.progress - if widget.load_status == webview.LoadStatus.loading: + if widget.load_status == usertypes.LoadStatus.loading: fields['perc'] = '[{}%] '.format(widget.progress) else: fields['perc'] = '' diff --git a/qutebrowser/qutebrowser.py b/qutebrowser/qutebrowser.py index 39c6e7a31..475c7b7da 100644 --- a/qutebrowser/qutebrowser.py +++ b/qutebrowser/qutebrowser.py @@ -69,6 +69,9 @@ def get_argparser(): 'tab-silent', 'tab-bg-silent', 'window'], help="How URLs should be opened if there is already a " "qutebrowser instance running.") + parser.add_argument('--backend', choices=['webkit', 'webengine'], + help="Which backend to use.") + parser.add_argument('--json-args', help=argparse.SUPPRESS) parser.add_argument('--temp-basedir-restarted', help=argparse.SUPPRESS) diff --git a/qutebrowser/utils/usertypes.py b/qutebrowser/utils/usertypes.py index a2c4d0429..a48cc6495 100644 --- a/qutebrowser/utils/usertypes.py +++ b/qutebrowser/utils/usertypes.py @@ -246,6 +246,13 @@ Exit = enum('Exit', ['ok', 'reserved', 'exception', 'err_ipc', 'err_init', 'err_config', 'err_key_config'], is_int=True, start=0) +# Load status of a tab +LoadStatus = enum('LoadStatus', ['none', 'success', 'success_https', 'error', + 'warn', 'loading']) + + + + class Question(QObject): """A question asked to the user, e.g. via the status bar. diff --git a/tests/helpers/stubs.py b/tests/helpers/stubs.py index d6c8b69d0..1877ac3a1 100644 --- a/tests/helpers/stubs.py +++ b/tests/helpers/stubs.py @@ -31,6 +31,7 @@ from PyQt5.QtWidgets import QCommonStyle, QWidget, QLineEdit from qutebrowser.browser.webkit import webview, history from qutebrowser.config import configexc +from qutebrowser.utils import usertypes from qutebrowser.mainwindow import mainwindow @@ -234,7 +235,7 @@ class FakeWebView(QWidget): super().__init__() self.progress = 0 self.scroll_pos = (-1, -1) - self.load_status = webview.LoadStatus.none + self.load_status = usertypes.LoadStatus.none self.tab_id = tab_id self.cur_url = url self.title = title