Summary
When a CrossOver-hosted (Wine) application is focused — for example, a Windows game running through CrossOver — aw-watcher-window-macos does not emit a new event for it. Instead, the bucket continues to report the previously focused native macOS window for the entire duration I'm in the Wine app. Time spent in Wine apps is therefore attributed to whatever I looked at before switching to them, which is wrong.
Steps to reproduce
- Launch a Windows application through CrossOver (any bottle).
- With
aw-watcher-window running, switch back and forth between a native macOS app (e.g. Safari) and the CrossOver window a few times, spending several seconds in each.
- Open the ActivityWatch web UI (or query the
aw-watcher-window_<hostname> bucket directly) and look at the events for that time range.
Expected behavior
Events are emitted while the CrossOver window is focused, showing some reasonable app identifier (e.g. CrossOver, the bottle name, or the Wine process name) and the current window title.
Actual behavior
No events are emitted while the CrossOver window is focused. The bucket shows the last native macOS window as if it remained focused the whole time.
Additional context
I wrote a minimal replacement watcher in AppleScript via osascript that uses System Events:
tell application "System Events"
set frontApp to first application process whose frontmost is true
set appName to name of frontApp
tell frontApp
set windowTitle to value of attribute "AXTitle" of (value of attribute "AXFocusedWindow")
end tell
return appName & "|" & windowTitle
end tell
This does capture CrossOver/Wine windows correctly, including the window title set by the Wine-hosted app. So the Accessibility API clearly exposes the information — the current Swift implementation seems to take a code path that doesn't reach it.
Speculation about possible root causes (haven't verified against the source):
- The implementation relies on
NSWorkspace.shared.frontmostApplication and a notification-based state that doesn't fire when focus moves to a CrossOver-hosted window.
- It queries only
AXMainWindow, which CrossOver-bottled apps may not set; AXFocusedWindow might work where AXMainWindow doesn't.
- It filters processes by bundle identifier / bundle type and excludes CrossOver's wrapper processes.
Happy to test fixes or provide more diagnostic output if useful.
Summary
When a CrossOver-hosted (Wine) application is focused — for example, a Windows game running through CrossOver —
aw-watcher-window-macosdoes not emit a new event for it. Instead, the bucket continues to report the previously focused native macOS window for the entire duration I'm in the Wine app. Time spent in Wine apps is therefore attributed to whatever I looked at before switching to them, which is wrong.Steps to reproduce
aw-watcher-windowrunning, switch back and forth between a native macOS app (e.g. Safari) and the CrossOver window a few times, spending several seconds in each.aw-watcher-window_<hostname>bucket directly) and look at the events for that time range.Expected behavior
Events are emitted while the CrossOver window is focused, showing some reasonable app identifier (e.g.
CrossOver, the bottle name, or the Wine process name) and the current window title.Actual behavior
No events are emitted while the CrossOver window is focused. The bucket shows the last native macOS window as if it remained focused the whole time.
Additional context
I wrote a minimal replacement watcher in AppleScript via
osascriptthat uses System Events:This does capture CrossOver/Wine windows correctly, including the window title set by the Wine-hosted app. So the Accessibility API clearly exposes the information — the current Swift implementation seems to take a code path that doesn't reach it.
Speculation about possible root causes (haven't verified against the source):
NSWorkspace.shared.frontmostApplicationand a notification-based state that doesn't fire when focus moves to a CrossOver-hosted window.AXMainWindow, which CrossOver-bottled apps may not set;AXFocusedWindowmight work whereAXMainWindowdoesn't.Happy to test fixes or provide more diagnostic output if useful.