on
Keyboard.io M01 and alt + tab
One thing I like about the UHK is that, by default, mod + d is an equivalent to alt + tab.
Moreover, it’s possible to keep mod key pressed, making it act just like alt + tab. It seems that the mod layer remembers the last sent modifier key and keep sending this modifier key as long as mod is being pressed.
Another way to see it is: let’s suppose mod + d is a simple shortcut to alt + tab. When releasing d, it would be equivalent to releasing alt and tab altogether. Since this is not what happens, something else is going on.
The way UHK behave is nice, since it lets us switch windows just like a regular alt + tab would do.
Switching windows with the M01
On the M01. There is no custom way to switching windows. You are expected to hit alt + tab, however, alt and tab are on different halves of the keyboard. Thus, the default way to switch windows on the M01 requires both hands, which is quite frustrating. ( ͡° ͜ʖ ͡°)
The naive way, Bind alt + tab to fn + d
One would try to map fn + d to alt + tab but this would not work. Actually the problem is already depicted in this thread here (along with a partial solution). In summary, mapping fn + d to alt + tab would act like a simple shortcut: In fn + d chord, releasing d key would be like releasing alt and tab altogether.
It’s complicated, let’s change the firmware
Let’s be honest, solving this issue is harder than it looks. One way to look at it is to imagine an abstract concept of transcient switching window session (basically a fancy term I came up with which represents the user inputing alt + tab + … + tab).
On the keyboard, we can try to represent a TWSS with these characteristics:
- It will begin when the users hits fn + d.
- It ends when user releases fn key.
- During it is active, it will simulates user hitting alt
- Will be accepting these keybindings
Key | Bound to |
---|---|
fn + d | alt + tab |
fn + f | → |
fn + e | ↑ |
fn + c | ↓ |
fn + s | ← |
The key bindings mentionned above are purely suggestions, they override default mouse control on the M01 since I don’t use this function. You may find useful to bind them differently.
We represent our TWSS session with this kaleidoscope plugin:
/** In charge of keeping alt pressed on during alt tab session
* Alt tab session ends when stopping key release are detected */
class WindowsSwitcherTranscient : public kaleidoscope::Plugin {
public:
enum State { NOT_SWITCHING, SWITCHING };
const static int stopping_array_s = 2;
Key stopping_keys[stopping_array_s] =
{ Key_Escape, ShiftToLayer(FUNCTION) };
WindowsSwitcherTranscient() { };
void activate() { alt_press_on(); }
kaleidoscope::EventHandlerResult onKeyswitchEvent(Key &mapped_key, KeyAddr key_addr, uint8_t keyState) {
if (state == NOT_SWITCHING)
return kaleidoscope::EventHandlerResult::OK;
for (int i = 0; i < stopping_array_s; i++) {
Key k = stopping_keys[i];
if (mapped_key == k && keyToggledOff(keyState)) {
alt_press_off();
break;
}
}
return kaleidoscope::EventHandlerResult::OK;
}
kaleidoscope::EventHandlerResult beforeReportingState() {
if (state == NOT_SWITCHING)
return kaleidoscope::EventHandlerResult::OK;
handleKeyswitchEvent(Key_LeftAlt, UNKNOWN_KEYSWITCH_LOCATION, IS_PRESSED | INJECTED);
return kaleidoscope::EventHandlerResult::OK;
}
private:
void alt_press_on() { state = SWITCHING; };
void alt_press_off() { state = NOT_SWITCHING; };
State state = NOT_SWITCHING;
} WindowsSwitcherTranscient;
A macro is defined which is bound to fn + d, it calls
static void windowSwitch(uint8_t keyState) {
kaleidoscope::hid::pressKey(Key_Tab, keyToggledOn(keyState));
WindowsSwitcherTranscient.activate();
}
You can find a complete example firmware here with no dependencies on external plugin: complete example. Also, there is a third party plugin available here: https://github.com/Nimamoh/Kaleidoscope-TranscientWindowSwitchingState. The third party plugin is the more likely to be maintained
It is certainly not the best solution as I am sure we could find a nice usage of M01 layers to help us solve this problem but it get the job done without much hassle
Knowing so, if you think you found an error or inexact content, you are more than welcome to notify it through comment below ⏬.
Also, if you found the content useful and it helped you, consider leaving a comment too or, better, give me fuel buying me a coffee with the link on the top of the website. 🙏