fix: lift modifier state to MobileTerminalWrapper for virtual keyboard integration

- Remove useSpecialKeys hook state, export pure utility functions instead
- MobileTerminalWrapper now owns activeModifier state
- SpecialKeysStrip and SpecialKeysPanel receive modifier via props
- TerminalComponent applies modifier to virtual keyboard input via activeModifier prop
- Modifier now works with both special keys AND virtual keyboard input
- Modifier clears after any key press (special or virtual keyboard)
This commit is contained in:
Fusion
2026-05-24 12:45:07 +02:00
parent 3d9ff44d1a
commit e555561a2d
5 changed files with 98 additions and 51 deletions
+23 -4
View File
@@ -1,11 +1,13 @@
import React from "react";
import { useSpecialKeys, type SpecialKey, type ModifierKey } from "../hooks/use-special-keys";
import { getSequenceWithModifier, type SpecialKey, type ModifierKey, KEY_SEQUENCES } from "../hooks/use-special-keys";
interface SpecialKeysStripProps {
onSend: (data: string) => void;
isVisible: boolean;
onMoreClick?: () => void;
onKeepFocus?: () => void;
activeModifier: ModifierKey | null;
onModifierChange: (modifier: ModifierKey | null) => void;
}
const PRIMARY_KEYS: { key: SpecialKey; label: string; isModifier?: boolean }[] = [
@@ -24,12 +26,29 @@ export const SpecialKeysStrip: React.FC<SpecialKeysStripProps> = ({
isVisible,
onMoreClick,
onKeepFocus,
activeModifier,
onModifierChange,
}) => {
const { sendKey, activeModifier } = useSpecialKeys({ onSend });
const handlePointerDown = (e: React.PointerEvent, key: SpecialKey) => {
e.preventDefault();
sendKey(key);
// Handle modifier keys (one-shot)
if (key === "ctrl" || key === "alt") {
onModifierChange(activeModifier === key ? null : key);
requestAnimationFrame(() => {
onKeepFocus?.();
});
return;
}
const result = getSequenceWithModifier(key, activeModifier);
if (result) {
onSend(result.sequence);
if (result.clearModifier) {
onModifierChange(null);
}
}
// Always refocus terminal after sending
requestAnimationFrame(() => {
onKeepFocus?.();