Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
ThrudTheBarbarian opened this issue Feb 9, 2025 · 1 comment
Open

Comments

@ThrudTheBarbarian
Copy link

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).

@ThrudTheBarbarian
Copy link
Author

ThrudTheBarbarian commented Feb 10, 2025

Ok, some new findings...

  1. Working normally on the MBP screen
  • On running the app from Xcode , it launches on the MBP built-in screen.
  • Clicking through the options until I get to where the cursor is set, it all works fine while on the MBP screen
  1. Not working on the 4K external monitor
  • On running the app from Xcode , it launches on the MBP built-in screen.
  • Dragging the window over to the 4K monitor, and the cursor won't be set

But...

2a) Fixing itself on the 4K external monitor...

  • Moving the mouse back to the MBP screen then back over to the 4K screen, and the cursor is now reliably set.

Could there be some display-related state that isn't being set when the window moves to a different screen ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant