fix: Autoklicker wartet auf Ubiquitys Hintergrundpruefung statt sie zu unterbrechen
Timing-Hypothese fuer den partman-rebuild-cache-Loop: der $bootable{}-Fix
brachte live keine Aenderung (siehe ADR-0023-Nachtrag), was gegen einen
rein rezeptseitigen Fehler spricht. Stattdessen zeigt die 'Etwas
Anderes'-Seite waehrend der Klickphase ein Status-Panel 'Konfiguration
der Installation wird ueberprueft ...' - ein Klick auf 'Jetzt
installieren' WAEHREND dieser Pruefung noch laeuft koennte sie
unterbrechen/neu anstossen statt sie abschliessen zu lassen.
atspi_click.py sucht jetzt vor jedem Klickversuch aktiv nach diesem
sichtbaren Text (find_showing_text(), rollenunabhaengig) und gibt bei
Treffer Exit-Code 3 zurueck, ohne zu klicken. autoclicker.sh behandelt
das als eigenen, nicht als Fehlversuch gezaehlten Zustand.
Noch nicht live verifiziert - naechster Schritt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
2e68dbea71
commit
4bf1992eb9
@ -30,10 +30,29 @@ Sprache ist durch "debian-installer/language=de" im Kexec-Append-Preseed
|
|||||||
grundsaetzlich auf de_DE gesetzt (siehe backend.sh), s.o. aber nicht
|
grundsaetzlich auf de_DE gesetzt (siehe backend.sh), s.o. aber nicht
|
||||||
verlaesslich fuer jede einzelne Seite.
|
verlaesslich fuer jede einzelne Seite.
|
||||||
|
|
||||||
|
NACHTRAG (real beim Testen entdeckt, 29.08.2026): auf der manuellen
|
||||||
|
Partitionierungsseite ("Etwas Anderes") lief der Klick auf "Jetzt
|
||||||
|
installieren" nachweislich zuverlaessig (AT-SPI meldete jedes Mal Erfolg),
|
||||||
|
aber die Seite kam nie voran - stattdessen loeste jeder Klick erneut die
|
||||||
|
Debconf-Frage "ubiquity/partman-rebuild-cache" aus
|
||||||
|
(/lib/partman/update.d/99signal_ubiquity), was ubi-partman.py zurueck auf
|
||||||
|
dieselbe Seite wirft (siehe ADR-0023-Nachtrag). Ein gezielter Fix am
|
||||||
|
Partitionsrezept (kein zusaetzliches $bootable{ } auf der Root-Partition
|
||||||
|
unter UEFI) aenderte NICHTS - das deutet auf einen zeitlichen statt
|
||||||
|
strukturellen Fehler hin: die Seite zeigt waehrend dieser Phase ein
|
||||||
|
Status-Panel "Konfiguration der Installation wird ueberprueft ..." - klickt
|
||||||
|
der Autoklicker WAEHREND dieser Hintergrundpruefung noch laeuft, koennte
|
||||||
|
er sie unterbrechen/neu anstossen, statt ihr Zeit zum Abschliessen zu
|
||||||
|
geben. Dieses Skript wartet deshalb jetzt aktiv, solange dieser Text
|
||||||
|
sichtbar ist (siehe VALIDATION_TEXT_MARKERS/find_showing_text()), und
|
||||||
|
klickt erst, wenn er verschwunden ist.
|
||||||
|
|
||||||
Exit-Codes: 0 = ein Button wurde gefunden und geklickt,
|
Exit-Codes: 0 = ein Button wurde gefunden und geklickt,
|
||||||
1 = kein eindeutiger Button gefunden (z.B. Seite im Ladezustand, oder echte
|
1 = kein eindeutiger Button gefunden (z.B. Seite im Ladezustand, oder echte
|
||||||
Mehrdeutigkeit - dann bewusst NICHT geklickt, siehe select_target()),
|
Mehrdeutigkeit - dann bewusst NICHT geklickt, siehe select_target()),
|
||||||
2 = pyatspi/AT-SPI-Bus nicht erreichbar (Bruecke evtl. nicht aktiv).
|
2 = pyatspi/AT-SPI-Bus nicht erreichbar (Bruecke evtl. nicht aktiv),
|
||||||
|
3 = Ubiquitys eigene Hintergrundpruefung laeuft noch sichtbar - bewusst
|
||||||
|
nicht geklickt, siehe Nachtrag oben.
|
||||||
"""
|
"""
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -88,6 +107,52 @@ PREFER_LABELS = {
|
|||||||
|
|
||||||
MAX_DEPTH = 40
|
MAX_DEPTH = 40
|
||||||
|
|
||||||
|
# Zweisprachig vorsichtshalber (siehe Multimedia-Codecs-Erfahrung oben),
|
||||||
|
# auch wenn dieser konkrete Text bisher immer deutsch beobachtet wurde.
|
||||||
|
VALIDATION_TEXT_MARKERS = (
|
||||||
|
"wird überprüft",
|
||||||
|
"wird ueberprueft",
|
||||||
|
"being checked",
|
||||||
|
"checking the install",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def find_showing_text(node, needle, depth=0):
|
||||||
|
"""Sucht ein sichtbares Accessible, dessen Name ODER Beschreibung den
|
||||||
|
Suchtext enthaelt - unabhaengig von seiner Rolle (Label/Expander/...),
|
||||||
|
da Ubiquitys Status-Panel-Text nicht zuverlaessig unter derselben Rolle
|
||||||
|
exponiert sein muss. Bei Unsicherheit ueber den Sichtbarkeitsstatus
|
||||||
|
bewusst konservativ (lieber einen Zyklus zu viel warten als einen
|
||||||
|
Klick mitten in die Pruefung setzen)."""
|
||||||
|
if node is None or depth > MAX_DEPTH:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
name = (node.name or "").strip().lower()
|
||||||
|
except Exception:
|
||||||
|
name = ""
|
||||||
|
try:
|
||||||
|
desc = (node.description or "").strip().lower()
|
||||||
|
except Exception:
|
||||||
|
desc = ""
|
||||||
|
if needle in name or needle in desc:
|
||||||
|
try:
|
||||||
|
state = node.getState()
|
||||||
|
return state.contains(pyatspi.STATE_SHOWING)
|
||||||
|
except Exception:
|
||||||
|
return True
|
||||||
|
try:
|
||||||
|
count = node.childCount
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
for i in range(count):
|
||||||
|
try:
|
||||||
|
child = node.getChildAtIndex(i)
|
||||||
|
except Exception:
|
||||||
|
continue
|
||||||
|
if find_showing_text(child, needle, depth + 1):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def collect_buttons(node, depth=0, acc=None):
|
def collect_buttons(node, depth=0, acc=None):
|
||||||
"""Alle sichtbaren+aktivierten Push-Buttons im Baum einsammeln (Rolle,
|
"""Alle sichtbaren+aktivierten Push-Buttons im Baum einsammeln (Rolle,
|
||||||
@ -171,14 +236,26 @@ def main():
|
|||||||
print(f"AT-SPI-Desktop nicht erreichbar: {exc}", file=sys.stderr)
|
print(f"AT-SPI-Desktop nicht erreichbar: {exc}", file=sys.stderr)
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
all_buttons = []
|
apps = []
|
||||||
for i in range(desktop.childCount):
|
for i in range(desktop.childCount):
|
||||||
try:
|
try:
|
||||||
app = desktop.getChildAtIndex(i)
|
app = desktop.getChildAtIndex(i)
|
||||||
except Exception:
|
except Exception:
|
||||||
continue
|
continue
|
||||||
if app is None:
|
if app is not None:
|
||||||
continue
|
apps.append(app)
|
||||||
|
|
||||||
|
for marker in VALIDATION_TEXT_MARKERS:
|
||||||
|
for app in apps:
|
||||||
|
if find_showing_text(app, marker):
|
||||||
|
print(
|
||||||
|
f"Hintergrundpruefung noch sichtbar ('{marker}'), warte statt zu klicken.",
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
return 3
|
||||||
|
|
||||||
|
all_buttons = []
|
||||||
|
for app in apps:
|
||||||
collect_buttons(app, 0, all_buttons)
|
collect_buttons(app, 0, all_buttons)
|
||||||
|
|
||||||
target = select_target(all_buttons)
|
target = select_target(all_buttons)
|
||||||
|
|||||||
@ -97,6 +97,13 @@ while [ "${SECONDS}" -lt "${end}" ]; do
|
|||||||
elif [ "${rc}" -eq 2 ]; then
|
elif [ "${rc}" -eq 2 ]; then
|
||||||
log "AT-SPI-Bus nicht erreichbar, breche ab: ${out}"
|
log "AT-SPI-Bus nicht erreichbar, breche ab: ${out}"
|
||||||
break
|
break
|
||||||
|
elif [ "${rc}" -eq 3 ]; then
|
||||||
|
# Ubiquitys eigene Hintergrundpruefung laeuft noch sichtbar (siehe
|
||||||
|
# atspi_click.py-Nachtrag) - bewusst NICHT als Fehlversuch zaehlen,
|
||||||
|
# nur abwarten. Real beim Testen entdeckt: ein Klick auf "Jetzt
|
||||||
|
# installieren" WAEHREND dieser Pruefung fuehrte wiederholt in die
|
||||||
|
# partman-rebuild-cache-Schleife statt zum eigentlichen Commit.
|
||||||
|
log "wartet auf Hintergrundpruefung: ${out}"
|
||||||
else
|
else
|
||||||
misses=$((misses + 1))
|
misses=$((misses + 1))
|
||||||
log "kein Treffer (${misses}): ${out}"
|
log "kein Treffer (${misses}): ${out}"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user