Merge pull request #620 from gedankenexperimenter/bug/qukeys-mod-flag-rollover

Fix Qukeys mod flag rollover
pull/625/head
Jesse Vincent 6 years ago committed by GitHub
commit 8fe381a0a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -173,11 +173,12 @@ bool Qukeys::flushKey(bool qukey_state, uint8_t keyswitch_state) {
// have a full HID report, and we don't want to accidentally turn
// off keys that the scan hasn't reached yet, so we force the
// current report to be the same as the previous one, then proceed
HID_KeyboardReport_Data_t hid_report;
// First, save the current report
memcpy(hid_report.allkeys, Keyboard.keyReport.allkeys, sizeof(hid_report));
HID_KeyboardReport_Data_t curr_hid_report;
// First, save the current report & previous report's modifiers
memcpy(&curr_hid_report, &Keyboard.keyReport, sizeof(curr_hid_report));
byte prev_hid_report_modifiers = Keyboard.lastKeyReport.modifiers;
// Next, copy the old report
memcpy(Keyboard.keyReport.allkeys, Keyboard.lastKeyReport.allkeys, sizeof(Keyboard.keyReport));
memcpy(&Keyboard.keyReport, &Keyboard.lastKeyReport, sizeof(Keyboard.keyReport));
// Instead of just calling pressKey here, we start processing the
// key again, as if it was just pressed, and mark it as injected, so
// we can ignore it and don't start an infinite loop. It would be
@ -188,11 +189,32 @@ bool Qukeys::flushKey(bool qukey_state, uint8_t keyswitch_state) {
hid::sendKeyboardReport();
// Next, we restore the current state of the report
memcpy(Keyboard.keyReport.allkeys, hid_report.allkeys, sizeof(hid_report));
memcpy(&Keyboard.keyReport, &curr_hid_report, sizeof(curr_hid_report));
// Last, if the key is still down, add its code back in
if (keyswitch_state & IS_PRESSED)
if (keyswitch_state & IS_PRESSED) {
handleKeyswitchEvent(keycode, row, col, IS_PRESSED | WAS_PRESSED);
} else {
// If this is the key that was released, send that release event now
handleKeyswitchEvent(Key_NoKey, row, col, WAS_PRESSED);
// ...and if there's another key in the queue that's about to also be
// flushed, we need to do something to clear this one's modifier flags (if
// any) from the previous report
if (key_queue_length_ > 1) {
// Restore the previous report; whatever was added by this key flush
// should not appear in the next one, because this key has now been
// released. This is necessary to handle the case where a qukey's primary
// key value has a modifier flag. Because we copy the last report
// directly, we're bypassing the mod-flag rollover protection offered by
// the HIDAdapter. Unfortunately, this does not help if we're rolling
// over multiple keys, and one of the unreleased ones has a mod flag.
// That's probably rare enough that it won't be noticed, however. THIS IS
// AN UGLY HACK, AND IT SHOULD BE FIXED WITH SOMETHING BETTER EVENTUALLY.
// Doing it right will most likely involve either major changes in
// KeyboardioHID or Kaleidoscope itself.
Keyboard.lastKeyReport.modifiers = prev_hid_report_modifiers;
}
}
// Now that we're done sending the report(s), Qukeys can process events again:
flushing_queue_ = false;
@ -217,12 +239,8 @@ void Qukeys::flushQueue(int8_t index) {
return;
flushKey(QUKEY_STATE_ALTERNATE, IS_PRESSED | WAS_PRESSED);
}
if (isQukey(key_queue_[0].addr)) {
flushKey(QUKEY_STATE_PRIMARY, IS_PRESSED | WAS_PRESSED);
} else {
flushKey(QUKEY_STATE_PRIMARY, WAS_PRESSED);
}
}
// Flush all the non-qukey keys from the front of the queue
void Qukeys::flushQueue() {

Loading…
Cancel
Save