diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fbf8355..ca9ecdf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,19 @@ Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added + +- Added the ability to directly focus the plugin's editor instead of allowing + the host to also process keyboard events by holding down the Shift + key while entering the plugin's GUI with your mouse. Certain hosts like + **Bitwig Studio** normally still respond to the common key presses like Space + for play/pause while interacting with a plugin. This does mean that it becomes + impossible to type a space character in those hosts, which can become a + problem when naming presets. With this feature you can temporarily override + this behaviour, and allow all keyboard input to go directly to Wine. This can + also be useful for _Voxengo_ plugins, which don't grab keyboard focus in their + settings and license dialogs. + ### Changed - Added more tracing for input focus handling when using the `+editor` diff --git a/README.md b/README.md index 6508d430..d024eb64 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ while also staying easy to debug and maintain. - [Bitbridge](#bitbridge) - [Wine prefixes](#wine-prefixes) - [Drag-and-drop](#drag-and-drop) + - [Input focus grabbing](#input-focus-grabbing) - [Downgrading Wine](#downgrading-wine) - [Installing a development build](#installing-a-development-build) - [Configuration](#configuration) @@ -200,6 +201,24 @@ X11 applications like your DAW. If you're using yabridge in _REAPER_ or _Carla_, then you may need to enable a [compatibility option](#compatibility-options) to prevent those hosts from stealing the drop. +### Input focus grabbing + +Yabridge tries to be clever about the way grabbing input focus for a plugin and +subsequently giving it back to the host works. One important detail here is that +when grabbing input focus, yabridge will always focus the _parent window_ passed +by the host for the plugin to embed itself into. This means that hosts like +Bitwig Studio can still process common keys like Space for play/pause even while +interacting with a plugin's GUI. The downside of this approach is that this also +means that in those hosts you simply cannot type a space character, as the key +will always go to the host. + +For the very specific situations where you may want to focus the plugin's editor +directly so that all keyboard input goes to Wine, you can hold down the +Shift key while entering the plugin's GUI with your mouse. This will +let you type spaces in text fields in **Bitwig Studio**, type text into the +settings and license dialogs in **Voxengo** plugins, and it will also allow you +to navigate dropdowns with the keyboard. + ### Downgrading Wine There have been a couple of small regressions in Wine after Wine 6.4. If you run diff --git a/src/wine-host/editor.cpp b/src/wine-host/editor.cpp index 72ede613..557cc569 100644 --- a/src/wine-host/editor.cpp +++ b/src/wine-host/editor.cpp @@ -785,7 +785,17 @@ void Editor::fix_local_coordinates() const { } void Editor::set_input_focus(bool grab) const { - const xcb_window_t focus_target = grab ? parent_window : host_window; + // NOTE: When grabbing focus, you can hold down the shift key to focus the + // Wine window directly. This allows you to use the space key in + // plugin GUIs in Bitwig when necessary (e.g. for naming presets) but + // still allow space to pause/resume the transport when it's not + // needed. It's also needed for dialogs in Voxengo plugins to function + // properly, as they don't grab input focus themselves. + const xcb_window_t focus_target = + grab ? (get_active_modifiers().value_or(0) & XCB_MOD_MASK_SHIFT + ? wine_window + : parent_window) + : host_window; xcb_generic_error_t* error = nullptr; const xcb_get_input_focus_cookie_t focus_cookie = @@ -865,6 +875,11 @@ std::optional Editor::get_active_modifiers() const noexcept { return std::nullopt; } + logger.log_editor_trace([&]() { + return "DEBUG: Active keyboard modifiers: " + + std::to_string(query_pointer_reply->mask); + }); + return query_pointer_reply->mask; } diff --git a/src/wine-host/editor.h b/src/wine-host/editor.h index 001c98dd..a5c4e751 100644 --- a/src/wine-host/editor.h +++ b/src/wine-host/editor.h @@ -242,6 +242,16 @@ class Editor { * is calling `SetFocus()`. See the comment inside of this function for more * details on when this is used. * + * NOTE: There's a little bit of special behaviour in here. When the shift + * key is held while grabbing input focus, then we'll focus + * `wine_window` directly instead of focussing `wrapper_window`. This + * allows you to temporarily override the default focus grabbing + * behaviour, allowing you to use the space key in plugins GUIs in + * Bitwig and to enter text in Voxengo settings and license dialogs. + * This can also help with plugins that use popups but still rely on + * the parent window's keyboard events to come up to control those + * popups. + * * @param grab Whether to grab input focus (if `true`) or to give back input * focus to `host_window` (if `false`). */