mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 01:00:29 +08:00
Issue #947: Improved layout handling and Unicode -> X11 keysyms translation
This commit is contained in:
parent
22db176ef0
commit
26238e241e
1
PKGBUILD
1
PKGBUILD
@ -62,6 +62,7 @@ depends=(
|
||||
python-pam
|
||||
"python-pillow>=8.3.1-1"
|
||||
python-xlib
|
||||
libxkbcommon
|
||||
python-hidapi
|
||||
python-six
|
||||
python-pyrad
|
||||
|
||||
@ -41,15 +41,19 @@ class SymmapModifiers:
|
||||
CTRL: int = 0x4
|
||||
|
||||
|
||||
def build_symmap(path: str) -> dict[int, dict[int, str]]:
|
||||
def build_symmap(path: str) -> dict[int, dict[int, str]]: # x11 keysym -> [(modifiers, webkey), ...]
|
||||
# https://github.com/qemu/qemu/blob/95a9457fd44ad97c518858a4e1586a5498f9773c/ui/keymaps.c
|
||||
logger = get_logger()
|
||||
|
||||
symmap: dict[int, dict[int, str]] = {}
|
||||
for (src, items) in [
|
||||
("<builtin>", list(X11_TO_AT1.items())),
|
||||
(path, list(_read_keyboard_layout(path).items())),
|
||||
("<builtin>", list(X11_TO_AT1.items())),
|
||||
]:
|
||||
# Пока лучшая логика - самые первые записи в файле раскладки
|
||||
# должны иметь приоритет над следующими, а дефолтный маппинг
|
||||
# только дополняет отсутствующие значения.
|
||||
|
||||
for (code, keys) in items:
|
||||
for key in keys:
|
||||
web_name = AT1_TO_WEB.get(key.code)
|
||||
@ -62,14 +66,15 @@ def build_symmap(path: str) -> dict[int, dict[int, str]]:
|
||||
logger.error("Invalid modifier key at mapping %s: %s / %s", src, web_name, key)
|
||||
continue
|
||||
|
||||
if code not in symmap:
|
||||
symmap[code] = {}
|
||||
symmap[code][
|
||||
modifiers = (
|
||||
0
|
||||
| (SymmapModifiers.SHIFT if key.shift else 0)
|
||||
| (SymmapModifiers.ALTGR if key.altgr else 0)
|
||||
| (SymmapModifiers.CTRL if key.ctrl else 0)
|
||||
] = web_name
|
||||
)
|
||||
if code not in symmap:
|
||||
symmap[code] = {}
|
||||
symmap[code].setdefault(modifiers, web_name)
|
||||
return symmap
|
||||
|
||||
|
||||
|
||||
@ -20,22 +20,50 @@
|
||||
# ========================================================================== #
|
||||
|
||||
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
|
||||
from typing import Generator
|
||||
|
||||
from .keysym import SymmapModifiers
|
||||
from .mappings import WebModifiers
|
||||
|
||||
|
||||
# =====
|
||||
def _load_libxkbcommon() -> ctypes.CDLL:
|
||||
path = ctypes.util.find_library("xkbcommon")
|
||||
if not path:
|
||||
raise RuntimeError("Where is libxkbcommon?")
|
||||
assert path
|
||||
lib = ctypes.CDLL(path)
|
||||
for (name, restype, argtypes) in [
|
||||
("xkb_utf32_to_keysym", ctypes.c_uint32, [ctypes.c_uint32]),
|
||||
]:
|
||||
func = getattr(lib, name)
|
||||
if not func:
|
||||
raise RuntimeError(f"Where is libc.{name}?")
|
||||
setattr(func, "restype", restype)
|
||||
setattr(func, "argtypes", argtypes)
|
||||
return lib
|
||||
|
||||
|
||||
_libxkbcommon = _load_libxkbcommon()
|
||||
|
||||
|
||||
def _ch_to_keysym(ch: str) -> int:
|
||||
assert len(ch) == 1
|
||||
return _libxkbcommon.xkb_utf32_to_keysym(ord(ch))
|
||||
|
||||
|
||||
# =====
|
||||
def text_to_web_keys( # pylint: disable=too-many-branches
|
||||
text: str,
|
||||
symmap: dict[int, dict[int, str]],
|
||||
shift_key: str=WebModifiers.SHIFT_LEFT,
|
||||
) -> Generator[tuple[str, bool], None, None]:
|
||||
|
||||
assert shift_key in WebModifiers.SHIFTS
|
||||
shift = False
|
||||
altgr = False
|
||||
|
||||
shifted = False
|
||||
for ch in text:
|
||||
# https://stackoverflow.com/questions/12343987/convert-ascii-character-to-x11-keycode
|
||||
# https://www.ascii-code.com
|
||||
@ -57,25 +85,34 @@ def text_to_web_keys( # pylint: disable=too-many-branches
|
||||
if not ch.isprintable():
|
||||
continue
|
||||
try:
|
||||
keys = symmap[ord(ch)]
|
||||
keys = symmap[_ch_to_keysym(ch)]
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
for (modifiers, key) in reversed(keys.items()):
|
||||
if (modifiers & SymmapModifiers.ALTGR) or (modifiers & SymmapModifiers.CTRL):
|
||||
for (modifiers, key) in keys.items():
|
||||
if modifiers & SymmapModifiers.CTRL:
|
||||
# Not supported yet
|
||||
continue
|
||||
|
||||
if modifiers & SymmapModifiers.SHIFT and not shifted:
|
||||
yield (shift_key, True)
|
||||
shifted = True
|
||||
elif not (modifiers & SymmapModifiers.SHIFT) and shifted:
|
||||
yield (shift_key, False)
|
||||
shifted = False
|
||||
if modifiers & SymmapModifiers.SHIFT and not shift:
|
||||
yield (WebModifiers.SHIFT_LEFT, True)
|
||||
shift = True
|
||||
elif not (modifiers & SymmapModifiers.SHIFT) and shift:
|
||||
yield (WebModifiers.SHIFT_LEFT, False)
|
||||
shift = False
|
||||
|
||||
if modifiers & SymmapModifiers.ALTGR and not altgr:
|
||||
yield (WebModifiers.ALT_RIGHT, True)
|
||||
altgr = True
|
||||
elif not (modifiers & SymmapModifiers.ALTGR) and altgr:
|
||||
yield (WebModifiers.ALT_RIGHT, False)
|
||||
altgr = False
|
||||
|
||||
yield (key, True)
|
||||
yield (key, False)
|
||||
break
|
||||
|
||||
if shifted:
|
||||
yield (shift_key, False)
|
||||
if shift:
|
||||
yield (WebModifiers.SHIFT_LEFT, False)
|
||||
if altgr:
|
||||
yield (WebModifiers.ALT_RIGHT, False)
|
||||
|
||||
@ -56,6 +56,7 @@ RUN pacman --noconfirm --ask=4 -Syy \
|
||||
python-pam \
|
||||
python-pillow \
|
||||
python-xlib \
|
||||
libxkbcommon \
|
||||
python-hidapi \
|
||||
python-zstandard \
|
||||
freetype2 \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user