diff --git a/src/editor.rs b/src/editor.rs index c6bd190e0..227ca1350 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -69,6 +69,20 @@ pub trait Editor: Send { /// loaded. fn param_values_changed(&self); + /// Called when the host sends a key-down event to the plugin view (VST3 + /// `IPlugView::onKeyDown`). Return `true` if the editor consumed the key + /// (the wrapper will return `kResultTrue` to the host so the host skips its + /// own accelerator handling); return `false` to let the host process the + /// key normally. + /// + /// This is primarily for text-input routing in hosts like REAPER that + /// intercept certain keys (space, Cmd-shortcuts) before they reach the + /// plugin's native view. The editor should only return `true` if a text + /// input in the editor currently has focus and can consume the character. + fn on_key_down(&self, _character: Option) -> bool { + false + } + // TODO: Reconsider adding a tick function here for the Linux `IRunLoop`. To keep this platform // and API agnostic, add a way to ask the GuiContext if the wrapper already provides a // tick function. If it does not, then the Editor implementation must handle this by diff --git a/src/wrapper/vst3/view.rs b/src/wrapper/vst3/view.rs index fd0fd255a..170e9c710 100644 --- a/src/wrapper/vst3/view.rs +++ b/src/wrapper/vst3/view.rs @@ -338,11 +338,26 @@ impl IPlugView for WrapperView

{ unsafe fn on_key_down( &self, - _key: vst3_sys::base::char16, - _key_code: i16, + key: vst3_sys::base::char16, + key_code: i16, _modifiers: i16, ) -> tresult { - kNotImplemented + // Only forward keys that carry a VST3 virtual key code. Those are + // keys the host (notably REAPER) may intercept as accelerators + // before they reach our native view — space, tab, return, arrows, + // etc. Plain printable characters arrive with `key_code = 0` and + // flow through the normal AppKit `keyDown:` path, which already + // handles text input via NSTextInputContext. Consuming them here + // would break letter input. + if key_code == 0 { + return kResultFalse; + } + let character = char::from_u32(key as u32); + if self.editor.lock().on_key_down(character) { + kResultOk + } else { + kResultFalse + } } unsafe fn on_key_up(