# HyprTile grid gamepad support

Gamepad input is intentionally limited to the launcher tile grid.

## Controls

- D-Pad or left analog stick: move the tile focus
- South face button (Xbox A / PlayStation Cross position): launch focused tile
- Left shoulder (LB/L1): previous page
- Right shoulder (RB/R1): next page

Page switching wraps around. When a page is changed with a shoulder button, the
first selectable tile on that page receives focus automatically.

The left stick uses a deadzone and delayed key-repeat so stick drift does not
cause accidental navigation.

## SDL3 / controller mappings

HyprTile does not initialize `SDL_INIT_GAMEPAD` at all unless Linux reports an
actual joystick/gamepad. After the launcher's first visible frame it performs a
small Linux input probe. On normal udev systems HyprTile dynamically opens
`libudev.so.1`, checks `ID_INPUT_JOYSTICK=1`, and installs an input hotplug
monitor. `libudev` is loaded at runtime, so no additional libudev development
package is required to compile HyprTile.

If no controller is attached, SDL's gamepad subsystem, joystick scan, and the
community mapping database are all skipped. When a controller is plugged in
later, the udev event causes HyprTile to initialize `SDL_INIT_GAMEPAD` once on
the main thread. From that point onward normal SDL3 hotplug events
(`SDL_EVENT_GAMEPAD_ADDED` / `SDL_EVENT_GAMEPAD_REMOVED`) handle devices for the
rest of the process lifetime.

If libudev is unexpectedly unavailable, HyprTile falls back to a low-frequency
probe of `/dev/input`, `/dev/input/by-id`, and `/dev/input/by-path`. This keeps
gamepad support functional without turning libudev into a hard runtime
requirement.

Controller mappings are loaded with `SDL_AddGamepadMappingsFromFile()`. The
community mapping database is only touched after SDL has been activated for a
real controller and is then loaded on a worker thread. SDL's built-in mappings
are available as soon as the deferred gamepad subsystem initialization
completes; additional mappings become available when the background database
load finishes.

Update the bundled community database with:

    make update-gamecontrollerdb

This downloads the current `gamecontrollerdb.txt` from:

    https://github.com/mdqinc/SDL_GameControllerDB

Runtime lookup order is:

1. `HYPRTILE_GAMECONTROLLERDB` when explicitly set
2. `/usr/local/share/hyprtile/gamecontrollerdb.txt`
3. `gamecontrollerdb.txt` beside the HyprTile executable
4. `~/.hyprtile/gamecontrollerdb.txt` as a per-user override

The per-user database is loaded last and can override mappings from the bundled
or system-wide database. If no external database is present, SDL3's built-in
mappings are still used.

## Scope

Gamepad input is disabled while an overlay, child lock, tile editor, file picker,
or tile drag operation owns the UI. It does not add gamepad controls to Notes,
Music, Video, Bluetooth, AI, Password Safe, Share Window, Hyprland Config, or
other overlays.
