mirror of
https://github.com/sipeed/NanoKVM.git
synced 2026-09-11 00:22:56 -05:00
Merge pull request #788 from ilyesAj/feat/add_french_layout
Add French keyboard layout support on paste window
This commit is contained in:
@@ -83,6 +83,81 @@ func LangueSwitch(base map[rune]Char, lang string) map[rune]Char {
|
||||
m['\u00B2'] = Char{0x40, 31} // ²
|
||||
m['\u00B3'] = Char{0x40, 32} // ³
|
||||
|
||||
case "fr":
|
||||
// French AZERTY layout
|
||||
// Letters: a↔q swap, z↔w swap, m moved to physical ; position
|
||||
m['a'] = Char{0, 20} // a is at physical Q key (HID 20)
|
||||
m['A'] = Char{2, 20}
|
||||
m['q'] = Char{0, 4} // q is at physical A key (HID 4)
|
||||
m['Q'] = Char{2, 4}
|
||||
m['z'] = Char{0, 26} // z is at physical W key (HID 26)
|
||||
m['Z'] = Char{2, 26}
|
||||
m['w'] = Char{0, 29} // w is at physical Z key (HID 29)
|
||||
m['W'] = Char{2, 29}
|
||||
m['m'] = Char{0, 51} // m is at physical ; key (HID 51)
|
||||
m['M'] = Char{2, 51}
|
||||
|
||||
// Numbers require Shift on AZERTY
|
||||
m['1'] = Char{2, 30}
|
||||
m['2'] = Char{2, 31}
|
||||
m['3'] = Char{2, 32}
|
||||
m['4'] = Char{2, 33}
|
||||
m['5'] = Char{2, 34}
|
||||
m['6'] = Char{2, 35}
|
||||
m['7'] = Char{2, 36}
|
||||
m['8'] = Char{2, 37}
|
||||
m['9'] = Char{2, 38}
|
||||
m['0'] = Char{2, 39}
|
||||
|
||||
// Unshifted number row → French/special characters
|
||||
m['&'] = Char{0, 30} // & at physical key 1
|
||||
m['\u00E9'] = Char{0, 31} // é at physical key 2
|
||||
m['"'] = Char{0, 32} // " at physical key 3
|
||||
m['\''] = Char{0, 33} // ' at physical key 4
|
||||
m['('] = Char{0, 34} // ( at physical key 5
|
||||
m['-'] = Char{0, 35} // - at physical key 6
|
||||
m['\u00E8'] = Char{0, 36} // è at physical key 7
|
||||
m['_'] = Char{0, 37} // _ at physical key 8
|
||||
m['\u00E7'] = Char{0, 38} // ç at physical key 9
|
||||
m['\u00E0'] = Char{0, 39} // à at physical key 0
|
||||
|
||||
// Physical - key (HID 45) → ) on AZERTY
|
||||
m[')'] = Char{0, 45} // ) at physical - key
|
||||
m['\u00B0'] = Char{2, 45} // ° at shift+physical - key
|
||||
|
||||
// Letter-row bracket/special keys
|
||||
m['^'] = Char{0, 47} // ^ (dead) at physical [ key (HID 47)
|
||||
m['\u00A8'] = Char{2, 47} // ¨ at shift+[
|
||||
m['$'] = Char{0, 48} // $ at physical ] key (HID 48)
|
||||
m['\u00A3'] = Char{2, 48} // £ at shift+]
|
||||
m['*'] = Char{0, 49} // * at physical \ key (HID 49)
|
||||
m['\u00B5'] = Char{2, 49} // µ at shift+\
|
||||
m['\u00F9'] = Char{0, 52} // ù at physical ' key (HID 52)
|
||||
m['%'] = Char{2, 52} // % at shift+'
|
||||
|
||||
// Bottom row remappings
|
||||
m[','] = Char{0, 16} // , at physical M key (HID 16)
|
||||
m['?'] = Char{2, 16} // ? at shift+physical M
|
||||
m[';'] = Char{0, 54} // ; at physical , key (HID 54)
|
||||
m['.'] = Char{2, 54} // . at shift+physical ,
|
||||
m[':'] = Char{0, 55} // : at physical . key (HID 55)
|
||||
m['/'] = Char{2, 55} // / at shift+physical .
|
||||
m['!'] = Char{0, 56} // ! at physical / key (HID 56)
|
||||
m['\u00A7'] = Char{2, 56} // § at shift+physical /
|
||||
|
||||
// AltGr combinations
|
||||
m['~'] = Char{0x40, 31} // AltGr+2
|
||||
m['#'] = Char{0x40, 32} // AltGr+3
|
||||
m['{'] = Char{0x40, 33} // AltGr+4
|
||||
m['['] = Char{0x40, 34} // AltGr+5
|
||||
m['|'] = Char{0x40, 35} // AltGr+6
|
||||
m['`'] = Char{0x40, 36} // AltGr+7
|
||||
m['\\'] = Char{0x40, 37} // AltGr+8
|
||||
m[']'] = Char{0x40, 45} // AltGr+physical -
|
||||
m['}'] = Char{0x40, 46} // AltGr+=
|
||||
m['@'] = Char{0x40, 39} // AltGr+0
|
||||
m['\u20AC'] = Char{0x40, 8} // € AltGr+E
|
||||
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ const de = {
|
||||
ctrlaltdel: 'Ctrl+Alt+Del',
|
||||
dropdownEnglish: 'Englisch',
|
||||
dropdownGerman: 'Deutsch',
|
||||
dropdownFrench: 'Französisch',
|
||||
dropdownRussian: 'Russisch'
|
||||
},
|
||||
mouse: {
|
||||
|
||||
@@ -91,6 +91,7 @@ const en = {
|
||||
clipboardReadError: 'Failed to read clipboard',
|
||||
dropdownEnglish: 'English',
|
||||
dropdownGerman: 'German',
|
||||
dropdownFrench: 'French',
|
||||
dropdownRussian: 'Russian',
|
||||
shortcut: {
|
||||
title: 'Shortcuts',
|
||||
|
||||
@@ -70,7 +70,14 @@ const fr = {
|
||||
placeholder: 'Veuillez saisir',
|
||||
submit: 'Soumettre',
|
||||
virtual: 'Clavier',
|
||||
ctrlaltdel: 'Ctrl+Alt+Del'
|
||||
ctrlaltdel: 'Ctrl+Alt+Del',
|
||||
readClipboard: 'Lire le presse-papiers',
|
||||
clipboardPermissionDenied: "Accès au presse-papiers refusé. Veuillez autoriser l'accès dans votre navigateur.",
|
||||
clipboardReadError: 'Échec de la lecture du presse-papiers',
|
||||
dropdownEnglish: 'Anglais',
|
||||
dropdownGerman: 'Allemand',
|
||||
dropdownFrench: 'Français',
|
||||
dropdownRussian: 'Russe'
|
||||
},
|
||||
mouse: {
|
||||
default: 'Curseur par défaut',
|
||||
|
||||
@@ -76,6 +76,7 @@ const ru = {
|
||||
ctrlaltdel: 'Ctrl+Alt+Del',
|
||||
dropdownEnglish: 'Английский',
|
||||
dropdownGerman: 'Немецкий',
|
||||
dropdownFrench: 'Французский',
|
||||
dropdownRussian: 'Русский'
|
||||
},
|
||||
mouse: {
|
||||
|
||||
@@ -29,6 +29,7 @@ export const Paste = () => {
|
||||
const languages = [
|
||||
{ value: 'en', label: t('keyboard.dropdownEnglish') },
|
||||
{ value: 'de', label: t('keyboard.dropdownGerman') },
|
||||
{ value: 'fr', label: t('keyboard.dropdownFrench') },
|
||||
{ value: 'ru', label: t('keyboard.dropdownRussian') }
|
||||
];
|
||||
|
||||
@@ -132,6 +133,7 @@ export const Paste = () => {
|
||||
|
||||
function isValidForLanguage(value: string, selectedLangue: string) {
|
||||
const isRussian = selectedLangue === 'ru';
|
||||
const isFrench = selectedLangue === 'fr';
|
||||
|
||||
for (const ch of value) {
|
||||
const code = ch.codePointAt(0) ?? 0;
|
||||
@@ -149,6 +151,12 @@ export const Paste = () => {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
} else if (isFrench) {
|
||||
// For French, allow ASCII and Latin-1/Extended accented characters
|
||||
// (é è ê ë à â ù û ç î ï ô œ æ ° µ £ § ¨ etc.)
|
||||
if (code <= 0x7F) continue;
|
||||
if (code >= 0x00A0 && code <= 0x017E) continue;
|
||||
return false;
|
||||
} else {
|
||||
// For English/German, only allow ASCII
|
||||
if (code <= 0x7F) continue;
|
||||
|
||||
Reference in New Issue
Block a user