From da750b15d3ea1dddf92d129bfd17e7c4c9f1712d Mon Sep 17 00:00:00 2001 From: clover caruso Date: Fri, 2 Oct 2026 13:00:12 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20the=20web=20build=20on=20a=20Mac=20shows?= =?UTF-8?q?=20chords=20as=20=E2=8C=98=20and=20=E2=8C=A5,=20the=20keys=20th?= =?UTF-8?q?at=20run=20them?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A Mac's browser takes the PC's chords with Command for Ctrl, but menus, the palette, tag lists and Keyboard options labelled them Ctrl+. They now read as a Mac's (⌥⌘N), and the symbol face that draws ⌘⌥⇧ is fetched on a Mac at start. Assisted-by: claude-opus-5.5 --- arc/platforms.md | 2 +- crates/snowbound/src/commands.rs | 12 +++++++++++- crates/snowbound/src/keys.rs | 17 ++++++++++------- crates/snowbound/src/tags.rs | 3 +-- crates/snowbound/src/web.rs | 9 +++++++++ 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/arc/platforms.md b/arc/platforms.md index 8bfebba569b3d1f58e009b10b63c4d02be1c2504..fbc4f26f3ab0e80c58a99eb76cd28a346ece5e1b 100644 --- a/arc/platforms.md +++ b/arc/platforms.md @@ -173,7 +173,7 @@ keyboard, the toolbar and the macOS menu bar all run commands from it. page has written the file and found nothing else wrote it since it was read; until then it is uncertain, as one whose answer was lost, and it goes again on top of another app's write. The sync popup says the folder isn't locked. -- Menus are the kit's own, as on Linux, with the PC's chords and ⌘ for Ctrl on a Mac; the +- Menus are the kit's own, as on Linux, with the PC's chords, which a Mac takes and shows with ⌘ for Ctrl and ⌥ for Alt; the browser keeps its own window and tab chords, so New Page and New Section add Alt to theirs. Dialogs are the browser's; Insert, and Open without a folder to give, ask for files to copy in; printing downloads the PDF. Servers and diff --git a/crates/snowbound/src/commands.rs b/crates/snowbound/src/commands.rs index bda20fec96c755a0e31523cb214bdf28ddb5f81a..48281d2feadc27b0ec405d859bf1fcbcc4f93ed8 100644 --- a/crates/snowbound/src/commands.rs +++ b/crates/snowbound/src/commands.rs @@ -1038,13 +1038,23 @@ impl Chord { } } +/// The platform whose way chords read in here: a Mac's in a browser on one, where ⌘ takes +/// the PC's Ctrl chords. +pub fn shown() -> Platform { + #[cfg(target_arch = "wasm32")] + if crate::platform::mac() { + return Platform::MacOs; + } + Platform::CURRENT +} + /// The chord a menu or hint shows for `id` here, empty where it has none. pub fn shortcut(id: Id) -> String { let chord = match id { Id::Tag(place) => tag_chord(place), id => chords(id).first().copied(), }; - chord.map_or_else(String::new, |chord| chord.label(Platform::CURRENT)) + chord.map_or_else(String::new, |chord| chord.label(shown())) } impl State { diff --git a/crates/snowbound/src/keys.rs b/crates/snowbound/src/keys.rs index e167d7eb0232484c4ddf8f35b8d4827ea58dfc7c..cf32509b99ba37b1e60d48d6399785559685e19e 100644 --- a/crates/snowbound/src/keys.rs +++ b/crates/snowbound/src/keys.rs @@ -72,7 +72,7 @@ fn group(id: Command) -> &'static str { } fn label(chord: Chord) -> String { - chord.label(Platform::CURRENT) + chord.label(commands::shown()) } fn title(id: Command) -> String { @@ -334,16 +334,19 @@ impl Keyboard { fn status(&mut self, ui: &mut Ui) { let theme = ui.theme.clone(); let row = theme.font_size * 2.0; - let mac = Platform::CURRENT == Platform::MacOs; + // A Mac's browser takes the PC's chords, Option for Alt. + let modifiers = match (Platform::CURRENT, commands::shown()) { + (Platform::MacOs, _) => "⌘ or ⌃", + (_, Platform::MacOs) => "⌘ or ⌥", + _ => "Ctrl or Alt", + }; let text = match &self.recording { None => "Click a shortcut to change it".to_owned(), Some(recording) => match recording.refused { None => format!("Type a shortcut for {}", title(recording.command)), - Some(Refusal::Unusable(chord, Unusable::Typing)) => format!( - "{} types text. Include {}", - label(chord), - if mac { "⌘ or ⌃" } else { "Ctrl or Alt" } - ), + Some(Refusal::Unusable(chord, Unusable::Typing)) => { + format!("{} types text. Include {}", label(chord), modifiers) + } Some(Refusal::Unusable(chord, Unusable::Editing)) => { format!("{} moves through text. Type another", label(chord)) } diff --git a/crates/snowbound/src/tags.rs b/crates/snowbound/src/tags.rs index d8e634c704b6a64a9c7d66d4495f8c13a2c88232..287c23c41ec8f0afc8484465fe5ffb7a7e7b8e54 100644 --- a/crates/snowbound/src/tags.rs +++ b/crates/snowbound/src/tags.rs @@ -6,7 +6,6 @@ use accesskit::Role; use canvas::editor::NoteTag; use canvas::gpu::{colorref, tag_sources}; use canvas::outline::{TagIcon, symbol_name}; -use draw::edit::Platform; use notebook::sidecar::art_name; use ui::{Anchor, Axis, Flags, Id, Spec, Ui, children, fill, fit, px}; use winit::keyboard::NamedKey; @@ -458,7 +457,7 @@ impl State { None => icon(ui, "icon", Some(crate::art::FONT_COLOR), theme.text), } let text = match commands::tag_chord(place) { - Some(chord) => format!("{} ({})", tag.label, chord.label(Platform::CURRENT)), + Some(chord) => format!("{} ({})", tag.label, chord.label(commands::shown())), None => tag.label.clone(), }; label(ui, "label", &text, tag); diff --git a/crates/snowbound/src/web.rs b/crates/snowbound/src/web.rs index 2b19d26c60c183dcec32f5aa6db14ef40b5d68e1..a34cc7abda43caf72f320b9d2a9da542644d3d0b 100644 --- a/crates/snowbound/src/web.rs +++ b/crates/snowbound/src/web.rs @@ -203,6 +203,11 @@ thread_local! { static LANGUAGE: RefCell = const { RefCell::new(String::new()) }; } +/// Whether the browser runs on a Mac, where Command takes the editing chords. +pub fn mac() -> bool { + MAC.get() +} + /// The page's canvas, which frames are drawn into. pub fn canvas() -> web_sys::HtmlCanvasElement { use wasm_bindgen::JsCast; @@ -920,6 +925,10 @@ pub async fn start( } STATE.with_borrow_mut(|slot| *slot = Some(state)); attach(module); + // A Mac's chords read ⌘⌥⇧, which only a fallback face draws. + if MAC.get() { + fetch_fallbacks("⌘⌥⇧"); + } request_frame(); Ok(()) } -- 2.54.0