ulysses/static/js/editor
CocoLng 8e918dfdbb
Ignore AltGr keystrokes in Ctrl+Alt keyboard shortcuts (#825)
* Ignore AltGr keystrokes in Ctrl+Alt keyboard shortcuts

Browsers report AltGr (right Alt on AZERTY/QWERTZ and most non-US
layouts, used to type @ # { } [ ] | \ and the euro sign) as
ctrlKey+altKey. The default keybinds map destructive actions to
Ctrl+Alt+<letter> (delete_session, new_session, incognito,
open_calendar), so a non-US user typing a special character could
silently fire them.

Guard the shortcut matcher, the editor keydown handler, and the rebind
capture with getModifierState('AltGraph'), which is true for AltGr but
false for a genuine left Ctrl+Alt. macOS is excluded: there the Option
key legitimately sets AltGraph and there is no AltGr/Ctrl+Alt collision
to guard against, so the guard would otherwise break Ctrl+Option /
Cmd+Option shortcuts (notably in Firefox).

The detection lives in one place — isAltGrEvent / IS_MAC in
static/js/platform.js — and all three call sites route through it, so the
guards can't drift apart.

The editor handler only skips the Ctrl+Alt chord block, so layout
shortcuts reachable via AltGr (e.g. [ ] brush size = AltGr+5/+8 on
AZERTY) keep working.

* Require Ctrl+Alt for the AltGr guard and consolidate keybind test marks

isAltGrEvent now also checks ctrlKey+altKey so it only suppresses the
"AltGr reported as Ctrl+Alt" collision; an event asserting AltGraph on
its own (a Linux ISO_Level3_Shift layout, a stray modifier) is left
alone. Pin it with test_isaltgr_false_when_altgraph_set_but_not_ctrl_alt.

Collapse the 12 per-test node skipif marks into one module-level
pytestmark, and note in platform.js why IS_MAC intentionally covers
iPad/iPhone and mirrors the isMac checks in calendar.js / sessions.js.
2026-06-02 11:12:54 +09:00
..
build Odysseus v1.0 2026-05-31 23:58:26 +09:00
filters Odysseus v1.0 2026-05-31 23:58:26 +09:00
fx Odysseus v1.0 2026-05-31 23:58:26 +09:00
tools Odysseus v1.0 2026-05-31 23:58:26 +09:00
ai-inpaint.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
ai-models.js feat(ai): add OpenRouter and Ollama Cloud providers (#231) 2026-06-01 14:26:10 +09:00
ai-rembg.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
ai-tool-runner.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
ai-tools-misc.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
canvas-coords.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
canvas-events.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
canvas-transforms.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
checkerboard.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
clipboard-and-drop.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
composite-helpers.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
harmonize-masks.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
history-panel.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
keyboard-shortcuts.js Ignore AltGr keystrokes in Ctrl+Alt keyboard shortcuts (#825) 2026-06-02 11:12:54 +09:00
layer-helpers.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
layer-panel.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
mask-utils.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
shortcuts-popover.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
slider-ux.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
snap.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
state.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
stroke-pipeline.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
stroke-tool-sliders.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
wire-import.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
wire-inpaint-controls.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
wire-merge-buttons.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
wire-selection-controls.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
wire-topbar-menus.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
wire-topbar-overflow.js Odysseus v1.0 2026-05-31 23:58:26 +09:00
wire-topbar.js Odysseus v1.0 2026-05-31 23:58:26 +09:00