We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3312 - [OSX 10.11] SDL_SetRelativeMouseMode without SDL_HINT_MOUSE_RELATIVE_MODE_WARP does not work
Summary: [OSX 10.11] SDL_SetRelativeMouseMode without SDL_HINT_MOUSE_RELATIVE_MODE_WAR...
Status: RESOLVED FIXED
Alias: None
Product: SDL
Classification: Unclassified
Component: events (show other bugs)
Version: 2.0.4
Hardware: x86 Other
: P2 major
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-04-21 12:17 UTC by Bjorn W
Modified: 2016-05-02 02:42 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Bjorn W 2016-04-21 12:17:22 UTC
(There was no entry in the OS section for OSX 10.11, El Capitan)

It seems SDL_SetRelativeMouseMode is broken on 10.11, in that no SDL_MOUSEMOTION events are sent *at all*. Regardless of windowed or fullscreen etc.

Reproduce by running test/testrelative - the red square in the middle does not move at all. Saw the same behaviour in my own code too at first.

Setting SDL_SetHint(SDL_HINT_MOUSE_RELATIVE_MODE_WARP, "1") makes it work, but it has a drawback that OSX accessibility handling interferes so for example if you jitter around the mouse quickly, it suddenly shows a mouse pointer which is 10x the size for a few seconds (even though it was hidden before).

So I guess there is something broken in the raw Input event handling on SDL 2.0.4 on OSX, as the RelativeMouseMode uses raw input first, and setting MODE_WARP makes it use "cooked" windowed events if I interpreted the doc correctly).

I'll dig into the sourcecode and see if I can find the cause..
Comment 1 Bjorn W 2016-04-21 14:35:17 UTC
The problem is in src/video/cocoa/SDL_cocoamouse.m in the Cocoa_HandleMouseEvent() method.

The fix is the removal of the ignore clause below (my #if 0). If we're in relative mode, I fail to see how it makes sense to check the locationInWindow at all, and indeed it fails here and this is why it doesn't work. I think you can just remove that if() completely. If we're in non-relative mode, the code is not executed there anyway.

------

    /* Non-relative movement is handled in -[Cocoa_WindowListener mouseMoved:] */
    if (!mouse->relative_mode) {
        return;
    }

#if 0
    /* Ignore events that aren't inside the client area (i.e. title bar.) */
    if ([event window]) {
        NSRect windowRect = [[[event window] contentView] frame];
        if (!NSPointInRect([event locationInWindow], windowRect)) {
            return;
        }
    }
#endif
Comment 2 Eric Wasylishen 2016-04-30 22:41:42 UTC
I can reproduce it on the latest mercurial, 6ad89111cb4f

1. open SDLTest.xcodeproj
2. select the "testrelative" target
3. click the run button
4. when the window appears, move the mouse. The red square is expected to move, but it does not.

I found a workaround: Cmd+Tab to another app, then click on the title bar of the testrelative window.
Comment 3 Eric Wasylishen 2016-05-01 02:05:44 UTC
Bjorn, your fix works for me too.

I checked the hg blame and the "Ignore events that aren't inside the client area (i.e. title bar.)" block was inserted in this commit:

http://hg.libsdl.org/SDL/rev/028ed8da2524

Looks like the intent of that block of code is so Cmd+Tabbing to another app, then dragging the title bar of the SDL window doesn't generate mouse events.

--

I added an NSLog, and when the return statement is hit, the mouse NSPoint is {0, 480}, and the windowRect is: {{0, 0}, {640, 480}}, so it's an off by one issue. Seems like there is a NSMouseInRect designed to deal with these cases.. maybe this is a proper fix?

diff -r 6ad89111cb4f src/video/cocoa/SDL_cocoamouse.m
--- a/src/video/cocoa/SDL_cocoamouse.m	Mon Apr 25 22:17:38 2016 +0200
+++ b/src/video/cocoa/SDL_cocoamouse.m	Sat Apr 30 19:55:43 2016 -0600
@@ -398,7 +398,7 @@
     /* Ignore events that aren't inside the client area (i.e. title bar.) */
     if ([event window]) {
         NSRect windowRect = [[[event window] contentView] frame];
-        if (!NSPointInRect([event locationInWindow], windowRect)) {
+        if (!NSMouseInRect([event locationInWindow], windowRect, NO)) {
             return;
         }
     }
Comment 4 Alex Szpakowski 2016-05-02 00:42:52 UTC
I've pushed a commit which changes the mouse code in the Cocoa backend to use NSMouseInRect instead of NSPointInRect, thanks Eric! Let me know how it works out – it seemed to fix things in my own tests.

https://hg.libsdl.org/SDL/rev/d41acf6379f6
Comment 5 Eric Wasylishen 2016-05-02 02:42:31 UTC
Thanks!

I tested the latest HG on both OS X 10.11.4 and 10.6.8, and testrelative is working on both versions of OS X.