# How to Configure Keyboard Shortcuts and Keymaps in ArmorPaint

> Learn to configure keyboard shortcuts and keymaps in ArmorPaint. Customize key assignments by editing JSON presets or programmatically using any_map_set() and keymap_save().

- Repository: [Armory 3D/armorpaint](https://github.com/armory3d/armorpaint)
- Tags: how-to-guide
- Published: 2026-09-11

---

**ArmorPaint stores keyboard shortcuts in a global `g_keymap` hash map initialized by `keymap_load()` in [`paint/sources/keymap.c`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/keymap.c), which reads JSON presets from `paint/assets/keymap_presets/` and can be customized by editing these files or programmatically calling `any_map_set()` followed by `keymap_save()`.**

ArmorPaint is an open-source 3D texture painting application built on the Armory3D engine. Configuring keyboard shortcuts and keymaps in ArmorPaint requires understanding its C-based input system, where shortcuts are defined as strings mapped to action identifiers and loaded from JSON preset files at startup.

## Core Keymap Architecture

ArmorPaint manages all input bindings through a centralized system centered on the global variable **`g_keymap`**. This hash map stores key-value pairs where the key is an action identifier (e.g., `tool_brush`, `action_paint`) and the value is a shortcut string (e.g., `"b"`, `"left"`).

When the application launches, **`keymap_load()`** in [`paint/sources/keymap.c`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/keymap.c) (lines 4‑18) initializes the system. It first calls **`keymap_get_default()`** (lines 40‑112) to populate `g_keymap` with hardcoded default values. If the user has selected a custom keymap via the configuration object, the function reads the corresponding JSON file from `paint/assets/keymap_presets/` using `data_get_blob()`, parses it, and overrides the default entries with any custom keys found (lines 7‑15).

## Keymap File Locations and Configuration

The active keymap filename is stored in the global configuration structure **`g_config->keymap`**, which is initialized in `config_init()` within [`paint/sources/config.c`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/config.c) (lines 100‑107). By default, desktop platforms use `"default.json"`, while touch devices automatically load `"touch.json"` from the `paint/assets/keymap_presets/` directory.

Available presets include:

- **[`default.json`](https://github.com/armory3d/armorpaint/blob/main/default.json)** – The built-in fallback generated at runtime when no custom map is specified.
- **[`touch.json`](https://github.com/armory3d/armorpaint/blob/main/touch.json)** – Optimized for touch interfaces.
- **[`blender.json`](https://github.com/armory3d/armorpaint/blob/main/blender.json)** – Example alternate preset demonstrating minimal overrides for Blender users.

## Methods to Configure Keyboard Shortcuts

You can customize shortcuts using three distinct approaches, depending on whether you prefer file editing, creating new presets, or runtime scripting.

### Method 1: Edit an Existing Preset

Locate the desired JSON file in `paint/assets/keymap_presets/` (e.g., [`blender.json`](https://github.com/armory3d/armorpaint/blob/main/blender.json)) and modify the values for specific actions. The JSON structure maps action identifiers directly to shortcut strings.

For example, to remap the brush tool and adjust brush radius controls:

```json
{
    "tool_brush": "b",
    "tool_eraser": "e",
    "brush_radius_increase": "]",
    "brush_radius_decrease": "[",
    "view_reset": "0",
    "view_front": "1"
}

```

Save the file and restart ArmorPaint, or reload the configuration to apply changes immediately.

### Method 2: Create a New Custom Keymap

Copy an existing preset file, rename it (e.g., [`my_custom.json`](https://github.com/armory3d/armorpaint/blob/main/my_custom.json)), and modify the shortcuts to your preference. Place the new file in `paint/assets/keymap_presets/`. To activate it:

1. Select the file from the **Keymap** dropdown in the ArmorPaint preferences UI.
2. Alternatively, manually set `g_config->keymap = "my_custom.json"` in your [`config.json`](https://github.com/armory3d/armorpaint/blob/main/config.json) file before launching.

The application will load [`my_custom.json`](https://github.com/armory3d/armorpaint/blob/main/my_custom.json) on the next startup, overriding the default bindings with your custom values.

### Method 3: Programmatic Runtime Changes

For plugins or scripts, modify the in-memory map directly using the `any_map_set()` function, then persist changes with `keymap_save()`:

```c
// Switch brush to "B" key and eraser to "X" at runtime
any_map_set(g_keymap, "tool_brush", "b");
any_map_set(g_keymap, "tool_eraser", "x");

// Save to disk (only works when not using "default.json")
keymap_save();

```

Note that `keymap_save()` (located at lines 20‑31 in [`paint/sources/keymap.c`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/keymap.c)) only writes to disk if the active keymap is not the built-in `"default.json"`.

## Shortcut String Syntax

The `keymap_shortcut()` function (lines 14‑55 in [`paint/sources/keymap.c`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/keymap.c)) parses shortcut strings at runtime. Valid syntax forms include:

- `"b"` – Single key press (B key).
- `"ctrl+shift+s"` – Combined modifier and key press.
- `"alt+number"` – Alt plus any number key.
- `"left"` / `"right"` – Mouse button identifiers handled specially by the input system.
- `"ctrl"` – Modifier-only shortcuts evaluated as boolean flags.
- `""` (empty string) – Disables the action entirely.

Modifier keys (`shift`, `ctrl`, `alt`) can be combined with primary keys using the plus sign separator.

## Querying Shortcuts in Custom Code

All UI and tool code checks input states through the **`keymap_shortcut()`** helper function, which interprets the shortcut string and checks modifier flags before calling the appropriate input query (`keyboard_down`, `keyboard_started`, `keyboard_repeat`, `mouse_down`, etc.).

Example usage in C:

```c
// Check if brush tool shortcut was just pressed
if (keymap_shortcut(any_map_get(g_keymap, "tool_brush"), SHORTCUT_TYPE_STARTED)) {
    // Activate brush tool
}

// Check if shortcut is currently held down
bool brush_pressed = keymap_shortcut(any_map_get(g_keymap, "tool_brush"),
                                    SHORTCUT_TYPE_DOWN);
if (brush_pressed) {
    // Execute continuous brush action
}

```

## Summary

- ArmorPaint uses a global `g_keymap` hash map defined in [`paint/sources/keymap.c`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/keymap.c) to store action-to-shortcut mappings.
- **`keymap_load()`** initializes defaults and overrides them with JSON presets from `paint/assets/keymap_presets/`.
- Customize shortcuts by editing existing JSON files, creating new presets, or calling `any_map_set()` programmatically.
- Use `keymap_save()` to persist changes, but only when a custom keymap (not `"default.json"`) is active.
- Shortcut strings support modifiers (`ctrl`, `shift`, `alt`), mouse buttons (`left`, `right`), and empty strings to disable actions.

## Frequently Asked Questions

### Where are keymap files stored in ArmorPaint?

Keymap preset files are located in the `paint/assets/keymap_presets/` directory of the ArmorPaint source repository. The active preset filename is stored in the `g_config->keymap` variable, initialized in [`paint/sources/config.c`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/config.c), and defaults to `"default.json"` on desktop or `"touch.json"` on mobile devices.

### How do I add modifier keys like Ctrl or Alt to a shortcut?

Use the plus sign separator in the JSON value string. For example, `"ctrl+shift+s"` binds the action to pressing Ctrl, Shift, and S simultaneously, while `"alt+number"` binds Alt plus any numeric key. The parser in `keymap_shortcut()` handles these combinations automatically.

### Can I disable a keyboard shortcut entirely?

Yes. Set the action's value to an empty string `""` in the JSON preset or via `any_map_set(g_keymap, "action_name", "")`. The `keymap_shortcut()` function interprets empty strings as disabled actions, preventing the input from triggering the associated function.

### Why are my custom keymap changes not saving to disk?

The **`keymap_save()`** function (lines 20‑31 in [`paint/sources/keymap.c`](https://github.com/armory3d/armorpaint/blob/main/paint/sources/keymap.c)) only writes to disk when the active keymap is not `"default.json"`. Ensure you have selected or created a custom preset filename (e.g., [`my_custom.json`](https://github.com/armory3d/armorpaint/blob/main/my_custom.json)) in your configuration before attempting to save runtime modifications.