feat: per-window detection — only flash windows needing attention
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
This commit is contained in:
@@ -46,9 +46,9 @@ class FlasherDaemon:
|
||||
self._running = False
|
||||
|
||||
def _tick(self) -> None:
|
||||
signals = self.detector.poll()
|
||||
result = self.detector.poll()
|
||||
|
||||
if signals is None:
|
||||
if result is None:
|
||||
if self.state_machine.state == FlasherState.WAITING_FOR_USER:
|
||||
self.state_machine.dismiss()
|
||||
self.overlay.hide()
|
||||
@@ -56,8 +56,8 @@ class FlasherDaemon:
|
||||
return
|
||||
|
||||
changed = self.state_machine.update(
|
||||
agent_working=signals.agent_working,
|
||||
approval_needed=signals.approval_needed,
|
||||
agent_working=result.signals.agent_working,
|
||||
approval_needed=result.signals.approval_needed,
|
||||
)
|
||||
|
||||
if not changed:
|
||||
@@ -74,9 +74,8 @@ class FlasherDaemon:
|
||||
|
||||
match self.state_machine.state:
|
||||
case FlasherState.WAITING_FOR_USER:
|
||||
pid = self.detector._pid
|
||||
if pid is not None:
|
||||
self.overlay.show(pid)
|
||||
if result.active_windows:
|
||||
self.overlay.show(result.active_windows)
|
||||
play_alert(self.config)
|
||||
self._waiting_since = time.monotonic()
|
||||
case FlasherState.AGENT_WORKING | FlasherState.IDLE:
|
||||
|
||||
Reference in New Issue
Block a user