Handling Key Releases

I posted this in the wishlist thread, but I’m wondering if there is a way to do with the current API. Is there a way to trigger an event when a key (on the computer keyboard) is released?

I ask because I have a tool that is unusable in 2.7. The tool sends a note on OSC message to Renoise when a key is pressed. Ideally, it would send a note off message when the key is released, but I don’t think this is possible right now. In 2.6 this was no problem but 2.7 doesn’t like notes with no associated note off events (for a good reason). This makes the tool unusable, and I can’t find a way to solve it. I tried to make the tool send a note off message right before each note on message, but that doesn’t work consistently: some messages get ignored. I suspect thst this is because the two messages are too close to each other in time.

Does anyone have an idea how to solve this?

No key release events at the moment. I’ve hold them back in the updates, because I didn’t wanted to destroy the key handling of existing scripts. If we add a “is_release” property to the passed “key” table, then every script first has to check for “is_released”, before doing anything. This kinda sucks, because in general, people will not be interested in release events, and every existing key handler has to be updated.

Maybe someone has an idea how else we could pass them instead. Via a second notifier function maybe? -> show_custom_dialog (…, key_handler_func, key_release_handler_func) ?

Thanks for replying. I realize that this would be problem for existing scripts, and that it would be inconvenient for most purposes. So I was thinking that maybe instead of adding an extra field, you could add something like “_up” or “_release” to the key name when it is released. I don’t know if this is the most elegant solution, but it wouldn’t break existing scripts.

I think nism might be on to something here. But the problem with this solution is that we don’t know what property is used to initialize the event. So perhaps a script uses if (key.character ~= nil) then write(key.character) end in this case we will always need to supply a nil on ‘up’ events and the same goes for notes from the VirtualPiano. So the implementation would be distorted and mangled for up events.

But you might want to phase these ideas in with an event wrapper.

The key handler is an event handler and as such should have it’s event passed as an argument. The event should describe what happened and who was involved. We can consider the current model as only describing who was involved and we assume the action was a press.

So lets write the simplest event model possible to start with:

event = {  
 key, -- name of the key, like 'esc' or 'a'  
 type, -- type of action 'down', 'up' or 'repeated'  

The key provides an id to what was interacted with and the type tells us what happened. Down will fire once when a key is pushed down, repeated will fire for soft presses and up will fire when we release the key.

The current key object is far more sophisticated than this implementation so we should replace the key string with the key object

event = {  
 key = {  
 name, -- name of the key, like 'esc' or 'a'  
 character, -- character representation of the key or nil   
 note, -- virtual keyboard piano key value (starting from 0) or nil  
 type, -- type of action 'down', 'up' or 'repeated'  

I omitted the modifiers attribute as it can be handled manually in variables and the repeated property as it is handled in the event.type. Now the key object supplies values for the key at the event and nothing else.

Now to implement this with backwards compatibility. As a simple solution we could add the event as a second optional argument to the key_handler and supplying an empty key object on ‘up’ events.

function key_handler(key [, event])  

But this will not hold if we want to remove the key argument later on, and supplying an empty key for ‘up’ events is kind of weak. But we need to supply an object with the ‘up’ event and it’s old key properties need to be empty.

So we change our key argument to an event and ‘fake’ the old key object when needed.

function key_handler(event)  
event {  
 key {  
 -- following values are only available on 'down' and 'repeated' they will be empty on 'up' and will be removed in ApiVersion X  
 name, -- name of the key, like 'esc' or 'a'   
 modifiers, -- modifier states. 'shift + control'   
 character, -- character representation of the key or nil   
 note, -- virtual keyboard piano key value (starting from 0) or nil   
 repeated, -- true when the key is soft repeated (hold down)   

This allows phasing from one to the other and does not loose any functionality.

any news on this?

is there any more or less functional workarounds to get “sort-of” key release behaviour?