Skip to content

fix(macos): keep JXA tracking when an app has no scriptable window - #168

Merged
ErikBjare merged 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:fix/jxa-non-scriptable-app-titles
Oct 19, 2026
Merged

ErikBjare merged 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:fix/jxa-non-scriptable-app-titles

Conversation

@TimeToBuildBob

Copy link
Copy Markdown
Contributor

Summary

Carries #64 (@michaeljelly) onto current master. #64 diagnosed a real bug: the JXA script performs unguarded window lookups, so when the frontmost app has no window we can inspect, the script throws, the poll is dropped, and no heartbeat is sent.

That still matters: jxa is the only macOS strategy that can apply privacy_filter (the swift helper cannot and the watcher refuses to start), so the JXA path is now load-bearing for privacy-conscious users rather than just a legacy option.

What changed

  • Guard the Safari document lookup, the Chrome-family tab lookup, and the Firefox window lookup.
  • Read the frontmost process's AXTitle as a fallback (works for apps that don't support JXA scripting, and for windows not flagged AXMain).
  • Always emit a title. The Python side indexes current_window["title"], so a missing key raised KeyError and skipped the heartbeat anyway.
  • Apply the review feedback from Fixes "unknown" being returned when some apps open #64: 2-space indentation, no trailing whitespace, a single documented NO_WINDOW_TITLE constant, and a fallback that calls windows() instead of indexing the method (oProcess.windows[0] was undefined).

Verification

  • node --check on the script body: syntax OK.
  • Local mock harness (not committed; JXA is macOS-only) exercising 10 cases against the real script text: normal Safari/Chrome, Safari with no document, Chrome/Firefox with no window, non-scriptable app whose windows() throws, windows whose attribute access throws, AXMain title, first-window fallback. All 10 pass; every failure path yields a title instead of throwing.
  • poetry run pytest -q: 158 passed.
  • Not verified on macOS hardware — no access to a Mac here. A quick osascript -l JavaScript printAppStatus.jxa on a Mac with an unscriptable app frontmost would close that gap.

Attribution

Diagnosis and original approach by @michaeljelly in #64; review notes by @ErikBjare. This PR is the cleaned-up carry.

Ref #64

The JXA strategy is the only macOS strategy that can apply privacy_filter
(the swift helper cannot), and its window lookups were unguarded. Safari with
no document, Chrome with no window, or an app whose window attributes are
unavailable threw out of the script, which dropped the poll and left the
heartbeat without a title.

Guard each lookup, read the AX title of the frontmost process as a fallback,
and always emit a title ("No window" when nothing can be read).

Carries ActivityWatch#64 by Michael Jelly, whose diagnosis and approach this follows, with
the review feedback applied: consistent 2-space indentation, one documented
constant instead of repeated comments, and a fallback that calls windows()
instead of indexing the method.

Co-Authored-By: Michael Jelly <53475252+michaeljelly@users.noreply.github.com>
Git-Session-Id: b9165dd9-0d50-48fa-b60e-cbd647875812
@greptile-apps

greptile-apps Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; both previous findings are fixed and no new actionable issue was found.

Summary

Keeps macOS JXA polling alive when the frontmost app has no readable window.

  • macOS window polls keep a title when a browser has no readable window.

Both previous findings are addressed. The harness passed locally; native macOS behavior remains unverified.

Reviews (2) · Last reviewed commit: "fix(macos): discard partial browser meta..." · Reviewed by Greptile

Comment thread aw_watcher_window/printAppStatus.jxa
Comment thread aw_watcher_window/printAppStatus.jxa
Git-Session-Id: 3824e6ab-2060-5d77-acd6-13eba49f9e65
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

CI-green and mergeable (Greptile 5/5) — waiting only on a maintainer click.

This PR is ready to merge, but the bot has pull-only access to this repo and can't self-merge — surfacing it here so it isn't lost. The monitoring loop will stop re-flagging it now that this note is posted.

@ErikBjare
ErikBjare merged commit 10638b2 into ActivityWatch:master Oct 19, 2026
7 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