@@ -9,7 +9,7 @@ use core_foundation::{
99 mach_port:: { CFMachPort , CFMachPortInvalidate , CFMachPortRef } ,
1010} ;
1111use foreign_types:: { foreign_type, ForeignType } ;
12- use std:: mem:: ManuallyDrop ;
12+ use std:: { mem:: ManuallyDrop , ptr } ;
1313
1414pub type CGEventField = u32 ;
1515pub type CGKeyCode = u16 ;
@@ -503,8 +503,21 @@ macro_rules! CGEventMaskBit {
503503}
504504
505505pub type CGEventTapProxy = * const c_void ;
506- type CGEventTapCallBackFn < ' tap_life > =
507- Box < dyn Fn ( CGEventTapProxy , CGEventType , & CGEvent ) -> Option < CGEvent > + ' tap_life > ;
506+
507+ /// What the system should do with the event passed to the callback.
508+ ///
509+ /// This value is ignored if [`CGEventTapOptions::ListenOnly`] is specified.
510+ pub enum CallbackResult {
511+ /// Pass the event unchanged to other consumers.
512+ Keep ,
513+ /// Drop the event so it is not passed to later consumers.
514+ Drop ,
515+ /// Replace the event with a different one.
516+ Replace ( CGEvent ) ,
517+ }
518+
519+ type CGEventTapCallbackFn < ' tap_life > =
520+ Box < dyn Fn ( CGEventTapProxy , CGEventType , & CGEvent ) -> CallbackResult + ' tap_life > ;
508521type CGEventTapCallBackInternal = unsafe extern "C" fn (
509522 proxy : CGEventTapProxy ,
510523 etype : CGEventType ,
@@ -513,24 +526,25 @@ type CGEventTapCallBackInternal = unsafe extern "C" fn(
513526) -> crate :: sys:: CGEventRef ;
514527
515528unsafe extern "C" fn cg_event_tap_callback_internal (
516- _proxy : CGEventTapProxy ,
517- _etype : CGEventType ,
518- _event : crate :: sys:: CGEventRef ,
519- _user_info : * const c_void ,
529+ proxy : CGEventTapProxy ,
530+ etype : CGEventType ,
531+ event : crate :: sys:: CGEventRef ,
532+ user_info : * const c_void ,
520533) -> crate :: sys:: CGEventRef {
521- let callback = _user_info as * mut CGEventTapCallBackFn ;
522- let event = CGEvent :: from_ptr ( _event) ;
523- let new_event = ( * callback) ( _proxy, _etype, & event) ;
524- let event = match new_event {
525- Some ( new_event) => new_event,
526- None => event,
527- } ;
528- ManuallyDrop :: new ( event) . as_ptr ( )
534+ let callback = user_info as * mut CGEventTapCallbackFn ;
535+ let event = ManuallyDrop :: new ( CGEvent :: from_ptr ( event) ) ;
536+ let response = ( * callback) ( proxy, etype, & event) ;
537+ use CallbackResult :: * ;
538+ match response {
539+ Keep => event. as_ptr ( ) ,
540+ Drop => ptr:: null_mut ( ) ,
541+ Replace ( new_event) => ManuallyDrop :: new ( new_event) . as_ptr ( ) ,
542+ }
529543}
530544
531545/// ```no_run
532546/// use core_foundation::runloop::{kCFRunLoopCommonModes, CFRunLoop};
533- /// use core_graphics::event::{CGEventTap, CGEventTapLocation, CGEventTapPlacement, CGEventTapOptions, CGEventType};
547+ /// use core_graphics::event::{CGEventTap, CGEventTapLocation, CGEventTapPlacement, CGEventTapOptions, CGEventType, CallbackResult };
534548/// let current = CFRunLoop::get_current();
535549///
536550/// CGEventTap::with(
@@ -540,7 +554,7 @@ unsafe extern "C" fn cg_event_tap_callback_internal(
540554/// vec![CGEventType::MouseMoved],
541555/// |_proxy, _type, event| {
542556/// println!("{:?}", event.location());
543- /// None
557+ /// CallbackResult::Keep
544558/// },
545559/// |tap| {
546560/// let loop_source = tap
@@ -555,11 +569,11 @@ unsafe extern "C" fn cg_event_tap_callback_internal(
555569/// ```
556570pub struct CGEventTap < ' tap_life > {
557571 mach_port : CFMachPort ,
558- _callback : Box < CGEventTapCallBackFn < ' tap_life > > ,
572+ _callback : Box < CGEventTapCallbackFn < ' tap_life > > ,
559573}
560574
561575impl CGEventTap < ' static > {
562- pub fn new < F : Fn ( CGEventTapProxy , CGEventType , & CGEvent ) -> Option < CGEvent > + ' static > (
576+ pub fn new < F : Fn ( CGEventTapProxy , CGEventType , & CGEvent ) -> CallbackResult + ' static > (
563577 tap : CGEventTapLocation ,
564578 place : CGEventTapPlacement ,
565579 options : CGEventTapOptions ,
@@ -578,7 +592,7 @@ impl<'tap_life> CGEventTap<'tap_life> {
578592 place : CGEventTapPlacement ,
579593 options : CGEventTapOptions ,
580594 events_of_interest : std:: vec:: Vec < CGEventType > ,
581- callback : impl Fn ( CGEventTapProxy , CGEventType , & CGEvent ) -> Option < CGEvent > + ' tap_life ,
595+ callback : impl Fn ( CGEventTapProxy , CGEventType , & CGEvent ) -> CallbackResult + ' tap_life ,
582596 with_fn : impl FnOnce ( & Self ) -> R ,
583597 ) -> Result < R , ( ) > {
584598 // SAFETY: We are okay to bypass the 'static restriction because the
@@ -596,14 +610,14 @@ impl<'tap_life> CGEventTap<'tap_life> {
596610 place : CGEventTapPlacement ,
597611 options : CGEventTapOptions ,
598612 events_of_interest : std:: vec:: Vec < CGEventType > ,
599- callback : impl Fn ( CGEventTapProxy , CGEventType , & CGEvent ) -> Option < CGEvent > + ' tap_life ,
613+ callback : impl Fn ( CGEventTapProxy , CGEventType , & CGEvent ) -> CallbackResult + ' tap_life ,
600614 ) -> Result < Self , ( ) > {
601615 let event_mask: CGEventMask = events_of_interest
602616 . iter ( )
603617 . fold ( CGEventType :: Null as CGEventMask , |mask, & etype| {
604618 mask | CGEventMaskBit ! ( etype)
605619 } ) ;
606- let cb: Box < CGEventTapCallBackFn > = Box :: new ( Box :: new ( callback) ) ;
620+ let cb: Box < CGEventTapCallbackFn > = Box :: new ( Box :: new ( callback) ) ;
607621 let cbr = Box :: into_raw ( cb) ;
608622 unsafe {
609623 let event_tap_ref = CGEventTapCreate (
0 commit comments