Skip to main content

Automatic Keyboard Layout Manager for i3wm

Project description

AKLM is a lightweight daemon that automatically switches your keyboard layout on Xorg with i3 window manager based on the focused application. No more manual layout switching when jumping between your IDE, browser, or terminal!

Why AKLM?

The Genesis

AKLM was born out of frustration while playing a game on Linux. The game was hardcoded to use the US keyboard layout with no option to change keymapping. For someone using an alternative layout (like Bépo or Dvorak), this made the game nearly unplayable.

AKLM solves this problem by automatically switching your keyboard layout based on which window has focus. Launch your game? AKLM switches to US. Go back to Firefox? Back to your preferred layout. It’s seamless and automatic.

How It Works

AKLM runs as a background daemon that:

  1. Monitors i3 window focus events using the i3 IPC protocol

  2. Reads window properties (specifically WM_CLASS) of the focused window

  3. Looks up the appropriate keyboard layout from its configuration file

  4. Switches the layout using setxkbmap when needed

The switching only happens when the layout actually needs to change, avoiding unnecessary system calls.

Installation

pip install aklm

Or install from source:

git clone https://git.yapbreak.fr/aoliva/aklm.git
cd aklm
pip install .

Requirements

  • Operating System: Linux with X11 (Xorg)

  • Window Manager: i3 or i3-gaps

  • Tools: setxkbmap (usually pre-installed)

  • Python: 3.10 or later

Dependencies:

  • i3ipc - for communicating with i3 window manager

Configuration

AKLM follows the XDG Base Directory Specification. It looks for configuration files in:

  1. System-wide: /etc/xdg/aklm.ini (or directories in $XDG_CONFIG_DIRS)

  2. User-specific: $XDG_CONFIG_HOME/aklm/aklm.ini (defaults to ~/.config/aklm/aklm.ini)

User configuration takes precedence over system-wide configuration.

Configuration File Format

Create ~/.config/aklm/aklm.ini with the following structure:

[general]
default_layout = fr bepo
setxkbmap = /usr/bin/setxkbmap

[log]
level = info

[layout]
firefox = fr
code = en
factorio = us
Steam = us
discord = fr bepo

Configuration Sections

[general]

  • default_layout: The keyboard layout to use when no specific mapping is found. Format: language variant (e.g., fr bepo, us, de nodeadkeys)

  • setxkbmap: Full path to the setxkbmap binary (default: /usr/bin/setxkbmap)

[log]

  • level: Logging verbosity. Options: error, warning, info, debug

[layout]

This section maps window classes to keyboard layouts. Each line follows the format:

window_class = layout
  • window_class: The WM_CLASS property of the application window

  • layout: The keyboard layout to use (same format as default_layout)

Finding Window Classes

To find the WM_CLASS of any window, use the xprop utility:

  1. Run xprop in a terminal

  2. Click on the window you want to identify

  3. Look for the WM_CLASS line in the output

$ xprop | grep WM_CLASS
WM_CLASS(STRING) = "code", "Code"

The second value (Code in this example) is what you should use in your configuration.

Common Window Classes:

  • Firefox: firefox

  • VS Code: code

  • Terminal (many): Alacritty, Terminator, Xterm

  • Steam: Steam

  • Discord: discord

Usage

Running AKLM

Start AKLM manually:

aklm

Or add it to your i3 configuration to start automatically:

# ~/.config/i3/config
exec --no-startup-id aklm

Running as a Systemd Service

For a more robust setup, create a systemd user service at ~/.config/systemd/user/aklm.service:

[Unit]
Description=Automatic Layout Manager
After=graphical-session.target

[Service]
Type=simple
ExecStart=/usr/bin/aklm
Restart=on-failure

[Install]
WantedBy=graphical-session.target

Then enable and start it:

systemctl --user enable --now aklm

Examples

Example 1: Multilingual Developer

A French developer using Bépo layout who needs US layout for gaming:

[general]
default_layout = fr bepo

[layout]
code = us
terminal = fr bepo
firefox = fr
Steam = us
factorio = us

Example 2: Documentation Writer

Someone who writes in multiple languages:

[general]
default_layout = us

[layout]
firefox = fr
libreoffice-writer = de
thunderbird = us

Troubleshooting

Layout Not Switching

  1. Check if AKLM is running: ps aux | grep aklm

  2. Verify window class: Use xprop to confirm the actual window class

  3. Check logs: Run AKLM with debug logging:

    [log]
    level = debug
  4. Test setxkbmap manually: setxkbmap fr to ensure it works

i3 Connection Issues

Ensure i3 IPC socket is accessible. Check that your i3 is running properly:

i3-msg -t get_version

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

License

AKLM is licensed under the MIT License. See the LICENSE file for details.

Author

Adrien Oliva <aoliva@yapbreak.fr>

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aklm-1.0.0.tar.gz (6.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aklm-1.0.0-py3-none-any.whl (6.9 kB view details)

Uploaded Python 3

File details

Details for the file aklm-1.0.0.tar.gz.

File metadata

  • Download URL: aklm-1.0.0.tar.gz
  • Upload date:
  • Size: 6.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for aklm-1.0.0.tar.gz
Algorithm Hash digest
SHA256 44489a361838030a790a40f9818fd25e752a412eaad7124aff62e26490b02c6c
MD5 6ef048b8b3d2cd5feafb2d46039c9681
BLAKE2b-256 3ce3e1ce28f9d149dfc2b24b05104ea858cd1fe2318af1162dd0beeab54cba14

See more details on using hashes here.

File details

Details for the file aklm-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: aklm-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 6.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for aklm-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 93f0cc8af5716d6a3e323cc4e6b4078fa799a268d6fa0a7b87aa469983a40581
MD5 a723a48c6dd16b50dad1294b92f39182
BLAKE2b-256 d32881ba5b8a086fbbd4327aff8d3b051eebb15835698b1817b71469e2dfbeda

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page