Skip to content

feat(wayland): accept aw-awatcher as the Wayland watcher - #143

Merged
ErikBjare merged 6 commits into
ActivityWatch:masterfrom
TimeToBuildBob:feat/wayland-accept-awatcher
Oct 18, 2026
Merged

ErikBjare merged 6 commits into
ActivityWatch:masterfrom
TimeToBuildBob:feat/wayland-accept-awatcher

Conversation

@TimeToBuildBob

@TimeToBuildBob TimeToBuildBob commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

What

_apply_wayland_substitutions() now looks for both Wayland watcher implementations and uses the first one available:

  1. aw-watcher-window-wayland (the standalone module)
  2. aw-awatcher (what the Linux desktop bundle ships)

Why

ActivityWatch/activitywatch#1531 makes the PyInstaller Linux bundle ship awatcher as aw-awatcher. Without this change, #142's detection finds no aw-watcher-window-wayland in a stock bundle, warns, and leaves the X11 watchers selected — which capture nothing on Wayland.

Erik on ActivityWatch/activitywatch#92: "Get on implementing Wayland support in aw-qt, should be as easy as bundling awatcher or something and adding the detection to aw-qt." This is the detection half of that pairing.

Behaviour

  • Nothing is substituted unless the user actually selected a watcher (unchanged).
  • If no Wayland watcher is installed, the original module list is returned and the warning now names both options.
  • aw-watcher-window-wayland is preferred when both are installed, so the standalone module keeps priority.

Tests

tests/test_wayland.py gains a class covering: only aw-awatcher available, both available (preference), insertion position, and no-wayland-watcher fallback. Existing tests are unchanged and still pass against the new selection path.

Refs ActivityWatch/activitywatch#92, ActivityWatch/activitywatch#1531

@greptile-apps

greptile-apps Bot commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; no new actionable issues remain.

Summary

Adds aw-awatcher as a Wayland replacement while keeping the standalone watcher as the automatic first choice.

  • Wayland sessions can use either installed Wayland watcher.
  • Stopping a Wayland watcher keeps it stopped after restart.

Both previous threads are addressed in the current code. Neither supplied root comment has a Comment number, so neither receives a numbered determination.

Reviews (2) · Last reviewed commit: "docs(wayland): spell out why an unavaila..." · Reviewed by Greptile

Comment thread aw_qt/manager.py
Comment thread aw_qt/manager.py
Comment thread aw_qt/config.py Fixed
@TimeToBuildBob

TimeToBuildBob commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor Author

🤖 AI code review

Adds aw-awatcher as a second accepted Wayland watcher. Moves Wayland watcher identities and session detection into a new aw_qt/wayland.py module, updates _apply_wayland_substitutions() to select the first installed watcher with explicit selections taking precedence, and extends persist_module_autostart() so stopping a Wayland watcher also disables the other Wayland watcher and the X11 watchers it replaces. Adds tests for the new selection logic and the persistence behavior.

Safe to merge — no P0/P1 findings

Confidence 5/5

✅ No findings. The diff looks correct to me on this pass.

Files changed (5) — the diff as I read it
  • aw_qt/config.py — Imports Wayland watcher constants and _is_wayland; when disabling a Wayland watcher on Wayland, also disables the other Wayland watcher and the replaced X11 modules before writing.
  • aw_qt/manager.py — Replaces the local WAYLAND_WATCHER and _is_wayland with imports from wayland.py; adds _select_wayland_watcher() and rewrites _apply_wayland_substitutions() to handle multiple watchers and explicit selections.
  • aw_qt/wayland.py — New module defining WAYLAND_WATCHER, WAYLAND_WATCHERS, _WAYLAND_REPLACED_MODULES, and _is_wayland().
  • tests/test_persist_toggles.py — Adds tests for stopping a Wayland watcher on Wayland disabling related watchers, and for X11 sessions leaving watchers untouched.
  • tests/test_wayland.py — Adds TestAwatcherAsWaylandWatcher covering aw-awatcher selection, preference, explicit selection, and fallback behavior.
Previous review passes
commit score findings engine when
6633979b646e 3/5 1 llm 2026-10-18 01:22 UTC
5186676546b5 4/5 1 llm 2026-10-18 01:43 UTC
f5ab32054e80 3/5 2 llm 2026-10-18 01:45 UTC
f5ab32054e80 3/5 1 llm 2026-10-18 02:02 UTC
cb8df12e18a5 5/5 0 llm 2026-10-18 02:22 UTC
cb8df12e18a5 4/5 1 llm 2026-10-18 02:41 UTC
83c3df49bb79 5/5 0 llm 2026-10-18 03:43 UTC

Reviewed 89ccfcf1de15 · openrouter/deepseek/deepseek-v4-flash-0731 · llm engine · 43s · about this reviewer

Maintainer commands

@TimeToBuildBob review (own line) — fresh review · @TimeToBuildBob fix — a worker acts on the findings. Once per comment; 👀 = received.

Comment thread aw_qt/manager.py
Comment thread aw_qt/manager.py
Comment thread aw_qt/wayland.py
Comment thread aw_qt/config.py
Comment thread tests/test_persist_toggles.py
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Pushed 5186676 and f5ab320 through the in-band review wrapper:

  • Both explicitly selected Wayland implementations now yield one watcher (first installed explicit selection); tests cover both orders with and without X11 selections.
  • A tray stop removes equivalent dormant autostart selections, so restarting cannot silently switch to the other implementation and resume tracking.
  • An unavailable explicit Wayland selection is preserved with a warning rather than silently dropped/replaced.
  • Shared detector/constants moved into aw_qt/wayland.py, removing the CodeQL import cycle.

Verification: 221 tests passed, mypy passed, Flake8 passed with the existing W503/E203 style exceptions, and git diff --check passed. The original P1 has a fix reply and was automatically resolved by re-review. The second local pass's P1/P2 were disputed and resolved on their own threads with evidence: clearing the dormant alternative is necessary for stop persistence, and the persistence tests intentionally exercise the real environment detector. A separate replay verified an already-disabled stop returns false and performs zero writes.

No further review rounds triggered. Current CI: CodeQL/Analyze passed; Linux, macOS and Windows tests still running. The CodeQL unused-symbol advisories remain; they do not reproduce the removed import cycle. Still stacked on #142; no merge attempted.

Comment thread aw_qt/manager.py Outdated
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Convergence adjudication — maintainer handoff

Recommendation: no remaining blocking review finding on cb8df12e18a5415365827c6ce97b584efff4476a; ready for maintainer judgment after #142 lands. No merge or new review request made.

  • Fixed: no new code changes in this adjudication. Reverified the earlier fixes for stopped tracking returning after restart, two Wayland implementations starting together, and unavailable explicit selections blocking fallback for separately selected X11 watchers. Both original Greptile P1s already have fix replies and resolved threads; all subsequent AI-review finding threads are also resolved.
  • Remaining, non-blocking: resolved the two remaining CodeQL threads with inline evidence. The WAYLAND_WATCHER import is an intentional compatibility re-export used by the tests (nitpick, not a runtime defect). The _WAYLAND_REPLACED_MODULES unused-global claim is false: both manager startup and config persistence import and use it. The AI review's summary-only docstring advisory overlooks the existing “unless X11 watchers were also selected” qualification; the Wayland-environment advisory explicitly identifies no defect. Neither warrants another code/review round.
  • Verified against: cb8df12e18a5415365827c6ce97b584efff4476a, matching the newest AI-review marker (cb8df12e18a5, 5/5, no blocking findings). Greptile's 3/5 summary still describes 904ff72f5b42, not this head; I am not presenting that stale score as a current-head review.
  • CI: all five current-head checks passed: Linux, macOS, Windows, CodeQL, and Analyze (python). Independently reran the full suite here: 223 passed.
  • Domain risk: native Wayland desktop/bundle verification still matters: confirm window/AFK capture with the shipped aw-awatcher, only one implementation running, and tray stop → application restart leaving tracking stopped. Unit/integration mocks do not prove compositor or packaged-process behavior.
  • Convergence: detector reports verdict: converged with zero unresolved P1/P2 findings, but round_convergence.stable_rounds is 0 (required: 2; only one Greptile round exists). Thread closure is not two stable review rounds. No Greptile retrigger, score override, or auto-merge.

Comment thread aw_qt/manager.py
@ErikBjare

Copy link
Copy Markdown
Member

@greptileai review

@ErikBjare

Copy link
Copy Markdown
Member

@TimeToBuildBob 142 merged, rebase

The Linux desktop bundle ships awatcher as `aw-awatcher`, but the
substitution only looked for `aw-watcher-window-wayland`, so a stock
bundle on Wayland still warned and started no watcher.

Look for both implementations and use the first one available,
preferring `aw-watcher-window-wayland` (the standalone module) over
`aw-awatcher` (the bundled one). Behaviour is otherwise unchanged:
nothing is substituted unless a watcher was actually selected, and the
X11 modules are kept when no Wayland watcher is installed.

Refs ActivityWatch/activitywatch#92

Git-Session-Id: 1827fd29-8a7c-5293-98ef-7481a8bcd9ad
Git-Session-Id: 845a16bb-4607-50b7-800e-27f61f3134ab
Git-Session-Id: fb4abb0b-d905-5b1a-91af-b74be3eee571
Git-Session-Id: fb4abb0b-d905-5b1a-91af-b74be3eee571
Git-Session-Id: c3ba4966-46ab-53e5-ae2c-2d797e9fd239
The old sentence ('kept unchanged unless X11 watchers were also selected')
read as if the unavailable selection survived the X11-substitution case. It
does not: it cannot run, so it is dropped from the returned launch list, while
the persisted autostart_modules config is untouched. State both cases
explicitly so the behaviour is not re-reported as a contradiction.

No behaviour change; tests/test_wayland.py already pins the result.

Git-Session-Id: 918d9d29-2603-4b15-b995-d9bb6201683a
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Rebased onto master (b0b405c, #142 squash-merged) and force-pushed 89ccfcf.

What changed:

Verification on the rebased head:

  • pytest tests/ → 223 passed (includes test_wayland.py and test_persist_toggles.py)
  • python -c "import aw_qt" → ok
  • PR state: MERGEABLE (was CONFLICTING), CI running

Greptile's review request from before the rebase will land on the new head; nothing else outstanding.

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

CI follow-up: all 5 checks now passed (Linux, macOS, Windows, CodeQL, Analyze). Greptile returned 5/5. AI review also 5/5 on current head 89ccfcf. Ready for merge.

@ErikBjare
ErikBjare merged commit 5fb7634 into ActivityWatch:master Oct 18, 2026
5 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.

3 participants