From f9d50abbad9bd62225075e9ec9b7efd6af72f2c2 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Sat, 7 Nov 2026 11:12:02 +0700 Subject: [PATCH] Pick select: say what it does in our own words --- crates/ui-egui/src/layers_keyboard_tests.rs | 9 +++------ crates/ui-egui/src/shortcuts.rs | 3 +-- docs/ui-parity.md | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/crates/ui-egui/src/layers_keyboard_tests.rs b/crates/ui-egui/src/layers_keyboard_tests.rs index 6fd06bba7..9be301f49 100644 --- a/crates/ui-egui/src/layers_keyboard_tests.rs +++ b/crates/ui-egui/src/layers_keyboard_tests.rs @@ -223,12 +223,9 @@ impl crate::FigApp { } } -/// Pick select (#1836): "Press Tab or ⌥Option Space / Control Space again to switch to pick -/// select." "Once activated, a pink outline is placed on a selected objects on the canvas, or any -/// node if nothing is selected." "Use Tab to move between parent objects on the canvas, -/// Return/Enter and ⇧Shift Return / Enter to move between parent and child layers. Press Space to -/// make you selection. Press Esc or click anywhere on the canvas to exit selection mode." -/// (Accessibility at Figma). +/// Pick select (#1836): Tab turns the selection box into a pink outline on the selected layer (or +/// the page's top layer); Tab walks siblings, Enter and Shift+Enter go down and up the tree, Space +/// selects, and Esc or a click on the canvas leaves it. #[test] fn tab_switches_the_selection_box_to_pick_select() { let (mut u, a, b) = setup(); diff --git a/crates/ui-egui/src/shortcuts.rs b/crates/ui-egui/src/shortcuts.rs index e32be309b..26bdb60d2 100644 --- a/crates/ui-egui/src/shortcuts.rs +++ b/crates/ui-egui/src/shortcuts.rs @@ -523,8 +523,7 @@ fn key_event(app: &mut FigApp, key: Key, physical: Option, m: Modifiers, re /// marquee (Shift toggles, Cmd/Ctrl takes nested layers), Escape drops it. pub(crate) fn key_box(app: &mut FigApp, key: Key, m: Modifiers) -> bool { let Some(mut b) = app.ui.key_box else { return false }; - // "Press Tab ... to switch to pick select" (Accessibility at Figma): the box becomes the - // pick cursor. + // Tab: the box becomes the pick cursor. if key == Key::Tab && m.is_none() { app.ui.key_box = None; app.start_pick_select(); diff --git a/docs/ui-parity.md b/docs/ui-parity.md index 4bda896d8..d08ed4c60 100644 --- a/docs/ui-parity.md +++ b/docs/ui-parity.md @@ -189,7 +189,7 @@ in the table. `crates/ui-egui/src/shortcut_keys_tests.rs` drives the keys a look | 2026-11-06 | patch | M7, #2032: closing a tab whose file has unsaved changes, by its X, a middle click, File ▸ Close tab or its shortcut, only showed a toast ("save first, or close again with Alt to discard") and left the tab open, so closing seemed not to work. It now asks the unsaved-changes question the window asks (`windows::TabClose`): Don't Save closes the tab, Cancel or Escape keeps it, Save saves the file and then closes it (a file without a path, or saved as .fig, asks where with Save as first and stays open if that is cancelled); Alt+close still drops the changes at once, and `file.close`'s `dialog.unsaved` request asks too. The three toasts left the catalogs. Tests: `titlebar_tests::closing_a_tab_with_unsaved_changes_asks`, `titlebar_tests::save_in_the_tab_question_saves_then_closes`. Reordering tabs by dragging, the issue's other half, landed on 2026-10-19 (`dragging_a_tab_along_the_bar_reorders_it_without_detaching`) | | 2026-11-02 | patch | M6, #1839: with a shape or frame tool chosen and nothing selected, the arrows show a placement crosshair in the middle of the view and move it by the nudge amounts (`tool.crosshair`), Enter places the object there (`tool.place`), Escape or a tool change takes it away; the canvas draws the crosshair and `ui.inspect` reports it (`tool.crosshair`), the Keyboard shortcuts panel lists the gesture ("Use the arrow keys to activate the crosshair cursor...", Accessibility at Figma). The board Shapes tool places on it too (its 160 px shape centred, as the tool centres a press), and the view pans by the overshoot when the crosshair is nudged past its edge. Tests: `place_crosshair_tests`, `shortcut_keys_tests::arrows_show_and_move_the_placement_crosshair_with_a_shape_tool`. | | 2026-11-05 | minor | M4, #1830: a paragraph's base direction can be forced (`TextDirection`: Auto, Ltr, Rtl on `ParaList`): Text ▸ Text direction ▸ Auto / Left to right / Right to left (`text.directionAuto` / `Ltr` / `Rtl`) and `text.direction {direction, ids?}` set the edited paragraphs while editing, else the layer's; `node.set textDirection`; the Type settings control once a right-to-left script is in the text; inspect `textDirection` / `lineDirections`; CSS `direction`; `.fig` lines' `sourceDirectionality` in and out. Layout gives each paragraph its base level (`Bidi::of` runs the algorithm per paragraph, as it starts over at each). Before, direction came from the letters only ("controls are available to override text direction per paragraph", Add right-to-left text). Tests: `text_behaviour_tests::text_direction_is_forced_per_paragraph`, `fig::text_direction_tests::a_lines_source_directionality_is_its_paragraphs_direction_both_ways`. | -| 2026-11-02 | minor | M1, #1836: pick select. Tab while the keyboard selection box shows, or Alt/Ctrl+Space again, puts a pink outline on the first selected layer (the page's top layer with nothing selected); Tab and Shift+Tab move it between sibling layers as the Layers panel lists them, Enter into a frame's top child, Shift+Enter out to the parent (never the page), Space selects the layer under it, Escape or a press on the canvas ends it; the chord again while the pick cursor shows brings the box back ("Press Tab or ⌥Option Space / Control Space again to switch to pick select", "a pink outline is placed on a selected objects on the canvas, or any node if nothing is selected", "Use Tab to move between parent objects on the canvas, Return/Enter and ⇧Shift Return / Enter to move between parent and child layers. Press Space to make you selection", Accessibility at Figma). The control channel's `ui.key` sends the box's and the pick cursor's keys to them too. One documented row more (135, 134 bound); four gesture rows. Tests: `layers_keyboard_tests::tab_switches_the_selection_box_to_pick_select`. | +| 2026-11-02 | minor | M1, #1836: pick select. Tab while the keyboard selection box shows, or Alt/Ctrl+Space again, puts a pink outline on the first selected layer (the page's top layer with nothing selected); Tab and Shift+Tab move it between sibling layers as the Layers panel lists them, Enter into a frame's top child, Shift+Enter out to the parent (never the page), Space selects the layer under it, Escape or a press on the canvas ends it; the chord again while the pick cursor shows brings the box back (Accessibility at Figma). The control channel's `ui.key` sends the box's and the pick cursor's keys to them too. One documented row more (135, 134 bound); four gesture rows. Tests: `layers_keyboard_tests::tab_switches_the_selection_box_to_pick_select`. | | 2026-11-05 | patch | M1, #2003: the Design panel's boolean operation menu leads Union, Subtract, Intersect and Exclude with original icons drawn in code (two offset squares, the result filled at reduced alpha). Numbers unchanged. | | 2026-11-05 | patch | M1, #1758: a mouse's side buttons (4 and 5) pan the canvas as the middle button does, the pan ending on release over the canvas or off it; the grab cursor shows while they're held. | | 2026-11-04 | patch | M1, #1852: a press on one of the open gradient's handles or stops on the canvas is the colour picker's own, not a press outside it (Figma keeps the picker and the handles up while a handle or stop is dragged; the stops are made to be dragged: "You can click and drag a stop to change its placement on the gradient", Use gradients as a fill or stroke). The canvas took the press and began the drag, then the picker, drawn later in the same frame, saw a press outside its card and closed, committing the drag's interaction at once; the handles vanished with it and the drag went on without an undo step of its own. Now the picker stays while a gradient handle or stop drags, and the drag is one undo step; a press elsewhere on the canvas still closes it. A handle drag whose button goes up off the canvas (over a panel or the picker) ends there too, instead of waiting, uncommitted, to move the handle to the next press on the canvas. Tests: `colorpicker_selection_tests::dragging_a_gradient_handle_on_the_canvas_keeps_the_picker_open`, `colorpicker_selection_tests::a_gradient_drag_released_off_the_canvas_ends_there`. |