keyboard.rs

 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}