fix: Wonder Ink prints without crashing, and prints worksheets at all

Little Waders, 0.2.2: SIGSEGV in QPrinter::resolution() every time a
teacher confirmed a print job. QWebEngineView.print() keeps the raw
QPrinter pointer and returns; Qt's didPrintPage() reads
printer->resolution() once Chromium has rendered the page, and by then
PyQt had deleted the printer, which print_view() held only as a local.
Reproduced in the lab with the 0.2.2 code, same backtrace, no job.

Keeping the printer alive fixed the crash and was measured, and Qt's
path was still not a print path: a worksheet PDF tab printed as one
blank page, a lesson went as 24.6 MB of 300 dpi pictures with no text,
and a queue refusing jobs was reported as printed.

Print is now: make a PDF (a worksheet already is one; a lesson page is
printToPdf'd onto the printer's own paper; an inline PDF is downloaded
and opened as a worksheet), show it in a preview with printer, pages,
copies and colour, and hand it to CUPS with lp — Chrome's route in the
same rooms. Nothing asynchronous holds a printer. Black and white uses
the driver's ColorModel=Grayscale, because Elmer's generic PCL 6 driver
ignores print-color-mode.

An exception escaping any slot no longer aborts Wonder Ink: PyQt6's
default is to kill the process, and it is now logged instead.

tests/test-classroom-printing.sh: 50 checks. tools/lab/wonderink-print-
check: 39 checks over 13 scenarios in the lab, against a queue built
from Elmer's PPD, judged by what CUPS received. Not yet on paper.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
ekklesia
2026-09-23 18:36:29 -05:00
co-authored by Claude Opus 5.5
parent 690ef95aff
commit 10433b850d
8 changed files with 1356 additions and 32 deletions
+10 -3
View File
@@ -342,8 +342,11 @@ check("local documents may not read other local documents",
"LocalContentCanAccessFileUrls, False" in wonderink)
check("nor reach the network",
"LocalContentCanAccessRemoteUrls, False" in wonderink)
check("there is no file chooser behind the print dialog",
"PrintDialogOption.PrintToFile, False" in wonderink)
# Qt's print dialog has a Print to File path with a "..." chooser behind
# it. Wonder Ink no longer uses that dialog: its preview offers CUPS
# printers and nothing else, and no file dialog exists anywhere in it.
check("there is no file chooser behind printing",
"QFileDialog" not in wonderink and "QPrintDialog" not in wonderink)
check("nothing downloaded is executed",
"subprocess" not in wonderink.split("def notify")[0]
and "QDesktopServices" not in wonderink
@@ -374,8 +377,12 @@ check("the Present-view autoplay fix is still there",
"PlaybackRequiresUserGesture, False" in wonderink)
check("fullscreen still returns to a maximised window",
"WindowFullScreen" in wonderink)
# One text box exists, and it is the print preview's page range. Anywhere
# else a text box in this window is an address bar.
preview = wonderink[wonderink.index("class PrintPreview"):wonderink.index("\ndef notify")]
check("still no new-tab button or address bar",
"setCornerWidget" not in wonderink and "QLineEdit" not in wonderink)
"setCornerWidget" not in wonderink
and wonderink.count("QLineEdit(") == 1 and "QLineEdit(" in preview)
print()
print("7b. the disc player is decided before a session starts")