Drop PyQt < 5.7.1 support for QtWebEngine
This commit is contained in:
parent
7a4a34c374
commit
a86170f45d
@ -21,10 +21,6 @@ matrix:
|
|||||||
- os: linux
|
- os: linux
|
||||||
env: DOCKER=ubuntu-xenial
|
env: DOCKER=ubuntu-xenial
|
||||||
services: docker
|
services: docker
|
||||||
- os: linux
|
|
||||||
language: python
|
|
||||||
python: 3.5
|
|
||||||
env: TESTENV=py35-pyqt56
|
|
||||||
- os: linux
|
- os: linux
|
||||||
language: python
|
language: python
|
||||||
python: 3.6
|
python: 3.6
|
||||||
|
@ -36,6 +36,7 @@ Added
|
|||||||
Changed
|
Changed
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
|
- PyQt/Qt 5.7.1 is now required for the QtWebEngine backend
|
||||||
- Scrolling with the scrollwheel while holding shift now scrolls sideways
|
- Scrolling with the scrollwheel while holding shift now scrolls sideways
|
||||||
- New way of clicking hints with which solves various small issues
|
- New way of clicking hints with which solves various small issues
|
||||||
- When yanking a mailto: link via hints, the mailto: prefix is now stripped
|
- When yanking a mailto: link via hints, the mailto: prefix is now stripped
|
||||||
|
@ -158,7 +158,7 @@
|
|||||||
|<<content-allow-images,allow-images>>|Whether images are automatically loaded in web pages.
|
|<<content-allow-images,allow-images>>|Whether images are automatically loaded in web pages.
|
||||||
|<<content-allow-javascript,allow-javascript>>|Enables or disables the running of JavaScript programs.
|
|<<content-allow-javascript,allow-javascript>>|Enables or disables the running of JavaScript programs.
|
||||||
|<<content-allow-plugins,allow-plugins>>|Enables or disables plugins in Web pages.
|
|<<content-allow-plugins,allow-plugins>>|Enables or disables plugins in Web pages.
|
||||||
|<<content-webgl,webgl>>|Enables or disables WebGL. For QtWebEngine, Qt/PyQt >= 5.7 is required for this setting.
|
|<<content-webgl,webgl>>|Enables or disables WebGL.
|
||||||
|<<content-css-regions,css-regions>>|Enable or disable support for CSS regions.
|
|<<content-css-regions,css-regions>>|Enable or disable support for CSS regions.
|
||||||
|<<content-hyperlink-auditing,hyperlink-auditing>>|Enable or disable hyperlink auditing (<a ping>).
|
|<<content-hyperlink-auditing,hyperlink-auditing>>|Enable or disable hyperlink auditing (<a ping>).
|
||||||
|<<content-geolocation,geolocation>>|Allow websites to request geolocations.
|
|<<content-geolocation,geolocation>>|Allow websites to request geolocations.
|
||||||
@ -1426,7 +1426,7 @@ Default: +pass:[false]+
|
|||||||
|
|
||||||
[[content-webgl]]
|
[[content-webgl]]
|
||||||
=== webgl
|
=== webgl
|
||||||
Enables or disables WebGL. For QtWebEngine, Qt/PyQt >= 5.7 is required for this setting.
|
Enables or disables WebGL.
|
||||||
|
|
||||||
Valid values:
|
Valid values:
|
||||||
|
|
||||||
|
@ -49,12 +49,8 @@ class DownloadItem(downloads.AbstractDownloadItem):
|
|||||||
|
|
||||||
def _is_page_download(self):
|
def _is_page_download(self):
|
||||||
"""Check if this item is a page (i.e. mhtml) download."""
|
"""Check if this item is a page (i.e. mhtml) download."""
|
||||||
try:
|
return (self._qt_item.savePageFormat() !=
|
||||||
return (self._qt_item.savePageFormat() !=
|
QWebEngineDownloadItem.UnknownSaveFormat)
|
||||||
QWebEngineDownloadItem.UnknownSaveFormat)
|
|
||||||
except AttributeError:
|
|
||||||
# Added in Qt 5.7
|
|
||||||
return False
|
|
||||||
|
|
||||||
@pyqtSlot(QWebEngineDownloadItem.DownloadState)
|
@pyqtSlot(QWebEngineDownloadItem.DownloadState)
|
||||||
def _on_state_changed(self, state):
|
def _on_state_changed(self, state):
|
||||||
@ -209,9 +205,6 @@ class DownloadManager(downloads.AbstractDownloadManager):
|
|||||||
def get_mhtml(self, tab, target):
|
def get_mhtml(self, tab, target):
|
||||||
"""Download the given tab as mhtml to the given target."""
|
"""Download the given tab as mhtml to the given target."""
|
||||||
assert tab.backend == usertypes.Backend.QtWebEngine
|
assert tab.backend == usertypes.Backend.QtWebEngine
|
||||||
# Raises browsertab.UnsupportedOperationError on older Qt versions
|
|
||||||
# but we let the caller handle that.
|
|
||||||
tab.action.check_save_page_supported()
|
|
||||||
assert self._mhtml_target is None, self._mhtml_target
|
assert self._mhtml_target is None, self._mhtml_target
|
||||||
self._mhtml_target = target
|
self._mhtml_target = target
|
||||||
tab.action.save_page()
|
tab.action.save_page()
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
from PyQt5.QtCore import QRect, Qt, QPoint
|
from PyQt5.QtCore import QRect, Qt, QPoint
|
||||||
from PyQt5.QtGui import QMouseEvent
|
from PyQt5.QtGui import QMouseEvent
|
||||||
|
|
||||||
from qutebrowser.utils import log, javascript, qtutils
|
from qutebrowser.utils import log, javascript
|
||||||
from qutebrowser.browser import webelem
|
from qutebrowser.browser import webelem
|
||||||
|
|
||||||
|
|
||||||
@ -159,15 +159,11 @@ class WebEngineElement(webelem.AbstractWebElement):
|
|||||||
# because it was added in Qt 5.6, but we can be sure we use that with
|
# because it was added in Qt 5.6, but we can be sure we use that with
|
||||||
# QtWebEngine.
|
# QtWebEngine.
|
||||||
# pylint: disable=no-member
|
# pylint: disable=no-member
|
||||||
# This also seems to break stuff on Qt 5.6 for some reason...
|
ev = QMouseEvent(QMouseEvent.MouseButtonPress, QPoint(0, 0),
|
||||||
if qtutils.version_check('5.7'):
|
QPoint(0, 0), QPoint(0, 0), Qt.NoButton, Qt.NoButton,
|
||||||
ev = QMouseEvent(QMouseEvent.MouseButtonPress, QPoint(0, 0),
|
Qt.NoModifier, Qt.MouseEventSynthesizedBySystem)
|
||||||
QPoint(0, 0), QPoint(0, 0), Qt.NoButton,
|
# pylint: enable=no-member
|
||||||
Qt.NoButton, Qt.NoModifier,
|
self._tab.send_event(ev)
|
||||||
Qt.MouseEventSynthesizedBySystem)
|
|
||||||
# pylint: enable=no-member
|
|
||||||
self._tab.send_event(ev)
|
|
||||||
|
|
||||||
# This actually "clicks" the element by calling focus() on it in JS.
|
# This actually "clicks" the element by calling focus() on it in JS.
|
||||||
js_code = javascript.assemble('webelem', 'focus', self._id)
|
js_code = javascript.assemble('webelem', 'focus', self._id)
|
||||||
self._tab.run_js_async(js_code)
|
self._tab.run_js_async(js_code)
|
||||||
|
@ -176,16 +176,16 @@ def shutdown():
|
|||||||
|
|
||||||
|
|
||||||
# Missing QtWebEngine attributes:
|
# Missing QtWebEngine attributes:
|
||||||
# - ScreenCaptureEnabled (5.7)
|
# - ScreenCaptureEnabled
|
||||||
# - Accelerated2dCanvasEnabled (5.7)
|
# - Accelerated2dCanvasEnabled
|
||||||
# - AutoLoadIconsForPage (5.7)
|
# - AutoLoadIconsForPage
|
||||||
# - TouchIconsEnabled (5.7)
|
# - TouchIconsEnabled
|
||||||
# - FocusOnNavigationEnabled (5.8)
|
# - FocusOnNavigationEnabled (5.8)
|
||||||
# - AllowRunningInsecureContent (5.8)
|
# - AllowRunningInsecureContent (5.8)
|
||||||
#
|
#
|
||||||
# Missing QtWebEngine fonts:
|
# Missing QtWebEngine fonts:
|
||||||
# - FantasyFont
|
# - FantasyFont
|
||||||
# - PictographFont (5.7)
|
# - PictographFont
|
||||||
|
|
||||||
|
|
||||||
MAPPINGS = {
|
MAPPINGS = {
|
||||||
@ -209,6 +209,8 @@ MAPPINGS = {
|
|||||||
# https://bugreports.qt.io/browse/QTBUG-58650
|
# https://bugreports.qt.io/browse/QTBUG-58650
|
||||||
# 'cookies-store':
|
# 'cookies-store':
|
||||||
# PersistentCookiePolicy(),
|
# PersistentCookiePolicy(),
|
||||||
|
'webgl':
|
||||||
|
Attribute(QWebEngineSettings.WebGLEnabled),
|
||||||
},
|
},
|
||||||
'input': {
|
'input': {
|
||||||
'spatial-navigation':
|
'spatial-navigation':
|
||||||
@ -278,12 +280,6 @@ MAPPINGS = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
|
||||||
MAPPINGS['content']['webgl'] = Attribute(QWebEngineSettings.WebGLEnabled)
|
|
||||||
except AttributeError:
|
|
||||||
# Added in Qt 5.7
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
MAPPINGS['general']['print-element-backgrounds'] = Attribute(
|
MAPPINGS['general']['print-element-backgrounds'] = Attribute(
|
||||||
QWebEngineSettings.PrintElementBackgrounds)
|
QWebEngineSettings.PrintElementBackgrounds)
|
||||||
|
@ -90,11 +90,6 @@ class WebEngineAction(browsertab.AbstractAction):
|
|||||||
def exit_fullscreen(self):
|
def exit_fullscreen(self):
|
||||||
self._action(QWebEnginePage.ExitFullScreen)
|
self._action(QWebEnginePage.ExitFullScreen)
|
||||||
|
|
||||||
def check_save_page_supported(self):
|
|
||||||
if not hasattr(QWebEnginePage, 'SavePage'):
|
|
||||||
raise browsertab.UnsupportedOperationError(
|
|
||||||
"Saving as mhtml is unsupported with Qt < 5.7")
|
|
||||||
|
|
||||||
def save_page(self):
|
def save_page(self):
|
||||||
"""Save the current page."""
|
"""Save the current page."""
|
||||||
self._action(QWebEnginePage.SavePage)
|
self._action(QWebEnginePage.SavePage)
|
||||||
@ -105,9 +100,7 @@ class WebEnginePrinting(browsertab.AbstractPrinting):
|
|||||||
"""QtWebEngine implementations related to printing."""
|
"""QtWebEngine implementations related to printing."""
|
||||||
|
|
||||||
def check_pdf_support(self):
|
def check_pdf_support(self):
|
||||||
if not hasattr(self._widget.page(), 'printToPdf'):
|
return True
|
||||||
raise browsertab.WebTabError(
|
|
||||||
"Printing to PDF is unsupported with QtWebEngine on Qt < 5.7")
|
|
||||||
|
|
||||||
def check_printer_support(self):
|
def check_printer_support(self):
|
||||||
if not hasattr(self._widget.page(), 'print'):
|
if not hasattr(self._widget.page(), 'print'):
|
||||||
@ -261,11 +254,7 @@ class WebEngineScroller(browsertab.AbstractScroller):
|
|||||||
def _init_widget(self, widget):
|
def _init_widget(self, widget):
|
||||||
super()._init_widget(widget)
|
super()._init_widget(widget)
|
||||||
page = widget.page()
|
page = widget.page()
|
||||||
try:
|
page.scrollPositionChanged.connect(self._update_pos)
|
||||||
page.scrollPositionChanged.connect(self._update_pos)
|
|
||||||
except AttributeError:
|
|
||||||
log.stub('scrollPositionChanged, on Qt < 5.7')
|
|
||||||
self._pos_perc = (None, None)
|
|
||||||
|
|
||||||
def _key_press(self, key, count=1):
|
def _key_press(self, key, count=1):
|
||||||
for _ in range(min(count, 5000)):
|
for _ in range(min(count, 5000)):
|
||||||
@ -501,7 +490,6 @@ class WebEngineTab(browsertab.AbstractTab):
|
|||||||
self.backend = usertypes.Backend.QtWebEngine
|
self.backend = usertypes.Backend.QtWebEngine
|
||||||
self._init_js()
|
self._init_js()
|
||||||
self._child_event_filter = None
|
self._child_event_filter = None
|
||||||
self.needs_qtbug54419_workaround = False
|
|
||||||
self._saved_zoom = None
|
self._saved_zoom = None
|
||||||
|
|
||||||
def _init_js(self):
|
def _init_js(self):
|
||||||
@ -516,13 +504,7 @@ class WebEngineTab(browsertab.AbstractTab):
|
|||||||
script.setSourceCode(js_code)
|
script.setSourceCode(js_code)
|
||||||
|
|
||||||
page = self._widget.page()
|
page = self._widget.page()
|
||||||
try:
|
script.setWorldId(QWebEngineScript.ApplicationWorld)
|
||||||
page.runJavaScript("", QWebEngineScript.ApplicationWorld)
|
|
||||||
except TypeError:
|
|
||||||
# We're unable to pass a world to runJavaScript
|
|
||||||
script.setWorldId(QWebEngineScript.MainWorld)
|
|
||||||
else:
|
|
||||||
script.setWorldId(QWebEngineScript.ApplicationWorld)
|
|
||||||
|
|
||||||
# FIXME:qtwebengine what about runsOnSubFrames?
|
# FIXME:qtwebengine what about runsOnSubFrames?
|
||||||
page.scripts().insert(script)
|
page.scripts().insert(script)
|
||||||
@ -567,19 +549,10 @@ class WebEngineTab(browsertab.AbstractTab):
|
|||||||
else:
|
else:
|
||||||
world_id = _JS_WORLD_MAP[world]
|
world_id = _JS_WORLD_MAP[world]
|
||||||
|
|
||||||
try:
|
if callback is None:
|
||||||
if callback is None:
|
self._widget.page().runJavaScript(code, world_id)
|
||||||
self._widget.page().runJavaScript(code, world_id)
|
else:
|
||||||
else:
|
self._widget.page().runJavaScript(code, world_id, callback)
|
||||||
self._widget.page().runJavaScript(code, world_id, callback)
|
|
||||||
except TypeError:
|
|
||||||
if world is not None and world != usertypes.JsWorld.jseval:
|
|
||||||
log.webview.warning("Ignoring world ID on Qt < 5.7")
|
|
||||||
# Qt < 5.7
|
|
||||||
if callback is None:
|
|
||||||
self._widget.page().runJavaScript(code)
|
|
||||||
else:
|
|
||||||
self._widget.page().runJavaScript(code, callback)
|
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
self.shutting_down.emit()
|
self.shutting_down.emit()
|
||||||
@ -602,11 +575,7 @@ class WebEngineTab(browsertab.AbstractTab):
|
|||||||
return self._widget.title()
|
return self._widget.title()
|
||||||
|
|
||||||
def icon(self):
|
def icon(self):
|
||||||
try:
|
return self._widget.icon()
|
||||||
return self._widget.icon()
|
|
||||||
except AttributeError:
|
|
||||||
log.stub('on Qt < 5.7')
|
|
||||||
return QIcon()
|
|
||||||
|
|
||||||
def set_html(self, html, base_url=None):
|
def set_html(self, html, base_url=None):
|
||||||
# FIXME:qtwebengine
|
# FIXME:qtwebengine
|
||||||
@ -712,19 +681,13 @@ class WebEngineTab(browsertab.AbstractTab):
|
|||||||
page.certificate_error.connect(self._on_ssl_errors)
|
page.certificate_error.connect(self._on_ssl_errors)
|
||||||
page.authenticationRequired.connect(self._on_authentication_required)
|
page.authenticationRequired.connect(self._on_authentication_required)
|
||||||
page.fullScreenRequested.connect(self._on_fullscreen_requested)
|
page.fullScreenRequested.connect(self._on_fullscreen_requested)
|
||||||
try:
|
page.contentsSizeChanged.connect(self.contents_size_changed)
|
||||||
page.contentsSizeChanged.connect(self.contents_size_changed)
|
|
||||||
except AttributeError:
|
|
||||||
log.stub('contentsSizeChanged, on Qt < 5.7')
|
|
||||||
|
|
||||||
view.titleChanged.connect(self.title_changed)
|
view.titleChanged.connect(self.title_changed)
|
||||||
view.urlChanged.connect(self._on_url_changed)
|
view.urlChanged.connect(self._on_url_changed)
|
||||||
view.renderProcessTerminated.connect(
|
view.renderProcessTerminated.connect(
|
||||||
self._on_render_process_terminated)
|
self._on_render_process_terminated)
|
||||||
try:
|
view.iconChanged.connect(self.icon_changed)
|
||||||
view.iconChanged.connect(self.icon_changed)
|
|
||||||
except AttributeError:
|
|
||||||
log.stub('iconChanged, on Qt < 5.7')
|
|
||||||
|
|
||||||
def event_target(self):
|
def event_target(self):
|
||||||
return self._widget.focusProxy()
|
return self._widget.focusProxy()
|
||||||
|
@ -71,7 +71,7 @@ class WebEngineView(QWebEngineView):
|
|||||||
A window without decoration.
|
A window without decoration.
|
||||||
QWebEnginePage::WebBrowserBackgroundTab:
|
QWebEnginePage::WebBrowserBackgroundTab:
|
||||||
A web browser tab without hiding the current visible
|
A web browser tab without hiding the current visible
|
||||||
WebEngineView. (Added in Qt 5.7)
|
WebEngineView.
|
||||||
|
|
||||||
Return:
|
Return:
|
||||||
The new QWebEngineView object.
|
The new QWebEngineView object.
|
||||||
@ -82,13 +82,6 @@ class WebEngineView(QWebEngineView):
|
|||||||
log.webview.debug("createWindow with type {}, background_tabs "
|
log.webview.debug("createWindow with type {}, background_tabs "
|
||||||
"{}".format(debug_type, background_tabs))
|
"{}".format(debug_type, background_tabs))
|
||||||
|
|
||||||
try:
|
|
||||||
background_tab_wintype = QWebEnginePage.WebBrowserBackgroundTab
|
|
||||||
except AttributeError:
|
|
||||||
# This is unavailable with an older PyQt, but we still might get
|
|
||||||
# this with a newer Qt...
|
|
||||||
background_tab_wintype = 0x0003
|
|
||||||
|
|
||||||
if wintype == QWebEnginePage.WebBrowserWindow:
|
if wintype == QWebEnginePage.WebBrowserWindow:
|
||||||
# Shift-Alt-Click
|
# Shift-Alt-Click
|
||||||
target = usertypes.ClickTarget.window
|
target = usertypes.ClickTarget.window
|
||||||
@ -103,7 +96,7 @@ class WebEngineView(QWebEngineView):
|
|||||||
target = usertypes.ClickTarget.tab
|
target = usertypes.ClickTarget.tab
|
||||||
else:
|
else:
|
||||||
target = usertypes.ClickTarget.tab_bg
|
target = usertypes.ClickTarget.tab_bg
|
||||||
elif wintype == background_tab_wintype:
|
elif wintype == QWebEnginePage.WebBrowserBackgroundTab:
|
||||||
# Middle-click / Ctrl-Click
|
# Middle-click / Ctrl-Click
|
||||||
if background_tabs:
|
if background_tabs:
|
||||||
target = usertypes.ClickTarget.tab_bg
|
target = usertypes.ClickTarget.tab_bg
|
||||||
@ -113,15 +106,6 @@ class WebEngineView(QWebEngineView):
|
|||||||
raise ValueError("Invalid wintype {}".format(debug_type))
|
raise ValueError("Invalid wintype {}".format(debug_type))
|
||||||
|
|
||||||
tab = shared.get_tab(self._win_id, target)
|
tab = shared.get_tab(self._win_id, target)
|
||||||
|
|
||||||
# WORKAROUND for https://bugreports.qt.io/browse/QTBUG-54419
|
|
||||||
vercheck = qtutils.version_check
|
|
||||||
qtbug54419_fixed = ((vercheck('5.6.2') and not vercheck('5.7.0')) or
|
|
||||||
qtutils.version_check('5.7.1') or
|
|
||||||
os.environ.get('QUTE_QTBUG54419_PATCHED', ''))
|
|
||||||
if not qtbug54419_fixed:
|
|
||||||
tab.needs_qtbug54419_workaround = True
|
|
||||||
|
|
||||||
return tab._widget # pylint: disable=protected-access
|
return tab._widget # pylint: disable=protected-access
|
||||||
|
|
||||||
|
|
||||||
@ -261,20 +245,16 @@ class WebEnginePage(QWebEnginePage):
|
|||||||
except shared.CallSuper:
|
except shared.CallSuper:
|
||||||
return super().javaScriptConfirm(url, js_msg)
|
return super().javaScriptConfirm(url, js_msg)
|
||||||
|
|
||||||
if PYQT_VERSION > 0x050700:
|
def javaScriptPrompt(self, url, js_msg, default):
|
||||||
# WORKAROUND
|
"""Override javaScriptPrompt to use qutebrowser prompts."""
|
||||||
# Can't override javaScriptPrompt with older PyQt versions
|
if self._is_shutting_down:
|
||||||
# https://www.riverbankcomputing.com/pipermail/pyqt/2016-November/038293.html
|
return (False, "")
|
||||||
def javaScriptPrompt(self, url, js_msg, default):
|
try:
|
||||||
"""Override javaScriptPrompt to use qutebrowser prompts."""
|
return shared.javascript_prompt(url, js_msg, default,
|
||||||
if self._is_shutting_down:
|
abort_on=[self.loadStarted,
|
||||||
return (False, "")
|
self.shutting_down])
|
||||||
try:
|
except shared.CallSuper:
|
||||||
return shared.javascript_prompt(url, js_msg, default,
|
return super().javaScriptPrompt(url, js_msg, default)
|
||||||
abort_on=[self.loadStarted,
|
|
||||||
self.shutting_down])
|
|
||||||
except shared.CallSuper:
|
|
||||||
return super().javaScriptPrompt(url, js_msg, default)
|
|
||||||
|
|
||||||
def javaScriptAlert(self, url, js_msg):
|
def javaScriptAlert(self, url, js_msg):
|
||||||
"""Override javaScriptAlert to use qutebrowser prompts."""
|
"""Override javaScriptAlert to use qutebrowser prompts."""
|
||||||
|
@ -823,8 +823,7 @@ def data(readonly=False):
|
|||||||
|
|
||||||
('webgl',
|
('webgl',
|
||||||
SettingValue(typ.Bool(), 'true'),
|
SettingValue(typ.Bool(), 'true'),
|
||||||
"Enables or disables WebGL. For QtWebEngine, Qt/PyQt >= 5.7 is "
|
"Enables or disables WebGL."),
|
||||||
"required for this setting."),
|
|
||||||
|
|
||||||
('css-regions',
|
('css-regions',
|
||||||
SettingValue(typ.Bool(), 'true',
|
SettingValue(typ.Bool(), 'true',
|
||||||
|
@ -539,22 +539,6 @@ class TabbedBrowser(tabwidget.TabWidget):
|
|||||||
# We can get signals for tabs we already deleted...
|
# We can get signals for tabs we already deleted...
|
||||||
return
|
return
|
||||||
|
|
||||||
# If needed, re-open the tab as a workaround for QTBUG-54419.
|
|
||||||
# See https://bugreports.qt.io/browse/QTBUG-54419
|
|
||||||
if (tab.backend == usertypes.Backend.QtWebEngine and
|
|
||||||
tab.needs_qtbug54419_workaround and url.isValid()):
|
|
||||||
log.misc.debug("Doing QTBUG-54419 workaround for {}, "
|
|
||||||
"url {}".format(tab, url))
|
|
||||||
background = self.currentIndex() != idx
|
|
||||||
self.setUpdatesEnabled(False)
|
|
||||||
try:
|
|
||||||
self.tabopen(url, background=background, idx=idx,
|
|
||||||
ignore_tabs_are_windows=True)
|
|
||||||
self.close_tab(tab, add_undo=False)
|
|
||||||
finally:
|
|
||||||
self.setUpdatesEnabled(True)
|
|
||||||
tab.needs_qtbug54419_workaround = False
|
|
||||||
|
|
||||||
@pyqtSlot(browsertab.AbstractTab, QIcon)
|
@pyqtSlot(browsertab.AbstractTab, QIcon)
|
||||||
def on_icon_changed(self, tab, icon):
|
def on_icon_changed(self, tab, icon):
|
||||||
"""Set the icon of a tab.
|
"""Set the icon of a tab.
|
||||||
|
@ -262,15 +262,16 @@ def get_backend(args):
|
|||||||
|
|
||||||
def check_qt_version(backend):
|
def check_qt_version(backend):
|
||||||
"""Check if the Qt version is recent enough."""
|
"""Check if the Qt version is recent enough."""
|
||||||
from PyQt5.QtCore import qVersion
|
from PyQt5.QtCore import qVersion, PYQT_VERSION
|
||||||
from qutebrowser.utils import qtutils
|
from qutebrowser.utils import qtutils
|
||||||
if qtutils.version_check('5.2.0', operator.lt):
|
if qtutils.version_check('5.2.0', operator.lt):
|
||||||
text = ("Fatal error: Qt and PyQt >= 5.2.0 are required, but {} is "
|
text = ("Fatal error: Qt and PyQt >= 5.2.0 are required, but {} is "
|
||||||
"installed.".format(qVersion()))
|
"installed.".format(qVersion()))
|
||||||
_die(text)
|
_die(text)
|
||||||
elif backend == 'webengine' and qtutils.version_check('5.6.0',
|
elif (backend == 'webengine' and (
|
||||||
operator.lt):
|
qtutils.version_check('5.7.0', operator.lt) or
|
||||||
text = ("Fatal error: Qt and PyQt >= 5.6.0 are required for "
|
PYQT_VERSION < 0x050701)):
|
||||||
|
text = ("Fatal error: Qt and PyQt >= 5.7.1 are required for "
|
||||||
"QtWebEngine support, but {} is installed.".format(qVersion()))
|
"QtWebEngine support, but {} is installed.".format(qVersion()))
|
||||||
_die(text)
|
_die(text)
|
||||||
|
|
||||||
|
@ -154,15 +154,6 @@ def link_pyqt(executable, venv_path):
|
|||||||
copy_or_link(path, dest)
|
copy_or_link(path, dest)
|
||||||
|
|
||||||
|
|
||||||
def patch_pypi_pyqt(venv_path):
|
|
||||||
executable = get_venv_executable(venv_path)
|
|
||||||
pyqt_dir = os.path.dirname(get_lib_path(executable, 'PyQt5.QtCore'))
|
|
||||||
qt_conf = os.path.join(pyqt_dir, 'Qt', 'libexec', 'qt.conf')
|
|
||||||
with open(qt_conf, 'w', encoding='utf-8') as f:
|
|
||||||
f.write('[Paths]\n')
|
|
||||||
f.write('Prefix = ..\n')
|
|
||||||
|
|
||||||
|
|
||||||
def copy_or_link(source, dest):
|
def copy_or_link(source, dest):
|
||||||
"""Copy or symlink source to dest."""
|
"""Copy or symlink source to dest."""
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
@ -186,15 +177,11 @@ def remove(filename):
|
|||||||
os.unlink(filename)
|
os.unlink(filename)
|
||||||
|
|
||||||
|
|
||||||
def get_venv_executable(path):
|
|
||||||
"""Get the Python executable in a virtualenv."""
|
|
||||||
subdir = 'Scripts' if os.name == 'nt' else 'bin'
|
|
||||||
return os.path.join(path, subdir, 'python')
|
|
||||||
|
|
||||||
|
|
||||||
def get_venv_lib_path(path):
|
def get_venv_lib_path(path):
|
||||||
"""Get the library path of a virtualenv."""
|
"""Get the library path of a virtualenv."""
|
||||||
return run_py(get_venv_executable(path),
|
subdir = 'Scripts' if os.name == 'nt' else 'bin'
|
||||||
|
executable = os.path.join(path, subdir, 'python')
|
||||||
|
return run_py(executable,
|
||||||
'from distutils.sysconfig import get_python_lib',
|
'from distutils.sysconfig import get_python_lib',
|
||||||
'print(get_python_lib())')
|
'print(get_python_lib())')
|
||||||
|
|
||||||
@ -213,19 +200,15 @@ def main():
|
|||||||
parser.add_argument('path', help="Base path to the venv.")
|
parser.add_argument('path', help="Base path to the venv.")
|
||||||
parser.add_argument('--tox', help="Add when called via tox.",
|
parser.add_argument('--tox', help="Add when called via tox.",
|
||||||
action='store_true')
|
action='store_true')
|
||||||
parser.add_argument('--pypi', help="Patch a PyPI-installed PyQt 5.6",
|
|
||||||
action='store_true')
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if args.pypi:
|
if args.tox:
|
||||||
patch_pypi_pyqt(args.path)
|
executable = get_tox_syspython(args.path)
|
||||||
else:
|
else:
|
||||||
if args.tox:
|
executable = sys.executable
|
||||||
executable = get_tox_syspython(args.path)
|
|
||||||
else:
|
venv_path = get_venv_lib_path(args.path)
|
||||||
executable = sys.executable
|
link_pyqt(executable, venv_path)
|
||||||
venv_path = get_venv_lib_path(args.path)
|
|
||||||
link_pyqt(executable, venv_path)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -120,13 +120,9 @@ def pytest_collection_modifyitems(config, items):
|
|||||||
_apply_platform_markers(item)
|
_apply_platform_markers(item)
|
||||||
if item.get_marker('xfail_norun'):
|
if item.get_marker('xfail_norun'):
|
||||||
item.add_marker(pytest.mark.xfail(run=False))
|
item.add_marker(pytest.mark.xfail(run=False))
|
||||||
if item.get_marker('js_prompt'):
|
if item.get_marker('js_prompt') and not config.webengine:
|
||||||
if config.webengine:
|
|
||||||
js_prompt_pyqt_version = 0x050700
|
|
||||||
else:
|
|
||||||
js_prompt_pyqt_version = 0x050300
|
|
||||||
item.add_marker(pytest.mark.skipif(
|
item.add_marker(pytest.mark.skipif(
|
||||||
PYQT_VERSION <= js_prompt_pyqt_version,
|
PYQT_VERSION <= 0x050300,
|
||||||
reason='JS prompts are not supported with this PyQt version'))
|
reason='JS prompts are not supported with this PyQt version'))
|
||||||
|
|
||||||
if deselected:
|
if deselected:
|
||||||
|
@ -197,7 +197,6 @@ Feature: Downloading things from a website.
|
|||||||
|
|
||||||
## mhtml downloads
|
## mhtml downloads
|
||||||
|
|
||||||
@qt>=5.8
|
|
||||||
Scenario: Downloading as mhtml is available
|
Scenario: Downloading as mhtml is available
|
||||||
When I open data/title.html
|
When I open data/title.html
|
||||||
And I run :download --mhtml
|
And I run :download --mhtml
|
||||||
@ -227,7 +226,6 @@ Feature: Downloading things from a website.
|
|||||||
And I wait for "File successfully written." in the log
|
And I wait for "File successfully written." in the log
|
||||||
Then the downloaded file Test title.mhtml should exist
|
Then the downloaded file Test title.mhtml should exist
|
||||||
|
|
||||||
@qt>=5.8
|
|
||||||
Scenario: Opening a mhtml download directly
|
Scenario: Opening a mhtml download directly
|
||||||
When I set storage -> prompt-download-directory to true
|
When I set storage -> prompt-download-directory to true
|
||||||
And I open html
|
And I open html
|
||||||
|
@ -80,7 +80,7 @@ Feature: Various utility commands.
|
|||||||
And I wait for the javascript message "Hello from JS!"
|
And I wait for the javascript message "Hello from JS!"
|
||||||
Then "Ignoring world ID 1" should be logged
|
Then "Ignoring world ID 1" should be logged
|
||||||
|
|
||||||
@qtwebkit_skip @pyqt>=5.7.0
|
@qtwebkit_skip
|
||||||
Scenario: :jseval uses separate world without --world
|
Scenario: :jseval uses separate world without --world
|
||||||
When I set general -> log-javascript-console to info
|
When I set general -> log-javascript-console to info
|
||||||
And I open data/misc/jseval.html
|
And I open data/misc/jseval.html
|
||||||
@ -88,14 +88,14 @@ Feature: Various utility commands.
|
|||||||
Then the javascript message "Hello from the page!" should not be logged
|
Then the javascript message "Hello from the page!" should not be logged
|
||||||
And the javascript message "Uncaught ReferenceError: do_log is not defined" should be logged
|
And the javascript message "Uncaught ReferenceError: do_log is not defined" should be logged
|
||||||
|
|
||||||
@qtwebkit_skip @pyqt>=5.7.0
|
@qtwebkit_skip
|
||||||
Scenario: :jseval using the main world
|
Scenario: :jseval using the main world
|
||||||
When I set general -> log-javascript-console to info
|
When I set general -> log-javascript-console to info
|
||||||
And I open data/misc/jseval.html
|
And I open data/misc/jseval.html
|
||||||
And I run :jseval --world 0 do_log()
|
And I run :jseval --world 0 do_log()
|
||||||
Then the javascript message "Hello from the page!" should be logged
|
Then the javascript message "Hello from the page!" should be logged
|
||||||
|
|
||||||
@qtwebkit_skip @pyqt>=5.7.0
|
@qtwebkit_skip
|
||||||
Scenario: :jseval using the main world as name
|
Scenario: :jseval using the main world as name
|
||||||
When I set general -> log-javascript-console to info
|
When I set general -> log-javascript-console to info
|
||||||
And I open data/misc/jseval.html
|
And I open data/misc/jseval.html
|
||||||
|
@ -334,9 +334,6 @@ class QuteProc(testprocess.Process):
|
|||||||
# pylint: disable=no-name-in-module,useless-suppression
|
# pylint: disable=no-name-in-module,useless-suppression
|
||||||
from PyQt5.QtWebEngineWidgets import QWebEnginePage
|
from PyQt5.QtWebEngineWidgets import QWebEnginePage
|
||||||
# pylint: enable=no-name-in-module,useless-suppression
|
# pylint: enable=no-name-in-module,useless-suppression
|
||||||
if not hasattr(QWebEnginePage, 'scrollPositionChanged'):
|
|
||||||
# Qt < 5.7
|
|
||||||
pytest.skip("QWebEnginePage.scrollPositionChanged missing")
|
|
||||||
if x is None and y is None:
|
if x is None and y is None:
|
||||||
point = 'PyQt5.QtCore.QPoint(*, *)' # not counting 0/0 here
|
point = 'PyQt5.QtCore.QPoint(*, *)' # not counting 0/0 here
|
||||||
elif x == '0' and y == '0':
|
elif x == '0' and y == '0':
|
||||||
|
@ -26,8 +26,6 @@ import collections
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from qutebrowser.utils import qtutils
|
|
||||||
|
|
||||||
|
|
||||||
def collect_tests():
|
def collect_tests():
|
||||||
basedir = os.path.dirname(__file__)
|
basedir = os.path.dirname(__file__)
|
||||||
@ -106,9 +104,6 @@ def _test_mhtml_requests(test_dir, test_path, httpbin):
|
|||||||
|
|
||||||
@pytest.mark.parametrize('test_name', collect_tests())
|
@pytest.mark.parametrize('test_name', collect_tests())
|
||||||
def test_mhtml(request, test_name, download_dir, quteproc, httpbin):
|
def test_mhtml(request, test_name, download_dir, quteproc, httpbin):
|
||||||
if not qtutils.version_check('5.7'):
|
|
||||||
pytest.skip("mhtml is unsupported with Qt < 5.7")
|
|
||||||
|
|
||||||
quteproc.set_setting('storage', 'download-directory',
|
quteproc.set_setting('storage', 'download-directory',
|
||||||
download_dir.location)
|
download_dir.location)
|
||||||
quteproc.set_setting('storage', 'prompt-download-directory', 'false')
|
quteproc.set_setting('storage', 'prompt-download-directory', 'false')
|
||||||
|
5
tox.ini
5
tox.ini
@ -66,10 +66,7 @@ passenv = {[testenv]passenv}
|
|||||||
deps =
|
deps =
|
||||||
{[testenv]deps}
|
{[testenv]deps}
|
||||||
PyQt5==5.6
|
PyQt5==5.6
|
||||||
sip==4.18.1
|
commands = {envpython} scripts/dev/run_pytest.py {posargs:tests}
|
||||||
commands =
|
|
||||||
{envpython} scripts/link_pyqt.py --pypi {envdir}
|
|
||||||
{envpython} scripts/dev/run_pytest.py {posargs:tests}
|
|
||||||
|
|
||||||
[testenv:py35-pyqt571]
|
[testenv:py35-pyqt571]
|
||||||
basepython = python3.5
|
basepython = python3.5
|
||||||
|
Loading…
Reference in New Issue
Block a user