admin管理员组

文章数量:1400366

I have Raycast and ChatGPT installed on my computer, both set to open their respective action panels using the Option + Space shortcut. Yes, they are conflicting now, but I don’t plan to change the shortcut because it’s very convenient, and many other apps might use this shortcut in the future.

To address this, I’m developing a shortcut management app with Tauri that intercepts conflicting shortcuts and opens a panel to let me choose which app should receive the event. However, I’m encountering an issue:

When I use the CGEventPostToPid API to send an event to a specific process (e.g., a browser with onkeydown = console.log), it works—the event is logged. But when I try this with apps like Raycast or ChatGPT, nothing happens. Switching to CGEventPost does deliver the event, but all apps listening for the shortcut trigger again, causing the same conflict!

I suspect CGEventPostToPid might not send events to background apps? (I’m not entirely sure—I’m not a professional macOS developer.) Are there alternative approaches to achieve my goal of selectively forwarding the shortcut event to one app? Any help would be greatly appreciated!

use core_foundation::runloop::{CFRunLoop, kCFRunLoopCommonModes};
use core_graphics::event_source::{CGEventSource, CGEventSourceStateID};
use core_graphics::{
  event::{
    CGEvent, CGEventFlags, CGEventTap, CGEventTapLocation, CGEventTapOptions,
    CGEventTapPlacement, CGEventType,
  },
  sys::CGEventSourceRef,
};

fn emit(e: CGEvent) {
  e.post(CGEventTapLocation::HID); // call `CGEventPost`
  // e.post_to_pid(57104); // call `CGEventPostToPid`
}

pub async fn run() {
  // down Option
  let state_id = CGEventSourceStateID::CombinedSessionState;
  let alt_source = CGEventSource::new(state_id).expect("Unable to create event source");
  let alt_down_event = CGEvent::new_keyboard_event(alt_source, 58, true).expect("Unable to create keyboard event");
  alt_down_event
    .set_flags(CGEventFlags::CGEventFlagAlternate | CGEventFlags::CGEventFlagNonCoalesced);
  emit(alt_down_event);

  // Press Space (while holding Option)
  let space_source = CGEventSource::new(state_id).expect("Unable to create event source");
  // 创建Option+Space组合事件
  let space_down_event =
    CGEvent::new_keyboard_event(space_source, 49, true).expect("Unable to create keyboard event");
  space_down_event
    .set_flags(CGEventFlags::CGEventFlagAlternate | CGEventFlags::CGEventFlagNonCoalesced);
  emit(space_down_event);

  // Release Space
  let space_source = CGEventSource::new(state_id).expect("Unable to create event source");
  let space_up_event =
    CGEvent::new_keyboard_event(space_source, 49, false).expect("Unable to create keyboard event");
  space_up_event
    .set_flags(CGEventFlags::CGEventFlagAlternate | CGEventFlags::CGEventFlagNonCoalesced);
  emit(space_up_event);

  // Release Option
  let alt_source = CGEventSource::new(state_id).expect("Unable to create event source");
  let alt_up_event = CGEvent::new_keyboard_event(alt_source, 58, false).expect("Unable to create keyboard event");
  alt_up_event.set_flags(CGEventFlags::CGEventFlagNonCoalesced);
  emit(alt_up_event);
}

本文标签: rustHow to send a shortcut key to a background application in macOS developmentStack Overflow