Repository: qmk/qmk_firmware
Pull request #24970: Add Super Alt-Tab macro example as module
Author: login: drashna
Labels: name: community_module
Created: 2025-03-01T20:20:09Z | Merged: 2025-03-20T22:12:46Z

## Description

Adds the Super Alt-Tab behavior from the [macros example](https://docs.qmk.fm/feature_macros#super-alt%E2%86%AFtab) as a module, with some configurable options

Blame tzarc

## Types of Changes

- [ ] Core
- [ ] Bugfix
- [x] New feature
- [ ] Enhancement/optimization
- [ ] Keyboard (addition or update)
- [ ] Keymap/layout (addition or update)
- [ ] Documentation

## Checklist

- [x] My code follows the code style of this project: [**C**](https://docs.qmk.fm/#/coding_conventions_c), [**Python**](https://docs.qmk.fm/#/coding_conventions_python)
- [x] I have read the [**PR Checklist** document](https://docs.qmk.fm/#/pr_checklist) and have made the appropriate changes.
- [ ] My change requires a change to the documentation.
- [x] I have updated the documentation accordingly.
- [x] I have read the [**CONTRIBUTING** document](https://docs.qmk.fm/#/contributing).
- [ ] I have added tests to cover my changes.
- [x] I have tested the changes and verified that they work and don't break anything (as well as I can manage).



Diff:
diff --git a/modules/qmk/super_alt_tab/qmk_module.json b/modules/qmk/super_alt_tab/qmk_module.json
new file mode 100644
index 000000000000..002f7fb69e34
--- /dev/null
+++ b/modules/qmk/super_alt_tab/qmk_module.json
@@ -0,0 +1,10 @@
+{
+    "module_name": "Super Alt Tab",
+    "maintainer": "QMK Maintainers",
+    "keycodes": [
+        {
+            "key": "COMMUNITY_MODULE_SUPER_ALT_TAB",
+            "aliases": ["CM_S_AT"]
+        }
+    ]
+}
diff --git a/modules/qmk/super_alt_tab/super_alt_tab.c b/modules/qmk/super_alt_tab/super_alt_tab.c
new file mode 100644
index 000000000000..dfeb4b57730a
--- /dev/null
+++ b/modules/qmk/super_alt_tab/super_alt_tab.c
@@ -0,0 +1,50 @@
+// Copyright 2025 Christopher Courtney, aka Drashna Jael're  (@drashna)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+ASSERT_COMMUNITY_MODULES_MIN_API_VERSION(1, 0, 0);
+
+static bool     is_alt_tab_active = false;
+static uint16_t alt_tab_timer     = 0;
+
+#ifndef COMMUNITY_MODULE_SUPER_ALT_TAB_TIMEOUT
+#    define COMMUNITY_MODULE_SUPER_ALT_TAB_TIMEOUT 1000
+#endif // COMMUNITY_MODULE_SUPER_ALT_TAB_TIMEOUT
+#ifndef COMMUNITY_MODULE_SUPER_ALT_TAB_MODIFIER
+#    define COMMUNITY_MODULE_SUPER_ALT_TAB_MODIFIER MOD_LALT
+#endif // COMMUNITY_MODULE_SUPER_ALT_TAB_MODIFIER
+#ifndef COMMUNITY_MODULE_SUPER_ALT_TAB_KEY
+#    define COMMUNITY_MODULE_SUPER_ALT_TAB_KEY KC_TAB
+#endif // COMMUNITY_MODULE_SUPER_ALT_TAB_KEY
+
+bool process_record_super_alt_tab(uint16_t keycode, keyrecord_t *record) {
+    if (!process_record_super_alt_tab_kb(keycode, record)) {
+        return false;
+    }
+
+    switch (keycode) { // This will do most of the grunt work with the keycodes.
+        case COMMUNITY_MODULE_SUPER_ALT_TAB:
+            if (record->event.pressed) {
+                if (!is_alt_tab_active) {
+                    is_alt_tab_active = true;
+                    register_mods(COMMUNITY_MODULE_SUPER_ALT_TAB_MODIFIER);
+                }
+                alt_tab_timer = timer_read();
+                register_code(COMMUNITY_MODULE_SUPER_ALT_TAB_KEY);
+            } else {
+                unregister_code(COMMUNITY_MODULE_SUPER_ALT_TAB_KEY);
+            }
+            break;
+    }
+    return true;
+}
+
+void housekeeping_task_super_alt_tab(void) {
+    if (is_alt_tab_active) {
+        if (timer_elapsed(alt_tab_timer) > COMMUNITY_MODULE_SUPER_ALT_TAB_TIMEOUT) {
+            unregister_mods(COMMUNITY_MODULE_SUPER_ALT_TAB_MODIFIER);
+            is_alt_tab_active = false;
+        }
+    }
+}


Reviews:
user: login: waffle87
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-01T20:25:51Z
user: login: waffle87
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-01T20:33:53Z
user: login: tzarc
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-02T02:42:14Z
user: login: tzarc
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-20T22:12:40Z

Review comments:
diff_hunk: @@ -0,0 +1,52 @@
+// Copyright 2025 Christopher Courtney, aka Drashna Jael're  (@drashna)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+#include "introspection.h"
+
+ASSERT_COMMUNITY_MODULES_MIN_API_VERSION(1, 0, 0);
+
+static bool     is_alt_tab_active = false; // ADD this near the beginning of keymap.c
+static uint16_t alt_tab_timer     = 0;     // we will be using them soon.
path: modules/qmk/super_alt_tab/super_alt_tab.c
user: login: waffle87
body: nitpick
```suggestion
static bool     is_alt_tab_active = false;
static uint16_t alt_tab_timer     = 0;
```
created_at: 2025-03-01T20:24:41Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,52 @@
+// Copyright 2025 Christopher Courtney, aka Drashna Jael're  (@drashna)
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include QMK_KEYBOARD_H
+
+#include "introspection.h"
+
path: modules/qmk/super_alt_tab/super_alt_tab.c
user: login: tzarc
body: ```suggestion

```
created_at: 2025-03-02T02:42:14Z
author_association: MEMBER

PR comments:
user: login: tzarc
created_at: 2025-03-02T02:43:12Z
body: Should probably add a note to the docs, too.
author_association: MEMBER
user: login: drashna
created_at: 2025-03-03T06:07:28Z
body: > Should probably add a note to the docs, too.

NOt sure I understand where, though.
author_association: MEMBER