@@ -1137,70 +1137,89 @@ impl TryFrom<Key> for core_graphics::event::CGKeyCode {
11371137fn get_layoutdependent_keycode ( string : & str ) -> CGKeyCode {
11381138 let mut pressed_keycode = 0 ;
11391139
1140+ let layout = current_keyboard_layout ( ) . unwrap ( ) ;
1141+
11401142 // loop through every keycode (0 - 127)
11411143 for keycode in 0 ..128 {
11421144 // no modifier
1143- if let Ok ( key_string) = keycode_to_string ( keycode, 0x100 ) {
1145+ if let Ok ( key_string) = keycode_to_string ( keycode, 0x100 , layout ) {
11441146 // debug!("{:?}", string);
11451147 if string == key_string {
11461148 pressed_keycode = keycode;
11471149 }
11481150 }
11491151
11501152 // shift modifier
1151- if let Ok ( key_string) = keycode_to_string ( keycode, 0x20102 ) {
1153+ if let Ok ( key_string) = keycode_to_string ( keycode, 0x20102 , layout ) {
11521154 // debug!("{:?}", string);
11531155 if string == key_string {
11541156 pressed_keycode = keycode;
11551157 }
11561158 }
11571159
11581160 // alt modifier
1159- // if let Some(string) = keycode_to_string(keycode, 0x80120) {
1161+ // if let Some(string) = keycode_to_string(keycode, 0x80120, layout ) {
11601162 // debug!("{:?}", string);
11611163 // }
11621164 // alt + shift modifier
1163- // if let Some(string) = keycode_to_string(keycode, 0xa0122) {
1165+ // if let Some(string) = keycode_to_string(keycode, 0xa0122, layout ) {
11641166 // debug!("{:?}", string);
11651167 // }
11661168 }
11671169
1170+ unsafe { CFRelease ( layout. cast :: < c_void > ( ) ) } ;
1171+
11681172 pressed_keycode
11691173}
11701174
1171- fn keycode_to_string ( keycode : u16 , modifier : u32 ) -> Result < String , String > {
1172- let mut current_keyboard = unsafe { TISCopyCurrentKeyboardInputSource ( ) } ;
1175+ fn current_keyboard_layout ( ) -> Result < CFDataRef , String > {
1176+ let current_keyboard = unsafe { TISCopyCurrentKeyboardInputSource ( ) } ;
11731177 let mut layout_data =
11741178 unsafe { TISGetInputSourceProperty ( current_keyboard, kTISPropertyUnicodeKeyLayoutData) } ;
1179+ unsafe { CFRelease ( current_keyboard. cast :: < c_void > ( ) ) } ;
1180+
1181+ if !layout_data. is_null ( ) {
1182+ return Ok ( layout_data) ;
1183+ }
1184+
1185+ debug ! (
1186+ "TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData) returned NULL"
1187+ ) ;
1188+
1189+ // TISGetInputSourceProperty returns null with some keyboard layout.
1190+ // Using TISCopyCurrentKeyboardLayoutInputSource to fix NULL return.
1191+ // See also: https://github.com/microsoft/node-native-keymap/blob/089d802efd387df4dce1f0e31898c66e28b3f67f/src/keyboard_mac.mm#L90
1192+ let current_keyboard = unsafe { TISCopyCurrentKeyboardLayoutInputSource ( ) } ;
1193+ layout_data =
1194+ unsafe { TISGetInputSourceProperty ( current_keyboard, kTISPropertyUnicodeKeyLayoutData) } ;
1195+ unsafe { CFRelease ( current_keyboard. cast :: < c_void > ( ) ) } ;
1196+
1197+ if !layout_data. is_null ( ) {
1198+ return Ok ( layout_data) ;
1199+ }
1200+
1201+ debug ! (
1202+ "TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData) returned NULL again"
1203+ ) ;
1204+ let current_keyboard = unsafe { TISCopyCurrentASCIICapableKeyboardLayoutInputSource ( ) } ;
1205+ let layout_data =
1206+ unsafe { TISGetInputSourceProperty ( current_keyboard, kTISPropertyUnicodeKeyLayoutData) } ;
1207+ unsafe { CFRelease ( current_keyboard. cast :: < c_void > ( ) ) } ;
1208+
11751209 if layout_data. is_null ( ) {
1176- debug ! (
1177- "TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData) returned NULL"
1178- ) ;
1179- unsafe { CFRelease ( current_keyboard. cast :: < c_void > ( ) ) } ;
1180-
1181- // TISGetInputSourceProperty returns null with some keyboard layout.
1182- // Using TISCopyCurrentKeyboardLayoutInputSource to fix NULL return.
1183- // See also: https://github.com/microsoft/node-native-keymap/blob/089d802efd387df4dce1f0e31898c66e28b3f67f/src/keyboard_mac.mm#L90
1184- current_keyboard = unsafe { TISCopyCurrentKeyboardLayoutInputSource ( ) } ;
1185- layout_data = unsafe {
1186- TISGetInputSourceProperty ( current_keyboard, kTISPropertyUnicodeKeyLayoutData)
1187- } ;
1188- if layout_data. is_null ( ) {
1189- debug ! (
1190- "TISGetInputSourceProperty(current_keyboard, kTISPropertyUnicodeKeyLayoutData) returned NULL again"
1191- ) ;
1192- unsafe { CFRelease ( current_keyboard. cast :: < c_void > ( ) ) } ;
1193- current_keyboard = unsafe { TISCopyCurrentASCIICapableKeyboardLayoutInputSource ( ) } ;
1194- layout_data = unsafe {
1195- TISGetInputSourceProperty ( current_keyboard, kTISPropertyUnicodeKeyLayoutData)
1196- } ;
1197- debug_assert ! ( !layout_data. is_null( ) ) ;
1198- debug ! ( "Using layout of the TISCopyCurrentASCIICapableKeyboardLayoutInputSource" ) ;
1199- }
1210+ Err ( "Failed to get the current keyboard layout" . to_string ( ) )
1211+ } else {
1212+ debug ! ( "Using layout of the TISCopyCurrentASCIICapableKeyboardLayoutInputSource" ) ;
1213+ Ok ( layout_data)
12001214 }
1215+ }
12011216
1217+ fn keycode_to_string (
1218+ keycode : u16 ,
1219+ modifier : u32 ,
1220+ layout_data : CFDataRef ,
1221+ ) -> Result < String , String > {
12021222 let keyboard_layout = unsafe { CFDataGetBytePtr ( layout_data) } ;
1203-
12041223 let mut keys_down: UInt32 = 0 ;
12051224 let mut chars: [ UniChar ; 1 ] = [ 0 ] ;
12061225 let mut real_length = 0 ;
@@ -1218,7 +1237,6 @@ fn keycode_to_string(keycode: u16, modifier: u32) -> Result<String, String> {
12181237 chars. as_mut_ptr ( ) ,
12191238 )
12201239 } ;
1221- unsafe { CFRelease ( current_keyboard. cast :: < c_void > ( ) ) } ;
12221240
12231241 if status != 0 {
12241242 error ! ( "UCKeyTranslate failed with status: {status}" ) ;
0 commit comments