diff --git a/plugins/Kaleidoscope-LongPress/src/kaleidoscope/plugin/LongPress.h b/plugins/Kaleidoscope-LongPress/src/kaleidoscope/plugin/LongPress.h index 30d91053a..d019b0699 100644 --- a/plugins/Kaleidoscope-LongPress/src/kaleidoscope/plugin/LongPress.h +++ b/plugins/Kaleidoscope-LongPress/src/kaleidoscope/plugin/LongPress.h @@ -48,8 +48,41 @@ struct LongPressMapping { // This constructor is here so that we can create an empty LongPress object in RAM // into which we can copy the values from a PROGMEM LongPress object. LongPressMapping() = default; + + + /// Compare two LongPressMapping objects to sort mappings on KeyAddr + /// always before mappings on Key objects. + /// Intended to be used with the qsort function. + static int compare(const LongPressMapping m1, const LongPressMapping m2) { + if (m1.addr != m2.addr) { + if (m1.addr == KeyAddr::none()) { + // if m1 is not specified by physical key address (but m2 is), m2 + // must be sorted first) + return 1; + } + + if (m2.addr == KeyAddr::none()) { + // if m2 is not specified by physical key address (but m1 is), m1 + // must be sorted first) + return -1; + } + } + + // in all other cases sort order is not relevant for us, but we just + // sort by the Key then. + if (m1.key == m2.key) { + return 0; + } + + if (m1.key > m2.key) { + return -1; + } + + return 1; + } }; + // ============================================================================= /// Kaleidoscope plugin for long-press keys /// @@ -267,6 +300,17 @@ class LongPress : public Plugin { void configureLongPresses(LongPressMapping const (&explicitmappings)[_explicitmappings_count]) { explicitmappings_ = explicitmappings; explicitmappings_count_ = _explicitmappings_count; + // sort the mappings to put all mappings on KeyAddr before mappings on + // Key. This is necessary to let mappings on KeyAddr take precedence + // over mappings on Key regardless of the order they were defined in + // “explicitmappings”. + if (explicitmappings_count_ > 0) { + int length = sizeof(explicitmappings_) / sizeof(explicitmappings_[0]); + qsort(explicitmappings_, + length, + sizeof(explicitmappings_[0]), + LongPressMapping::compare); + } } private: