@@ -19,7 +19,7 @@ use crate::{
19
19
WindowEvent , WindowInfo , WindowOpenOptions ,
20
20
} ;
21
21
22
- use super :: keyboard:: { from_nsstring, make_modifiers} ;
22
+ use super :: keyboard:: { from_nsstring, key_code_to_code , make_modifiers} ;
23
23
use super :: window:: WindowState ;
24
24
use super :: {
25
25
NSDragOperationCopy , NSDragOperationGeneric , NSDragOperationLink , NSDragOperationMove ,
@@ -220,7 +220,8 @@ unsafe fn create_view_class() -> &'static Class {
220
220
add_simple_mouse_class_method ! ( class, mouseEntered, MouseEvent :: CursorEntered ) ;
221
221
add_simple_mouse_class_method ! ( class, mouseExited, MouseEvent :: CursorLeft ) ;
222
222
223
- add_simple_keyboard_class_method ! ( class, keyDown) ;
223
+ class. add_method ( sel ! ( keyDown: ) , keyDown as extern "C" fn ( & Object , Sel , id ) ) ;
224
+
224
225
add_simple_keyboard_class_method ! ( class, keyUp) ;
225
226
add_simple_keyboard_class_method ! ( class, flagsChanged) ;
226
227
@@ -554,3 +555,51 @@ extern "C" fn handle_notification(this: &Object, _cmd: Sel, notification: id) {
554
555
}
555
556
}
556
557
}
558
+
559
+ /// Checks if a certain key event should be intercepted.
560
+ /// This is useful in DAW hosts such as Logic Pro which propagate
561
+ /// all keys globally.
562
+ fn should_intercept_key ( event : id ) -> bool {
563
+ use keyboard_types:: Code ;
564
+ let key_code = unsafe { NSEvent :: keyCode ( event) } ;
565
+ let code = key_code_to_code ( key_code) ;
566
+
567
+ matches ! (
568
+ code,
569
+ // Regular number keys
570
+ Code :: Digit0 | Code :: Digit1 | Code :: Digit2 | Code :: Digit3 | Code :: Digit4 |
571
+ Code :: Digit5 | Code :: Digit6 | Code :: Digit7 | Code :: Digit8 | Code :: Digit9 |
572
+ // Numpad keys
573
+ Code :: Numpad0 | Code :: Numpad1 | Code :: Numpad2 | Code :: Numpad3 | Code :: Numpad4 |
574
+ Code :: Numpad5 | Code :: Numpad6 | Code :: Numpad7 | Code :: Numpad8 | Code :: Numpad9 |
575
+ // Period
576
+ Code :: Period | Code :: NumpadDecimal |
577
+ // Enter, Backspace and ESC
578
+ Code :: Enter | Code :: Backspace | Code :: Escape
579
+ )
580
+ }
581
+
582
+ #[ allow( non_snake_case) ]
583
+ extern "C" fn keyDown ( this : & Object , _: Sel , event : id ) {
584
+ let state = unsafe { WindowState :: from_view ( this) } ;
585
+
586
+ if should_intercept_key ( event) {
587
+ // Process the key event but don't let it propagate to the parent
588
+ if let Some ( key_event) = state. process_native_key_event ( event) {
589
+ let _status = state. trigger_event ( Event :: Keyboard ( key_event) ) ;
590
+ // We don't call super implementation - this prevents the key from reaching the host
591
+ }
592
+ } else {
593
+ // Normal handling for other keys
594
+ if let Some ( key_event) = state. process_native_key_event ( event) {
595
+ let status = state. trigger_event ( Event :: Keyboard ( key_event) ) ;
596
+
597
+ if let EventStatus :: Ignored = status {
598
+ unsafe {
599
+ let superclass = msg_send ! [ this, superclass] ;
600
+ let ( ) = msg_send ! [ super ( this, superclass) , keyDown: event] ;
601
+ }
602
+ }
603
+ }
604
+ }
605
+ }
0 commit comments