From e1ed35bfd82b418ed7b1d9d5de891656d8ea8974 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Mon, 26 Jul 2021 14:44:23 +0200 Subject: [PATCH] Don't respond to hit tests from the Win32 window This will let us detect other, non-wrapper windows to the right and to the bottom of a plugin GUI. Useful for drag-and-drop so we don't end up overriding Wine's internal drag-and-drop mechanism. --- src/wine-host/editor.cpp | 17 ++++++++++++++++- src/wine-host/editor.h | 6 +++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/wine-host/editor.cpp b/src/wine-host/editor.cpp index 707072e9..7e54847c 100644 --- a/src/wine-host/editor.cpp +++ b/src/wine-host/editor.cpp @@ -1082,6 +1082,20 @@ LRESULT CALLBACK window_proc(HWND handle, SetCursor(arrow_cursor); } } break; + // NOTE: Needed for our `is_cursor_in_wine_window()` implementation. Our + // `win32_window` extends way past the visible plugin GUI. And + // even though it will appear nicely clipped on screen, + // `WindowFromPoint()` would still return our window when hovering + // to the right or bottom of a plugin GUI, even if there's another + // window right behind it. To make sure we can detect other Wine + // windows in that region, we need to make sure that + // `WindowFromPoint()` doesn't consider the parent window (it's + // not going to be relevant anyways). In practice this will still + // mean that the function returns our parent window if it's the + // only window on that coordinate. + case WM_NCHITTEST: { + return HTNOWHERE; + } break; } return DefWindowProc(handle, message, wParam, lParam); @@ -1259,7 +1273,8 @@ bool is_cursor_in_wine_window() noexcept { // `WindowFromPoint()` will still return that same huge window // when we hover over an area to the right or to the bottom of a // plugin GUI. We can easily detect by just checking the window - // class name. + // class name. Also check out the `WM_NCHITTEST` implementation in + // the message loop above. std::array window_class_name{0}; GetClassName(windows_window, window_class_name.data(), window_class_name.size()); diff --git a/src/wine-host/editor.h b/src/wine-host/editor.h index 0f7c6299..2f5926ac 100644 --- a/src/wine-host/editor.h +++ b/src/wine-host/editor.h @@ -72,9 +72,9 @@ xcb_atom_t get_atom_by_name(xcb_connection_t& x11_connection, /** * Check if the cursor is within a Wine window. We can of course only detect * Wine applications within the current prefix. This ignores the extended client - * area of yabridge windows (which might mean that this function will spuriously - * return false if another window on the bottom right of an editor window is - * 'obstructed' by this clipped, invisible window). + * area of yabridge windows. (so it will consider other Wine windows to the + * right or to the bottom of a yabridge plugin editor, but not the extended + * client area itself) */ bool is_cursor_in_wine_window() noexcept;