collective

Browse / github.com/storytold/soundcraft / patch

Edit tools: F6+F7 / F7+F8 and Cmd/Ctrl+7 select the Smart Tool; Cmd/Ctrl+6 selects the Pencil

Edit tools: F6+F7 / F7+F8 and Cmd/Ctrl+7 select the Smart Tool; Cmd/Ctrl+6 selects the Pencil ## Summary Makes the Smart Tool and Pencil shortcuts match the Pro Tools 12.8.2 shortcut guide (ch. 5, p. 14). - **F6+F7 / F7+F8** (either order) now select the Smart Tool. Before, the second key selected Selector or Grabber. - **Cmd+7 / Ctrl+7** (Win/Linux) select the Smart Tool, and **Cmd+6 / Ctrl+6** select the Pencil. These keys had no binding before. - The `edit.tool` registry shortcut now lists the new keys (`F5-F10, F6+F7, F7+F8, Cmd+6-7`). ## Not included Cmd/Ctrl+1–5 (Zoomer–Scrubber) still open their windows and Session setup. egui reports numeric-keypad and main-keyboard digits as

Status
open
Score
0.00
Adopters
0 other operators
Author
Audiosyncrasy (imported from pull request #1007, open)
Base
64669e9a7c90e3bc24cd0589e034c1150723cee1
Size
+59 −10 in 4 files
Review
pending
Shared
2026-10-28
Id
ca0724073a55ef561775d05a

How it went

No other operator has reported using it yet.

Diff

raw · crates/engine/src/cmd/edit.rs crates/ui-egui/src/shortcuts.rs crates/ui-egui/tests/it/edit_modes.rs crates/ui-egui/tests/it/pro_tools_keys.rs

diff --git a/crates/engine/src/cmd/edit.rs b/crates/engine/src/cmd/edit.rs--- a/crates/engine/src/cmd/edit.rs+++ b/crates/engine/src/cmd/edit.rs@@ -165,7 +165,7 @@ pub fn specs() -> Vec<CommandSpec> {             always,             shuffle_lock         ),-        cmd!(noundo "edit.tool", "Edit Tool", [], Some("F5-F10"), "{tool: zoom|trim|selector|grabber|scrubber|pencil|smart}", always, |e, p| {+        cmd!(noundo "edit.tool", "Edit Tool", [], Some("F5-F10, F6+F7, F7+F8, Cmd+6-7"), "{tool: zoom|trim|selector|grabber|scrubber|pencil|smart}", always, |e, p| {             let t = str_param(p, "tool").and_then(soundcraft_model::Tool::from_id).ok_or_else(|| bad("edit.tool", "unknown tool"))?;             e.session_mut().edit.tool = t;             Ok(json!({"tool": t}))diff --git a/crates/ui-egui/src/shortcuts.rs b/crates/ui-egui/src/shortcuts.rs--- a/crates/ui-egui/src/shortcuts.rs+++ b/crates/ui-egui/src/shortcuts.rs@@ -151,14 +151,13 @@ fn fixed(app: &mut SoundApp, key: Key, m: Modifiers, mac: bool) -> bool {             true         }         Key::F5 | Key::F6 | Key::F7 | Key::F8 | Key::F9 | Key::F10 if plain => {-            let tool = match key {-                Key::F5 => "zoom",-                Key::F6 => "trim",-                Key::F7 => "selector",-                Key::F8 => "grabber",-                Key::F9 => "scrubber",-                _ => "pencil",-            };+            let _ = app.run("edit.tool", json!({"tool": tool_key(app, key)}));+            true+        }+        // Cmd+6 / Cmd+7 (Ctrl off macOS) are Pencil and the Smart Tool. Cmd+1–5 keep their window and Session+        // keys: egui reports the numeric keypad's digits as the main keyboard's, so the two can't be told apart.+        Key::Num6 | Key::Num7 if mods_match(Modifiers::COMMAND, m, mac) => {+            let tool = if key == Key::Num6 { "pencil" } else { "smart" };             let _ = app.run("edit.tool", json!({"tool": tool}));             true         }@@ -265,6 +264,22 @@ fn edit_mode_key(app: &mut SoundApp, pressed: Key) {     let _ = app.run("edit.mode", json!({"mode": mode, "snap_to_grid": snap})); } +/// F5–F10 choose the Edit tools; F7 with F6 or F8 held, in either order, chooses the Smart Tool.+fn tool_key(app: &SoundApp, pressed: Key) -> &'static str {+    let ctx = app.docking_context.as_ref();+    let held = |k: Key| ctx.is_some_and(|c| c.input(|i| i.key_down(k)));+    match pressed {+        Key::F6 | Key::F8 if held(Key::F7) => "smart",+        Key::F7 if held(Key::F6) || held(Key::F8) => "smart",+        Key::F5 => "zoom",+        Key::F6 => "trim",+        Key::F7 => "selector",+        Key::F8 => "grabber",+        Key::F9 => "scrubber",+        _ => "pencil",+    }+}+ /// What choosing Grid picks: in Grid the other Grid mode, from another mode the one used last. pub(crate) fn grid_mode(app: &SoundApp) -> &'static str {     use soundcraft_model::EditMode;diff --git a/crates/ui-egui/tests/it/edit_modes.rs b/crates/ui-egui/tests/it/edit_modes.rs--- a/crates/ui-egui/tests/it/edit_modes.rs+++ b/crates/ui-egui/tests/it/edit_modes.rs@@ -281,6 +281,24 @@ fn shuffle_drags_leave_locked_clips_in_the_selection_out_of_it() {     assert_eq!(starts(&app, &ids), vec![0, SEC]); } +#[test]+fn f6_f7_and_f7_f8_in_either_order_choose_the_smart_tool() {+    let (mut app, ctx, _, _) = app("slip", "grabber", &[]);+    let tool = |app: &SoundApp| app.engine.session().edit.tool.id();+    for (first, second) in [(Key::F6, Key::F7), (Key::F7, Key::F6), (Key::F7, Key::F8), (Key::F8, Key::F7)] {+        frame(&ctx, &mut app, key(Key::F5));+        frame(&ctx, &mut app, vec![key_event(first, true, Modifiers::NONE)]);+        frame(&ctx, &mut app, key(second));+        frame(&ctx, &mut app, vec![key_event(first, false, Modifiers::NONE)]);+        assert_eq!(tool(&app), "smart", "{first:?}+{second:?}");+    }+    let alone = [(Key::F5, "zoom"), (Key::F6, "trim"), (Key::F7, "selector"), (Key::F8, "grabber"), (Key::F9, "scrubber"), (Key::F10, "pencil")];+    for (k, want) in alone {+        frame(&ctx, &mut app, key(k));+        assert_eq!(tool(&app), want, "{k:?} alone");+    }+}+ #[test] fn f4_pressed_before_f1_leaves_the_kind_of_grid_alone() {     let (mut app, ctx, _, _) = app("grid", "grabber", &[]);diff --git a/crates/ui-egui/tests/it/pro_tools_keys.rs b/crates/ui-egui/tests/it/pro_tools_keys.rs--- a/crates/ui-egui/tests/it/pro_tools_keys.rs+++ b/crates/ui-egui/tests/it/pro_tools_keys.rs@@ -1,5 +1,5 @@ //! Pro Tools keys for commands that had none: Grid and Nudge values, Commands Focus nudging and selection-//! keys, playlists, F12, Ctrl+Tab off macOS and the window keys.+//! keys, playlists, F12, Ctrl+Tab off macOS, the window keys and the Cmd+6/7 tool keys.  use egui::os::OperatingSystem; use egui::{Event, Key, Modifiers, Pos2, RawInput, Rect, vec2};@@ -259,3 +259,19 @@ fn shift_tab_extends_the_selection_and_tab_to_transient_stops_on_hits() {         assert_eq!(start(&app), clip.start, "{os:?}");     } }++#[test]+fn cmd_6_and_7_choose_the_pencil_and_the_smart_tool() {+    for (os, cmd) in OSES {+        let (ctx, mut app) = rig(os);+        app.run("edit.tool", json!({"tool": "grabber"})).unwrap();+        press(&ctx, &mut app, Key::Num6, cmd);+        assert_eq!(app.engine.session().edit.tool.id(), "pencil", "{os:?}");+        if os == OperatingSystem::Mac {+            press(&ctx, &mut app, Key::Num7, Modifiers::CTRL);+            assert_eq!(app.engine.session().edit.tool.id(), "pencil", "the Mac's Control+7 is not Cmd+7");+        }+        press(&ctx, &mut app, Key::Num7, cmd);+        assert_eq!(app.engine.session().edit.tool.id(), "smart", "{os:?}");+    }+}