Skip to content

Add ICursorService for system, image and animated mouse cursors - #625

Open
botoddly wants to merge 1 commit into
mainfrom
mouse-cursors
Open

botoddly wants to merge 1 commit into
mainfrom
mouse-cursors

Conversation

@botoddly

@botoddly botoddly commented Oct 6, 2026

Copy link
Copy Markdown
Collaborator

Exposes SDL's mouse cursors through a new ICursorService, registered by Build().

  • CreateSystemCursor(SystemCursor), CreateCursor(Image, Vector2Int hotspot) and CreateCursor(ReadOnlySpan<CursorFrame>, Vector2Int hotspot) for animated cursors (SDL_CreateAnimatedCursor, SDL 3.4).
  • SetCursor(Cursor), ResetCursor() and IsCursorVisible.
  • The service owns every cursor and destroys the remaining ones on app disposal, before PixelyFactory shuts SDL down. All calls must be on the main thread.
  • Images are copied into SDL-owned ARGB8888 surfaces, because the Windows backend keeps the surfaces of an animated cursor after the call.
  • Frames are validated: no frames, missing images, mixed sizes, a hotspot outside the image, negative or too long durations. Positive durations round up to whole milliseconds, so they never become the zero that stops the animation.
  • SystemCursor has only the SDL 3.4 shapes, because browser archives are SDL 3.4.2.
  • New shared ImageSurfaces.GetPackedPitch, now also used by SdlImageWriter and Window.SetIcon. SetIcon previously assumed 4 bytes per pixel and could read past the image for other formats; it now throws NotSupportedException for such images.

Docs: docs/cursors.md, plus notes in docs/headless.md and docs/hosting.md. Tutorial: Pixely.Tutorials.Cursor.

Testing:

  • CursorServiceTests on SDL's dummy driver cover validation, lifetime, the main-thread rule and the SDL calls. The dummy driver has no system cursors, so CreateSystemCursor is tested only for its failure path there.
  • The tutorial ran headless with a scripted scenario covering every key.
  • Not verified: how cursors look and animate on a real desktop or in the browser. This needs a manual check.

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

Successfully merging this pull request may close these issues.

1 participant