Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add logic for CursorEntered/CursorLeft on Windows #150

Merged

Conversation

Fredemus
Copy link
Contributor

@Fredemus Fredemus commented Oct 2, 2023

Necessary to fix vizia/vizia#407, which is a bug that locks up the GUI when you press down on a mouse button inside the window and release the button outside the window.

Copy link
Member

@robbert-vdh robbert-vdh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be implemented without any additional state tracking or heuristics.

Take a look at the documentation of TrackMouseEvent. You can use it to get WM_MOUSEHOVER events when the cursor enters the client area, and WM_MOUSELEAVE events when the cursor leaves the client area. You need to set both the TME_HOVER and the TME_LEAVE flags in the TRACKMOUSEEVENT struct for that to work, and you need to repeat the call any time you receiver either of the two window messages. So the idea is that you call it after creating the window, and you then repeat the exact same call when handling those two window messages.

@Fredemus
Copy link
Contributor Author

Fredemus commented Oct 7, 2023

I first tried to do it like that, but WM_MOUSEHOVER ends up firing every time the mouse moves inside the window. This way it only happens the first time the mouse enters the window, which lines up with how it works on x11.

edit: also looks like winit does it the same way as I: https://github.com/rust-windowing/winit/blob/ee0db52ac49d64b46c500ef31d7f5f5107ce871a/src/platform_impl/windows/event_loop.rs#L1443

@robbert-vdh
Copy link
Member

In that case you'd be able to just only set TME_HOVER when initially creating the window and when handling WM_MOUSELEAVE, and only set TME_LEAVE when handling WM_MOUSEENTER, no? If that works that sounds like a better solution than approximating it by tracking mouse moves.

@Fredemus
Copy link
Contributor Author

Fredemus commented Oct 8, 2023

WM_MOUSEENTER

For some reason there is no WM_MOUSEENTER, only WM_MOUSEHOVER

@robbert-vdh
Copy link
Member

Sorry yeah I meant WM_MOUSEHOVER.

@Fredemus
Copy link
Contributor Author

Fredemus commented Oct 8, 2023

Ah okay. For reasons I don't really understand just sending TrackMouseEvent with TME_HOVER in WM_MOUSELEAVE means the event never fires, no matter if I set either TME_HOVER or TME_LEAVE initially, or both. I also tried to change dwHoverTime in case the system default was weird. It seemingly has to happen in WM_MOUSEMOVE.

I digged up the documentation I based this on.

src/win/window.rs Outdated Show resolved Hide resolved
@Fredemus Fredemus force-pushed the feature/windows-cursor-enter-leave branch from 94d21af to b46a6ad Compare January 8, 2024 16:41
@Fredemus Fredemus force-pushed the feature/windows-cursor-enter-leave branch from b46a6ad to d8cedc8 Compare January 9, 2024 00:38
Copy link
Member

@robbert-vdh robbert-vdh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how to feel about the Win32 API for this, but I guess this is the way to do it. 😅

LGTM.

@robbert-vdh robbert-vdh merged commit 26b019d into RustAudio:master Mar 18, 2024
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Mouse locks up when releasing mouse capture outside the window in vizia_baseview
2 participants