X Tutup
Skip to content

[Mac Catalyst] Mouse hover (non-contact move) events not delivered by SKCanvasView #3523

@mattleibow

Description

@mattleibow

Description

On Mac Catalyst, SKCanvasView with EnableTouchEvents = true does not deliver mouse hover events (mouse move without any button pressed). The Touch event only fires for Pressed, Moved (with contact), and Released — never for non-contact Moved, Entered, or Exited actions.

Expected Behavior

When the mouse cursor moves over the SKCanvasView without any button pressed, the Touch event should fire with:

  • ActionType = SKTouchAction.Moved and InContact = false, OR
  • ActionType = SKTouchAction.Entered / SKTouchAction.Exited when the cursor enters/leaves the view

This works correctly on other platforms (e.g., WPF, WinUI).

Actual Behavior

No touch events are delivered at all when the mouse hovers over the canvas without pressing a button. Only mouse clicks (Pressed/Released) and dragging (Moved with InContact=true) generate events.

Root Cause Analysis

On Mac Catalyst (UIKit), mouse hover requires a UIHoverGestureRecognizer to be added to the view. Standard UIGestureRecognizer and touch handling (touchesBegan/touchesMoved/touchesEnded) only track contacts (finger or mouse button pressed), not passive pointer movement.

Suggested Fix

In the Mac Catalyst platform handler for SKCanvasView, add a UIHoverGestureRecognizer:

// In the Mac Catalyst SKCanvasView handler (e.g., SKCanvasViewHandler or the native view)
var hoverRecognizer = new UIHoverGestureRecognizer((recognizer) =>
{
    var location = recognizer.LocationInView(this);
    var skPoint = new SKPoint((float)location.X, (float)location.Y);
    
    SKTouchAction action = recognizer.State switch
    {
        UIGestureRecognizerState.Began => SKTouchAction.Entered,
        UIGestureRecognizerState.Changed => SKTouchAction.Moved,
        UIGestureRecognizerState.Ended or 
        UIGestureRecognizerState.Cancelled => SKTouchAction.Exited,
        _ => SKTouchAction.Moved
    };
    
    var args = new SKTouchEventArgs(/* id */ -1, action, SKMouseButton.Unknown, SKTouchDeviceType.Mouse, 
        skPoint, inContact: false, wheelDelta: 0, pressure: 0);
    OnTouch(args);
});
AddGestureRecognizer(hoverRecognizer);

UIHoverGestureRecognizer is available since iOS 13.0 / Mac Catalyst 13.0.

Reproduction Steps

  1. Create a MAUI app targeting net9.0-maccatalyst
  2. Add an SKCanvasView with EnableTouchEvents="True"
  3. Subscribe to the Touch event and log all events
  4. Run on macOS
  5. Move the mouse cursor over the canvas without clicking
  6. Observe: no events are logged

Environment

  • SkiaSharp: 3.119.1
  • SkiaSharp.Views.Maui.Controls: 3.119.1
  • .NET: 9.0
  • macOS (Mac Catalyst)
  • Also affects iPadOS with trackpad/mouse support

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      X Tutup