feat(decky): native-touch controller layout + restructured shortcuts + artwork

Ship a Steam Input controller layout (controller_config/punktfunk.vdf) whose
always-on `ts_n` command enables native touchscreen delivery on the Deck, and
have the backend auto-install it (apply_controller_config: copy to
controller_base/templates + upsert the per-account configset entry, chown to the
user, back up first). This is what makes the Deck touchscreen reach the client
as native touch under gamescope without disabling Steam Input (impossible on the
Deck) — no manual controller setup.

Two shortcuts sharing the "Punktfunk" name (so one config key covers both): a
hidden stateful stream entry and a visible stateless entry that launches straight
into the gamepad UI. Both get full artwork (grid/gridwide/hero/logo/icon,
replaced with exported PNGs). Drop the art-generation script.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 16:31:44 +02:00
parent 927a571414
commit 60d4653083
13 changed files with 1052 additions and 373 deletions
+5
View File
@@ -31,6 +31,7 @@ import {
import { streamPin } from "./library";
import { PunktfunkRoute, ROUTE } from "./page";
import { PairModal } from "./pair";
import { ensureGamepadUiShortcut } from "./steam";
// ----------------------------------------------------------------------------------------
// QAM panel — quick status + entry into the full page + one-tap stream for known hosts
@@ -196,6 +197,10 @@ const QamPanel: FC = () => {
export default definePlugin(() => {
routerHook.addRoute(ROUTE, PunktfunkRoute, { exact: true });
// Ensure the visible, stateless "Punktfunk" library entry (opens the gamepad UI / console
// home) exists and is repointed to the current plugin dir — also installs the native-touch
// controller config. Fire-and-forget: cosmetic library upkeep must never block plugin load.
void ensureGamepadUiShortcut();
return {
// `name` is the plugin's INTERNAL id — it must stay in sync with plugin.json (the loader
// keys plugins by it), so it stays lowercase; user-facing strings say "Punktfunk".