mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Try restarting the render process on crash
Also only load the link reports web view on demand
This commit is contained in:
parent
c9b2578b33
commit
c6d6716965
@ -146,6 +146,7 @@ class Boss(QObject):
|
||||
self.gui.preview.split_start_requested.connect(self.split_start_requested)
|
||||
self.gui.preview.split_requested.connect(self.split_requested)
|
||||
self.gui.preview.link_clicked.connect(self.link_clicked)
|
||||
self.gui.preview.render_process_restarted.connect(self.report_render_process_restart)
|
||||
self.gui.check_book.item_activated.connect(self.check_item_activated)
|
||||
self.gui.check_book.check_requested.connect(self.check_requested)
|
||||
self.gui.check_book.fix_requested.connect(self.fix_requested)
|
||||
@ -170,6 +171,9 @@ class Boss(QObject):
|
||||
self.gui.reports.refresh_starting.connect(self.commit_all_editors_to_container)
|
||||
self.gui.reports.delete_requested.connect(self.delete_requested)
|
||||
|
||||
def report_render_process_restart(self):
|
||||
self.gui.show_status_message(_('The Qt WebEngine Render process crashed and has been restarted'))
|
||||
|
||||
@property
|
||||
def currently_editing(self):
|
||||
' Return the name of the file being edited currently or None if no file is being edited '
|
||||
|
@ -14,8 +14,8 @@ from functools import partial
|
||||
from threading import Thread
|
||||
|
||||
from PyQt5.Qt import (
|
||||
QApplication, QBuffer, QByteArray, QIcon, QMenu, QSize, QTimer,
|
||||
QToolBar, QUrl, QVBoxLayout, QWidget, pyqtSignal
|
||||
QApplication, QBuffer, QByteArray, QIcon, QMenu, QSize, QTimer, QToolBar, QUrl,
|
||||
QVBoxLayout, QWidget, pyqtSignal
|
||||
)
|
||||
from PyQt5.QtWebEngineCore import QWebEngineUrlSchemeHandler
|
||||
from PyQt5.QtWebEngineWidgets import (
|
||||
@ -30,7 +30,10 @@ from calibre.ebooks.oeb.base import OEB_DOCS, XHTML_MIME, serialize
|
||||
from calibre.ebooks.oeb.polish.parsing import parse
|
||||
from calibre.gui2 import NO_URL_FORMATTING, error_dialog, open_url
|
||||
from calibre.gui2.tweak_book import TOP, actions, current_container, editors, tprefs
|
||||
from calibre.gui2.webengine import create_script, insert_scripts, secure_webengine, Bridge, from_js, to_js
|
||||
from calibre.gui2.webengine import (
|
||||
Bridge, RestartingWebEngineView, create_script, from_js, insert_scripts,
|
||||
secure_webengine, to_js
|
||||
)
|
||||
from calibre.gui2.widgets2 import HistoryLineEdit2
|
||||
from calibre.utils.ipc.simple_worker import offload_worker
|
||||
from polyglot.builtins import unicode_type
|
||||
@ -325,10 +328,10 @@ class WebPage(QWebEnginePage):
|
||||
self.bridge.set_split_mode.emit(1 if enabled else 0)
|
||||
|
||||
|
||||
class WebView(QWebEngineView):
|
||||
class WebView(RestartingWebEngineView):
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWebEngineView.__init__(self, parent)
|
||||
RestartingWebEngineView.__init__(self, parent)
|
||||
self.inspector = QWebEngineView(self)
|
||||
w = QApplication.instance().desktop().availableGeometry(self).width()
|
||||
self._size_hint = QSize(int(w/3), int(w/2))
|
||||
@ -337,12 +340,13 @@ class WebView(QWebEngineView):
|
||||
self.setPage(self._page)
|
||||
self.clear()
|
||||
self.setAcceptDrops(False)
|
||||
self.renderProcessTerminated.connect(self.render_process_terminated)
|
||||
self.render_process_failed.connect(self.render_process_died)
|
||||
|
||||
def render_process_terminated(self):
|
||||
def render_process_died(self):
|
||||
error_dialog(self, _('Render process crashed'), _(
|
||||
'The Qt WebEngine Render process has crashed so Preview/Live css'
|
||||
' will not work. You should try restarting the editor.'), show=True)
|
||||
'The Qt WebEngine Render process has crashed so Preview/Live css will not work.'
|
||||
' You should try restarting the editor.')
|
||||
, show=True)
|
||||
|
||||
def sizeHint(self):
|
||||
return self._size_hint
|
||||
@ -393,6 +397,7 @@ class Preview(QWidget):
|
||||
link_clicked = pyqtSignal(object, object)
|
||||
refresh_starting = pyqtSignal()
|
||||
refreshed = pyqtSignal()
|
||||
render_process_restarted = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWidget.__init__(self, parent)
|
||||
@ -403,6 +408,7 @@ class Preview(QWidget):
|
||||
self.view._page.bridge.request_sync.connect(self.request_sync)
|
||||
self.view._page.bridge.request_split.connect(self.request_split)
|
||||
self.view._page.loadFinished.connect(self.load_finished)
|
||||
self.view.render_process_restarted.connect(self.render_process_restarted)
|
||||
self.pending_go_to_anchor = None
|
||||
self.inspector = self.view.inspector
|
||||
l.addWidget(self.view)
|
||||
|
@ -21,7 +21,6 @@ from PyQt5.Qt import (
|
||||
QStyledItemDelegate, QModelIndex, QRect, QStyle, QPalette, QTimer, QMenu,
|
||||
QAbstractItemModel, QTreeView, QFont, QRadioButton, QHBoxLayout,
|
||||
QFontDatabase, QComboBox, QUrl)
|
||||
from PyQt5.QtWebEngineWidgets import QWebEngineView
|
||||
|
||||
from calibre import human_readable, fit_image
|
||||
from calibre.constants import DEBUG
|
||||
@ -29,7 +28,7 @@ from calibre.ebooks.oeb.polish.report import (
|
||||
gather_data, CSSEntry, CSSFileMatch, MatchLocation, ClassEntry,
|
||||
ClassFileMatch, ClassElement, CSSRule, LinkLocation)
|
||||
from calibre.gui2 import error_dialog, question_dialog, choose_save_file, open_url
|
||||
from calibre.gui2.webengine import secure_webengine
|
||||
from calibre.gui2.webengine import secure_webengine, RestartingWebEngineView
|
||||
from calibre.gui2.tweak_book import current_container, tprefs, dictionaries
|
||||
from calibre.gui2.tweak_book.widgets import Dialog
|
||||
from calibre.gui2.progress_indicator import ProgressIndicator
|
||||
@ -578,7 +577,7 @@ class LinksModel(FileCollection):
|
||||
pass
|
||||
|
||||
|
||||
class WebView(QWebEngineView):
|
||||
class WebView(RestartingWebEngineView):
|
||||
|
||||
def sizeHint(self):
|
||||
return QSize(600, 200)
|
||||
@ -604,11 +603,8 @@ class LinksWidget(QWidget):
|
||||
e.textChanged.connect(f.proxy.filter_text)
|
||||
s.addWidget(f)
|
||||
self.links.restore_table('links-table', sort_column=1)
|
||||
self.view = WebView(self)
|
||||
secure_webengine(self.view)
|
||||
self.view = None
|
||||
self.setContextMenuPolicy(Qt.NoContextMenu)
|
||||
self.view.setContextMenuPolicy(Qt.NoContextMenu)
|
||||
s.addWidget(self.view)
|
||||
self.ignore_current_change = False
|
||||
self.current_url = None
|
||||
f.current_changed.connect(self.current_changed)
|
||||
@ -616,10 +612,16 @@ class LinksWidget(QWidget):
|
||||
s.restoreState(read_state('links-view-splitter'))
|
||||
except TypeError:
|
||||
pass
|
||||
s.setCollapsible(0, False), s.setCollapsible(1, True)
|
||||
s.setCollapsible(0, False)
|
||||
s.setStretchFactor(0, 10)
|
||||
|
||||
def __call__(self, data):
|
||||
if self.view is None:
|
||||
self.view = WebView(self)
|
||||
secure_webengine(self.view)
|
||||
self.view.setContextMenuPolicy(Qt.NoContextMenu)
|
||||
self.splitter.addWidget(self.view)
|
||||
self.splitter.setCollapsible(1, True)
|
||||
self.ignore_current_change = True
|
||||
self.model(data)
|
||||
self.filter_edit.clear()
|
||||
@ -644,11 +646,13 @@ class LinksWidget(QWidget):
|
||||
if link.anchor.id:
|
||||
url.setFragment(link.anchor.id)
|
||||
if url is None:
|
||||
self.view.setHtml('<p>' + _('No destination found for this link'))
|
||||
if self.view:
|
||||
self.view.setHtml('<p>' + _('No destination found for this link'))
|
||||
self.current_url = url
|
||||
elif url != self.current_url:
|
||||
self.current_url = url
|
||||
self.view.setUrl(url)
|
||||
if self.view:
|
||||
self.view.setUrl(url)
|
||||
|
||||
def double_clicked(self, index):
|
||||
link = index.data(Qt.UserRole)
|
||||
|
@ -6,10 +6,11 @@ from __future__ import absolute_import, division, print_function, unicode_litera
|
||||
|
||||
import json
|
||||
|
||||
from PyQt5.Qt import QObject, pyqtSignal
|
||||
from PyQt5.Qt import QObject, Qt, pyqtSignal
|
||||
from PyQt5.QtWebEngineWidgets import QWebEngineScript, QWebEngineView
|
||||
|
||||
from calibre import prints
|
||||
from calibre.utils.monotonic import monotonic
|
||||
from calibre.utils.rapydscript import special_title
|
||||
|
||||
|
||||
@ -125,6 +126,27 @@ class Bridge(QObject):
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
class RestartingWebEngineView(QWebEngineView):
|
||||
|
||||
render_process_restarted = pyqtSignal()
|
||||
render_process_failed = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QWebEngineView.__init__(self, parent)
|
||||
self._last_reload_at = None
|
||||
self.renderProcessTerminated.connect(self.render_process_terminated)
|
||||
self.render_process_restarted.connect(self.reload, type=Qt.QueuedConnection)
|
||||
|
||||
def render_process_terminated(self):
|
||||
if self._last_reload_at is not None and monotonic() - self._last_reload_at < 2:
|
||||
self.render_process_failed.emit()
|
||||
print('The Qt WebEngine Render process crashed too often')
|
||||
else:
|
||||
self._last_reload_at = monotonic()
|
||||
self.render_process_restarted.emit()
|
||||
prints('The Qt WebEngine Render process crashed, restarting it')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from calibre.gui2 import Application
|
||||
from calibre.gui2.tweak_book.preview import WebPage
|
||||
|
Loading…
x
Reference in New Issue
Block a user