From bf841b4eff032f63c0b888b706a58ffd340adcb6 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Wed, 11 Sep 2019 14:26:23 +0200 Subject: [PATCH] Macros: Implement a compact sequence step This introduces two new macro action steps: `MACRO_ACTION_STEP_TAP_SEQUENCE`, and `MACRO_ACTION_STEP_TAP_CODE_SEQUENCE`. Both of these will tap everything that follows up to a terminating zero (or in case of the first, double zeroes). The purpose of these new steps is to allow one to store longer sequences of tapped input in a more compact manner, without having to prefix each step with an action. Signed-off-by: Gergely Nagy --- doc/plugin/Macros.md | 15 +++++++++ src/kaleidoscope/plugin/Macros.cpp | 36 +++++++++++++++++---- src/kaleidoscope/plugin/Macros/MacroSteps.h | 24 ++++++++++---- 3 files changed, 62 insertions(+), 13 deletions(-) diff --git a/doc/plugin/Macros.md b/doc/plugin/Macros.md index 79c79ead..25ac5cfa 100644 --- a/doc/plugin/Macros.md +++ b/doc/plugin/Macros.md @@ -171,6 +171,21 @@ not supported by this compact representation. * `U(key)`, `Ur(key)`, `Uc(key)`: Simulates a key being released (going up). * `T(key)`, `Tr(key)`, `Tc(key)`: Simulates a key being tapped (pressed first, then released). +### Key sequences + +One often used case for macros is to type longer sequences of text. In these +cases, assembling the macro step by step using the events described above is +verbose both in source code, and compiled. For this reason, the plugin provides +two other actions, both of which take a sequence of keys, and will tap all of +them in order. + +* `SEQ(K(key1), K(key2), ...)`: Simulates all the given keys being tapped in + order, with the currently active interval waited between them. The keys need + to be specified by their full name. +* `SEQc(Kc(key1), Kc(key2), ...)`: Same as `SEQ()`, but the keys are prefixed + with `Key_`, and they ignore the `flags` component of a key, and as such, are + limited to ordinary keys. + ### Controlling when to send reports While the plugin will - by default - send a report after every step, that is not diff --git a/src/kaleidoscope/plugin/Macros.cpp b/src/kaleidoscope/plugin/Macros.cpp index 9f99dd59..23e5db69 100644 --- a/src/kaleidoscope/plugin/Macros.cpp +++ b/src/kaleidoscope/plugin/Macros.cpp @@ -1,5 +1,5 @@ /* Kaleidoscope-Macros - Macro keys for Kaleidoscope. - * Copyright (C) 2017-2018 Keyboard.io, Inc. + * Copyright (C) 2017-2019 Keyboard.io, Inc. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software @@ -39,11 +39,7 @@ void playMacroKeyswitchEvent(Key key, uint8_t keyswitch_state, bool explicit_rep kaleidoscope::hid::sendMouseReport(); } -static void readKeyCodeAndPlay(const macro_t *macro_p, uint8_t flags, uint8_t keyStates, bool explicit_report) { - Key key; - key.flags = flags; - key.keyCode = pgm_read_byte(macro_p++); - +static void playKeyCode(Key key, uint8_t keyStates, bool explicit_report) { if (keyIsPressed(keyStates)) { playMacroKeyswitchEvent(key, IS_PRESSED, explicit_report); } @@ -52,6 +48,14 @@ static void readKeyCodeAndPlay(const macro_t *macro_p, uint8_t flags, uint8_t ke } } +static void readKeyCodeAndPlay(const macro_t *macro_p, uint8_t flags, uint8_t keyStates, bool explicit_report) { + Key key; + key.flags = flags; + key.keyCode = pgm_read_byte(macro_p++); + + playKeyCode(key, keyStates, explicit_report); +} + void Macros_::play(const macro_t *macro_p) { macro_t macro = MACRO_ACTION_END; uint8_t interval = 0; @@ -104,6 +108,26 @@ void Macros_::play(const macro_t *macro_p) { readKeyCodeAndPlay(macro_p++, 0, IS_PRESSED | WAS_PRESSED, false); break; + case MACRO_ACTION_STEP_TAP_SEQUENCE: { + uint8_t keyCode; + do { + flags = pgm_read_byte(macro_p++); + keyCode = pgm_read_byte(macro_p++); + playKeyCode(Key(keyCode, flags), IS_PRESSED | WAS_PRESSED, false); + delay(interval); + } while (!(flags == 0 && keyCode == 0)); + break; + } + case MACRO_ACTION_STEP_TAP_CODE_SEQUENCE: { + uint8_t keyCode; + do { + keyCode = pgm_read_byte(macro_p++); + playKeyCode(Key(keyCode, 0), IS_PRESSED | WAS_PRESSED, false); + delay(interval); + } while (keyCode != 0); + break; + } + case MACRO_ACTION_END: default: return; diff --git a/src/kaleidoscope/plugin/Macros/MacroSteps.h b/src/kaleidoscope/plugin/Macros/MacroSteps.h index 1d4b77a7..49f988fb 100644 --- a/src/kaleidoscope/plugin/Macros/MacroSteps.h +++ b/src/kaleidoscope/plugin/Macros/MacroSteps.h @@ -1,5 +1,5 @@ /* Kaleidoscope-Macros - Macro keys for Kaleidoscope. - * Copyright (C) 2017-2018 Keyboard.io, Inc. + * Copyright (C) 2017-2019 Keyboard.io, Inc. * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software @@ -33,6 +33,9 @@ typedef enum { MACRO_ACTION_STEP_EXPLICIT_REPORT, MACRO_ACTION_STEP_IMPLICIT_REPORT, MACRO_ACTION_STEP_SEND_REPORT, + + MACRO_ACTION_STEP_TAP_SEQUENCE, + MACRO_ACTION_STEP_TAP_CODE_SEQUENCE, } MacroActionStepType; typedef uint8_t macro_t; @@ -44,16 +47,23 @@ typedef uint8_t macro_t; #define I(n) MACRO_ACTION_STEP_INTERVAL, n #define W(n) MACRO_ACTION_STEP_WAIT, n -#define Dr(k) MACRO_ACTION_STEP_KEYDOWN, (k).flags, (k).keyCode +#define Kr(k) (k).flags, (k).keyCode +#define Kc(k) (Key_ ## k).keyCode +#define K(k) Kr(Key_ ## k) + +#define Dr(k) MACRO_ACTION_STEP_KEYDOWN, Kr(k) #define D(k) Dr(Key_ ## k) -#define Ur(k) MACRO_ACTION_STEP_KEYUP, (k).flags, (k).keyCode +#define Ur(k) MACRO_ACTION_STEP_KEYUP, Kr(k) #define U(k) Ur(Key_ ## k) -#define Tr(k) MACRO_ACTION_STEP_TAP, (k).flags, (k).keyCode +#define Tr(k) MACRO_ACTION_STEP_TAP, Kr(k) #define T(k) Tr(Key_ ## k) -#define Dc(k) MACRO_ACTION_STEP_KEYCODEDOWN, (Key_ ## k).keyCode -#define Uc(k) MACRO_ACTION_STEP_KEYCODEUP, (Key_ ## k).keyCode -#define Tc(k) MACRO_ACTION_STEP_TAPCODE, (Key_ ## k).keyCode +#define Dc(k) MACRO_ACTION_STEP_KEYCODEDOWN, Kc(k) +#define Uc(k) MACRO_ACTION_STEP_KEYCODEUP, Kc(k) +#define Tc(k) MACRO_ACTION_STEP_TAPCODE, Kc(k) + +#define SEQ(...) MACRO_ACTION_STEP_TAP_SEQUENCE, __VA_ARGS__, MACRO_ACTION_END, MACRO_ACTION_END +#define SEQc(...) MACRO_ACTION_STEP_TAP_CODE_SEQUENCE, __VA_ARGS__, MACRO_ACTION_END #define WITH_EXPLICIT_REPORT MACRO_ACTION_STEP_EXPLICIT_REPORT #define WITH_IMPLICIT_REPORT MACRO_ACTION_STEP_IMPLICIT_REPORT