Skip to content

Replace osascript polling with direct AX API for Zoom mute detection#3709

Merged
yujonglee merged 4 commits intomainfrom
devin/1770472838-ax-zoom-mute
Feb 8, 2026
Merged

Replace osascript polling with direct AX API for Zoom mute detection#3709
yujonglee merged 4 commits intomainfrom
devin/1770472838-ax-zoom-mute

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Feb 7, 2026

Replace osascript with direct AX API for Zoom mute detection

Summary

Replaces the osascript/AppleScript-based Zoom mute state detection with direct macOS Accessibility API calls via cidre's ax module. Instead of spawning an external osascript process every polling cycle, the new implementation:

  1. Finds Zoom's PID via ns::RunningApp::with_bundle_id()
  2. Navigates the AX tree directly: app element → menu bar → "Meeting" menu bar item → menu items
  3. Checks for "Mute Audio" / "Unmute Audio" menu item titles

This eliminates per-poll process spawning overhead and removes the std::process::Command dependency from this module.

Motivated by discussion in yury/cidre#38 about using cidre's accessibility API bindings.

Updates since last revision

  • Replaced the unsafe { std::mem::transmute(&*value) } in ax_element_title with cidre's safe value.try_as_string()? method, eliminating the unsafe block entirely. This addresses the Graphite review comment about potential UB if the AX API returned a non-CFString type.
  • Removed the now-unused cf import.

Review & Testing Checklist for Human

  • Test on macOS with Zoom in a meeting: This cannot be tested in CI. Verify the AX tree structure matches expectations (app → menu bar child → "Meeting" menu bar item → menu → menu items). Run the existing test_check_zoom_mute_state ignored test with Zoom open.
  • Menu item title casing: Old code only matched "Mute audio" / "Unmute audio" (lowercase). New code also matches "Mute Audio" / "Unmute Audio". Verify which casing Zoom actually uses to confirm the old strings are still needed.
  • Verify accessibility permission flow: Confirm that the AX API calls fail gracefully (return None) when accessibility permissions are not granted, matching the previous behavior.

Notes

  • The polling architecture (WatcherState, is_zoom_using_mic() gate, Observer trait impl) is unchanged — only the check_zoom_mute_state() internals were replaced.
  • The cidre dependency now explicitly requests the "ax" feature (previously relied on default "full" features).
  • The previous unsafe transmute concern has been resolved by using cf::Type::try_as_string(), which safely returns None if the value is not a CFString.

Requested by: @yujonglee
Link to Devin run


Open with Devin

Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
@netlify
Copy link

netlify bot commented Feb 7, 2026

Deploy Preview for hyprnote canceled.

Name Link
🔨 Latest commit 395a29d
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote/deploys/69880a68be501900084545cf

@netlify
Copy link

netlify bot commented Feb 7, 2026

Deploy Preview for hyprnote-storybook canceled.

Name Link
🔨 Latest commit 395a29d
🔍 Latest deploy log https://app.netlify.com/projects/hyprnote-storybook/deploys/69880a683aebc30008e3fe6d

@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Copy link
Contributor Author

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
devin-ai-integration bot and others added 2 commits February 8, 2026 02:54
…_title

Co-Authored-By: yujonglee <yujonglee.dev@gmail.com>
@yujonglee yujonglee merged commit 6dd0099 into main Feb 8, 2026
12 of 13 checks passed
@yujonglee yujonglee deleted the devin/1770472838-ax-zoom-mute branch February 8, 2026 04:00
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.

1 participant