After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 653437 - gtk2 win32 tablet support broken
gtk2 win32 tablet support broken
Status: RESOLVED OBSOLETE
Product: gtk+
Classification: Platform
Component: Backend: Win32
2.24.x
Other Windows
: Normal normal
: ---
Assigned To: gtk-win32 maintainers
gtk-bugs
: DirtyHarry3033 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2011-06-26 17:59 UTC by Martin Renold
Modified: 2018-05-02 15:08 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
obvious fix of invalid cast (799 bytes, patch)
2011-06-26 18:00 UTC, Martin Renold
none Details | Review
initialize root_x/root_y members (fixes issue A) (1.00 KB, patch)
2011-06-26 18:01 UTC, Martin Renold
none Details | Review
half-assed attempt to restore propagate() test to WM_MOUSEMOVE (935 bytes, patch)
2011-08-14 23:05 UTC, Ben Jackson
none Details | Review
Refinement of Ben Jackson's propagate fix for mouse move (1.68 KB, patch)
2011-10-15 20:42 UTC, Mihai Cozma
none Details | Review

Description Martin Renold 2011-06-26 17:59:31 UTC
I'm trying to make MyPaint work with GTK 2.24 on Windows. With limited success so far. There are three issues:

A) MyPaint crashes with assertion failure because it receives x,y coordinates in the range of 10^9. Fix attached.

B) When extended events are reported, normal events are not suppressed. There is code to suppress them, but it doesn't work (any more). Setting GDK_NATIVE_WINDOWS=1 does not fix this.

C) Tablet pointer offset is wrong. Initially it's not too bad (maybe as much as the menubar height), but after moving the window it's clearly wrong. Setting GDK_NATIVE_WINDOWS=1 fixes this.
Comment 1 Martin Renold 2011-06-26 18:00:55 UTC
Created attachment 190704 [details] [review]
obvious fix of invalid cast
Comment 2 Martin Renold 2011-06-26 18:01:49 UTC
Created attachment 190705 [details] [review]
initialize root_x/root_y members (fixes issue A)
Comment 3 Martin Renold 2011-06-26 18:12:30 UTC
For reference, the corresponding MyPaint bugreport: https://gna.org/bugs/?18186

I have been trying to fix B) but so far I did not find a clean fix. The problem seems to be that normal WM_MOUSEMOVE events are reported to a different GdkWindow than the wintab motion events. The window where WM_MOUSEMOVE events are reported does not have extension events enabled, and because of this it doesn't ignore core events when ignore_core is set.

I guess the code should use _gdk_window_get_input_window_for_event() to get the correct (non-native) GdkWindow for an event, as the X11 implementation does, but I haven't figured out where/how to insert this. Maybe there is some easier workaround...

Finally, I haven't tested with GTK 3 yet but it looks like the input handling has changed too much for any of the fixes here to apply there.
Comment 4 Ben Jackson 2011-08-13 05:36:44 UTC
I am running mypaint git with gtk+ 2.24.4 and encountered the same issues.  I went through similar debug having not seen this bug.

Regarding (C) I specifically determined that (x,y) == (x_root,y_root) *when the button is pressed*.  I had the same window suspicion but event.window does *not* change.  Clearly the window used for gdk_input_translate_coordinates must change to see that problem.  I have noticed that if I edge out of the canvas (without lifting up) that as soon as I'm over the gutter at the top of the window suddenly the position is fine.

I also have an additional problem:

D) No input devices are detected.

Comparing this with 2.17.2 (which is what mypaint 0.9.1 was shipped with) I discovered via GDK_DEBUG=input that the _gdk_input_wintab_init_check was seeing garbage in 2.24.4.  Not complete garbage, but enough noise (specifically PHYSID=0) to disregard all devices.  I traced this to the following commit:

commit 88f54ea47d4a55bbbf9e34a7a0502f365eb69ae5
Author: Tor Lillqvist <tml@iki.fi>
Date:   Thu Sep 9 19:48:42 2010 +0300

    Avoid potential DLL hijacking in Wintab code

    Load Wintab32.dll from an absolute path. A proper Wintab32.dll, if
    present, should be in the Windows system directory, so load it from
    there.

my wild speculation is that opening the explicit path version reloads the DLL and the second copy does not have the right global state.  If you go back to simply LoadLibrary("Wintab32.dll") it discovers devices just fine again.
Comment 5 Ben Jackson 2011-08-13 06:00:45 UTC
Following up on (B):  I note the introduction of _gdk_input_crossing_event() in:

commit 341b8a47529ad5f1bddee19cb6e32fac6c7b8856
Author: Tor Lillqvist <tml@iki.fi>
Date:   Thu Aug 13 22:49:35 2009 +0300

    Initialize missing methods on Windows

    Set the input_window_destroy and input_window_crossing methods of the
    GdkWindowImplIface on Windows. Add implementation of
    _gdk_input_crossing_event that is mostly dummy, though.

the *only* behavior of which is to do if (!enter) _gdk_input_ignore_core = FALSE; (the rest is #ifdef'd out).  If there really is some kind of window transition on mousedown maybe it synthesizes a crossing event and hits that code.

Neutering that function didn't change any behavior, though.
Comment 6 Ben Jackson 2011-08-13 08:03:48 UTC
On (B) again I think I found the spot where WM_MOUSEMOVE -> GDK_MOTION_NOTIFY is not getting blocked.

Between these two commits there were a bunch of changes:

commit 1288ef1707dbb9a38d58be8c0dece6ea15a5ba00
Author: Cody Russell <bratsche@gnome.org>
Date:   Sun Mar 1 09:36:15 2009 -0500

    Grab changes

commit f4331caf8345fbdae729bc124ae5174a08e57aec
Author: Cody Russell <bratsche@gnome.org>
Date:   Sun Mar 1 08:55:50 2009 -0500

    grabs

Including the initial removal of the propagate() test:

+#if 0   // XXX - this seems to always block us from creating motion notify events -- Cody
       if (!propagate (&window, msg, grab_window, grab_owner_events, grab_mask,
                      doesnt_want_button_motion, TRUE))

which is cryptic but literally 10 times longer than the commit message and all we have to go on.

About a month later it looks like a lot of those changes in that area in f4331caf are unwound by:

commit 5341efd4d481f8cb478e0f6d48d534ae83813d45
Author: Alexander Larsson <alexl@redhat.com>
Date:   Wed Jul 1 10:26:37 2009 +0200

    Make win32 backend build and minimally work

Probably 40 lines of code surrounding the propagate() call are removed but the result does not restore the pre-Cody version and loses the propagate() test.

(and as a result I think my comment 5 is a red herring)
Comment 7 Ben Jackson 2011-08-14 23:03:41 UTC
I finally got a build going so I can test more elaborate changes:

Re: commit 88f54ea47 (pathname to wintab32.dll) here is my current theory:  Every time you load wintab32 (and by extension wacom_tablet) the Wacom driver initializes a copy of its global state.  All of the cursors have PHYSID=0 because it hasn't seen any of the actual devices in proximity.  When queried it returns very broad information (claiming all kinds of capability like tangential pressure which really don't exist).  Since gdk loads it (a new copy) and immediately queries it it sees all PHYSID=0 devices and ignores them.  The same thing happens if gdk is the first wintab32 user after boot *until* the pen comes into proximity and the Wacom driver identifies that particular pen.  The only thing that loading it without the path does is share the wintab32 state with some prior application which allows it to see the pens which previously came into proximity.

Re: my comment 6 above referring to commits that removed propagate() from the WM_MOUSEMOVE case:  If I cobble that back in (it requires some modifications because of other changes between 2.17.2 and 2.24.4) *and* I set GDK_NATIVE_WINDOWS then mypaint works fine (I also applied the Martin Renold patches from the attatchements).  Without GDK_NATIVE_WINDOWS I can see from some additional debug that the window selected by gdk_window_at_pointer() for tablet events does not match the one found by msg->hwnd in the WM_MOUSEMOVE case.  That fact alone probably explains most of the issues with coordinate offset (wrong window) and the fact that WM_MOUSEMOVE (the core event) is not suppressed (the window it's looking at doesn't have extension events enabled).

I have no idea how to go about debugging the window thing.
Comment 8 Ben Jackson 2011-08-14 23:05:39 UTC
Created attachment 193832 [details] [review]
half-assed attempt to restore propagate() test to WM_MOUSEMOVE

I do not know the significance of the "doesnt_want()" test in propagate() and the one that was there in 2.17.2 was removed at some point (maybe just for being dead code after this propagate() was removed?) so I stubbed it out since it's the _gdk_input_ignore_core that I care about.
Comment 9 Alexia Death 2011-09-17 21:06:40 UTC
These bugs crop up in GIMP as well making tablets on Windows unusable beyond basic core pointer and putting a gloomy shadow over the 2.8 release that we strive to do as soon as possible.
Comment 10 Michael Schumacher 2011-09-19 10:38:05 UTC
*** Bug 624985 has been marked as a duplicate of this bug. ***
Comment 11 Mihai Cozma 2011-10-11 14:55:29 UTC
I've started since a few days ago to look into this problem, and until I get everything setup for building GTK on my windows machine I have the following question, targeted at any kind GTK developer who might read this. The question is related to the value of GDK_NATIVE_WINDOWS.

Supposing that issue A is fixed, and issue B gets fixed and knowing that having set GDK_NATIVE_WINDOWS=1 fixes issue C, can we leave that set to 1 and consider the bug fixed, or it is set in the official binary release to 0 by default, so we should find another way for fixing this issue C?

Thanks and looking forward for your answer.
Comment 12 Mihai Cozma 2011-10-15 20:42:49 UTC
Created attachment 199078 [details] [review]
Refinement of Ben Jackson's propagate fix for mouse move

I have successfully applied the above patches and they work. 

I have made a refinement of Ben Jackson's fix by restoring the original "doesnt_want_button_motion" function instead of "doesnt_want_what_what" function. The rest is the same and it works as expected.

I have also noticed a strange behavior for issue C (when GDK_NATIVE_WINDOWS is not set):

The drawing is very very slow. I do not know why, as with GDK_NATIVE_WINDOWS it is working like a charm, but without it, besides the offset, the drawing is incredibly slow. 

I have noticed also that if you use myPaint in fullscreen (F11 shortcut), there is no offset at all, but it still draws very very slow.

As Ben said, the coordinates are correct for the "tip down" event of the tablet's pen, but are incorrect for the movement events. I've taken this a bit further and calculated that the wrong offset is always equal to the offset of the application's window from the top-left corner of the screen (that is why it works in fullscreen). Using this information I suspect somewhere the coordinates are received in "screen" mode but used in "client" mode (with top-left corner of the window being 0,0) and I have tried to replace the coordinates calculation code passed to events in several places but with no success.

I will continue to try and fix this, but I'm afraid even with offset fix, there is something very wrong with the painting code when GDK_NATIVE_WINDOWS is not set, so I think another option which should be considered is setting the above mentioned environment variable to 1 for mypaint only and we should be OK with it until gtk 3.0 comes on Windows.

I attach here the refinement of Ben Jackson's fix.
Comment 13 Martin Renold 2011-10-15 21:06:36 UTC
Mihai: drawing is very slow most likely because the active input device changes several times a second. This causes MyPaint to switch between tool settings and/or spam the undo stack with tiny stroke fragments.
Comment 14 Mihai Cozma 2011-10-15 23:22:16 UTC
Martin, thanks for the input, I understand now.

I have spent the last four hours reading all code related to GDK_NATIVE_WINDOWS  as I considered it is a good starting point, and I have found nothing that could point to the root of the offset problem. Device detecting seems to be independent of GDK_NATIVE_WINDOWS, so it might be a consequence of the new virtual windows system that occurs only on Windows platform, and it might lead to the device switching you are talking about.

My conclusion is the following:

During the development of gtk+ 2, the developers have started to implement a virtual windows system, where only the gtk root window is a native system window, the rest being virtual windows. Most of the changes related to this (I believe) were made by having version 2.16 as a starting point. 

It is quite obvious that it was quite a breaking change for gtk enabled applications, as in 2.18 the GDK_NATIVE_WINDOWS was introduced as an alternative for applications that do "weird" things on the new virtual windows system. I guess this is one of the reasons (along probably many new development ideas) for gtk 3, as there was need for some things to be done from scratch, and I also think MyPaint is also one of these applications.

Giving the explanation of why GDK_NATIVE_WINDOWS was introduced, I see no obvious reason of not use it for MyPaint under Microsoft Windows platform, giving that the other parts of the bugs are fixed. 

This solution will not help the port of MyPaint to gtk 3, but having a stable Windows release as soon as possible on gtk 2.24 is kind of a priority for many users, and spending more time in finding the right solution for this offset issue will not guarantee an easier porting to gtk 3, in which a lot of things are changed.

So my suggestion is to have this bugged fixed by:

1. Having Martin's two patches applied to 2.24 by a kind GTK developer
2. Having Ben Jackson's patch(diff) with my refining added also applied to 2.24 by a kind GTK developer.
3. Having GDK_NATIVE_WINDOWS set for MyPaint under Windows by a kind MyPaint developer.

After these are implemented and the new GTK released, I am more than willing to help get a stable release on Windows asap.
Comment 15 Mihai Cozma 2011-10-15 23:43:06 UTC
I want to add that also with GDK_NATIVE_WINDOWS=1, I have noticed a fast cursor switch between gdk circle and Windows default mouse pointer. It is annoying but it doesn't affect painting at normal speeds at all.
Comment 16 Bakhtiar Hasmanan 2011-10-21 03:18:04 UTC
another minor issue of enabling GDK_NATIVE_WINDOWS that I noticed is pointer become lose its "focus on hover" ability over menu.
Comment 17 Martin Renold 2011-10-23 10:20:34 UTC
I have tested the changes with GDK_NATIVE_WINDOWS=1 and they seem to work fine.

The cursor flickering has nothing to do with this bugreport. It also happens when setting GDK_NATIVE_WINDOWS=1 on GTK 2.24 git without applying the patches. Whenever the MyPaint canvas display is updated (eg. when panning the canvas with the arrow keys, or when painting with the mouse), the cursor reverts to a pointer until the next motion event.
Comment 18 Mihai Cozma 2011-10-26 10:26:58 UTC
I think this is the vulnerability that triggered loading the wintab directly:
http://secunia.com/advisories/45815
(my antivirus found it).

(In reply to comment #4)
> I am running mypaint git with gtk+ 2.24.4 and encountered the same issues.  I
> went through similar debug having not seen this bug.
> 
> Regarding (C) I specifically determined that (x,y) == (x_root,y_root) *when the
> button is pressed*.  I had the same window suspicion but event.window does
> *not* change.  Clearly the window used for gdk_input_translate_coordinates must
> change to see that problem.  I have noticed that if I edge out of the canvas
> (without lifting up) that as soon as I'm over the gutter at the top of the
> window suddenly the position is fine.
> 
> I also have an additional problem:
> 
> D) No input devices are detected.
> 
> Comparing this with 2.17.2 (which is what mypaint 0.9.1 was shipped with) I
> discovered via GDK_DEBUG=input that the _gdk_input_wintab_init_check was seeing
> garbage in 2.24.4.  Not complete garbage, but enough noise (specifically
> PHYSID=0) to disregard all devices.  I traced this to the following commit:
> 
> commit 88f54ea47d4a55bbbf9e34a7a0502f365eb69ae5
> Author: Tor Lillqvist <tml@iki.fi>
> Date:   Thu Sep 9 19:48:42 2010 +0300
> 
>     Avoid potential DLL hijacking in Wintab code
> 
>     Load Wintab32.dll from an absolute path. A proper Wintab32.dll, if
>     present, should be in the Windows system directory, so load it from
>     there.
> 
> my wild speculation is that opening the explicit path version reloads the DLL
> and the second copy does not have the right global state.  If you go back to
> simply LoadLibrary("Wintab32.dll") it discovers devices just fine again.
Comment 19 Alexander Larsson 2011-11-01 11:42:21 UTC
I just landed a rewrite in the gtk-2-23-win32 branch that makes tablets work again in win32, at least with testinput and gimp.
Comment 20 Alexander Larsson 2011-11-08 14:53:15 UTC
Landed in gtk-2-24 branch now.
Comment 21 Alexia Death 2011-12-15 16:33:01 UTC
Drawing on canvas now works with gimp, however, dragging a guide from toolbar does not. The same behavior as before reappears, events seem to be coming from  both the pen and the tablet.
Comment 22 Alexia Death 2011-12-15 16:33:47 UTC
mouse and tablet, I meant.
Comment 23 Martin Renold 2012-02-04 16:13:18 UTC
Not sure if this is stretching this bugreport, but we've had reports from different MyPaint 1.0 users on Windows users saying that pressure doesn't work. Too many to blame it on individual setup, IMO. Obviously, it also works for some users.

See https://gna.org/bugs/?19229 for some links. You'll find more of them in the MyPaint forum, including some workaround suggestions that usually work for exactly one user.
Comment 24 Alexia Death 2012-02-04 17:15:32 UTC
I read those reports too. They were about specific version of bamboo tablet and at least one solution was related to upgrading/downgrading the driver. It's possible and maybe even probable that issue is between the wacom driver and wintab interface.
Comment 25 Gissehel 2012-06-13 19:37:46 UTC
Here is the comment on the "pressure lost" I posted on the mypaint bugtracker yesterday on https://gna.org/bugs/?19229

I can make what ever test you want to help improve the situation.

---

I've got some new informations for all "pressure lost" on wacom tablets.

I've got an old Wacom Pen&Touch that I used to use on a daily basis with mypaint (including 1.0.0) on windows (7 - 64 bits).

I recently bought a new Wacom Pen&Touch.

The old Pen&Touch is labelled CTH 460/K
The new one is labelled CTH 470/K

Here is what I observe.

First : Deleting drivers, Manually removing wintab32.dll then reinstalling drivers doesn't change anything to the following description.

When I plug the CTH 470/K on the computer and I try to use mypaint 1.0.0, I don't have pressure (tablet act as a mouse).

When I plug the CTH 460/K on the computer and I try to use mypaint 1.0.0, I have pressure (tablet act as expected).

When I plug both CTH 460/K and CTH 470/K, on the computer, and I try to use mypaint 1.0.0, pressure works on BOTH hardwares.

When I plug both CTH 460/K and CTH 470/K, on the computer, I start mypaint 1.0.0 and then I unplug the CTH 460/K, I can still use pressure on already lauched mypaint. But I launch a new mypaint instance, the tablet act as a mouse. If I switch between "old mypaint process" and "new mypaint process", I have alternatively pressure and not pressure.

When I plug only CTH 470/K, and launch mypaint, pressure doesn't work. If I plug CTH 460/K pressure still doesn't work on mypaint, but if I launch a new mypaint process, pressure will work.

Everything said here with mypaint 1.0.0 works the same with gimp 2.8 (also tested inkscape on severals test cases)

What I deduce :
- This is probably not a mypaint 1.0.0 related problem
- This is not a Bamboo/not Bamboo, not even a Bamboo pen&touch related problem but a Bamboo pen&touch 2010 versus Bamboo pen&touch 2012 related problem.
- I look like an initialization problem somewhere. both tablet works when ever the process has been started when the CTH 460/K was plugged.
- The problem may concern every 2012 wacom tablet, because it look like Intuos (who have entire different drivers) are affected the same way.
Comment 26 Gissehel 2012-06-13 19:44:27 UTC
I forgot to add that when the CTH 470/K doesn't act as a tablet but as a mouse (pressure doesn't work), I can still use pressure on applications using the "web plugin" and bamboo dock.

Those non GTK processes load wintab32.dll (as seen by process explorer) so the seems to use the wintab32 API. So it seems that there is a way to use wintab32 and to make CTH 470/K working without having to plug a CTH 460/K.
Comment 27 Martin Renold 2012-08-12 11:06:51 UTC
Looks like users still get too many device changes in MyPaint. It looks like issue B - "normal events are not suppressed" - of my original report.

MyPaint bugreport: https://gna.org/bugs/?19948 ("Brushstrokes lag and break up on windows")
Comment 28 Michael Schumacher 2017-07-03 13:54:17 UTC
How much of this bug report is still relevant? Are the patches still valid, or have they already landed as part of the change mentioned in comment 20?
Comment 29 GNOME Infrastructure Team 2018-05-02 15:08:25 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to GNOME's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/gtk/issues/363.