Skip to content

Support Bluetooth keyboards in the live installer - #133

Open
damos1212 wants to merge 2 commits into
omacom:quattrofrom
damos1212:bluetooth-installer
Open

Support Bluetooth keyboards in the live installer#133
damos1212 wants to merge 2 commits into
omacom:quattrofrom
damos1212:bluetooth-installer

Conversation

@damos1212

@damos1212 damos1212 commented Aug 28, 2026

Copy link
Copy Markdown

Why

The live installer currently assumes that a keyboard can be connected through
USB or a 2.4 GHz receiver. That is not always possible: some keyboards are
Bluetooth-only, some USB connections provide charging but not wired input, and
some machines do not have a compatible free port or the required cable.

A mouse does not resolve this because the text installer still needs keyboard
input for account details and encryption credentials. The useful path is to
break the pairing catch-22 automatically: discover and pair the keyboard while
the welcome screen is waiting, then use that keyboard for the installer itself.

This complements omacom/omarchy#8816, which provides Bluetooth input at the
encrypted-disk prompt after installation. Both layers are needed for an
installation that does not depend on a temporary USB keyboard.

Pairing flow

  1. The welcome screen asks users with a Bluetooth keyboard to put it in pairing
    mode.
  2. The live ISO powers on Bluetooth and scans in the background while that
    screen is waiting.
  3. The helper requires keyboard-specific discovery information; a generic HID service alone is not enough.
  4. If exactly one eligible unpaired keyboard is visible, pairing starts
    automatically. If several are visible, it pairs none rather than guessing.
  5. When required, the user types the displayed pairing code on the Bluetooth
    keyboard itself and presses Return. This is handled by the Bluetooth pairing
    protocol before normal HID input is available, so no existing mouse or
    keyboard is required.
  6. The helper trusts and connects the keyboard. The user can then press Return
    on it to enter and complete the normal installer.

Scanning is limited to the welcome screen and is stopped when installation
begins.

Encrypted first reboot

Pairing only in the ephemeral live environment would leave a cable-free install
stranded at its first LUKS prompt. On encrypted, non-deferred installations,
when the bundled runtime supports it, the configurator therefore offers a separate opt-in to carry the selected bond
into the installed system and enable the early-boot support from
omacom/omarchy#8816.

That second decision is not implied by installer pairing. The prompt explains
that the bond material will be included in the unencrypted boot image and that
Bluetooth radio, firmware, or battery failures remain possible.

The orchestrator validates the controller and device addresses, rejects unsafe
symlinks, copies only the selected bond and controller metadata, and invokes the
runtime setup before the final Limine UKI build. It does not copy unrelated
phones, headsets, or other paired devices.

Limitations

  • Multiple nearby unpaired keyboards require a fallback rather than an
    automatic guess.
  • Unusual pairing methods may not support the DisplayOnly keyboard flow.
  • Adapter or firmware incompatibility can still prevent discovery.
  • Firmware and BIOS interfaces remain outside the live operating system and
    cannot gain Bluetooth support from this change.

Failure handling

The pairing helper stops and reaps its pairing/scanning processes when the welcome screen ends. The welcome animation stops before passkeys are displayed. Failed attempts can retry, and connection retries preserve an existing successful bond. The helper writes its private selection marker atomically only after confirming paired, trusted, and connected state.

The build records whether its runtime includes Bluetooth-unlock support. The configurator gates the encrypted-boot option on that capability. If support is absent, it requires acknowledgement that another keyboard is available after reboot or aborts. The orchestrator checks the installed command before copying bond data. Handoff rejects unsafe source/cache and target ancestor/file symlinks and restricts copied state permissions.

Validation

  • Pairing, cancellation, runtime-capability, and greeter-order fixtures: bash test/unit/bluetooth-keyboard-pair-test.sh.
  • Bond handoff and provisioning regressions: python3 -m unittest test.unit.test_bluetooth_unlock test.unit.test_provisioning_state.
  • Python compilation, Bash syntax, and git diff --check.

The full Python baseline has 50 existing keyboard-layout errors because localectl cannot access the system bus in the test sandbox. That suite is not reported as passing.

Remaining verification

This PR is open for review. No ISO build, physical Bluetooth keyboard pairing/passkey UI check, encrypted first reboot, or firmware compatibility test has been performed. The fixtures verify software boundaries, not hardware acceptance. Encrypted-boot support requires a runtime package carrying omacom/omarchy#8816; installer pairing remains a separate operation.

@damos1212
damos1212 marked this pull request as ready for review August 28, 2026 21:36
@damos1212

Copy link
Copy Markdown
Author

Audited the installer pairing flow and its handoff to omacom/omarchy#8816, then added a follow-up fix.

  • Terminating the welcome helper now exits and reaps its pairing/scanning children instead of leaving the configurator waiting for the scan deadline.
  • Pairing requires keyboard-specific evidence and refuses multiple candidates. Failed attempts can retry; connection retries preserve an already successful bond instead of invoking pair again and removing it.
  • The selection marker is written atomically with private permissions only after paired, trusted, and connected state is confirmed.
  • The welcome animation stops before pairing begins, so it cannot paint over passkeys.
  • The ISO records whether its bundled runtime includes Bluetooth-unlock support. Unsupported runtimes require fallback-keyboard acknowledgement or abort; the target command is also checked before bond copying.
  • Handoff rejects additional source/cache and target ancestor/file symlinks, validates the marker shape, and tightens copied state permissions.

Validation: pairing success, mouse/multiple-candidate refusal, disconnected state, cancellation/child cleanup, retry-after-pair-failure, and connection retry without re-pairing passed. Both retry cases crossed the real cooldown. Capability transitions, fallback acknowledgement/abort, and greeter ordering fixtures passed. All 31 focused Bluetooth/provisioning Python tests passed, along with compilation, Bash syntax, and git diff --check. A cross-PR fixture passed through the actual runtime setup and ISO validation for both Classic Bluetooth and BLE bonds.

Remaining acceptance work: build and boot an ISO, exercise a physical keyboard/passkey UI, and test the encrypted first reboot. Raw bluetoothctl pairing output still reaches the terminal; device-name sanitization is not a complete terminal-output filter. The full Python baseline remains unverified because 50 existing keyboard-layout cases cannot access the system bus in the sandbox. The description now matches the current open-for-review state and avoids claiming hardware validation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant