@@ -19,7 +19,7 @@ use crate::{
1919 WindowEvent , WindowInfo , WindowOpenOptions ,
2020} ;
2121
22- use super :: keyboard:: { from_nsstring, make_modifiers} ;
22+ use super :: keyboard:: { from_nsstring, key_code_to_code , make_modifiers} ;
2323use super :: window:: WindowState ;
2424use super :: {
2525 NSDragOperationCopy , NSDragOperationGeneric , NSDragOperationLink , NSDragOperationMove ,
@@ -220,7 +220,8 @@ unsafe fn create_view_class() -> &'static Class {
220220 add_simple_mouse_class_method ! ( class, mouseEntered, MouseEvent :: CursorEntered ) ;
221221 add_simple_mouse_class_method ! ( class, mouseExited, MouseEvent :: CursorLeft ) ;
222222
223- add_simple_keyboard_class_method ! ( class, keyDown) ;
223+ class. add_method ( sel ! ( keyDown: ) , keyDown as extern "C" fn ( & Object , Sel , id ) ) ;
224+
224225 add_simple_keyboard_class_method ! ( class, keyUp) ;
225226 add_simple_keyboard_class_method ! ( class, flagsChanged) ;
226227
@@ -554,3 +555,51 @@ extern "C" fn handle_notification(this: &Object, _cmd: Sel, notification: id) {
554555 }
555556 }
556557}
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