From 999404330619b9531a0c885304f268dc326d3ab1 Mon Sep 17 00:00:00 2001 From: Asahi Lina Date: Thu, 22 May 2025 11:00:41 +0900 Subject: [PATCH] Use WM_WINDOW_ROLE instead of WM_STATE to detect the host window Ardour brings up the plugin UI before the host window is visible, and it is missing some properties. Using WM_WINDOW_ROLE instead of WM_STATE makes it work. For reference, these are the properties that are set on the window at the time of plugin GUI instantiation: _NET_WM_ICON(CARDINAL) = Icon (16 x 16): WM_WINDOW_ROLE(STRING) = "plugin_ui" _NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 6294918 _NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_UTILITY _NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0x600d85 WM_CLIENT_LEADER(WINDOW): window id # 0x600001 _NET_WM_PID(CARDINAL) = 1604801 WM_LOCALE_NAME(STRING) = "en_US.UTF-8" WM_CLIENT_MACHINE(STRING) = "homura" WM_NORMAL_HINTS(WM_SIZE_HINTS): program specified size: 521 by 46 WM_PROTOCOLS(ATOM): protocols WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST WM_CLASS(STRING) = "ardour-8.12.0", "Ardour-8.12.0" WM_ICON_NAME(STRING) = "Audio 1: Melodyne (by Celemony) [VST3]" _NET_WM_ICON_NAME(UTF8_STRING) = "Audio 1: Melodyne (by Celemony) [VST3]" WM_NAME(STRING) = "Audio 1: Melodyne (by Celemony) [VST3]" _NET_WM_NAME(UTF8_STRING) = "Audio 1: Melodyne (by Celemony) [VST3]" --- src/wine-host/editor.cpp | 20 ++++++++++++++------ src/wine-host/editor.h | 5 +++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/wine-host/editor.cpp b/src/wine-host/editor.cpp index 42597911..40c01e9d 100644 --- a/src/wine-host/editor.cpp +++ b/src/wine-host/editor.cpp @@ -87,13 +87,18 @@ constexpr uint32_t wrapper_event_mask = constexpr char active_window_property_name[] = "_NET_ACTIVE_WINDOW"; /** - * We'll use this property to filter windows for `host_window_`. Like `xprop` - * and `xwininfo`, we'll only consider windows with this property set, although - * we won't filter on whether or not the window is actually visible because it - * may be minimalized when the plugin's GUI is being opened. + * We'll set this property on the Wine window to emulate the behavior of + * a minimal window manager. */ constexpr char icccm_wm_state_property_name[] = "WM_STATE"; +/** + * We'll use this property to filter windows for `host_window_`. WM_STATE + * can end up being set too late during window initialization, so we miss + * identifying the host window. + */ +constexpr char icccm_wm_window_role_property_name[] = "WM_WINDOW_ROLE"; + /** * This `WM_STATE` property value indicates that a window is a visible top level * window. Needs to be set on Wine's window as part of emulating the behavior of @@ -292,6 +297,9 @@ Editor::Editor(MainContext& main_context, }), xcb_wm_state_property_( get_atom_by_name(*x11_connection_, icccm_wm_state_property_name)), + xcb_wm_window_role_property_( + get_atom_by_name(*x11_connection_, + icccm_wm_window_role_property_name)), parent_window_(parent_window_handle), wrapper_window_( x11_connection_, @@ -316,7 +324,7 @@ Editor::Editor(MainContext& main_context, wine_window_(get_x11_handle(win32_window_.handle_)), host_window_(find_host_window(*x11_connection_, parent_window_, - xcb_wm_state_property_) + xcb_wm_window_role_property_) .value_or(parent_window_)) { logger.log_editor_trace([&]() { return "DEBUG: host_window: " + std::to_string(host_window_); @@ -931,7 +939,7 @@ bool Editor::is_wine_window_active() const { void Editor::redetect_host_window() noexcept { const xcb_window_t new_host_window = find_host_window(*x11_connection_, parent_window_, - xcb_wm_state_property_) + xcb_wm_window_role_property_) .value_or(parent_window_); if (new_host_window == host_window_) { return; diff --git a/src/wine-host/editor.h b/src/wine-host/editor.h index 7b4786f6..52eaa4f5 100644 --- a/src/wine-host/editor.h +++ b/src/wine-host/editor.h @@ -374,6 +374,11 @@ class Editor { */ xcb_atom_t xcb_wm_state_property_; + /** + * The atom corresponding to `WM_WINDOW_ROLE`. + */ + xcb_atom_t xcb_wm_window_role_property_; + /** * The window handle of the editor window created by the DAW. */