Skip to content

Add Comet view support: gesture tap, scroll, and stable IDs#33

Merged
Redth merged 2 commits intoRedth:mainfrom
davidortinau:comet-view-support
Mar 11, 2026
Merged

Add Comet view support: gesture tap, scroll, and stable IDs#33
Redth merged 2 commits intoRedth:mainfrom
davidortinau:comet-view-support

Conversation

@davidortinau
Copy link
Copy Markdown
Contributor

Summary

This PR adds first-class support for Comet MVU views in MauiDevFlow. Comet views implement MAUI interfaces (IView, IButton, IScrollView, IGestureView) but do not subclass Microsoft.Maui.Controls types, so they were previously invisible to the visual tree walker and unresponsive to agent tap/scroll commands.

What's added

  1. IGestureView tap support — Detects Comet's IGestureView.Gestures collection via reflection, finds TapGesture instances, and invokes them. Falls back to MAUI interface-based tap (IButton.Clicked(), etc.) and finally to native platform tap via Handler.PlatformView.

  2. IScrollView scroll support — Handles Comet ScrollView (implements IScrollView but not Controls.ScrollView) by accessing the handler's platform view and performing native scroll (UIScrollView.SetContentOffset on iOS/macCatalyst, RecyclerView.ScrollBy on Android, ScrollViewer.ChangeView on Windows).

  3. Stable element IDs via Handler.PlatformView — For Comet views that lack Element.Id, the walker now checks IView.AutomationId first, then falls back to the platform view's accessibility identifier (e.g., UIView.AccessibilityIdentifier) for stable IDs across visual tree snapshots.

  4. CometViewResolver — New reflection-based utility that resolves Comet view wrappers to their inner view types, extracts properties, and provides Comet-aware type names in the visual tree. Caches all reflection metadata and short-circuits immediately when Comet is not loaded.

Safety: all changes are additive

All changes are additive — existing MAUI app behavior is unchanged:

  • New switch cases are placed after existing case View v / case ScrollView sv cases, so standard MAUI controls always match first
  • New else if (element is IView) branches only execute when the existing if (element is VisualElement) branch doesn't match
  • CometViewResolver.TryResolveCometView() returns null immediately when Comet assembly is not loaded (cached boolean check)
  • No existing method signatures were changed
  • No existing behavior was modified for views that subclass MAUI Controls base classes

Testing

  • Comet app: Live tested against CometControlsGallery on Mac Catalyst — sidebar navigation tap, button tap, and scroll all verified working
  • MAUI reference app: Verified no regressions in standard MAUI app (tap, scroll, visual tree snapshot all unchanged)

Known limitation

Comet view element IDs may change across MVU state rebuilds (the view tree is reconstructed on state changes). This is architectural to Comet's MVU model and not a regression introduced by this PR.

davidortinau and others added 2 commits March 10, 2026 19:59
- CometViewResolver: Handle AmbiguousMatchException from generic
  handlers (ViewHandler<TView,TPlatform>) by walking inheritance
  chain with DeclaredOnly flag. Add outer try/catch to prevent
  unhandled exceptions from aborting tree walks.
- VisualTreeWalker: Extract visibility, bounds, opacity, and text
  from IView/IText interfaces for non-VisualElement types (Comet).
  Use ??= for text extraction to preserve IText-resolved values.
- DevFlowAgentService: Add interface-based tap handling (IButton,
  ISwitch, ICheckBox, IRadioButton) for Comet views that implement
  MAUI interfaces but not Controls classes. Add TryNativeTapOnHandler
  fallback using handler PlatformView reflection.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three changes to support Comet views in MauiDevFlow automation:

1. HandleTap: Add IGestureView support via reflection. Comet views use
   IGestureView.Gestures with TapGesture.Invoke() instead of MAUI
   TapGestureRecognizer. New TryInvokeCometGestureTap checks for the
   interface by name and invokes tap gestures without a Comet dependency.

2. HandleScroll: Add IView/IScrollView support. Comet ScrollView
   implements IScrollView but not Controls.ScrollView. Added
   TryNativeScrollOnHandler for element-targeted scroll, and
   FindDescendantIScrollView for page-level scroll. Platform override
   TryNativeScrollOnPlatformView delegates to native UIScrollView
   (iOS/macCatalyst), RecyclerView (Android), or ScrollViewer (Windows).

3. GenerateId: Extract platform view from IView.Handler for
   EnsurePlatformStableId. Comet auto-stamps AccessibilityIdentifier
   on native views, but GenerateId was passing the Comet.View to
   EnsurePlatformStableId which expected a UIView. Now falls through
   to handler.PlatformView, yielding stable platform-stamped IDs.

Validated against CometControlsGallery on Mac Catalyst:
- Sidebar tap (Text + OnTap gesture): WORKS
- Button tap (IButton interface): WORKS
- ScrollView scroll (element-targeted): WORKS
- Page-level scroll (IScrollView discovery): WORKS
- MAUI reference app: No regressions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Redth Redth merged commit e3a7cb5 into Redth:main Mar 11, 2026
2 checks passed
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.

2 participants