Detector now walks each AXWindow subtree independently and returns both aggregate signals (for state machine) and a list of AXWindow element refs for windows with active approval signals. Overlay reads position/size directly from AXWindow elements via AXValueGetValue, eliminating the CGWindowList dependency (which returned empty names for Electron windows anyway). Daemon passes only the active AXWindow refs to the overlay, so only the specific window(s) waiting for user input get flashed. Made-with: Cursor
63 lines
1.8 KiB
Python
63 lines
1.8 KiB
Python
"""Manual test: shows a pulsing border around Cursor windows for 10 seconds.
|
|
|
|
With no args, flashes all windows (for visual testing).
|
|
With --per-window, only flashes windows with active signals (production behavior).
|
|
"""
|
|
import argparse
|
|
import sys
|
|
import time
|
|
|
|
from ApplicationServices import (
|
|
AXUIElementCreateApplication,
|
|
AXUIElementCopyAttributeValue,
|
|
)
|
|
from Cocoa import NSApplication, NSRunLoop, NSDate
|
|
|
|
from cursor_flasher.config import Config
|
|
from cursor_flasher.overlay import OverlayManager
|
|
from cursor_flasher.detector import CursorDetector
|
|
|
|
app = NSApplication.sharedApplication()
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--per-window", action="store_true",
|
|
help="Only flash windows that need attention")
|
|
args = parser.parse_args()
|
|
|
|
config = Config()
|
|
overlay = OverlayManager(config)
|
|
detector = CursorDetector()
|
|
|
|
pid = detector._find_cursor_pid()
|
|
if pid is None:
|
|
print("Cursor not running")
|
|
sys.exit(1)
|
|
|
|
if args.per_window:
|
|
result = detector.poll()
|
|
if result is None or not result.active_windows:
|
|
print("No windows currently need attention")
|
|
sys.exit(0)
|
|
ax_windows = result.active_windows
|
|
print(f"Flashing {len(ax_windows)} window(s) that need attention...")
|
|
else:
|
|
app_element = AXUIElementCreateApplication(pid)
|
|
_, children = AXUIElementCopyAttributeValue(app_element, "AXChildren", None)
|
|
ax_windows = []
|
|
for child in children:
|
|
_, role = AXUIElementCopyAttributeValue(child, "AXRole", None)
|
|
if str(role) == "AXWindow":
|
|
ax_windows.append(child)
|
|
print(f"Flashing all {len(ax_windows)} Cursor window(s)...")
|
|
|
|
overlay.show(ax_windows)
|
|
|
|
end_time = time.time() + 10
|
|
while time.time() < end_time:
|
|
NSRunLoop.currentRunLoop().runUntilDate_(
|
|
NSDate.dateWithTimeIntervalSinceNow_(0.1)
|
|
)
|
|
|
|
overlay.hide()
|
|
print("Done.")
|