Skip to content

Add whiteboard undo and redo shortcuts - #366

Merged
jserv merged 1 commit into
sysprog21:mainfrom
xuntla:whiteboard-undo-shortcuts
Oct 22, 2026
Merged

jserv merged 1 commit into
sysprog21:mainfrom
xuntla:whiteboard-undo-shortcuts

Conversation

@xuntla

@xuntla xuntla commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Whiteboard history actions currently require the toolbar. Add Ctrl+Z for Undo and Ctrl+Y or Ctrl+Shift+Z for Redo on Windows/Linux, and Cmd+Z/Cmd+Shift+Z on macOS while focus is in the canvas or drawing toolbar, preserving text-field undo. Printable ASCII characters follow the selected keyboard layout, so punctuation does not trigger a shortcut based on its physical key. Only a single non-ASCII character can fall back to the physical key code; named keys and empty values are ignored.

Make the canvas reachable with Tab and focus it without scrolling after an accepted drawing start. After Undo, Redo or Clear, preserve focus on a usable toolbar control and move it to the canvas only if the previously focused control becomes disabled or focus was on the page body. Keyboard and button edits share the existing applyBoardEdit() path and editing restrictions. Document the shortcuts in the existing README row under "Whiteboard interviews".

Acceptance criteria from #352

  • AC1: One history action per distinct press; browser tests cover strokes, erasers, undoable Clear and discarded redo branches.
  • AC2: Tab access, visible focus, no-scroll focus restoration, usable buttons and platform-specific shortcut hints are covered. Tests cover repeated Enter activation of Undo and Redo, focus recovery when a button becomes disabled, and unchanged scroll positions. The drawing-start case captures scroll positions before pointer-down.
  • AC3: Tests reject edits before start, while paused, during behavioral rounds, after ending and during unfinished strokes; no edit is queued.
  • AC4: Text-field undo remains usable; tests cover outside focus, composition, repeats, extra modifiers and previously handled events, including non-Latin fallback events. Printable ASCII punctuation, named keys, empty values and ASCII control characters do not trigger unintended board edits.
  • AC5: Empty history and ignored events add no operation; the default is prevented only for successful actions. The handler adds no warning.
  • AC6: Keyboard and button actions share applyBoardEdit(); tests verify repainting and serialized replay operations with local sinks. After drawing uploads settle, Undo and Redo must each produce a new completed upload whose JPEG content, byte length and stroke metadata match the current board.

Validation

Automated test environment: Ubuntu 26.04 LTS under WSL2, using Linux Chromium through Playwright 1.64.1, Node.js 22.22.3, Rust stable 1.99.1 and OpenJDK 21. Non-Latin key events and macOS shortcut combinations are simulated in Linux Chromium.

  • The original Ctrl and Cmd shortcut cases failed before implementation and pass with this change. The non-Latin layout cases failed before the key-code fallback was added. The toolbar-focus and printable-key regression cases also failed before their respective corrections and pass afterward. The Ctrl+Shift+Z synchronization case failed before the additional Redo binding was implemented and passes afterward.
  • All seventeen whiteboard shortcut cases pass, including printable-key matching, non-Latin fallback, toolbar focus retention and drawing-start scrolling. Removing drawing-start preventScroll fails the scroll assertion; using physical codes unconditionally fails the Latin-precedence assertions.
  • Synchronization checks independently verify drawing, Undo and Redo uploads and replay operations. Removing the edit-triggered publish scheduling fails the Undo upload wait; reusing an earlier JPEG fails the Undo image comparison.
  • Both Windows/Linux Redo bindings are listed in the tooltip, aria-keyshortcuts and README. Guard tests exercise available Undo and Redo history, including Ctrl+Shift+Z, rather than relying on empty history to reject an event.
  • Focused whiteboard shortcut, whiteboard model and Run shortcut suites: 59 passed, no failures or skips.
  • CI=true ./scripts/test.sh passed after integration with upstream 3198a99: exit 0; 1,883 Rust tests passed, all 1,385 browser tests passed with no skips, and 49 hook checks passed.
  • cargo-audit passed with one allowed yanked-version warning for tokio 1.54.0. actionlint, Ruff, ShellCheck and the complete formatter chain, including commentflow and shfmt, passed.
  • Manual check: basic Ctrl+Z/Ctrl+Y operations behaved as expected during a live interview in Google Chrome 155.0.8059.85 on Windows 11. Toolbar focus retention and recovery also passed manual browser testing on Windows. I also confirmed that Ctrl+Shift+Z performs Redo in a manual browser check.
  • Coverage gaps: 23 Rust tests remain ignored by default. Native macOS behavior and full end-to-end live-service and recording validation remain untested.

Closes #352

@xuntla
xuntla marked this pull request as ready for review October 19, 2026 09:32

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="tests/browser/whiteboard-shortcuts.test.js">

<violation number="1" location="tests/browser/whiteboard-shortcuts.test.js:134">
P2: This test does not verify the advertised no-scroll behavior for an accepted drawing start. `draw()` has already scrolled the canvas and the baseline is captured afterward; record the scroll position after bringing the canvas into view but before pointer-down, then assert it is unchanged after the stroke starts.</violation>
</file>

Reply to a comment to ask cubic a question or push back. It learns from your replies.

View guided diff | Re-trigger cubic


async function draw(page, offset = 0, dot = false) {
const canvas = page.locator("#board");
await canvas.scrollIntoViewIfNeeded();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This test does not verify the advertised no-scroll behavior for an accepted drawing start. draw() has already scrolled the canvas and the baseline is captured afterward; record the scroll position after bringing the canvas into view but before pointer-down, then assert it is unchanged after the stroke starts.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At tests/browser/whiteboard-shortcuts.test.js, line 134:

<comment>This test does not verify the advertised no-scroll behavior for an accepted drawing start. `draw()` has already scrolled the canvas and the baseline is captured afterward; record the scroll position after bringing the canvas into view but before pointer-down, then assert it is unchanged after the stroke starts.</comment>

<file context>
@@ -0,0 +1,384 @@
+
+async function draw(page, offset = 0, dot = false) {
+  const canvas = page.locator("#board");
+  await canvas.scrollIntoViewIfNeeded();
+  const box = await canvas.boundingBox();
+  await page.mouse.move(box.x + 40 + offset, box.y + 40);
</file context>

Comment thread web/interview.js Outdated
@xuntla
xuntla force-pushed the whiteboard-undo-shortcuts branch from 99d1d4d to 26ea5d7 Compare October 19, 2026 11:00
@sysprog21 sysprog21 deleted a comment from xuntla Oct 19, 2026
@jserv
jserv requested review from ColtenOuO and alanhc October 19, 2026 17:26
Comment thread web/interview.js Outdated
@xuntla
xuntla force-pushed the whiteboard-undo-shortcuts branch from 26ea5d7 to 7fc4c83 Compare October 20, 2026 03:07
@xuntla
xuntla requested a review from jserv October 21, 2026 02:53
Comment thread web/interview.js Outdated
@xuntla
xuntla force-pushed the whiteboard-undo-shortcuts branch from 7fc4c83 to 6517b74 Compare October 21, 2026 04:07
@xuntla
xuntla requested a review from jserv October 21, 2026 09:56
Comment thread tests/browser/whiteboard-shortcuts.test.js Outdated
@xuntla
xuntla force-pushed the whiteboard-undo-shortcuts branch from 6517b74 to 763cff9 Compare October 21, 2026 15:25
@xuntla
xuntla requested a review from jserv October 22, 2026 04:41
Comment thread web/interview.js
Whiteboard corrections require returning to the toolbar. Allow undo and
redo from the focused board controls while preserving text-field undo,
editing restrictions, synchronization and recording behavior.
@xuntla
xuntla force-pushed the whiteboard-undo-shortcuts branch from 763cff9 to 8b4ad37 Compare October 22, 2026 06:35

@ColtenOuO ColtenOuO left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@jserv
jserv merged commit 0116b9b into sysprog21:main Oct 22, 2026
10 checks passed
@jserv

jserv commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Thank @xuntla for contributing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add keyboard undo and redo to whiteboard interviews

3 participants