mirror of https://github.com/jetkvm/kvm.git
Added German (T1) mappings, UK mappings, updated UK apple mappings. Added functionality to disable keyboard mapping.
This commit is contained in:
parent
8732a6aff8
commit
40b1c70be0
30
config.go
30
config.go
|
@ -12,25 +12,27 @@ type WakeOnLanDevice struct {
|
|||
}
|
||||
|
||||
type Config struct {
|
||||
CloudURL string `json:"cloud_url"`
|
||||
CloudToken string `json:"cloud_token"`
|
||||
GoogleIdentity string `json:"google_identity"`
|
||||
JigglerEnabled bool `json:"jiggler_enabled"`
|
||||
AutoUpdateEnabled bool `json:"auto_update_enabled"`
|
||||
KeyboardLayout string `json:"keyboard_layout"`
|
||||
IncludePreRelease bool `json:"include_pre_release"`
|
||||
HashedPassword string `json:"hashed_password"`
|
||||
LocalAuthToken string `json:"local_auth_token"`
|
||||
LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration
|
||||
WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"`
|
||||
CloudURL string `json:"cloud_url"`
|
||||
CloudToken string `json:"cloud_token"`
|
||||
GoogleIdentity string `json:"google_identity"`
|
||||
JigglerEnabled bool `json:"jiggler_enabled"`
|
||||
AutoUpdateEnabled bool `json:"auto_update_enabled"`
|
||||
KeyboardLayout string `json:"keyboard_layout"`
|
||||
KeyboardMappingEnabled bool `json:"keyboard_mapping_enabled"`
|
||||
IncludePreRelease bool `json:"include_pre_release"`
|
||||
HashedPassword string `json:"hashed_password"`
|
||||
LocalAuthToken string `json:"local_auth_token"`
|
||||
LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration
|
||||
WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"`
|
||||
}
|
||||
|
||||
const configPath = "/userdata/kvm_config.json"
|
||||
|
||||
var defaultConfig = &Config{
|
||||
CloudURL: "https://api.jetkvm.com",
|
||||
AutoUpdateEnabled: true, // Set a default value
|
||||
KeyboardLayout: "us",
|
||||
CloudURL: "https://api.jetkvm.com",
|
||||
AutoUpdateEnabled: true, // Set a default value
|
||||
KeyboardLayout: "us",
|
||||
KeyboardMappingEnabled: false,
|
||||
}
|
||||
|
||||
var config *Config
|
||||
|
|
108
jsonrpc.go
108
jsonrpc.go
|
@ -143,6 +143,18 @@ func rpcSetKeyboardLayout(KeyboardLayout string) (string, error) {
|
|||
return KeyboardLayout, nil
|
||||
}
|
||||
|
||||
func rpcGetKeyboardMappingState() (bool, error) {
|
||||
return config.KeyboardMappingEnabled, nil
|
||||
}
|
||||
|
||||
func rpcSetKeyboardMappingState(enabled bool) (bool, error) {
|
||||
config.KeyboardMappingEnabled = enabled
|
||||
if err := SaveConfig(); err != nil {
|
||||
return config.KeyboardMappingEnabled, fmt.Errorf("failed to save config: %w", err)
|
||||
}
|
||||
return enabled, nil
|
||||
}
|
||||
|
||||
var streamFactor = 1.0
|
||||
|
||||
func rpcGetStreamQualityFactor() (float64, error) {
|
||||
|
@ -521,51 +533,53 @@ func rpcResetConfig() error {
|
|||
|
||||
// TODO: replace this crap with code generator
|
||||
var rpcHandlers = map[string]RPCHandler{
|
||||
"ping": {Func: rpcPing},
|
||||
"getDeviceID": {Func: rpcGetDeviceID},
|
||||
"deregisterDevice": {Func: rpcDeregisterDevice},
|
||||
"getCloudState": {Func: rpcGetCloudState},
|
||||
"keyboardReport": {Func: rpcKeyboardReport, Params: []string{"modifier", "keys"}},
|
||||
"absMouseReport": {Func: rpcAbsMouseReport, Params: []string{"x", "y", "buttons"}},
|
||||
"wheelReport": {Func: rpcWheelReport, Params: []string{"wheelY"}},
|
||||
"getVideoState": {Func: rpcGetVideoState},
|
||||
"getUSBState": {Func: rpcGetUSBState},
|
||||
"unmountImage": {Func: rpcUnmountImage},
|
||||
"rpcMountBuiltInImage": {Func: rpcMountBuiltInImage, Params: []string{"filename"}},
|
||||
"setJigglerState": {Func: rpcSetJigglerState, Params: []string{"enabled"}},
|
||||
"getJigglerState": {Func: rpcGetJigglerState},
|
||||
"sendWOLMagicPacket": {Func: rpcSendWOLMagicPacket, Params: []string{"macAddress"}},
|
||||
"getKeyboardLayout": {Func: rpcGetKeyboardLayout},
|
||||
"setKeyboardLayout": {Func: rpcSetKeyboardLayout, Params: []string{"kbLayout"}},
|
||||
"getStreamQualityFactor": {Func: rpcGetStreamQualityFactor},
|
||||
"setStreamQualityFactor": {Func: rpcSetStreamQualityFactor, Params: []string{"factor"}},
|
||||
"getAutoUpdateState": {Func: rpcGetAutoUpdateState},
|
||||
"setAutoUpdateState": {Func: rpcSetAutoUpdateState, Params: []string{"enabled"}},
|
||||
"getEDID": {Func: rpcGetEDID},
|
||||
"setEDID": {Func: rpcSetEDID, Params: []string{"edid"}},
|
||||
"getDevChannelState": {Func: rpcGetDevChannelState},
|
||||
"setDevChannelState": {Func: rpcSetDevChannelState, Params: []string{"enabled"}},
|
||||
"getUpdateStatus": {Func: rpcGetUpdateStatus},
|
||||
"tryUpdate": {Func: rpcTryUpdate},
|
||||
"getDevModeState": {Func: rpcGetDevModeState},
|
||||
"setDevModeState": {Func: rpcSetDevModeState, Params: []string{"enabled"}},
|
||||
"getSSHKeyState": {Func: rpcGetSSHKeyState},
|
||||
"setSSHKeyState": {Func: rpcSetSSHKeyState, Params: []string{"sshKey"}},
|
||||
"setMassStorageMode": {Func: rpcSetMassStorageMode, Params: []string{"mode"}},
|
||||
"getMassStorageMode": {Func: rpcGetMassStorageMode},
|
||||
"isUpdatePending": {Func: rpcIsUpdatePending},
|
||||
"getUsbEmulationState": {Func: rpcGetUsbEmulationState},
|
||||
"setUsbEmulationState": {Func: rpcSetUsbEmulationState, Params: []string{"enabled"}},
|
||||
"checkMountUrl": {Func: rpcCheckMountUrl, Params: []string{"url"}},
|
||||
"getVirtualMediaState": {Func: rpcGetVirtualMediaState},
|
||||
"getStorageSpace": {Func: rpcGetStorageSpace},
|
||||
"mountWithHTTP": {Func: rpcMountWithHTTP, Params: []string{"url", "mode"}},
|
||||
"mountWithWebRTC": {Func: rpcMountWithWebRTC, Params: []string{"filename", "size", "mode"}},
|
||||
"mountWithStorage": {Func: rpcMountWithStorage, Params: []string{"filename", "mode"}},
|
||||
"listStorageFiles": {Func: rpcListStorageFiles},
|
||||
"deleteStorageFile": {Func: rpcDeleteStorageFile, Params: []string{"filename"}},
|
||||
"startStorageFileUpload": {Func: rpcStartStorageFileUpload, Params: []string{"filename", "size"}},
|
||||
"getWakeOnLanDevices": {Func: rpcGetWakeOnLanDevices},
|
||||
"setWakeOnLanDevices": {Func: rpcSetWakeOnLanDevices, Params: []string{"params"}},
|
||||
"resetConfig": {Func: rpcResetConfig},
|
||||
"ping": {Func: rpcPing},
|
||||
"getDeviceID": {Func: rpcGetDeviceID},
|
||||
"deregisterDevice": {Func: rpcDeregisterDevice},
|
||||
"getCloudState": {Func: rpcGetCloudState},
|
||||
"keyboardReport": {Func: rpcKeyboardReport, Params: []string{"modifier", "keys"}},
|
||||
"absMouseReport": {Func: rpcAbsMouseReport, Params: []string{"x", "y", "buttons"}},
|
||||
"wheelReport": {Func: rpcWheelReport, Params: []string{"wheelY"}},
|
||||
"getVideoState": {Func: rpcGetVideoState},
|
||||
"getUSBState": {Func: rpcGetUSBState},
|
||||
"unmountImage": {Func: rpcUnmountImage},
|
||||
"rpcMountBuiltInImage": {Func: rpcMountBuiltInImage, Params: []string{"filename"}},
|
||||
"setJigglerState": {Func: rpcSetJigglerState, Params: []string{"enabled"}},
|
||||
"getJigglerState": {Func: rpcGetJigglerState},
|
||||
"sendWOLMagicPacket": {Func: rpcSendWOLMagicPacket, Params: []string{"macAddress"}},
|
||||
"getKeyboardLayout": {Func: rpcGetKeyboardLayout},
|
||||
"setKeyboardLayout": {Func: rpcSetKeyboardLayout, Params: []string{"kbLayout"}},
|
||||
"setKeyboardMappingState": {Func: rpcSetKeyboardMappingState, Params: []string{"enabled"}},
|
||||
"getKeyboardMappingState": {Func: rpcGetKeyboardMappingState},
|
||||
"getStreamQualityFactor": {Func: rpcGetStreamQualityFactor},
|
||||
"setStreamQualityFactor": {Func: rpcSetStreamQualityFactor, Params: []string{"factor"}},
|
||||
"getAutoUpdateState": {Func: rpcGetAutoUpdateState},
|
||||
"setAutoUpdateState": {Func: rpcSetAutoUpdateState, Params: []string{"enabled"}},
|
||||
"getEDID": {Func: rpcGetEDID},
|
||||
"setEDID": {Func: rpcSetEDID, Params: []string{"edid"}},
|
||||
"getDevChannelState": {Func: rpcGetDevChannelState},
|
||||
"setDevChannelState": {Func: rpcSetDevChannelState, Params: []string{"enabled"}},
|
||||
"getUpdateStatus": {Func: rpcGetUpdateStatus},
|
||||
"tryUpdate": {Func: rpcTryUpdate},
|
||||
"getDevModeState": {Func: rpcGetDevModeState},
|
||||
"setDevModeState": {Func: rpcSetDevModeState, Params: []string{"enabled"}},
|
||||
"getSSHKeyState": {Func: rpcGetSSHKeyState},
|
||||
"setSSHKeyState": {Func: rpcSetSSHKeyState, Params: []string{"sshKey"}},
|
||||
"setMassStorageMode": {Func: rpcSetMassStorageMode, Params: []string{"mode"}},
|
||||
"getMassStorageMode": {Func: rpcGetMassStorageMode},
|
||||
"isUpdatePending": {Func: rpcIsUpdatePending},
|
||||
"getUsbEmulationState": {Func: rpcGetUsbEmulationState},
|
||||
"setUsbEmulationState": {Func: rpcSetUsbEmulationState, Params: []string{"enabled"}},
|
||||
"checkMountUrl": {Func: rpcCheckMountUrl, Params: []string{"url"}},
|
||||
"getVirtualMediaState": {Func: rpcGetVirtualMediaState},
|
||||
"getStorageSpace": {Func: rpcGetStorageSpace},
|
||||
"mountWithHTTP": {Func: rpcMountWithHTTP, Params: []string{"url", "mode"}},
|
||||
"mountWithWebRTC": {Func: rpcMountWithWebRTC, Params: []string{"filename", "size", "mode"}},
|
||||
"mountWithStorage": {Func: rpcMountWithStorage, Params: []string{"filename", "mode"}},
|
||||
"listStorageFiles": {Func: rpcListStorageFiles},
|
||||
"deleteStorageFile": {Func: rpcDeleteStorageFile, Params: []string{"filename"}},
|
||||
"startStorageFileUpload": {Func: rpcStartStorageFileUpload, Params: []string{"filename", "size"}},
|
||||
"getWakeOnLanDevices": {Func: rpcGetWakeOnLanDevices},
|
||||
"setWakeOnLanDevices": {Func: rpcSetWakeOnLanDevices, Params: []string{"params"}},
|
||||
"resetConfig": {Func: rpcResetConfig},
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ type SelectMenuProps = Pick<
|
|||
const sizes = {
|
||||
XS: "h-[24.5px] pl-3 pr-8 text-xs",
|
||||
SM: "h-[32px] pl-3 pr-8 text-[13px]",
|
||||
SM_Wide: "h-[32px] pl-3 pr-8 mr-5 text-[13px]",
|
||||
MD: "h-[40px] pl-4 pr-10 text-sm",
|
||||
LG: "h-[48px] pl-4 pr-10 px-5 text-base",
|
||||
};
|
||||
|
|
|
@ -17,6 +17,10 @@ import useKeyboard from "@/hooks/useKeyboard";
|
|||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import { ConnectionErrorOverlay, HDMIErrorOverlay, LoadingOverlay } from "./VideoOverlay";
|
||||
|
||||
// TODO Implement keyboard lock API to resolve #127
|
||||
// https://developer.chrome.com/docs/capabilities/web-apis/keyboard-lock
|
||||
// An appropriate error message will need to be displayed in order to alert users to browser compatibility issues.
|
||||
|
||||
export default function WebRTCVideo() {
|
||||
const [keys, setKeys] = useState(useKeyboardMappingsStore.keys);
|
||||
const [chars, setChars] = useState(useKeyboardMappingsStore.chars);
|
||||
|
@ -155,8 +159,6 @@ export default function WebRTCVideo() {
|
|||
// Invert the scroll value to match expected behavior
|
||||
const invertedScroll = -roundedScroll;
|
||||
|
||||
// TODO remove debug logs
|
||||
console.log("wheelReport", { wheelY: invertedScroll });
|
||||
send("wheelReport", { wheelY: invertedScroll });
|
||||
|
||||
// TODO this is making scrolling feel slow and sluggish, also throwing a violation in chrome
|
||||
|
@ -179,7 +181,7 @@ export default function WebRTCVideo() {
|
|||
// TODO remove debug logging
|
||||
console.log(shiftKey + " " +ctrlKey + " " +altKey + " " +metaKey + " " +mappedKeyModifers.shift + " "+mappedKeyModifers.altLeft + " "+mappedKeyModifers.altRight + " ")
|
||||
|
||||
const filteredModifiers = activeModifiers.filter(Boolean);3
|
||||
const filteredModifiers = activeModifiers.filter(Boolean);
|
||||
// Example: activeModifiers = [0x01, 0x02, 0x04, 0x08]
|
||||
// Assuming 0x01 = ControlLeft, 0x02 = ShiftLeft, 0x04 = AltLeft, 0x08 = MetaLeft
|
||||
return (
|
||||
|
@ -210,8 +212,13 @@ export default function WebRTCVideo() {
|
|||
modifier =>
|
||||
altKey ||
|
||||
mappedKeyModifers.altLeft ||
|
||||
(modifier !== modifiers["AltLeft"]),
|
||||
)
|
||||
.filter(
|
||||
modifier =>
|
||||
altKey ||
|
||||
mappedKeyModifers.altRight ||
|
||||
(modifier !== modifiers["AltLeft"] && modifier !== modifiers["AltRight"]),
|
||||
(modifier !== modifiers["AltRight"])
|
||||
)
|
||||
// Meta: Keep if Meta is pressed or if the key isn't a Meta key
|
||||
// Example: If metaKey is true, keep all modifiers
|
||||
|
@ -230,8 +237,9 @@ export default function WebRTCVideo() {
|
|||
async (e: KeyboardEvent) => {
|
||||
e.preventDefault();
|
||||
const prev = useHidStore.getState();
|
||||
let code = e.code;
|
||||
const localisedKey = e.key;
|
||||
const code = e.code;
|
||||
console.log("MAPPING ENABLED: " + settings.keyboardMappingEnabled)
|
||||
var localisedKey = settings.keyboardMappingEnabled ? e.key : code;
|
||||
console.log(e);
|
||||
console.log("Localised Key: " + localisedKey);
|
||||
|
||||
|
@ -282,12 +290,12 @@ export default function WebRTCVideo() {
|
|||
// event, so we need to clear the keys after a short delay
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=28089
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1299553
|
||||
// TODO add this to the activekey state
|
||||
// TODO set this to remove from activekeystate as well
|
||||
if (e.metaKey) {
|
||||
setTimeout(() => {
|
||||
const prev = useHidStore.getState();
|
||||
sendKeyboardEvent([], newModifiers || prev.activeModifiers);
|
||||
activeKeyState.current.delete("MetaLeft");
|
||||
activeKeyState.current.delete("MetaRight");
|
||||
}, 10);
|
||||
}
|
||||
|
||||
|
@ -302,6 +310,7 @@ export default function WebRTCVideo() {
|
|||
chars,
|
||||
keys,
|
||||
modifiers,
|
||||
settings,
|
||||
],
|
||||
);
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ export default function PasteModal() {
|
|||
} catch (error) {
|
||||
notifications.error("Failed to paste text");
|
||||
}
|
||||
}, [rpcDataChannel?.readyState, send, setDisableVideoFocusTrap, setPasteMode]);
|
||||
}, [rpcDataChannel?.readyState, send, setDisableVideoFocusTrap, setPasteMode, chars, keys, modifiers]);
|
||||
|
||||
useEffect(() => {
|
||||
if (TextAreaRef.current) {
|
||||
|
@ -144,6 +144,9 @@ export default function PasteModal() {
|
|||
The following characters won't be pasted as the current keyboard layout does not contain a valid mapping:{" "}
|
||||
{invalidChars.join(", ")}
|
||||
</span>
|
||||
<span className="text-xs text-red-500 dark:text-red-400">
|
||||
Tip: You can set your desired keyboard layout in settings, and remember to enable keyboard mapping.
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -79,6 +79,7 @@ export default function SettingsSidebar() {
|
|||
const settings = useSettingsStore();
|
||||
const [send] = useJsonRpc();
|
||||
const [keyboardLayout, setKeyboardLayout] = useState("us");
|
||||
const [kbMappingEnabled, setKeyboardMapping] = useState(false);
|
||||
const [streamQuality, setStreamQuality] = useState("1");
|
||||
const [autoUpdate, setAutoUpdate] = useState(true);
|
||||
const [devChannel, setDevChannel] = useState(false);
|
||||
|
@ -161,6 +162,20 @@ export default function SettingsSidebar() {
|
|||
});
|
||||
};
|
||||
|
||||
const handleKeyboardMappingChange = (enabled: boolean) => {
|
||||
send("setKeyboardMappingState", { enabled }, resp => {
|
||||
if ("error" in resp) {
|
||||
notifications.error(
|
||||
`Failed to set keyboard maping state state: ${resp.error.data || "Unknown error"}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
settings.setkeyboardMappingEnabled(enabled);
|
||||
useKeyboardMappingsStore.setMappingsState(enabled);
|
||||
setKeyboardMapping(enabled);
|
||||
});
|
||||
};
|
||||
|
||||
const handleStreamQualityChange = (factor: string) => {
|
||||
send("setStreamQualityFactor", { factor: Number(factor) }, resp => {
|
||||
if ("error" in resp) {
|
||||
|
@ -295,6 +310,13 @@ export default function SettingsSidebar() {
|
|||
useKeyboardMappingsStore.setLayout(String(resp.result))
|
||||
});
|
||||
|
||||
send("getKeyboardMappingState", {}, resp => {
|
||||
if ("error" in resp) return;
|
||||
setKeyboardMapping(resp.result as boolean);
|
||||
settings.setkeyboardMappingEnabled(resp.result as boolean);
|
||||
useKeyboardMappingsStore.setMappingsState(resp.result as boolean);
|
||||
});
|
||||
|
||||
send("getStreamQualityFactor", {}, resp => {
|
||||
if ("error" in resp) return;
|
||||
setStreamQuality(String(resp.result));
|
||||
|
@ -536,20 +558,32 @@ export default function SettingsSidebar() {
|
|||
description="Customize keyboard behaviour"
|
||||
/>
|
||||
<div className="space-y-4">
|
||||
<SettingsItem
|
||||
title="Enable Keyboard Mapping"
|
||||
description="Enables mapping of keys from your native layout to the layout of the target device"
|
||||
>
|
||||
<Checkbox
|
||||
checked={kbMappingEnabled}
|
||||
onChange={e => {
|
||||
handleKeyboardMappingChange(e.target.checked);
|
||||
}}
|
||||
/>
|
||||
</SettingsItem>
|
||||
<SettingsItem
|
||||
title="Keyboard Layout"
|
||||
description="Set keyboard layout (this should match the target machine)"
|
||||
>
|
||||
<SelectMenuBasic
|
||||
size="SM"
|
||||
size="SM_Wide"
|
||||
label=""
|
||||
// TODO figure out how to make this selector wider like the EDID one?
|
||||
//fullWidthƒ
|
||||
// TODO figure out how to make this selector wider like the EDID one?, (done but not sure if in desired way.)
|
||||
//fullWidth
|
||||
value={keyboardLayout}
|
||||
options={[
|
||||
{ value: "uk", label: "GB" },
|
||||
{ value: "uk_apple", label: "GB Apple" },
|
||||
{ value: "us", label: "US" },
|
||||
{ value: "uk", label: "UK" },
|
||||
{ value: "uk_apple", label: "UK (Apple)" },
|
||||
{ value: "de_t1", label: "German (T1)" },
|
||||
]}
|
||||
onChange={e => handleKeyboardLayoutChange(e.target.value)}
|
||||
/>
|
||||
|
|
|
@ -265,6 +265,9 @@ interface SettingsState {
|
|||
mouseMode: string;
|
||||
setMouseMode: (mode: string) => void;
|
||||
|
||||
keyboardMappingEnabled: boolean;
|
||||
setkeyboardMappingEnabled: (enabled: boolean) => void;
|
||||
|
||||
debugMode: boolean;
|
||||
setDebugMode: (enabled: boolean) => void;
|
||||
|
||||
|
@ -276,6 +279,9 @@ interface SettingsState {
|
|||
export const useSettingsStore = create(
|
||||
persist<SettingsState>(
|
||||
set => ({
|
||||
keyboardMappingEnabled: false,
|
||||
setkeyboardMappingEnabled: enabled => set({keyboardMappingEnabled: enabled}),
|
||||
|
||||
isCursorHidden: false,
|
||||
setCursorVisibility: enabled => set({ isCursorHidden: enabled }),
|
||||
|
||||
|
@ -535,18 +541,42 @@ export const useLocalAuthModalStore = create<LocalAuthModalState>(set => ({
|
|||
class KeyboardMappingsStore {
|
||||
private _layout: string = 'us';
|
||||
private _subscribers: (() => void)[] = [];
|
||||
private _mappingsEnabled: boolean = false;
|
||||
|
||||
public keys = getKeyboardMappings(this._layout).keys;
|
||||
public chars = getKeyboardMappings(this._layout).chars;
|
||||
public modifiers = getKeyboardMappings(this._layout).modifiers;
|
||||
|
||||
private mappedKeys = getKeyboardMappings(this._layout).keys;
|
||||
private mappedChars = getKeyboardMappings(this._layout).chars;
|
||||
private mappedModifiers = getKeyboardMappings(this._layout).modifiers;
|
||||
|
||||
setLayout(newLayout: string) {
|
||||
if (this._layout === newLayout) return;
|
||||
this._layout = newLayout;
|
||||
const updatedMappings = getKeyboardMappings(newLayout);
|
||||
this.keys = updatedMappings.keys;
|
||||
this.chars = updatedMappings.chars;
|
||||
this.modifiers = updatedMappings.modifiers;
|
||||
this.mappedKeys = updatedMappings.keys;
|
||||
this.mappedChars = updatedMappings.chars;
|
||||
this.mappedModifiers = updatedMappings.modifiers;
|
||||
if (this._mappingsEnabled) {
|
||||
this.keys = this.mappedKeys;
|
||||
this.chars = this.mappedChars;
|
||||
this.modifiers = this.mappedModifiers;
|
||||
this._notifySubscribers();
|
||||
}
|
||||
}
|
||||
|
||||
setMappingsState(enabled: boolean) {
|
||||
this._mappingsEnabled = enabled;
|
||||
if (this._mappingsEnabled) {
|
||||
this.keys = this.mappedKeys;
|
||||
this.chars = this.mappedChars;
|
||||
this.modifiers = this.mappedModifiers;
|
||||
} else {
|
||||
this.keys = getKeyboardMappings('us').keys;
|
||||
this.chars = getKeyboardMappings('us').chars;
|
||||
this.modifiers = getKeyboardMappings('us').modifiers;
|
||||
}
|
||||
this._notifySubscribers();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import {keysUKApple, charsUKApple, modifiersUKApple } from './layouts/uk_apple';
|
||||
import {keysUK, charsUK, modifiersUK } from './layouts/uk';
|
||||
import {keysUS, charsUS, modifiersUS } from './layouts/us';
|
||||
import { keysDE_T1, charsDE_T1, modifiersDE_T1 } from './layouts/de_t1';
|
||||
|
||||
export function getKeyboardMappings(layout: string) {
|
||||
switch (layout) {
|
||||
|
@ -9,6 +11,18 @@ export function getKeyboardMappings(layout: string) {
|
|||
chars: charsUKApple,
|
||||
modifiers: modifiersUKApple,
|
||||
};
|
||||
case "uk":
|
||||
return {
|
||||
keys: keysUK,
|
||||
chars: charsUK,
|
||||
modifiers: modifiersUK,
|
||||
};
|
||||
case "de_t1":
|
||||
return {
|
||||
keys: keysDE_T1,
|
||||
chars: charsDE_T1,
|
||||
modifiers: modifiersDE_T1,
|
||||
};
|
||||
case "us":
|
||||
default:
|
||||
return {
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import { charsUS, keysUS, modifiersUS } from "./us";
|
||||
|
||||
export const keysDE_T1 = {
|
||||
...keysUS,
|
||||
} as Record<string, number>;
|
||||
|
||||
export const charsDE_T1 = {
|
||||
...charsUS,
|
||||
|
||||
"y": { key: "KeyZ", shift: false },
|
||||
"Y": { key: "KeyZ", shift: true },
|
||||
"z": { key: "KeyY", shift: false },
|
||||
"Z": { key: "KeyY", shift: true },
|
||||
|
||||
"ä": { key: "Quote", shift: false },
|
||||
"Ä": { key: "Quote", shift: true },
|
||||
"ö": { key: "Semicolon", shift: false },
|
||||
"Ö": { key: "Semicolon", shift: true },
|
||||
"ü": { key: "BracketLeft", shift: false },
|
||||
"Ü": { key: "BracketLeft", shift: true },
|
||||
"ß": { key: "Minus", shift: false },
|
||||
"?": { key: "Minus", shift: true },
|
||||
|
||||
"§": { key: "Digit3", shift: true },
|
||||
"°": { key: "Backquote", shift: true },
|
||||
|
||||
"@": { key: "KeyQ", shift: false, altRight: true },
|
||||
"\"": { key: "Digit2", shift: true },
|
||||
|
||||
"#": { key: "Backslash", shift: false },
|
||||
"'": { key: "Backslash", shift: true },
|
||||
|
||||
".": { key: "Period", shift: false },
|
||||
":": { key: "Period", shift: true },
|
||||
",": { key: "Comma", shift: false },
|
||||
";": { key: "Comma", shift: true },
|
||||
|
||||
"-": { key: "Slash", shift: false },
|
||||
"_": { key: "Slash", shift: true },
|
||||
|
||||
"*": { key: "BracketRight", shift: true },
|
||||
"+": { key: "BracketRight", shift: false },
|
||||
"=": { key: "Digit0", shift: true },
|
||||
"~": { key: "BracketRight", shift: false, altRight: true },
|
||||
"{": { key: "Digit7", shift: false, altRight: true },
|
||||
"}": { key: "Digit0", shift: false, altRight: true },
|
||||
"[": { key: "Digit8", shift: false, altRight: true },
|
||||
"]": { key: "Digit9", shift: false, altRight: true },
|
||||
|
||||
"\\": { key: "Minus", shift: false, altRight: true },
|
||||
"|": { key: "IntlBackslash", shift: true, altRight: true },
|
||||
|
||||
"<": { key: "IntlBackslash", shift: false },
|
||||
">": { key: "IntlBackslash", shift: true },
|
||||
|
||||
"^": {key: "Backquote", shift: false},
|
||||
|
||||
"€": { key: "KeyE", shift: false, altRight: true },
|
||||
|
||||
"²": {key: "Digit2", shift: false, altRight: true },
|
||||
"³": {key: "Digit3", shift: false, altRight: true },
|
||||
|
||||
"μ": {key: "KeyM", shift: false, altRight: true },
|
||||
|
||||
} as Record<string, { key: string; shift: boolean; altLeft?: boolean; altRight?: boolean }>;
|
||||
|
||||
export const modifiersDE_T1 = {
|
||||
...modifiersUS,
|
||||
} as Record<string, number>;
|
|
@ -0,0 +1,24 @@
|
|||
import { charsUS, keysUS, modifiersUS } from "./us";
|
||||
|
||||
export const keysUK = {
|
||||
...keysUS,
|
||||
} as Record<string, number>;
|
||||
|
||||
export const charsUK = {
|
||||
...charsUS,
|
||||
"`": { key: "Backquote", shift: false },
|
||||
"~": { key: "Backslash", shift: true },
|
||||
"\\": { key: "IntlBacklash", shift: false },
|
||||
"|": { key: "IntlBacklash", shift: true },
|
||||
"#": { key: "Backslash", shift: false },
|
||||
"£": { key: "Digit3", shift: true },
|
||||
"@": { key: "Quote", shift: true },
|
||||
"\"": { key: "Digit2", shift: true },
|
||||
"¬": { key: "Backquote", shift: true },
|
||||
"¦": { key: "Backquote", shift: false, altRight: true },
|
||||
"€": { key: "Digit4", shift: false, altRight: true },
|
||||
} as Record<string, { key: string; shift: boolean; altLeft?: boolean; altRight?: boolean; }>;
|
||||
|
||||
export const modifiersUK = {
|
||||
...modifiersUS,
|
||||
} as Record<string, number>;
|
|
@ -16,6 +16,7 @@ export const charsUKApple = {
|
|||
"£": { key: "Digit3", shift: true },
|
||||
"@": { key: "Digit2", shift: true },
|
||||
"\"": { key: "Quote", shift: true },
|
||||
"¬": { key: "KeyL", shift: false, altLeft: true},
|
||||
} as Record<string, { key: string; shift: boolean; altLeft?: boolean; altRight?: boolean; }>;
|
||||
|
||||
// Modifiers are typically the same between UK and US layouts
|
||||
|
|
Loading…
Reference in New Issue