Usability

Rewriting keyboard shortcuts (accelerators) from scratch

GUI Usability

In my defining post, Darktable: crashing into the wall in slow-motion, I presented the trainwreck that the new “Great MIDI turducken” was. The purpose of this turducken1 was to rewrite the keyboard shortcuts system to extend it for MIDI devices.

To this day, I’m still mad about this enterprise of mass-destruction, here is a recap of he the reasons:

  1. it replaced in 2021 a keyboard shortcuts system that was pretty good, feature-complete, well tested, stable and coded in less than 1500 lines (comments included),
  2. …to add support for MIDI devices and PlayStation gamepads (!?!)…
  3. …but in my 2022 Darktable survey, one year after this new feature, over 1251 users who participated:
    • 81% of users didn’t have a MIDI device and didn’t plan to get one,
    • 2% didn’t even know what a MIDI device was.
    • 8% of users had a MIDI device but didn’t use it with Darktable,
    • 6% were considering maybe getting a MIDI device in the future,
    • 2% of users had a MIDI device they actually used in Darktable,
  4. the code was absolutely terrible, in terms of:
    • code quality: unlegible if/switch-case statements nested on 4 levels, in the middle of 1000-lines functions (I posted example snippets in my article),
    • code volume:
      • 3546 lines of code for Darktable 4.0,
      • 4397 lines of code for Darktable 5.0,
      • the increase in volume is a direct consequence of trying to fix bugs in an architecture that can’t be fixed because its complexity promotes more complexity. All that stems from the design, but solving issues created by complexity with adding more complexity is not a solution.
    • code complexity:
      • cyclomatic complexity :
        • 1088 for Darktable 4.0,
        • 1245 for Darktable 5.0 (details ),
      • cognitive complexity :
        • 1885 for Darktable 4.0,
        • 2098 for Darktable 5.0 (details ).
      • it is by far the most complex feature of the software, even though it does not operate on images. As a comparison, the second most complex feature is the EXIF metadata decoding, which has a cognitive complexity of 1348.
  5. it doesn’t decode key modifiers by design, but only deals with hardware key-strokes, which means:
    • “1” input from the numeric pad is decoded Keypad End,
    • “1” input from a French AZERTY keyboard is decoded Shift+&, or Shift+" on BÉPO,
    • you therefore need to duplicate all your number-based shortcuts for each way of entering a number, and be prepared for the shortcut settings window to not contain any actual number in the key combinations.
  6. the user-end design is absolutely terrible, with way too many actions and emulations to configure (“effects”), that are not even fully documented 4 years later (what is “ctrl-toggle” ? “right-activate” ?), and the shortcut configuration uses a weird split-window that doesn’t make any sense,
  7. the implementation is also terrible: the feature is aware of all the software GUI, and the software GUI is aware of the shortcuts code. There is no modularity here, and changing anything in the shortcuts code may have unexpected and undesired effect anywhere in the software.2 Just see the dependency graph below,
  8. several “shortcuts” (or MIDI bindings) can be attached to the same action, which means every user interaction has to lookup the whole list of available actions, inducing very inefficient shortcut handling, GUI lags in some cases and “unknown key combination” false positives in peculiar cases.
image
Non-decoded number keys and weird window splitting between "action" and "shortcut".
image

The dependency graph of src/gui/accelerators.c (Great MIDI turducken) before the rewrite. Guess why we call it “spaghetti code "… This makes it clear that there is a double-sided dependency between the accels code and the rest of the GUI code. This is a nightmare to maintain.

Search

You can also ask Chantal, the AI search engine.