mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 20:34:22 +00:00
Merge pull request #6702 from danngreen/fix/mac-cursor-after-move
macOS: the canvas cursor stays after the pointer moves (#6362)
This commit is contained in:
@@ -35,7 +35,6 @@ trait Backend {
|
||||
fn suspend(&mut self, window: &Self::Window);
|
||||
fn restore(&mut self, window: &Self::Window);
|
||||
fn build(&mut self, request: &Request) -> Option<Self::Cursor>;
|
||||
fn current(&self) -> Option<Self::Cursor>;
|
||||
fn set(&mut self, cursor: &Self::Cursor);
|
||||
}
|
||||
|
||||
@@ -73,9 +72,10 @@ impl<B: Backend> State<B> {
|
||||
&& *key == request.key
|
||||
&& *owned == window
|
||||
{
|
||||
if self.backend.current().as_ref() != Some(cursor) {
|
||||
self.backend.set(cursor);
|
||||
}
|
||||
// AppKit can show the system arrow when the pointer moves while
|
||||
// `NSCursor.currentCursor` (the app's last set cursor) still reads as ours, so a
|
||||
// comparison would keep the arrow. Setting the cursor again costs nothing.
|
||||
self.backend.set(cursor);
|
||||
return;
|
||||
}
|
||||
self.release();
|
||||
@@ -135,9 +135,6 @@ impl Backend for AppKit {
|
||||
fn build(&mut self, request: &Request) -> Option<Self::Cursor> {
|
||||
build(&request.bitmap)
|
||||
}
|
||||
fn current(&self) -> Option<Self::Cursor> {
|
||||
Some(NSCursor::currentCursor())
|
||||
}
|
||||
fn set(&mut self, cursor: &Self::Cursor) {
|
||||
cursor.set();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ use std::cell::Cell;
|
||||
struct Fake {
|
||||
window: Option<u8>,
|
||||
suspended: Vec<u8>,
|
||||
current: Option<Key>,
|
||||
sets: usize,
|
||||
builds: usize,
|
||||
restores: Vec<u8>,
|
||||
@@ -27,17 +26,12 @@ impl Backend for Fake {
|
||||
fn restore(&mut self, w: &u8) {
|
||||
self.suspended.retain(|v| v != w);
|
||||
self.restores.push(*w);
|
||||
self.current = None;
|
||||
}
|
||||
fn build(&mut self, r: &Request) -> Option<Key> {
|
||||
self.builds += 1;
|
||||
(!self.fail).then_some(r.key)
|
||||
}
|
||||
fn current(&self) -> Option<Key> {
|
||||
self.current
|
||||
}
|
||||
fn set(&mut self, cursor: &Key) {
|
||||
self.current = Some(*cursor);
|
||||
fn set(&mut self, _: &Key) {
|
||||
self.sets += 1;
|
||||
}
|
||||
}
|
||||
@@ -66,19 +60,16 @@ fn deliver(state: &mut State<Fake>, request: Option<Request>) {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mac_cursor_ownership_deduplicates_reasserts_and_restores() {
|
||||
fn mac_cursor_ownership_reasserts_every_pass_and_restores() {
|
||||
let req = request(1.0);
|
||||
let mut state = fake_state();
|
||||
deliver(&mut state, Some(req.clone()));
|
||||
assert_eq!(state.backend.suspended, [1]);
|
||||
assert_eq!((state.backend.builds, state.backend.sets), (1, 1));
|
||||
// The pointer moves and AppKit shows the system arrow, but the app's current cursor
|
||||
// still reads as ours. The next pass sets it again without rebuilding or re-suspending.
|
||||
deliver(&mut state, Some(req.clone()));
|
||||
assert_eq!(state.backend.sets, 1);
|
||||
// Simulate a platform fallback replacing the cursor after finalization. The next pass
|
||||
// reasserts; this proves the protocol, not AppKit timing or absence of transient flicker.
|
||||
state.backend.current = None;
|
||||
deliver(&mut state, Some(req.clone()));
|
||||
assert_eq!(state.backend.sets, 2);
|
||||
assert_eq!((state.backend.builds, state.backend.sets, state.backend.suspended.len()), (1, 2, 1));
|
||||
deliver(&mut state, None);
|
||||
assert_eq!(state.backend.restores, [1]);
|
||||
deliver(&mut state, Some(req.clone()));
|
||||
|
||||
File diff suppressed because one or more lines are too long
+3
-2
@@ -1,6 +1,6 @@
|
||||
# UI and interaction parity
|
||||
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-12 · **Change:** minor (Remove Background in the Contextual Task Bar, Properties › Quick Actions and the Control bar; previously minor: Ruler origin: the corner drag snaps as a drawn point does; previously minor: Live Paint Bucket fills faces crossed in one drag (#6373); previously: #6404: transform-aware Eyedropper character copying; scores and estimates unchanged; previously: Outline view: images and gradient meshes are picked on what Outline draws, so a click inside them reaches the path behind, #6437; previously minor: a middle-click on a document tab closes it, #6506; previously minor: Blob Brush: a round tip's preview is the outline of the area it adds, round at both ends, as the stroke it commits (#4343); scores and estimates unchanged; previously:; ruler double-click adds a guide at the pointer, #5239; G5: Inventory Icons built-in symbol library (four built-ins); previously minor: files that record no units open in Preferences › Units › General, #5820; previously minor: interim macOS cursor delivery, #2292; native validation pending; scores and estimates unchanged; Control bar › Snapping includes the existing Snap to Glyph and Alignment Guides toggles (#6164); scores and estimates unchanged; floating tab groups collapse into the side icon rail and opened rail panels fold back into it, #5925 in part; numeric fields step on wheel hover without taking keyboard focus, #5949; Character Styles panel: a double-click on a style's row opens its Character Style Options; the dialog keeps a fixed width and scrolls its sections, so its buttons stay on screen; Selection QoL: marquee modes and visible feedback, #5313; #3380 deletion-only review follow-up: independent survivors keep gradient placement, owned subpaths avoid discarded copies, and contracts/status/evidence are clarified; endpoint highlighting remains open; scores and estimates unchanged; Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Layers: Rename (`ui.rename`) opens the name field of the selected layer, group or object, #5324; Properties in Edit Artboards: Transform section above the Artboards section, #5219; scrubby labels: the Control bar's Stroke: and Opacity: links and the Properties panel's Stroke link scrub their fields, #4088; Properties: Quick Actions has Repeat Options for one selected repeat, #5181; Direct Selection: Shift-click picks several blend spine points, which drag together, #5285; Direct Selection: Cmd/Ctrl held lends the Selection tool and shows its bounding box, #3901; Join tool trims two crossing open paths and joins them at the crossing, #5844; Control bar: Paragraph: link and Align left/center/right while type is selected, #5372; shape tools: a press on the selection's centre point moves it and one in the rotate zone outside a box corner turns it, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged)
|
||||
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-11-12 · **Change:** minor (macOS: the canvas cursor stays after the pointer moves, #6362; scores and estimates unchanged; previously minor: Remove Background in the Contextual Task Bar, Properties › Quick Actions and the Control bar; previously minor: Ruler origin: the corner drag snaps as a drawn point does; previously minor: Live Paint Bucket fills faces crossed in one drag (#6373); previously: #6404: transform-aware Eyedropper character copying; scores and estimates unchanged; previously: Outline view: images and gradient meshes are picked on what Outline draws, so a click inside them reaches the path behind, #6437; previously minor: a middle-click on a document tab closes it, #6506; previously minor: Blob Brush: a round tip's preview is the outline of the area it adds, round at both ends, as the stroke it commits (#4343); scores and estimates unchanged; previously:; ruler double-click adds a guide at the pointer, #5239; G5: Inventory Icons built-in symbol library (four built-ins); previously minor: files that record no units open in Preferences › Units › General, #5820; previously minor: interim macOS cursor delivery, #2292; native validation pending; scores and estimates unchanged; Control bar › Snapping includes the existing Snap to Glyph and Alignment Guides toggles (#6164); scores and estimates unchanged; floating tab groups collapse into the side icon rail and opened rail panels fold back into it, #5925 in part; numeric fields step on wheel hover without taking keyboard focus, #5949; Character Styles panel: a double-click on a style's row opens its Character Style Options; the dialog keeps a fixed width and scrolls its sections, so its buttons stay on screen; Selection QoL: marquee modes and visible feedback, #5313; #3380 deletion-only review follow-up: independent survivors keep gradient placement, owned subpaths avoid discarded copies, and contracts/status/evidence are clarified; endpoint highlighting remains open; scores and estimates unchanged; Drop Shadow and glow dialogs: spinner arrows, #5367, #5368; Stroke Weight Up and Down shortcuts, #5797; Layers: Rename (`ui.rename`) opens the name field of the selected layer, group or object, #5324; Properties in Edit Artboards: Transform section above the Artboards section, #5219; scrubby labels: the Control bar's Stroke: and Opacity: links and the Properties panel's Stroke link scrub their fields, #4088; Properties: Quick Actions has Repeat Options for one selected repeat, #5181; Direct Selection: Shift-click picks several blend spine points, which drag together, #5285; Direct Selection: Cmd/Ctrl held lends the Selection tool and shows its bounding box, #3901; Join tool trims two crossing open paths and joins them at the crossing, #5844; Control bar: Paragraph: link and Align left/center/right while type is selected, #5372; shape tools: a press on the selection's centre point moves it and one in the rotate zone outside a box corner turns it, #5477; scores and estimates unchanged) · **Target:** Adobe Illustrator 2026 (30.x; Units › East Asian Type acts, with Q and Ha units; scores unchanged)
|
||||
>
|
||||
> Vector Halftone preview update (2026-11-10): temporary dot selection marks are hidden, and the bounding box stays available (#6369).
|
||||
>
|
||||
@@ -332,7 +332,7 @@ tools, never checked side by side) isn't captured row by row.
|
||||
| Tool double-click opens its options | done | |
|
||||
| Per-platform mapping (Cmd ↔ Ctrl, Option ↔ Alt) | done | |
|
||||
| Eyedropper cursor; Use Precise Cursors | partial | original pipette at the sampling tip, distinct from the precise crosshair at five DPI scales (#1269); OS cursor display unverified; while Caps Lock is on, the tools that Use Precise Cursors changes show the crosshair, and the saved preference does not change (the desktop app reads the lock state on macOS, Windows and Linux X11, not on native Wayland; `view.capsLock` reads or sets it); a Use Precise Cursors command toggles the preference and can take a shortcut (#1663); cursors are painted into the window on Wayland (#1652, not run on Linux) |
|
||||
| macOS canvas cursor delivery (#2292) | partial | The UI prepares the existing glyphs as aligned 1×/2× RGBA requests; the desktop host builds AppKit cursors and owns cursor rectangles for the root document window. Detached document viewports and requests without a usable native bitmap retain the visible system fallback; precise-cursor and UI-scale preferences retained. Headless regressions cover routing, pixels/hotspots and lifecycle; native focus/menu/handback timing, mixed displays, Spotlight and full-screen Spaces remain unverified. Wayland still paints its glyphs. |
|
||||
| macOS canvas cursor delivery (#2292) | partial | The UI prepares the existing glyphs as aligned 1×/2× RGBA requests; the desktop host builds AppKit cursors and owns cursor rectangles for the root document window. While it owns the cursor, the host sets it again on every pass, so the tool's cursor stays when the pointer moves (#6362). Detached document viewports and requests without a usable native bitmap retain the visible system fallback; precise-cursor and UI-scale preferences retained. Headless regressions cover routing, pixels/hotspots and lifecycle; native focus/menu/handback timing, mixed displays, Spotlight and full-screen Spaces remain unverified. Wayland still paints its glyphs. |
|
||||
| Every tool's modifiers checked against the shortcut reference | missing | this is the fidelity pass |
|
||||
|
||||
## Keyboard shortcuts
|
||||
@@ -526,6 +526,7 @@ before release (#6373). [Paint faces and edges](https://helpx.adobe.com/illustra
|
||||
| 2026-11-12 | minor | Live Paint Bucket fills faces crossed in one drag (#6373). Scores and estimates unchanged. |
|
||||
| 2026-11-12 | minor | Save refusal follow-up (#6146): changed format opens its Save options; unchanged format retains original options. Focused UI regressions passed, including the format-change case that failed before the fix; native panel acceptance pending. Scores and estimates unchanged. |
|
||||
| 2026-11-11 | minor | Ruler origin: the corner drag snaps as a drawn point does, onto the art's and the artboards' anchors, centres, edges and paths, and with Snap to Point along the ruler guides; scores and estimates unchanged |
|
||||
| 2026-11-11 | minor | macOS canvas cursor delivery (#2292): while the host owns the cursor it sets it again on every pass, so the tool's cursor stays after the pointer moves (#6362); `mac_cursor` ownership test updated; scores and estimates unchanged. |
|
||||
| 2026-11-11 | minor | Eyedropper copies effective character dimensions between transformed text objects (#6404); scores and estimates unchanged. |
|
||||
| 2026-11-11 | minor | Ordinary Save to a location refusing writes offers Save As (#6146); cancellation preserves the original path and modified state; automation receives READ_ONLY_LOCATION. Scores and estimates unchanged. Validation pending. |
|
||||
| 2026-11-11 | minor | Outline view: a click on a path's outline selects it through an image or a gradient mesh in front, which Outline draws as a frame or mesh lines (#6437). |
|
||||
|
||||
Reference in New Issue
Block a user