blog · git · desktop · images · contact
2020-02-24
In der README von lariza steht:
Background information
----------------------
What lariza is and what it's not
...
Especially, it's very likely that lariza will never have a "follow
mode" like dwb, luakit or others have. I've used these browsers for
quite some time and I've also used Firefox extensions that add a
"follow mode". The point is, "follow mode" doesn't work anymore. This
was a good thing ten years ago. Today, a lot of websites make heavy
use of JavaScript or hovering. You NEED some kind of pointing device.
I found using "follow mode" to be very frustrating today, because you
still have to reach for the mouse all the time. So, you might as well
just optimize your mousing workflow.
„Ten years ago“ bezieht sich auf 2004 und war vielleicht damals schon zu optmistisch.
Jedenfalls könnte sich das ändern.
2019 war ein „Jahr des Schmerzes“. Ja, klingt ein bisschen dramatisch. :) Das ganze Jahr über hatte ich es mit Schmerzen in den Handgelenken zu tun und anderen Problemen in dieser Gegend. Das ist immer noch ein bisschen ungeklärt alles und auch noch nicht ganz vorbei. Das Ding ist aber, dass es mir derzeit wirklich schwer fällt, die Maus zu benutzen. Wie da oben aber schon steht, zwingt lariza einen eigentlich genau dazu und deswegen habe ich dann aufgehört, den Browser zu benutzen. Bin zurück zu Firefox, was seine eigenen Bugs hat, und dann zu Chromium – mit Vimium als Plugin.
Vimium hat ein paar nette Shortcuts, aber vor allen Dingen auch einen „Follow Mode“. Das ist so viel komfortabler als Mausbenutzung oder ein Touchscreen. Meiner Ansicht nach sollte jeder Browser (jede UI allgemein?) sowas eingebaut haben und es sollte der Standard sein, wie wir im Web navigieren, aber nungut.
Jedenfalls ist es sprichwörtlich schmerzhaft, lariza in der aktuellen Form zu benutzen. Ich will das Projekt nicht aufgeben, also muss man da was tun.
Eine kleine Vorschau.
Man drücke einen Hotkey (derzeit f
), um Link Hints zu aktivieren:
Man beachte, dass die Labels rechts neben den eigentlichen Links sitzen, was anders als in anderen Implementierungen ist – darauf kommen wir noch zu sprechen. Die Labels sehen dann wie kleine Pfeilchen aus, um die Verwirrung hoffentlich ein bisschen zu lindern.
Den Rest kennt man: Man tippt ein paar der Zeichen der Labels ein, um
die Auswahl immer weiter einzuschränken. Als nächstes habe ich h
gedrückt:
In hellem Grün die aktuelle Auswahl. Ich könnte jetzt Enter
drücken,
um den Link zu öffnen. Man beachte, dass das eigentliche Element nochmal
hervorgehoben ist – auch darauf kommen wir noch zurück.
Dann d
gedrückt:
Jetzt ist nur noch ein Label übrig, man muss aber trotzdem Enter
zum
Bestätigen der Auswahl drücken. Yep, auch darüber sprechen wir noch.
WebKit trennt den C-/GTK-Code von allem, was in der eigentlichen Webseite passiert. Mit anderen Worten, man kommt von C aus nicht an das DOM der Seite ran. Man muss JavaScript benutzen. lariza lässt daher schon ein kurzes Stückchen JS laufen, um die Liste der URLs für RSS-/Atom-Feeds zu bekommen.
Daraus ergeben sich ein paar Probleme.
Zuerst einmal muss natürlich auch der Follow Mode in JS geschrieben sein. Man muss ja ans DOM und das geht nur mit JS. Die Bauchschmerzen hier entstehen nicht dadurch, dass „JavaScript eine blöde Sprache“ sei, sondern dadurch, dass es eine fast komplett getrennte Welt ist – ein großer Bruch zwischen C/GTK und dieser JS-Welt. Es ist im Wesentlichen ein zweites Programm, das irgendwie mit dem ersten kommunizieren muss. Sein Code läuft asynchron zum Hauptprogramm, Input-Events sind ganz andere und so weiter.
Habe ich so gemacht, dass ich ein generisches „Userkript“-Feature eingebaut habe, so ähnlich wie surf das hat. Anders als surf führt lariza aber nach dem Laden einer Seite einfach alle Dateien aus, die sich in einem bestimmten Verzeichnis befinden.
Um ehrlich zu sein, ist der Follow Mode auch so ziemlich das einzige, wofür man Userskripte in meinen Augen sinnvollerweise einsetzen kann. Man kann jetzt an eigene Keybinds denken, aber da bitte erstmal weiterlesen. Okay, man kann mit Userskripten vielleicht noch auf lästigen Webseiten bestimmte Elemente löschen. Das war’s dann aber, glaube ich, auch. Vielleicht bin ich auch nicht kreativ genug. Trotzdem war dieser Ansatz der am wenigsten invasivste – der Diff ist winzig und lariza selbst weiß auch gar nichts von einem Follow Mode. Es sagt WebKit nur, dass es ein bisschen JavaScript ausführen soll. Wie wir gleich sehen werden, funktioniert das so einigermaßen, ist aber weit entfernt von einer perfekten Lösung und vielleicht nicht einmal eine gute.
Was ich schon nicht hinbekommen habe, ist, meine eigenen Skripte gegenüber denen der Webseite zu isolieren. Heißt also, wenn man nicht in den Userskripten alles in eine anonyme Funktion wrappt, wie unten gezeigt, dann kann die Webseite deine Variablen auslesen und beeinflussen! Oder du kannst Variablen im Code der Webseite kaputtmachen. Ziemlich nervig – und sieht auch so aus, als wäre das bei Browsern wie Chromium anders.
(function() {
// Configuration
var charset = "sdfghjklertzuivbn".split("");
var key_follow = "f";
var key_follow_new_win = "F";
function update_highlights_or_abort()
{
...
}
...
}());
Das kann man nun zwar mit dieser anonymen Funktion umgehen, aber wenn es um Key-Handler geht, wird es viel schlimmer. Man kämpft nämlich gegen die Webseite an. Das Firefox-Plugin Vim Vixen hat das Problem auch (und verliert den Kampf – Key-Handler der Webseite und des Plugins triggern beide). Nur Vimium scheint dieses Problem meistens nicht zu haben, allerdings enthält dessen Code auch Kommentare wie: „Wir laufen so früh wie möglich, damit die Webseite vor uns keine Keys abfangen kann.“ Vielleicht ist es auch nur Chromium, was sich etwas geschickter dabei anstellt, die beiden Welten zu trennen. Keine Ahnung. Wenn ich so darüber nachdenke, fallen mir letztlich auch ein paar Webseiten ein, die ich auf der Arbeit nutzen muss, bei denen selbst Vimium versagt.
Das ist schon ganz schön mies. Ich konnte auch keinen Weg finden, das zu
vermeiden. Vermutlich wird man eine ganz eigene JS API bauen müssen, um
das Thema sauber zu lösen, damit lariza-Skripte ihre Event-Handler
darüber registrieren können und nicht über das normale
document.addEventListener()
gehen müssen. Jeder Tastendruck würde dann
zuerst an unsere eigenen Handler geschickt und, falls diese nichts damit
anfangen können, auf dem normalen Wege zur Webseite. Habe ich bisher
noch nicht so gemacht, weil es recht aufwändig ist (und weil es noch
andere Dinge gibt, die kräftig in die Hose gehen, daher weiß ich noch
gar nicht, ob sich der Aufwand überhaupt lohnen würde). Stattdessen
haben wir jetzt folgenden Workaround:
Wird der Follow Mode aktiviert, dann erstellen wir ein verstecktes
input
-Feld und fokussieren es. Gibt man dann die Buchstaben der Labels
ein, wird eigentlich in dieses Feld reingetippt. Albern, scheint aber zu
funktionieren – zumindest für die Eingabe der Labels. Sollte eine
Webseite schon die f
-Taste zum initialen Aktivieren des Follow Modes
ohne Fokus der Input-Box für sich beanspruchen, ist man wieder
aufgeschmissen. Hatte kurz darüber nachgedacht, daraus ein Alt + f
zu
machen, aber das ist nicht sehr angenehm.
Noch ein Rückschlag war die Performance von
element.getBoundingClientRect()
in WebKit: Diese Funktion kann benutzt
werden, um die sichtbare Position eines Elements zu berechnen.
Idealerweise könnten wir damit die Labels „perfekt“ platzieren, nämlich
genau bei den Elementen, auf die sie verweisen. Ist aber zu langsam.
Viel zu langsam. Auf Webseiten mit vielen Links dauert die Erstellung
aller Labels einige Sekunden auf meinem i7, der mit 3.4 GHz läuft. Die
genannte Funktion scheint aber in Chromium schnell zu sein und Vimium
benutzt sie auch, weshalb dieses Plugin sehr gute Ergebnisse erzielt.
Wir können’s aber nicht benutzen. Als Workaround platzieren wir jetzt
die Labels so nahe wie möglich am referenzierten Element im DOM und
hoffen dann, dass sie schon irgendwo in der Nähe auftauchen werden. Für
<a>
-Elemente werden sie als Kind hinzugefügt. Deswegen tauchen sie
rechts davon auf.
Funktioniert aber auf „fancy“ Webseiten oft nicht richtig. Manchmal
erscheinen die Labels einfach an der falschen Stelle. Deswegen wird das
von einem Label referenzierte Element noch einmal bei der Auswahl
hervorgehoben. Und deswegen ist auch das finale Drücken von Enter
zum
Öffnen eines Links notwendig, denn – jenachdem, wie fies die Webseite
ist – man erwischt sonst oft aus Versehen einfach ein völlig falsches
Element.
Und natürlich passiert all das tief im DOM der Seite. Das CSS der
Webseite greift also auch für unsere Labels. Manchmal erscheinen sie
daher in Großbuchstaben, weil die Webseite das so will. Oder sie haben
ein kleines Icon, weil die Webseite das :before
-Pseudoelement benutzt.
Oder andere Elemente überdecken unsere Labels, weil, tja, die Webseite
das so will. Das führt uns schließlich zum nächsten Abschnitt.
Man schaue sich nur die Bugtracker von Vimium oder Vim Vixen an. Selbst diese Plugins funktionieren nicht immer. Vimium ist eigentlich verdammt gut, aber trotzdem, manchmal geht’s nicht.
Ist keine Überraschung. Webseiten sind keine passiven Dokumente. Jedenfalls heute nicht mehr. Es sind Applikationen. Und als Programmierer eines Follow Mode kämpft man ständig gegen sie an. Man kann sich das so vorstellen: Man denke an ein normales in C geschriebenes Programm für X11 und dann hat man ein anderes Program, das im selben Adressraum läuft und versucht, alle „klickbaren“ Elemente zu finden. Du weißt, wo der Ziel-Framebuffer ist, und es gibt eine kleine „API“, um grundlegende Elemente wie Buttons zu finden. Im Wesentlichen hat man aber keine Ahnung, was alles klickbar ist, weil jeder Pixel aufgrund von irgendwelchem Code klickbar gemacht sein könnte. Und dann muss man gegen das interne Fokussystem der Anwendung kämpfen. Und gegen ihr Eventsystem. Und überhaupt. Ich weiß jetzt nicht, ob das der bestmögliche Vergleich ist, aber so ungefähr fühlt sich das an. Das kann vielleicht für einfachere Programme wie leafpad noch funktionieren, aber nicht für sowas wie Blender. Es wird immer eine unvollständige Lösung sein.
Die wichtigsten Beispiele:
element.addEventListener()
benutzt, gibt es, soweit ich weiß, keine Möglichkeit, die
registrierten Handler aufzulisten.<audio>
-Tags, die im DOM gar nicht auftauchen?element.getBoundingClientRect()
, benutzen
könnten, hätten wir damit nur die Bounding-Box eines Elements. Wo
platzieren wir also das Label? Oben links? In der Mitte? Wir haben
keine Ahnung, was der User als „das Element“ oder „den klickbaren
Bereich“ wahrnimmt. Das kann also immer noch sehr missverständlich
sein, insbesondere bei großen Elementen.Ich behaupte, wenn man das sauber lösen will, muss man das in der Rendering-Engine selbst machen. Oder am besten vereinfacht man das Web wieder und entfernt die ganzen feschen Features, die oftmals ohnehin keine Verbesserung von irgendwas bringen.
Aus genau diesen Gründen habe ich damals keinen Follow Mode für lariza gebaut und auch nie geplant gehabt. Wenn ich nicht diese Probleme mit den Handgelenken hätte, wäre mir meine Zeit viel zu schade, um mich damit auseinanderzusetzen, aber, ja, hab’s dann doch gemacht, weil es besser ist als gar nichts.
Wahrscheinlich wird lariza höchstens das Feature der Userskripte
bekommen. Ich bin noch nicht sicher, ob ich follow_mode.js
bundlen
oder in ein eigenes Repo packen werde. Außerdem muss ich das alles noch
weiter testen und ausprobieren. Vielleicht werfe ich es doch wieder weg,
falls es einfach nicht gut genug ist.
Ich würde auch gerne vermeiden, lariza in noch so einen „vi-artigen Browser“ zu verwandeln. Davon gibt’s genug. Außerdem ist das super viel Arbeit. Im Moment ist lariza klein und das ist sehr gut so.
Aber … ja, der Follow Mode macht einige Designkonzepte von lariza
kaputt. Plötzlich gibt es einen Mix aus „alle Browser-Hotkeys werden in
C behandelt und sind mit Alt
gepräfixt“ und „drücke f
, um einen
besonderen Modus in der JavaScript-Welt zu aktivieren“. Fühlt sich wie
eine Mischung aus Emacs und vi an. Einfach nicht sauber. Ich habe da
dann das Bedürfnis, die existierenden Hotkeys aufzuräumen und ein paar
Konzepte anzupassen, aber dann wäre man eben bei genau einem vi-artigen
Browser.
Um ehrlich zu sein, hätte ich den Follow Mode gerne als rein optionales Feature. Schon alleine, weil er so wackelig ist und oft kaputt geht.
Trotz aller Hürden macht (mir – in der derzeitigen Situation) die Benutzung des Browsers gleich viel mehr Spaß, wenn es einen Follow Mode gibt. :) Es ist so eine typische 80%-Lösung, aber wenn es funktioniert, dann ist es toll und sehr angenehm.