Mouse movement problems in fullscreen mode

I found something that might be an SDL issue (or a Linux issue).

Within the SDL screen if the mouse is within a certain region of the
screen, it is turned off by calling SDL_ShowCursor( SDL_DISABLE ); and
when it leaves the given region it’s turned on with SDL_ENABLE.

It all works fine in windowed mode, but when it is in full-screen mode,
the the SDL_ShowCursor( SDL_ENABLE ) call causes the cursor to jump,
upwards and sometimes sideways too. If the SDL_ShowCursor() function is
not called, the mouse coordinates are always fine, whether in
fullscreen or windowed mode. In windowed mode things are fine even if
the SDL_ShowCursor() is called. It’s only in fullscreen mode when the
ShowCursor call makes the mouse jump.

I printed the mouse motion events (x,y), it shows what happens when the
mouse is dragged downwards, at a more or less even speed:

motion 359,357
motion 359,360
motion 359,362
SDL_ShowCursor( SDL_ENABLE )
motion 376,202
motion 376,205
motion 376,208
motion 376,209

As you can see, enabling the cursor makes it jump up by 160 pixels and
slightly to the right this time (although the horzontal jump seems to be
unpredictable, the vertical is always upwards).

The system I’m running is SuSE Linux 10.0 (2.6.13 kernel), x86_64
(Athlon) the X server is xorg, 6.8.2, the video card is an NVidia
GeForce 6200 with the NVidia driver. The SDL lib I use is 1.2.13,
installed from the source tarball.

The user code (i.e. my code) is a single thread (sitting in the event
loop). There’s a constant stream of SDL_PushEvents() from a 10ms timer,
but they are always SDL_USEREVENT, the mouse events are all generated
by SDL itself (that is, I’m sure that it is not a bug in my code and my
code works just fine when it runs in windowed mode).

Anyone has seen something like that before?

Thanks,

Zoltan

This comment from the source code might shed some light on the subject:

/* Determine whether the mouse should be in relative mode or not.
This function is called when the input grab state or cursor
visibility state changes.
If the cursor is not visible, and the input is grabbed, the
driver can place the mouse in relative mode, which may result
in higher accuracy sampling of the pointer motion.
*/

Absolute positioning of the mouse cursor is subject to the settings of
the windowing environment. Those settings change the mouse movement
data stream and reflects not only the user’s settings for mouse
movement while using desktop applications, but is also constrained to
pixel-sized movements. In full screen mode, windowing systems are
obliged to neglect those changes to the mouse movement data stream if
you ask them to (some even let you “grab” the pointer without being in
fullscreen mode.) So we’ve established that in certain modes, SDL
"grabs" the cursor for itself and puts it into relative movement mode
and in that mode the windowing system will not track the position of
the cursor.

When SDL tells the windowing system to “ungrab” the cursor, the
windowing system has its own idea about where the cursor is located.
Perhaps SDL should decide for it by moving the cursor explicitly to
the same location it has been reporting to the application using SDL,
but that would be a little less flexible.

To solve your problem I recommend calling SDL_MoveCursor() after
SDL_ShowCursor(SDL_ENABLE).On Mon, Dec 8, 2008 at 2:34 AM, Zolt?n K?csi wrote:

I found something that might be an SDL issue (or a Linux issue).

Within the SDL screen if the mouse is within a certain region of the
screen, it is turned off by calling SDL_ShowCursor( SDL_DISABLE ); and
when it leaves the given region it’s turned on with SDL_ENABLE.

It all works fine in windowed mode, but when it is in full-screen mode,
the the SDL_ShowCursor( SDL_ENABLE ) call causes the cursor to jump,
upwards and sometimes sideways too. If the SDL_ShowCursor() function is
not called, the mouse coordinates are always fine, whether in
fullscreen or windowed mode. In windowed mode things are fine even if
the SDL_ShowCursor() is called. It’s only in fullscreen mode when the
ShowCursor call makes the mouse jump.

I printed the mouse motion events (x,y), it shows what happens when the
mouse is dragged downwards, at a more or less even speed:

motion 359,357
motion 359,360
motion 359,362
SDL_ShowCursor( SDL_ENABLE )
motion 376,202
motion 376,205
motion 376,208
motion 376,209

As you can see, enabling the cursor makes it jump up by 160 pixels and
slightly to the right this time (although the horzontal jump seems to be
unpredictable, the vertical is always upwards).

The system I’m running is SuSE Linux 10.0 (2.6.13 kernel), x86_64
(Athlon) the X server is xorg, 6.8.2, the video card is an NVidia
GeForce 6200 with the NVidia driver. The SDL lib I use is 1.2.13,
installed from the source tarball.

The user code (i.e. my code) is a single thread (sitting in the event
loop). There’s a constant stream of SDL_PushEvents() from a 10ms timer,
but they are always SDL_USEREVENT, the mouse events are all generated
by SDL itself (that is, I’m sure that it is not a bug in my code and my
code works just fine when it runs in windowed mode).

Anyone has seen something like that before?

Thanks,

Zoltan


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


http://codebad.com/

Thanks for the explanation!

When SDL tells the windowing system to “ungrab” the cursor, the
windowing system has its own idea about where the cursor is located.
Perhaps SDL should decide for it by moving the cursor explicitly to
the same location it has been reporting to the application using SDL,
but that would be a little less flexible.

I think it would definitely be a good idea if it did that (or at least
there was an option to do that). The visibility and the position of the
pointer, at least from a user’s (i.e. SDL application developer’s)
point of view are two orthogonal concepts. Whether I can see it or not
should not change its position (bar quantum effects :-). I appreciate
the technical issues behind it, but as an SDL user I should not be
concerned about the inner workings of the library. From my point of
view all I can see is the stream of events I receive from
SDL_WaitEvent() and from that aspect calling SDL_ShowCursor() makes a
completely unwarranted random change in the location of the pointer,
indistinguishable from the end user suddenly jerking the mouse.

To solve your problem I recommend calling SDL_MoveCursor() after
SDL_ShowCursor(SDL_ENABLE).

Yes, I already do that as a work-around:

SDL_GetMouseState( &x, &y );
SDL_ShowCursor( SDL_ENABLE );
SDL_WarpMouse( x, y );

But it is really a kludge that (at least I believe) should be done
inside of SDL_ShowCursor() or in an SDL_ShowCursorSafe()

Regards,

Zoltan

I think it would definitely be a good idea if it did that (or at least
there was an option to do that). The visibility and the position of the
pointer, at least from a user’s (i.e. SDL application developer’s)
point of view are two orthogonal concepts.

I agree. For SDL 1.3 the mouse will be where you’d expect it to be when
it’s ungrabbed/unhidden.

See ya!
-Sam Lantinga, Lead Software Engineer, Blizzard Entertainment