Fix infinite loop in TUIO connection and remove conflicting keyboard shortcut

- Use ref for callbacks in useTuioConnection to prevent infinite re-renders when entering presentation mode
- Remove disabled deselect-all shortcut that conflicted with exit-presentation-mode (both using Escape)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Henrik Bruhn 2026-01-20 15:10:12 +01:00
parent 2ffebb9eb7
commit ae552a9fbd
2 changed files with 10 additions and 17 deletions

View file

@ -143,19 +143,6 @@ export function useGlobalShortcuts(options: UseGlobalShortcutsOptions = {}) {
priority: -1, // Lower priority than Ctrl+Y priority: -1, // Lower priority than Ctrl+Y
}, },
// Selection
{
id: "deselect-all",
description: "Deselect All",
key: "Escape",
handler: () => {
// This will be handled by GraphEditor
// Just documenting it here
},
category: "Selection",
enabled: false, // React Flow handles this internally
},
// View // View
{ {
id: "fit-view", id: "fit-view",

View file

@ -20,8 +20,14 @@ export function useTuioConnection(
} }
) { ) {
const clientRef = useRef<TuioClientManager | null>(null); const clientRef = useRef<TuioClientManager | null>(null);
const callbacksRef = useRef(callbacks);
const { websocketUrl, protocolVersion } = useTuioStore(); const { websocketUrl, protocolVersion } = useTuioStore();
// Keep callbacks ref up to date
useEffect(() => {
callbacksRef.current = callbacks;
}, [callbacks]);
useEffect(() => { useEffect(() => {
if (!shouldConnect) { if (!shouldConnect) {
// Disconnect if we should not be connected // Disconnect if we should not be connected
@ -38,15 +44,15 @@ export function useTuioConnection(
{ {
onTangibleAdd: (hardwareId: string, info: TuioTangibleInfo) => { onTangibleAdd: (hardwareId: string, info: TuioTangibleInfo) => {
useTuioStore.getState().addActiveTangible(hardwareId, info); useTuioStore.getState().addActiveTangible(hardwareId, info);
callbacks?.onTangibleAdd?.(hardwareId, info); callbacksRef.current?.onTangibleAdd?.(hardwareId, info);
}, },
onTangibleUpdate: (hardwareId: string, info: TuioTangibleInfo) => { onTangibleUpdate: (hardwareId: string, info: TuioTangibleInfo) => {
useTuioStore.getState().updateActiveTangible(hardwareId, info); useTuioStore.getState().updateActiveTangible(hardwareId, info);
callbacks?.onTangibleUpdate?.(hardwareId, info); callbacksRef.current?.onTangibleUpdate?.(hardwareId, info);
}, },
onTangibleRemove: (hardwareId: string) => { onTangibleRemove: (hardwareId: string) => {
useTuioStore.getState().removeActiveTangible(hardwareId); useTuioStore.getState().removeActiveTangible(hardwareId);
callbacks?.onTangibleRemove?.(hardwareId); callbacksRef.current?.onTangibleRemove?.(hardwareId);
}, },
onConnectionChange: (connected, error) => { onConnectionChange: (connected, error) => {
useTuioStore.getState().setConnectionState(connected, error); useTuioStore.getState().setConnectionState(connected, error);
@ -72,5 +78,5 @@ export function useTuioConnection(
useTuioStore.getState().clearActiveTangibles(); useTuioStore.getState().clearActiveTangibles();
} }
}; };
}, [shouldConnect, websocketUrl, protocolVersion, callbacks]); }, [shouldConnect, websocketUrl, protocolVersion]);
} }