From b0a817dc3731c52ee1a904f1ffa0ee56755bf598 Mon Sep 17 00:00:00 2001 From: AirborneDetergent Date: Sat, 6 Dec 2025 02:52:49 +0000 Subject: [PATCH 1/2] Fix caps lock saving bug and make reset, record, and play/pause shortcuts work outside of Monaco editor --- components/editor/metadataeditor.tsx | 29 ++++++++++++++++++++++++++- components/editor/monaco.tsx | 30 ---------------------------- 2 files changed, 28 insertions(+), 31 deletions(-) diff --git a/components/editor/metadataeditor.tsx b/components/editor/metadataeditor.tsx index 26022ac3..3c2de539 100644 --- a/components/editor/metadataeditor.tsx +++ b/components/editor/metadataeditor.tsx @@ -11,10 +11,15 @@ import { styled } from '@mui/material/styles'; import Typography from '@mui/material/Typography'; import { User } from '@supabase/supabase-js'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; +import { useTransientAtom } from 'jotai-game'; import { authorProfileAtom, codeNeedSaveAtom, descriptionAtom, + isPlayingAtom, + playAtom, + recordingAtom, + resetAtom, shaderDataUrlThumbAtom, shaderIDAtom, titleAtom, @@ -46,6 +51,10 @@ export const MetadataEditor = ({ user }: { user?: User }) => { const setCodeNeedSave = useSetAtom(codeNeedSaveAtom); const [title, setTitle] = useAtom(titleAtom); const [description, setDescription] = useAtom(descriptionAtom); + const [isRecording, setRecording] = useTransientAtom(recordingAtom); + const [isPlaying] = useTransientAtom(isPlayingAtom); + const setPlay = useSetAtom(playAtom); + const setReset = useSetAtom(resetAtom); const [visibility, setVisibility] = useAtom(visibilityAtom); const [shaderID, setShaderID] = useAtom(shaderIDAtom); const setShaderDataUrlThumb = useSetAtom(shaderDataUrlThumbAtom); @@ -91,10 +100,28 @@ export const MetadataEditor = ({ user }: { user?: User }) => { useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { - if (e.ctrlKey && e.key === 's') { + // Make shortcuts work if caps lock is enabled + const key = e.key.toLocaleLowerCase(); + // Save shortcut + if (e.ctrlKey && key === 's') { e.preventDefault(); upsertShader(false); } + // Rewind shortcut + if (e.altKey && e.ctrlKey && key === 'arrowdown') { + e.preventDefault(); + setReset(true); + } + // Play/Pause shortcut + if (e.altKey && e.ctrlKey && key === 'arrowup') { + e.preventDefault(); + setPlay(!isPlaying()); + } + // Record shortcut + if (e.altKey && e.ctrlKey && key === 'r') { + e.preventDefault(); + setRecording(!isRecording()); + } }; document.addEventListener('keydown', handleKeyDown); return () => document.removeEventListener('keydown', handleKeyDown); diff --git a/components/editor/monaco.tsx b/components/editor/monaco.tsx index 57d7cac7..ebf8b1d8 100644 --- a/components/editor/monaco.tsx +++ b/components/editor/monaco.tsx @@ -1,18 +1,13 @@ 'use client'; import Editor from '@monaco-editor/react'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; -import { useTransientAtom } from 'jotai-game'; import { codeAtom, codeNeedSaveAtom, - isPlayingAtom, languageAtom, manualReloadAtom, monacoEditorAtom, parseErrorAtom, - playAtom, - recordingAtom, - resetAtom, vimAtom } from 'lib/atoms/atoms'; import { slangConfiguration, slangLanguageDef } from 'lib/grammars/slang'; @@ -35,13 +30,9 @@ interface VimMode { const Monaco = props => { const [code, setCode] = useAtom(codeAtom); - const [isRecording, setRecording] = useTransientAtom(recordingAtom); const [codeNeedSave, setCodeNeedSave] = useAtom(codeNeedSaveAtom); const parseError = useAtomValue(parseErrorAtom); - const [isPlaying] = useTransientAtom(isPlayingAtom); - const setPlay = useSetAtom(playAtom); const setManualReload = useSetAtom(manualReloadAtom); - const setReset = useSetAtom(resetAtom); const vim = useAtomValue(vimAtom); const [vimContext, setVimContext] = useState(undefined); const [editor, setEditor] = useAtom(monacoEditorAtom); @@ -257,27 +248,6 @@ const Monaco = props => { _editor.addCommand(monaco.KeyMod.Alt | monaco.KeyCode.Enter, () => { setManualReload(true); }); - // Play/Pause shortcut - _editor.addCommand( - monaco.KeyMod.Alt | monaco.KeyMod.CtrlCmd | monaco.KeyCode.UpArrow, - () => { - setPlay(!isPlaying()); - } - ); - // Record shortcut - _editor.addCommand( - monaco.KeyMod.Alt | monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyR, - () => { - setRecording(!isRecording()); - } - ); - // Rewind shortcut - _editor.addCommand( - monaco.KeyMod.Alt | monaco.KeyMod.CtrlCmd | monaco.KeyCode.DownArrow, - () => { - setReset(true); - } - ); // https://github.com/microsoft/monaco-editor/issues/392 document.fonts.ready.then(() => monaco.editor.remeasureFonts()); From a738cb2b148fda67a8d5f90bb86ac59a542796c3 Mon Sep 17 00:00:00 2001 From: AirborneDetergent Date: Sat, 6 Dec 2025 11:29:53 +0000 Subject: [PATCH 2/2] Fix issue with shortcuts not working in Monaco --- components/editor/monaco.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/components/editor/monaco.tsx b/components/editor/monaco.tsx index ebf8b1d8..9d1f04c1 100644 --- a/components/editor/monaco.tsx +++ b/components/editor/monaco.tsx @@ -244,6 +244,24 @@ const Monaco = props => { onMount={(_editor, monaco: Monaco) => { monacoRef.current = monaco; setEditor(_editor); + // Shortcuts will be overriden by Monaco when the window is focused if + // Monaco has the same shortcut and it isn't disabled here + monaco.editor.addKeybindingRules([ + { + keybinding: + monaco.KeyMod.CtrlCmd | monaco.KeyMod.Alt | monaco.KeyCode.UpArrow, + command: null + }, + { + keybinding: + monaco.KeyMod.CtrlCmd | monaco.KeyMod.Alt | monaco.KeyCode.DownArrow, + command: null + }, + { + keybinding: monaco.KeyMod.CtrlCmd | monaco.KeyMod.Alt | monaco.KeyCode.KeyR, + command: null + } + ]); // Compile shortcut _editor.addCommand(monaco.KeyMod.Alt | monaco.KeyCode.Enter, () => { setManualReload(true);