# The Architecture for Detecting Keyboard Layouts and Input Methods in Fastfetch

> Explore the fastfetch architecture for detecting keyboard layouts and input methods. Understand how platform-specific logic separates detection from presentation.

- Repository: [fastfetch-cli/fastfetch](https://github.com/fastfetch-cli/fastfetch)
- Tags: architecture
- Published: 2026-03-30

---

**Fastfetch implements a strict separation between platform-specific detection logic in `src/detection/keyboard/` and the presentation module in `src/modules/keyboard/`, but it currently enumerates physical keyboard devices only and does not expose keyboard layouts or input method editor (IME) information.**

The fastfetch-cli/fastfetch repository organizes hardware detection into a layered architecture where raw data gathering remains isolated from formatting and output logic. While the project reliably identifies connected keyboards across Linux, Windows, BSD, macOS, and Haiku, the detection framework intentionally stops at device enumeration and does not query desktop environment APIs for layout or input method data.

## How Fastfetch Detects Keyboard Devices

Fastfetch’s keyboard detection follows a three-tier architecture: platform-specific detectors, a common detection API, and the module presentation layer.

### Platform-Specific Detection Layer

Each supported operating system implements its own detector under `src/detection/keyboard/` that queries the kernel or system APIs for connected HID devices:

- **[`src/detection/keyboard/keyboard_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/keyboard/keyboard_linux.c)** — Parses `/proc/bus/input/devices` to extract device names, serial numbers, and handler types.
- **[`src/detection/keyboard/keyboard_windows.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/keyboard/keyboard_windows.c)** — Uses the Windows Raw Input API to enumerate keyboard hardware.
- **[`src/detection/keyboard/keyboard_bsd.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/keyboard/keyboard_bsd.c)** — Queries `sysctl` interfaces for device information.
- **[`src/detection/keyboard/keyboard_apple.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/keyboard/keyboard_apple.c)** — Walks the IOKit registry to identify HID keyboards on macOS.
- **[`src/detection/keyboard/keyboard_haiku.cpp`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/keyboard/keyboard_haiku.cpp)** — Calls Haiku’s `get_input_devices` system function.
- **[`src/detection/keyboard/keyboard_nosupport.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/keyboard/keyboard_nosupport.c)** — Returns a "not supported" stub for unsupported platforms.

### The Detection API

All platform implementations expose a unified entry point declared in [`src/detection/keyboard/keyboard.h`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/keyboard/keyboard.h):

```c
const char* ffDetectKeyboard(FFlist* devices);

```

This function populates an `FFlist` of `FFKeyboardDevice` structures containing `name` and `serial` fields. The return value is `NULL` on success or an error string on failure, allowing the module layer to handle diagnostics consistently across platforms.

### Module Presentation Layer

The [`src/modules/keyboard/keyboard.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/modules/keyboard/keyboard.c) file defines `ffPrintKeyboard()`, which orchestrates the output flow:

1. Allocates a result list and calls `ffDetectKeyboard()`.
2. Applies user-supplied filters from `--ignores` options defined in [`src/modules/keyboard/option.h`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/modules/keyboard/option.h).
3. Formats output as plain text, custom strings, or JSON via helpers in the module.

This separation ensures that adding a new platform requires only implementing the detection interface, while the formatting, filtering, and JSON serialization logic remains portable.

## Linux Detection Deep Dive

On Linux, [`src/detection/keyboard/keyboard_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/keyboard/keyboard_linux.c) implements a finite-state parser for the `/proc/bus/input/devices` pseudo-file. The kernel exports one device per block, with lines prefixed by single-letter identifiers:

```c
/* src/detection/keyboard/keyboard_linux.c */
const char* ffDetectKeyboard(FFlist* devices)
{
    FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate();
    if (!ffAppendFileBuffer("/proc/bus/input/devices", &content))
        return "Unable to read /proc/bus/input/devices";

    // Walk line-by-line parsing device blocks
    while (ffStrbufGetline(&line, &len, &content)) {
        switch (line[0]) {
            case 'N':   // "N: Name=..." — extract device name
                // Parse and trim the quoted name string
                break;

            case 'H':   // "H: Handlers=..." — verify kbd handler exists
                if (!ffStrbufMatchSeparatedNS(&kbd, handlersLen, handlers, ' '))
                    goto skipDevice;  // Not a keyboard if no "kbd" handler
                break;

            case 'B':   // "B: ..." — filter by capabilities bitmask
                // Skip pseudo-devices like Power buttons
                break;

            case 'U':   // "U: Uniq=..." — capture serial number
                break;

            case '\0':  // Empty line marks end of device block
                if (device.name.length > 0) {
                    FFKeyboardDevice* added = ffListAdd(devices);
                    ffStrbufInitMove(&added->name, &device.name);
                    ffStrbufInitMove(&added->serial, &device.serial);
                }
                break;
        }
    }
    return NULL;
}

```

The parser specifically looks for the `kbd` handler token in the `H:` line to distinguish actual keyboards from mice, touchpads, or power buttons that share the input subsystem.

## Why Fastfetch Does Not Report Layouts or IMEs

Despite the architecture supporting keyboard detection, fastfetch **does not** expose **keyboard layouts** (e.g., XKB `layout`/`variant`) or **input method editors** (ibus, fcitx, macOS Input Sources, Windows IME).

This limitation stems from three design constraints:

1. **Desktop Environment Fragmentation** — Layout and IME data resides in DE-specific APIs (X11 XKB, Wayland zwp_input_method, macOS Text Input Sources, Windows TSF) rather than kernel interfaces.
2. **Dependency Weight** — Querying these APIs requires linking against heavy GUI libraries (libX11, libwayland-client, Cocoa, COM) that conflict with fastfetch’s goal of remaining lightweight and dependency-minimal.
3. **Scope Definition** — The current `keyboard` module is strictly a **hardware enumerator**, not a configuration inspector.

Extending fastfetch to include layout or IME detection would require creating new detector files (e.g., `src/detection/keyboardlayout/`) that query the respective DE APIs and a corresponding module to expose the data.

## Practical Usage Examples

### Display Connected Keyboards

Run fastfetch with the keyboard module enabled (included in most presets by default):

```bash
fastfetch

```

Sample output:

```

 Keyboard
    Apple Keyboard
    Dell Wired Keyboard

```

### Custom Formatting

Output only device names using the format string option:

```bash
fastfetch --module keyboard --format "{name}"

```

Result:

```

Apple Keyboard
Dell Wired Keyboard

```

### Filter Out Specific Devices

Use the `--ignore` flag to exclude built-in or unwanted keyboards using substring matching:

```bash
fastfetch --module keyboard --ignore "Apple "

```

### JSON Output for Scripting

Extract structured data for further processing:

```bash
fastfetch --module keyboard --output json

```

Example JSON fragment:

```json
{
  "keyboard": {
    "result": [
      { "name": "Apple Keyboard", "serial": "12345678", "ignored": false },
      { "name": "Dell Wired Keyboard", "serial": "", "ignored": false }
    ]
  }
}

```

## Summary

- **Fastfetch** separates keyboard detection (`src/detection/keyboard/`) from presentation (`src/modules/keyboard/`) to maintain portable formatting logic across platforms.
- **Platform detectors** parse OS-specific APIs: `/proc/bus/input/devices` on Linux, Raw Input on Windows, IOKit on macOS, and sysctl on BSD.
- **Device enumeration** captures hardware names and serial numbers, but **does not include** active keyboard layouts or input methods.
- **Extending** fastfetch to support layouts would require new DE-specific detectors for XKB, ibus, fcitx, or platform IME APIs.
- Users can filter, format, or export keyboard data via the module’s command-line options and JSON output mode.

## Frequently Asked Questions

### Does fastfetch show my current keyboard layout?

No. According to the fastfetch source code, the detection framework in `src/detection/keyboard/` only enumerates physical hardware devices. It does not query XKB, Wayland input methods, or OS-specific layout registries. You would need to extend the codebase with a new detector module to capture layout information.

### How does fastfetch identify keyboards on Linux?

The Linux detector in [`src/detection/keyboard/keyboard_linux.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/detection/keyboard/keyboard_linux.c) reads `/proc/bus/input/devices` and parses device blocks looking for the `kbd` handler token. It extracts the `N:` (Name) and `U:` (Uniq/serial) fields, filtering out non-keyboard pseudo-devices by their capability bitmasks.

### Can I filter out specific keyboards from the output?

Yes. The keyboard module supports the `--ignore` option defined in [`src/modules/keyboard/option.h`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/modules/keyboard/option.h). Pass a substring to exclude matching devices: `fastfetch --module keyboard --ignore "Internal"`. The filter runs in [`src/modules/keyboard/keyboard.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/src/modules/keyboard/keyboard.c) after detection but before printing.

### Where is the keyboard detection code located?

All keyboard-related source files live under two directories: `src/detection/keyboard/` contains platform-specific implementations (Linux, Windows, BSD, macOS, Haiku) and the common header [`keyboard.h`](https://github.com/fastfetch-cli/fastfetch/blob/main/keyboard.h) declaring `ffDetectKeyboard()`. The presentation layer resides in `src/modules/keyboard/` and includes [`keyboard.c`](https://github.com/fastfetch-cli/fastfetch/blob/main/keyboard.c), [`option.h`](https://github.com/fastfetch-cli/fastfetch/blob/main/option.h), and formatting helpers.