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.1.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.1-py3-none-any.whl (7.2 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for aklm-1.0.1.tar.gz
Algorithm Hash digest
SHA256 d390d539e334c8ef10559be7eae51272731824443eb5946416d956b4956ddeba
MD5 d5393865ee6642e8bde9274ba0f363b6
BLAKE2b-256 92c506a546f44ed3258f1e6d73f9c98759679db5d753abb3f4dd2ca14618d05f

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for aklm-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 81c9e8f49a47fcc1a8b70b3ddd5dbce83f8e2af7e6429e12152bd6b0599f821c
MD5 0c9ff697e14ce0626c80f6904b6fdaf4
BLAKE2b-256 454602fce3d7effa112f050b51e625810ed3909edc5262d8241c04cd0e935286

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