summary refs log tree commit diff
path: root/quantum/action_util.c
diff options
context:
space:
mode:
authorprecondition <57645186+precondition@users.noreply.github.com>2023-07-07 16:18:02 +0200
committerGitHub <noreply@github.com>2023-07-08 00:18:02 +1000
commit1abf8f3e8b8a9b358be3c27867f9bee7422507f3 (patch)
tree22df0acf90ca877cf4b1066116704a310227be99 /quantum/action_util.c
parentbaf289112460d73e889a8a442a932bc4198ccc05 (diff)
[Feature] Send a dummy keycode to neutralize flashing modifiers in retro tap and key overrides (#20992)
Diffstat (limited to 'quantum/action_util.c')
-rw-r--r--quantum/action_util.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/quantum/action_util.c b/quantum/action_util.c
index 361f410d2d..909dea0595 100644
--- a/quantum/action_util.c
+++ b/quantum/action_util.c
@@ -500,3 +500,28 @@ __attribute__((weak)) void oneshot_layer_changed_kb(uint8_t layer) {
 uint8_t has_anymod(void) {
     return bitpop(real_mods);
 }
+
+#ifdef DUMMY_MOD_NEUTRALIZER_KEYCODE
+/** \brief Send a dummy keycode in between the register and unregister event of a modifier key, to neutralize the "flashing modifiers" phenomenon.
+ *
+ * \param active_mods 8-bit packed bit-array describing the currently active modifiers (in the format GASCGASC).
+ *
+ * Certain QMK features like  key overrides or retro tap must unregister a previously
+ * registered modifier before sending another keycode but this can trigger undesired
+ * keyboard shortcuts if the clean tap of a single modifier key is bound to an action
+ * on the host OS, as is for example the case for the left GUI key on Windows, which
+ * opens the Start Menu when tapped.
+ */
+void neutralize_flashing_modifiers(uint8_t active_mods) {
+    // In most scenarios, the flashing modifiers phenomenon is a problem
+    // only for a subset of modifier masks.
+    const static uint8_t mods_to_neutralize[] = MODS_TO_NEUTRALIZE;
+    const static uint8_t n_mods               = ARRAY_SIZE(mods_to_neutralize);
+    for (uint8_t i = 0; i < n_mods; ++i) {
+        if (active_mods == mods_to_neutralize[i]) {
+            tap_code(DUMMY_MOD_NEUTRALIZER_KEYCODE);
+            break;
+        }
+    }
+}
+#endif