PrimoDev/ apps

PoorDeck

Painel estilo Stream Deck pro Mac, controlado pelo celular

  • macOS
  • Web (phone, tablet or any browser on the same Wi-Fi)
  • Grátis
  • Open source
  • v0.0.3

O que é o PoorDeck?

O PoorDeck é um painel de controle no estilo Stream Deck pro Mac que você usa pelo celular, tablet ou qualquer navegador na mesma rede Wi-Fi. Um app de barra de menus no Mac serve a interface, executa as ações e tem o editor de páginas, botões e tema.

Ainda está em desenvolvimento (WIP), nas versões 0.x. É grátis e o código está no GitHub (o repositório ainda não declara uma licença); pra instalar, baixe o DMG nos Releases, que não é assinado nem notarizado, ou rode pelo código-fonte.

O que ele faz

  1. 01Pareamento por QR code ou URL, sem nuvem e sem conta
  2. 02Botões que abrem ou trazem pra frente apps do Mac, com o ícone real
  3. 03Atalhos de teclado com qualquer combinação de ⌘ ⌥ ⌃ ⇧
  4. 04Teclas de mídia: tocar e pausar, próxima, anterior, volume e mudo
  5. 05Volume do sistema e volume por app com reforço até 2x
  6. 06Página Dock que espelha os apps abertos e fixados
  7. 07Páginas com swipe e colunas separadas pra retrato e paisagem
  8. 08Editor de páginas, botões e tema com prévia do aparelho, e packs pra importar e exportar páginas

Perguntas frequentes

O PoorDeck é grátis?
Sim. É gratuito e o código está no GitHub. O repositório ainda não tem um arquivo de licença.
Está pronto pra usar?
Ainda não está finalizado: o projeto está marcado como WIP e as versões são 0.x. Dá pra instalar e testar, mas espere mudanças.
Qual versão do macOS e o que mais eu preciso?
macOS 14.2 ou mais novo no Mac. No outro aparelho, só um navegador na mesma rede Wi-Fi; o cliente web pode ser instalado na tela inicial.
Como instalo e passo pelo Gatekeeper?
Baixe o DMG nos Releases e arraste o PoorDeck pra Aplicativos. O build não é assinado nem notarizado, então na primeira vez clique com o botão direito no app e escolha Abrir, ou rode xattr -dr com.apple.quarantine /Applications/PoorDeck.app.
Que permissões ele pede?
Rede local, pra servir o painel pro celular; Acessibilidade, pra enviar atalhos de teclado; e captura de áudio, pra controlar o volume de cada app. Tudo fica na rede local, sem nuvem.
Qual a diferença pra um Stream Deck?
O Stream Deck é um aparelho físico da Elgato. O PoorDeck usa uma tela que você já tem, como celular ou tablet, e o Mac faz o papel de servidor.

Documentação

README do repositório lucianodiisouza/PoorDeck, atualizado a cada deploy. O texto original é em inglês.

A Stream-Deck-style control surface for your Mac — driven from your phone, tablet, or any browser on the same Wi-Fi.

Screenshot 2026-08-12 at 10 19 12

PoorDeck is two projects:

  • desktop/ — a macOS menu-bar app (SwiftUI) that is the server. It hosts the client, executes the actions, holds the configuration, and gives you the editor UI for pages, buttons, and theme.
  • client/ — a Svelte + Vite web app the desktop serves. It's a thin renderer: it draws the pages and sends button presses over a WebSocket.

You install the desktop app on your Mac, then pair a device by scanning a QR code (or typing the URL). Same Wi-Fi is all it needs — no cloud, no account.

Architecture

┌──────────────── Mac ────────────────┐        ┌──── phone / tablet / web ────┐
│  PoorDeck.app (menu bar + config)    │  http  │  Svelte client                │
│  • HTTP + WebSocket server (native)  │◀──────▶│  • renders pages              │
│  • Bonjour  _poordeck._tcp           │   ws   │  • swipe to switch page       │
│  • executes actions, edits layout    │        │  • tap to fire an action      │
│  • persists layout to disk           │        │  • drives volume sliders      │
└──────────────────────────────────────┘        └───────────────────────────────┘

The server is built on Network.framework — no third-party dependencies. The HTTP server serves the built client and upgrades /ws to a WebSocket that speaks the JSON protocol in desktop/…/Model/Protocol.swift (mirrored in client/src/lib/types.ts). On connect the server pushes the full resolved layout (app icons baked in as data URLs); it re-pushes whenever you edit the layout in the config window, so connected devices update live.

What it does

  • Pairing — the config window shows a QR code / URL for a device on the same network. Each device persists a stable deviceId in localStorage, so a reload or reconnect from the same phone counts as one device, not three. The config UI shows a paired badge and a live connected-device count.
  • Open / switch apps — tap a button to launch or foreground a Mac app, rendered with the app's real icon.
  • Keyboard shortcuts — post any ⌘/⌥/⌃/⇧ combo via CGEvent (needs Accessibility permission).
  • Media keys — play/pause, next, previous, fast-forward, rewind, volume up/down, mute — the standard transport keys.
  • System volume — a master-output slider + mute, live in both directions.
  • Per-app volume — Core Audio process taps drive a live list of apps playing audio: icons, horizontal sliders, per-app mute, boost up to 2×. Built on the same process-tap pipeline that powers Voulum.
  • Dock page — mirror running (and pinned) apps; tap to activate or launch.
  • Pages & orientation — swipe between pages; per-page column counts for portrait and landscape, with an optional orientation lock.
  • Editors — add/edit/delete pages and buttons and edit the theme (background, surface, text, accent, corner radius) right in the config window, with a live device preview that can follow the device's real orientation.
  • Persistence — the layout is saved as JSON in ~/Library/Application Support/PoorDeck/layout.json and reloaded on launch (seeded from a default on first run).

Run it from source

Requires Xcode, xcodegen (brew install xcodegen), and Node.

scripts/build-run.sh

That builds the client, generates + builds the app, kills any running copy, and launches the freshly built bundle (printing its version, build time, and git commit so you know it's the latest). Look for the grid icon in the menu bar; open configuration to see the QR code, then scan it from a device on the same network.

To wipe every trace of the app from your Mac — built bundles, installed copies, saved layout, and preferences:

scripts/uninstall.sh

Client dev server (hot reload)

For UI iteration you can run Vite directly, but the WebSocket needs the desktop app running to connect to:

cd client && npm run dev

Releases (DMG)

Tagged commits ship a .dmg via GitHub Actions (.github/workflows/release.yml).

  • Cut a release — push a v* tag; the workflow builds a self-contained Release bundle (the client is embedded in PoorDeck.app/Contents/Resources/web), wraps it in a .dmg, and attaches it to a GitHub Release for that tag:

    git tag v0.1.0
    git push origin v0.1.0
  • First release / manual run — trigger the workflow from the Actions tab ("Run workflow") and type the tag; it creates the tag's release if it doesn't exist yet.

  • Build a DMG locally — same packaging, no CI:

    scripts/make-dmg.sh          # → dist/PoorDeck-<version>.dmg

The build is ad-hoc signed only — no Apple Developer ID signature or notarization. macOS quarantines it on first launch, so open it once with right-click ▸ Open, or clear the flag:

xattr -dr com.apple.quarantine /Applications/PoorDeck.app