fix(bureau): affiche les PDF et conserve les réglages dans la fenêtre native

Deux réglages du moteur manquaient pour que l'aperçu fonctionne hors
navigateur, tous deux constatés en lançant la fenêtre native.

Qt WebEngine laisse PdfViewerEnabled à False et le conditionne à
PluginsEnabled : le volet n'affichait qu'un bouton « Ouvrir » au lieu du
document. pywebview n'expose pas ces attributs et construit son propre
profil, donc on les pose sur la vue au chargement de la fenêtre — bien
avant qu'un document, et donc une <iframe>, soit ouvert. Sans objet sous
Windows, où WebView2 embarque déjà son lecteur.

pywebview démarre par ailleurs en mode privé, sur un profil éphémère qui
ne conserve ni cookies ni localStorage. L'interface y range la largeur du
volet d'aperçu, et le lecteur PDF du moteur y garde l'état de sa barre
latérale de vignettes : les deux se seraient réinitialisés à chaque
lancement. L'application ne charge que son propre serveur local, rien de
tiers n'est stocké au passage.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-22 21:09:56 +02:00
parent 552fc453dd
commit 24db55c46c

View File

@@ -51,6 +51,32 @@ def _wait_until_ready(base_url: str, timeout: float = 30.0) -> bool:
return False
def _activer_lecteur_pdf_qt() -> None:
"""Active le lecteur PDF interne de Qt WebEngine (backend Linux).
L'aperçu du compte rendu s'appuie sur le lecteur PDF du moteur, via une
``<iframe>``. Qt laisse ``PdfViewerEnabled`` à False et le conditionne à
``PluginsEnabled`` : sans les deux, le volet n'affiche qu'un bouton
« Ouvrir » au lieu du document. pywebview n'expose pas ces réglages et
construit son propre profil, donc on les pose sur la vue une fois la
fenêtre chargée — l'``<iframe>`` n'apparaît qu'à l'ouverture d'un document,
donc bien après.
Sans objet sous Windows (WebView2 embarque déjà son lecteur) ; l'appel y
est neutre puisque le backend Qt n'est alors pas importé.
"""
try:
from webview.platforms.qt import BrowserView, QWebEngineSettings
except ImportError:
return
attribut = QWebEngineSettings.WebAttribute
for fenetre in BrowserView.instances.values():
reglages = fenetre.webview.page().settings()
reglages.setAttribute(attribut.PluginsEnabled, True)
reglages.setAttribute(attribut.PdfViewerEnabled, True)
def run() -> None:
"""Lance le serveur puis la fenêtre native. Bloque jusqu'à fermeture."""
port = _find_free_port()
@@ -75,9 +101,16 @@ def run() -> None:
# clic droit -> « Inspecter » (ou « Inspect element ») pour ouvrir la console.
debug = os.environ.get("PLESNA_DEBUG", "").lower() in ("1", "true", "yes")
webview.create_window(WINDOW_TITLE, base_url, width=1280, height=860)
fenetre = webview.create_window(WINDOW_TITLE, base_url, width=1280, height=860)
fenetre.events.loaded += _activer_lecteur_pdf_qt
try:
webview.start(debug=debug)
# private_mode=False : pywebview part sinon sur un profil éphémère qui
# ne conserve ni cookies ni localStorage. Or l'interface y range ses
# réglages — largeur du volet d'aperçu — et le lecteur PDF du moteur y
# garde l'état de sa barre latérale de vignettes. En mode privé, tout
# cela se réinitialise à chaque lancement. L'application ne charge que
# son propre serveur local : rien de tiers n'est stocké au passage.
webview.start(debug=debug, private_mode=False)
finally:
# Fermeture de la fenêtre -> arrêt propre du serveur.
server.should_exit = True