// Copyright (c) 2026 Storm Dragon // SPDX-License-Identifier: GPL-3.0-or-later package app import ( "context" "errors" "git.stormux.org/storm/cthulhu/internal/atspi" "git.stormux.org/storm/cthulhu/internal/review" "git.stormux.org/storm/cthulhu/internal/wine" "strings" ) type wineReviewCapturer interface { Capture(context.Context, atspi.ObjectID) (*atspi.AccessibleTree, error) } type reviewCaptureRouter struct { native review.TreeCapturer wine wineReviewCapturer } func reservedWineID(id atspi.ObjectID) bool { return id.Path == "/wine" || strings.HasPrefix(id.Path, "/wine/") } func (r *reviewCaptureRouter) FreshReviewWindow(id atspi.ObjectID) bool { return reservedWineID(id) } func (r *reviewCaptureRouter) NativeCapturerFor(id atspi.ObjectID) review.TreeCapturer { if reservedWineID(id) { return nil } return r.native } func (r *reviewCaptureRouter) CaptureDesktop(ctx context.Context) (*atspi.AccessibleTree, error) { return r.native.CaptureDesktop(ctx) } func (r *reviewCaptureRouter) CaptureReviewWindow(ctx context.Context, id atspi.ObjectID) (*atspi.AccessibleTree, error) { if !reservedWineID(id) { return r.native.CaptureReviewWindow(ctx, id) } if r.wine == nil || !wine.IsReviewID(id) { return nil, wine.ErrReviewUnavailable } tree, err := r.wine.Capture(ctx, id) if errors.Is(err, wine.ErrReviewLimited) { err = review.ErrLimitedReview } return tree, err } func (r *reviewCaptureRouter) CaptureDocument(ctx context.Context, id atspi.ObjectID) (*atspi.AccessibleTree, error) { if reservedWineID(id) { return nil, wine.ErrReviewUnavailable } return r.native.CaptureDocument(ctx, id) } func (r *reviewCaptureRouter) CaptureDocumentText(ctx context.Context, id atspi.ObjectID) (*atspi.AccessibleTree, error) { if reservedWineID(id) { return nil, wine.ErrReviewUnavailable } return r.native.CaptureDocumentText(ctx, id) }