Skip to content

✨ Replace event monitors, improve AX permission handling#849

Merged
SenpaiHunters merged 36 commits into
developfrom
fix-trigger-key
Oct 27, 2025
Merged

✨ Replace event monitors, improve AX permission handling#849
SenpaiHunters merged 36 commits into
developfrom
fix-trigger-key

Conversation

@mrkai77
Copy link
Copy Markdown
Owner

@mrkai77 mrkai77 commented Oct 12, 2025

Introduces three new event monitors (replacing all previous ones):

  • ActiveEventMonitor: The most powerful option. It creates a CFMachPort via CGEvent.tapCreate, allowing it to receive and optionally modify events. This monitor is used by Loop for handling the trigger key and user-defined shortcuts, enabling it to block events from reaching the frontmost application when Loop is active.
  • PassiveEventMonitor: The default event monitor when event mutation isn’t required. Like ActiveEventMonitor, it uses a CFMachPort created with CGEvent.tapCreate to receive events, but simply passes them to a callback executed on a separate task, helping to avoid downstream lag. Used to track mouse movement, or middle click events.
  • LocalEventMonitor: Built on NSEvent.addLocalMonitorForEvents. This monitor only receives events directed at Loop itself, and is used for recording trigger keys and for UI navigation (e.g. within the action selection popup).

Beyond the new event monitors, this update brings some other optimizations and overall improvements:

  • WindowActionCache: Maintains an up-to-date dictionary mapping all user actions to their keybinds, enabling more efficient action lookups from the active event monitor. This dictionary-based approach dramatically improves performance, where the previous method required iterating through actions to find a match.
  • Logger(category:): New initializer for app-wide Logger instances, which internally initializes a Logger with Loop's bundle ID.
  • AccessibilityManager.stream(initial:): Now listens for system notifications to track changes in AX API access. LoopManager uses this stream to start and stop the event monitor as needed, and the advanced settings view now uses this mechanism instead of polling.
  • CGEventFlags extensions: By processing CGEvents rather than NSEvents, we can now detect which side each modifier key was pressed on.
  • PreviewController animations: The preview window now scales from/to 80% (instead of 0%) when appearing or disappearing, leading to a much smoother animation :)
  • ScreenUtility: findScreen's implementation has been fixed, where it was previously using the AppKit coordinate space to find windows whose frames were provided in the CoreGraphics coordinate space. Now, it will use screen.displayBounds which is provided in CoreGraphics coordinate space.

@mrkai77 mrkai77 requested a review from Copilot October 12, 2025 23:57
@mrkai77 mrkai77 self-assigned this Oct 12, 2025
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces three new event monitoring classes to replace previous implementations and improve AX permission handling, along with performance optimizations and UI enhancements.

  • Replaces event monitoring with specialized classes: ActiveEventMonitor for event modification, PassiveEventMonitor for passive observation, and LocalEventMonitor for app-specific events
  • Introduces WindowActionCache for efficient keybind-to-action lookups using dictionary-based caching
  • Updates accessibility permission tracking to use system notifications instead of polling

Reviewed Changes

Copilot reviewed 34 out of 34 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
Loop/Window Management/Window/Window.swift Adds window level validation and updates string description format
Loop/Window Management/Window Action/WindowDirection+Snapping.swift Renames public method and makes helper methods private
Loop/Window Management/Window Action/WindowActionCache.swift New cache class for efficient keybind-to-action lookups
Loop/Window Management/Window Action/WindowAction.swift Removes static lookup method in favor of cache-based approach
Loop/Utilities/Logger+Extensions.swift New convenience initializer for Logger with app bundle ID
Loop/Utilities/EventMonitor.swift Removes old event monitoring implementation
Loop/Utilities/Event Monitoring/*.swift New specialized event monitoring classes
Loop/Utilities/AccessibilityManager.swift Enhanced AX permission tracking with notification system
Loop/Extensions/*.swift Various extensions for CGEventFlags and Bundle improvements
Loop/Core/*.swift Updates to use new event monitoring and caching systems
Comments suppressed due to low confidence (1)

Loop/Window Action Indicators/Preview Window/PreviewController.swift:1

  • Corrected spelling of 'receieved' to 'received'.
//

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment thread Loop/Utilities/Event Monitoring/PassiveEventMonitor.swift Outdated
Comment thread Loop/Utilities/Event Monitoring/ActiveEventMonitor.swift Outdated
Comment thread Loop/Window Management/Window Action/WindowActionCache.swift
Comment thread Loop/Utilities/Event Monitoring/ActiveEventMonitor.swift Outdated
@mrkai77 mrkai77 force-pushed the fix-trigger-key branch 2 times, most recently from 93eb7cf to 911cea4 Compare October 13, 2025 01:40
@mrkai77 mrkai77 changed the title Introduce ActiveEventMonitor, PassiveEventMonitor, LocalEventMonitor, improve AX permission handling ✨ Introduce ActiveEventMonitor, PassiveEventMonitor, LocalEventMonitor, improve AX permission handling Oct 18, 2025
@mrkai77 mrkai77 linked an issue Oct 18, 2025 that may be closed by this pull request
4 tasks
# Conflicts:
#	Loop/Core/WindowDragManager.swift
#	Loop/Settings Window/Loop/AdvancedConfiguration.swift
@mrkai77 mrkai77 requested a review from Copilot October 24, 2025 20:07
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

Copilot reviewed 60 out of 60 changed files in this pull request and generated 7 comments.

Comments suppressed due to low confidence (1)

Loop/Core/LoopManager.swift:1

  • The method attemptWindowSnap is called twice on consecutive lines - once with self. and once without. This appears to be duplicate code that should be removed.
//

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Loop/Window Management/Window Action/WindowActionCache.swift
Comment thread Loop/Utilities/Logger+Extensions.swift
Comment thread Loop/Utilities/Event Monitoring/BaseEventTapMonitor.swift Outdated
Comment thread Loop/Core/Triggers/KeybindObserver.swift Outdated
Comment thread Loop/Settings Window/Loop/ExcludedAppsConfiguration.swift
Comment thread Loop/Extensions/CGKeyCode+Extensions.swift
Comment thread Loop/App/AppDelegate+UNNotifications.swift Outdated
@SenpaiHunters SenpaiHunters merged commit 4978aad into develop Oct 27, 2025
1 check passed
@SenpaiHunters SenpaiHunters deleted the fix-trigger-key branch October 27, 2025 07:37
@mrkai77 mrkai77 changed the title ✨ Introduce ActiveEventMonitor, PassiveEventMonitor, LocalEventMonitor, improve AX permission handling ✨ Replace event monitors, improve AX permission handling Nov 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment