1use std::ffi::{CStr, c_void};
2
3use objc::{msg_send, runtime::Object, sel, sel_impl};
4
5use crate::PlatformKeyboardLayout;
6
7use super::{
8 TISCopyCurrentKeyboardLayoutInputSource, TISGetInputSourceProperty, kTISPropertyInputSourceID,
9 kTISPropertyLocalizedName,
10};
11
12pub(crate) struct MacKeyboardLayout {
13 id: String,
14 name: String,
15}
16
17impl PlatformKeyboardLayout for MacKeyboardLayout {
18 fn id(&self) -> &str {
19 &self.id
20 }
21
22 fn name(&self) -> &str {
23 &self.name
24 }
25}
26
27impl MacKeyboardLayout {
28 pub(crate) fn new() -> Self {
29 unsafe {
30 let current_keyboard = TISCopyCurrentKeyboardLayoutInputSource();
31
32 let id: *mut Object = TISGetInputSourceProperty(
33 current_keyboard,
34 kTISPropertyInputSourceID as *const c_void,
35 );
36 let id: *const std::os::raw::c_char = msg_send![id, UTF8String];
37 let id = CStr::from_ptr(id).to_str().unwrap().to_string();
38
39 let name: *mut Object = TISGetInputSourceProperty(
40 current_keyboard,
41 kTISPropertyLocalizedName as *const c_void,
42 );
43 let name: *const std::os::raw::c_char = msg_send![name, UTF8String];
44 let name = CStr::from_ptr(name).to_str().unwrap().to_string();
45
46 Self { id, name }
47 }
48 }
49}