From 79b39d8c7f68a998c7b1332a5a10a1a8cc281e90 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Mon, 16 Jul 2018 08:16:18 +0200 Subject: Refactor print handling and fix window.print On Qt 5.7.1, window.print() caused a CommandError which wasn't handled as the command was called from accept_navigation_request. Instead, we now show the dialog in AbstractPrinting and use that directly. (cherry picked from commit 9298f3d055d6cfa73fba9f326ca7d80520276899) --- qutebrowser/browser/browsertab.py | 29 ++++++++++++++++-- qutebrowser/browser/commands.py | 42 +++++---------------------- qutebrowser/browser/webengine/webenginetab.py | 10 +++---- qutebrowser/browser/webkit/webkittab.py | 2 +- 4 files changed, 40 insertions(+), 43 deletions(-) diff --git a/qutebrowser/browser/browsertab.py b/qutebrowser/browser/browsertab.py index 0170b4627..9a2d13242 100644 --- a/qutebrowser/browser/browsertab.py +++ b/qutebrowser/browser/browsertab.py @@ -25,7 +25,8 @@ import itertools import attr from PyQt5.QtCore import pyqtSignal, pyqtSlot, QUrl, QObject, QSizeF, Qt from PyQt5.QtGui import QIcon -from PyQt5.QtWidgets import QWidget, QApplication +from PyQt5.QtWidgets import QWidget, QApplication, QDialog +from PyQt5.QtPrintSupport import QPrintDialog import pygments import pygments.lexers @@ -187,8 +188,9 @@ class AbstractPrinting: """Attribute of AbstractTab for printing the page.""" - def __init__(self): + def __init__(self, tab): self._widget = None + self._tab = tab def check_pdf_support(self): raise NotImplementedError @@ -212,6 +214,29 @@ class AbstractPrinting: """ raise NotImplementedError + def show_dialog(self): + """Print with a QPrintDialog.""" + self.check_printer_support() + + def print_callback(ok): + """Called when printing finished.""" + if not ok: + message.error("Printing failed!") + diag.deleteLater() + + def do_print(): + """Called when the dialog was closed.""" + self.to_printer(diag.printer(), print_callback) + + diag = 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: + do_print() + else: + diag.open(do_print) + class AbstractSearch(QObject): diff --git a/qutebrowser/browser/commands.py b/qutebrowser/browser/commands.py index 0fddcd1e7..6578e4bb7 100644 --- a/qutebrowser/browser/commands.py +++ b/qutebrowser/browser/commands.py @@ -25,9 +25,9 @@ import shlex import functools import typing -from PyQt5.QtWidgets import QApplication, QTabBar, QDialog +from PyQt5.QtWidgets import QApplication, QTabBar from PyQt5.QtCore import pyqtSlot, Qt, QUrl, QEvent, QUrlQuery -from PyQt5.QtPrintSupport import QPrintDialog, QPrintPreviewDialog +from PyQt5.QtPrintSupport import QPrintPreviewDialog from qutebrowser.commands import userscripts, cmdexc, cmdutils, runners from qutebrowser.config import config, configdata @@ -415,27 +415,6 @@ class CommandDispatcher: tab.printing.to_pdf(filename) log.misc.debug("Print to file: {}".format(filename)) - def _print(self, tab): - """Print with a QPrintDialog.""" - def print_callback(ok): - """Called when printing finished.""" - if not ok: - message.error("Printing failed!") - diag.deleteLater() - - def do_print(): - """Called when the dialog was closed.""" - tab.printing.to_printer(diag.printer(), print_callback) - - diag = QPrintDialog(tab) - if utils.is_mac: - # For some reason we get a segfault when using open() on macOS - ret = diag.exec_() - if ret == QDialog.Accepted: - do_print() - else: - diag.open(do_print) - @cmdutils.register(instance='command-dispatcher', name='print', scope='window') @cmdutils.argument('count', count=True) @@ -453,22 +432,15 @@ class CommandDispatcher: return try: - if pdf: - tab.printing.check_pdf_support() - else: - tab.printing.check_printer_support() if preview: - tab.printing.check_preview_support() + self._print_preview(tab) + elif pdf: + self._print_pdf(tab, pdf) + else: + tab.printing.show_dialog() except browsertab.WebTabError as e: raise cmdexc.CommandError(e) - if preview: - self._print_preview(tab) - elif pdf: - self._print_pdf(tab, pdf) - else: - self._print(tab) - @cmdutils.register(instance='command-dispatcher', scope='window') def tab_clone(self, bg=False, window=False): """Duplicate the current tab. diff --git a/qutebrowser/browser/webengine/webenginetab.py b/qutebrowser/browser/webengine/webenginetab.py index 9f840b715..9bc246107 100644 --- a/qutebrowser/browser/webengine/webenginetab.py +++ b/qutebrowser/browser/webengine/webenginetab.py @@ -976,7 +976,7 @@ class WebEngineTab(browsertab.AbstractTab): tab=self, parent=self) self.zoom = WebEngineZoom(tab=self, parent=self) self.search = WebEngineSearch(parent=self) - self.printing = WebEnginePrinting() + self.printing = WebEnginePrinting(tab=self) self.elements = WebEngineElements(tab=self) self.action = WebEngineAction(tab=self) self.audio = WebEngineAudio(parent=self) @@ -1315,10 +1315,10 @@ class WebEngineTab(browsertab.AbstractTab): super()._on_navigation_request(navigation) if navigation.url == QUrl('qute://print'): - command_dispatcher = objreg.get('command-dispatcher', - scope='window', - window=self.win_id) - command_dispatcher.printpage() + try: + self.printing.show_dialog() + except browsertab.WebTabError as e: + message.error(str(e)) navigation.accepted = False if not navigation.accepted or not navigation.is_main_frame: diff --git a/qutebrowser/browser/webkit/webkittab.py b/qutebrowser/browser/webkit/webkittab.py index 31cb82f29..7b7ad0c7d 100644 --- a/qutebrowser/browser/webkit/webkittab.py +++ b/qutebrowser/browser/webkit/webkittab.py @@ -658,7 +658,7 @@ class WebKitTab(browsertab.AbstractTab): tab=self, parent=self) self.zoom = WebKitZoom(tab=self, parent=self) self.search = WebKitSearch(parent=self) - self.printing = WebKitPrinting() + self.printing = WebKitPrinting(tab=self) self.elements = WebKitElements(tab=self) self.action = WebKitAction(tab=self) self.audio = WebKitAudio(parent=self) -- cgit v1.2.3-54-g00ecf