<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Użyteczność on Ansel</title><link>https://ansel.photos/pl/tags/uzytecznosc/</link><description>Recent content in Użyteczność on Ansel</description><generator>Hugo -- gohugo.io</generator><language>pl</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/pl/tags/uzytecznosc/index.xml" rel="self" type="application/rss+xml"/><item><title>Przepisywanie skrótów klawiszowych (akceleratorów) od zera</title><link>https://ansel.photos/pl/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>fe4ed54675cf61f8fb6d47d251f00b51be84268c6bb7efdb985444374bc13759</guid><description>&lt;p>W moim przełomowym wpisie, &lt;a href="https://ansel.photos/pl/news/darktable-dans-le-mur-au-ralenti/" title="" rel="dofollow" >&lt;em>Darktable: crashing into the wall in slow-motion&lt;/em>&lt;/a>, przedstawiłem katastrofę, jaką był nowy „Wielki turducken MIDI&amp;quot;. Celem tego turduckena&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup> było przepisanie systemu skrótów klawiszowych, aby rozszerzyć go o urządzenia MIDI.&lt;/p>
&lt;p>Do dziś jestem wściekły na to przedsięwzięcie masowego niszczenia, oto podsumowanie powodów:&lt;/p>
&lt;ol>
&lt;li>w 2021 roku zastąpił system skrótów klawiszowych, który był całkiem dobry, kompletny funkcjonalnie, dobrze przetestowany, stabilny i zakodowany w mniej niż &lt;strong>1500 liniach&lt;/strong> (łącznie z komentarzami),&lt;/li>
&lt;li>…aby dodać obsługę urządzeń MIDI i gamepadów PlayStation (!?!)…&lt;/li>
&lt;li>…ale w moim ankiecie Darktable z 2022 roku, rok po tej nowej funkcji, spośród ponad 1251 użytkowników, którzy wzięli udział:
&lt;ul>
&lt;li>81% użytkowników nie miało urządzenia MIDI i nie planowało go kupić,&lt;/li>
&lt;li>2% nawet nie wiedziało, czym jest urządzenie MIDI.&lt;/li>
&lt;li>8% użytkowników miało urządzenie MIDI, ale nie używało go z Darktable,&lt;/li>
&lt;li>6% rozważało &lt;em>może&lt;/em> kupno urządzenia MIDI w przyszłości,&lt;/li>
&lt;li>&lt;strong>2% użytkowników miało urządzenie MIDI, którego faktycznie używało w Darktable&lt;/strong>,&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>kod był absolutnie okropny pod względem:
&lt;ul>
&lt;li>jakości kodu: nieczytelne instrukcje &lt;code>if&lt;/code>/&lt;code>switch-case&lt;/code> zagnieżdżone na 4 poziomach, w środku funkcji liczących 1000 linii (przykładowe fragmenty zamieściłem w moim &lt;a href="https://ansel.photos/pl/news/darktable-dans-le-mur-au-ralenti/#keyboard-shortcuts" title="" rel="dofollow" >artykule&lt;/a>),&lt;/li>
&lt;li>objętości kodu:
&lt;ul>
&lt;li>&lt;strong>3546 linii&lt;/strong> kodu dla Darktable 4.0,&lt;/li>
&lt;li>&lt;strong>4397 linii&lt;/strong> kodu dla Darktable 5.0,&lt;/li>
&lt;li>wzrost objętości jest bezpośrednim skutkiem prób naprawiania błędów w architekturze, której nie da się naprawić, ponieważ jej złożoność sprzyja jeszcze większej złożoności. Wszystko to wynika z projektu, ale rozwiązywanie problemów stworzonych przez złożoność poprzez dodawanie kolejnej złożoności nie jest rozwiązaniem.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>złożoności kodu:
&lt;ul>
&lt;li>&lt;a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity" title="Wikipedia link" target="_blank" rel="noopener noreferrer nofollow" >złożoność cyklomatyczna&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> dla Darktable 4.0,&lt;/li>
&lt;li>&lt;strong>1245&lt;/strong> dla 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" >szczegóły&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" >złożoność poznawcza&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> dla Darktable 4.0,&lt;/li>
&lt;li>&lt;strong>2098&lt;/strong> dla 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" >szczegóły&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>jest to zdecydowanie najbardziej złożona funkcja oprogramowania, mimo że nie operuje na obrazach. Dla porównania, drugą najbardziej złożoną funkcją jest dekodowanie metadanych EXIF, którego złożoność poznawcza wynosi &lt;strong>1348&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;strong>z założenia&lt;/strong> nie dekoduje modyfikatorów klawiszy, lecz zajmuje się wyłącznie sprzętowymi naciśnięciami klawiszy, co oznacza, że:
&lt;ul>
&lt;li>wejście „1&amp;quot; z klawiatury numerycznej jest dekodowane jako &lt;code>Keypad End&lt;/code>,&lt;/li>
&lt;li>wejście „1&amp;quot; z francuskiej klawiatury AZERTY jest dekodowane jako &lt;code>Shift+&amp;amp;&lt;/code> lub &lt;code>Shift+&amp;quot;&lt;/code> na BÉPO,&lt;/li>
&lt;li>musisz zatem zduplikować wszystkie swoje skróty oparte na cyfrach dla każdego sposobu wprowadzania cyfry i przygotować się na to, że okno ustawień skrótów nie będzie zawierać żadnej faktycznej cyfry w kombinacjach klawiszy.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>projekt od strony użytkownika jest absolutnie okropny, ze zdecydowanie zbyt wieloma akcjami i emulacjami do skonfigurowania („efektami&amp;quot;), które nawet 4 lata później nie są w pełni udokumentowane (czym jest „ctrl-toggle&amp;quot;? „right-activate&amp;quot;?), a konfiguracja skrótów używa dziwnego podzielonego okna, które nie ma żadnego sensu,&lt;/li>
&lt;li>implementacja jest równie okropna: funkcja jest świadoma całego GUI oprogramowania, a GUI oprogramowania jest świadome kodu skrótów. Nie ma tu żadnej modularności, a zmiana czegokolwiek w kodzie skrótów może mieć nieoczekiwane i niepożądane skutki gdziekolwiek w oprogramowaniu.&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup> Spójrz tylko na graf zależności poniżej,&lt;/li>
&lt;li>kilka „skrótów&amp;quot; (lub powiązań MIDI) może być przypisanych do tej samej akcji, co oznacza, że każda interakcja użytkownika musi przeszukać całą listę dostępnych akcji, powodując bardzo nieefektywną obsługę skrótów, w niektórych przypadkach opóźnienia GUI oraz fałszywe alarmy „nieznana kombinacja klawiszy&amp;quot; w szczególnych przypadkach.&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>
Niezdekodowane klawisze cyfr i dziwny podział okna między „akcją" a „skrótem".
&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>Graf zależności &lt;code>src/gui/accelerators.c&lt;/code> (Wielki turducken MIDI) przed przepisaniem. Zgadnij, dlaczego nazywamy to „&lt;a href="https://en.wikipedia.org/wiki/Spaghetti_code" title="Wikipedia link" target="_blank" rel="noopener noreferrer nofollow" >kodem spaghetti&amp;thinsp;&lt;sup class="icon">&lt;i class="fab fa-wikipedia-w">&lt;/i>&lt;/sup>&lt;/a>&amp;quot;… Widać wyraźnie, że istnieje dwustronna zależność między kodem akceleratorów a resztą kodu GUI. Utrzymanie tego to koszmar.&lt;/p></description></item></channel></rss>