Prosíme přihlašte se nebo zaregistrujte.

Přihlašte se svým uživatelským jménem a heslem.
Vaše pomoc je stále potřeba!

Autor Téma: Vlastní rozložení klávesnice  (Přečteno 190 krát)

ramael

  • Stálý člen
  • **
  • Příspěvků: 847
Vlastní rozložení klávesnice
« kdy: 10 Září 2025, 06:19:14 »
Předmluva
To tak píšu knihovnu v micropythonu na bluetooth HID komunikaci aby si studenti odzkoušeli sestrojit a zprovoznit vlastní klávesnici nebo myš.
A napadlo mne jak jim vlastně vysvětlím proč nemohou poslat přímo třeba znak a ale místo toho kód 0x04 v payloadu.
Konkrétně to dělá 8 Byte, kde
  • 1.Byte je modifikátor (ctrl, shift, alt, …)
  • 2.Byte je rezervován (0x00)
  • 3.~8.Bytes jsou zbylé klávesy (až 6 kláves najednou je možno detekovat)
A jak se to transformuje až po to co vidíme po stisku dané klávesy na obrazovce. A k tomu patří xkb layouty.

Jde se na to
A když už jsem nad tím dumal, napsal jsem si vlastní rozložení klávesnice a vlastně tím i vyzdvihnoul jednoduchost pure Wayland.
Není to žádný Hexenwerk. Wayland a tím nemyslím prasopsa Gnome, se snaží dbát na bezpečnost, jednoduchost a nechávat prostor uživateli.
Takže se nemusí editovat žádný systémový soubor který by se mohl při nějaké aktualizaci přepsat.
Stačí si vytvořit složku v domovském adresáři ~/.xkb/symbols
Kód: [Vybrat]
  mkdir -p ~/.xkb/symbols
A v ní vytvořit soubor s vlastním layoutem. Jako inspiraci si vezměte soubor /usr/share/X11/xkb/symbols/cz
Já si vytvořil soubor ramael :)
Kód: [Vybrat]
  cd ~/.xkb/symbols/
  >ramael
a do něho napsal toto:
Kód: [Vybrat]
// ~/.xkb/symbols/ramael

//  Numpad overlay: KP_* + superscript/subscript + box drawing
//  Zkrátka mne nevyhovuje jak se chová a je omezená numerická část klávesnice
partial keypad_keys
xkb_symbols "better_numpad" {
    name[Group1] = "Ramael (pad: KP_* + superscripts/subscripts + box, Level5 lock)";

    key <NMLK> { [ ISO_Level5_Lock ] };

    // 7 8 9 (horní řada)
    key <KP7> { type[Group1]="EIGHT_LEVEL_WITH_LEVEL5_LOCK",
        symbols[Group1]=[ KP_7, U2077, U2087, NoSymbol, U250C, NoSymbol, U2554, NoSymbol ] }; // ┌ ╔
    key <KP8> { type[Group1]="EIGHT_LEVEL_WITH_LEVEL5_LOCK",
        symbols[Group1]=[ KP_8, U2078, U2088, NoSymbol, U252C, NoSymbol, U2566, NoSymbol ] }; // ┬ ╦
    key <KP9> { type[Group1]="EIGHT_LEVEL_WITH_LEVEL5_LOCK",
        symbols[Group1]=[ KP_9, U2079, U2089, NoSymbol, U2510, NoSymbol, U2557, NoSymbol ] }; // ┐ ╗

    // 4 5 6 (střed)
    key <KP4> { type[Group1]="EIGHT_LEVEL_WITH_LEVEL5_LOCK",
        symbols[Group1]=[ KP_4, U2074, U2084, NoSymbol, U251C, NoSymbol, U2560, NoSymbol ] }; // ├ ╠
    key <KP5> { type[Group1]="EIGHT_LEVEL_WITH_LEVEL5_LOCK",
        symbols[Group1]=[ KP_5, U2075, U2085, NoSymbol, U253C, NoSymbol, U256C, NoSymbol ] }; // ┼ ╬
    key <KP6> { type[Group1]="EIGHT_LEVEL_WITH_LEVEL5_LOCK",
        symbols[Group1]=[ KP_6, U2076, U2086, NoSymbol, U2524, NoSymbol, U2563, NoSymbol ] }; // ┤ ╣

    // 1 2 3 (spodek)
    key <KP1> { type[Group1]="EIGHT_LEVEL_WITH_LEVEL5_LOCK",
        symbols[Group1]=[ KP_1, U00B9, U2081, NoSymbol, U2514, NoSymbol, U255A, NoSymbol ] }; // └ ╚
    key <KP2> { type[Group1]="EIGHT_LEVEL_WITH_LEVEL5_LOCK",
        symbols[Group1]=[ KP_2, U00B2, U2082, NoSymbol, U2534, NoSymbol, U2569, NoSymbol ] }; // ┴ ╩
    key <KP3> { type[Group1]="EIGHT_LEVEL_WITH_LEVEL5_LOCK",
        symbols[Group1]=[ KP_3, U00B3, U2083, NoSymbol, U2518, NoSymbol, U255D, NoSymbol ] }; // ┘ ╝

    // 0 – speciál: KP_0, ⁰, ₀, -, ─, │, ═, ║
    key <KP0> { type[Group1]="EIGHT_LEVEL_WITH_LEVEL5_LOCK",
        symbols[Group1]=[ KP_0, U2070, U2080, NoSymbol, U2500, U2502, U2550, U2551 ] };

    // desetinná tečka
    key <KPDL> { type[Group1]="EIGHT_LEVEL_WITH_LEVEL5_LOCK",
        symbols[Group1]=[ KP_Decimal, U00B7, NoSymbol, NoSymbol, KP_Decimal, U00B7, NoSymbol, NoSymbol ] };

    // operátory
    key <KPAD> { [ KP_Add      ] };
    key <KPSU> { [ KP_Subtract ] };
    key <KPMU> { [ KP_Multiply ] };
    key <KPDV> { [ KP_Divide   ] };
    key <KPEQ> { [ KP_Equal    ] };
    key <KPEN> { [ KP_Enter    ] };
};

// [u][/u]= Varianty rozložení [u][/u]=

// CZ QWERTY (prog_typo) + vlastní diakritika + numpad overlay
// Toto je spíše taková testovací varianta
partial alphanumeric_keys
xkb_symbols "basic" {
    include "cz(prog_typo)"
    include "ramael(better_numpad)"
    name[Group1] = "Ramael (Czech prog + Level5 pad)";

    // qwerty…
    key <AD03> { type[Group1]="EIGHT_LEVEL_ALPHABETIC",
        symbols[Group1]=[ e, E, eacute, Eacute, ecaron, Ecaron, ediaeresis, Ediaeresis ] };
    key <AD04> { type[Group1]="EIGHT_LEVEL_ALPHABETIC",
        symbols[Group1]=[ r, R, rcaron, Rcaron, permile, registered, NoSymbol, NoSymbol ] };
    key <AD06> { [ y, Y, yacute, Yacute ] };
    key <AD07> { type[Group1]="EIGHT_LEVEL_ALPHABETIC",
        symbols[Group1]=[ u, U, uring, Uring, uacute, Uacute, udiaeresis, Udiaeresis ] };
    key <AD08> { [ i, I, iacute, Iacute ] };
    key <AD09> { type[Group1]="EIGHT_LEVEL_ALPHABETIC",
        symbols[Group1]=[ o, O, oacute, Oacute, odiaeresis, Odiaeresis, NoSymbol, NoSymbol ] };

    // asdfgh…
    key <AC01> { type[Group1]="EIGHT_LEVEL_ALPHABETIC",
        symbols[Group1]=[ a, A, aacute, Aacute, adiaeresis, Adiaeresis, NoSymbol, NoSymbol ] };
    key <AC02> { type[Group1]="EIGHT_LEVEL_ALPHABETIC",
        symbols[Group1]=[ s, S, scaron, Scaron, ssharp, U1E9E, NoSymbol, NoSymbol ] }; // ß/ẞ
    key <AC03> { [ d, D, dcaron, Dcaron ] };

    // zxc…
    key <AB01> { [ z, Z, zcaron, Zcaron ] };
    key <AB03> { [ c, C, ccaron, Ccaron ] };
    key <AB06> { [ n, N, ncaron, Ncaron ] };
};

// US základ + české mrtvé klávesy a overlay numpad
// Prohozená vrchní řada kláves, kde jsou české znaky dostupné až s altgr
// KLávesa LSGT použita na diakritiku
partial alphanumeric_keys
xkb_symbols "easy" {
    include "cz(coder)"
    include "ramael(better_numpad)"
    name[Group1] = "Ramael (US + Czech easy)";

    key <TLDE> { [ any, any, section, plusminus ] };

    key <AE12> { [ equal, plus, notequal, similarequal ] };
    key <AD03> { [ any, any, EuroSign, NoSymbol ] };
    key <AD04> { [ any, any, registered, NoSymbol ] };

    key <AC02> { [ any, any, ssharp, U1E9E ] };

    key <AB01> { [ any, any, degree, NoSymbol ] };
    key <AB03> { [ any, any, copyright, NoSymbol ] };
    key <AB04> { [ any, any, at, NoSymbol ] };
    key <AB08> { [ any, any, guillemetleft, NoSymbol ] };
    key <AB09> { [ any, any, guillemetright, ellipsis ] };
    key <AB10> { [ any, any, endash, emdash ] };
   
    key <BKSL> { [ any, any, brokenbar, any ] };

    // LSGT ´ˇ˚¨
    key <LSGT> { [ dead_acute, dead_caron, dead_abovering, dead_diaeresis ] };

    include "level3(ralt_switch)"
};

// Dále jsou rozložení česká klasická s mojí numpad funkcionalitou
// pokud se někomu líbí předělaný numpad, ale používá qwerty klasiku
partial alphanumeric_keys
xkb_symbols "qwerty" {
    include "cz(qwerty)"
    include "ramael(better_numpad)"

    name[Group1] = "Ramael (Czech qwerty + better nupad";
};

// pokud se někomu líbí předělaný numpad, ale používá qwertz klasiku
partial alphanumeric_keys
xkb_symbols "qwertz" {
    include "cz(basic)"
    include "ramael(better_numpad)"

    name[Group1] = "Ramael (Czech qwertz + better nupad";
};

// pokud se někomu líbí předělaný numpad, ale používá velmi dobře rozšířenou qwerty klasiku
partial alphanumeric_keys
xkb_symbols "prog_typo" {
    include "cz(prog_typo)"
    include "ramael(better_numpad)"

    name[Group1] = "Ramael (Czech prog_typo + better nupad";
};

Tím jsem vytvořil šest nových layoutů. První je úprava numerické klávesnice. Změnil jsem funkci klávesy numlock.
Nyní kromě obvyklých 4 možností na klávesu je těch možností 8. V základu bez numlock se rovnou píší čísla. Kvůli
kompatibilitě jsem tam umístil KP_* protože některé programy na to koukají.
Pořadí kláves je v levelech (ISO level 3):
  • LV1 znak bez modifikátorů
  • LV2 znak se shiftem
  • LV3 znak s modifikátorem většinou altgr (lze změnit)
  • LV4 znak s altgr + shift
Dále se dají přidat další čtyři levely (ISO level 5):
  • LV5 znak v level5, já zvolil numlock s lock funkcí. To znamená že se klávesa nemusí držet.
  • LV6 znak se shift
  • LV7 znak s modifikátorem většinou altgr
  • LV8 znak shift + altgr
Se shift se píší čísla v horním indexu s altgr spodním indexu.
Kombinaci shift + altgr jsem vynechal klíčovým slovem NoSymbol.
V level 5 po stisku numlock se píší tabulkové znaky. Se shift nic. S altgr zdvojený znak.
Příklad chování klávesy KP_7: 7;⁷;₇;;┌;;╔;;
Otestujte a uvidíte. Vlastně tabulka v příloze (vytvořená díky tomu layoutu) numpadu demonstruje na co to je a jak to funguje.
Dobré na psaní pro studenty a zkrátka pro lidi co potřebují takové znaky.
Tato varianta v layoutu ramael se nazývá better_numpad

Pak je tam ještě varianta basic, na které jsem testoval možnosti. V reálu moc krkolomné.
Dále varianta easy. Tu používám. Je to vlastně kopie varianty cz(coder) kde je US rozložení.
A s altgr jsou v číselné řadě české znaky. Přidány znaky e-€; r-®; z-°;c-©;v-@
Klávesa napravo od levého shiftu se jmenuje LSGT. Na ni jsem namapoval interpunkční znaménka v pořadí
čárka, háček, kroužek a dvojtečka: ´ˇ˚¨ Říká se tomu mrtvé znaky a syntaxe je dead_skorocokoliv
Pro čtenáře kterým se líbí jen vylepšený numpad, jsem vytvořil ještě klasiku (qwerty, qwertz a prog_typo) s mým layoutem numpadu.

Pak už stačí dát do konfiguračního souboru WM jen:
  • kb_layout ramael
  • kb_variant easy  # můj favorit :)
Názvy znaků které se v layoutech používají jsou v souboru /usr/include/X11/keysymdef.h
Protože je toho hodně a pod UTF8 kódy se něco nedá představit, napsal jsem kraťoučký filtr v pythonu který vyzobe
názvy, Utf8 hodnoty a zobrazí jak ten znak ve skutečnosti vypadá:

Kód: [Vybrat]
#!/usr/bin/env python3
# ~/vypis_keysymdef.py

import re
import sys

pat = re.compile(
    r"^#define\s+XK_([A-Za-z0-9_]+)\s+0x[0-9a-f]+\s[i]/\[/i]\s*U\+([0-9A-F]{4,6})"
)
for line in sys.stdin:
    m = pat.search(line)
    if not m:
        continue
    name, hexcp = m.groups()
    ch = chr(int(hexcp, 16))
    print(f"{name:<24} U+{hexcp}  {ch}")


Uložit třeba jako ~/vypis_keysymdef.py. Dát tomu právo na spuštění

Kód: [Vybrat]
chmod +x ~/vypis_keysymdef.py

A pak už jen spustit

Kód: [Vybrat]
cat /usr/include/X11/keysymdef.h | ~/vypis_keysymdef.py
Výsledek si můžete uložit třeba do souboru:
Kód: [Vybrat]
cat /usr/include/X11/keysymdef.h | ~/vypis_keysymdef.py > nazvyznakuvkeysymdef.txt
a můžete experimentovat

---

Pro ty co nemají pure wayland ale používají fcitx5 je tu řešení. Vytvořte si ještě podsložku rules a v ní
dva soubory:
Kód: [Vybrat]
  mkdir -p ~/·xkb/rules/
  cp /usr/share/X11/xkb/rules/evdev.lst ~/·xkb/rules/evdev.lst
  tee ~/.xkb/rules/evdev.xml
Pak je třeba si soubor evdev.lst upravit (přidat tam svůj layuot a své variant).
Do sekce ! layout dát ramael Ramael custom layout
A so sekce ! variant řádky:
Kód: [Vybrat]
basic           ramael: Ramael (Czech prog + Level5 pad)
easy            ramael: Ramael (US + Czech easy)
qwerty          ramael: Ramael (Ramael qwerty + better numpad)
qwertz          ramael: Ramael (Ramael qwertz + better numpad)
prog_typo       ramael: Ramael (Ramael prog_typo + better numpad)
`
v příloze pro ilustraci výpis mého ~/.xkb/rules/evdev.lst


Dále editovat soubor evdev.xml. Není třeba kopírovat celý originál. Stačí vložit jen vlastní záznam  podle tohoto vzoru:

Kód: [Vybrat]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xkbConfigRegistry SYSTEM "xkb.dtd">
<xkbConfigRegistry version="1.1">

 <layoutList>
   <layout>
      <configItem>
         <name>ramael</name>
         <shortDescription>Ra</shortDescription>
         <description>Ramael custom layout</description>
         <languageList><iso639Id>ces</iso639Id></languageList>
      </configItem>
    <variantList>
      <variant>
        <configItem>
          <name>basic</name>
          <description>Ramael (Czech prog + Level5 pad)</description>
        </configItem>
      </variant>
      <variant>
        <configItem>
          <name>easy</name>
          <description>Ramael (US + Czech easy)</description>
        </configItem>
      </variant>
      <variant>
        <configItem>
          <name>qwerty</name>
          <description>Ramael (Czech qwerty + better numpad)</description>
        </configItem>
      </variant>
      <variant>
        <configItem>
          <name>qwertz</name>
          <description>Ramael (Czech qwertz + better numpad)</description>
        </configItem>
      </variant>
      <variant>
        <configItem>
          <name>prog_typo</name>
          <description>Ramael (Czech prog_typo + better numpad)</description>
        </configItem>
      </variant>
    </variantList>
   </layout>

 </layoutList>
</xkbConfigRegistry>

Po tomto kroku si budete moc díky addon keyboard v fcitx5 vybrat i toto rozložení a variantu a používat to.
Samozřejmě že si takto i můžete přehodit klávesy. Třeba pravý ctrl s altgr. A spoustu jiných psích kusů udělat.
Předpřipravené možnosti jsou v evdev.lst v sekci option. Stačí je jen includovat do vašeho layoutu.
Původně jsem myslel, že to bude "ultimativní" návod. Jenže těch možností co se dá jak udělat a přenastavit je tolik
že bych mohl psát týden a stejně by to nestačilo.
Klidně si ty konfigurační soubory nakopírujte podle postupů výše a používejte nebo upravujte dle libosti. Jak jsem psal
skoro na začátku, přidal jsem tam pár klasických layoutů aby to bylo použitelné pro všechny.

Pokud byste to chtěli aplikovat do X11(bez Fcitx5) nebo Gnome, tak hodně štěstí. Budete muset editovat xorg.conf a
projít spoustu dalších pekel aby se to podařilo. S tím nepomůžu jak na to, protože to nemám nainstalované a
tak to nemohu odzkoušet. Budu rád pokud se toho někdo zhostí.

U přiložených souborů smažte přípony .txt. Hloupé omezení fóra
« Poslední změna: 10 Září 2025, 06:21:32 od ramael »
Lenovo: ThinkPad X380 Yoga Joutůůůůb
Codeberg  GitHub

 

Provoz zaštiťuje spolek OpenAlt.