diff --git a/examples/Features/AppSwitcher/AppSwitcher.cpp b/examples/Features/AppSwitcher/AppSwitcher.cpp
new file mode 100644
index 00000000..e75c94bf
--- /dev/null
+++ b/examples/Features/AppSwitcher/AppSwitcher.cpp
@@ -0,0 +1,79 @@
+/* -*- mode: c++ -*-
+ * AppSwitcher -- A Kaleidoscope Example
+ * Copyright (C) 2021 Keyboardio, 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
+ * Foundation, version 3.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see .
+ */
+
+#define KALEIDOSCOPE_HOSTOS_GUESSER 1
+
+#include
+
+#include "AppSwitcher.h"
+
+namespace kaleidoscope {
+namespace plugin {
+
+EventHandlerResult AppSwitcher::onKeyEvent(KeyEvent &event) {
+ // Ignore all key releases
+ if (keyToggledOff(event.state))
+ return EventHandlerResult::OK;
+
+ if (event.key == AppSwitcher_Next || event.key == AppSwitcher_Prev) {
+ bool add_shift_flag = false;
+ if (event.key == AppSwitcher_Prev) {
+ add_shift_flag = true;
+ }
+
+ // For good measure:
+ event.state |= INJECTED;
+
+ // If AppSwitcher was not already active, hold its modifier first.
+ if (!active_addr_.isValid()) {
+ if (::HostOS.os() == hostos::OSX) {
+ event.key = Key_LeftGui;
+ } else {
+ event.key = Key_LeftAlt;
+ }
+ Runtime.handleKeyEvent(event);
+ }
+
+ // Clear the event's key address so we don't clobber the modifier.
+ event.addr.clear();
+ event.key = Key_Tab;
+ if (add_shift_flag)
+ event.key.setFlags(SHIFT_HELD);
+ // Press tab
+ Runtime.handleKeyEvent(event);
+ // Change state to release; this will get processed when we return OK below.
+ event.state = WAS_PRESSED | INJECTED;
+ } else if (active_addr_.isValid()) {
+ // If any non-AppSwitcher key is pressed while AppSwitcher is active, that
+ // will close AppSwitcher instead of processing that keypress. We mask the
+ // address of the key that closed AppSwitcher so that its release doesn't
+ // have any effect. Then we turn the event for that key's press into an
+ // event for the release of the AppSwitcher's modifier key.
+ live_keys.mask(event.addr);
+ event.addr = active_addr_;
+ event.state = WAS_PRESSED | INJECTED;
+ event.key = live_keys[event.addr];
+ // Turn off AppSwitcher:
+ active_addr_.clear();
+ }
+ return EventHandlerResult::OK;
+}
+
+} // namespace plugin
+} // namespace kaleidoscope
+
+kaleidoscope::plugin::AppSwitcher AppSwitcher;
diff --git a/examples/Features/AppSwitcher/Macros.h b/examples/Features/AppSwitcher/AppSwitcher.h
similarity index 53%
rename from examples/Features/AppSwitcher/Macros.h
rename to examples/Features/AppSwitcher/AppSwitcher.h
index 1099bb03..00de27a6 100644
--- a/examples/Features/AppSwitcher/Macros.h
+++ b/examples/Features/AppSwitcher/AppSwitcher.h
@@ -1,6 +1,6 @@
/* -*- mode: c++ -*-
* AppSwitcher -- A Kaleidoscope Example
- * Copyright (C) 2016-2018 Keyboardio, Inc.
+ * Copyright (C) 2021 Keyboardio, 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
@@ -17,13 +17,27 @@
#pragma once
-#include
+#include
+#include "Kaleidoscope-Ranges.h"
+
+constexpr Key AppSwitcher_Next{kaleidoscope::ranges::SAFE_START};
+constexpr uint16_t _prev_val = AppSwitcher_Next.getRaw() + 1;
+constexpr Key AppSwitcher_Prev{_prev_val};
+
+namespace kaleidoscope {
+namespace plugin {
+
+class AppSwitcher : public kaleidoscope::Plugin {
+
+ public:
+ EventHandlerResult onKeyEvent(KeyEvent &event);
+
+ private:
+ KeyAddr active_addr_ = KeyAddr::none();
-enum {
- M_APPSWITCH,
- M_APPCANCEL,
};
-const macro_t *macroAppSwitch(uint8_t keyState);
-const macro_t *macroAppCancel(uint8_t keyState);
-void macroAppSwitchLoop();
+} // namespace plugin
+} // namespace kaleidoscope
+
+extern kaleidoscope::plugin::AppSwitcher AppSwitcher;
diff --git a/examples/Features/AppSwitcher/AppSwitcher.ino b/examples/Features/AppSwitcher/AppSwitcher.ino
index ad46fefc..56f3c0ac 100644
--- a/examples/Features/AppSwitcher/AppSwitcher.ino
+++ b/examples/Features/AppSwitcher/AppSwitcher.ino
@@ -17,10 +17,10 @@
#include "Kaleidoscope.h"
#include "Kaleidoscope-EEPROM-Settings.h"
-#include "Kaleidoscope-Macros.h"
#include "Kaleidoscope-HostOS.h"
+#include "Kaleidoscope-Ranges.h"
-#include "Macros.h"
+#include "AppSwitcher.h"
/* *INDENT-OFF* */
KEYMAPS(
@@ -32,7 +32,7 @@ KEYMAPS(
Key_PageDown, Key_Z, Key_X, Key_C, Key_V, Key_B, Key_Escape,
Key_LeftControl, Key_Backspace, Key_LeftGui, Key_LeftShift,
- M(M_APPSWITCH),
+ AppSwitcher_Next,
Key_skip, Key_6, Key_7, Key_8, Key_9, Key_0, Key_skip,
Key_Enter, Key_Y, Key_U, Key_I, Key_O, Key_P, Key_Equals,
@@ -40,24 +40,13 @@ KEYMAPS(
Key_skip, Key_N, Key_M, Key_Comma, Key_Period, Key_Slash, Key_Minus,
Key_RightShift, Key_RightAlt, Key_Spacebar, Key_RightControl,
- M(M_APPCANCEL)
+ AppSwitcher_Prev
),
)
/* *INDENT-ON* */
-const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
- switch (macroIndex) {
- case M_APPSWITCH:
- return macroAppSwitch(keyState);
- case M_APPCANCEL:
- return macroAppCancel(keyState);
- }
- return MACRO_NONE;
-}
-
-KALEIDOSCOPE_INIT_PLUGINS(EEPROMSettings,
- HostOS,
- Macros);
+KALEIDOSCOPE_INIT_PLUGINS(HostOS,
+ AppSwitcher);
void setup() {
Kaleidoscope.setup();
@@ -67,6 +56,5 @@ void setup() {
}
void loop() {
- macroAppSwitchLoop();
Kaleidoscope.loop();
}
diff --git a/examples/Features/AppSwitcher/Macros.cpp b/examples/Features/AppSwitcher/Macros.cpp
deleted file mode 100644
index 9baaafa2..00000000
--- a/examples/Features/AppSwitcher/Macros.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/* -*- mode: c++ -*-
- * AppSwitcher -- A Kaleidoscope Example
- * Copyright (C) 2016-2018 Keyboardio, 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
- * Foundation, version 3.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see .
- */
-
-#define KALEIDOSCOPE_HOSTOS_GUESSER 1
-
-#include
-
-#include "Macros.h"
-
-namespace H = kaleidoscope::hostos;
-
-static bool appSwitchActive = false;
-
-const macro_t *macroAppSwitch(uint8_t keyState) {
- appSwitchActive = true;
-
- // Key was just pressed, or is being held
- if (keyIsPressed(keyState)) {
- if (HostOS.os() == H::OSX)
- return MACRO(Dr(Key_LeftGui), D(Tab));
- else
- return MACRO(Dr(Key_LeftAlt), D(Tab));
- }
- // Key was just released
- if (keyToggledOff(keyState)) {
- if (HostOS.os() == H::OSX)
- return MACRO(U(Tab), Dr(Key_LeftGui));
- else
- return MACRO(U(Tab), Dr(Key_LeftAlt));
- }
- // otherwise we do nothing
- return MACRO_NONE;
-}
-
-const macro_t *macroAppCancel(uint8_t keyState) {
- if (keyToggledOn(keyState))
- appSwitchActive = false;
- return MACRO_NONE;
-}
-
-void macroAppSwitchLoop() {
- Key mod = Key_LeftAlt;
-
- if (HostOS.os() == H::OSX)
- mod = Key_LeftGui;
-
- // if appSwitchActive is true, we continue holding Alt.
- if (appSwitchActive) {
- handleKeyswitchEvent(mod, UnknownKeyswitchLocation, IS_PRESSED);
- }
-}