But how does KE solve the twisting problem? Either a key is triggered when it is pressed or when it is released. Is there something in between?
It listens to input events directly, basically Keyboard input is first processed by KE and then passed onto MacOS for action. I assume BTT (working at a higher level) processes it at the MacOS level since it only asks for Accessibility perms, not Input Monitoring perms.
Accessibility permissions include Input Monitoring permissions
But yes, that's basically it. KE basically acts as a virtual keyboard driver to receive any events before macOS sees them.
@Andreas_Hegenberg It's not urgent at all. But could you take a look at the key repetition problem when you get a chance? Or just tell me that it can't be solved and I'll continue with KM
I‘ll debug that soon! Should be possible, but I first need to figure out why the repeat doesn‘t work
I’ve been using Karabiner to turn my spacebar into a modifier for arrow keys for a while. It seems to work pretty well for me.
It types space on keyup, and only if no other key is pressed at the same time. There are settings you can change to fine tune the various timing thresholds.
Here’s what I use for JKLI as arrow keys when holding space. If you go to “Complex Modifications” and “Add your own rule” then paste this in, it should work.
{
"description": "space_modifier - arrow keys - JKLI",
"manipulators": [
{
"from": {
"key_code": "spacebar",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"set_variable": {
"name": "space_modifier",
"value": 1
}
}
],
"to_after_key_up": [
{
"set_variable": {
"name": "space_modifier",
"value": 0
}
}
],
"to_if_alone": [
{
"key_code": "spacebar"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "j",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "left_arrow"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "k",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "down_arrow"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "l",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "right_arrow"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "i",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "up_arrow"
}
],
"type": "basic"
}
]
}
Also, you might want to lower the “to_if_alone_timeout_milliseconds” value in the Karabiner “Parameters” settings.
Thank you @ocean-success. Maybe I'll install KE and give it a try. But I'm going to stay skeptical Maybe I'm underestimating my stupidity ... but if one key is triggered when released and the next one when pressed, I really don't see how that should work when typing fast.
What works is a mixture. Say space + f is supposed to trigger something. But if space and f are typed in quick succession, then space and f should just be typed.
To ensure this distinction, both keys must be typed on “down”. Space is always typed. However, if the key is subsequently recognized as a “modifier”, space is deleted. But this is not a real shortcut and space is not a real modifier.
In short, what works is this Key Sequence (Leertaste = Space):
To prevent “Space” from being typed several times if the key is held for longer, a shortcut space = space (prevent recursive trigger) must also be added.
Oh I agree with staying skeptical, If you’re a fast enough typer, you still might have some problems with this karabiner setup. Only way to know is to test for yourself of course.
I’m curious, does or could your BTT setup allow modifiers through with the arrow keys? By that I mean with the Karabiner setup, I can hold space, and then also hold option + shift to select text with the JKLI arrow keys for example.
That should work. But why do you want to also hold “Space” when the modifier + arrow keys are sufficient?
This is exactly what the DSL translates to, haha. Works pretty much the same way. I have been making more additions to my navigation layer and it's been working well.
@Frank1 Well, rather than wanting to also hold space, it’s that I often already am.
I often use option, command and shift + arrow to navigate between words, select text, go to the beginning of a line etc. With the Karabiner setup, I can hold the spacebar down the whole time, and then add in whatever regular modifiers I need.
These also don’t need to be set up individually in Karabiner, they just pass through with the JKLI keys. Doing it this way also keeps the regular system default shortcuts intact, which I’ve been trying to do more and more.
@kayg04 Nice, I’m not familiar with this DSL stuff, is it basically a simpler UI for Karabiner?
@ocean-success I see. Then you have very dexterous fingers.
Basically, you can also use a BTT setup to hold down space while you trigger a shortcut (modifier + letter).
However, you must prevent space from being typed while you are holding the key. The easiest way to do this is to set up a shortcut so that space is typed when the key is released. Space = Space (prevent recursive trigger).
But as I said, this would cause problems for me when typing quickly. But maybe it works for you.
@Frank1 So I was typing a reply to you when I got distracted with making a better version of my Karabiner setup. I don’t know if this would address any finger dexterity issues, but I thought I’d share it either way.
Along with the JKLI keys on the right side, this adds Command, Option, Control and Shift to the left side. The E and R keys are kind of like mini hyper keys, equivalent to holding multiple modifier keys.
{
"description": "space_modifier - arrow keys - JKLI (and modifier keys)",
"manipulators": [
{
"from": {
"key_code": "spacebar",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"set_variable": {
"name": "space_modifier",
"value": 1
}
}
],
"to_after_key_up": [
{
"set_variable": {
"name": "space_modifier",
"value": 0
}
}
],
"to_if_alone": [
{
"key_code": "spacebar"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "j",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "left_arrow"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "k",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "down_arrow"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "l",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "right_arrow"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "i",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "up_arrow"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "f",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "left_command"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "r",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "left_command",
"modifiers": "left_shift"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "d",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "left_option"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "e",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "left_option",
"modifiers": "left_shift"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "s",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "left_control"
}
],
"type": "basic"
},
{
"conditions": [
{
"name": "space_modifier",
"type": "variable_if",
"value": 1
}
],
"from": {
"key_code": "a",
"modifiers": {
"optional": [
"any"
]
}
},
"to": [
{
"key_code": "left_shift"
}
],
"type": "basic"
}
]
}
Oh and thanks for all the BTT information, I don’t know which parts I’ll use yet, but I learn quite a lot reading about your various experiments around here.
@ocean-success Whew, this is highly elaborate. A little too much for my taste. But to each his own
So, if you want to press ⌘+O, do you press space+F+O?
That could also be done with BTT. I've just tried it out. It works.
F long press and hold = cmd down. Cmd up can be implemented in different ways.
And if you want to press the space bar at the same time, you can do that too. But space has no meaning. You could also scratch your ear.
But in the end we always come to the same problem. With BTT his only works if the letter “F” is typed when the key is released.
I assume that in your KE setup “F” only becomes ⌘ if Space is pressed and held before? I don't think this can be done with BTT. And even if it were, we are back to the same problem: Space is typed when the key is released. Can you confirm that this is also the case in your setup?
Anyway, I always find such considerations very interesting. Maybe we'll find the optimum solution at some point. And if not, it's also fun to search for it.
Edit: Ah, wait. Maybe “F” can only be ⌘ when Space is pressed. Presumably this works with the Advanced Conditions.
Ha, yes, elaborate indeed. I’ve been trying to do more and more of this stuff with BTT in hopes of simplifying my setup… but as was mentioned earlier in this thread, some things Karabiner is just better at.
Yes, something like Space+F+W also works for Command+W for example.
Everything in the picture I shared above applies only while holding space. So yes, F is Command only if Space is held first. Space by itself gets typed on keyup, but only if no other key is pressed during the hold.
So, Space+F does not type Space on keyup. However because Space by itself gets typed on keyup, it could still cause problems if you’re a fast enough typer, or if you’re used to typing it on keydown.
Yes, basically that is the idea. You don't have to write 100s of json for something very simple. Here's what my config looks write now.
That is very nice, I'll have to look into it. As yes, the json is my biggest challenge in using Karabiner.