fix(core): prevent Alt+Key shortcuts from hijacking macOS Option-key input (#14866)

Fixes #14519

## Summary

On macOS, the Option key combined with a letter produces locale input
characters (e.g. Polish layout: Option+S → `ś`, Option+L → `ł`). The
AFFiNE command registry registers shortcuts like `Alt+KeyS` (used for
Page ↔ Edgeless mode switch) via `tinykeys`, which matches on
`event.code` (the physical key) — so it fires even when the user was
actually typing a non-ASCII character.

Reported in #14519: Polish users cannot type `ś` inside AFFiNE because
Option+S triggers the mode switch instead.

## Fix

In the command registry handler
([registry.ts](packages/frontend/core/src/commands/registry/registry.ts)),
skip the command when Alt is the only modifier **and** the key produced
a non-ASCII character — the user intends to type the character, not
invoke the shortcut.

Matches the existing handling in blocksuite's `keymap.ts` (added for the
same class of issue in #14059).

## Demo



https://github.com/user-attachments/assets/eb6d2e69-39bf-4236-a886-9e2bde425626



## Verified locally (macOS)

- Switched input source to Polish
- Typed `właśnie` in an AFFiNE doc — all characters including `ś`
(Option+S), `ł` (Option+L) now produce the correct output
- Previously Option+S would toggle edgeless mode
- US layout (Option+S → `ß`) and other locale chars (ą, ń, ę) also now
pass through correctly
- Regular Cmd-based shortcuts (Cmd+K, Cmd+S, etc.) unaffected because
the guard excludes `metaKey`

## Test plan

- [x] On macOS, add Polish input source (System Settings → Keyboard →
Input Sources → +)
- [x] Switch to Polish layout
- [x] In any AFFiNE doc, type Option+S → `ś` appears (not mode switch)
- [x] Confirm other shortcuts (Cmd+K, Cmd+Enter, etc.) still work
- [x] Confirm on US layout that Option+S produces `ß` (OS default)
without firing the mode switch

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed keyboard event handling with Alt key and non-ASCII characters to
prevent unintended command execution.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
Abdul Rehman
2026-05-03 23:35:35 +05:00
committed by GitHub
parent 9751cab16c
commit 39abb936b8

View File

@@ -68,6 +68,20 @@ export const AffineCommandRegistry = new (class {
window,
{
[keybinding]: (e: Event) => {
// Skip when Alt produces a locale input character (e.g. macOS
// Polish layout: Option+S → "ś"). The user is typing the
// character, not invoking the shortcut bound to the physical
// key. Matches the handling in blocksuite's keymap.ts.
if (
e instanceof KeyboardEvent &&
e.altKey &&
!e.metaKey &&
!e.ctrlKey &&
e.key.length === 1 &&
e.key.charCodeAt(0) > 0x7e
) {
return;
}
e.preventDefault();
command.run()?.catch(e => {
console.error(`Failed to run command [${command.id}]`, e);