RustAudio / baseview

low-level window system interface for audio plugin UIs
Apache License 2.0
259 stars 54 forks source link

Add a `set_focus(bool)` interface for getting and losing keyboard focus #152

Open Engid opened 8 months ago

Engid commented 8 months ago

This is a compilation of discussions from the discord chat from @ilmai et al.

Changes required in baseview to capture focus, pass it to client gui libraries (ie Vizia), then return focus to host if client requests it to bubble up.

Per @geom3trik in plugin-gui:

“ Vizia has a cx.focus() method which is called when a view wants keyboard focus. Presumably this function could then call the appropriate baseview function to capture the input focus, and then when the focus is released back to the window baseview could release it to the host?”

Ilmai explained:

So if you pass a mouse event to vizia and vizia asks for text input focus based on that, you shouldn't also be passing those keyboard events to the host because otherwise pressing the spacebar for example would play/pause the timeline in addition to entering a whitespace in a textbox.

Engid commented 8 months ago

Per ilmai:

For reference here's what I'm doing on Mac with my own windowing abstraction experiment that I'm using for slint. It's not really production-ready but seems to work as expected based on some testing. https://github.com/ilmai/plugin-things/blob/main/plugin-canvas/src/platform/mac/view.rs#L255

The boolean is checked here https://github.com/ilmai/plugin-things/blob/main/plugin-canvas/src/platform/mac/view.rs#L66 Windows and Linux have similar logic

And set_input_focus() is called from here https://github.com/ilmai/plugin-things/blob/main/nih_plug_slint/src/window_adapter.rs#L318


UPDATES 11/12/2023:

NOTES: set_input_focus() defined here in a permalink url

ALSO NOTE: further comment from ilmai:

That's not enough on Windows as you need a separate message window that capture the input since Live and some other hosts don't let keyboard events through to the plugin. And on top of that, you need a message hook to catch modifier key presses since you want to always capture those and not just when the window has input focus.

dathinaios commented 4 months ago

(Dionysis from the Rust Audio discord here 🙂👋)

So, I am giving this a go again. I am reading the baseview code and follow it ok but we need more clarity on what needs to be implemented. Focusing on Mac for now but if we get the interface down it should not be too difficult to implement for other platforms (famous last words 😁).

I had a look at @ilmai 's code from the link above and I can not see where the input_focus boolean interacts with NSWindow. From a discord conversation @ilmai has said:

you don't really need to set input focus yourself like that, but the GUI crate (vizia in this case) asking for input focus should dictate if keyboard events are passed to the parent window or not

That sounds to me as if baseview is not handling the focus but simply storing the boolean and then it is a matter of calling the focus method from Vizia (or other GUI) which I assume already has access to the NSWindow.

Is this correct? 🤔