Skip to content

feat(recording): full AX element extraction, modifier tracking, scroll phase, Win32 fixes#29

Merged
mohabbis merged 2 commits into
masterfrom
feat/recording-improvements
Jun 9, 2026
Merged

feat(recording): full AX element extraction, modifier tracking, scroll phase, Win32 fixes#29
mohabbis merged 2 commits into
masterfrom
feat/recording-improvements

Conversation

@mohabbis

@mohabbis mohabbis commented Jun 9, 2026

Copy link
Copy Markdown
Owner

Summary

  • macOS — full AX attribute extraction: each mouse click now captures all 6 accessibility attributes (role, title, description, value, identifier, role_description) via AXUIElementCopyElementAtPosition; app name is resolved via PID → AXUIElementCreateApplication → AXTitle. Tap switched to kCGEventTapOptionListenOnly so slow AX lookups never block the system event queue.
  • macOS — modifier & character tracking: key events now extract the modifier bitmask via CGEventGetFlags (Shift/Ctrl/Alt/Cmd/CapsLock) and the actual characters via CGEventKeyboardGetUnicodeString.
  • macOS — scroll phase: reads kCGScrollWheelEventScrollPhase (field 99) with fallback to kCGScrollWheelEventMomentumPhase (field 123) for accurate phase values.
  • Windows — element inspection: get_element_at implemented via WindowFromPoint + GetClassNameA/GetWindowTextA/GetAncestor(GA_ROOTOWNER) — no new dependencies required.
  • Windows — modifier & character tracking: GetKeyState extracts modifier state; GetKeyboardState + ToUnicode translates virtual key codes to characters. WM_SYSKEYDOWN/UP now handled.
  • Windows — scroll events: WM_MOUSEWHEEL and WM_MOUSEHWHEEL now recorded using HIWORD(mouseData)/WHEEL_DELTA normalisation — previously missing entirely.
  • Windows — critical bug fix: GLOBAL_TX was declared but never assigned in WindowsRecorder::start(), making all Windows recording completely broken (hooks installed but events never reached the bridge channel). Fixed.
  • ElementInfo: added value, description, identifier, role_description optional fields for full attribute capture.

Test plan

  • macOS: start recording, click a button in a native app — verify ElementInfo in the event timeline shows role, name, app, and at least some of the new optional fields
  • macOS: record a key sequence with modifiers (Cmd+C) — verify modifiers bitmask and chars are populated correctly
  • macOS: scroll in a window — verify phase field is non-zero where applicable
  • Windows: start recording, click a window element — verify ElementInfo role/name/app are populated
  • Windows: record key events — verify modifier state and characters extracted
  • Windows: scroll — verify Scroll events appear in the timeline
  • Both platforms: inspect_element command returns populated ElementInfo
  • README status checklist: all four items now marked [x]

https://claude.ai/code/session_01GAPteYe8ztzpa1mdh2M2m6


Generated by Claude Code

@vercel

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ghost Ready Ready Preview, Comment Jun 9, 2026 1:56pm

@mohabbis mohabbis marked this pull request as ready for review June 9, 2026 13:47
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

…l phase, Win32 element inspection

- macOS: extract all 6 AX attributes (role, title, description, value, identifier,
  role_description) per click; resolve app name via PID→AXUIElementCreateApplication;
  switch tap to kCGEventTapOptionListenOnly so slow AX lookups never block the event queue
- macOS: extract modifier flags via CGEventGetFlags (Shift/Ctrl/Alt/Cmd/CapsLock bitmask)
  and actual characters via CGEventKeyboardGetUnicodeString on key events
- macOS: read kCGScrollWheelEventScrollPhase (field 99) and kCGScrollWheelEventMomentumPhase
  (field 123) for accurate scroll phase values
- Windows: implement get_element_at via WindowFromPoint + GetClassNameA/GetWindowTextA/
  GetAncestor(GA_ROOTOWNER) for role, name, and app extraction without new dependencies
- Windows: extract modifier state via GetKeyState (VK_SHIFT/CONTROL/MENU/LWIN/RWIN) and
  translate characters via GetKeyboardState + ToUnicode on key events
- Windows: add WM_MOUSEWHEEL and WM_MOUSEHWHEEL handling (HIWORD delta / WHEEL_DELTA=120)
- Windows: fix pre-existing bug where GLOBAL_TX was never set in WindowsRecorder::start(),
  making all Windows recording completely broken (events never reached the bridge channel)
- core/events.rs: add value, description, identifier, role_description optional fields to
  ElementInfo for full attribute capture
- README: mark all four previously unchecked recording features as complete

https://claude.ai/code/session_01GAPteYe8ztzpa1mdh2M2m6
@mohabbis mohabbis merged commit b7644d7 into master Jun 9, 2026
12 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