@@ -1130,70 +1130,87 @@ impl TryFrom<Key> for core_graphics::event::CGKeyCode {
11301130fn get_layoutdependent_keycode ( string : & str ) -> CGKeyCode {
11311131 let mut pressed_keycode = 0 ;
11321132
1133+ let layout = current_keyboard_layout ( ) . unwrap ( ) ;
1134+
11331135 // loop through every keycode (0 - 127)
11341136 for keycode in 0 ..128 {
11351137 // no modifier
1136- if let Ok ( key_string) = keycode_to_string ( keycode, 0x100 ) {
1138+ if let Ok ( key_string) = keycode_to_string ( keycode, 0x100 , layout ) {
11371139 // debug!("{:?}", string);
11381140 if string == key_string {
11391141 pressed_keycode = keycode;
11401142 }
11411143 }
11421144
11431145 // shift modifier
1144- if let Ok ( key_string) = keycode_to_string ( keycode, 0x20102 ) {
1146+ if let Ok ( key_string) = keycode_to_string ( keycode, 0x20102 , layout ) {
11451147 // debug!("{:?}", string);
11461148 if string == key_string {
11471149 pressed_keycode = keycode;
11481150 }
11491151 }
11501152
11511153 // alt modifier
1152- // if let Some(string) = keycode_to_string(keycode, 0x80120) {
1154+ // if let Some(string) = keycode_to_string(keycode, 0x80120, layout ) {
11531155 // debug!("{:?}", string);
11541156 // }
11551157 // alt + shift modifier
1156- // if let Some(string) = keycode_to_string(keycode, 0xa0122) {
1158+ // if let Some(string) = keycode_to_string(keycode, 0xa0122, layout ) {
11571159 // debug!("{:?}", string);
11581160 // }
11591161 }
11601162
11611163 pressed_keycode
11621164}
11631165
1164- fn keycode_to_string ( keycode : u16 , modifier : u32 ) -> Result < String , String > {
1165- let mut current_keyboard = unsafe { TISCopyCurrentKeyboardInputSource ( ) } ;
1166+ fn current_keyboard_layout ( ) -> Result < CFDataRef , String > {
1167+ let current_keyboard = unsafe { TISCopyCurrentKeyboardInputSource ( ) } ;
11661168 let mut layout_data =
11671169 unsafe { TISGetInputSourceProperty ( current_keyboard, kTISPropertyUnicodeKeyLayoutData) } ;
1170+ unsafe { CFRelease ( current_keyboard. cast :: < c_void > ( ) ) } ;
1171+
1172+ if !layout_data. is_null ( ) {
1173+ return Ok ( layout_data) ;
1174+ }
1175+
1176+ debug ! (
1177+ "TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData) returned NULL"
1178+ ) ;
1179+
1180+ // TISGetInputSourceProperty returns null with some keyboard layout.
1181+ // Using TISCopyCurrentKeyboardLayoutInputSource to fix NULL return.
1182+ // See also: https://github.com/microsoft/node-native-keymap/blob/089d802efd387df4dce1f0e31898c66e28b3f67f/src/keyboard_mac.mm#L90
1183+ let current_keyboard = unsafe { TISCopyCurrentKeyboardLayoutInputSource ( ) } ;
1184+ layout_data =
1185+ unsafe { TISGetInputSourceProperty ( current_keyboard, kTISPropertyUnicodeKeyLayoutData) } ;
1186+ unsafe { CFRelease ( current_keyboard. cast :: < c_void > ( ) ) } ;
1187+
1188+ if !layout_data. is_null ( ) {
1189+ return Ok ( layout_data) ;
1190+ }
1191+
1192+ debug ! (
1193+ "TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData) returned NULL again"
1194+ ) ;
1195+ let current_keyboard = unsafe { TISCopyCurrentASCIICapableKeyboardLayoutInputSource ( ) } ;
1196+ let layout_data =
1197+ unsafe { TISGetInputSourceProperty ( current_keyboard, kTISPropertyUnicodeKeyLayoutData) } ;
1198+ unsafe { CFRelease ( current_keyboard. cast :: < c_void > ( ) ) } ;
1199+
11681200 if layout_data. is_null ( ) {
1169- debug ! (
1170- "TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData) returned NULL"
1171- ) ;
1172- unsafe { CFRelease ( current_keyboard. cast :: < c_void > ( ) ) } ;
1173-
1174- // TISGetInputSourceProperty returns null with some keyboard layout.
1175- // Using TISCopyCurrentKeyboardLayoutInputSource to fix NULL return.
1176- // See also: https://github.com/microsoft/node-native-keymap/blob/089d802efd387df4dce1f0e31898c66e28b3f67f/src/keyboard_mac.mm#L90
1177- current_keyboard = unsafe { TISCopyCurrentKeyboardLayoutInputSource ( ) } ;
1178- layout_data = unsafe {
1179- TISGetInputSourceProperty ( current_keyboard, kTISPropertyUnicodeKeyLayoutData)
1180- } ;
1181- if layout_data. is_null ( ) {
1182- debug ! (
1183- "TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData) returned NULL again"
1184- ) ;
1185- unsafe { CFRelease ( current_keyboard. cast :: < c_void > ( ) ) } ;
1186- current_keyboard = unsafe { TISCopyCurrentASCIICapableKeyboardLayoutInputSource ( ) } ;
1187- layout_data = unsafe {
1188- TISGetInputSourceProperty ( current_keyboard, kTISPropertyUnicodeKeyLayoutData)
1189- } ;
1190- debug_assert ! ( !layout_data. is_null( ) ) ;
1191- debug ! ( "Using layout of the TISCopyCurrentASCIICapableKeyboardLayoutInputSource" ) ;
1192- }
1201+ Err ( "Failed to get the current keyboard layout" . to_string ( ) )
1202+ } else {
1203+ debug ! ( "Using layout of the TISCopyCurrentASCIICapableKeyboardLayoutInputSource" ) ;
1204+ Ok ( layout_data)
11931205 }
1206+ }
11941207
1208+ fn keycode_to_string (
1209+ keycode : u16 ,
1210+ modifier : u32 ,
1211+ layout_data : CFDataRef ,
1212+ ) -> Result < String , String > {
11951213 let keyboard_layout = unsafe { CFDataGetBytePtr ( layout_data) } ;
1196-
11971214 let mut keys_down: UInt32 = 0 ;
11981215 let mut chars: [ UniChar ; 1 ] = [ 0 ] ;
11991216 let mut real_length = 0 ;
@@ -1211,7 +1228,6 @@ fn keycode_to_string(keycode: u16, modifier: u32) -> Result<String, String> {
12111228 chars. as_mut_ptr ( ) ,
12121229 )
12131230 } ;
1214- unsafe { CFRelease ( current_keyboard. cast :: < c_void > ( ) ) } ;
12151231
12161232 if status != 0 {
12171233 error ! ( "UCKeyTranslate failed with status: {status}" ) ;
0 commit comments