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
|
|
@ -297,8 +297,12 @@ impl Platform for WindowsPlatform {
|
|||
self.text_system.clone()
|
||||
}
|
||||
|
||||
fn keyboard_layout(&self) -> String {
|
||||
"unknown".into()
|
||||
fn keyboard_layout(&self) -> Box<dyn PlatformKeyboardLayout> {
|
||||
Box::new(
|
||||
KeyboardLayout::new()
|
||||
.log_err()
|
||||
.unwrap_or(KeyboardLayout::unknown()),
|
||||
)
|
||||
}
|
||||
|
||||
fn on_keyboard_layout_change(&self, _callback: Box<dyn FnMut()>) {
|
||||
|
|
@ -836,6 +840,42 @@ fn should_auto_hide_scrollbars() -> Result<bool> {
|
|||
Ok(ui_settings.AutoHideScrollBars()?)
|
||||
}
|
||||
|
||||
struct KeyboardLayout {
|
||||
id: String,
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl PlatformKeyboardLayout for KeyboardLayout {
|
||||
fn id(&self) -> &str {
|
||||
&self.id
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyboardLayout {
|
||||
fn new() -> Result<Self> {
|
||||
let mut buffer = [0u16; KL_NAMELENGTH as usize];
|
||||
unsafe { GetKeyboardLayoutNameW(&mut buffer)? };
|
||||
let id = HSTRING::from_wide(&buffer).to_string();
|
||||
let entry = windows_registry::LOCAL_MACHINE.open(format!(
|
||||
"System\\CurrentControlSet\\Control\\Keyboard Layouts\\{}",
|
||||
id
|
||||
))?;
|
||||
let name = entry.get_hstring("Layout Text")?.to_string();
|
||||
Ok(Self { id, name })
|
||||
}
|
||||
|
||||
fn unknown() -> Self {
|
||||
Self {
|
||||
id: "unknown".to_string(),
|
||||
name: "unknown".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{ClipboardItem, read_from_clipboard, write_to_clipboard};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue