Windows下如何将XKB keysym名称转换为字符(TypeScript场景)
XKB按键符号转Windows字符的实现方案
我在Windows 11上用TypeScript开发,需要将Ubuntu的XKB文件转换成Windows可用的键盘定义文件。目前能处理普通字符(如Q),但像EuroSign这类按键符号(keysym)名称,需要转换成对应字符,不想用硬编码对照表,想找支持代理对的Windows或跨平台函数,比如实现:
const input = "EuroSign" const output = someConvertingFunction(input) // output = '€'
可行方案
没有直接的Windows或跨平台API能直接完成这个转换,但可以借助Unicode规范和X11 keysym的命名规则实现,无需手动硬编码全量对照表:
利用Unicode字符名称映射
大部分XKB keysym名称是Unicode字符官方名称的驼峰形式(比如EuroSign对应Unicode名称EURO SIGN)。可以先构建一个「keysym名称-字符」的映射表,初始化一次后重复使用,还能支持代理对对应的增补平面字符:// 初始化keysym到字符的映射表 const keysymToCharMap = new Map<string, string>(); // 遍历基本多语言平面(BMP) for (let code = 0; code <= 0xFFFF; code++) { const char = String.fromCodePoint(code); const unicodeName = char.match(/\p{Name}/u)?.input; if (unicodeName) { // 将Unicode名称转为XKB keysym的驼峰格式 const keysymName = unicodeName.split(' ') .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) .join(''); keysymToCharMap.set(keysymName, char); } } // 遍历增补平面(支持代理对字符) for (let code = 0x10000; code <= 0x10FFFF; code++) { const char = String.fromCodePoint(code); const unicodeName = char.match(/\p{Name}/u)?.input; if (unicodeName) { const keysymName = unicodeName.split(' ') .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) .join(''); keysymToCharMap.set(keysymName, char); } } // 转换函数 function convertKeysymToChar(keysymName: string): string | undefined { return keysymToCharMap.get(keysymName); } // 测试示例 console.log(convertKeysymToChar("EuroSign")); // 输出 '€' console.log(convertKeysymToChar("GreekOmega")); // 输出 'Ω'补充特殊keysym映射
少数XKB keysym和Unicode名称不匹配(比如ssharp对应ß,Unicode名称是LATIN SMALL LETTER SHARP S),这类只需手动补充少量映射:// 添加特殊映射项 keysymToCharMap.set("ssharp", "ß"); keysymToCharMap.set("lstroke", "ł"); keysymToCharMap.set("Lstroke", "Ł");处理十六进制keysym
对于XKB中直接写的十六进制值(如0x1001E9E),直接用String.fromCodePoint转换即可:const hexKeysym = "0x1001E9E"; const targetChar = String.fromCodePoint(parseInt(hexKeysym, 16));
内容的提问来源于stack exchange,提问作者user3443063
相关产品推荐
相关产品推荐

