Version (which release did you use?)
The latest git version
Describe the bug
The new keyboard hook functionality does not always work correctly, and some of the keypresses gets sent to the application in additon to Nog handling it. In fact for me this is so common that it's almost unusable at the moment.
To Reproduce
The easiest way to produce it is probably to have a workspace with text editors open, and switch the focus between them. But I'm not sure if it's reproducable on all systems.
Expected behavior
All handled keypresses should be swallowed.
More details
I think I know what's going on, since I debugged this a bit. When a key is pressed, a message is sent to another thread through a channel, and once it's handled there, another message is sent back indicate that the key was handled. The main hook thread waits for 100ms to get this message back, and if it doesn't it lets the key press through to other applications. So that's one press getting through even if it's not handled. But what's worse is that the channel is now out of sync (there's more than one message in the queue), so it will start to block KeyUp events instead of KeyDown, which makes things worse.
This 100ms is warranted, as Windows requires the keyboard hooks to not take too long, so that can't be changed. One way to mitigate the issue would be to use a higher thread priority for the processing thread, but that's still quite fragile, it's quite hard to guarantee these timing requirements in all cases.
So instead I recommend, that the actual keymappig is checked inside the hook function, to avoid having to rely on context switches being fast enough. Another improvement for that would be to make sure that no thread locking happens there, for example by making the keymappings buffered so that atomic swaps are used to bring in the new mappings.
This still has a small problem that I don't know how to solve easily, if the mapping is changed by a mode switch, and a new keypress happens immediately after, the re-mapping might not be processed fast enough. But that's probably a very small problem. I can think of a couple of wayst to solve it, but neither of them is easy or desirable.
One way is to have a completely static mapping, that is the mapping of all modes and the mode switches are know in advance. Then the switching would be easily done quickly in the hook itself.
Another way would be to somehow be able to call lua in a way that only allows remapping calls, which probably also would be quick enough.
A third way, very similar to the second one is to queue all real actions, like focusing windows, switching workspaces and so on, but still call lua for every keypress. Lua is quite fast by itself so I think it should be fast enough, and if not, luajit would definitely be able to do it. So that would IMO be the eventual real fix for the issue. This way the lua script could probably be called from the hook function itself on every keypress. And then there's a separate processor that makes all the magic happen.
Note that the issue is probably much worse than it should be right now, at the moment Nog seems to use 100% cpu of one core at all times, which probably delays some actions for more than 100ms. I haven't tracked down what's causing that.
Also note that it would probably be worth blocking key up events as well. They could be done by for example storing handled keys (without modifiers), in a HashSet, and then check that and remove the key on key up.
Version (which release did you use?)
The latest git version
Describe the bug
The new keyboard hook functionality does not always work correctly, and some of the keypresses gets sent to the application in additon to Nog handling it. In fact for me this is so common that it's almost unusable at the moment.
To Reproduce
The easiest way to produce it is probably to have a workspace with text editors open, and switch the focus between them. But I'm not sure if it's reproducable on all systems.
Expected behavior
All handled keypresses should be swallowed.
More details
I think I know what's going on, since I debugged this a bit. When a key is pressed, a message is sent to another thread through a channel, and once it's handled there, another message is sent back indicate that the key was handled. The main hook thread waits for 100ms to get this message back, and if it doesn't it lets the key press through to other applications. So that's one press getting through even if it's not handled. But what's worse is that the channel is now out of sync (there's more than one message in the queue), so it will start to block KeyUp events instead of KeyDown, which makes things worse.
This 100ms is warranted, as Windows requires the keyboard hooks to not take too long, so that can't be changed. One way to mitigate the issue would be to use a higher thread priority for the processing thread, but that's still quite fragile, it's quite hard to guarantee these timing requirements in all cases.
So instead I recommend, that the actual keymappig is checked inside the hook function, to avoid having to rely on context switches being fast enough. Another improvement for that would be to make sure that no thread locking happens there, for example by making the keymappings buffered so that atomic swaps are used to bring in the new mappings.
This still has a small problem that I don't know how to solve easily, if the mapping is changed by a mode switch, and a new keypress happens immediately after, the re-mapping might not be processed fast enough. But that's probably a very small problem. I can think of a couple of wayst to solve it, but neither of them is easy or desirable.
One way is to have a completely static mapping, that is the mapping of all modes and the mode switches are know in advance. Then the switching would be easily done quickly in the hook itself.
Another way would be to somehow be able to call lua in a way that only allows remapping calls, which probably also would be quick enough.
A third way, very similar to the second one is to queue all real actions, like focusing windows, switching workspaces and so on, but still call lua for every keypress. Lua is quite fast by itself so I think it should be fast enough, and if not, luajit would definitely be able to do it. So that would IMO be the eventual real fix for the issue. This way the lua script could probably be called from the hook function itself on every keypress. And then there's a separate processor that makes all the magic happen.
Note that the issue is probably much worse than it should be right now, at the moment Nog seems to use 100% cpu of one core at all times, which probably delays some actions for more than 100ms. I haven't tracked down what's causing that.
Also note that it would probably be worth blocking key up events as well. They could be done by for example storing handled keys (without modifiers), in a HashSet, and then check that and remove the key on key up.