33 Commits
Author SHA1 Message Date
Maksim Totmin eb7c6a23d5 chore(aur): sync PKGBUILD for cmd/ layout, pkgrel 3
- build: ./cmd/streamdeck-lets-go (not '.')
- source: bare filenames (AUR forbids subdirectories)
- install: srcdir root (matching source paths)
2026-08-26 11:24:21 +07:00
Maksim Totmin db85a371af fix: add cmd/streamdeck-lets-go, anchor .gitignore to root
The .gitignore pattern 'streamdeck-lets-go' matched the cmd/ directory
name, silently preventing the entrypoint from being tracked since the
restructure. Anchoring to '/streamdeck-lets-go' fixes this while still
ignoring the build binary at repo root.
2026-08-26 11:24:21 +07:00
Maksim Totmin c1bc4ddf15 docs: use HTTPS clone URL in README 2026-08-26 10:36:13 +07:00
Maksim Totmin 41856e6aaa refactor: restructure to standard Go project layout (cmd/ + internal/)
- Move entry point to cmd/streamdeck-lets-go/
- Split package main into internal packages:
  - internal/deck: hardware control (Deck, events, brightness)
  - internal/render: key rendering, icons, fonts, PageManager
  - internal/web: HTTP API + embedded SPA
  - internal/daemon: event loop, autoswitch, screensaver, actions
- Add ConfigDir() to internal/config
- Export cross-package API (Deck, PageManager, WebServer, etc.)
- Move dist/arch/ → packaging/ with updated PKGBUILD/.SRCINFO
- Add Makefile (build, test, vet, fmt, install)
- Update README with new build commands and project structure
- Delete unused media.go stub
2026-08-26 10:35:20 +07:00
Maksim Totmin 598bbe9ff1 fix: correct libusb dependency name in AUR package 2026-08-26 09:33:10 +07:00
Maksim Totmin f32a64ad10 chore: update AUR package URLs to totmin/streamdeck-lets-go 2026-08-26 09:26:07 +07:00
Maksim Totmin cbe8066606 fix: stale display outputs leaking between pages in web UI
Bug: when the StreamDeck was on a non-main page (e.g. dashboard) and the
web UI was opened in a private browser tab, the frontend defaulted to the
first page in config while display outputs from the other page were still
applied to keys sharing the same index.

Fix 1 (backend): send the current active page via SSE immediately on new
client connection so the frontend knows the correct page from the start.

Fix 2 (frontend): only apply display output text/background to keys that
have a display config, preventing cross-page leakage.
2026-07-12 11:27:10 +07:00
Maksim Totmin 3a16476d58 fix depends: libusb-1.0 -> libusb 2026-07-03 09:30:48 +07:00
Maksim Totmin 331458c97a release: v0.1.0 2026-07-03 09:29:49 +07:00
Maksim Totmin 5f95f4c83f fix AUR maintainer email 2026-07-03 09:22:59 +07:00
Maksim Totmin 4cafbe83ee add MIT license, AUR packaging files, and credits 2026-06-23 16:59:15 +07:00
Maksim Totmin 7e36fa7415 cli: add 'switch' command to change page on running daemon 2026-06-22 14:59:32 +07:00
Maksim Totmin 212768df9a cli: remove 'serve', fix --help to show commands 2026-06-22 14:52:16 +07:00
Maksim Totmin 3cba4fe436 cli: add --page flag to start on a specific page 2026-06-22 14:44:16 +07:00
Maksim Totmin 3e7a55550f reconnect: faster retry (1s) and health check (2s) 2026-06-22 10:28:43 +07:00
Maksim Totmin 62674eb3f5 daemon: pause work on device disconnect to save battery 2026-06-22 10:25:10 +07:00
Maksim Totmin 13bf035d2d text-only keys: transparent bg in web UI, #21252b bg on device 2026-06-22 10:14:06 +07:00
Maksim Totmin 22caab4b84 Dynamic key generators: plugin system for auto-generated pages
Add dynamic_keys support to PageConfig — a contract-based plugin
system where any executable outputs a JSON array of KeyConfig to stdout.
The daemon runs the generator on a configurable interval and renders
the keys dynamically on the Stream Deck.

Core changes:
- config: DynamicKeyGen struct (command/script, interval, timeout, max_keys)
- config: full validation for dynamic_keys fields
- action: execDynamicKeys() with safe JSON parsing (stderr logged separately,
  env vars STREAMDECK_KEY_COUNT / STREAMDECK_CONFIG_DIR)
- page: activeKeys() merges static + dynamic keys (static wins by index)
- page: startDynamicKeys / stopDynamicKeys lifecycle, per-page results cache
- page: rerenderActivePage() with deadlock-safe lock ordering
- daemon: event handler uses activeKeys() for dynamic key actions

Web UI:
- GET /api/pages returns effective_keys (merged static + cached dynamic)
- app.js: gridKeys uses effective_keys when available
- app.js: guard against editing dynamic keys through the UI
- index.html: " dynamic" badge + effective key count in page switcher
- polls /api/pages every 10s to keep the UI in sync

Image rendering:
- loadImage: gift.ResizeToFill instead of gift.Resize (preserves aspect
  ratio, crops to fill — no more stretched cover art)

Example & docs:
- config.example.json: games page with dynamic_keys + back button
- README.md: comprehensive Dynamic Key Generators section (architecture
  diagram, config reference, generator contract, merge behavior,
  env vars, error handling, Python + Shell examples, tips)
2026-06-21 21:05:32 +07:00
Maksim Totmin d171c26755 Fix keyboard input on Wayland: use ydotool instead of wtype
- Replace wtype with ydotool as primary keyboard input tool on Wayland
  (wtype had a bug sending ESC instead of correct keys to GUI apps)
- Use 'ydotool type' command for better Wine/game compatibility
- Automatically start ydotoold daemon on startup if available
- Keep wtype as fallback for backward compatibility
- Improve keyboard action support for games running in Wine
2026-06-17 22:19:54 +07:00
Maksim Totmin 2a23a038e3 Fix rendering of keys with background only (no icon or label) 2026-06-17 20:28:25 +07:00
Maksim Totmin 724618c9b4 Improve icon rendering: fix scaling and centering for emoji, FontAwesome, and SVG icons 2026-06-17 20:19:56 +07:00
Maksim Totmin f1583bcca4 Apply show_label_background to device rendering and display keys 2026-06-17 20:19:06 +07:00
Maksim Totmin 10cbf028f1 Add global show_label_background setting with UI control 2026-06-17 20:19:02 +07:00
Maksim Totmin 7047b6b4e3 fix: svg icons now respect icon_scale parameter 2026-06-17 15:12:17 +07:00
Maksim Totmin 434d5bc1a9 fix: x-if->x-show for page select to fix x-model+x-for race 2026-06-17 14:00:35 +07:00
Maksim Totmin 84038b5be2 fix: load FA locally instead of CDN; Alpine color input error via x-init+ 2026-06-17 13:53:48 +07:00
Maksim Totmin a093719bd1 fix: imageCache key includes targetSize/faScale; Alpine color input error breaks x-if rendering 2026-06-17 13:22:05 +07:00
Maksim Totmin 9e336404ed fix: honor icon_scale for all icon types in grid view
- index.html: replace three conditional render paths (FA CSS icon,
  image img, label span) with a single img always routed through
  /api/render, which correctly applies icon_scale, font_size, etc.
  FA icons were previously rendered via CSS font classes, bypassing
  the backend render endpoint and ignoring icon_scale
2026-06-17 12:28:26 +07:00
Maksim Totmin 8c2184b93d fix: restart periodic keys on device page switch, render display output in UI grid
- daemon.go: call stopPeriodicKeys/startPeriodicKeys after page switch
  from device gesture and auto-switch (was missing, causing goroutines
  to never restart for the correct page)
- app.js: forward display output background to /api/render preview URL
- index.html: show preview image and text from display output when key
  has no configured background/icon/label
2026-06-17 11:12:00 +07:00
Maksim Totmin 1d6748bc0c fix: keep active page on config save, add Cyrillic preview support, fix grid sizing
- daemon.go: save/restore active page on config reload instead of
  always activating default_page (fixes page switch on save)
- render.go: replace basicfont.Face7x13 with parseDisplayFace() for
  unicode/Cyrillic support in edit key preview
- web.go: add SSE endpoint (GET /api/events) for real-time page_changed
  events and POST /api/activate-page API
- app.js: persist active page via localStorage, listen for SSE
  page_changed events
- styles.css, index.html: fix grid sizing (width 100%, minmax(0, 1fr),
  aspect-ratio on key buttons, max-width 525px)
2026-06-17 10:48:31 +07:00
Maksim Totmin 9f85cbddd9 Multi-action keys with tap/long-press/double-tap/hold, gesture timing, display output colors, global font, and display output JSON/color parsing
- Multi-action system: each key supports multiple actions with different triggers
  (tap, long_press, double_tap, hold_start, hold_end)
- GestureEngine: timing-based gesture detection with configurable thresholds
- New config types: KeyAction, TimingConfig, DisplayOutput
- Display output now supports JSON format (text/background/text_color) and
  first-line-as-hex-color format for dynamic key backgrounds
- Display background colors are reflected in the web UI on the grid
- renderUnicodeText/renderUnicodeTextOnImage accept custom text color (fg)
- Global font setting (medium/regular) in Settings UI
- PageManager.defaultFont used as fallback for per-key font
- Alpine.js bundled locally (no CDN dependency)
- Web UI: action tabs (Tap/Long Press/Double Tap/Hold), unified More section
  with appearance + display settings, gesture timing sliders in Settings
- Grid: subtle action type icons in top-left corner matching display indicator style
- Backward compatible: old config 'action' field auto-migrated to 'actions' array
- M+ 1m font files in assets/ for reference
- Updated config.example.json and README with all new features
2026-06-17 00:09:48 +07:00
Maksim Totmin e536f97b18 Multi-device support, dynamic grid adaptation, keyboard action
- Multi-device: OpenAllDecks(), GET /api/decks, per-deck PageManagers
- Dynamic grid: frontend adapts to connected device layout
- Keyboard action: new action type for sending key combos via wtype/xdotool
- Key recorder UI: click-based modifier toggles + single key capture
- Config: remove hardcoded maxKey validation
- Screensaver and auto-switch sync across all decks
2026-06-16 22:51:39 +07:00
Maksim Totmin a187e2b268 Initial commit: Stream Deck daemon with web UI
- Web-based key editor (Alpine.js SPA)
- Actions: shell commands, scripts, built-in media/volume/brightness, page switching
- Keyboard shortcut action (wtype/xdotool)
- On-device display with periodic command output
- Auto page switching (Hyprland, Sway, Niri, GNOME, KDE, X11)
- Screensaver with idle detection
- Config hot-reload
- Multi-device support
2026-06-16 22:35:14 +07:00