From bd45ffea17c2c773b7202d9387f22fa3d19ca7a7 Mon Sep 17 00:00:00 2001 From: Handy-Insel Date: Mon, 2 Nov 2026 11:33:54 +0100 Subject: [PATCH] =?UTF-8?q?Alt+F4=20bei=20gerade=20ge=C3=B6ffnetem=20Dialo?= =?UTF-8?q?g=20schlie=C3=9Ft=20nicht=20mehr=20das=20Programm?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auf dem langsameren Build-Runner schlug der Alt+F4-Test fehl: Kam der Tastendruck an, bevor der Dialog gezeichnet und gesperrt war, übersah die Ausweichsuche das Popup (winfo_ismapped = 0) und Alt+F4 galt dem Hauptfenster. Die Suche nutzt jetzt den Fensterstatus. Neuer Test erzwingt genau diesen Zustand plattformunabhängig. Co-Authored-By: Claude Opus 5.5 --- provtool/__init__.py | 2 +- provtool/gui/rahmen.py | 11 +++++++++-- tests/test_gui.py | 20 ++++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/provtool/__init__.py b/provtool/__init__.py index 5f80904..abffec8 100644 --- a/provtool/__init__.py +++ b/provtool/__init__.py @@ -1,5 +1,5 @@ """Provisions-Manager 95 – Provisionsabrechnung für Unterhändler der Handy-Insel Miesbach.""" -__version__ = "1.1.2" +__version__ = "1.1.3" APP_NAME = "Provisions-Manager 95" APP_ORG = "Handy-Insel Miesbach" diff --git a/provtool/gui/rahmen.py b/provtool/gui/rahmen.py index a40a529..183d16f 100644 --- a/provtool/gui/rahmen.py +++ b/provtool/gui/rahmen.py @@ -288,8 +288,15 @@ class Hauptrahmen: def suche(widget): for kind in widget.winfo_children(): - if isinstance(kind, tk.Toplevel) and hasattr(kind, "abbrechen") and kind.winfo_ismapped(): - gefunden.append(kind) + # Fensterstatus statt winfo_ismapped(): direkt nach dem Einblenden ist der Status schon + # „normal“, gezeichnet ist das Fenster aber evtl. noch nicht (langsamer PC, Wine). + if isinstance(kind, tk.Toplevel) and hasattr(kind, "abbrechen"): + try: + offen = kind.winfo_exists() and kind.wm_state() != "withdrawn" + except tk.TclError: + offen = False + if offen: + gefunden.append(kind) suche(kind) suche(self.root) return gefunden[-1] if gefunden else None diff --git a/tests/test_gui.py b/tests/test_gui.py index 6c2437f..97a9b57 100644 --- a/tests/test_gui.py +++ b/tests/test_gui.py @@ -298,6 +298,26 @@ def test_schliessen_waehrend_rundgang(lauf_mit_daten): lauf.pruefen() +def test_alt_f4_bevor_die_sperre_steht(lauf_mit_daten, monkeypatch): + """Erzwingt den Zustand vom langsamen Build-Rechner: Dialog ist offen, aber Tk-Sperre und + Zeichnen sind noch nicht fertig. Alt+F4 muss trotzdem nur den Dialog schließen.""" + from provtool.gui import win95 as w + from provtool.gui.dialogs import InfoDialog + monkeypatch.setattr(w.Dialog, "_sperre_setzen", lambda self, versuch=0: None) # keine Sperre + monkeypatch.setattr(w.Dialog, "winfo_ismapped", lambda self: 0) # „noch nicht gezeichnet“ + lauf = lauf_mit_daten + lauf.ablauf([ + (IMMER, lambda: InfoDialog(lauf.root).zeigen(), "Info öffnen"), + # wie unter Windows: Tk liefert den Tastendruck an das Fenster mit Fokus – hier noch das Hauptfenster + (lambda: lauf.dialog(InfoDialog) is not None, lambda: lauf.app.rahmen.alt_f4(lauf.root), + "Alt+F4 (Fokus noch beim Hauptfenster)"), + (lambda: lauf.dialog(InfoDialog) is None, lambda: None, "Dialog geschlossen"), + ], sekunden=8) + assert lauf.lebt, "Alt+F4 darf bei offenem Dialog nicht das ganze Programm beenden" + assert not lauf.uebrig, lauf.uebrig + lauf.pruefen() + + def test_alt_f4_im_rundgang_beendet_nur_den_rundgang(lauf_mit_daten): lauf = lauf_mit_daten rg = lambda: getattr(lauf.app, "_rundgang", None) # noqa: E731