Files
Warp/apps/desktop/README.md
T
tajniak81andClaude Opus 5.5 b6bf3ce741
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Test (windows-latest) (push) Canceled after 0s
CI / Storage tests on PostgreSQL (push) Canceled after 0s
CI / Complement (federation off) (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
CI / Smoke test the binary (push) Canceled after 0s
CI / Admin panel (push) Canceled after 0s
CI / Web client (push) Canceled after 0s
Desktop client (warp-desktop) with Wails v3
apps/desktop is the web client in a native window. It embeds the same
build warp-web does and serves it through the same Go package, so every
screen is shared. Unlike warp-web it proxies nothing: the client calls the
homeserver directly, and the CSP allows the homeserver plus any https:
and wss: origin for the call backend.

- First run asks for the homeserver: a server name or address, with
  .well-known discovery and a /versions check; File > Change homeserver
  asks again. Signed-in sessions keep their own base URL, so a change
  never sends one server's token to another.
- Links to other sites open in the system browser (/_desktop/links.js,
  added to index.html); only http, https and mailto are opened.
- One instance at a time, since sessions and keys live in the webview's
  storage.
- Dev builds open the DevTools Protocol on Windows when
  WARP_DESKTOP_REMOTE_DEBUGGING_PORT is set, for scripted testing.
- Packaging: icon, version info and manifest in the Windows exe, a macOS
  .app with camera and microphone descriptions, Linux packages via nfpm.
  Make targets: desktop, desktop-run, desktop-test, desktop-resources,
  desktop-macos, desktop-linux.

Web client: host and client move out of internal/ so the desktop app can
import them, and host gains AnyCallOrigin. The Dockerfile, .dockerignore
and the vite output path follow the move.

Pinned to Wails v3.0.0-beta.27.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 21:43:54 +02:00

146 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Warp desktop client
The [web client](../web/README.md) in a native window, built with
[Wails v3](https://v3alpha.wails.io). Every screen is the web client's:
`warp-desktop` embeds the same build `warp-web` does and serves it through
the same Go package (`apps/web/host`), so web and desktop don't drift
apart. It runs on Windows (WebView2), macOS (WKWebView) and Linux
(WebKitGTK).
```
window ──► wails.localhost ──► shell (this app) ── the web client, /config.json
│ first-run page, links
└──────────────────────────────────────────────► homeserver /_matrix/*
```
Unlike `warp-web`, the desktop app isn't installed next to one homeserver,
so it proxies nothing. The client calls the homeserver directly, the way
any Matrix client does; homeservers answer CORS for every origin. The
Content-Security-Policy allows the homeserver plus any `https:` and `wss:`
origin, because the call backend (the LiveKit JWT service and SFU) is
learned from the homeserver at run time and can't be listed in advance.
## What it adds to the web client
- **First run asks for the homeserver.** A server name (`example.org`) or
an address. Discovery follows `/.well-known/matrix/client` and checks
`/_matrix/client/versions`. If the well-known document names an address
that doesn't answer, the typed address is used when that one works.
**File → Change homeserver…** asks again. A session already signed in
keeps the server it signed in to until you sign out, so changing the
homeserver never sends one server's access token to another.
- **Links to other sites open in the system browser.** That covers a URL in
a message, `target="_blank"` and `window.open`. Without this they would
replace the app in its window or open a bare webview window.
`/_desktop/links.js` does it; the shell adds a `<script>` tag for it to
`index.html`. Only `http`, `https` and `mailto` URLs are opened.
- **One instance at a time.** Sessions and encryption keys live in the
webview's storage, and two instances on one store would both sync and
use the same one-time keys. Starting the app again brings the open window
forward.
## Where things are kept
| What | Where |
|---|---|
| The chosen homeserver | `desktop.json` in the user config directory, under `Warp` (`%AppData%\Warp` on Windows, `~/Library/Application Support/Warp` on macOS, `~/.config/Warp` on Linux) |
| Sessions, encryption keys, cache | the webview's storage: `%LocalAppData%\Warp\WebView2` on Windows; the platform webview's default location elsewhere |
Signing out deletes a session's keys, the same as in the browser (see
[Encryption keys in the browser](../web/README.md#encryption-keys-in-the-browser)).
## Build and run
Requires Go 1.26, Node 22 and pnpm. On Windows the WebView2 runtime, which
Windows 11 ships with, and no C compiler. On macOS, Xcode's command line
tools. On Linux, a C compiler with `libgtk-4-dev` and `libwebkitgtk-6.0-dev`
(Wails needs cgo there, and builds against GTK 4 by default).
```bash
pnpm install
make desktop # builds the web client, then bin/warp-desktop
./bin/warp-desktop
```
| Flag | Environment | |
|---|---|---|
| `-homeserver` | `WARP_DESKTOP_HOMESERVER` | use this homeserver for this run without saving it |
| `-version` | | print the version |
| Command | What |
|---|---|
| `make desktop` | a release build: `-tags production` (no developer tools), and on Windows a GUI program with no console |
| `make desktop-run` | build the web client and run the app with the developer tools (View → Open Developer Tools) |
| `make desktop-test` | vet and test the Go code |
| `make desktop-macos` | on macOS: `bin/Warp.app` |
| `make desktop-linux` | on Linux: `bin/warp-desktop.deb`, `.rpm` and `.pkg.tar.zst` |
| `make desktop-resources` | regenerate the icons and the Windows `.syso` files |
A development build (one without `-tags production`) also opens the Chrome
DevTools Protocol when `WARP_DESKTOP_REMOTE_DEBUGGING_PORT` is set, on
Windows. A script or Playwright can then drive the real window:
```bash
WARP_DESKTOP_REMOTE_DEBUGGING_PORT=9229 go run ./cmd/warp-desktop
```
## Packaging
The inputs are in `build/`. The `wails3` CLI does the generating and the
Linux packaging; the Makefile runs it with `go run` at the version
`go.mod` pins (`v3.0.0-beta.27`), so it needs no install. `DESKTOP_VERSION`
in the Makefile (default `0.1.0`) is the version the OS sees in each
package; `-version` prints the build's git version.
- **Windows.** `cmd/warp-desktop/rsrc_windows_{amd64,arm64}.syso` carry the
icon, the version info and the application manifest (per-monitor DPI,
common controls 6, `asInvoker`). They are committed, so `make desktop`
(and a plain `go build`) links them in with no extra step. The icon,
`build/windows/icon.ico`, takes 16–48 px from the brand favicon (the
symbol's small cut) and 64–256 px from the app icon tile;
`build/windows/mkico.go` merges the two. After changing the icon,
`build/windows/info.json`, the manifest or `DESKTOP_VERSION`, run
`make desktop-resources` and commit the `.syso` files.
- **macOS.** `make desktop-macos`, on a Mac, builds the binary and puts it
in `bin/Warp.app` with `build/darwin/Info.plist` and `icons.icns`, then
signs the bundle ad hoc. The `Info.plist` has `NSCameraUsageDescription`
and `NSMicrophoneUsageDescription`: without them macOS ends the app the
moment a call or the QR scanner asks for the camera or microphone. The
bundle is for the CPU it was built on, and ad-hoc signed it opens only on
the machine that built it; to hand it out, sign it with a Developer ID
and notarize it.
- **Linux.** `make desktop-linux`, on Linux, builds the binary and turns it
into `.deb`, `.rpm` and Arch packages with nfpm (through `wails3 tool
package`, configured by `build/linux/nfpm.yaml`). They install
`/usr/bin/warp-desktop`, a menu entry and the icon, and depend on GTK 4
and WebKitGTK 6.0 (Ubuntu 24.04+, Debian 13+, Fedora 40+).
`DESKTOP_FORMATS=deb` builds one format; `DESKTOP_MAINTAINER` defaults
to your git name and email.
`build/appicon.png` and `build/windows/favicon.ico` are copies from the
brand kit (`DESIGN/warp-brand/logo-kit`, not in git):
`symbol/warp-symbol-app-icon-1024.png` and `web/favicon.ico`.
## Layout
| Path | What |
|---|---|
| `cmd/warp-desktop/` | the binary: the Wails app, window, menu and single-instance lock |
| `internal/shell/` | the webview's `http.Handler`: the client through `apps/web/host`, the first-run page and discovery, the settings file, links |
| `build/` | packaging inputs: icons, the Windows manifest and version info, `Info.plist`, the nfpm config |
## Not yet
These follow from [PLAN.md §8.3](../../PLAN.md):
- Installers and signing: a Windows installer (NSIS or MSIX) and a signed
executable, a universal (arm64 + amd64), Developer ID signed and
notarized macOS `.app` in a `.dmg`, an AppImage or Flatpak. `wails3`
has tasks for most of these. None of the packages above is built in CI
yet.
- Native notifications, a tray icon, auto-update.
- Sync and encryption in Go (`mautrix-go`) behind the same Pinia stores,
with the access token in the OS keychain. Today the desktop app runs
matrix-js-sdk in the webview exactly as the browser does. Whether to move
this to Go is open question 5 in the plan.