mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-06-16 16:33:55 +02:00
Made input focus grabbing more aggressive #38
This fixes keyboard input in REAPER, and I haven't found any downsides to this approach yet.
This commit is contained in:
@@ -15,6 +15,11 @@ Versioning](https://semver.org/spec/v2.0.0.html).
|
|||||||
the suggestion to enable the `hack_reaper_update_display` workaround for
|
the suggestion to enable the `hack_reaper_update_display` workaround for
|
||||||
REAPER when it is not already enabled.
|
REAPER when it is not already enabled.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Changed the way keyboard input focus works to also allow keyboard input in
|
||||||
|
_REAPER_. Please let me know if this causes any issues elsewhere!
|
||||||
|
|
||||||
## [1.6.1] - 2020-09-28
|
## [1.6.1] - 2020-09-28
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
+29
-17
@@ -110,14 +110,12 @@ Editor::Editor(const Configuration& config,
|
|||||||
// within. For robustness's sake this should be done both when the actual
|
// within. For robustness's sake this should be done both when the actual
|
||||||
// window the Wine window is embedded in (which may not be the parent
|
// window the Wine window is embedded in (which may not be the parent
|
||||||
// window) is moved or resized, and when the user moves his mouse over the
|
// window) is moved or resized, and when the user moves his mouse over the
|
||||||
// window. We also want to set keyboard focus when the user clicks on the
|
// window because this is sometimes needed for plugin groups.
|
||||||
// Windows since Bitwig 3.2 now explicitely requires this.
|
|
||||||
const uint32_t topmost_event_mask = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
const uint32_t topmost_event_mask = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
||||||
xcb_change_window_attributes(x11_connection.get(), topmost_window,
|
xcb_change_window_attributes(x11_connection.get(), topmost_window,
|
||||||
XCB_CW_EVENT_MASK, &topmost_event_mask);
|
XCB_CW_EVENT_MASK, &topmost_event_mask);
|
||||||
xcb_flush(x11_connection.get());
|
xcb_flush(x11_connection.get());
|
||||||
const uint32_t parent_event_mask =
|
const uint32_t parent_event_mask = XCB_EVENT_MASK_ENTER_WINDOW;
|
||||||
XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_ENTER_WINDOW;
|
|
||||||
xcb_change_window_attributes(x11_connection.get(), parent_window,
|
xcb_change_window_attributes(x11_connection.get(), parent_window,
|
||||||
XCB_CW_EVENT_MASK, &parent_event_mask);
|
XCB_CW_EVENT_MASK, &parent_event_mask);
|
||||||
xcb_flush(x11_connection.get());
|
xcb_flush(x11_connection.get());
|
||||||
@@ -216,19 +214,6 @@ void Editor::handle_x11_events() const {
|
|||||||
case XCB_ENTER_NOTIFY:
|
case XCB_ENTER_NOTIFY:
|
||||||
fix_local_coordinates();
|
fix_local_coordinates();
|
||||||
break;
|
break;
|
||||||
case XCB_FOCUS_IN:
|
|
||||||
fix_local_coordinates();
|
|
||||||
|
|
||||||
// Explicitely request input focus when the user clicks on the
|
|
||||||
// window. This is needed for Bitwig Studio 3.2, as the parent
|
|
||||||
// window now captures all keyboard events and forwards them to
|
|
||||||
// the main Bitwig Studio window instead of allowing the child
|
|
||||||
// window to handle those events.
|
|
||||||
xcb_set_input_focus(x11_connection.get(),
|
|
||||||
XCB_INPUT_FOCUS_PARENT, wine_window,
|
|
||||||
XCB_CURRENT_TIME);
|
|
||||||
xcb_flush(x11_connection.get());
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(generic_event);
|
free(generic_event);
|
||||||
@@ -280,6 +265,19 @@ void Editor::fix_local_coordinates() const {
|
|||||||
xcb_flush(x11_connection.get());
|
xcb_flush(x11_connection.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Editor::grab_input_focus() const {
|
||||||
|
// Explicitely request input focus when the user clicks on the window. This
|
||||||
|
// is needed for Bitwig Studio 3.2, as the parent window now captures all
|
||||||
|
// keyboard events and forwards them to the main Bitwig Studio window
|
||||||
|
// instead of allowing the child window to handle those events. We used to
|
||||||
|
// do this on the X11 FocusIn event, but that's not getting fired for REAPER
|
||||||
|
// so we now do this on `WM_PARENTNOTIFY` which included every time the user
|
||||||
|
// clicks on the Wine window.
|
||||||
|
xcb_set_input_focus(x11_connection.get(), XCB_INPUT_FOCUS_PARENT,
|
||||||
|
wine_window, XCB_CURRENT_TIME);
|
||||||
|
xcb_flush(x11_connection.get());
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK window_proc(HWND handle,
|
LRESULT CALLBACK window_proc(HWND handle,
|
||||||
UINT message,
|
UINT message,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
@@ -315,6 +313,20 @@ LRESULT CALLBACK window_proc(HWND handle,
|
|||||||
editor->send_idle_event();
|
editor->send_idle_event();
|
||||||
return 0;
|
return 0;
|
||||||
} break;
|
} break;
|
||||||
|
case WM_PARENTNOTIFY: {
|
||||||
|
auto editor = reinterpret_cast<Editor*>(
|
||||||
|
GetWindowLongPtr(handle, GWLP_USERDATA));
|
||||||
|
if (!editor) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab input focus when the user interacts with the Wine window.
|
||||||
|
// Ideally this would only be done when the window does not yet have
|
||||||
|
// keyboard focus but I wasn't able to find a reliable way to do
|
||||||
|
// that that also works in REAPER.
|
||||||
|
editor->fix_local_coordinates();
|
||||||
|
editor->grab_input_focus();
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefWindowProc(handle, message, wParam, lParam);
|
return DefWindowProc(handle, message, wParam, lParam);
|
||||||
|
|||||||
@@ -136,7 +136,6 @@ class Editor {
|
|||||||
*/
|
*/
|
||||||
void handle_x11_events() const;
|
void handle_x11_events() const;
|
||||||
|
|
||||||
private:
|
|
||||||
/**
|
/**
|
||||||
* Lie to the Wine window about its coordinates on the screen for
|
* Lie to the Wine window about its coordinates on the screen for
|
||||||
* reparenting without using XEmbed. See the comment at the top of the
|
* reparenting without using XEmbed. See the comment at the top of the
|
||||||
@@ -144,6 +143,14 @@ class Editor {
|
|||||||
*/
|
*/
|
||||||
void fix_local_coordinates() const;
|
void fix_local_coordinates() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Steal keyboard focus. This is done whenever the user clicks on the window
|
||||||
|
* since we don't have a way to detect whether the client window is calling
|
||||||
|
* `SetFocus()`.
|
||||||
|
*/
|
||||||
|
void grab_input_focus() const;
|
||||||
|
|
||||||
|
private:
|
||||||
/**
|
/**
|
||||||
* A pointer to the currently active window. Will be a null pointer if no
|
* A pointer to the currently active window. Will be a null pointer if no
|
||||||
* window is active.
|
* window is active.
|
||||||
|
|||||||
Reference in New Issue
Block a user