Complete desktop parity and security audit (#42)
This commit is contained in:
@@ -2,6 +2,32 @@
|
||||
|
||||
use iced::keyboard::{self, key::Named};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum DesktopPlatform {
|
||||
MacOs,
|
||||
Linux,
|
||||
Windows,
|
||||
}
|
||||
|
||||
impl DesktopPlatform {
|
||||
pub const fn current() -> Self {
|
||||
if cfg!(target_os = "macos") {
|
||||
Self::MacOs
|
||||
} else if cfg!(target_os = "windows") {
|
||||
Self::Windows
|
||||
} else {
|
||||
Self::Linux
|
||||
}
|
||||
}
|
||||
|
||||
const fn primary_modifier(self) -> keyboard::Modifiers {
|
||||
match self {
|
||||
Self::MacOs => keyboard::Modifiers::LOGO,
|
||||
Self::Linux | Self::Windows => keyboard::Modifiers::CTRL,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub enum UiAction {
|
||||
About,
|
||||
@@ -314,8 +340,12 @@ pub fn actions_in(group: MenuGroup) -> impl Iterator<Item = &'static ActionSpec>
|
||||
}
|
||||
|
||||
pub fn shortcut_label(action: UiAction) -> Option<String> {
|
||||
shortcut_label_for(action, DesktopPlatform::current())
|
||||
}
|
||||
|
||||
pub fn shortcut_label_for(action: UiAction, platform: DesktopPlatform) -> Option<String> {
|
||||
let shortcut = spec_for(action).shortcut?;
|
||||
if cfg!(target_os = "macos") {
|
||||
if platform == DesktopPlatform::MacOs {
|
||||
Some(shortcut.to_owned())
|
||||
} else {
|
||||
Some(shortcut.replace('⇧', "Shift+").replace('⌘', "Ctrl+"))
|
||||
@@ -685,13 +715,21 @@ pub const fn aliases(action: UiAction) -> &'static [&'static str] {
|
||||
}
|
||||
|
||||
pub fn shortcut_action(key: &keyboard::Key, modifiers: keyboard::Modifiers) -> Option<UiAction> {
|
||||
shortcut_action_for(DesktopPlatform::current(), key, modifiers)
|
||||
}
|
||||
|
||||
pub fn shortcut_action_for(
|
||||
platform: DesktopPlatform,
|
||||
key: &keyboard::Key,
|
||||
modifiers: keyboard::Modifiers,
|
||||
) -> Option<UiAction> {
|
||||
if key.as_ref() == keyboard::Key::Named(Named::Tab) && modifiers.is_empty() {
|
||||
return Some(UiAction::TogglePaneFocus);
|
||||
}
|
||||
if key.as_ref() == keyboard::Key::Named(Named::F1) {
|
||||
return Some(UiAction::Help);
|
||||
}
|
||||
if !modifiers.command() {
|
||||
if !modifiers.contains(platform.primary_modifier()) {
|
||||
return None;
|
||||
}
|
||||
match key.as_ref() {
|
||||
@@ -940,36 +978,62 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn conventional_shortcuts_resolve_to_the_registered_actions() {
|
||||
let primary = keyboard::Modifiers::COMMAND;
|
||||
for (key, expected) in [
|
||||
("o", UiAction::OpenFolder),
|
||||
("s", UiAction::Save),
|
||||
("f", UiAction::Find),
|
||||
("k", UiAction::CommandPalette),
|
||||
("n", UiAction::NewEntry),
|
||||
("w", UiAction::CloseWindow),
|
||||
("q", UiAction::Quit),
|
||||
("x", UiAction::Cut),
|
||||
("c", UiAction::CopyField),
|
||||
("v", UiAction::Paste),
|
||||
(",", UiAction::Settings),
|
||||
fn conventional_shortcuts_resolve_on_every_supported_platform() {
|
||||
for (platform, primary, label) in [
|
||||
(DesktopPlatform::MacOs, keyboard::Modifiers::LOGO, "⌘S"),
|
||||
(DesktopPlatform::Linux, keyboard::Modifiers::CTRL, "Ctrl+S"),
|
||||
(
|
||||
DesktopPlatform::Windows,
|
||||
keyboard::Modifiers::CTRL,
|
||||
"Ctrl+S",
|
||||
),
|
||||
] {
|
||||
assert_eq!(
|
||||
shortcut_action(&keyboard::Key::Character(key.into()), primary),
|
||||
Some(expected)
|
||||
shortcut_label_for(UiAction::Save, platform).as_deref(),
|
||||
Some(label)
|
||||
);
|
||||
for (key, expected) in [
|
||||
("o", UiAction::OpenFolder),
|
||||
("s", UiAction::Save),
|
||||
("f", UiAction::Find),
|
||||
("k", UiAction::CommandPalette),
|
||||
("n", UiAction::NewEntry),
|
||||
("w", UiAction::CloseWindow),
|
||||
("q", UiAction::Quit),
|
||||
("x", UiAction::Cut),
|
||||
("c", UiAction::CopyField),
|
||||
("v", UiAction::Paste),
|
||||
(",", UiAction::Settings),
|
||||
] {
|
||||
assert_eq!(
|
||||
shortcut_action_for(platform, &keyboard::Key::Character(key.into()), primary,),
|
||||
Some(expected)
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
shortcut_action_for(
|
||||
platform,
|
||||
&keyboard::Key::Character("f".into()),
|
||||
primary | keyboard::Modifiers::SHIFT,
|
||||
),
|
||||
Some(UiAction::SearchContents)
|
||||
);
|
||||
assert_eq!(
|
||||
shortcut_action_for(
|
||||
platform,
|
||||
&keyboard::Key::Named(Named::F1),
|
||||
keyboard::Modifiers::NONE,
|
||||
),
|
||||
Some(UiAction::Help)
|
||||
);
|
||||
}
|
||||
assert_eq!(
|
||||
shortcut_action(
|
||||
&keyboard::Key::Character("f".into()),
|
||||
primary | keyboard::Modifiers::SHIFT,
|
||||
shortcut_action_for(
|
||||
DesktopPlatform::MacOs,
|
||||
&keyboard::Key::Character("s".into()),
|
||||
keyboard::Modifiers::CTRL,
|
||||
),
|
||||
Some(UiAction::SearchContents)
|
||||
);
|
||||
assert_eq!(
|
||||
shortcut_action(&keyboard::Key::Named(Named::F1), keyboard::Modifiers::NONE),
|
||||
Some(UiAction::Help)
|
||||
None
|
||||
);
|
||||
assert_eq!(shortcut_label(UiAction::Help).as_deref(), Some("F1"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user