Der Traum vom Screenreader, der uns passend zu unserer Aufgabe optimal mit Informationen versorgt

In meinem Artikel zu Screenreadern im Wandel der zeit habe ich diskutiert, warum viele der Werkzeuge und funktionen ohne Offscreen-Modell nicht fnktionieren können. Diese Werkzeuge wurden und werden vor allem gebraucht, um die Screenreader für Anwendungen anzupassen. Durch die Aufsplittung der Informationen in einen Baum, der von einer Anwendung gefüllt wird, muss für den Anwender wieder ein sinnvolles Modell zusammengesetzt werden. Gleichzeitig ergibt sich die chance, dass durch eine gute Unterstützung einer Anwendung sich ein sehr hochwertiges Informationsmodell beschaffen läßt – nur leider nicht in der Form, die der Anwender braucht.

Deshalb will ich versuchen Konzepte und Vorschläge zu entwickeln, die diese Modelltransformation leisten können.

== Ideen zum Transformieren des Objektbaums ==
Vorausgesetzt wird, dass der Baum mit sinnvollen und korrekten Informationen gefüllt ist. Dies liegt in der Verantwortung einer Anwendung, die dies wiederum im Wesentlichen durch ihr Framework erledigen läßt. Ohne eine solche Grundlage, können wir beim besten Willen kein sinnvolles Modell erstellen. Damit ist bereits klar erkennbar, welche objekte welche Rollen spielen und welche Status sie haben. Man könnte sagen, wie haben ein zerlegtes aber vermutlich vollständiges Puzzle. Die Aufgabe besteht nun darin, die Teile richtig zusammenzusetzen. OK, aber was heißt richtig? Nun, das ist dummerweise abhängig von der Anwendung, dem Anwender und manchmal auch von der Aufgabe, die der Anwender erledigen möchte. Klingt nicht wirklich ermutigend oder? Aber es bleibt uns keine andere Wahl. Zurück zum Off-Screen-Modell wird es vorerst nicht geben. Zum Vergleich: Im Offscreenmodell sind die Informationen so wie auf dem Schirm angeordnet, sodass ein Eingabefeld oder Listenelement dem links davon stehenden Bezeichner zugeordnet werden kann.

=== Zusammensetzen der Bildschrimdarstellung ===
Es gibt allerdings ein wenig Hilfe beim zusammensetzen des Puzzles zumindest so, wie es die Anwender auf dem Schirm stehen. Jedes Objekt aus dem Objektbaum ist an ein Fenster gekoppelt. Mehrere Objekte können dabei zu einem Fenster gehören und ein Fenster, das einem Objekt zugeordnet ist, kann untergeordnete Fenster haben, die selbtst keine Objekte besitzen. Außerdem gibt es aber auch komplexe Steuerelemente, die keine von Windows erstellten Unterfenster haben und keine passenden untergeordneten Objekte. Aber immerhin stimmen bei den Objewkten, die einem Fenster klar zuzuordnen sind, wohl die Positionsangaben. Es sind nämlich die Koordinaten des Fensters. Gleichzeitig können wir über Windows die Fensterhierarchie auslesen und wissen somit, wie die Objekte in der Anwendung strukturiert sind. Oft werden die Hierarchien aus Objektbaum und Fenstern ähnlich sein, aber verlassen können wir uns darauf vermutlich nicht.

Wenn wir die Positionen der Objekte bzw. Fenster haben, dann können wir sie auf einem virtuellen Arbeitsblatt so positionieren, wie sie auf dem Bildschirm angezeigt werden. Das ist zwar nicht ganz exakt – z.B. gehen Textumbrüche verloren und wir können nicht ohne weiteres erkennen, welche Teile eines Fenstertextes überdeckt sind, aber es wird ausreichen, um die Inhalte wieder in einen sinnvollen Zusammenhang zu bringen. Mindestens sind die Angaben geeignet, beim Anpassen zu helfen – Bezeichner für Steuerelemente zu finden.

Das ganze wäre zwar mit etwas Rechenaufwand verbunden, aber es könnte uns auch beim Festlegen von Objektpfaden helfen – denn wir wissen, wie wir durch die Fensterhierarchie zum gewünschten Objekt kommen – nämlich durch die Liste der übergeordneten Fenster.
=== Aliase für Objekte ===
Das erste Konzept beinhaltet die Möglichkeit Objekten semantisch sinnvolle Namen zu geben. Dabei ist nicht gemeint, was der Anwender vorgelesen bekommt, sondern wie man gezielt die Informationsfrüchte aus dem Baum pflückt. Die Daten werden oft angefragt und zur weiteren Verarbeitung ist es hilfreich, wenn klar ersichtlich ist, welches Puzleteil gemeint ist. Für einen Alias wird ein Name mit dem Pfad zum Objekt im Baum verknüpft.
=== Objektpfade ===
Das Problem zog sich bereits durch die Werkzeuge für das Offscreen-Modell. Wie kann man eine Bezeichnung (Label), ein Fenster oder eine Zelle in einer Tabelle so identifizieren, dass sie auch beim vergrößern des Anwendungsfensters, beim Aktualisieren von Daten etc. wiedergefunden wird. Das ist leider nicht trivial. Auch hier kann uns die Anwendung helfen. Wenn z.B. jedes Steuerelement eine eindeutige Steuerelement-Id hat, können wir es daran identifizieren. Darüber hinaus gibt es Namen, Objektklassen, Positionen im Fenster, Positionen im Objektbaum oder gar eine Prüfsumme über den Inhalt, die hier verwendet werden können. Ein Objektpfad sollte so aufgebaut sein, dass einzelne oder mehrere dieser Kriterien verwendet werden können, um einen Teil des Pfades zu identifizieren. Der Pfad leitet uns also sicher durch den Baum und verhindert, dass wir Objekte mit ähnlichen eigenschaften verwechseln. Ohne einen verläßlichen Objektpfad, können wir benötigte Informationen nicht ermitteln und damit kein Modell erstellen. Die Aliase ordnen nun einem Objektpfad einen leicht lesbaren Namen zu, der möglichst aussagekräftig beschreibt, was sich dahinter verbirgt.

Der Screenreader kann uns hier unterstützen, in dem er prüft, ob Cpntrol-Ids in der Anwendung eindeutig sind (das wäre ziemlich optimal), welche Fensterklassen verwendet werden und den Pfad mit Hilfe der Fensterpositionen eingrenzen helfen. Screenreader können hier den Benutzerkonfort durch clevere Unterstützung schaffen, wenn sie es schaffen, die Suche nach Fensterklassen und Merkmalen zur Identifikation des richtigen Fensters oder Objekts vom Anwender fernzuhalten.
=== Objektverhalten festlegen ===
Anpassungen bestehen im Wesentlichen aus diesen Punkten:
* Identifizieren von Informationen
* Klassifizieren von Informationen
* Vorlesen von Informationen auf anfrage
* Vorlesen von Informationen bei Änderungen
* Aktivieren von bestimmten Objekten wie Buttons etc.
Bislang wurden Anpassungen über Skripte programmiert, die diese Bereiche kombiniert haben. Da die Informationen im Wesentlichen nun bereits in Objekten getrennt vorliegen (im Offscreen-Modell lagen sie oft in einem großen Block), können wir über Aliase und Objektpfade den Objekten das gewünschte Verhalten zuweisen. Wir können
* Einem bestimmten Objekt einen Namen geben
* Es als Knopf, Textfeld oder einem der anderen Steuerelementtypen zuordnen. Es könnten sogar anwendungsspezifische Steuerelementtypen sein.
* Einem Objekt Kurztasten zur Aktivierung, zum vorlesen etc. zuweisen.
* Den Inhalt auf Änderungen überwachen lassen
* …
Dafür müssen wir nur eine Reihe von aktionen, die ein Screenreader beherrscht über Aliase mit Objektpfade verknüpfen.

Arbeiten wir z.B. in einem Musikaufnahmeprogram, dann können wir die Aussteuerungsanzeige so überwachen, dass sie ab einem bestimmten Niveau ein akustisches Signal auslöst, den Wert vorliest oder auf der Braillezeile schweigend einen Hinweis platziert. Wir können festlegen, dass wir einen bestimmten Bereich der Statusleiste über einen Hotkey vorgelesen bekommen. und wir können Reglern, die nicht als solche erkennbar waren identifizieren und deren Wert auslesen oder manipulieren.

Zusammenfassend können wir über dieses Konzept einen Objektbaum mit semantischen Verhalten ausrüsten. Das Beispiel einer Musiksoftware zeigt, dass es unterschiedliche Verhaltensmodelle geben muss nämlich für die unterschiedlichen Anwendungsfälle. Beim Aufnehmen müchte ich über die Aussteuerung unmittelbar informiert werden, beim Abspielen interessiert mich vielleicht eher die genaue Position im Track. Wenn man ein Verhaltensmodell festlegen kann, dann kann man auch zwischen solchen umschalten oder gar aufgrund von Änderungen im Objektbaum die Umschaltung automatisch vornehmen lassen. Wenn der Record-Knopf seinen Status von unpressed auf pressed geändert hat (er also eingedrückt wurde), dann können wir unser Aufnahmeverhalten aktivieren. Die Unterschiede zur Skriptprogrammierung sind hier im Wesentlichen:
* Ein aufgabenabhängiges Verhalten, falls dies notwendig ist.
* Eine Zuweisung von Verhalten zu Objekten anstatt im Skript direkt auf Objektklassen etc. zu prüfen. Das Ergebnis ist das gleiche, aber diese Ansatz ist beim Zuweisen des Verhaltens weniger technisch. Sind erst einmal für eine Anwendung Aliase vergeben, dann kann auch ein anwender ohne Programiererfahrung den Objekten sein gewünschtes Verhalten zuweisen.

=== Virtuelle Objekte ===
Nun, bislang haben wir nichts weiter getan,als gezielt und manuell oder halbautomatisch Informationen aus dem Baum herauszupicken. Einer der großen Vorteile des Offscreen-Modells besteht aber darin, dass zusammengehörige Informationen präsentiert werden – weil auch sehende Anwender einen Zusammenhang über die Anordnung auf dem Schirm herstellen. Diesen Zusammenhang läßt sich mit einem Puzzle aus Informationen, dass manchmal sogar falsche Zusammenhänge sugeriert, nicht herstellen. Wir müssen das Puzzle also zunächst richtig oder besser gesagt kontextbezogen zusammensetzen.

Um das zu erreichen müssen wir virtuelle Objekte erstellen – also container, in denen wir Objekte zusammenstellen können. Im einfachsten Fall setzen wir eine Beschriftung und ein Eingabefeld zu einem Objekt zusammen. Bei unserer Musiksoftware können wir aus einer Reihe von Reglern eine Art virtuelles Pult mit den wichtigsten Objekten für eine Aufgabe zusammenstellen.

Wir werden verschiedene virtuelle Objekte brauchen, denn die Ausgabe in Sprache, Braille oder Großschrift hat unterschiedliche und teilweise auch Gegensätzliche Eigenschaften. Einer Sprachausgabe ist die Textmenge relativ egal – sie kann in kurzer Zeit viele Informationen ausgeben. Eine Braillezeile ist kostbar, hat wenig platz und eignet sich für exakte Details. Vergrößerungen müssen den optischen Zusammenhang der Objekte waren, damit ein Anwender in die Anwendung hinein und herauszoomen kann. Es gilt wie oben schon gesagt: können wir ein virtuelles Objekt erstellen, dann können wirauch viele erstellen. Virtuelle Objekte können genauso mit Verhalten belegt werden wie andere Objekte auch. Damit kann eine Pegelanzeige, die mit einer passenden Beschriftung (durch Zuweisung eines Namens) eine Änderung melden und auf der Zeile anzeigen, welcher Pegel sich geändert hat.

Genauso wie das komponieren von Objekten zu virtuellen möglich ist, könnte auch ein komplexes Objekt, das durch die Anwendung nicht hinreichend zerlegt wurde, als Menge virtueller Teilobjekte dargestellt werden. Allerdings ist es wohl recht aufwändig, ein objekt sinnvoll und zuverlässig zu zerlegen. Aber feste Zeichenketten zum Auffinden von Beschriftungen etc. dürften hier helfen können.

Bildlich gesprochen machen wir unser Puzzle passend, indem wir die Teile zerschneiden oder sie zusammenkleben.

Wird das Objektmodell umgeschaltet oder die Anwendung gestartet, können Sprache, Braillezeile und Großschrift auf das gleiche oder unterschiedliche reale oder virtuelle Objekte gesetzt werden. Diese sind dann Startpunkt für die Navigation des Screenreader-Nutzers. Zusammenfassend können wir also aus dem Objektbaum ein Objektmodell erstellen, dass den Anforderungen des Anwenders entspricht. Das Modell kann sich von aufgabe zu Aufgabe ändern, so wie auch das Verhaltensmodell umgeschaltet werden kann.

=== Regelbasiertes Verhalten und Modellierung ===
Bislang haben wir nur solche Objekte betrachtet, zu denen wir einen festen Objektpfad erstellen können. Wird aber eine Webanwendung gestartet, ein Worddokument geöffnet etc., dann wissen wir nicht, wieviele Objekte sich im Objektbaum befinden. Außerdem wollen wir, dass sich alle Tabellen, Grafiken etc., die eine bestimmte Struktur haben, gleich verhalten. Das bedeutet, dass wir unsere Verhaltenszuweisung neben festen Aliases auch an Regeln knüpfen können müssen. Z.B. können wir sagen, das alle Tabellen, die 5 Spalten und mehr als 3 Zeilen haben in bestimmter Weise dargestellt werden sollen. Wir könten z..B auf jeder Tabellenzeile zu Beginn eine Zusammenfassung der Spaltenüberschriften auf der Brailezeile darstellen.
== Für wen ist dieses Modell der Anpassung ==
Viele werden nun rufen, das sei alles viel zu kompliziert und kein normaler Anwender könne das verstehen geschweigedenn anwenden. Ganz so weit würde ich zwar nicht gehen, aber es ist klar, dass sich das Konzept vorallem an die richtet, die regelmäßig Anwendungen für Anwender an einen Screenreader anpassen. Z.B. die Hilfsmittelfirmen, die für JAWS Skripte erstellen. Dort hat man bereits jetzt die Notwendigkeit viele technische Konzepte anwenden zu müssen und ein Objektbaum ist diesen Anpassern sehr vertraut. Ein engagierter oder verzweifelter Anwender kann aber ebenfalls davon profitieren, wenn er bereit ist, sich in die Materie einzuarbeiten.

== Wie kann eine Anpassung ablaufen? ==
=== prinzipieller Ablauf ===
Bevor ich ein Beispiel beleuchten möchte, zunächst das grundsätzliche Vorgehen. Eine große Überraschung ist es nicht, denn ähnlich musste man schon immer bei Anpassungen vorgehen:
* Identifizieren der Objekte, an denen man interessiert ist. Eine Anpassung soll immer nur so weit gehen, wie es nötig ist. Wenn andere Teile der Anwendung hinreichend bedienbar sind, muss man das Puzzle dort nicht zerlegen und neu zusammensetzen.
* Speziell für meinen Ansatz: Zurechtschneiden der Puzzleteile. Wie beschrieben brauchen wir manchmal virtuelle Objekte, damit wir genau die Informationen in der Hand haben, die wir wollen. Dafür erstellen wir virtuelle Objekte auf Basis der existierenden und geben Schnitte und Kleberänder an, um die Teile zu formen. Über die Benutzerführung habe ich hier noch keine detaillierten Gedanken gefasst. Der Anwender wird über reguläre ausdrücke, Positionsangaben im Text, Formatstrings und dem im Programmierumfeld üblichen Werkzeugen die Objekte zurechtschneiden müssen. z.B. könnte eine Syntax ähnlich wie die von sed (stream editor) verwendet werden, um den Inhalt von Objekten zu komprimieren (sehr empfehlenswert für die raillezeile).
* Anschließend sollten die Teile mit Namen versehen werden.
* Die benannten Objekte werden nun mit dem gewünschten Verhalten ausgestattet.
* Wen sich ein muster ergibt und dynamische Objektmengen im spiel sind, müssen diese Schritte (warum nicht Objekte regelgesteuert zerschneiden und verkleben) automatisiert werden.
* Bereitstellen einer Art eigener oberflöche spezifisch für einen Anwendungsfall. Diese Oberflöche (weine Komposition aus virtuellen Objetken) kann regelbasiert eingeblendet werden.
=== Beschriften eines Steuerelements ===
Einer der häufigsten Probleme besteht schlicht darin, Objekte mit gleichem oder kryptischem Namen mit einer Sinnvollen Beschriftung zu versehen. Ich würde dann als Screenreader so vorgehen:
* Der Anwender fordert auf einem Objekt an, dass es beschriftet werden soll. Die Aktion kann durch die Maus oder das Fokussierte Objekt gestartet werden. Damit können sehende anwender auch die Teile beschriften, die nicht per Tastatur erreichbar sind.
* Der SR empfiehlt den Objekt einen Alias zu geben und schlägt einen Namen aus Typ und Text des >Objekts vor z.B. Sltr-OK.
* Der Screenreader prüft die umgebenden Objekte auf eindeutige Merkmale wie Control-Ids und bietet dem Anwender daraus einen mögtlichst eindeutigen Objektpfad an. Falls der Anwender die Anwendung gut kennt, kann er hier manuell Optimierungen festlegen.
* Der SR fordert die neue Beschriftung an und vermerkt sie zum Objektpfad.
* Falls das objekt eine Objekt- oder Fensterklasse verwendet, die kein Standard ist und für die Klasse keine bekannte Objektklasse festgelegt wurde, empfieht der SR die Klasse nun mit einer sinnvollen Objektklasse zu verknüpfen. Dabei kann er auch die umgebenden Objekte und Fenster zu Rate ziehen. Auch die Styles des Fensters können hier Aufschluss geben – denn sie legen oft fest, wie das Fenster optisch dargestellt wird.
* Der SR erfragt, ob für das objekt Kurztasten zum Aktivieren oder Auslesen verwendet werden soll und prüft bei der Eingabe, ob die Kurztaste bereits belegt ist.

So ähnlich könnten auch andere Anpassungen von einer Art Assistenten gesteuert stattfinden. Hmmm, klingt irgendwie nach dem Prompt erstellen und Fensterklasse zuweisen von JaWS! Ja, das stimmt und es gibt für mich keinen Grund diese Werkzeuge nicht ähnlich nachzubilden, aber mit mehr Intelligenz des SR. Ich wusste zwar, was die JAWS-Werkzeuge im einzelnen tun, konnte sie aber nie im Orchester spielen lassen. Hier muss der SR geeignete Maßnahmen vorschlagen und den Anwender interakti unterstützen. Er sollte OCR-Techniken und andere dinge einsetzen, um es einem blinden Anwender zu erlauben, sich eine Anwendung zugänglich zu machen und das hier beschriebene Konzept anwenden zu können.

== Fazit ==
In letzter Zeit lösten kostenlose Screenreader in Anwenderkreisen viel Aufregung aus. Die Einen glauben, kommerzielle Screenreader wären ein aussterbendes Geschäftsmodell. Die Anderen sorgen sich um deren Finanzierung, denn Sachbearbeitern kann nicht ohne Weiteres klargemacht werden, warum hier teure Lizenzen notwendig sind. Sicher kann ein freier Screenreader wie NVDA Teile dieser Ideen umsetzen, aber es gibt noch viel Arbeit für die Screnreader um dem Anwender bei den neuen Herausforderungen zur Seite zu stehen. Projekte wie NVDA richten sich im Wesentlichen an private Nutzer, denn sie stellen das Grot der Anwender, Tester etc. Wer sich die notwendigen Schnittstellen nicht selbst programmiert, oder das notwendige Geld bereitstellt, bekommt nachvollziehbarerweise wenig Unterstützung durch das Wntwicklungsteam. Sie mögen die Probleme einsehen, die Lösung gut finden, aber es gibt oft drängedere probleme für die Masse statt für einzelne Anwender. Hier teilt sich die Anwenderschaft klar in private und berufliche Nutzer. Privat kann man nach alternativen Anwendungen suchen. Eine Anpassung kommt hier selten in Frage, denn diese sind teuer und oft von Anwendern ohne Fachkenntnis kaum durchzuführen. Bei den beruflichen Anwendern ist es umgekehrt. Alternative Anwendungen sind i.d.R. nicht möglich. Dafür gibtt es die Möglichkeit, dass ein Kostenträger die anpassung übernimt – falls sie technisch möglich ist.

Klar ist auch, dass es jenseits der Verantwortung der Anwendungsentwickler Anpassungsbedarf bei den Screenreadern gibt. Selbst wenn Anwendungen optimal mit Zugänglichkeitsinformationen ausgerüstet sind, heißt dies nicht, dass sie effizient mit einem Screenreader bedient werden können. Diese Optimierung ist von den Softwareentwicklern nicht zu leisten, denn sie Bedarf Kenntnis über die Anwendungsfälle die unterstützt werden sollen und Wissen über den Anwender und die Nutzung eines Screenreaders. Facebook ist technisch barrierefrei, aber nicht effizient bedienbar. Wenn uns das privat nervt, können wir uns abmelden. Brauchen wir es beruflich, ist der Job gefärdet!
Also: Für berufiche Anwender führt kein Weg an professionellen Anpassungen vorbei. Diese sind oft nur mit entspr. Schnittstellen und Funktionen im Screenreader umsetzbar.

Ein Gedanke zu „Der Traum vom Screenreader, der uns passend zu unserer Aufgabe optimal mit Informationen versorgt

Schreibe einen Kommentar