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

CursorEntered and CursorLeft events not getting sent if entered a second window while holding the mouse button down #3908

Open
noemu opened this issue Sep 11, 2024 · 4 comments
Labels
DS - windows S - platform parity Unintended platform differences

Comments

@noemu
Copy link

noemu commented Sep 11, 2024

CursorEntered and CursorLeft works perfectly only for the window you start the drag and drop gesture. While holding the mouse button the events are not fired in another window.

How to reproduce:

  • create 2 windows (e.g. press ctrl+N in the window example)
  • make a drag and drop gesture from one window into another (press and hold a mouse button, in first window and release it in the second window)

Expected Result:

  • CursorEntered event is fired as soon as the second window is entered.

Actual Result:

  • CursorEntered event is fired after the mouse button is released. And a second CursorLeft event is fired for the first window.

I've tested it only on windows. I'm not sure if it is related to windows or the following fixed bug Issue #3153

@madsmtm madsmtm added B - bug Dang, that shouldn't have happened DS - windows S - platform parity Unintended platform differences and removed B - bug Dang, that shouldn't have happened DS - windows labels Sep 11, 2024
@madsmtm
Copy link
Member

madsmtm commented Sep 11, 2024

On macOS, if I click and hold the cursor from window A to B, I get the following sequence:

Window A: MouseInput { state: Pressed, ... }
Window A: CursorLeft
Window A: MouseInput { state: Released, ... }
Window B: CursorEntered

I have no idea what the desired is, but I'm not sure we really have the ability to influence this in Winit, at least not without a lot of hacks?

@noemu
Copy link
Author

noemu commented Sep 11, 2024

On Windows:
FileHovered, FileDropped and FilesHoveredLeft is also affected by this Issue.
I started a File-Drag with drag-rs from Window A. Window B doesn't fire any events until the mouse is released.

The whole event-loop of window B isn't running as long as the mouse button is pressed. Switching to window B with Alt-Tab while holding the mouse button, seems to enable the event-loop of B. Maybe switching the focus could be a workaround for my implementation.

@noemu
Copy link
Author

noemu commented Sep 13, 2024

I finally figured out, why it's behaving like that.

It's basically because of capture_mouse / SetCapture(window).

WM_LBUTTONDOWN => {
            ...
            unsafe { capture_mouse(window, &mut userdata.window_state_lock()) };
            ...
        },

As long as the mouse is captured by a window, all events are forwarded to its event loop.

The workaround for me is to check in MouseMove if I entered another window. And in that case I would switch the SetCapture to the window under the cursor.

@daxpedda
Copy link
Member

daxpedda commented Oct 9, 2024

AFAIK capturing is necessary for "pointer focus" to work correctly.
This is the concept of having mouse events continue to be sent to the window where the input was started.

@madsmtm on most backends I believe you don't receive a CursorEnter/CursorLeave on other windows during pointer focus, so I think MacOS should be adjusted.

Whatever comes out of this, I believe we should make sure all backends behave the same, barring any platform-specific dangers coming up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DS - windows S - platform parity Unintended platform differences
Development

No branches or pull requests

3 participants