Darktable hat seine eigenen GUI-Widgets-Bibliothek für Schieberegler und Kombinationsboxen (auch Drop-Down-Menüs oder Auswahllisten genannt), genannt Bauhaus (im Quellcode unter src/bauhaus/bauhaus.c
). Während sie Gtk als Backend verwenden, sind Bauhaus benutzerdefinierte Objekte. Und wie vieles bei Darktable, gleich benutzerdefiniert verfault.
Im Jahr 2022 bemerkte ich Parasiten-Neuzeichnungen und Lags bei deren Nutzung, was zu einem frustrierenden Benutzererlebnis führte: Das Widget-Neuzeichnen schien darauf zu warten, dass Pipeline-Berechnungen abgeschlossen waren, was bedeutete, dass Benutzer nicht wirklich sicher waren, ob ihre Wertänderung registriert wurde, was sie dazu bringen könnte, es erneut zu versuchen, einen weiteren Zyklus teurer Neuberechnungen zu starten, und ihren Computer tatsächlich für mehrere sehr frustrierende Minuten nutzloser Zwischenpipeline-Berechnungen einfror.
Wie es der Zufall wollte, fanden statische Code-Analyse-Tools heraus, dass die Bauhaus-Bibliothek auch die 4. komplexeste Quellcodedatei im gesamten Darktable-Software hinsichtlich der Zyklen-Komplexität ist, mit einem Wert von 735 und einer technischen Schuld von geschätzten 1 Tag und 7 Stunden. Wenn Sie kein Programmierer sind, misst die Zyklen-Komplexität die Anzahl der verschiedenen Pfade, die der Code nehmen kann, und hohe Werte machen ihn nicht nur schwerer zu verstehen (und damit zu debuggen), sondern auch anfälliger für Ausnahmefälle, Fehler und kontextabhängig seltsame Probleme. Die Zyklen-Komplexität ist eine indirekte Metrik für die Wahrscheinlichkeit, dass dieser Code explodieren wird, wenn Sie es am wenigsten erwarten, etwas, das zu beachten ist, wenn die produktivsten „Entwickler“ in Ihrem Team ein Grundschullehrer, ein Kinderarzt und ein Bankberater sind.
Was besonders frustrierend war, ist, dass ich bereits 2019 daran gearbeitet hatte, diese Datei zu vereinfachen. Drei Jahre später war es, als hätte ich nichts getan, dank Feature Creep und MIDI/Gamepad-Unterstützung. Als die Parasiten-Neuzeichnungen auftauchten, war ich mit unverständlich Spaghetti-Code konfrontiert, den ich ordentlich nicht beheben konnte. Ein erster Versuch, falsche Sachen zu korrigieren, führte im August 2022 zu einer Sackgasse und entmutigte mich. Zu versuchen, das umzugehen, war nicht die Lösung.
Also musste ich es fast vollständig neu schreiben, was keinen Spaß machte und mir eine verrückte Menge an Stunden kostete (ich hörte auf zu zählen bei 3 Wochen, Vollzeit, und das war für den zweiten Versuch im August–November 2023).
Wussten Sie, dass, sobald eine Kombination Focus hatte (entweder, weil Sie darauf geklickt hatten oder den Fokus per Tastenkombination hatten), Sie anfangen konnten, die ersten Buchstaben des Labels zu tippen, das Sie auswählen wollten, und es würde automatisch das nächste Element in der Liste auswählen? Wusste ich auch nicht, bevor ich diese Aufgabe übernommen habe, weil es nirgendwo dokumentiert ist. Ebenso wenig wie viele andere versteckte Funktionen dort, die hinzugefügt wurden, um deviante und marginale Anwendungsfälle zu berücksichtigen, aber die Code-Struktur für alle komplexer machten. (Spoiler-Alert: Ich behielt diese spezielle Funktion, entfernte jedoch andere).
Liste der Verbesserungen
- Die Cursor-Koordinaten (in Pop-Ups) werden nur an einem Ort berechnet und dann gespeichert. Dies spart viele Zwischenberechnungen, von denen einige inkonsistent waren, da der Code kopiert und anstatt über Getter und Setter verwendet wurde. Jetzt werden Koordinatenabweichungen und Änderungen durch einheitliche Getter und Setter bearbeitet, was bedeutet, dass jede zukünftige Änderung nur an einer Stelle erfolgen muss und der gesamte Code dies nutzt.
- Neue Werte (aus Schiebereglern und Kombinationsboxen) werden nicht mehr beim Scrollen oder Ziehen und Ablegen an die Pixel-Pipeline gesendet, sondern nur am Ende. Dies basiert auf einer maschinengelernten Timeout-Aufzeichnung der durchschnittlichen Zeit, die für die Berechnung einer vollständigen Pipeline benötigt wird. Das GUI wartet zwischen 20 ms und 2,5 Sekunden, um Änderungen zu senden, was verhindert, dass bei jedem Scroll- oder Drag-Vorgang unnötige und redundante, aber teure Berechnungen durchgeführt werden, die die Software nur verzögern. Ähnlich werden sie jetzt nur beim Ereignis „Maus-Taste losgelassen“ gesendet, anstatt bei den „Maus-Taste gedrückt“ und „Maus-Taste losgelassen“-Ereignissen (gegeben, dass ein typischer Mausklick beide Ereignisse sendet). Dies sollte eine Menge unnötiger Pipeline-Neuberechnungen ersparen.
- Widgets werden sofort bei Benutzeraktionen vor den neuen Werten an die Pixel-Pipeline gezeichnet. Dies garantiert sofortiges Benutzerfeedback, auch wenn das tatsächliche Pixelergebnis später kommt, und begrenzt Frustrationen auf langsamen Rechnern.
- Es werden keine Wertänderungsereignisse gesendet, wenn die Widgets Benutzerinteraktion erhielten, aber ihr Wert sich tatsächlich nicht änderte.
- Klicken auf den Chevron (den rechten Pfeil) der Kombibox erfassen. Früher musste man auf das Label klicken, um das Drop-Down-Menü der Kombibox zu öffnen, was super frustrierend war, wenn man aus Software mit einer ordentlichen GUI kam. Der Chevron selbst reagierte nicht auf Klicks.
- Kombiboxen-Drop-Downs nicht scrollen. Diese Funktion begann als cooles Projekt: das derzeit ausgewählte Element mit dem Label abzugleichen. Problem ist, dass die Positionierung des Drop-Down-Popups letztendlich von der Desktop-Umgebung gehandhabt wird, wir können sie nur höflich bitten, das zu tun, was wir wünschen, aber es gibt keine Garantie, dass unsere Wünsche erfüllt werden. Außerdem ist es möglich, das Popup außerhalb des Ansichtsbereichs rollen zu lassen, nichts verhindert dies. Alles in allem ist es anfällig und zufällig, besser bleibt man bei der Standard-Fensterpositionierung.
Veraltete Funktionen
Die Möglichkeit, Tastaturkürzel Schiebereglern und Kombiboxen zuzuweisen, wurde derzeit entfernt. Schieberegler und Kombiboxen sind ohnehin mit Pfeiltasten und dem Mausrad sobald sie den Fokus haben1 verknüpft, und es ist immer noch möglich, Fokus Aufnahme einem Tastenkürzel zuzuweisen. Die derzeitige Logik besteht darin, den Fokus durch Tastaturkürzel anzufordern und dann den Wert mit den Pfeiltasten zu bearbeiten. Fokusanforderungen machen das Widget auch automatisch in der GUI sichtbar, indem die Seitenleiste gegebenenfalls gescrollt wird.
Wie auch immer, das aktuelle Kürzel-System wird vollständig durch native Gtk-Beschleuniger ersetzt werden müssen, die bereits für das globale Menü verwendet werden (und in Darktable vor 2021 verwendet wurden). Derzeit haben wir beide Systeme, eines davon ist ein Ungetüm mit enormer Komplexität und wahrscheinlich verantwortlich für die Verlangsamungen. KISS.
Vorsicht
Das „Format“-Kombibox im Export-Modul initialisiert seinen Wert nicht richtig. Dies ist ein nicht standardmäßiges Bauhaus-Widget, das besondere Aufmerksamkeit erfordert. Bislang müssen Sie die Speicheroption aktualisieren oder eine Voreinstellung neu laden.
Wann immer Sie die brüchige alte Farbe, die die rostigen Wände hielt, entfernen, riskieren Sie, Kollateralschäden zu verursachen. Seien Sie vorsichtig mit Ansel bei Verwendung der AppImage und Win EXE markiert Ansel-57ed58d ab heute Abend und melden Sie alles Seltsame.
Downloads
Technische Details
Die aktuellen Änderungen haben reduziert:
- zyklische Komplexität von 735 auf 494
- kognitive Komplexität von 796 auf 432
- technische Schulden von 1 Tag und 7 Stunden auf 4 Stunden und 50 Minuten.
Wenn Sie kein Programmierer sind, bedeuten diese Metriken einfach, dass der Code in Zukunft leichter und weniger zeitaufwendig zu warten ist und wahrscheinlich weniger fehleranfällig ist.
Translated from English by : ChatGPT. In case of conflict, inconsistency or error, the English version shall prevail.
In GUI programming, a widget has the focus when it is the one recording keyboard events. Text entries are the most obvious example, but Darktable hacked that concept to generalize to pretty much every widget. ↩︎