GNOME Bugzilla – Bug 143460
Missed tablet button click/release events on win32 (wintab)
Last modified: 2007-01-19 02:52:16 UTC
When using a Wacom Graphire 3 USB tablet, driver version 4.78-6, on Windows XP SP1 together with lastest gtk-2-4 from anoncvs, The GIMP 2.0.1 and --use-wintab specified, button click and release events are often missed (about half the time) when using the side buttons on the stylus or all buttons on the Wacom mouse ("puck"). The pressure sensitive tip and eraser of the stylus work OK since there is workaround code in GDK to detect missed clicks by using the pressure information. When using the stylus, the missed events are annoying if the side button is accidentally clicked and the release event is missed. In particular, it could be confusing for new users who are unaware of the problem when everything suddenly seems to stop working because the middle button has been pressed accidentally. The Wacom mouse is more or less useless for drawing if --use-wintab is specified since even left button clicks/releases are missed. The events seem to get lost because the Wintab initialisation code specifically requests a packet rate of 50 (in gdk/win32/gdkinput-win32.c, function gdk_input_wintab_init()) by setting the lc.lcPktRate field to 50. My tablet with the indicated driver version seems to use 100 packets/s by default, and my guess is that half of the packets are simply thrown away to get the lower packet rate. If I change the code to use the default packet rate, for example by replacing the line that sets lcPktRate with the line "WTInfo (WTI_DDCTXS + devix, CTX_PKTRATE, &lc.lcPktRate);", click events are no longer missed and everything seems to work fine for me. However, there is a potential problem - the rate of motion events are doubled for me, which causes the CPU usage of The GIMP to roughly double to around 50-75% on an Intel P4 2.4 GHz, depending on which drawing tool, brush size etc that is used. I don't know what will happen on a slower machine, but there could be problems. Unfortunately I currently don't have access to any other machine so I can't test if this really is a problem. I guess that there is a good reason that the packet rate was hard-coded? The high CPU usage seems to be caused by The GIMP, if I run the tests/testinput program in GTK+ with --use-wintab, CPU usage stays around 5 % when drawing in it. There are a few solutions to get around the increased CPU usage, with varying degree of ugliness: 1. Increase the packet rate to the default value and try to change The GIMP to use less CPU for handling one event. Could it be possible to batch up the handling of several motion events, or at least avoid flushing the display for each motion event? I am no expert on the internals of The GIMP, so I don't know how hard this would be. 2. Don't change the packet rate, switch to absolute reporting of tablet button events from Wintab (remove PK_BUTTONS from lcPktMode) and detect clicks/releases manually in _gdk_input_other_event by comparing the current button state with some saved state. 3. Increase the packet rate to the default value and throw away half of the motion events in _gdk_input_other_events (one should probably check which packet rate the tablet uses so it doesn't break for a tablet that actually sends 50 packets/second, a problem that one might have to look out for is that the lcPktRate field might not be working for some older tablets/drivers, at least according to the (very old) Wacom FAQ available at http://www.wacomeng.com/devsupport/ibmpc/wacomwindevfaq.html#FAQ3.9 ). Option 1 is in my opinion the cleanest and most desirable, since an increased packet rate should also result in smoother curves when moving the stylus fast. A variant of option 3 is to allow the user to specify the event rate to adapt to the capacity of the computer. One could consider the CPU usage to be a possible bug/enhancement in The GIMP and just go ahead and change the packet rate in GTK+ and try to enhance The GIMP later, though personally I don't like breaking things for users on older computers. CPU usage for The GIMP could also be high when running on Linux/X11 using tablets with high packet rates, so the Linux developers can probably contribute to this discussion as well. Maybe one should have a discussion on gtk-devel-list and gimp-devel-list? (As a side note, I should really build the lastest version of The GIMP from CVS to see that the CPU usage remains high in the lastest version, but I haven't had time to set everything up.)
The problem with missing press/release events could be considered a driver limitation/bug. I'll try to contact Wacom and see what they think about it.
I can confirm this bug, and I'm using the Wacom Intuous 2 with GIMP 2.2.1 and GTK 2.4.14. Using the DuoSwitch on the stylus is supposed to initiate a right-click event, yet GTK misses it roughly half of the time.
According to a Wacom software engineer, this is indeed a limitation in the driver (it discards packets to get the specified packet rate _after_ the button information has been converted to relative mode). He recommends to use absolute reporting of button data, and apparently that is what more or less everybody uses. The alternative is to get all packets and drop some of them manually to get the desired packet rate. He could not give any promise on when it might be fixed. When I get some time to burn I'll try to cook up a patch that uses absolute mode instead. It shouldn't be that difficult. Tor: What branch would you prefer such patch to be against? 2-4, 2-6 or HEAD?
> What branch would you prefer such patch to be against? 2-4, 2-6 or HEAD? All three, I guess ;-) I might still do a 2.4 snapshot build. There shouldn't be any much difference between them.
I've created a patch that switches to absolute button reporting, which also allows us to drop the code that detects missing click events only for the stylus. The patch also swaps button 2 and 3, as that works better with my Wacom Graphire 3 tablet. In particular, it is very annoying having to use the scroll wheel on the puck to do a right-click. Now I don't know how other tablets report their buttons, so it is possible that this will break things for other users, and a configuration setting or something would have to be added to fix it instead. I can remove that part of the patch if you don't like it. What do you think?
Created attachment 37753 [details] [review] Patch that switches to absolute button reporting Patch against latest gtk-2-6 sources from anoncvs, tested on Windows XP SP2 and using a Wacom Graphire 3
I just noticed I missed specifying a type for button_map[], will attach an updated patch soon.
Created attachment 38322 [details] [review] Revised patch for absolute button reporting Here's the updated patch, sorry that it took so long.
The problem with lost click events seems to be fixed in driver version 4.90-3 for my Wacom Graphire 3 tablet. I wonder if similar fixes are available for Intuous? If so, changing to absolute button reporting would not be necessary.
Any news on a driver fix for Intuos? If not, I'll apply the patch.
There seems to be updated drivers available for Intuos but I don't know if they fix the problem. I don't have any Intuos hardware to test on. Even with the improved drivers there are some advantages with using absolute button reporting such as better handling of lost events (if the CPU can't keep up with the packet rate) for all buttons. On the other hand the patch needs some testing against current GTK+ and GIMP. I could try to do that soonish if you also think it could be useful.
Thanks. Patch finally committed to trunk and gtk-2-10: 2007-01-19 Robert Ögren <gtk@roboros.com> Fix for bug #143460 - missed tablet clicks on Windows * gdk/win32/gdkinput-win32.c (_gdk_input_wintab_init_check): Request absolute reporting of tablet button state, and cut down the packet queue size a bit. (_gdk_input_other_event): Change button state handling accordingly. Also drop the no longer necessary code that detects missed clicks/releases for button 1. The switch to absolute button state should prevent missed events for all buttons. Additionally, swap button 2 and 3. (_gdk_input_grab_pointer): Don't reset button_state, that will only cause a new press event as soon as the next tablet packet arrives.