Darktable tiene su propia biblioteca de widgets de GUI, para sliders y comboboxes (también conocidos como menús desplegables o cuadros de selección), llamada Bauhaus (en el código fuente, está en src/bauhaus/bauhaus.c
). Aunque usan Gtk como backend, Bauhaus son objetos personalizados. Y como muchas cosas en Darktable, personalizado equivale a podrido.
En 2022, noté redibujados parásitos y retrasos , al usarlos, lo que lleva a una experiencia de usuario frustrante: el redibujado del widget parecía esperar a que se completaran las recomputaciones del pipeline, lo que significaba que los usuarios no estaban realmente seguros de que su cambio de valor se registrara, lo que podría llevarlos a intentarlo de nuevo, comenzando otro ciclo de recomputación costosa, y congelando efectivamente su computadora durante varios minutos muy frustrantes de recomputaciones de pipeline intermedias inútiles.
Resulta que las herramientas de análisis de código estático encuentran que la biblioteca Bauhaus también es el 4º archivo de código fuente más complejo en todo el software Darktable en términos de complejidad ciclomática, con un puntaje de 735 y una deuda técnica estimada en 1 día y 7 horas. Si no eres programador, la complejidad ciclomática mide el número de caminos diferentes que el código puede tomar, y valores altos lo hacen no solo más difícil de entender (y por lo tanto de depurar), sino también más propenso a casos extremos, errores y problemas extraños dependientes del contexto. La complejidad ciclomática es una métrica indirecta de la probabilidad de que este código estalle en tu cara cuando menos lo esperas, algo a tener en cuenta cuando los “desarrolladores” más prolíficos de tu equipo son un maestro de escuela primaria, un pediatra y un consultor bancario.
Lo que es particularmente frustrante es que ya trabajé para simplificar este archivo en 2019. 3 años después, fue como si no hubiera hecho nada, gracias al aumento de funciones y al soporte de MIDI/gamepad. Cuando aparecieron los redibujos parásitos, me quedé con un código espagueti ininteligible que no pude arreglar adecuadamente. Un primer intento de corregir errores llevó a un callejón sin salida, en agosto de 2022, y me desanimó. Intentar rodearlo no iba a funcionar.
Así que tuve que reescribirlo casi por completo, lo cual no fue divertido y me llevó una cantidad de horas tremenda (dejé de contar a las 3 semanas, a tiempo completo, y eso fue para la segunda tentativa en agosto-noviembre de 2023).
Sabías que, una vez que un cuadro combinado tenía el foco (ya sea porque hiciste clic en él o le diste el foco a través de un atajo de teclado), podías comenzar a escribir las primeras letras de la etiqueta que querías seleccionar y automáticamente seleccionaría el elemento más cercano en la lista? Yo tampoco lo sabía antes de emprender esta tarea, porque no está documentado en ninguna parte. Como muchas características ocultas en él, añadidas para cumplir con casos de uso desviados y marginales, pero complejizando la estructura del código para todos. (Spoiler alerta: mantuve esta característica particular, pero eliminé otras).
Lista de mejoras
- Las coordenadas del cursor (en ventanas emergentes) se calculan solo en un lugar, luego se almacenan. Eso ahorra muchas recomputaciones intermedias, algunas de ellas inconsistentes porque el código se copió y pegó y se duplicó en lugar de usar getters y setters . Ahora, los desplazamientos y cambios de coordenadas se manejan a través de getters y setters unificados, lo que significa que cualquier cambio futuro solo tendrá que hacerse en un lugar, y todo el código lo usará.
- Los nuevos valores (de los deslizadores y cuadros combinados) ya no se envían a la línea de píxeles durante el desplazamiento o el arrastre y soltado, sino solo al final. Esto se basa en un tiempo de espera aprendido por máquina que registra el tiempo promedio necesario para calcular una línea completa. La GUI esperará entre 20 ms y 2,5 s para enviar cambios a la línea, evitando así volver a calcular en cada paso de desplazamiento o arrastre, lo que genera cálculos inútiles y redundantes, aunque costosos, que solo hacen que el software se retrase. De manera similar, ahora solo se envían en el evento de liberación de botón, en lugar de los eventos de presionar y liberar botón (dado que un clic típico del mouse envía ambos eventos). Debería ahorrar bastantes recomputaciones de línea innecesarias.
- Los widgets se redibujan inmediatamente en eventos del usuario, antes de que los nuevos valores se envíen a la línea de píxeles. Esto asegura una retroalimentación inmediata del usuario, aunque el resultado del píxel real pueda llegar más tarde, y limita la frustración en computadoras lentas.
- No enviar eventos de cambio de valor si los widgets recibieron interacción del usuario pero su valor no cambió realmente.
- Capturar clics en el signo de chevron de los cuadros combinados (flecha hacia la derecha). Anteriormente, necesitabas hacer clic en la etiqueta para desplegar el menú desplegable del cuadro combinado, lo cual era muy frustrante si venías de un software con una GUI adecuada. El chevron en sí mismo no respondía a los clics.
- No desplazar los menús desplegables de los cuadros combinados. Esa característica comenzó como un proyecto genial: alinear el elemento actualmente seleccionado con la etiqueta. El problema es que la posición del menú emergente desplegable finalmente la maneja el entorno de escritorio, solo podemos pedirle educadamente que haga lo que deseamos, pero no hay garantía de que nuestros deseos sean satisfechos. También es posible hacer que el menú emergente se desplace fuera de la ventana de visualización, nada lo impide. En resumen, es frágil y aleatorio, mejor seguir con la posición de ventana predeterminada.
Características obsoletas
La capacidad de asignar atajos de teclado a los deslizadores y cuadros combinados ha sido eliminada por ahora. Los deslizadores y cuadros combinados están vinculados de todos modos a las teclas de flecha y al desplazamiento del mouse una vez que obtienen el enfoque1, y aún es posible asignar la captura del enfoque a un atajo de teclado. La lógica actual es solicitar el enfoque a través de atajos de teclado y luego editar el valor usando las teclas de flecha. Las solicitudes de enfoque también hacen que el widget sea visible en la GUI, desplazando la barra lateral si es necesario.
De todos modos, el sistema actual de atajos tendrá que ser reemplazado por completo por aceleradores nativos de Gtk, que ya se usan para el menú global (y se usaban en Darktable antes de 2021). Actualmente, tenemos ambos sistemas, uno de los cuales es una monstruosidad de complejidad y probablemente responsable de ralentizaciones. KISS.
Advertencias
El cuadro combinado “formato” en el módulo de exportación no inicializa su valor correctamente. Este es un widget Bauhaus no estándar que necesita cuidado adicional. Por el momento, necesitarás actualizar la opción de almacenamiento o recargar un preajuste.
Siempre que retires la pintura vieja que mantenía las paredes oxidadas, corres el riesgo de causar daños colaterales. Ten cuidado con Ansel cuando utilices AppImage y Win EXE etiquetados como Ansel-57ed58d de esta noche y reporta cualquier cosa extraña.
Descargas
Detalles geeks
Los cambios actuales han reducido :
- la complejidad ciclomática de 735 a 494
- la complejidad cognitiva de 796 a 432
- la deuda técnica de 1 día y 7 horas a 4 horas y 50 min.
Si no eres programador, estas métricas simplemente significan que el código será más fácil y menos complicado de mantener en el futuro, y probablemente menos propenso a errores.
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. ↩︎