I just upgrade my atreus from kaleidoscope 1.99.3 to 1.99.5 and I struggled to update some macro.
I have macro that do different thing if modifier is pressed or not. A simple example :
case KEY_COMMA:
if (keyToggledOn(event.state)) {
if (Kaleidoscope.hid().keyboard().wasModifierKeyActive(Key_LeftShift)) {
return MACRO(I(15), U(LeftShift), T(Comma), D(LeftShift));
} else {
return MACRO(I(15), T(M));
}
}
I was using MACRODOWN method but just migrate to use new way.
My problem is when LeftShift is held I need a macro with no modifier active. I formerly solve this by begining Macro releasing the modifier key. But with the last version it does not work anymore.
I try unsuccessfully to use Kaleidoscope.hid().keyboard().clearModifier() or Runtime.handleKeyEvent() to do so.
The problem you’re having is that MACRO() can’t release a key that wasn’t pressed by the Macros plugin. Since Kaleidoscope’s event-driven redesign, the Macros plugin works by pressing and releasing keys on a small supplemental virtual keyboard, and cannot effect keys held on the main keyboard by calling Macros.release(), which is what U(LeftShift) does, because that will only release that key on the supplemental keyboard.
I would be happy to look at the rest of your Macros code and see if there are any that need more complex adjustments, and I can also help you set up CharShift (or the custom ShiftBlocker plugin) if you want.
I just have a quick look at your solutions and believe the “ShiftBlocker” plugin is what I need.
The CharShift plugin would not do the job for some case where I use different macro depending on OS and alt codes for windows.
I also recommend using the following instead of wasModifierKeyActive():
bool isShiftKeyHeld() {
for (Key key : kaleidoscope::live_keys.all()) {
if (key.isKeyboardShift())
return true;
}
return false;
}
Unlike wasModifierKeyActive() (and isModifierKeyActive(), which is no longer problematic), you won’t get a false positive for a key with a modifier flag (e.g. LSHIFT(Key_1)).
@merlin thank you for your suggestions. It also helped me a lot. I managed to convert most of my macros to CharShift. I still have a few problems with tilde.
I’m trying to get the default layout so that the rightmost key of the left side is backtick when pressed normal and tilde when pressed with shift. On the finnish keyboard the tilde is achieved pressing MACRO(D(RightAlt), T(RightBracket, U(RightAlt), T(Space)).
I cannot figure out how to use the ShiftBlocker to achieve these combinations.
Your whole macroAction() function is the deprecated version, so it needs to be replaced with the newer KeyEvent version. I haven’t tested this code, so there may be some errors in it, but if I got it all right, it should serve as a replacement for your old macroAction() function:
const macro_t *macroAction(uint8_t macro_id, KeyEvent &event) {
// All these macros only play when a key toggles on, so it's more efficient to
// just test for that once.
if (keyToggledOn(event.state)) {
switch (macro_id) {
case MACRO_VERSION_INFO:
Macros.type(PSTR("Keyboardio Atreus - Kaleidoscope "));
Macros.type(PSTR(BUILD_INFORMATION));
break;
case M_BACKTICK_AND_TILDE:
// Check for any `shift` keys that are currently being held.
bool shift_active = false;
for (Key key : live_keys.all()) {
if (key.isKeyboardShift())
shift_active = true;
}
if (shift_active) {
// If one or more `shift` keys are held, we can't use `MACRO()` because
// we need to disable ShiftBlocker when we're done.
ShiftBlocker.enable();
Macros.tap(RALT(Key_RightBracket));
Macros.tap(Key_Space);
ShiftBlocker.disable();
} else {
// It's more efficient to use a single `Tr()` with a key value that
// contains a modifier flag than to use separate commands for pressing
// and releasing the modifier.
return MACRO(Tr(LSHIFT(Key_Equals)), T(Space));
}
break;
case M_CARET:
return MACRO(Tr(LSHIFT(Key_RightBracket)), T(Space));
case M_PARENTHESIS:
return MACRO(D(LeftShift), T(8), T(9), U(LeftShift), T(LeftArrow));
case M_ANGLES:
return MACRO(T(NonUsBackslashAndPipe), Tr(LSHIFT(Key_NonUsBackslashAndPipe)), T(LeftArrow));
case M_DOUBLE_EQUALS:
return MACRO(D(LeftShift), T(0), T(0), U(LeftShift));
case M_ALT_SHIFT_COMMA:
// Modifier flags can be combined.
return MACRO(Tr(LSHIFT(LALT(Key_Comma))));
case M_ALT_SHIFT_X_T:
// Modifier flag preprocessor macros are not sensitive to the order in
// which they are applied to the key value.
return MACRO(Tr(LALT(LSHIFT(Key_X))), T(T));
default:
break;
}
}
return MACRO_NONE;
}
If you have any further questions, or if something doesn’t work properly, don’t hesitate to ask again!
There is still one problem but I’m not sure what causes it. For some reason sometimes the macro is not played or the resulting keypresses are not visible.
I added some printlines to serial to verify this. The execution is inside the macroAction function and I get the output to serial that certain key is pressed but nothing is output from the keyboard.
Thank you @rloic and @merlin for your help! I was testing the keyboard only in Ubuntu in Gnome Terminal. For some reason Gnome Terminal seems to be the problem. The macros work fine for instance in vscode, gedit and xterm but Gnome Terminal “swallows” the macros maybe once in 10 presses.
Trailing commas are pretty common in lists with one item per line, and are especially nice for version control. If another item is added to the end of a list without a trailing comma, the diff will show three lines (two for adding a comma to one line, and one for the new line) instead of just one.