Skip to content

macOS CGEventTap timeout disables transitions toggle — not always re-enabled #129

@nikkundra

Description

@nikkundra

Description

Cursr's transition toggle intermittently flips to OFF without user action on macOS. The Cursr log files reveal the root cause: macOS kills Cursr's CGEventTap due to timeout, and Cursr's re-enable attempt does not always succeed.

Environment

  • macOS: Tahoe (latest)
  • Cursr: v1.7.3 (pre-release)
  • Machine: MacBook Pro M3 Max (40 GPU cores)
  • Displays: 1x Built-in Liquid Retina XDR + 4x INNOCN 27M2V (27" 4K Mini LED, 160Hz)
  • Usage: Single Mac, 5 displays (not multi-computer KVM)

Log Evidence

From ~/Library/Application Support/cursr/Logs/app2.log:

2026-02-12T11:39:47Z [n_warn] System disabled CGEventTap due to timeout, re-enabaling
2026-02-12T11:40:03Z [n_warn] System disabled CGEventTap due to timeout, re-enabaling
2026-02-12T11:40:24Z [n_warn] System disabled CGEventTap due to timeout, re-enabaling
2026-02-12T19:24:53Z [n_warn] System disabled CGEventTap due to timeout, re-enabaling
2026-02-12T19:24:54Z [n_warn] System disabled CGEventTap due to timeout, re-enabaling

5 occurrences on a single day (2026-02-12). After these events, the UI toggle is sometimes left in the OFF state.

Contributing Factor: Stale Display Setups

The conf.json file (640KB) contains 34 saved display setups, of which only 1 is active (last activated). The other 33 have never been activated. On every wake/resolution change, Cursr generates hundreds of display-matching warnings:

[warn] Display configuration (left: 0, top: 0, right: 1919, ...) already matched with a detected display (...). Cannot apply it to display (...)

This flood of matching attempts may be slowing the CGEventTap callback, causing macOS to hit its timeout threshold and disable the tap.

Expected Behavior

When macOS sends CGEventType.tapDisabledByTimeout, Cursr should reliably call CGEventTapEnable(tap, true) to re-enable the event tap and ensure the UI toggle reflects the actual state.

Suggested Improvements

  1. More robust CGEventTapEnable recovery — retry with backoff if re-enable fails
  2. Verify UI toggle state matches actual tap state after re-enable attempt
  3. Reduce display matching overhead — only match active/recent setups, not all 34
  4. Log success/failure of re-enable — currently only logs the attempt ("re-enabaling"), not the result

Workaround

I created a monitoring script that checks conf.json's disabled field every 30s and re-enables + restarts Cursr when it detects the toggle has flipped OFF: https://github.com/kundrnik/niks-general-computer-tech-optimizations/pull/15

Related Issues

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions