Files
org_roam/output/20251122223053-keyboard.html
2025-12-28 20:55:38 +00:00

542 lines
20 KiB
HTML
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2025-12-28 Sun 20:54 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>keyboard</title>
<meta name="generator" content="Org Mode" />
<style type="text/css">
#content { max-width: 60em; margin: auto; }
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #e6e6e6;
border-radius: 3px;
background-color: #f2f2f2;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: auto;
}
pre.src:before {
display: none;
position: absolute;
top: -8px;
right: 12px;
padding: 3px;
color: #555;
background-color: #f2f2f299;
}
pre.src:hover:before { display: inline; margin-top: 14px;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-authinfo::before { content: 'Authinfo'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-hledger:before { content: 'hledger'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.equation-container {
display: table;
text-align: center;
width: 100%;
}
.equation {
vertical-align: middle;
}
.equation-label {
display: table-cell;
text-align: right;
vertical-align: middle;
}
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { }
</style>
<link rel="stylesheet" href="/assets/styles/style.css" />
<link rel="stylesheet" href="/assets/styles/bigger-picture.min.css" />
<link rel="stylesheet" href="/assets/styles/media.css" />
<script src="/assets/scripts/script.js" defer></script>
<script src="/assets/scripts/search.js" defer></script>
<script src="/assets/scripts/bigger-picture.min.js" defer></script>
<script src="/assets/scripts/svg-pan-zoom.min.js" defer></script>
<script src="/assets/scripts/gallery-init.js" defer></script>
</head>
<body>
<div id="preamble" class="status">
<div class="banner-header">
<div class="banner-left">
<a href="/20241210233721-brain_moc.html"> <img src="/assets/gr.png" alt="Site Logo" class="banner-logo" /> </a>
<div id="updated">Updated: 2025-12-28 Sun 19:48</div>
</div>
<div class="banner-search">
<input id="search-box"
type="search"
placeholder="Search notes…"
aria-label="Search notes"
autocomplete="off" />
<div id="search-results"></div>
</div>
<button id="close-all">Close All</button>
</div>
</div>
<div id="stack-root">
<div class="stack-track">
<article class="stack-pane pane-root" data-url="/20251122223053-keyboard.html">
<div id="content" class="content">
<div class="title-section">
<div class="title-controls">
<button class="pane-fullscreen" aria-label="Fullscreen">F</button>
<button class="pane-edit" aria-label="Edit pane">E</button>
<button class="pane-close" aria-label="Close pane">×</button>
</div>
<h1 class="title">keyboard</h1>
<div class="title-metadata">
<span class="metadata-item">
<span class="metadata-label">planted:</span>
<span class="metadata-value">2025-11-22</span>
</span>
<span class="metadata-item">
<span class="metadata-label">last tended to:</span>
<span class="metadata-value">2025-12-28</span>
</span>
</div>
</div>
<div id="outline-container-org7685b3d" class="outline-2">
<h2 id="org7685b3d"><a href="#org7685b3d">Keyboard inputs</a></h2>
<div class="outline-text-2" id="text-org7685b3d">
<p>
This all comes from the fact that a &ldquo;key press&rdquo; isn&rsquo;t one thing &#x2014; it&rsquo;s
a stack of specs and translations from <b>keyboard hardware → USB/HID →
Linux kernel → userspace (XKB/Wayland) → Hyprland binds</b>.
</p>
</div>
<div id="outline-container-big-picture-what-happens-when-you-press-a-key" class="outline-3">
<h3 id="big-picture-what-happens-when-you-press-a-key"><a href="#big-picture-what-happens-when-you-press-a-key">1. Big picture: what happens when you press a key?</a></h3>
<div class="outline-text-3" id="text-big-picture-what-happens-when-you-press-a-key">
<p>
When you hit a key (like your &ldquo;lock&rdquo; key), roughly this happens:
</p>
<div class="org-src-container">
<pre class="src src-text">Physical switch on keyboard
Keyboard firmware → USB HID "usage" (e.g. 0x07:0xE3 = Left GUI)
Linux kernel input subsystem (evdev) → KEY_LEFTMETA (code 125)
libinput / xkbcommon → keysyms (like Super_L, L, etc.)
Hyprland → your `bind = SUPER, L, exec, ...`
</pre>
</div>
<p>
The &ldquo;topic&rdquo; we&rsquo;ve been poking at is basically <b>understanding each layer
in that stack</b>.
</p>
<hr />
</div>
</div>
<div id="outline-container-usb-hid-where-700e3-comes-from" class="outline-3">
<h3 id="usb-hid-where-700e3-comes-from"><a href="#usb-hid-where-700e3-comes-from">2. USB HID: where <code>700e3</code> comes from</a></h3>
<div class="outline-text-3" id="text-usb-hid-where-700e3-comes-from">
<p>
Modern USB keyboards follow the <b>USB HID (Human Interface Device)
specification</b>. This spec defines <b>Usage Tables</b>: numerical codes for
things like keys, buttons, axes, etc.
</p>
<ul class="org-ul">
<li>The keyboard page is <b>Usage Page 0x07 (Keyboard/Keypad)</b>.</li>
<li>In your <code>evtest</code> output, <code>MSC_SCAN value 700e3</code> means:
<ul class="org-ul">
<li><code>0x07</code> (Keyboard page)</li>
<li><code>0xE3</code> (Left GUI / &ldquo;Windows/Super&rdquo; key)</li>
</ul></li>
</ul>
<p>
You can see the official tables here (PDF):
</p>
<ul class="org-ul">
<li><b>HID Usage Tables (includes Keyboard/Keypad page 0x07)</b>
<a href="https://usb.org/sites/default/files/hut1_21.pdf">https://usb.org/sites/default/files/hut1_21.pdf</a>
(<a href="https://usb.org/sites/default/files/hut1_21.pdf?utm_source=chatgpt.com">USB
Implementers Forum</a>)</li>
</ul>
<p>
If you scroll to the <b>Keyboard/Keypad Page (0x07)</b> section, it lists all
the key usages: A, B, C, modifiers, function keys, etc. There&rsquo;s also a
standalone Keyboard/Keypad-page extract people mirror, like this PDF
snippet:
(<a href="https://d1.amobbs.com/bbs_upload782111/files_47/ourdev_692986N5FAHU.pdf?utm_source=chatgpt.com">d1.amobbs.com</a>)
</p>
<p>
So:
</p>
<ul class="org-ul">
<li><code>700e3</code> = Page <code>0x07</code>, Usage <code>0xE3</code><i>Keyboard Left GUI</i></li>
<li><code>7000f</code> = Page <code>0x07</code>, Usage <code>0x0F</code><i>Keyboard L</i> key</li>
</ul>
<p>
That&rsquo;s how we knew your lock key was sending <b>Super + L</b>.
</p>
<hr />
</div>
</div>
<div id="outline-container-linux-input-subsystem-ev_msc-ev_key-key_leftmeta" class="outline-3">
<h3 id="linux-input-subsystem-ev_msc-ev_key-key_leftmeta"><a href="#linux-input-subsystem-ev_msc-ev_key-key_leftmeta">3. Linux input subsystem: <code>EV_MSC</code>, <code>EV_KEY</code>, <code>KEY_LEFTMETA</code></a></h3>
<div class="outline-text-3" id="text-linux-input-subsystem-ev_msc-ev_key-key_leftmeta">
<p>
Linux has a dedicated <b>input subsystem</b> in the kernel (<code>drivers/input</code>,
<code>drivers/hid</code> etc.) that takes those HID usages and turns them into a
unified stream of <b>input events</b>.
(<a href="https://docs.kernel.org/input/input.html?utm_source=chatgpt.com">Linux
Kernel Documentation</a>)
</p>
<p>
Key ideas:
</p>
<ul class="org-ul">
<li>Devices expose <code>/dev/input/eventX</code> nodes.</li>
<li>Each event is a struct with:
<ul class="org-ul">
<li><code>type</code> (e.g. <code>EV_KEY</code>, <code>EV_MSC</code>, <code>EV_REL</code>, <code>EV_SYN</code>)</li>
<li><code>code</code> (e.g. <code>KEY_L</code>, <code>KEY_LEFTMETA</code>)</li>
<li><code>value</code> (pressed = 1, released = 0, repeat = 2)</li>
</ul></li>
</ul>
<p>
Docs worth bookmarking:
</p>
<ul class="org-ul">
<li><b>Linux input subsystem overview</b>
<a href="https://docs.kernel.org/input/input.html">https://docs.kernel.org/input/input.html</a>
(<a href="https://docs.kernel.org/input/input.html?utm_source=chatgpt.com">Linux
Kernel Documentation</a>)</li>
<li><b>Input event types and codes (<code>event-codes.txt</code>)</b>
<a href="https://www.kernel.org/doc/Documentation/input/event-codes.txt">https://www.kernel.org/doc/Documentation/input/event-codes.txt</a>
(<a href="https://www.kernel.org/doc/Documentation/input/event-codes.txt?utm_source=chatgpt.com">Kernel.org</a>)</li>
</ul>
<p>
The <b>keycode definitions</b> (<code>KEY_L</code>, <code>KEY_LEFTMETA</code>, etc.) live in:
</p>
<ul class="org-ul">
<li><code>include/uapi/linux/input-event-codes.h</code> in the kernel source Example
mirror:
<a href="https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/input-event-codes.h">https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/input-event-codes.h</a>
(<a href="https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/input-event-codes.h?utm_source=chatgpt.com">GitHub</a>)</li>
</ul>
<p>
When <code>evtest</code> prints:
</p>
<div class="org-src-container">
<pre class="src src-text">type 4 (EV_MSC), code 4 (MSC_SCAN), value 700e3
type 1 (EV_KEY), code 125 (KEY_LEFTMETA), value 0
</pre>
</div>
<p>
that means:
</p>
<ul class="org-ul">
<li><code>EV_MSC / MSC_SCAN</code>&ldquo;Here is the raw hardware scancode&rdquo; (from USB
HID).</li>
<li><code>EV_KEY / KEY_LEFTMETA</code>&ldquo;Linux mapped that scancode to logical key
LEFTMETA&rdquo;.</li>
</ul>
<hr />
</div>
</div>
<div id="outline-container-xkb-xkbcommon-mapping-to-actual-characters-modifiers" class="outline-3">
<h3 id="xkb-xkbcommon-mapping-to-actual-characters-modifiers"><a href="#xkb-xkbcommon-mapping-to-actual-characters-modifiers">4. XKB / xkbcommon: mapping to actual characters &amp; modifiers</a></h3>
<div class="outline-text-3" id="text-xkb-xkbcommon-mapping-to-actual-characters-modifiers">
<p>
Above the kernel, you&rsquo;ve got an extra mapping layer that says:
</p>
<blockquote>
<p>
For keycode N, with this layout, when Shift is held, produce this
character/symbol.
</p>
</blockquote>
<p>
On X11 this is handled by <b>XKB (X Keyboard Extension)</b>; on Wayland
compositors (including Hyprland) the same ideas are implemented via
<b>xkbcommon</b>.
</p>
<p>
Docs:
</p>
<ul class="org-ul">
<li><b>X Keyboard Extension (XKB) protocol spec</b>
<a href="https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html">https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html</a>
(<a href="https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html?utm_source=chatgpt.com">X.Org</a>)</li>
<li><b>Arch Wiki: X keyboard extension</b> (good high-level intro)
<a href="https://wiki.archlinux.org/title/X_keyboard_extension">https://wiki.archlinux.org/title/X_keyboard_extension</a>
(<a href="https://wiki.archlinux.org/title/X_keyboard_extension?utm_source=chatgpt.com">ArchWiki</a>)</li>
<li>A nice &ldquo;practical&rdquo; walkthrough of XKB concepts:
<a href="https://medium.com/@damko/a-simple-humble-but-comprehensive-guide-to-xkb-for-linux-6f1ad5e13450">https://medium.com/[cite/t:@damko/a-simple-humble-but-comprehensive-guide-to-xkb-for-linux-6f1ad5e13450</a>]
(<a href="https://medium.com/%40damko/a-simple-humble-but-comprehensive-guide-to-xkb-for-linux-6f1ad5e13450?utm_source=chatgpt.com">Medium</a>)</li>
</ul>
<p>
Hyprland, Sway, etc. all use libinput + xkbcommon under the hood to
interpret those keycodes and translate them into keysyms and modifiers.
</p>
<hr />
</div>
</div>
<div id="outline-container-hyprland-your-config-where-the-bindings-fit-in" class="outline-3">
<h3 id="hyprland-your-config-where-the-bindings-fit-in"><a href="#hyprland-your-config-where-the-bindings-fit-in">5. Hyprland / your config: where the bindings fit in</a></h3>
<div class="outline-text-3" id="text-hyprland-your-config-where-the-bindings-fit-in">
<p>
Hyprland sits at the top of this stack:
</p>
<ul class="org-ul">
<li>It listens to the input events (via libinput).</li>
<li>It sees keysyms/modifiers (e.g. <code>Super</code>, <code>L</code>).</li>
<li>It matches them against your config:</li>
</ul>
<div class="org-src-container">
<pre class="src src-ini">bind = SUPER, L, exec, hyprlock
</pre>
</div>
<p>
So your keyboard&rsquo;s &ldquo;lock&rdquo; key:
</p>
<ol class="org-ol">
<li>Firmware sends HID usages <code>0xE3</code> (Left GUI) and <code>0x0F</code> (L).</li>
<li>Linux maps them to <code>KEY_LEFTMETA</code> (125) and <code>KEY_L</code> (38).</li>
<li>xkbcommon maps that to <code>Super</code> + <code>L</code>.</li>
<li>Hyprland says: &ldquo;Ah, SUPER+L → run <code>hyprlock</code>&rdquo;.</li>
</ol>
<p>
The &ldquo;topic&rdquo; you stumbled into is just <b>peeling back each abstraction
layer</b>.
</p>
<hr />
</div>
</div>
<div id="outline-container-handy-tools-libraries-if-you-want-to-go-deeper" class="outline-3">
<h3 id="handy-tools-libraries-if-you-want-to-go-deeper"><a href="#handy-tools-libraries-if-you-want-to-go-deeper">6. Handy tools &amp; libraries if you want to go deeper</a></h3>
<div class="outline-text-3" id="text-handy-tools-libraries-if-you-want-to-go-deeper">
<ul class="org-ul">
<li><code>evtest</code>, <code>libinput debug-events</code>, <code>showkey</code> → To watch what your
keyboard is actually sending.</li>
<li><b>Python-evdev</b> &#x2013; Python bindings to read <code>/dev/input/event*</code>
yourself: <a href="https://python-evdev.readthedocs.io/">https://python-evdev.readthedocs.io/</a>
(<a href="https://python-evdev.readthedocs.io/?utm_source=chatgpt.com">python-evdev.readthedocs.io</a>)</li>
<li>Linux input subsystem docs again:
<a href="https://docs.kernel.org/driver-api/input.html">https://docs.kernel.org/driver-api/input.html</a>
(<a href="https://docs.kernel.org/driver-api/input.html?utm_source=chatgpt.com">Linux
Kernel Documentation</a>)</li>
</ul>
<p class="backlinks-section" id="backlinks">
Backlinks
</p>
<ul class="org-ul backlinks-list">
<li><a href="20250417173809-linux_stuff.html#ID-bdb493df-db92-4c93-9558-0b10fdff3048">linux<sub>moc</sub></a></li>
</ul>
</div>
</div>
</div>
</div>
</div></article></div></div>
<div id="postamble" class="status">
<footer>
<div class="copyright-container">
<div class="copyright">
Copyright &copy; 2022-2025 Zaine Qayyum. All rights reserved unless otherwise noted.</div></div>
<div class="generated">
Created with <a href="https://www.gnu.org/software/emacs/">Emacs</a> 30.2 (<a href="https://orgmode.org">Org</a> mode 9.7.11) on <a href="https://www.archlinux.org/">Arch</a> <a href="https://www.gnu.org">GNU</a>/<a href="https://www.kernel.org/">Linux</a>
</div>
</footer>
</div>
</body>
</html>