@@ -9,7 +9,7 @@ use core_foundation::{
9
9
mach_port:: { CFMachPort , CFMachPortInvalidate , CFMachPortRef } ,
10
10
} ;
11
11
use foreign_types:: { foreign_type, ForeignType } ;
12
- use std:: mem:: ManuallyDrop ;
12
+ use std:: { mem:: ManuallyDrop , ptr } ;
13
13
14
14
pub type CGEventField = u32 ;
15
15
pub type CGKeyCode = u16 ;
@@ -503,8 +503,21 @@ macro_rules! CGEventMaskBit {
503
503
}
504
504
505
505
pub 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 > ;
508
521
type CGEventTapCallBackInternal = unsafe extern "C" fn (
509
522
proxy : CGEventTapProxy ,
510
523
etype : CGEventType ,
@@ -513,24 +526,25 @@ type CGEventTapCallBackInternal = unsafe extern "C" fn(
513
526
) -> crate :: sys:: CGEventRef ;
514
527
515
528
unsafe 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 ,
520
533
) -> 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
+ }
529
543
}
530
544
531
545
/// ```no_run
532
546
/// 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 };
534
548
/// let current = CFRunLoop::get_current();
535
549
///
536
550
/// CGEventTap::with(
@@ -540,7 +554,7 @@ unsafe extern "C" fn cg_event_tap_callback_internal(
540
554
/// vec![CGEventType::MouseMoved],
541
555
/// |_proxy, _type, event| {
542
556
/// println!("{:?}", event.location());
543
- /// None
557
+ /// CallbackResult::Keep
544
558
/// },
545
559
/// |tap| {
546
560
/// let loop_source = tap
@@ -555,11 +569,11 @@ unsafe extern "C" fn cg_event_tap_callback_internal(
555
569
/// ```
556
570
pub struct CGEventTap < ' tap_life > {
557
571
mach_port : CFMachPort ,
558
- _callback : Box < CGEventTapCallBackFn < ' tap_life > > ,
572
+ _callback : Box < CGEventTapCallbackFn < ' tap_life > > ,
559
573
}
560
574
561
575
impl 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 > (
563
577
tap : CGEventTapLocation ,
564
578
place : CGEventTapPlacement ,
565
579
options : CGEventTapOptions ,
@@ -578,7 +592,7 @@ impl<'tap_life> CGEventTap<'tap_life> {
578
592
place : CGEventTapPlacement ,
579
593
options : CGEventTapOptions ,
580
594
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 ,
582
596
with_fn : impl FnOnce ( & Self ) -> R ,
583
597
) -> Result < R , ( ) > {
584
598
// SAFETY: We are okay to bypass the 'static restriction because the
@@ -596,14 +610,14 @@ impl<'tap_life> CGEventTap<'tap_life> {
596
610
place : CGEventTapPlacement ,
597
611
options : CGEventTapOptions ,
598
612
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 ,
600
614
) -> Result < Self , ( ) > {
601
615
let event_mask: CGEventMask = events_of_interest
602
616
. iter ( )
603
617
. fold ( CGEventType :: Null as CGEventMask , |mask, & etype| {
604
618
mask | CGEventMaskBit ! ( etype)
605
619
} ) ;
606
- let cb: Box < CGEventTapCallBackFn > = Box :: new ( Box :: new ( callback) ) ;
620
+ let cb: Box < CGEventTapCallbackFn > = Box :: new ( Box :: new ( callback) ) ;
607
621
let cbr = Box :: into_raw ( cb) ;
608
622
unsafe {
609
623
let event_tap_ref = CGEventTapCreate (
0 commit comments