Merge pull request #5669 from dotCooCoo/fix/cmd-space-tool-drag-cursor

Keep drawing cursor during mid-drag Cmd+Space
This commit is contained in:
BFlat
2026-11-05 01:17:06 +07:00
committed by GitHub
3 changed files with 47 additions and 4 deletions
+10 -2
View File
@@ -401,10 +401,11 @@ fn canvas_cursor(app: &mut VectorcraftApp, ui: &Ui, view_info: vectorcraft_engin
let space = ui.input(|i| i.key_down(egui::Key::Space));
let drag = ui.data(|d| d.get_temp::<Drag>(drag_id()));
let panning = matches!(drag, Some(Drag::Pan { .. }));
let tool_holds = drag.is_some_and(drag::tool_holds);
// A tool that holds the press (Pencil, a brush, a shape) keeps Space out of the way: the drag
// began before Space went down, so Space pans nothing, and the hand would promise a pan the
// drag does not do.
let space = space && !drag.is_some_and(drag::tool_holds);
let space = space && !tool_holds;
// A zoom drag keeps its cursor when Space is pressed (with or without Shift) or Cmd is let go.
let zoom_drag = matches!(drag, Some(Drag::ZoomBox { .. } | Drag::ZoomScrub { .. }));
let zooming = zoom_drag || if space { m.command } else { app.session.tool_id() == "zoom" };
@@ -424,8 +425,15 @@ fn canvas_cursor(app: &mut VectorcraftApp, ui: &Ui, view_info: vectorcraft_engin
} else {
None
};
// Cmd borrows a selection tool only at pointer-down. Pressed during another tool's drag, it
// cannot change the owner, so do not preview the borrowed tool's cursor. A drag that started
// with a borrowed selection tool keeps its Command modifier and cursor.
let mut cursor_mods = mods(m, space);
if tool_holds && !vectorcraft_tools::catalog::is_selection_tool(app.session.tool_id()) {
cursor_mods.cmd = false;
}
// In Presentation Mode the pointer is the default one, with no tool cursor.
let tool_cursor = (app.ui.screen_mode < 3).then(|| view_cursor.or_else(|| hover_cursor(app, mods(m, space), view_info, hover_still)));
let tool_cursor = (app.ui.screen_mode < 3).then(|| view_cursor.or_else(|| hover_cursor(app, cursor_mods, view_info, hover_still)));
let cur = if let Some(c) = tool_cursor.flatten() {
let painter = ui.ctx().layer_painter(egui::LayerId::new(egui::Order::Tooltip, egui::Id::unique("tool-cursor")));
// The loaded place cursor carries the file's thumbnail.
+34
View File
@@ -5044,6 +5044,40 @@ fn space_during_a_pencil_drag_keeps_the_pencil_cursor() {
shown(&mut app, vec![space(false)]);
}
/// Cmd+Space pressed after a tool starts drawing does not borrow the Selection cursor: the
/// drawing tool still owns the drag. The Zoom cursor takes over once the button is released.
#[test]
fn cmd_space_mid_tool_drag_keeps_the_active_tool_cursor() {
use egui::{CursorIcon, Event, Modifiers};
for tool in ["pencil", "rectangle", "pen"] {
let mut app = VectorcraftApp::new(Session::new(), Default::default());
app.session.execute("file.new", &json!({"width": 400, "height": 300})).unwrap();
app.select_tool(tool);
let ctx = egui::Context::default();
frame(&mut app, &ctx, vec![]);
let c = app.canvas_rect.unwrap().center();
let shown = |app: &mut VectorcraftApp, events: Vec<Event>| {
let screen_rect = Some(egui::Rect::from_min_size(Pos2::ZERO, vec2(800.0, 600.0)));
let mut out = ctx.run_ui(egui::RawInput { screen_rect, focused: false, events, ..Default::default() }, |ui| show(app, ui));
out.textures_delta.clear();
out.platform_output.cursor_icon
};
let button = |pos, pressed| Event::PointerButton { pos, button: egui::PointerButton::Primary, pressed, modifiers: Modifiers::NONE };
let space = |pressed| Event::Key { key: egui::Key::Space, physical_key: None, pressed, repeat: false, modifiers: Modifiers::COMMAND };
let tool_cursor = shown(&mut app, vec![Event::PointerMoved(c)]);
shown(&mut app, vec![button(c, true)]);
shown(&mut app, vec![Event::PointerMoved(c + vec2(10.0, 5.0))]);
let center = app.view().unwrap().center;
assert_eq!(
shown(&mut app, vec![Event::ModifiersChanged(Modifiers::COMMAND), space(true), Event::PointerMoved(c + vec2(40.0, 20.0))]),
tool_cursor,
"{tool}: Cmd+Space must keep the active drag's cursor"
);
assert_eq!(app.view().unwrap().center, center, "{tool}: the view stays still during the drag");
assert_eq!(shown(&mut app, vec![button(c + vec2(40.0, 20.0), false)]), CursorIcon::ZoomIn, "{tool}: Zoom returns after release");
}
}
/// In a rotated view the Selection tool's marquee is drawn where the tool selects: through the
/// screen corners of the document rectangle between the press and the pointer.
#[test]
+3 -2
View File
@@ -1,6 +1,6 @@
# UI and interaction parity
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-04 · **Change:** minor (Select by Artboards add-on selects by overlap, inside or outside several artboards; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged) · **Target:** Adobe Illustrator 2026 (30.x)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-04 · **Change:** minor (Select by Artboards add-on selects by overlap, inside or outside several artboards; Cmd+Space keeps the active drawing cursor during its drag; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged)
## Feature submission evidence
@@ -30,6 +30,7 @@ Artboard Options forwards the active Artboard tool's Scale Artwork with Artboard
| Date | Change | Summary |
|---|---|---|
| 2026-11-04 | minor | Cmd+Space pressed during an active drawing drag keeps that tool's cursor; clarify that Space can move an in-progress shape or anchor. Scores and estimates unchanged. |
| 2026-11-04 | minor | Selection Tools add-on: Select by Artboards selects the objects overlapping, fully inside or fully outside several chosen artboards, from a dialog that lists, searches and multi-selects the artboards and fits one in the window on double-click (#5525, #5548, #5549, a VectorCraft addition); scores and estimates unchanged. |
| 2026-11-04 | minor | File › Export › Export As PNG… exports the active artboard, or each artboard the Artboard tool has selected (one file each), instead of always the first (#5502); a choice the caller gives is kept; scores and estimates unchanged |
| 2026-11-04 | minor | Document Tools add-on (a VectorCraft addition): Object › Plug-ins › Document Tools › Batch Trace Folder asks for a folder of images and a destination folder and traces each image into it (#4921); scores and estimates unchanged |
@@ -234,7 +235,7 @@ tools, never checked side by side) isn't captured row by row.
| Behaviour | Status | Notes |
|---|---|---|
| Space: Hand; Cmd+Space / Cmd+Alt+Space: zoom in/out; middle button pans | done | Space pressed while a tool holds the press (Pencil, a brush, a shape, a selection drag) is ignored: the cursor keeps the tool's own, and Space pans only when it is down at the press — the state before the fix showed the hand while the drag panned nothing. `space_during_a_pencil_drag_keeps_the_pencil_cursor` |
| Space: Hand; Cmd+Space / Cmd+Alt+Space: zoom in/out; middle button pans | done | Space pressed after a tool takes a drag keeps the view still and shows that tool's cursor. Shape and anchor tools may use Space to move the geometry being drawn. Cmd+Space pressed mid-drag likewise keeps the active tool cursor. Space held before a press starts a view gesture, and its view cursor returns after release. `space_during_a_pencil_drag_keeps_the_pencil_cursor`, `cmd_space_mid_tool_drag_keeps_the_active_tool_cursor` |
| Document window scroll bars along the right and bottom edges (Normal and Full Screen Mode with Menu Bar; none in Full Screen and Presentation Mode): a thumb as long as the view against the art and the artboards; dragging it scrolls, a click on the track pages, the wheel over a bar scrolls along it; in a rotated view they follow the screen's axes | partial | #2322. The span is the art and the artboards with half a window around them, not Illustrator's 227 in canvas: VectorCraft has no bounded drawing area (#2284). A track click pages rather than jumping to the click; the page size and the rotated-view behaviour are our own choice (the public documentation gives neither) |
| Cmd/Ctrl: last-used selection tool; Cmd+Alt: Group Selection inside Direct Selection | done | Cmd+Alt lends Group Selection only while Direct Selection is active (Cmd borrow from the Pen keeps Direct Selection so Alt stays copy/subtract); engine pointer regressions |
| Eyedropper styles highlighted characters only and preserves ranges across Type switches | done | Font/paint, Shift color-only, Unicode, Undo/Redo and stale-range regression tests; enabled non-neutral source or target object transparency is refused atomically; disable Transparency to sample supported attributes |