Move check for cursor within Wine window to editor

We'll reuse this for the LeaveNotify check instead to avoid having to
ignore all `NonVirtual` events.
This commit is contained in:
Robbert van der Helm
2021-07-26 13:59:55 +02:00
parent 0523a06ed7
commit 85264a759d
3 changed files with 40 additions and 23 deletions
+27
View File
@@ -1245,4 +1245,31 @@ ATOM get_window_class() noexcept {
return window_class_handle; return window_class_handle;
} }
bool is_cursor_in_wine_window() noexcept {
static const HWND windows_desktop_window = GetDesktopWindow();
POINT windows_pointer_pos;
GetCursorPos(&windows_pointer_pos);
if (HWND windows_window = WindowFromPoint(windows_pointer_pos);
windows_window && windows_window != windows_desktop_window) {
// NOTE: Because resizing reparented Wine windows without XEmbed is
// a bit janky, yabridge creates windows with client areas
// large enough to fit the entire screen, and the plugin then
// embeds its own GUI in a portion of that. The result is that
// `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 and skip that though,
// since the embedded plugin windows won't have an X11 window
// ID property.
const xcb_window_t x11_window =
static_cast<xcb_window_t>(reinterpret_cast<size_t>(
GetProp(windows_window, "__wine_x11_whole_window")));
if (x11_window == XCB_NONE) {
return true;
}
}
return false;
}
#undef THROW_X11_ERROR #undef THROW_X11_ERROR
+9
View File
@@ -69,6 +69,15 @@ constexpr char xdnd_aware_property_name[] = "XdndAware";
xcb_atom_t get_atom_by_name(xcb_connection_t& x11_connection, xcb_atom_t get_atom_by_name(xcb_connection_t& x11_connection,
const char* atom_name); const char* atom_name);
/**
* 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).
*/
bool is_cursor_in_wine_window() noexcept;
/** /**
* Used to store the maximum width and height of a screen. * Used to store the maximum width and height of a screen.
*/ */
+4 -23
View File
@@ -283,8 +283,6 @@ void WineXdndProxy::end_xdnd() {
#endif #endif
void WineXdndProxy::run_xdnd_loop() { void WineXdndProxy::run_xdnd_loop() {
const HWND windows_desktop_window = GetDesktopWindow();
std::optional<xcb_window_t> last_xdnd_window; std::optional<xcb_window_t> last_xdnd_window;
// Position and status messages should be sent in lockstep, which makes // Position and status messages should be sent in lockstep, which makes
// everything a bit more complicated. Because of that we may need to spool // everything a bit more complicated. Because of that we may need to spool
@@ -428,27 +426,10 @@ void WineXdndProxy::run_xdnd_loop() {
// We want to ignore all Wine windows (within this prefix), since Wine // We want to ignore all Wine windows (within this prefix), since Wine
// will be able to handle the drag-and-drop better than we can // will be able to handle the drag-and-drop better than we can
POINT windows_pointer_pos; if (is_cursor_in_wine_window()) {
GetCursorPos(&windows_pointer_pos); maybe_leave_last_window();
if (HWND windows_window = WindowFromPoint(windows_pointer_pos); last_xdnd_window.reset();
windows_window && windows_window != windows_desktop_window) { continue;
// NOTE: Because resizing reparented Wine windows without XEmbed is
// a bit janky, yabridge creates windows with client areas
// large enough to fit the entire screen, and the plugin then
// embeds its own GUI in a portion of that. The result is that
// `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 and skip that though,
// since the embedded plugin windows won't have an X11 window
// ID property.
const xcb_window_t x11_window =
static_cast<xcb_window_t>(reinterpret_cast<size_t>(
GetProp(windows_window, "__wine_x11_whole_window")));
if (x11_window == XCB_NONE) {
maybe_leave_last_window();
last_xdnd_window.reset();
continue;
}
} }
// When transitioning between windows we need to announce this to // When transitioning between windows we need to announce this to