I have a feeling I am going into well-discussed territory here.
There exists a number of posts that discuss how to change modifiers. I think I have read them all by now. You have the ShapeShifter plugin that changes the key typed while holding down shift. Someone made a ModifierLayers plugin that maps a whole layer to e.g. Shift. (I think. It uses the old plugin system, and I am too much a noob to know how to get it to work).
The exact problem I am trying to solve is that, depending on the key, I want AltGr/Right Alt to be held instead of shift.
I want to, when I press Shift + 2, create @ instead of ".
I know this has also been discussed on the forums, but the solution in those cases seemed to be to switch keyboard layouts on the OS level from (in my case) danish to US.
I donât want to that.
Currently I am using US layout because I like that layout better. But the rest of my family and my coworkers are pretty annoyed every time they need to use my keyboard (which has danish layout). And with my first 100% programmable keyboard (the Keyboardio, duh) I want to switch all my PCs to Danish, but configure the Keyboardio to use the US layout. But that means I have to be able to switch modifier from shift to altgr.
And before you ask: Yes, I will keep both keyboards attached. The normal keyboard for all the normal people, and the Keyboardio for me.
With macros I was able to put one on e.g. the â2â key that produced a @ even with danish keyboard layout when shift was held. But it wouldnât repeat. Do I need that repeat? Probably not, but out of sheer principle I want the keyboard to behave exactly like normal. Curse my OCD!
I have so far come up with this:
EventHandlerResult MyAwesomePlugin::onKeyswitchEvent(Key &mapped_key, byte row,
byte col, uint8_t key_state) {
uint8_t modifiers = Keyboard.lastKeyReport.modifiers;
if(mapped_key == Key_2) {
set_key_ = false;
// Check if only shifts are pressed
if(!(modifiers & ~SHIFT_KEYS) && (modifiers & SHIFT_KEYS)) {
if(keyToggledOn(key_state)) {
// If key was just pressed
// and set the modifiers to AltGr
set_key_ = true;
} else if(keyIsPressed(key_state)) {
// If key is pressed
// Have non-shift modifiers been pressed?
if(modifiers & ~SHIFT_KEYS) {
return EventHandlerResult::OK;
}
// Set modifiers to AltGr
set_key_ = true;
} else if(keyToggledOff(key_state)) {
// Some debugging message I removed.
}
}
}
return EventHandlerResult::OK;
}
At first I had everything in onKeyswitchEvent, but then I read about how the report could be incomplete at just about any stage until it was sent over the wire. So I tried to make the changes as late as possible and used beforeReportingState:
EventHandlerResult MyAwesomePlugin::beforeReportingState() {
if(set_key_) {
Keyboard.keyReport.modifiers = RIGHT_ALT_KEY;
}
if(!memcmp(Keyboard.lastKeyReport.allkeys,
Keyboard.keyReport.allkeys,
sizeof(Keyboard.keyReport))) {
// Here we end up if the reports are the same. At this point the keyboard should
// not send a new report. That logic is elsewhere in the firmware. When I hold
// down shift I never end up here, although the report modifiers have been set to
// RIGHT_ALT_KEY. I think there is something else going on in the firmware, but I
// have no idea how to find out.
}
return EventHandlerResult::OK;
}
I cannot figure out what is happening since the reports are not the same. What goes into allkeys?
If I just press any other key than 2 and shift I get key repeat, but not with 2 and shift.
Without knowing anything really about Kaleidoscope my guess is that because I hold down shift the whole time, and I change the modifier to not have shift but right alt instead, the firmware still sees that shift at a time when it needs to figure out if a report should be sent.
Do I make myself clear, or am I just sounding like the noob I am?