Skip to content

Conversation

@coderwei99
Copy link
Contributor

Description

In the Arc browser on macOS, pressing Cmd+Z in Drawnix triggers both the Plait framework's undo action (board.undo()) and the browser's default undo action, which reopens the last closed tab. This creates a confusing user experience as the browser's action interferes with the expected whiteboard undo behavior.

This PR adds explicit handling of the Cmd+Z keybinding in the buildDrawnixHotkeyPlugin to:

  • Call board.undo() to perform the Plait undo action.
  • Use event.preventDefault() to prevent event propagation, blocking the Arc browser's default undo behavior.

No additional custom logic was added beyond the Plait undo action, ensuring minimal changes while resolving the issue.

Testing

  1. Environment: Test in Arc browser on macOS with Drawnix.
  2. Cmd+Z:
    • Create a shape (e.g., rectangle) in Drawnix.
    • Press Cmd+Z and verify:
      • The shape is undone (Plait undo works).
      • No browser tabs are reopened.
  3. Other Browsers:
    • Test in Chrome and Safari to ensure no regression in Cmd+Z behavior.

Impact

  • Fixes unexpected tab reopening in Arc browser when using Cmd+Z.
  • Improves user experience by ensuring consistent undo behavior in Drawnix.
  • No breaking changes; the fix is isolated to the Cmd+Z keybinding.

@pubuzhixing8
Copy link
Contributor

pubuzhixing8 commented Aug 28, 2025

@coderwei99 Great job, very fine improvement!

However, I make a mistake for hotkey plugin, I should overridden keydown to implement the hotkey plugin, because we can not stop the default undo action in the globalKeyDown function, the undo will exec twice 😂, you could change it in this pr or ignore it(I will correct it later).

Add return can stop the default undo action in the plait hotkey plugin.

if (isHotkey(['mod+z'], { byKey: true })(event)) {
     board.undo();
    event.preventDefault();
    return;
}

@coderwei99
Copy link
Contributor Author

@pubuzhixing8 My mistake — I didn’t take the native Plait undo behavior into account.
I’ve fixed it by adding a return after handling Cmd+Z to prevent the double undo. Thanks for pointing this out! 🙏

@pubuzhixing8
Copy link
Contributor

pubuzhixing8 commented Aug 29, 2025

Look good to me @coderwei99 , ready to merge.

I would replace the overridden method globalKeyDown with keyDown, real avoid invoking undo twice (Using keyDown method to handle undo and redo action in plait hotkey plugin https://github.com/worktile/plait/blob/8c90c002876c8f39156010f5b0b03672287b823a/packages/core/src/plugins/with-history.ts#L92 ).

@coderwei99
Copy link
Contributor Author

@pubuzhixing8

After my investigation, I found that the undo action really was being executed twice.
This happens because globalKeyDown is triggered first, and then keyDown is also executed. Since the original keyDown method already contains the undo logic, the undo runs twice.

I plan to fix this by modifying the code as follows:

const { globalKeyDown, keyDown } = board;
board.globalKeyDown = (event: KeyboardEvent) => {
// ... other code
}
board.keyDown = (event: KeyboardEvent) => {
  if (isHotkey(['mod+z'], { byKey: true })(event)) {
    board.undo();
    event.preventDefault();
    return;
  }

  if (isHotkey(['mod+shift+z'], { byKey: true })(event)) {
    board.redo();
    event.preventDefault();
    return;
  }

  keyDown(event);
};

And I will remove the undo logic from globalKeyDown.

I’m new to this kind of whiteboard project, so I apologize for any oversights.

@pubuzhixing8
Copy link
Contributor

@pubuzhixing8

After my investigation, I found that the undo action really was being executed twice. This happens because globalKeyDown is triggered first, and then keyDown is also executed. Since the original keyDown method already contains the undo logic, the undo runs twice.

I plan to fix this by modifying the code as follows:

const { globalKeyDown, keyDown } = board;
board.globalKeyDown = (event: KeyboardEvent) => {
// ... other code
}
board.keyDown = (event: KeyboardEvent) => {
  if (isHotkey(['mod+z'], { byKey: true })(event)) {
    board.undo();
    event.preventDefault();
    return;
  }

  if (isHotkey(['mod+shift+z'], { byKey: true })(event)) {
    board.redo();
    event.preventDefault();
    return;
  }

  keyDown(event);
};

And I will remove the undo logic from globalKeyDown.

I’m new to this kind of whiteboard project, so I apologize for any oversights.

Cool @coderwei99 , new code segment is good to resolve the issue perfectly.

@pubuzhixing8
Copy link
Contributor

Look good to me!

@pubuzhixing8 pubuzhixing8 merged commit f600dec into plait-board:develop Aug 31, 2025
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.

2 participants