Fix plugins not updating with dropdowns

This commit is contained in:
Robbert van der Helm
2020-03-23 22:19:49 +01:00
parent c046f9fe7b
commit 5d1051a00c
3 changed files with 19 additions and 20 deletions
+3 -2
View File
@@ -7,8 +7,9 @@ Yet Another way to use Windows VST2 plugins in Linux VST hosts.
There are a few things that should be done before releasing this, including: There are a few things that should be done before releasing this, including:
- Implement missing features: - Implement missing features:
- GUIs. It mostly works right now, but there are a few small problems - GUIs. The only problem remaining is that child windows (such as dropdowns)
remaining regarding window placement and child windows (i.e. droopdowns). don't appear anchored to the reparented editor and will still appear in the
top left corner of the screen.
- Add missing details if any to the architecture section. - Add missing details if any to the architecture section.
- Document what this has been tested on and what does or does not work. - Document what this has been tested on and what does or does not work.
- Document wine32 support. - Document wine32 support.
+15 -17
View File
@@ -78,10 +78,6 @@ bool Editor::embed_into(const size_t parent_window_handle) {
return false; return false;
} }
// TODO: Right now the child's child windows are not anchored to the window
// and do not receive keyboard focus. THis affects things like
// dropdowns.
// This follows the embedding procedure specified in the XEmbed sped: // This follows the embedding procedure specified in the XEmbed sped:
// https://specifications.freedesktop.org/xembed-spec/xembed-spec-latest.html // https://specifications.freedesktop.org/xembed-spec/xembed-spec-latest.html
// under 'Embedding life cycle // under 'Embedding life cycle
@@ -89,18 +85,7 @@ bool Editor::embed_into(const size_t parent_window_handle) {
// a library // a library
const size_t child_window_handle = get_x11_handle().value(); const size_t child_window_handle = get_x11_handle().value();
xcb_reparent_window(x11_connection.get(), child_window_handle,
parent_window_handle, 0, 0);
// Honestly, I'm not sure if all of this XEmbed stuff is even doing anything // Honestly, I'm not sure if all of this XEmbed stuff is even doing anything
// This tells the WM that the parent window embedding and mapping/uumapping
// a child window. Requires the PROPERTY_NOTIFY event.
std::array<int, 2> xembed_info_values{xembed_protocol_version, 1};
xcb_change_property(x11_connection.get(), XCB_PROP_MODE_REPLACE,
child_window_handle, xcb_xembed_info, xcb_xembed_info,
32, 2, xembed_info_values.data());
const int parent_events = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | const int parent_events = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
XCB_EVENT_MASK_STRUCTURE_NOTIFY; XCB_EVENT_MASK_STRUCTURE_NOTIFY;
@@ -113,6 +98,16 @@ bool Editor::embed_into(const size_t parent_window_handle) {
xcb_change_window_attributes(x11_connection.get(), child_window_handle, xcb_change_window_attributes(x11_connection.get(), child_window_handle,
XCB_CW_EVENT_MASK, &child_events); XCB_CW_EVENT_MASK, &child_events);
xcb_reparent_window(x11_connection.get(), child_window_handle,
parent_window_handle, 0, 0);
// This tells the WM that the parent window embedding and mapping/uumapping
// a child window. Requires the PROPERTY_NOTIFY event.
std::array<int, 2> xembed_info_values{xembed_protocol_version, 1};
xcb_change_property(x11_connection.get(), XCB_PROP_MODE_REPLACE,
child_window_handle, xcb_xembed_info, xcb_xembed_info,
32, 2, xembed_info_values.data());
// Tell the window from Wine it's embedded into the window provided by the // Tell the window from Wine it's embedded into the window provided by the
// host // host
send_xembed_event(child_window_handle, xembed_embedded_notify_msg, 0, send_xembed_event(child_window_handle, xembed_embedded_notify_msg, 0,
@@ -125,7 +120,7 @@ bool Editor::embed_into(const size_t parent_window_handle) {
xcb_map_window(x11_connection.get(), child_window_handle); xcb_map_window(x11_connection.get(), child_window_handle);
xcb_flush(x11_connection.get()); xcb_flush(x11_connection.get());
ShowWindow(win32_handle->get(), SW_SHOW); ShowWindow(win32_handle->get(), SW_SHOWNORMAL);
return true; return true;
} }
@@ -135,7 +130,10 @@ void Editor::handle_events() {
// the window // the window
if (win32_handle.has_value()) { if (win32_handle.has_value()) {
MSG msg; MSG msg;
while (PeekMessage(&msg, win32_handle->get(), 0, 0, PM_REMOVE)) { // The second argument has to be null since we not only want to handle
// events for this window but also for all child windows (i.e.
// dropdowns). I spent way longer debugging this than I want to admit.
while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
} }
+1 -1
View File
@@ -124,7 +124,7 @@ class PluginBridge {
*/ */
std::thread parameters_handler; std::thread parameters_handler;
/** /**
* The t thread that handles calls to `processReplacing` (and `process`). * The thread that handles calls to `processReplacing` (and `process`).
*/ */
std::thread process_replacing_handler; std::thread process_replacing_handler;