In meinem grundlegenden Beitrag Darktable: crashing into the wall in slow-motion habe ich das Desaster dargestellt, das der neue „Great MIDI turducken" war. Der Zweck dieses Turduckens1 war es, das System der Tastaturkürzel neu zu schreiben, um es auf MIDI-Geräte zu erweitern.
Bis heute bin ich immer noch wütend über dieses Unternehmen der Massenzerstörung, hier eine Zusammenfassung der Gründe:
- es ersetzte 2021 ein System der Tastaturkürzel, das ziemlich gut, funktional vollständig, gut getestet, stabil und in weniger als 1500 Zeilen (Kommentare inbegriffen) programmiert war,
- …um Unterstützung für MIDI-Geräte und PlayStation-Gamepads hinzuzufügen (!?!)…
- …aber in meiner Darktable-Umfrage von 2022, ein Jahr nach dieser neuen Funktion, gaben von über 1251 teilnehmenden Nutzern an:
- 81 % der Nutzer hatten kein MIDI-Gerät und planten nicht, sich eines anzuschaffen,
- 2 % wussten nicht einmal, was ein MIDI-Gerät ist.
- 8 % der Nutzer hatten ein MIDI-Gerät, verwendeten es aber nicht mit Darktable,
- 6 % erwogen, sich vielleicht in Zukunft ein MIDI-Gerät anzuschaffen,
- 2 % der Nutzer hatten ein MIDI-Gerät, das sie tatsächlich in Darktable verwendeten,
- der Code war absolut furchtbar, in Bezug auf:
- Codequalität: unleserliche
if/switch-case-Anweisungen, auf 4 Ebenen verschachtelt, inmitten von Funktionen mit 1000 Zeilen (Beispielausschnitte habe ich in meinem Artikel gepostet), - Codevolumen:
- 3546 Zeilen Code für Darktable 4.0,
- 4397 Zeilen Code für Darktable 5.0,
- die Zunahme des Volumens ist eine direkte Folge des Versuchs, Bugs in einer Architektur zu beheben, die nicht behoben werden kann, weil ihre Komplexität weitere Komplexität fördert. All das rührt vom Design her, aber Probleme, die durch Komplexität verursacht werden, durch das Hinzufügen von mehr Komplexität zu lösen, ist keine Lösung.
- Codekomplexität:
- zyklomatische Komplexität :
- 1088 für Darktable 4.0,
- 1245 für Darktable 5.0 (Details ),
- kognitive Komplexität :
- 1885 für Darktable 4.0,
- 2098 für Darktable 5.0 (Details ).
- es ist mit Abstand die komplexeste Funktion der Software, obwohl sie nicht auf Bildern operiert. Zum Vergleich: die zweitkomplexeste Funktion ist die Dekodierung der EXIF-Metadaten, die eine kognitive Komplexität von 1348 hat.
- zyklomatische Komplexität :
- Codequalität: unleserliche
- es dekodiert von Grund auf keine Tastenmodifikatoren, sondern behandelt nur Hardware-Tastenanschläge, was bedeutet:
- eine „1"-Eingabe vom Ziffernblock wird als
Keypad Enddekodiert, - eine „1"-Eingabe von einer französischen AZERTY-Tastatur wird als
Shift+&dekodiert, oder alsShift+"auf BÉPO, - Sie müssen daher alle Ihre zahlenbasierten Tastenkürzel für jede Art der Zahleneingabe duplizieren und darauf gefasst sein, dass das Einstellungsfenster für die Tastenkürzel keine einzige echte Zahl in den Tastenkombinationen enthält.
- eine „1"-Eingabe vom Ziffernblock wird als
- das nutzerseitige Design ist absolut furchtbar, mit viel zu vielen zu konfigurierenden Aktionen und Emulationen („Effekte"), die selbst 4 Jahre später nicht einmal vollständig dokumentiert sind (was ist „ctrl-toggle"? „right-activate"?), und die Konfiguration der Tastenkürzel verwendet ein seltsames geteiltes Fenster, das keinerlei Sinn ergibt,
- die Implementierung ist ebenfalls furchtbar: die Funktion kennt die gesamte GUI der Software, und die GUI der Software kennt den Code der Tastenkürzel. Hier gibt es keine Modularität, und eine Änderung an irgendetwas im Code der Tastenkürzel kann unerwartete und unerwünschte Auswirkungen an jeder Stelle der Software haben.2 Sehen Sie sich nur den Abhängigkeitsgraphen unten an,
- mehrere „Tastenkürzel" (oder MIDI-Bindungen) können an dieselbe Aktion angehängt werden, was bedeutet, dass jede Nutzerinteraktion die gesamte Liste der verfügbaren Aktionen durchsuchen muss, was eine sehr ineffiziente Handhabung der Tastenkürzel, in manchen Fällen GUI-Verzögerungen und in eigentümlichen Fällen „unbekannte Tastenkombination"-Falschmeldungen verursacht.


Der Abhängigkeitsgraph von src/gui/accelerators.c (Great MIDI turducken) vor der Neufassung. Raten Sie, warum wir das „Spaghetti-Code " nennen… Das macht deutlich, dass es eine beidseitige Abhängigkeit zwischen dem Accels-Code und dem restlichen GUI-Code gibt. Das ist ein Albtraum in der Wartung.
Also, anders gesagt, ein (sehr schlechter) Programmierer ersetzte eine funktionierende und einfache Funktion durch ein Monstrum, mit der Zustimmung des Maintainers (der selbst niemals derart schlechten Code schreiben würde, aber entschlossen ist, bei den Beiträgen „nicht an Schwung zu verlieren", koste es, was es wolle), um 2 % der Nutzerbasis zufriedenzustellen. All das für eine sekundäre (tertiäre?) Funktion.
Ich nenne das falsche Prioritäten. Zumal es einen Entwickler und viele Betatester mehrere Monate harter Arbeit kostete, nur um die Dinge zu verschlimmern, und dann wurde die harte Arbeit zur Rechtfertigung, die Änderung niemals rückgängig zu machen, was als Fehlschluss der versunkenen Kosten bekannt ist.
Ich bin ein Nutzer, mich interessiert der Code nicht
Sich um den Code der Anwendungen zu kümmern, die Sie nutzen, ist genau wie sich darum zu kümmern, ob die Rohre, die Wasser in Ihr Zuhause bringen, aus Blei bestehen. Es ist nicht Ihre Aufgabe, Rohre sind vergraben und außer Sichtweite, Sie haben also allen Grund, sich nicht darum zu kümmern — und die für das Wassernetz Verantwortlichen haben allen Grund, dass Sie sich nicht darum kümmern — aber sie werden eine Auswirkung auf Ihre Gesundheit haben, und diese Auswirkungen bleiben unsichtbar, bis es zu spät ist. Software hat vielleicht keine direkte Auswirkung auf Ihre Gesundheit,3 aber die Art, wie sie gemacht ist, wird langfristig Auswirkungen auf Sie haben.
Ich befinde mich in einer unangenehmen Position – der Kassandra — die den Nutzern erklären muss, dass Probleme, die sie nicht kennen, nicht sehen und die ihnen egal sind, sehr wohl die tägliche Benutzbarkeit und Stabilität der Werkzeuge beeinträchtigen, die sie verwenden, aber auf nicht offensichtliche Weise. In jedem Fall beeinträchtigen diese Probleme direkt die Wahrscheinlichkeit, dass irgendein Maintainer eines Tages die Bugs behebt, mit denen er konfrontiert ist.
Schlechte Nachrichten zu überbringen macht Sie zur schlechten Nachricht, aber schlechte Nachrichten zu überbringen, die niemanden interessieren, macht Sie zum Arschloch, obwohl diese schlechten Nachrichten die seltsamen und zufälligen Probleme erklären, die seit 2021 in den Bug-Trackern von Darktable immer häufiger werden, die über Jahre nicht gelöst werden, weil der Code an diesem Punkt keine Bugs enthält, er ist ein Bug. Aber hier müssen Sie sich Filterblasen stellen: je nachdem, wo im Web Sie hinschauen, finden Sie entweder Menschen, die zutiefst glücklich mit Darktable sind (Performance, Stabilität, Design), und Menschen, die zutiefst unglücklich damit sind. Meine empirische Beobachtung ist, dass die zufriedenen Nutzer im Durchschnitt leistungsstarke Computer besitzen und MINT-Abschlüsse haben.4 Die unglücklichen Menschen neigen dazu, sich abzuwenden und die Zeit zu reduzieren, die sie mit der Software verlieren, was bedeutet, dass Sie, wenn Sie nicht aktiv nach ihnen suchen, nur Ihren Survivorship Bias nähren. Und obwohl ich keinen Sinn darin sehe, Nutzer zu Darktable (oder zu irgendeinem Open-Source-Fotoeditor) bekehren zu wollen, weil jedem das Seine, ist das Aussortieren und Abschrecken von Nutzern aufgrund ihrer Computerkompetenz ein großer Fehlschlag für jede Bildbearbeitungs-App.
Als jemand mit einem YouTube-Kanal, der erklärt, wie man Darktable verwendet, und der Einzelschulungen gibt, ziehe ich tendenziell vielfältigeres Feedback an als nur die GitHub-Issue-Tracker (wo Designkritik ohnehin recht schnell abgewürgt wird), und erlebe in Videochats aus erster Hand diese seltsamen, zufälligen und nicht reproduzierbaren Bugs. Jeder privilegierte Mensch neigt dazu, Zeugnisse über Probleme, die er selbst nicht hat, zu leugnen, herunterzuspielen oder zu ignorieren, oder sogar die Person, die sie meldet, für die Probleme verantwortlich zu machen. Deshalb habe ich oft diesen Eindruck von zwei parallelen Universen, die nicht miteinander kommunizieren, aber aufeinander herabschauen, wenn es um Feedback zu Darktable geht. Natürlich haben sich die Darktable-Entwickler dafür entschieden, dorthin zu schauen, wo die Sonne scheint.
Und obwohl Darktable wie ein aktives Projekt aussieht, dem regelmäßig viele neue Funktionen von einem Dutzend Leuten hinzugefügt werden, ist es umso schwieriger zu erklären, dass hinter den Kulissen tatsächlich eine Zerstörung der Codebasis stattfindet, denn die Codequalität verschlechtert sich mit der Zeit erheblich, bis es überhaupt nicht mehr möglich sein wird, zu debuggen. Das Volumen der Änderungen sagt nichts über Qualität, Zuverlässigkeit oder Wartbarkeit aus. Aber 2 Jahrhunderte Kapitalismus haben uns darauf konditioniert, nach glänzenden neuen Funktionen zu streben, koste es, was es wolle, und in dieser Hinsicht erfüllt Darktable die Erwartungen.
Code wird kaputt geboren. Jede Software hat Bugs. Schlimmer noch, wir verwenden viele Bibliotheken von Drittanbietern, um das „Rad nicht neu zu erfinden", aber diese Bibliotheken werden in Zukunft ihre API ändern, was bedeutet, dass Code, der heute funktioniert, morgen aufhört zu funktionieren und in Zukunft überarbeitet werden muss, wenn sich Abhängigkeiten ändern. Code ist wie ein Garten: jede neue Jahreszeit bringt ihr Maß an Arbeit mit sich. Das nennt man Wartung. Sobald man das anerkennt, liegt die Weisheit darin, Wege zu planen, um Wartung zuerst möglich und dann einfach zu machen.
Guter Code ist Code, der leicht zu warten ist. Das heißt, guter Code ist so geschrieben, dass er angenehm für die Menschen ist, die ihn lesen, verstehen und beheben müssen. Wir schreiben Code nicht für Computer. Wir schreiben Code nicht dafür, dass Funktionen jetzt und in den nächsten Monaten „einfach funktionieren". Code ist nichts, was wir unter einer schönen Haube verstecken, in der Hoffnung, ihn nie wieder ansehen zu müssen. Code ist ein lebender Organismus, der Energie und Zeit kostet, um ihn am Leben zu erhalten.
Wartung hat einen Preis, einen, der oft unterschätzt wird. Es spielt keine Rolle, ob Ihr Produkt das beste am Markt ist, wenn Ihre Wartungskosten prohibitiv sind, werden (informierte) Kunden es meiden. Wartung ist langweilig, uninteressant, nicht sexy. Wartung ist das Gegenteil davon, glänzende neue Dinge einzuführen: es geht darum, sicherzustellen, dass verstaubte alte Dinge weiterhin klaglos funktionieren. In Ihren Software-Release-Notes steht sie am Ende. Nutzer freuen sich nicht über gewartete Funktionen, aber sie werden wütend über ungewarteten Code und neigen dazu, die falsche Metrik zu verwenden, um zu beurteilen, wie gut ein Projekt gewartet wird (nämlich: Betriebsamkeit und Anschein von Arbeit). Sie gewinnen also nichts durch das Warten von Code, aber Sie verlieren dadurch, ihn nicht zu warten, und es wird Sie etwas kosten, ob Sie es tun oder nicht.
Code ist unwartbar, wenn jede Fehlerbehebung zu einem neuen Bug an anderer Stelle führt, auf eine Whack-a-mole-Art, und die Fehlerbehebungen ihrem Wesen nach eigentlich kontextabhängiges Flicken und Behelfslösungen sind, die der Software nur Komplexität hinzufügen. Wenn Sie diesen Punkt erreichen, ist Ihre einzige Option, den beanstandeten Code von Grund auf neu zu schreiben. Was bedeutet, dass vergangene Arbeit gerade jetzt mehr Arbeit geschaffen hat. Und wenn diese spezielle vergangene Arbeit bereits vorherige Arbeit überschrieben hatte, begeben wir uns in die Idiokratie.
Mehr Code ist kein Erfolg oder eine Errungenschaft. Errungenschaften liegen im Lösen der Probleme der Nutzer. Auch hier trifft uns die kapitalistische Denkweise hart: wir würden Arbeit gerne am Volumen des hinzugefügten Codes messen. Mehr Code ist nur mehr Haftung, mehr technische Schuld, mehr Wartungskosten. Das ist eine kognitive Dissonanz, da es bei Software gerade um das Schreiben von Code geht. Aber denken Sie so darüber: ein Auto zu bauen bedeutet nicht, mehr Stahl über 4 Rädern hinzuzufügen, denn irgendwann muss sich das Auto bewegen. Sie brauchen die richtige Menge Stahl, auf die richtige Weise an den richtigen Stellen geformt: Sie müssen effizient und sparsam sein. Bei Software geht es darum, die Probleme der Nutzer mit Computern zu lösen, nicht darum, Code zu horten.
In Projekten, in denen Mitwirkende nicht bezahlt werden, ist langweilige Wartung nicht das, wofür die Leute ihre Samstage verbringen wollen, und das ist ein echtes Anliegen, was das Projektmanagement betrifft. Es ist umso wichtiger, Wartung einfach zu machen, wenn Menschen umsonst arbeiten. Glücklicherweise hat Darktable null Projektmanagement, nur einen Schwarm zufälliger Mitwirkender, die zu zufälligen Zeiten ihr eigenes Süppchen kochen, ohne einheitliches Ziel, Strategie, Zeitplan oder Arbeitsteilung. Deshalb möchte ich, dass alle aufhören, den Begriff „Darktable-Team" zu verwenden. Es gibt kein Darktable-Team, denn es gibt keine Arbeitsteilung, keine Führung, keinen Zeitplan, keine Roadmap, keine Planung, kein Ziel, keine Prioritäten, keine Vision, keine Strategie, keine Methode, kein Design, keine Kommunikation im Vorfeld des Handelns, keine Spezifikationsdokumente für die zu lösenden Probleme. Das ist der Computerclub einer Highschool, bestehend aus unverbundenen Einzelpersonen.
Es gibt 3 Dinge, die ein Entwickler tun muss, um sicherzustellen, dass die Wartung so einfach wie möglich ist:
- die geringste Menge Code schreiben: einen Bug unter 300 Zeilen aufzuspüren wird viel schneller gehen als unter 3000 Zeilen,
- den einfachsten Code schreiben: „einfach" im Sinne von „die funktionale Logik hat wenige Schritte, wenige Annahmen, wenige Sonderfälle". Einfacher bedeutet leichter zu lesen, zu verstehen und zu beheben, aber auch, dass es beim Testen weniger Fälle abzudecken gibt. In der Praxis bedeutet es, kontextabhängige Fälle, Nutzeroptionen, Varianten,
if/elseim Code zu vermeiden. - in sich geschlossenen Code schreiben: die Softwarefunktionalität zwischen Modulen (Unterprogrammen) aufteilen, die über den Kern kommunizieren und voneinander isoliert sind. Wenn das Codevolumen wächst, garantiert das, dass Änderungen, die innerhalb von Modulen geschehen, keine unvorhergesehenen Auswirkungen außerhalb haben.
Schließlich müssen Sie bewerten, ob die neuen Funktionen, die Sie hinzufügen, die zusätzlichen Wartungskosten wert sind. Im Fall des Tastenkürzel-Handlers bedienen wir die „Bedürfnisse" (oder eher den Luxus) von 2 % der Nutzerbasis mit einer Implementierung, die (mindestens) doppelt so kompliziert ist wie die, die sie ersetzte. Wägen Sie das in Ihrem kapitalistischen Verstand ab…5
Codekomplexität kann mithilfe der Graphentheorie gemessen werden, durch zyklomatische Komplexität, kognitive Komplexität oder N-Pfad-Komplexität. Viele Forschungsartikel korrelieren Codevolumen und/oder Codekomplexität mit der Anzahl versteckter Bugs, was ziemlich intuitiv ist: die Codezeile, die Sie nicht schreiben, ist die einzige, in der Sie niemals Bugs haben werden. Einfachheit ist das Ziel. Und wie ich auf die harte Tour herausgefunden habe, ist die Komplexität der GUI (Front-End) oft eine direkte Folge der Komplexität des Back-Ends. Es gibt viele Leute, die den Mond anheulen, um die mystische Figur des UI/UX-Designers zu beschwören, in der Hoffnung, die furchtbare GUI von Darktable (kompliziert und inkonsistent) auf magische Weise zu lösen. Die GUI existiert nicht parallel zum Back-End, sie verdrahtet nur die vom Back-End erwartete Eingabe mit grafischen Bedienelementen. Das Front-End zu vereinfachen kann nicht ohne die Vereinfachung des Back-Ends geschehen, das ist nur ein dummes Dogma, ausgedacht von Leuten, die nur Soft Skills haben. Aber Back-Ends zu vereinfachen ist viel komplizierter, als nur Mockups zu zeichnen.
Wie sich herausstellt, ist das, was mit dem Great MIDI turducken geschah, in allen 3 Punkten gescheitert: Codevolumen, Codekomplexität, Codeabgeschlossenheit. Und die Darktable-Entwickler werden niemals aus ihren Fehlern lernen, wie Darktable 5.0 beweist. Als sich die Bugs bei den Tastenkürzeln im Laufe der Zeit in Ansel häuften (zusätzlich zu Funktionen, die vom Design her furchtbar sind), versuchte ich, sie auf Wegen zu beheben, die es vermieden, das Ganze neu zu schreiben, bis ziemlich klar war, dass ich die Neufassung nicht mehr viel länger würde vermeiden können.
Das nennt man technische Schuld . Der gesamte Code des Great MIDI turducken war dazu gedacht, einmal geschrieben zu funktionieren, nicht dazu, langfristig wartbar zu sein. Er ist im Grunde ein Proof of Concept, der es niemals in die Produktion hätte schaffen dürfen. Und der eigentliche Beweis seiner Unwartbarkeit ist, wie stark das Codevolumen und die Komplexität von Bugfix zu Bugfix zwischen Darktable 3.8 und 5.0 gewachsen sind, wodurch er sogar noch unwartbarer wird, während Bugs behoben werden. Das ist die Definition davon, sich in ein Spinnennetz zu kleben: je mehr Sie sich bewegen, desto mehr bleiben Sie stecken.
Mein Fehler ist vielleicht, dass ich 2022 begonnen habe, meine Kritik am (fehlenden) Management von Darktable zu äußern, nachdem ich den Beweis erhalten hatte, dass der desorganisierte Haufen von Mitwirkenden ihre Fehler niemals erkennen und daraus lernen würde. Wobei das selbst auferlegte und untragbare Arbeitstempo eher dazu geeignet war, Burnout zu erzeugen als Reflexion. Seitdem versucht Pascal Obry, der derzeitige selbsternannte Maintainer von Darktable, alle davon zu überzeugen, dass ich ein unerträgliches Teammitglied bin, unfähig, mit anderen Personen zusammenzuarbeiten, die mir widersprechen, das angefangen hat, alle zu beleidigen. Natürlich wurde keine spezifische und technische Antwort auf die Probleme gegeben, die ich in Darktable: crashing into the wall in slow-motion aufgeworfen habe, nur vage beruhigende Pauschalaussagen nach dem Motto „Darktable ist ein aktives Projekt, gesund, weil es viele Mitwirkende hat". Als ob mehr desorganisierte Affen am Ende einem Ingenieur gleichkämen, wenn man nur genug von ihnen hinzufügt.
Ich glaube, ich war 4 Jahre lang nichts als nett – in der Tat viel zu nett — bis ich erkannte, wie sehr diese Leute dem Projekt geschadet haben. Sie lernen nicht und werden niemals aus ihren Fehlern lernen, weil sie sie nicht einmal anerkennen werden, und die Entwicklung von Darktable 5.0 bestätigt nur den Trend. Aber dass sich immer mehr seltsame, zufällige und nicht reproduzierbare Bugs in den Bug-Trackern häufen, ist ein ziemlich klares Indiz dafür, dass etwas grundlegend falsch läuft. Zumal die Untersuchung dieser Bugs mich zu Archäologie in furchtbaren Codehaufen führte, die nicht einmal 2 Jahre alt waren, und obwohl mein Wissen und meine Erfahrung mit der Darktable-Codebasis über die Jahre gewachsen sind, nahm meine Fähigkeit ab, die eigentliche Ursache von Bugs zu beheben, und ich sah mich mit immer verwirrenderen Irrgärten aus Code-Indirektionen konfrontiert.6
Es ist schwer, all das Menschen zu erklären, die Computer als magische Kisten sehen, die von Tech-Zauberern entworfen wurden. Da drin gibt es keine Magie. Es ist größtenteils Mathematik und Anwendungen. Viele Entwickler werden gestehen, schlecht in Mathematik zu sein, was bedeutet, dass sie auch schlecht im Programmieren sind. Denn Mathematik besteht nicht nur darin, arithmetische Operationen auszuführen, sie ist eine ganze Disziplin des Geistes, die es erlaubt, komplexe Probleme zu abstrahieren, um sie in einfache Probleme zu zerlegen, die zu einfachem Code und einfacher GUI führen werden. Gute Programmierer verbringen viel Zeit damit, darüber nachzudenken, wie man wenig Code schreibt. Denn Code ist eine Haftung, Code ist technische Schuld, Code ist kostspielig in der Wartung. Also zahlen Sie die Schuld im Voraus, ohne Zinsen, indem Sie viel über Ihren Code nachdenken, bevor Sie ihn schreiben, statt zuerst zu programmieren und dann Jahre damit zu verbringen, Brände zu löschen.
All dies wirft auch die Frage auf, wem Open-Source-Code und Open-Source-Projekte gehören. Da der Gründer des Darktable-Projekts, Hanatos, das Schiff verlassen hat, ebenso wie die gesamte erste Generation von Entwicklern, aus verschiedenen Gründen, ernannte sich der letzte verbliebene Mann der ersten Generation zum neuen Maintainer. Er ist ein sehr fähiger und versierter Entwickler: sein Code ist sauber, ordentlich, und ich habe bislang keinen Bug in einer Zeile gefunden, in der git blame „Pascal Obry" sagte. Aber seine Politik in Bezug auf das Code-Management ist furchtbar: er glaubt, dass jeder Beitrag ein guter Beitrag ist, dass der „Schwung" von Beiträgen nicht gebremst werden sollte, und ist schlichtweg unfähig, „Nein" zu Beiträgen zu sagen, was bedeutet, dass nahezu alle Pull Requests gemergt werden. Es ist Frankreich im Jahr 1940: alles kommt herein, wird mit einem breiten Lächeln empfangen, und der Führer bekommt doppelt so viele Juden wie angefordert. Währenddessen werden die Widerstandskämpfer als Terroristen bezeichnet.
Aber es gibt einen riesigen Unterschied zwischen der Qualität des Codes, den Pascal schreibt, und der Qualität des Codes, den er akzeptiert und mergt. Das ist ein beunruhigendes Paradox, das seine Wurzeln zwischen der Angst, etwas zu verpassen und dem radikalen Technopositivismus findet, der zu Dogma und Glaubenssätzen neigt, mit einer völligen Missachtung von Design und Nutzerperspektive. Und vielleicht ein übertriebenes Vertrauen in die Fähigkeit der „Community", Bugs später zu beheben.
Es gibt viele Fälle, in denen es besser ist, nichts zu tun, als es falsch zu tun, besonders wenn Sie bestehende Funktionen ersetzen. Da Darktable ein nicht-destruktiver Code-Editor ist, investieren Sie in ihn, wenn Sie eine Datenbank von Bildbearbeitungen beginnen. Es sei denn, Sie planen, alle Ihre Bilder in hochauflösende Dateien mit hoher Bittiefe zu exportieren, sobald Sie mit der Bearbeitung fertig sind, um sie nie wieder zu ändern. Das schafft eine berechtigte Erwartung an langfristige Stabilität und Konsistenz, sodass Ihre alten Bearbeitungen weiterhin geöffnet, aufgefrischt und erneut exportiert werden können, vielleicht in neue Formate, vielleicht in höhere Auflösungen. Den Kurs im Anwendungsdesign zu ändern ist eine Art Vertragsbruch, und obwohl die GNU/GPL-Lizenz jede rechtliche Verantwortung aufhebt, hebt sie nicht die Schäden an den Nutzern auf. Ebenso wenig erstattet sie die Jahre meines Lebens, die ich verloren habe, um ihren Mist zu beheben.
Selbst wenn man also die entwicklerzentrierten Wartungsprobleme außer Acht lässt, gibt es auch eine Diskussion darüber zu führen, wer darüber entscheidet, wie alte und bewährte Funktionen ersetzt werden, besonders jene grundlegenden und universellen Funktionen von Desktop-Anwendungen wie die Handhabung von Dateien (Import, Export, Durchsuchen) oder die Interaktion mit Maus und Tastatur, die so lange so allgegenwärtig waren, dass die 2020er-Jahre 30 Jahre zu spät kommen, um vorzugeben, sie neu zu erfinden.
Viel Arbeit und viele Arbeitsstunden wurden investiert, um die Tastaturkürzel zu verschlechtern, um fehlerhafter Politik und schädlicher Dogmen willen, zusätzlich zu Wunschdenken und Social Loafing , bei dem alle hoffen, dass sich Die Community® (auch bekannt als jemand anderes) darum kümmern wird, ihre eigenen Fehler zu beheben. Die Nutzer mussten außerdem ihre Tastaturkonfiguration verlieren und waren gezwungen, alles zurückzusetzen und alles neu zu lernen. Aber es auf die richtige Weise zu tun, hätte tatsächlich weniger Arbeit und weniger Arbeitsstunden gekostet. Das ist eine sich selbst nährende Schleife des Wahnsinns, die ein toxisches Arbeitsumfeld schafft, in dem Instabilität weitere Instabilität fördert, in dem Komplexität weitere Komplexität fördert, und das wiederum ohne irgendeine Art von Funktions-Roadmap, die allen Beteiligten eine allgemeine Richtung und Sichtbarkeit geben würde.
Eine kurze Geschichte des schlechten Designs
Erst nachdem ich die Tastenkürzel-Funktion von Grund auf neu rekonstruiert hatte, verstand ich, was bei den Tastenkürzeln/Accelerators von Darktable schiefgelaufen war.
Zunächst gibt es diese lähmende Zügellosigkeit an Funktionen, die es verlockend macht, die GUI zu entrümpeln, indem man Funktionen einfach versteckt, nur um sie dann über die Tastatur zu bedienen. Das Problem ist dann, dass solche Funktionen nicht immer Nischen- und optionale Funktionen sind (wie das Tastenkürzel, das die Maskeninteraktionen umgeht, wenn man die Hauptbildvorschau in der Dunkelkammer per Drag-and-Drop verschiebt), sondern für Nutzer definitiv nicht auffindbar sind. Ansel hat dieses Problem mit dem globalen Menü gelöst.
Einige Funktionen waren über eine grundlegende Vimkeys-Unterstützung versteckt, wenn Sie beginnen, : einzugeben: :q beendet die Anwendung, :set gefolgt vom Namen des Schiebereglers oder der Combobox ändert den Wert. Das ist natürlich nirgendwo im Darktable-Handbuch dokumentiert, und als Nutzer von Darktable seit mehr als einem Jahrzehnt hatte ich noch nie davon gehört, bevor ich seinen Code löschte, denn dieser kleine Scherz lauscht all Ihren Tastenanschlägen, um zu bestimmen, ob er auf Ihre Eingabe reagieren soll oder nicht.
Aber dann gibt es auch die Tatsache, dass Module selbstgebaute Gtk-Widgets verwenden (namens „Bauhaus", in src/bauhaus/bauhaus.c), die nicht alles implementieren, was man von einem GUI-Widget erwarten würde, das Nutzerereignisse erfasst, insbesondere nicht die Barrierefreiheits-Funktionen.
Eine der grundlegendsten Barrierefreiheits-Funktionen ist die Fähigkeit, durch fokussierbare Widgets zu wechseln. Im GUI- (und Gtk-)Jargon ist ein fokussierbares Widget eines, das Tastenanschlag-Ereignisse erfassen kann, sobald es fokussiert ist. Widgets werden typischerweise fokussiert, sobald man sie anklickt, aber Gtk verwaltet auch intern eine Fokuskette , in der Sie mit der Tab-Taste und den Pfeiltasten navigieren. Das erste Problem ist, dass die Tab-Taste in Darktable dem „Vorschau"-Modus zugewiesen war (Ein-/Ausschalten aller Panels in der Ansicht). Und tatsächlich wäre dies mit nativen Gtk-Accelerators überhaupt nicht möglich gewesen, da Tab von Gtk belegt und in nutzerdefinierten Tastenkürzeln verboten ist, aber da Darktable seinen eigenen Tastenkürzel-Handler implementierte, schon vor dem Great MIDI turducken, wurde es überschrieben. Somit wurde das tabulatorbasierte Durchlaufen der Fokuskette einfach deaktiviert, weil die Tab-Taste etwas anderem zugewiesen war. Aber das zweite Problem war, dass die selbstgebauten Bauhaus-Widgets auch alle Pfeiltasten-Anschläge erfassten. Somit war auch das Navigieren zwischen Bedienelementen in sequenzieller Weise (nächstes/vorheriges) vom Design her völlig unmöglich. Genau wie die Bauhaus-Widgets alle Maus-Scroll-Ereignisse erfassten, was das Scrollen der Seitenpanels verhinderte.
Da eine sequenzielle/inkrementelle Navigation zwischen fokussierbaren Widgets vom Design her unmöglich war, mussten notwendigerweise alle Tastaturinteraktionen absolut gemacht werden: für jeden Schieberegler, für jede Combobox hätten Sie ein Tastenkürzel, das den Wert direkt zugeordnet erhöht/verringert/zurücksetzt.
Aber weitere Probleme entstanden, als Module mehrfach instanziierbar gemacht wurden, denn Bedienelemente wurden durch einen Accelerator-Pfad wie view/module/slider/increase oder view/module/slider/decrease identifiziert, aber alle Modulinstanzen erbten denselben Pfad. Das löste die Notwendigkeit aus, all das zur Laufzeit zu verwalten, mit Nutzereinstellungen, um zu entscheiden, ob das anvisierte Modul das erste, letzte oder zuletzt bediente Modul sein sollte.
All das auf MIDI und Gamepads zu verallgemeinern, machte es nur noch schlimmer, denn zusätzlich dazu, ein Tastenkürzel pro möglicher Aktion pro Widget zu haben, gab es dann die Notwendigkeit, die Emulation typischer Desktop-Interaktion von anderen Eingabegeräten zu verwalten. Aber statt die Emulationsschicht auf hoher Ebene zu verwalten, an der Schnittstelle zwischen MIDI und regulären Tastatur-/Maus-Tastenkürzeln, hat ein furchtbarer Entwickler eine Abstraktionsschicht von Aktionen völlig überentwickelt, eingebettet in Module, native Gtk-Widgets (als Overlay) und selbstgebaute Bauhaus-Widgets (tief eingebettet). Das Problem ist, dass diese Abstraktionsschicht nicht wirklich eine Schicht war, sondern eher wie ein metastasierender Tumor, der sich überall ausbreitet. Ihn und all seine Abhängigkeiten zu entfernen, führte zum Entfernen von 7674 Zeilen, verteilt über 163 Dateien, obwohl er eigentlich in src/gui/accelerators.c (4412 Zeilen Code, Kommentare und Leerzeilen) implementiert sein sollte.
Tastaturkürzel/Accels von Grund auf neu gestalten
Der nullte Schritt der Neugestaltung sind diese 2 einfachen Anforderungen:
- Jede Aktion sollte in der GUI auffindbar sein, Tastaturkürzel sind nicht dazu gedacht, die GUI zu entrümpeln; das Entrümpeln der GUI ist eine Frage des Aufbrechens des Arbeitsablaufs in einzelne Schritte und des Präsentierens nur derjenigen Bedienelemente, die für den aktuellen Schritt von Bedeutung sind.
- Die Software sollte vollständig allein mit der Maus und allein mit der Tastatur bedienbar sein. Gemischte Interaktion sollte völlig optional sein.
Die erste Einschränkung der Neugestaltung besteht daher darin, absolute Tastenkürzel völlig optional zu machen, das heißt, den Tastatur-Arbeitsablauf für einen sequenziellen/relativen Zugriff zu gestalten (das Wechseln zwischen nächstem/vorherigem Bedienelement).
Interaktion mit fokussierten Bedienelementen
Das geteilte Paradigma „fokussieren" und dann „interagieren" (das ich nicht erfunden habe…) ist sehr mächtig, weil es erlaubt, Tastenanschläge in den richtigen Kontext einzugrenzen, was bedeutet, dass dieselben Tastenanschläge (insbesondere die Up/Down/Right/Left-Pfeiltasten) mehr als einmal in der GUI angehängt werden können und je nachdem, welcher Kontext den Fokus hat, unterschiedlich behandelt werden. Das ist flexibler und tatsächlich einfacher7 als die Darktable-Obsession, alles mit globalen, absoluten Tastenkürzeln zu verdrahten, die dann bei oft wiederverwendeten Tasten kollidieren würden und dazu führten, dass man als Behelfslösung immer mehr Tastenmodifikatoren hinzufügen musste.
Bislang gab das Navigieren durch die Bedienelemente ihnen nur Fokus. Was ist mit der tatsächlichen Interaktion?
In der Leuchttisch-Ansicht, sobald das Vorschaubild-Raster fokussiert ist, erfolgt die Navigation durch die Vorschaubilder mit den typischen Pfeiltasten, Page Up/Down usw. (siehe die Dokumentation für alle Details), und Bildauswahlen können auf verschiedene Weisen (Stapel, Serie, einzeln) auch über die Tastatur getroffen werden.
In der Dunkelkammer-Ansicht kann das Ändern von Werten an Schiebereglern und Comboboxen mit den Pfeiltasten erfolgen (möglicherweise mit Shift für einen groben Schritt oder Ctrl für einen feinen Schritt), das Auslösen des Farbwählers (an Schiebereglern, die ihn unterstützen) erfolgt mit Insert usw. (lesen Sie auch hier die Dokumentation für Details).
Also, nochmals, bislang kein nutzerdefiniertes Tastenkürzel, keine kryptische Tastenkombination zum Merken, es sind größtenteils Pfeiltasten, und dennoch kann auf alles zugegriffen werden.
Absolutes Fokussieren von Bedienelementen
Das ist alles großartig, aber es lässt Sie auf einer Art Ikea-Parcours zurück, wenn Sie direkt auf einen bestimmten Bereich der Anwendung zugreifen müssen, Sie aber durch alle Abschnitte von der Eingangstür an navigieren müssen.
Um dem abzuhelfen, war eine sehr alte Darktable-Funktion die Registerkarte „Lieblingsmodule", also eine spezielle Registerkarte, die die GUI der meistgenutzten Module basierend auf Nutzerwahl duplizierte. Das löst im Grunde Aufgeblähtheit mit mehr Aufgeblähtheit, und dennoch haben die Nutzer das sehr liebgewonnen. Wenn wir uns jedoch auf das Ziel konzentrieren statt auf das Mittel, ist die Anforderung ein schneller Zugriff auf beliebige Module, was vollkommen verständlich ist.
Dies wurde also neu implementiert als eine Möglichkeit, ein absolutes Tastenkürzel zu definieren, das sofort ein Bildverarbeitungsmodul oder eines seiner internen Bedienelemente fokussiert. Das Fokussieren eines versteckten Moduls oder Bedienelements lässt es automatisch in der GUI erscheinen. Von dort aus erfolgt die weitere Interaktion genau wie zuvor, mit einheitlichen Tastenkombinationen. Das reduziert die Anzahl der zu konfigurierenden Tastenkürzel erheblich, macht das Ganze generischer und das Einstellungsfenster der Tastenkürzel viel einfacher.
Absolute Tastenkürzel können auch auf Menüeinträge abzielen (auch bekannt als globale Aktionen), in welchem Fall sie im Menü, neben dem Aktions-Label, angezeigt werden, was wiederum eine native Gtk-Funktion ohne jeglichen Overhead ist.
MIDI-Controller ersetzen
Wenn wir all den Hype beiseitelassen, dedizierte Controller zu haben und sich wie ein Flugzeugpilot zu fühlen, ist das Einzige, was MIDI-Controller haben und was Tastatur und Maus niemals haben werden, die Fähigkeit, Potentiometer (Drehknöpfe) direkt an GUI-Schieberegler anzuhängen. Aber dann besteht der Preis dafür darin, ein zusätzliches Gerät zu haben, das Platz (und Staub) auf Ihrem Schreibtisch einnimmt, ganz zu schweigen von zukünftigem Elektronikmüll. Alle Fotografen, die ich kenne, die MIDI-Geräte oder Loupedecks gekauft haben, verstauten sie „vorübergehend", um etwas Schreibtischfläche zurückzugewinnen… und holten sie nie wieder aus dem Lager.
Bildverarbeitungs-Bedienelemente können mit Einzeltasten-Kürzeln verdrahtet werden, weil Ansel ein benutzerdefiniertes Tastenkürzel-Overlay über den nativen Gtk-Accelerator-Funktionen verwendet. Ich habe die selbstgebauten Bauhaus-Widgets so modifiziert, dass, wenn man eines der obigen absoluten Fokussierungs-Tastenkürzel drückt und gedrückt hält, das Mausrad-Scrollen direkt auf das Widget abgebildet wird, selbst wenn die Maus nicht über dem richtigen Schieberegler liegt.
Indem man also Ein-Buchstaben-Tastenkürzel zum Fokussieren eines Bedienelements mit dem Maus- (oder Touchpad-)Scrollen kombiniert, erhält man all die Vorzüge der MIDI-Drehknöpfe ohne das zusätzliche Gerät, die zusätzliche Bibliothek zur Unterstützung und die Wunderwerke überentwickelter Emulationsschichten.
Aber all das geschieht immer noch mit dem einen und einzigen absoluten Tastenkürzel, sodass Sie nicht mehrere Tastenkürzel pro Bedienelement definieren und sich merken müssen, nur um sich dann ohne verfügbare Tastenkombinationen wiederzufinden.
Aktionen ohne Tastenkürzel, Suchmaschine und vimkeys-artige Auslöser
Mein Tastenkürzel-Handler ist ein dünner Wrapper über der nativen Accelerators-API von Gtk. Als solche wird eine Aktion durch einen Textpfad definiert, wie Ansel/Darkroom/Modules/Exposure/Black level, der eine eindeutige Kennung ist, lesbar sowohl von einem Computer als auch von einem Menschen. Die GUI deklariert eine an jeden dieser Pfade angehängte Funktion, die den auszuführenden Code enthält, um die entsprechende Aktion anzuwenden. Dann bildet der Tastenkürzel-Handler eine Tastenkombination auf diesen Pfad ab.
Also, wann immer ein Nutzer einige Tasten drückt, schlägt der Tastenkürzel-Handler nach, ob wir einen bekannten Pfad für diese Kombination haben, und wenn er einen findet, löst er die daran angehängte Funktion aus. Das ist ein narrensicheres Design, das nichts über das Innere der Ansel-Module, selbstgebauten Widgets usw. weiß. So kann es ohne Overhead auf viele Teile der Software erweitert werden.
Aber es ist tatsächlich viel mächtiger als nur das. Denn indem wir alle bekannten Pfade auflisten, können wir dann Pfade zurückgeben, die einer Textsuchanfrage entsprechen (Suche nach einem Bedienelement, Modul oder globalen Menüeintrag nach Namen), also alle Aktionen aus einer Liste finden, aber wir können sie dann auch auslösen, obwohl sie an kein Tastenkürzel angehängt sind.

Da Bildverarbeitungsmodule auf diese Weise ebenfalls gefunden und angezeigt werden können, ersetzt dies auch die Modul-Suchmaschine und gewinnt etwas vertikalen Platz für lange Module und ihre Maskierungs-/Überblendungsoptionen zurück (und entfernt rund 200 Zeilen Code). Von dort aus habe ich sie auf alle Werkzeugkästen erweitert und global gemacht, was bedeutet, dass die Aktions-Suchmaschine in allen Ansichten funktioniert, aber nur die für die aktuelle Ansicht relevanten Aktionen auflistet.
In der Dunkelkammer unterstützt sie auch Modul-Mehrfachinstanzen, was es erlaubt, direkt auf eine bestimmte Instanz abzuzielen (mehr dazu in der Dokumentation).
Standardmäßig ist die globale Aktionssuche auf das Ctrl+P-Tastenkürzel abgebildet und kann über das globale Menü Hilfe oder mit einer Schaltfläche Aktionen suchen in der Mitte der Kopfleiste aufgerufen werden. Dies ersetzt auch gewissermaßen die Vimkeys, die eine sehr partielle Unterstützung von GUI-Aktionen hatten (und die Accelerators vollständig hätten duplizieren müssen, um sie auf einen nützlichen Stand zu erweitern), sodass Sie, statt : gefolgt von einem Befehl einzugeben, Ctrl+P drücken und entweder den Pfad der Aktion eingeben oder eine Anfrage beginnen und aus der Liste der Treffer auswählen können (mit den Pfeiltasten und dann Enter).
Die Treffer werden nach absteigender Relevanz sortiert (von oben nach unten), und die Relevanz wird aus der Position des Treffers berechnet. Die Annahme hier ist, dass, da Aktionspfade von links nach rechts von generisch zu spezifisch verlaufen (view/module/control), Texttreffer, die am Ende des Pfades auftreten, eher Bedienelemente als Module oder Ansichten treffen sollen, die wir als spezifischer und daher relevanter erachten. Dies kann vermeiden, dass man an all den Modulinhalten vorbeiscrollen muss, die einer Textanfrage bei der Suche nach einem Bedienelement entsprechen könnten.
Fenster zum Bearbeiten von Tastenkürzeln
Da es jetzt nur ein nutzerkonfigurierbares Tastenkürzel pro Bedienelement gibt, ist die GUI zum Auflisten und Bearbeiten von Tastenkürzeln ein einfacher Baum:

Es genügt, in die Spalte Tasten zu doppelklicken, um mit der Aufzeichnung einer neuen Tastenkombination zu beginnen. Da es so einfach ist, ersetzt dieses Fenster auch das Cheatsheet auf einen Schlag. Tastenkürzel können nach dem Namen der Aktion oder nach den verwendeten Tasten nachgeschlagen werden, und die Tastensuche verfügt über Auto-Vervollständigung für Tastenmodifikatoren (Details in der Dokumentation). Das Tastenkürzel-Popup kann über das globale Menü Bearbeiten → Tastaturkürzel… angezeigt werden.
Dokumentation innerhalb der Software
Die Sache ist die: Eine aktuelle Dokumentation der Standard-Tastenkürzel zu pflegen, ist mühsam, weil sie zu kleinteilig ist. Es ist die Art von Dokument, das schon veraltet ist, sobald man mit dem Schreiben fertig ist. Da die Standard-Tastenkürzel ohnehin in der Anwendung implementiert werden müssen, ist der beste Ort, sie zu dokumentieren, direkt darin selbst, sodass die Aktualisierung automatisch erfolgt.
Darktable hatte 2 redundante Oberflächen für Tastenkürzel, eine zum Einrichten der Kürzel und eine andere Art „Spickzettel"-Popup (das lange Zeit nur über… ein Tastenkürzel zugänglich war. So viel zum Thema Auffindbarkeit). Der Grund war, dass das Einstellungs-Popup viel zu überladen war, um als eine Art Kurzübersicht zu dienen. Dann wurden Tastenkürzel in die Tooltips einiger Bedienelemente aufgenommen… Tooltips, die nur erscheinen, wenn man mit der Maus über die Bedienelemente fährt. Wie unsinnig ist es, dass man die Maus benutzen soll, um Fall für Fall herauszufinden, wie man die Tastatur benutzt?
Ansel hat Tastenkürzel (Tastenkombinationen), die im Einstellungs-Popup aufgeführt und auch in der globalen Aktionssuche wieder aufgerufen werden. Aber diese Tastenkürzel beschränken sich nicht auf die vom Benutzer konfigurierbaren; ich habe den Tastenkürzel-Handler um „virtuelle Tastenkürzel" erweitert, also Tastenkürzel, die im Grunde keiner Aktion zugeordnet, aber genau wie der Rest deklariert sind und unter den übrigen als „gesperrte" Tastenkürzel erscheinen.

Diejenigen Tastenkürzel, die als kontextbezogene Interaktion bei Fokus beschrieben sind, dokumentieren die generischen Aktionen, die auf das fokussierte Bedienelement abzielen, unabhängig davon, ob das Bedienelement relativ oder absolut fokussiert wurde.
Implementierungsdetails
Der Quellcode für das gesamte Tastenkürzel-Handler-System, einschließlich der GUI-Teile (globale Aktionssuche und Bearbeitungs-Popup für Tastenkürzel), umfasst 1144 Codezeilen, wovon die Hälfte auf die GUI entfällt, bei einer zyklomatischen Komplexität von 216 . Das ist ein Fünftel des Codevolumens bei einem Sechstel der Komplexität (verglichen mit Darktable 5.0), obwohl es zusätzliche Funktionen bietet (Tastensuche mit Auto-Vervollständigung, globale Suche, explizite Ziele für Modulinstanzen usw.). Die MIDI-Unterstützung wurde fallengelassen, weil ich, ganz ehrlich, nicht sehe, welches Problem sie löst, das nicht bereits durch das aktuelle, einfachere Design gelöst wird.
Die einer Tastenkombination zugeordnete Aktion zu finden, dauert rund ein Dutzend Nanosekunden, während der große MIDI-Turducken 10 bis 50 Millisekunden pro Tastendruck benötigte.8
Der Abhängigkeitsgraph dieser Funktion ist in der Entwicklerdokumentation zu sehen, er ist viel sauberer als der vorherige Spaghetti-Teller. Der übrige GUI-Code von Ansel interagiert mit dem Tastenkürzel-Handler, indem er neue Accelerator-Pfade deklariert, ihnen zugeordnete Callback-Funktionen registriert und möglicherweise Standard-Tastenkürzel, all das mit einer einzigen Methode aus der API. Die Tastenkürzel-Behandlung ist unabhängig von und immun gegen Ansel-Interna, insbesondere weiß sie nichts über Module oder selbstgebaute Bauhaus-Widgets, sodass das Design vollständig in sich geschlossen ist. Die Einstellungen werden pro Sprache in ~/.config/ansel/keyboardrc-LANG gespeichert, unter Verwendung einer nativen Gtk-Accelerator-Map . Die API ist in der Ansel-Entwicklerdokumentation vollständig dokumentiert für künftige Wartung und Erweiterung, sodass kein Reverse Engineering nötig sein wird.


So arbeite ich, weil ich nicht zum Spaß programmiere. Programmieren macht mir keinen Spaß. Ich löse Probleme und versuche dabei, keine neuen zu schaffen.
Schlussfolgerung
Dies ist das Musterbeispiel für alles, was bei Darktable in Bezug auf unerbittliches Over-Engineering schiefgelaufen ist, und dafür, wie es hätte behoben werden sollen. Die hier vorgeschlagene Lösung ist besser, weil:
- die gesamte GUI über die Tastatur navigiert werden kann, ohne sich ein einziges Tastenkürzel merken zu müssen,
- Bedienelemente, Module und andere Aktionen nur ein einziges direktes, absolutes, vom Benutzer konfigurierbares Tastenkürzel haben, das die Aktion direkt auslöst oder das Bedienelement fokussiert, sofern vorhanden, was die Einstellungs-GUI deutlich weniger überwältigend macht und die Notwendigkeit eines zusätzlichen Spickzettel-Popups beseitigt,
- Aktionen global durchsuchbar und auslösbar sind, unabhängig davon, ob sie an eine Tastenkombination gebunden sind oder nicht,
- Taste+Scroll-Mischinteraktionen ohne zusätzlichen Aufwand ausgelöst werden können, wodurch MIDI-Drehknöpfe und -Schieberegler emuliert werden, ohne dass zusätzliche Hardware nötig ist,
- Der Code objektiv 5- bis 6-mal einfacher ist (je nachdem, welche Metrik man betrachtet),
- Das Ganze vollständig dokumentiert und im Code ausführlich kommentiert ist,
- Jeder künftige hirntote Idiot, der C lesen kann, in der Lage sein wird, dieses Ding zu warten, das ohnehin nicht viel Wartung benötigen sollte, weil es nichts Cleveres tut und außerhalb des Kerns der Software lebt.
Translated from English by : ChatGPT, Claude. In case of conflict, inconsistency or error, the English version shall prevail.
A turducken is a chicken stuffing a duck stuffing a turkey. That’s a decadent amount of meat that will likely go to waste, unless you have 20 persons to feed. Anyway, it will take forever to cook, and the turkey will likely be dry by the time the chicken is well done. ↩︎
Developers call that “whack-a-mole bug fixing” . ↩︎
Although the stress and anxiety inflicted upon workers by ever-changing software stacks is largely underrated, since innovation is deemed to increase productivity by definition, regardless of user feedback. ↩︎
STEM: Science Technology Engineering Mathematics ↩︎
I don’t see why the capitalistic mindset is ok when it comes to getting excited about new products, but gets boring when it reaches return on investment and hidden/sunk costs… ↩︎
I’m not talking here about the Darktable way of “fixing bugs” that consists into rushing on the visible manifestation of the bug, and adding a fourth level of nested
ifto take care of the pathological corner case. That’s working around the cause of the bug by creating more technical debt, not actually fixing the root cause of the bug. And since that root cause will generally stem many visible manifestations, patching all the manifestations is actually more complicated on the long run, and leads to brittle code. ↩︎Flexibility is usually the opposite of simplicity, so you have to enjoy when you can win on both fronts. ↩︎
Remember that the shortcut handler has to listen to all keystrokes before deciding if it’s supposed to do something with them or discard them, so this part of the software runs all the time for all users, whether or not they actually use shortcuts. ↩︎