From b3d166aaf5b5572a16e24a01cb10a9760acfce42 Mon Sep 17 00:00:00 2001 From: Andrew Varga Date: Mon, 4 Aug 2025 21:31:59 +0200 Subject: [PATCH 1/4] disable undo invoked by electron file menu if input is focused --- src/lib/utils.ts | 13 +++++++++++++ src/menu/register.ts | 10 +++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 912fbb969cd..f703c098d66 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -38,6 +38,19 @@ export async function refreshPage(method = 'UI button') { window?.location.reload() } +export function activeFocusIsInput() { + return document.activeElement && isInputElement(document.activeElement) +} + +function isInputElement( + element: EventTarget +): element is HTMLInputElement | HTMLTextAreaElement { + return ( + element instanceof HTMLInputElement || + element instanceof HTMLTextAreaElement + ) +} + /** * Get all labels for a keyword call expression. */ diff --git a/src/menu/register.ts b/src/menu/register.ts index 448d573a96c..8eab64ac3f6 100644 --- a/src/menu/register.ts +++ b/src/menu/register.ts @@ -4,7 +4,7 @@ import type { Project } from '@src/lib/project' import type { SettingsType } from '@src/lib/settings/initialSettings' import { engineCommandManager, sceneInfra } from '@src/lib/singletons' import { reportRejection } from '@src/lib/trap' -import { uuidv4 } from '@src/lib/utils' +import { activeFocusIsInput, uuidv4 } from '@src/lib/utils' import { authActor, commandBarActor, @@ -124,9 +124,13 @@ export function modelingMenuCallbackMostActions( data: { name: 'format-code', groupId: 'code' }, }) } else if (data.menuLabel === 'Edit.Undo') { - editorManager.undo() + if (!activeFocusIsInput()) { + editorManager.undo() + } } else if (data.menuLabel === 'Edit.Redo') { - editorManager.redo() + if (!activeFocusIsInput()) { + editorManager.redo() + } } else if (data.menuLabel === 'View.Orthographic view') { settingsActor.send({ type: 'set.modeling.cameraProjection', From 42435c53cc303244ab7ceaca450ab86d8390cbd7 Mon Sep 17 00:00:00 2001 From: Andrew Varga Date: Mon, 4 Aug 2025 21:33:09 +0200 Subject: [PATCH 2/4] cleanup: remove unused params --- src/components/ModelingPageProvider.tsx | 8 +------- src/menu/register.ts | 5 +---- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/components/ModelingPageProvider.tsx b/src/components/ModelingPageProvider.tsx index 91698c2a492..05ab4d1dc73 100644 --- a/src/components/ModelingPageProvider.tsx +++ b/src/components/ModelingPageProvider.tsx @@ -105,13 +105,7 @@ export const ModelingPageProvider = ({ } }, [location]) - const cb = modelingMenuCallbackMostActions( - settings, - navigate, - filePath, - project, - token - ) + const cb = modelingMenuCallbackMostActions(settings, navigate, filePath) useMenuListener(cb) const kclCommandMemo = useMemo(() => { diff --git a/src/menu/register.ts b/src/menu/register.ts index 8eab64ac3f6..dd5b2b05842 100644 --- a/src/menu/register.ts +++ b/src/menu/register.ts @@ -1,6 +1,5 @@ import { AxisNames } from '@src/lib/constants' import { PATHS } from '@src/lib/paths' -import type { Project } from '@src/lib/project' import type { SettingsType } from '@src/lib/settings/initialSettings' import { engineCommandManager, sceneInfra } from '@src/lib/singletons' import { reportRejection } from '@src/lib/trap' @@ -17,9 +16,7 @@ import type { NavigateFunction } from 'react-router-dom' export function modelingMenuCallbackMostActions( settings: SettingsType, navigate: NavigateFunction, - filePath: string, - project: Project | undefined, - token: string | undefined + filePath: string ) { // Menu listeners const cb = (data: WebContentSendPayload) => { From e325452f11500ad3bd41ad51fab592a8e64a6858 Mon Sep 17 00:00:00 2001 From: Andrew Varga Date: Mon, 4 Aug 2025 21:55:12 +0200 Subject: [PATCH 3/4] execute actual undo when input is focused --- src/menu/register.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/menu/register.ts b/src/menu/register.ts index dd5b2b05842..7751147cfd1 100644 --- a/src/menu/register.ts +++ b/src/menu/register.ts @@ -121,11 +121,17 @@ export function modelingMenuCallbackMostActions( data: { name: 'format-code', groupId: 'code' }, }) } else if (data.menuLabel === 'Edit.Undo') { - if (!activeFocusIsInput()) { + if (activeFocusIsInput()) { + document.execCommand('undo') + // Cleaner, but can't import 'electron' to this file: + // webContents.getFocusedWebContents()?.undo() + } else { editorManager.undo() } } else if (data.menuLabel === 'Edit.Redo') { - if (!activeFocusIsInput()) { + if (activeFocusIsInput()) { + document.execCommand('redo') + } else { editorManager.redo() } } else if (data.menuLabel === 'View.Orthographic view') { From ac8cd5bfbe3650094ed20485109c4090e7632399 Mon Sep 17 00:00:00 2001 From: Andrew Varga Date: Mon, 4 Aug 2025 22:21:09 +0200 Subject: [PATCH 4/4] tsc --- src/components/FileMachineProvider.tsx | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/components/FileMachineProvider.tsx b/src/components/FileMachineProvider.tsx index 5ca34a7da48..63607ece114 100644 --- a/src/components/FileMachineProvider.tsx +++ b/src/components/FileMachineProvider.tsx @@ -433,13 +433,7 @@ export const FileMachineProvider = ({ // eslint-disable-next-line react-hooks/exhaustive-deps -- TODO: blanket-ignored fix me! }, [location]) - const cb = modelingMenuCallbackMostActions( - settings, - navigate, - filePath, - project, - token - ) + const cb = modelingMenuCallbackMostActions(settings, navigate, filePath) useMenuListener(cb) const kclCommandMemo = useMemo(() => {