Ariver
2026-07-07 97285a121e3ddd6d93c78d9208d6f0e94b733868
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/env bash
set -euo pipefail
 
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
QUICK_SEARCH="$ROOT_DIR/Apptag/QuickSearch.swift"
CONTENT_VIEW="$ROOT_DIR/Apptag/ContentView.swift"
TAG_NAV="$ROOT_DIR/Apptag/TagNavigationView.swift"
 
python3 - "$QUICK_SEARCH" "$CONTENT_VIEW" "$TAG_NAV" <<'PY'
import re
import sys
from pathlib import Path
 
quick_search = Path(sys.argv[1]).read_text(encoding="utf-8")
content_view = Path(sys.argv[2]).read_text(encoding="utf-8")
tag_nav = Path(sys.argv[3]).read_text(encoding="utf-8")
 
 
def fail(message: str) -> None:
    print(f"FAIL: {message}", file=sys.stderr)
    sys.exit(1)
 
 
def require(condition: bool, message: str) -> None:
    if not condition:
        fail(message)
 
 
def require_contains(source: str, needle: str, message: str) -> None:
    require(needle in source, message)
 
 
require_contains(
    quick_search,
    "tagLauncherQuickSearchCompositionChanged",
    "Quick Search must publish IME composition state",
)
require_contains(
    quick_search,
    "if !field.isComposingText, field.stringValue != text",
    "Quick Search updateNSView must not overwrite marked text",
)
require_contains(
    quick_search,
    "if textView.hasMarkedText()",
    "Quick Search doCommandBy must pass marked text commands through to IME",
)
require_contains(
    quick_search,
    "guard !isComposingText else",
    "Quick Search keyDown must pass marked text key events through to IME",
)
require_contains(
    quick_search,
    "guard field?.isComposingText != true else { return }",
    "Quick Search submit fallback must not launch while composing text",
)
 
apply_match = re.search(
    r"func apply\(_ configuration: QuickSearchPanelConfiguration, anchorView: QuickSearchPanelAnchorView\).*?func closePanel\(\)",
    quick_search,
    re.S,
)
require(apply_match is not None, "Quick Search panel apply block is missing")
apply_body = apply_match.group(0)
require_contains(
    apply_body,
    "let shouldOrderForInput = shouldOrderPanelForInput(panel)",
    "Quick Search panel must compute whether ordering is actually needed",
)
require_contains(
    apply_body,
    "if shouldOrderForInput",
    "Quick Search panel activate/orderFront must be gated",
)
require_contains(
    quick_search,
    "field.currentEditor() == nil",
    "Quick Search focus retry must stop once the field editor is active",
)
 
require_contains(
    content_view,
    "@State private var quickSearchCompositionActive = false",
    "ContentView must track Quick Search composition state",
)
require_contains(
    content_view,
    "shouldIgnoreQuickSearchDismissDuringComposition",
    "ContentView must ignore mouse/backdrop dismiss while composing text",
)
require_contains(
    content_view,
    "source == QuickSearchDismissSource.mouse || source == QuickSearchDismissSource.backdrop",
    "composition dismiss guard must be scoped to mouse/backdrop dismissals",
)
 
mouse_match = re.search(
    r"override func mouseDown\(with event: NSEvent\).*?@objc private func performActivation",
    tag_nav,
    re.S,
)
require(mouse_match is not None, "TagNavigation mouseDown block is missing")
mouse_body = mouse_match.group(0)
for needle, message in [
    ("let maxTrackingDuration: TimeInterval = 8", "TagNavigation tracking loop must have a hard time limit"),
    ("window.isVisible", "TagNavigation tracking loop must exit when the window is gone or hidden"),
    ("NSApp.isActive", "TagNavigation tracking loop must exit when the app loses active state"),
    ("NSEvent.pressedMouseButtons & (1 << 0) == 0", "TagNavigation tracking loop must recover if mouseUp is lost"),
    ("onReorderEnded()", "TagNavigation abnormal exits must clean up an active reorder"),
]:
    require_contains(mouse_body, needle, message)
 
print("PASS windowserver event safety QA")
PY