GNOME Bugzilla – Bug 609956
Missing global mouse capture when a mouse button is held down
Last modified: 2018-02-10 03:29:21 UTC
I'm running this test under Windows Vista, in case that matters. Steps to reproduce: 1. Run gtk-demo. 2. Run the "Text Widget / Multiple Views" demo. 3. Move the "TextView" so that the right hand side of the window is clear of the "GTK+ Code Demos" window. 4. Press and hold the mouse button on the larger of the two scrollbars. 5. Move the mouse up and down on top of the "TextView" window and observe that scrolling works fine here. 6. Move the mouse to just off the right of the "TextView" window and observe that moving the mouse up and down does not scroll at all here. 7. While the mouse is outside the window, release the button. Move the mouse back into the window and observe that the button-release message was missed and GTK thinks the button is still down. There needs to be some sort of global mouse capture when a button is pressed. Currently it seems that the mouse is captured only for windows in the same application.
Created attachment 153812 [details] [review] Patch against gtk+-2.18.7 that hacks around this bug Attaching a patch that fixes the problem. I call SetCapture and ReleaseCapture when mouse buttons are pressed and released, and pass messages to the captured window while one is active. It's a complete hack, almost certainly the wrong way to do it, but it works. Might be a good starting point for someone that knows how that code should be modified.
Thanks. Please add a comment here if you notice any bad side-effect of this. If not, I guess it should be committed.
I already know it'll break any gdk_pointer_grab() currently in effect. So far I've found that this breaks submenus, and it probably breaks other things too. Currently I'm playing around with having button_down_grab_start() do nothing if GetCapture() returns non-NULL. I tried using gdk_pointer_grab() instead of going straight to win32 SetCapture() but then events didn't arrive at all. At a guess it was capturing on the wrong HWND.
Created attachment 153989 [details] [review] Improved version of the previous patch This is an improved version of the patch that tries to avoid stomping on grabs created by gdk_pointer_grab() and friends. It really needs to be properly integrated with the exist grab system, but I don't understand that code well enough to do it properly.
Created attachment 173100 [details] [review] win32: Restore button event propagation Here's a simple patch that restores mouse button event propagation (like in 2.16.x and before), but ported to the new API. It will ensure that for example mouse up event outside the window will reach the GdkWindow which is currently grabbing the pointer. It does not solve the case where another window gets focused (like pressing Alt+Tab while still holding down the mouse button), but I'm working on another patch which will solve that issue (it is a separate issue).
Comment on attachment 153989 [details] [review] Improved version of the previous patch Sorry, I didn't mean to obsolete your patch. :)
This bug seems to be related to bug #605569.
Created attachment 173123 [details] [review] win32: Generate pointer grab broken event when focus is lost
Created attachment 173124 [details] [review] win32: Restore pointer event propagation Fixes delivery of button and motion events when pointer is grabbed. These events are quite essential for widgets like GtkScrollbar and GtkPaned.
Comment on attachment 173100 [details] [review] win32: Restore button event propagation Replaced by new patch which also propagates pointer motion events.
Created attachment 173125 [details] [review] win32: Restore pointer event propagation Fixes delivery of button and motion events when pointer is grabbed. These events are quite essential for widgets like GtkScrollbar and GtkPaned.
Created attachment 173126 [details] [review] win32: Pointer grab broken event on focus loss Tweak variable naming and remove a redundant check.
Comment on attachment 173123 [details] [review] win32: Generate pointer grab broken event when focus is lost Forgot to obsolete the previous version of this patch.
Created attachment 173130 [details] [review] win32: Pointer grab broken event on focus loss Simplify a bit.
Created attachment 173131 [details] [review] win32: Restore emulation of X11's automatic active grab
Alright, I think I'm a happy, been testing my GTK+-based application with these changes and everything seems to be in order. Wonderful to be able to use scroll-bars like before, buttons behaving like they used to, and GtkPaned not ending up in a bad state when the mouse leaves the window. :)
We're moving to gitlab! As part of this move, we are closing bugs that haven't seen activity in more than 5 years. If this issue is still imporant to you and still relevant with GTK+ 3.22 or master, please consider creating a gitlab issue for it.