{"id":3851,"date":"2026-06-12T21:55:52","date_gmt":"2026-06-13T04:55:52","guid":{"rendered":"https:\/\/rose.dev\/blog\/?p=3851"},"modified":"2026-06-12T22:03:27","modified_gmt":"2026-06-13T05:03:27","slug":"press-shift-to-disable-caps-lock-xkb-edition","status":"publish","type":"post","link":"https:\/\/rose.dev\/blog\/2026\/06\/12\/press-shift-to-disable-caps-lock-xkb-edition\/","title":{"rendered":"Press SHIFT to Disable Caps Lock: xkb Edition"},"content":{"rendered":"\n<p>Everyone remembers my famous last post about <a href=\"https:\/\/rose.dev\/blog\/2022\/08\/19\/press-shift-to-disable-caps-lock\/\" data-type=\"post\" data-id=\"2189\" target=\"_blank\" rel=\"noreferrer noopener\">making Caps Lock idempotent<\/a>. Here&#8217;s how to do it on Linux with xkb (assuming you&#8217;re running xkb).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">wtf is xkb?<\/h2>\n\n\n\n<p>XKB (X Keyboard Extension) is the Linux\/Unix system that controls how your keyboard behaves at a low level. It defines keymaps, layouts, modifiers, and rules for translating key presses into characters and actions. If you switch layouts, remap keys, or use advanced shortcuts on Linux, XKB is usually doing the heavy lifting under the hood.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Talk is Cheap<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">mkdir -p ~\/.config\/xkb\/symbols\/<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">cat &gt; ~\/.config\/xkb\/symbols\/capsidem &lt;&lt; 'EOF'\ndefault partial modifier_keys\nxkb_symbols \"basic\" {\n    include \"us(basic)\"\n\n    key &lt;CAPS&gt; {\n        type[Group1] = \"ONE_LEVEL\",\n        symbols[Group1] = [ Caps_Lock ],\n        actions[Group1] = [ LockMods(modifiers = Lock, affect = lock) ]\n    };\n    key &lt;LFSH&gt; {\n        type[Group1] = \"ALPHABETIC\",\n        actions[Group1] = [ SetMods(modifiers=Shift),\n                            SetMods(modifiers=Shift+Lock, clearLocks) ]\n    };\n    key &lt;RTSH&gt; {\n        type[Group1] = \"ALPHABETIC\",\n        actions[Group1] = [ SetMods(modifiers=Shift),\n                            SetMods(modifiers=Shift+Lock, clearLocks) ]\n    };\n};\nEOF<\/code><\/pre>\n\n\n\n<p>For me, because I&#8217;m using Hypr 0.55, I can load it instantly like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">hyprctl eval 'hl.config({ input = { kb_layout = \"capsidem\" } })'<\/code><\/pre>\n\n\n\n<p>And just add that block itself without the <code>hyprctl eval<\/code> to my Lua config to persist it on boot.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Other<\/h2>\n\n\n\n<p>Check you&#8217;re running xkb with your stack first. Then probably something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">setxkbmap -layout capsidem -print | xkbcomp -I$HOME\/.config\/xkb - $DISPLAY<\/code><\/pre>\n\n\n\n<p>Or, create the file into <code>\/usr\/share\/X11\/xkb\/symbols\/<\/code> (requires sudo) and run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code class=\"\">setxkbmap -layout capsidem<\/code><\/pre>\n<hr>\r\nIt helps me if you share this post<br>\r\n<small style=\"user-select: all\">https:\/\/rose.dev\/blog\/2026\/06\/12\/press-shift-to-disable-caps-lock-xkb-edition\/<\/small>\r\n<br\/>\r\n<br\/>\r\nPublished 2026-06-12 21:55:52 ","protected":false},"excerpt":{"rendered":"<p>Everyone remembers my famous last post about making Caps Lock idempotent. Here&#8217;s how to do it on Linux with xkb (assuming you&#8217;re running xkb). wtf is xkb? XKB (X Keyboard Extension) is the Linux\/Unix system that controls how your keyboard behaves at a low level. It defines keymaps, layouts, modifiers, and rules for translating key &hellip; <a href=\"https:\/\/rose.dev\/blog\/2026\/06\/12\/press-shift-to-disable-caps-lock-xkb-edition\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Press SHIFT to Disable Caps Lock: xkb Edition<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","jetpack_post_was_ever_published":false},"categories":[832,833],"tags":[1093,940,1249,1303,1094,1260],"class_list":["post-3851","post","type-post","status-publish","format-standard","hentry","category-software","category-technology","tag-caps-lock","tag-keyboard","tag-linux","tag-settings","tag-shift","tag-system"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/posts\/3851","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/comments?post=3851"}],"version-history":[{"count":4,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/posts\/3851\/revisions"}],"predecessor-version":[{"id":3855,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/posts\/3851\/revisions\/3855"}],"wp:attachment":[{"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/media?parent=3851"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/categories?post=3851"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rose.dev\/blog\/wp-json\/wp\/v2\/tags?post=3851"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}