winit icon indicating copy to clipboard operation
winit copied to clipboard

On Windows, fix left mouse button release event not being sent on drag finish

Open feelingnothing opened this issue 3 years ago • 6 comments

After tricking windows into thinking we are pressing on HTCAPTION, we would not get WM_NCLBUTTONUP, thus creating unexpected behavior in winit dependent projects (https://github.com/emilk/egui/issues/1245#issue-1134534176) Some debugging after it appears that wine have different logic that winapi (for context see this)

With event tracing we can see that the most suitable event triggered on every drag is WM_EXITSIZEMOVE(docs): image

  • Fixes: https://github.com/rust-windowing/winit/issues/2192

feelingnothing avatar Feb 19 '22 17:02 feelingnothing

I'd be interested in seeing this merged! the drag_window feature is critical for users that want to draw their own window frame.

emilk avatar Mar 28 '22 22:03 emilk

Can't we just set the flag inside Window::drag_window? Window should have access to WindowState.

maroider avatar Mar 31 '22 20:03 maroider

Can't we just set the flag inside Window::drag_window? Window should have access to WindowState.

I mean there is no difference, anyways to have to check for HTCAPTION in WM_NCLBUTTONDOWN, either we do it in drag_window or in event handler doesn't matter. I like how it makes all dragging logic in dragging function, but check for HTCAPTION is dragging logic too.

feelingnothing avatar Apr 02 '22 16:04 feelingnothing

Thanks, but this leads to undesired Released events if we are actually dragging inside the HTCAPTION area. One idea could be to instead emit a message with HTCLIENT instead of HTCAPTION on drag_window, use it as indicator that it's a user generated event in the event loop, but forwarding HTCAPTION to DefWindowProc to internally let it do the dragging stuff for us..

I don't think there is a way to Release event to be emitted in unwanted situation, considering dragging flag in window state. With event logger from @maroider we can see that WM_EXITSIZEMOVE is the most suitable one. The windows api tells that this event is trigged in the end of every move or resize, considering the dragging flag I'm sure nothing out of ordinary would happend

feelingnothing avatar Apr 02 '22 16:04 feelingnothing

Can't we just set the flag inside Window::drag_window? Window should have access to WindowState.

Right, I like this more under the light drag_resize_window. I guess we could even drop then the whole handling NCLBUTTONDOWN event.

I don't think there is a way to Release event to be emitted in unwanted situation, considering dragging flag in window state.

Sorry if I wasn't clear on it. Normal dragging without drag_window using the native decorations from Windows will emit the same HTCAPTION message which we use for emulating. So in both cases the dragging flag will be set leading to the released event. In the case of native decorations this is not desired as we do not emit the corresponding Pressed event.

msiglreith avatar Apr 03 '22 11:04 msiglreith

I guess we could even drop then the whole handling NCLBUTTONDOWN event.

Wouldn't that re-introduce the issue fixed by #839?

maroider avatar Apr 03 '22 23:04 maroider