Bug on mouseEvents with MacOSX

3 bugs I ran into on MacOSX with a december version of SDL 1.3HG :
-a- There is no mouseWheelEvents in fullscreenmode ! (in the code below I just remove the | SDL_FULLSCREEN to get the wheel events)
-b- in fullscreen mode 2 sets of SDL_MOUSEMOTION are sent and half of them are shifted up by 20 pixels. I investigated where the events are posted and half of them com from SDL_CocoaWindows.m (MouseMoved) and SDL_cocoamouse.m (Cocoa_HandleMouseEvent). Only the cocoamouse event have the right coordinates BUT they are “jet-lagged” when on the top of the screen (the part where the shifted events from cocoawindows are not triggered). It looks like the post of wrong events from cocoawindow have a higher priority and “push” the good events to arrive sooner !!! BTW half of the events are still wrong and it’s hard to rely on them !
-c- As I said in a previous post The events triggered by the trackpad of a macBookPro are both GestureEvents AND MouseEvents. Not all the mouseEvents are triggered correctly (most of mouseMotion never happen so it is impossible to follow the real mouse cursor) and they are also very late (up to 1.5 seconds late)

to fix -a-
in SDL_cocoaEvents.m Cocoa_PumpEvents() in the big switch I added "case NSScrollWheel : " before “case NSMouseMoved:” so the wheel events are forwarded to Cocoa_HandleMouseEvent() and in SDL_CocoaMouse.m Cocoa_HandleMouseEvent() I also handle NSScrollWheel in the switch and copied some code from SDL_cocoawindow.m
case NSScrollWheel:
x = [event deltaX];
y = [event deltaY];

    if (x > 0) {
        x += 0.9f;
    } else if (x < 0) {
        x -= 0.9f;
    }
    if (y > 0) {
        y += 0.9f;
    } else if (y < 0) {
        y -= 0.9f;
    }
    SDL_SendMouseWheel(window, (int)x, (int)y);      
    break;

to fix -b-
in SDL_cocoawindow.m fct mouseMoved i check if the win mode is fullscreen to choose the right way to retrieve the mouse coordinates :
if (window->flags & SDL_WINDOW_FULLSCREEN)
point = [NSEvent mouseLocation];
else
point = [theEvent locationInWindow];

to fix -c- I Don’t know !!! I hope Sam will understand what happen there. The only cue I have is the “jet-lag” of events mousePress may be related to the same “jet-lag” I found between cocoaMouse and cocoawindows (in SDL_cocoaEvents.m you call both Cocoa_HandleMouseEvent(_this, event); AND [NSApp sendEvent:event]; nf the latter just seams more reactive.

WARNING : The way I fixed -a- and -b- is not the right one since in non fullscreen mode there are probably 2 times every events …

//TAKE CARE THIS APP NEVER ENDS = you have to keep a xcode window with a stop button away from the main screen where the fullscreen stuff will happen
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL/SDL_main.h>
SDL_Surface *screen = NULL;
SDL_Surface *screen2 = NULL;

/**

  • display info about the surface in stdout
    */
    void SDL_SurfaceInfo(const char * name, const SDL_Surface *thing) {
    printf("%s: w:%d h:%d flags=%08x bpp:%d masks RGBA=%08x %08x %08x %08x \n", name, thing->w, thing->h, thing->flags, thing->format->BitsPerPixel, thing->format->Rmask, thing->format->Gmask, thing->format->Bmask, thing->format->Amask);
    }// SDL_SurfaceInfo()--------------------------------------------------------------------

int SDL_main (int argc, const char * argv[]) {
Uint32 initflags = SDL_INIT_VIDEO;
Uint8 video_bpp = 32;
Uint32 video_flags = SDL_HWSURFACE | SDL_FULLSCREEN;
//Uint32 video_flags = SDL_HWSURFACE;

/* Initialize the SDL library */
if ( SDL_Init(initflags) < 0 ) {
fprintf(stderr, “ERROR: Couldn’t initialize SDL: %s\n”, SDL_GetError());fflush(stderr);
exit(1);
}
screen=SDL_SetVideoMode(1920, 1200, 32, video_flags);

SDL_SurfaceInfo(" Screen info", screen);

int done = 0;
SDL_Event event;
while((!done) && (SDL_WaitEvent(&event))) {
switch (event.type) {
case SDL_MOUSEMOTION:
SDL_DrawPoint(screen,event.motion.x, event.motion.y, 0xFFFFFFFF);
SDL_Flip(screen);
printf(" =>SDL_MOUSEMOTION at %d,%d\n", event.motion.x, event.motion.y);
break;

case SDL_MOUSEWHEEL:
  printf("  =>SDL_MOUSEWHEEL  at %d,%d\n", event.motion.x, event.motion.y);
  break;   
default :
  printf("  =>ANOTHER EVENT\n");
  break;   
}

}
return 0;
}

I looked into a couple other mouse-related problems when I tried SDL
1.3. I recommended back then that Sam go a little more low level with
this; it seems most mouse events are caught, then moved back up to a
window, then into the SDL event queue.

It might be the new multiple window system that is the reason for this,
but it actually has the problem that some things (have been patched
other ways) like right mouse click get caught by the window an
interpreted. The code would probably be a bit easier (and less laggy)
if the events went right from the mouse events to the SDL queue, and
mouse events in windows ignored.

Note this is all from a quick perusal of SDL code. I’m not an obj-C
expert (my code is mostly cross platform so I stick to carbon APIs) so
this might be a bad idea.

[>] Brian

Thanks vernier. I applied your “Patch B” which fixed my jumpy mouse on the Mac.------------------------
| Mike Kasprzak | Sykhronics Entertainment (http://www.sykhronics.com) | Blog (http://www.toonormal.com) | Twitter (http://www.twitter.com/mikekasprzak) |

Hi,

3 bugs I ran into on MacOSX with a december version of SDL 1.3HG :
-a- There is no mouseWheelEvents in fullscreenmode ! (in the code below I
just remove the | SDL_FULLSCREEN to get the wheel events)

I can verify this.

-b- in fullscreen mode 2 sets of SDL_MOUSEMOTION are sent and half of them
are shifted up by 20 pixels. I investigated where the events are posted and
half of them com from SDL_CocoaWindows.m (MouseMoved) and SDL_cocoamouse.m
(Cocoa_HandleMouseEvent). Only the cocoamouse event have the right
coordinates BUT they are “jet-lagged” when on the top of the screen (the
part where the shifted events from cocoawindows are not triggered). It looks
like the post of wrong events from cocoawindow have a higher priority and
"push" the good events to arrive sooner !!! BTW half of the events are still
wrong and it’s hard to rely on them !
-c- As I said in a previous post The events triggered by the trackpad of a
macBookPro are both GestureEvents AND MouseEvents. Not all the mouseEvents
are triggered correctly (most of mouseMotion never happen so it is
impossible to follow the real mouse cursor) and they are also very late (up
to 1.5 seconds late)

to fix -a-
in SDL_cocoaEvents.m Cocoa_PumpEvents() in the big switch I added "case
NSScrollWheel : " before “case NSMouseMoved:” so the wheel events are
forwarded to Cocoa_HandleMouseEvent() and in SDL_CocoaMouse.m
Cocoa_HandleMouseEvent() I also handle NSScrollWheel in the switch and
copied some code from SDL_cocoawindow.m
case NSScrollWheel:
x = [event deltaX];
y = [event deltaY];

if (x > 0) {
x += 0.9f;
} else if (x < 0) {
x -= 0.9f;
}
if (y > 0) {
y += 0.9f;
} else if (y < 0) {
y -= 0.9f;
}
SDL_SendMouseWheel(window, (int)x, (int)y);
break;

It is the correct way to fix it, as Cocoa_HandleMouseEvent will ignore all
non-fullscreen windows. Attached a slightly modified patch (to avoid code
duplication), fix-wheel.patch.

to fix -b-
in SDL_cocoawindow.m fct mouseMoved i check if the win mode is fullscreen to
choose the right way to retrieve the mouse coordinates :
if (window->flags & SDL_WINDOW_FULLSCREEN)
point = [NSEvent mouseLocation];
else
point = [theEvent locationInWindow];

I think we can simply ignore this event handler in SDLWindow in fullscreen
mode. See attached fix-double-motion.patch.

to fix -c- I Don’t know !!! I hope Sam will understand what happen there.
The only cue I have is the “jet-lag” of events mousePress may be related to
the same “jet-lag” I found between cocoaMouse and cocoawindows (in
SDL_cocoaEvents.m you call both Cocoa_HandleMouseEvent(_this, event); AND
[NSApp sendEvent:event]; nf the latter just seams more reactive.

I haven’t seen such symptom on my box. The events received from
Cocoa_HandleMouseEvent are all quite reliable and quick. There is no
1.5 seconds “jet-lag” here, every mouse events are responded in milliseconds.

WARNING : The way I fixed -a- and -b- is not the right one since in non
fullscreen mode there are probably 2 times every events …

This are in, thanks!


http://hg.libsdl.org/SDL/rev/00d1fef487c5On Thu, Jan 20, 2011 at 3:40 PM, Jjgod Jiang wrote:

Hi,

On Thu, Jan 13, 2011 at 1:41 PM, vernier <frederic.vernier at laposte.net> wrote:

3 bugs I ran into on MacOSX with a december version of SDL 1.3HG :
-a- There is no mouseWheelEvents in fullscreenmode ! (in the code below I
just remove the | SDL_FULLSCREEN to get the wheel events)

I can verify this.

-b- in fullscreen mode 2 sets of SDL_MOUSEMOTION are sent and half of
them
are shifted up by 20 pixels. I investigated where the events are posted
and
half of them com from SDL_CocoaWindows.m (MouseMoved) and
SDL_cocoamouse.m
(Cocoa_HandleMouseEvent). Only the cocoamouse event have the right
coordinates BUT they are “jet-lagged” when on the top of the screen (the
part where the shifted events from cocoawindows are not triggered). It
looks
like the post of wrong events from cocoawindow have a higher priority and
"push" the good events to arrive sooner !!! BTW half of the events are
still
wrong and it’s hard to rely on them !
-c- As I said in a previous post The events triggered by the trackpad of
a
macBookPro are both GestureEvents AND MouseEvents. Not all the
mouseEvents
are triggered correctly (most of mouseMotion never happen so it is
impossible to follow the real mouse cursor) and they are also very late
(up
to 1.5 seconds late)

to fix -a-
in SDL_cocoaEvents.m Cocoa_PumpEvents() in the big switch I added "case
NSScrollWheel : " before “case NSMouseMoved:” so the wheel events are
forwarded to Cocoa_HandleMouseEvent() and in SDL_CocoaMouse.m
Cocoa_HandleMouseEvent() I also handle NSScrollWheel in the switch and
copied some code from SDL_cocoawindow.m
case NSScrollWheel:
x = [event deltaX];
y = [event deltaY];

if (x > 0) {
x += 0.9f;
} else if (x < 0) {
x -= 0.9f;
}
if (y > 0) {
y += 0.9f;
} else if (y < 0) {
y -= 0.9f;
}
SDL_SendMouseWheel(window, (int)x, (int)y);
break;

It is the correct way to fix it, as Cocoa_HandleMouseEvent will ignore all
non-fullscreen windows. Attached a slightly modified patch (to avoid code
duplication), fix-wheel.patch.

to fix -b-
in SDL_cocoawindow.m fct mouseMoved i check if the win mode is fullscreen
to
choose the right way to retrieve the mouse coordinates :
if (window->flags & SDL_WINDOW_FULLSCREEN)
point = [NSEvent mouseLocation];
else
point = [theEvent locationInWindow];

I think we can simply ignore this event handler in SDLWindow in fullscreen
mode. See attached fix-double-motion.patch.

to fix -c- I Don’t know !!! I hope Sam will understand what happen
there.
The only cue I have is the “jet-lag” of events mousePress may be related
to
the same “jet-lag” I found between cocoaMouse and cocoawindows (in
SDL_cocoaEvents.m you call both Cocoa_HandleMouseEvent(_this, event); AND
[NSApp sendEvent:event]; nf the latter just seams more reactive.

I haven’t seen such symptom on my box. The events received from
Cocoa_HandleMouseEvent are all quite reliable and quick. There is no
1.5 seconds “jet-lag” here, every mouse events are responded in
milliseconds.

WARNING : The way I fixed -a- and -b- is not the right one since in non
fullscreen mode there are probably 2 times every events …

  • Jiang


-Sam Lantinga, Founder and President, Galaxy Gameworks LLC