Skip to content

SDL_SetCursor doesn't work very well on Mac external monitors #12230

@ThrudTheBarbarian

Description

@ThrudTheBarbarian

My app wants to change the cursor when the mouse moves into a view in my Appkit-alike framework when the user has selected an icon in the collection view at the bottom.

On the built-in-to-the-laptop screen, the below code works perfectly every time. On either of the 2 external monitors plugged in, it works maybe 2-5% of the time (and once it's not working it seems to stay not working for the duration of the app). I can't find anything that correlates to it "working" on the external monitors.

- (void) _setCursor
    {
    NSLog(@"setting cursor");
    if (_cursor)
        SDL_DestroyCursor(_cursor);

    if (_cursorImage == nil)
        SDL_Log("no image!");
        SDL_SetCursor(_arrowCursor);
    else
        {
        int W = _cursorImage.width * _zoomFactor[_zoom];
        int H = _cursorImage.height * _zoomFactor[_zoom];
        SDL_Surface *scaled  = SDL_CreateSurface(W, H, SDL_PIXELFORMAT_ABGR8888);

        id<AZRenderer> azr      = AZRenderer.renderer;
        SDL_Surface *surface    = [azr surfaceFor:_cursorImage.texture];
        SDL_Rect srcRect        = SDL_RECT(_cursorImage.srcRect);
        SDL_BlitSurfaceScaled(surface, &srcRect,
                              scaled, NULL,
                              SDL_SCALEMODE_LINEAR);
        SDL_DestroySurface(surface);

        _cursor = SDL_CreateColorCursor(scaled, 0, 0);
        if (!SDL_SetCursor(_cursor))
            SDL_Log("setcursor failed: %s", SDL_GetError());

        SDL_DestroySurface(scaled);
        }
    }

The call to SDL_SetCursor always succeeds, and in fact it looks as though the cursor is being set on the external monitor, but as soon as I move the mouse, it is reset to the arrow again - see attached video. I did manage to capture the single frame when the mouse doesn't move for a while, and the cursor stayed set, but that was a large video to upload :)

sdl_setcursor.mov

I added logging to every call of SDL_SetCursor in my app, and it never calls anything other than the above. In the debugger, the values always look fine (which again agrees with the set-then-reset theory).

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions