Bug affecting systems with two monitors, and a potential fix
This discussion is connected to the gimp-developer-list.gnome.org mailing list which is provided by the GIMP developers and not related to gimpusers.com.
This is a read-only list on gimpusers.com so this discussion thread is read-only, too.
Bug affecting systems with two monitors, and a potential fix | David Polberger | 30 Sep 01:04 |
Bug affecting systems with two monitors, and a potential fix | Martin Nordholts | 02 Oct 08:15 |
Bug affecting systems with two monitors, and a potential fix | David Polberger | 27 Nov 03:49 |
Bug affecting systems with two monitors, and a potential fix
I have been trying to fix a bug affecting the paint tools on systems with two monitors (possibly only Xinerama systems), and have run into a few snags that I would appreciate some help with. (I'm pretty sure that this bug has been reported in Bugzilla, but the closest report I can find is 168880, and that is incomplete; I will open a new bug if I can't find an existing report.)
I use Xinerama to extend my desktop. My setup looks like this:
+------------------+-----------------------+ | | | | | 1024x768 | | | | | 1280x1024 | | | | | | +------------------+ | | | | | +-----------------------+
The monitor to the left is ordinarily filled with panels (the toolbox, layers, channels, brushes, etc), while the higher-resolution monitor is used to hold the image I'm editing. The problem is that when I use a paint tool (on the higher-resolution monitor), I cannot paint past the 1024th horizontal display pixel (indicated by the line in the figure above). Painting past the 768th vertical display pixel works fine. What happens when I try to paint past the 1024th horizontal display pixel is that pixel x - 1024 is painted instead. (To be precise, just pressing the primary mouse button once works, and moving it one pixel in any direction also works; I get the behavior described above when continuing to paint past the 1024th horizontal display pixel.)
I have been trying to investigate this bug using GDB, and while I have come up with a solution that cures the problem, it's likely not the correct fix. This seems to be a GDK problem, but I would like some feedback from this list on whether this is indeed the case.
gimp_display_shell_canvas_tool_events() (in gimpdisplayshell-callbacks.c) seems to be called whenever an event is fired, such as the user moving the mouse pointer, or pressing a button. When the user is moving the mouse, the event is GDK_MOTION_NOTIFY (line 1086 in 2.3.18). The code that calls the mouse motion code of the active tool (tool_manager_motion_active()) is called in one of two places in the GDK_MOTION_NOTIFY code, depending on whether GDK believes that there are any "motion history events" associated with the current device (through gdk_device_get_history()[1]); the code roughly looks like this:
[1] http://library.gnome.org/devel/gdk/unstable/gdk-Input-Devices.html#id2970254
if (there are motion history events)
{
iterate over the motion history events and transform the coordinates
call the motion code of the active tool with the new coordinates
}
else
{
call the motion code of the active tool with the old coordinates
}
(This explains why I can paint once, and move the mouse pointer one pixel before I get the erroneous behavior.)
I have noted that if I paint in the left part of the image (0 < x < 1024), GDK never reports that there are any motion history events, and thus, the motion code of the active tool is called with the old coordinates -- at all times, and things work as expected. If, however, I paint past the 1024th horizontal display pixel, GDK _will_ report that there are motion history events, and thus, GIMP will attempt to iterate over the history events and (incorrectly) modifies the coordinates, leading to the behavior described above.
The upshot is that if I simply comment out the first block, and always go with the old coordinates, everything works like a charm:
/*if (there are motion history events)
{
iterate over the motion history events and transform the coordinates
call the motion code of the active tool with the new coordinates
}
else*/
{
call the motion code of the active tool with the old coordinates
}
I'm sure that GDK is queried for the motion history for a reason, though (although it doesn't seem to ever work on my system). I'm happy that I have managed to fix a bug -- at least for my own purposes -- that has annoyed me for some time now, but it doesn't seem to be a proper fix. I'd be happy to send a patch that can be applied to the Subversion trunk, but as noted, I would like to get some feedback on this first.
I'm using Ubuntu Feisty Fawn.
Regards,
Bug affecting systems with two monitors, and a potential fix
David Polberger wrote:
I have been trying to investigate this bug using GDB, and while I have come up with a solution that cures the problem, it's likely not the correct fix. This seems to be a GDK problem, but I would like some feedback from this list on whether this is indeed the case.
I'm happy that I have managed to fix a bug -- at least for my own purposes -- that has annoyed me for some time now, but it doesn't seem to be a proper fix. I'd be happy to send a patch that can be applied to the Subversion trunk, but as noted, I would like to get some feedback on this first.
Congratulations on your first steps towards becoming a GIMP developer! ;)
You are however right in that that the solution that worked for you would not be appropriate for the official GIMP since indeed GIMP looks at the history of a device for a reason; to smooth out strokes e.g. when painting with brushes large enough for making GIMP choke.
Without having looked closely at the issue and just reading your analysis of it, the bug appears to be in the libs GIMP use. Might be the GTK X backend, or even as deep as X itself, perhaps in the form of a mouse driver bug or something.
There is a chance that this bug has been fixed in more recent versions of GTK and/or X and/or your mouse driver, so before continuing your search for a fix lower down in the libs I highly recommend you to use the latest SVN versions of the appropriate libs (and GIMP).
Regards, Martin Nordholts
Bug affecting systems with two monitors, and a potential fix
Thanks for your reply, Martin.
Martin Nordholts wrote:
Without having looked closely at the issue and just reading your analysis of it, the bug appears to be in the libs GIMP use. Might be the GTK X backend, or even as deep as X itself, perhaps in the form of a mouse driver bug or something.
I built and debugged both GTK (GDK) and XLib, and neither are to blame. GDK's X11 backend simply calls XLib's XGetMotionEvents(), which merely sends a message to the X server. I've verified that the information returned from the X server is to blame, not any of the libraries.
This means that the bug is in the X server itself. devices.c:ProcGetMotionEvents() in the X server seems to get its information from a virtual function, *mouse->valuator->GetMotionProc, so this may have something to do with the mouse device code. If I find time, I will try to debug the X server.
(I have tried to file a bug report with their Bugzilla server, but for
whatever reason I can't create an account. I'll try again later.)
--
David Polberger