API observable for tool focus?

Hello all!

I’ve come up empty when looking for an observable that holds the dialog active/inactive (focused) state. I’d like to know when the user clicked on the main window and my tool lost focus. Is there such an animal lurking in the API?

If not, does anyone have any idea how I might derive the state using other API calls / window states?

An _observable is like a switch. It acts at a given moment, depending on a cause.

Keeping the dialog focused always will cause Renoise to lose her keyboard commands. Only the key commands programmed in the tool will work. You must keep this detail in mind.

You can use an envelope in your “dialog”, like a local row{}.
Then you can check if that local exists and if it is visible. If visible, invoke :show() (also exists :close()). You can put this idea in a :add_timer() and force the window to always be in the foreground. This I think is possible. I have never done it because I think it is not convenient unless you use an ON/OFF switch on the tool. When ON, it will activate the timer, and the user will be aware that the window tool will always be in the foreground.

Simply, if the user loses focus of the window, they have to be able to click somewhere in Renoise to retrieve it (or a keyboard command, like add_keybinding{name="Name_of_the_tool",invoke=function() end}, accessible from “Renoise:Preferences/Keys:Global/Tools/Name_of_the_tool”).

I appreciate your response, and the work you’ve done on tools, but you haven’t really answered my question. I’m looking for a state variable in the API that says if the tool dialog is focused (or, alternatively, if the main window has received focus).

Also, this is somewhat inaccurate:

This only applies to modal dialogs. Non-modal dialogs can send any input back to Renoise (even when focused)—it just needs to be passed through in the keyhandler function.

¡Pero gracias!

With the current API I think you can only detect some Renoise frames, not a floating tool window. For that, it would be necessary to refer to a specific id. This does not appear to be programmed in the API.

With a non modal dialog as this:
renoise.app():show_custom_dialog(title, content_view [, key_handler, key_handler_options])

AFAIK you can only create your own keyboard command functions and invoke them. Is it possible to invoke Renoise keyboard commands while this tool window is focused? How do you do that?

function your_keyhandler(dialog, key)
  -- Deal with the keys you want to catch
  if key.name == 'foo' then
    -- ...
  elseif key.name == 'bar' then
    -- ...
  end

  return key -- <-- this passes the key back to Renoise
end

If you want to make sure the key you caught doesn’t get sent back to Renoise, return nil. You can do that inside of your conditional statements as needed.

As far as I know, the only key that needs special handling is the Escape key, since that appears to be hardwired into the dialog. With a dialog open, you can’t hit Escape to enter edit mode unless you explicitly deal with it in your keyhandler.

-- put this at the top of your keyhandler
if key.name == 'esc' then
  renoise.song().transport.edit_mode = (renoise.song().transport.edit_mode == false) -- toggle edit mode
end

There’s a possibility the user has bound Escape to a different action, or unbound it for toggling edit mode, so this isn’t ideal, but it should work well for everybody else.

1 Like

I should add: Shift + Escape is bound to move focus between the Pattern Editor and the Pattern Matrix by default, but there’s nothing obvious in the API to be able to focus the Pattern Matrix, so that’s one key combination that probably can’t be simulated.

But this that you comment is so that you, as a programmer, can create your own keyboard commands with your own functions (which is what I said), not the Renoise keyboard commands already assigned. I thought you were saying there was some way for the tool to run Renoise’s already assigned keyboard commands, which would be great (in a non modal dialog, as show_custom_dialog).

In fact, you don’t need to put return key in your function. Each condition is already running. Perhaps it would be better to add return to the end of each condition.

Custom windows tools would also benefit if it were possible to bind Renoise’s global already assigned keyboard commands. That would save a lot of functions.

I agree, a renoise.tool():trigger_keybinding(keybinding_name) or something would be really cool.