<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Usabilidad on Ansel</title><link>https://ansel.photos/es/tags/usabilidad/</link><description>Recent content in Usabilidad on Ansel</description><generator>Hugo -- gohugo.io</generator><language>es</language><copyright>© Copyright 2022-2025 – Aurélien Pierre</copyright><lastBuildDate>Sun, 01 Jun 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://ansel.photos/es/tags/usabilidad/index.xml" rel="self" type="application/rss+xml"/><item><title>Reescribir desde cero los atajos de teclado (aceleradores)</title><link>https://ansel.photos/es/news/rewriting-key-shortcuts/</link><pubDate>Sun, 01 Jun 2025 00:00:00 +0000</pubDate><updated>Sun, 01 Jun 2025 00:00:00 +0000</updated><guid>c1d6adcbfa51e9e73fef1530f98d1fc5e0af8f5d34e35fa53fd230888f3552f9</guid><description>&lt;p>En mi artículo fundacional, &lt;a href="https://ansel.photos/es/news/darktable-dans-le-mur-au-ralenti/" title="" rel="dofollow" >&lt;em>Darktable: estrellándose contra el muro a cámara lenta&lt;/em>&lt;/a>, presenté el desastre que era el nuevo «gran turducken MIDI». El propósito de este turducken&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> era reescribir el sistema de atajos de teclado para ampliarlo a los dispositivos MIDI.&lt;/p>
&lt;p>A día de hoy, sigo furioso por esta empresa de destrucción masiva; aquí tienes un resumen de las razones:&lt;/p>
&lt;ol>
&lt;li>en 2021 reemplazó un sistema de atajos de teclado que era bastante bueno, funcionalmente completo, bien probado, estable y programado en menos de &lt;strong>1500 líneas&lt;/strong> (comentarios incluidos),&lt;/li>
&lt;li>…para añadir compatibilidad con dispositivos MIDI y mandos de PlayStation (!?!)…&lt;/li>
&lt;li>…pero en mi encuesta de Darktable de 2022, un año después de esta nueva función, de más de 1251 usuarios que participaron:
&lt;ul>
&lt;li>el 81% de los usuarios no tenía un dispositivo MIDI ni pensaba conseguir uno,&lt;/li>
&lt;li>el 2% ni siquiera sabía lo que era un dispositivo MIDI.&lt;/li>
&lt;li>el 8% de los usuarios tenía un dispositivo MIDI pero no lo usaba con Darktable,&lt;/li>
&lt;li>el 6% se planteaba &lt;em>quizás&lt;/em> conseguir un dispositivo MIDI en el futuro,&lt;/li>
&lt;li>&lt;strong>el 2% de los usuarios tenía un dispositivo MIDI que realmente usaba en Darktable&lt;/strong>,&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>el código era absolutamente terrible, en términos de:
&lt;ul>
&lt;li>calidad del código: sentencias &lt;code>if&lt;/code>/&lt;code>switch-case&lt;/code> ilegibles anidadas en 4 niveles, en medio de funciones de 1000 líneas (publiqué fragmentos de ejemplo en mi &lt;a href="https://ansel.photos/es/news/darktable-dans-le-mur-au-ralenti/#keyboard-shortcuts" title="" rel="dofollow" >artículo&lt;/a>),&lt;/li>
&lt;li>volumen de código:
&lt;ul>
&lt;li>&lt;strong>3546 líneas&lt;/strong> de código para Darktable 4.0,&lt;/li>
&lt;li>&lt;strong>4397 líneas&lt;/strong> de código para Darktable 5.0,&lt;/li>
&lt;li>el aumento de volumen es una consecuencia directa de intentar corregir errores en una arquitectura que no se puede arreglar porque su complejidad fomenta más complejidad. Todo eso surge del diseño, pero resolver los problemas creados por la complejidad añadiendo más complejidad no es una solución.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>complejidad del código:
&lt;ul>
&lt;li>&lt;a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity" title="Wikipedia link" target="_blank" rel="noopener noreferrer nofollow" >complejidad ciclomática&amp;thinsp;&lt;sup class="icon">&lt;i class="fab fa-wikipedia-w">&lt;/i>&lt;/sup>&lt;/a>:
&lt;ul>
&lt;li>&lt;strong>1088&lt;/strong> para Darktable 4.0,&lt;/li>
&lt;li>&lt;strong>1245&lt;/strong> para Darktable 5.0 (&lt;a href="https://sonarcloud.io/component_measures?id=aurelienpierreeng_darktable-5&amp;amp;metric=complexity&amp;amp;view=list" title="External link" target="_blank" rel="noopener noreferrer nofollow" >detalles&amp;thinsp;&lt;sup class="icon">&lt;i class="fa fa-external-link-alt">&lt;/i>&lt;/sup>&lt;/a>),&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="https://www.sonarsource.com/blog/cognitive-complexity-because-testability-understandability/" title="External link" target="_blank" rel="noopener noreferrer nofollow" >complejidad cognitiva&amp;thinsp;&lt;sup class="icon">&lt;i class="fa fa-external-link-alt">&lt;/i>&lt;/sup>&lt;/a>:
&lt;ul>
&lt;li>&lt;strong>1885&lt;/strong> para Darktable 4.0,&lt;/li>
&lt;li>&lt;strong>2098&lt;/strong> para Darktable 5.0 (&lt;a href="https://sonarcloud.io/component_measures?metric=cognitive_complexity&amp;amp;view=list&amp;amp;id=aurelienpierreeng_darktable-5" title="External link" target="_blank" rel="noopener noreferrer nofollow" >detalles&amp;thinsp;&lt;sup class="icon">&lt;i class="fa fa-external-link-alt">&lt;/i>&lt;/sup>&lt;/a>).&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>es con diferencia la función más compleja del software, aunque no opera sobre imágenes. A modo de comparación, la segunda función más compleja es la decodificación de metadatos EXIF, que tiene una complejidad cognitiva de &lt;strong>1348&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>no decodifica los modificadores de teclas &lt;strong>por diseño&lt;/strong>, sino que solo trata las pulsaciones de teclas físicas, lo que significa que:
&lt;ul>
&lt;li>la entrada «1» del teclado numérico se decodifica como &lt;code>Keypad End&lt;/code>,&lt;/li>
&lt;li>la entrada «1» de un teclado francés AZERTY se decodifica como &lt;code>Shift+&amp;amp;&lt;/code>, o &lt;code>Shift+&amp;quot;&lt;/code> en BÉPO,&lt;/li>
&lt;li>por lo tanto necesitas duplicar todos tus atajos basados en números para cada forma de introducir un número, y prepararte para que la ventana de configuración de atajos no contenga ningún número real en las combinaciones de teclas.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>el diseño de cara al usuario es absolutamente terrible, con demasiadas acciones y emulaciones que configurar («efectos»), que ni siquiera están completamente documentadas 4 años después (¿qué es «ctrl-toggle»? ¿«right-activate»?), y la configuración de atajos usa una extraña ventana dividida que no tiene ningún sentido,&lt;/li>
&lt;li>la implementación también es terrible: la función conoce toda la GUI del software, y la GUI del software conoce el código de los atajos. Aquí no hay modularidad, y cambiar cualquier cosa en el código de los atajos puede tener efectos inesperados e indeseados en cualquier parte del software.&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup> Basta con ver el grafo de dependencias de abajo,&lt;/li>
&lt;li>se pueden asociar varios «atajos» (o asignaciones MIDI) a la misma acción, lo que significa que cada interacción del usuario tiene que recorrer toda la lista de acciones disponibles, provocando una gestión de atajos muy ineficiente, retardos en la GUI en algunos casos y falsos positivos de «combinación de teclas desconocida» en casos peculiares.&lt;/li>
&lt;/ol>
&lt;figure class="img-wrapper caption-figure" id="shortcuts-brokenpng">
&lt;button class="open-lightbox-button" onclick="lightbox(&amp;#34;shortcuts-brokenpng&amp;#34;)">
&lt;i class="fa fa-expand-alt open-lightbox-icon fa-fw">&lt;/i>
&lt;/button>
&lt;button class="open-link-button" onclick="window.open('https:\/\/ansel.photos\/shortcuts-broken.png', '_blank');">
&lt;i class="fa fa-external-link-alt open-link-icon fa-fw">&lt;/i>
&lt;/button>
&lt;div class="img-container" onclick="lightbox(&amp;#34;shortcuts-brokenpng&amp;#34;)" style="cursor: pointer;" >
&lt;img src=https://ansel.photos/shortcuts-broken.png alt="image"
style=" "
decoding="async" loading="lazy"sizes="(max-width: 992px) 100vw, (max-width: 1200px) 66.67vw, 50vw" srcset="https://ansel.photos/shortcuts-broken_hu_e37121e26018e231.png 140w, https://ansel.photos/shortcuts-broken_hu_8766cdc7ed4c0ffe.png 264w, https://ansel.photos/shortcuts-broken_hu_3b7b1b3ab0c67aa4.png 331w, https://ansel.photos/shortcuts-broken_hu_4ce881621b99a2f7.png 400w, https://ansel.photos/shortcuts-broken_hu_41339900c3d3c228.png 496w, https://ansel.photos/shortcuts-broken_hu_b92319103d74af03.png 576w, https://ansel.photos/shortcuts-broken_hu_e47c9ad52cb7218b.png 600w, https://ansel.photos/shortcuts-broken_hu_2084be612ea1c347.png 720w, https://ansel.photos/shortcuts-broken_hu_c71b36b9691e7e8b.png 800w, https://ansel.photos/shortcuts-broken_hu_2febe49d8584f2b1.png 992w, https://ansel.photos/shortcuts-broken_hu_d31c96ca69e52d05.png 1200w, https://ansel.photos/shortcuts-broken_hu_98feacdcc50345e.png 1320w, https://ansel.photos/shortcuts-broken_hu_d99d42c5ec93ce86.png 1440w, https://ansel.photos/shortcuts-broken_hu_1f781700c7610d93.png 1600w, https://ansel.photos/shortcuts-broken_hu_f1176a8dfd24e2cb.png 1920w, https://ansel.photos/shortcuts-broken_hu_2c23e9088e4fe430.png 2048w"width="2508" height="1674"/>
&lt;/div>
&lt;figcaption>
Teclas numéricas no decodificadas y extraña división de ventana entre «acción» y «atajo».
&lt;/figcaption>
&lt;/figure>
&lt;figure class="img-wrapper caption-figure" id="accelerators-beforejpg">
&lt;button class="open-lightbox-button" onclick="lightbox(&amp;#34;accelerators-beforejpg&amp;#34;)">
&lt;i class="fa fa-expand-alt open-lightbox-icon fa-fw">&lt;/i>
&lt;/button>
&lt;button class="open-link-button" onclick="window.open('https:\/\/ansel.photos\/accelerators-before.jpg', '_blank');">
&lt;i class="fa fa-external-link-alt open-link-icon fa-fw">&lt;/i>
&lt;/button>
&lt;div class="img-container" onclick="lightbox(&amp;#34;accelerators-beforejpg&amp;#34;)" style="cursor: pointer;" >
&lt;img src=https://ansel.photos/accelerators-before.jpg alt="image"
style=" "
decoding="async" loading="lazy"sizes="(max-width: 992px) 100vw, (max-width: 1200px) 66.67vw, 50vw" srcset="https://ansel.photos/accelerators-before_hu_5f28983ffa269553.jpg 140w, https://ansel.photos/accelerators-before_hu_7622d56153ebaa50.jpg 264w, https://ansel.photos/accelerators-before_hu_6047a51a0a471dd7.jpg 331w, https://ansel.photos/accelerators-before_hu_11921ace387df1ec.jpg 400w, https://ansel.photos/accelerators-before_hu_85ed35537ae98e7.jpg 496w, https://ansel.photos/accelerators-before_hu_93478e0a0c240e0f.jpg 576w, https://ansel.photos/accelerators-before_hu_5b4f95f36ee81e48.jpg 600w, https://ansel.photos/accelerators-before_hu_8c81fb4523fe5064.jpg 720w, https://ansel.photos/accelerators-before_hu_3cc8ddd08babe7e5.jpg 800w, https://ansel.photos/accelerators-before_hu_5b099d695d7c6396.jpg 992w, https://ansel.photos/accelerators-before_hu_2dc23bad4b919367.jpg 1200w, https://ansel.photos/accelerators-before_hu_a20b8485baa1c620.jpg 1320w, https://ansel.photos/accelerators-before_hu_cef15eb2da9b6ff7.jpg 1440w, https://ansel.photos/accelerators-before_hu_efac0aace80f01eb.jpg 1600w, https://ansel.photos/accelerators-before_hu_fee979325612c769.jpg 1920w, https://ansel.photos/accelerators-before_hu_a5ad2ea57d9b2659.jpg 2048w"width="3730" height="1912"/>
&lt;/div>
&lt;figcaption>
&lt;p>El grafo de dependencias de &lt;code>src/gui/accelerators.c&lt;/code> (el gran turducken MIDI) antes de la reescritura. Adivina por qué lo llamamos «&lt;a href="https://en.wikipedia.org/wiki/Spaghetti_code" title="Wikipedia link" target="_blank" rel="noopener noreferrer nofollow" >código espagueti&amp;thinsp;&lt;sup class="icon">&lt;i class="fab fa-wikipedia-w">&lt;/i>&lt;/sup>&lt;/a>»… Esto deja claro que hay una dependencia bidireccional entre el código de los aceleradores y el resto del código de la GUI. Esto es una pesadilla de mantener.&lt;/p></description></item></channel></rss>