gpui: Introduce PlatformKeyboardLayout
trait for human-friendly keyboard layout names (#29049)
This PR adds a new `PlatformKeyboardLayout` trait with two methods: `id(&self) -> &str` and `name(&self) -> &str`. The `id()` method returns a unique identifier for the keyboard layout, while `name()` provides a human-readable name. This distinction is especially important on Windows, where the `id` and `name` can be quite different. For example, the French layout has an `id` of `0000040C`, which is not human-readable, whereas the `name` would simply be `French`. Currently, the existing `keyboard_layout()` method returns what's essentially the same as `id()` in this new design. This PR implements the `name()` method for both Windows and macOS. On Linux, for now, `name()` still returns the same value as `id()`. Release Notes: - N/A
This commit is contained in:
parent
0454e7a22e
commit
f0ef3110d3
16 changed files with 197 additions and 68 deletions
|
@ -7,9 +7,9 @@ use super::{
|
|||
use crate::{
|
||||
Action, AnyWindowHandle, BackgroundExecutor, ClipboardEntry, ClipboardItem, ClipboardString,
|
||||
CursorStyle, ForegroundExecutor, Image, ImageFormat, Keymap, MacDispatcher, MacDisplay,
|
||||
MacWindow, Menu, MenuItem, PathPromptOptions, Platform, PlatformDisplay, PlatformTextSystem,
|
||||
PlatformWindow, Result, ScreenCaptureSource, SemanticVersion, Task, WindowAppearance,
|
||||
WindowParams, hash,
|
||||
MacWindow, Menu, MenuItem, PathPromptOptions, Platform, PlatformDisplay,
|
||||
PlatformKeyboardLayout, PlatformTextSystem, PlatformWindow, Result, ScreenCaptureSource,
|
||||
SemanticVersion, Task, WindowAppearance, WindowParams, hash,
|
||||
};
|
||||
use anyhow::{Context as _, anyhow};
|
||||
use block::ConcreteBlock;
|
||||
|
@ -825,20 +825,8 @@ impl Platform for MacPlatform {
|
|||
self.0.lock().validate_menu_command = Some(callback);
|
||||
}
|
||||
|
||||
fn keyboard_layout(&self) -> String {
|
||||
unsafe {
|
||||
let current_keyboard = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
|
||||
let input_source_id: *mut Object = TISGetInputSourceProperty(
|
||||
current_keyboard,
|
||||
kTISPropertyInputSourceID as *const c_void,
|
||||
);
|
||||
let input_source_id: *const std::os::raw::c_char =
|
||||
msg_send![input_source_id, UTF8String];
|
||||
let input_source_id = CStr::from_ptr(input_source_id).to_str().unwrap();
|
||||
|
||||
input_source_id.to_string()
|
||||
}
|
||||
fn keyboard_layout(&self) -> Box<dyn PlatformKeyboardLayout> {
|
||||
Box::new(MacKeyboardLayout::new())
|
||||
}
|
||||
|
||||
fn app_path(&self) -> Result<PathBuf> {
|
||||
|
@ -1501,6 +1489,7 @@ unsafe extern "C" {
|
|||
pub(super) fn LMGetKbdType() -> u16;
|
||||
pub(super) static kTISPropertyUnicodeKeyLayoutData: CFStringRef;
|
||||
pub(super) static kTISPropertyInputSourceID: CFStringRef;
|
||||
pub(super) static kTISPropertyLocalizedName: CFStringRef;
|
||||
}
|
||||
|
||||
mod security {
|
||||
|
@ -1590,6 +1579,45 @@ impl UTType {
|
|||
}
|
||||
}
|
||||
|
||||
struct MacKeyboardLayout {
|
||||
id: String,
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl PlatformKeyboardLayout for MacKeyboardLayout {
|
||||
fn id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
impl MacKeyboardLayout {
|
||||
fn new() -> Self {
|
||||
unsafe {
|
||||
let current_keyboard = TISCopyCurrentKeyboardLayoutInputSource();
|
||||
|
||||
let id: *mut Object = TISGetInputSourceProperty(
|
||||
current_keyboard,
|
||||
kTISPropertyInputSourceID as *const c_void,
|
||||
);
|
||||
let id: *const std::os::raw::c_char = msg_send![id, UTF8String];
|
||||
let id = CStr::from_ptr(id).to_str().unwrap().to_string();
|
||||
|
||||
let name: *mut Object = TISGetInputSourceProperty(
|
||||
current_keyboard,
|
||||
kTISPropertyLocalizedName as *const c_void,
|
||||
);
|
||||
let name: *const std::os::raw::c_char = msg_send![name, UTF8String];
|
||||
let name = CStr::from_ptr(name).to_str().unwrap().to_string();
|
||||
|
||||
Self { id, name }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::ClipboardItem;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue