<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Usabilidade on Ansel</title><link>https://ansel.photos/pt_br/tags/usabilidade/</link><description>Recent content in Usabilidade on Ansel</description><generator>Hugo -- gohugo.io</generator><language>pt_br</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/pt_br/tags/usabilidade/index.xml" rel="self" type="application/rss+xml"/><item><title>Reescrevendo os atalhos de teclado (aceleradores) do zero</title><link>https://ansel.photos/pt_br/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>9408b787d759499a4c00aab4646af6a366efa78174b13919c3b24030a9058f0b</guid><description>&lt;p>No meu texto de referência, &lt;a href="https://ansel.photos/pt_br/news/darktable-dans-le-mur-au-ralenti/" title="" rel="dofollow" >&lt;em>Darktable: batendo no muro em câmera lenta&lt;/em>&lt;/a>, apresentei o desastre que era o novo &amp;ldquo;Grande turducken MIDI&amp;rdquo;. O propósito desse turducken&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> era reescrever o sistema de atalhos de teclado para estendê-lo a dispositivos MIDI.&lt;/p>
&lt;p>Até hoje, ainda estou irritado com essa empreitada de destruição em massa; aqui vai um resumo dos motivos:&lt;/p>
&lt;ol>
&lt;li>em 2021, substituiu um sistema de atalhos de teclado que era muito bom, completo em recursos, bem testado, estável e escrito em menos de &lt;strong>1500 linhas&lt;/strong> (comentários incluídos),&lt;/li>
&lt;li>…para adicionar suporte a dispositivos MIDI e gamepads de PlayStation (!?!)…&lt;/li>
&lt;li>…mas na minha pesquisa sobre o Darktable de 2022, um ano após esse novo recurso, dentre os mais de 1251 usuários que participaram:
&lt;ul>
&lt;li>81% dos usuários não tinham um dispositivo MIDI e não planejavam adquirir um,&lt;/li>
&lt;li>2% nem sabiam o que era um dispositivo MIDI.&lt;/li>
&lt;li>8% dos usuários tinham um dispositivo MIDI mas não o usavam com o Darktable,&lt;/li>
&lt;li>6% estavam considerando &lt;em>talvez&lt;/em> adquirir um dispositivo MIDI no futuro,&lt;/li>
&lt;li>&lt;strong>2% dos usuários tinham um dispositivo MIDI que realmente usavam no Darktable&lt;/strong>,&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>o código era absolutamente terrível, em termos de:
&lt;ul>
&lt;li>qualidade de código: instruções &lt;code>if&lt;/code>/&lt;code>switch-case&lt;/code> ilegíveis aninhadas em 4 níveis, no meio de funções de 1000 linhas (postei trechos de exemplo no meu &lt;a href="https://ansel.photos/pt_br/news/darktable-dans-le-mur-au-ralenti/#keyboard-shortcuts" title="" rel="dofollow" >artigo&lt;/a>),&lt;/li>
&lt;li>volume de código:
&lt;ul>
&lt;li>&lt;strong>3546 linhas&lt;/strong> de código para o Darktable 4.0,&lt;/li>
&lt;li>&lt;strong>4397 linhas&lt;/strong> de código para o Darktable 5.0,&lt;/li>
&lt;li>o aumento de volume é uma consequência direta de tentar corrigir bugs em uma arquitetura que não pode ser consertada porque sua complexidade promove mais complexidade. Tudo isso decorre do design, mas resolver problemas criados pela complexidade adicionando mais complexidade não é solução.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>complexidade de 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" >complexidade 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 o Darktable 4.0,&lt;/li>
&lt;li>&lt;strong>1245&lt;/strong> para o 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" >detalhes&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" >complexidade 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 o Darktable 4.0,&lt;/li>
&lt;li>&lt;strong>2098&lt;/strong> para o 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" >detalhes&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>é de longe o recurso mais complexo do software, mesmo não operando sobre imagens. Para comparação, o segundo recurso mais complexo é a decodificação de metadados EXIF, que tem uma complexidade cognitiva de &lt;strong>1348&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>ele não decodifica modificadores de tecla &lt;strong>por design&lt;/strong>, mas lida apenas com as teclas pressionadas no hardware, o que significa:
&lt;ul>
&lt;li>a entrada &amp;ldquo;1&amp;rdquo; do teclado numérico é decodificada como &lt;code>Keypad End&lt;/code>,&lt;/li>
&lt;li>a entrada &amp;ldquo;1&amp;rdquo; de um teclado francês AZERTY é decodificada como &lt;code>Shift+&amp;amp;&lt;/code>, ou &lt;code>Shift+&amp;quot;&lt;/code> no BÉPO,&lt;/li>
&lt;li>portanto, você precisa duplicar todos os seus atalhos baseados em números para cada forma de inserir um número, e se preparar para que a janela de configuração de atalhos não contenha nenhum número real nas combinações de teclas.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>o design voltado ao usuário é absolutamente terrível, com ações e emulações demais para configurar (&amp;ldquo;efeitos&amp;rdquo;), que nem sequer estão totalmente documentadas 4 anos depois (o que é &amp;ldquo;ctrl-toggle&amp;rdquo;? &amp;ldquo;right-activate&amp;rdquo;?), e a configuração de atalhos usa uma estranha janela dividida que não faz o menor sentido,&lt;/li>
&lt;li>a implementação também é terrível: o recurso conhece toda a GUI do software, e a GUI do software conhece o código dos atalhos. Não há modularidade alguma aqui, e mudar qualquer coisa no código dos atalhos pode ter efeitos inesperados e indesejados em qualquer parte do software.&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup> Basta ver o grafo de dependências abaixo,&lt;/li>
&lt;li>vários &amp;ldquo;atalhos&amp;rdquo; (ou vinculações MIDI) podem estar associados à mesma ação, o que significa que cada interação do usuário precisa consultar a lista inteira de ações disponíveis, induzindo um tratamento de atalhos muito ineficiente, travamentos da GUI em alguns casos e falsos positivos de &amp;ldquo;combinação de teclas desconhecida&amp;rdquo; em 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 não decodificadas e estranha divisão de janela entre "ação" e "atalho".
&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>O grafo de dependências de &lt;code>src/gui/accelerators.c&lt;/code> (Grande turducken MIDI) antes da reescrita. Adivinhe por que chamamos isso de &amp;ldquo;&lt;a href="https://en.wikipedia.org/wiki/Spaghetti_code" title="Wikipedia link" target="_blank" rel="noopener noreferrer nofollow" >código espaguete&amp;thinsp;&lt;sup class="icon">&lt;i class="fab fa-wikipedia-w">&lt;/i>&lt;/sup>&lt;/a>&amp;quot;… Isso deixa claro que há uma dependência bidirecional entre o código dos aceleradores e o resto do código da GUI. É um pesadelo de manter.&lt;/p></description></item></channel></rss>