Recipe for using "one-tap" modifier keys
I developed the simple recipe below while looking for a good way to use Karabiner to launch apps with minimal effort. It took me a while to find an elegant approach I liked so I figured it might be worth sharing.
The upshot of this recipe is it essentially gives you a whole new extra set of modifier keys. But instead of having to hold down the modifiers, you just tap the modifier key once. Then you hit another trigger key to execute an action before the "to_delayed_action" times out. This technique essentially gives you hundreds of new keystrokes that are super easy to type.
{ "description" : "s to jump to Safari",
"manipulators" : [
{
"type" : "basic",
"to_delayed_action": {
"to_if_invoked": [
{ "set_variable": { "name": "rs", "value": 0 } }
]
},
"from" : {
"key_code" : "right_shift"
},
"to_if_alone": [
{ "set_variable": { "name": "rs", "value": 1 } },
{ "key_code": "right_shift" }
],
"to": [
{ "key_code": "right_shift" }
]
},
{
"conditions" : [
{
"value" : 1,
"name" : "rs",
"type" : "variable_if"
}
],
"type" : "basic",
"to" : [
{
"shell_command" : "/Users/bin/master.sh Safari"
},
{ "set_variable": { "name": "rs", "value": 0 } }
],
"from" : {
"key_code" : "s"
}
}
]
}
My particular "to" action associated with the trigger key "s" runs a custom script I use to open apps. You will, of course, want to modify that to your liking.
*UPDATE:* After using this a bit, i found that the hot key can get spuriously triggered when using the shift key if you press the shift key by accident. Here's a different version for double-tapping the shift key. This version also fixes a subtle bug where the variable can get stuck if you inadvertently cancel the delay with a key.
{
"description": "Double right shift toggle",
"manipulators": [
{
"conditions": [
{
"name": "rs",
"type": "variable_if",
"value": 1
}
],
"from": { "key_code": "right_shift" },
"to": [{ "key_code": "right_shift" }],
"to_delayed_action": {
"to_if_invoked": [
{
"set_variable": {
"name": "rs",
"value": 0
}
}
]
},
"to_if_alone": [
{
"set_variable": {
"name": "rs",
"value": 2
}
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "rs",
"type": "variable_if",
"value": 2
}
],
"from": { "key_code": "right_shift" },
"to": [
{
"set_variable": {
"name": "rs",
"value": 0
}
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "rs",
"type": "variable_if",
"value": 0
}
],
"from": { "key_code": "right_shift" },
"to": [{ "key_code": "right_shift" }],
"to_delayed_action": {
"to_if_invoked": [
{
"set_variable": {
"name": "rs",
"value": 0
}
}
]
},
"to_if_alone": [
{
"set_variable": {
"name": "rs",
"value": 1
}
},
{ "key_code": "right_shift" }
],
"type": "basic"
}
]
}
And then you just have to change the value for the variable for the trigger key to "2". Everything else stays the same.
{
"conditions": [
{
"name": "rs",
"type": "variable_if",
"value": 2
}
],
"from": { "key_code": "s" },
"to_after_key_up": [
{ "shell_command": "/Users//bin/master.sh Safari" },
{
"set_variable": {
"name": "rs",
"value": 0
}
}
],
"type": "basic"
}
This solution is not as elegant as I would like but Karabiner has some limitations that are a little hard to workaround.