Desktop client (warp-desktop) with Wails v3
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
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
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>
This commit is contained in:
1 parent
76dfc98a86
commit
b6bf3ce741
38 files changed
+1616
-17
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 7.3 KiB |
@@ -0,0 +1,18 @@
|
||||
//go:build !production
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// devBrowserArgs opens the Chrome DevTools Protocol on Windows when
|
||||
// WARP_DESKTOP_REMOTE_DEBUGGING_PORT is set, so a script or Playwright can
|
||||
// drive the app's webview. Production builds leave it out.
|
||||
func devBrowserArgs() []string {
|
||||
if p, err := strconv.Atoi(os.Getenv("WARP_DESKTOP_REMOTE_DEBUGGING_PORT")); err == nil && p > 0 {
|
||||
return []string{"--remote-debugging-port=" + strconv.Itoa(p)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
//go:build production
|
||||
|
||||
package main
|
||||
|
||||
func devBrowserArgs() []string { return nil }
|
||||
@@ -0,0 +1,163 @@
|
||||
// Command warp-desktop is the Warp desktop client: the web client in a
|
||||
// native window (Wails v3), talking to the homeserver directly.
|
||||
//
|
||||
// warp-desktop [-homeserver https://matrix.example.org]
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
|
||||
"github.com/dariuszjaniak/warp/apps/desktop/internal/shell"
|
||||
"github.com/dariuszjaniak/warp/apps/web/client"
|
||||
)
|
||||
|
||||
// Set with -ldflags "-X main.version=...".
|
||||
var version = "0.0.0-dev"
|
||||
|
||||
//go:embed appicon.png
|
||||
var icon []byte
|
||||
|
||||
// appID names the app to the OS: the single-instance lock, and the
|
||||
// directory the settings live in on Linux and macOS.
|
||||
const appID = "io.github.dariuszjaniak.warp"
|
||||
|
||||
func main() {
|
||||
if err := run(); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "warp-desktop:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
homeserver := flag.String("homeserver", os.Getenv("WARP_DESKTOP_HOMESERVER"),
|
||||
"homeserver base URL for this run, instead of the one chosen in the app (WARP_DESKTOP_HOMESERVER)")
|
||||
showVersion := flag.Bool("version", false, "print the version and exit")
|
||||
flag.Parse()
|
||||
|
||||
if *showVersion {
|
||||
fmt.Println("warp-desktop", version)
|
||||
return nil
|
||||
}
|
||||
|
||||
logger := slog.New(slog.NewTextHandler(os.Stderr, nil))
|
||||
slog.SetDefault(logger)
|
||||
|
||||
dirs, err := dataDirs()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
files, built := client.FS()
|
||||
if !built {
|
||||
logger.Warn("the web client was not built into this binary; serving a placeholder page")
|
||||
files = nil
|
||||
}
|
||||
|
||||
var app *application.App
|
||||
sh, err := shell.New(shell.Options{
|
||||
Store: shell.NewStore(filepath.Join(dirs.config, "desktop.json")),
|
||||
Homeserver: *homeserver,
|
||||
Client: files,
|
||||
Version: version,
|
||||
Logger: logger,
|
||||
OpenURL: func(u string) error { return app.Browser.OpenURL(u) },
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var window *application.WebviewWindow
|
||||
app = application.New(application.Options{
|
||||
Name: "Warp",
|
||||
Description: "A Matrix client",
|
||||
Icon: icon,
|
||||
Logger: logger,
|
||||
Assets: application.AssetOptions{Handler: sh},
|
||||
// The client's sessions and encryption keys are in the webview's
|
||||
// storage; two instances on one store would both sync and both
|
||||
// use the same one-time keys.
|
||||
SingleInstance: &application.SingleInstanceOptions{
|
||||
UniqueID: appID,
|
||||
OnSecondInstanceLaunch: func(application.SecondInstanceData) {
|
||||
if window != nil {
|
||||
window.Restore()
|
||||
window.Show()
|
||||
window.Focus()
|
||||
}
|
||||
},
|
||||
},
|
||||
Mac: application.MacOptions{
|
||||
ApplicationShouldTerminateAfterLastWindowClosed: true,
|
||||
},
|
||||
Windows: application.WindowsOptions{
|
||||
WebviewUserDataPath: dirs.webview,
|
||||
AdditionalBrowserArgs: devBrowserArgs(),
|
||||
},
|
||||
})
|
||||
|
||||
window = app.Window.NewWithOptions(application.WebviewWindowOptions{
|
||||
Name: "main",
|
||||
Title: "Warp",
|
||||
Width: 1200,
|
||||
Height: 800,
|
||||
MinWidth: 360,
|
||||
MinHeight: 480,
|
||||
URL: "/",
|
||||
})
|
||||
|
||||
app.Menu.SetApplicationMenu(appMenu(app, window))
|
||||
|
||||
return app.Run()
|
||||
}
|
||||
|
||||
func appMenu(app *application.App, window *application.WebviewWindow) *application.Menu {
|
||||
menu := app.NewMenu()
|
||||
if runtime.GOOS == "darwin" {
|
||||
menu.AddRole(application.AppMenu)
|
||||
}
|
||||
file := menu.AddSubmenu("File")
|
||||
file.Add("Change homeserver…").OnClick(func(*application.Context) {
|
||||
window.SetURL(shell.SetupPath)
|
||||
})
|
||||
file.AddSeparator()
|
||||
if runtime.GOOS == "darwin" {
|
||||
file.AddRole(application.CloseWindow)
|
||||
} else {
|
||||
file.AddRole(application.Quit)
|
||||
}
|
||||
menu.AddRole(application.EditMenu)
|
||||
menu.AddRole(application.ViewMenu)
|
||||
menu.AddRole(application.WindowMenu)
|
||||
return menu
|
||||
}
|
||||
|
||||
type dirs struct {
|
||||
config string // settings
|
||||
webview string // the webview's storage, on Windows
|
||||
}
|
||||
|
||||
func dataDirs() (dirs, error) {
|
||||
cfg, err := os.UserConfigDir()
|
||||
if err != nil {
|
||||
return dirs{}, err
|
||||
}
|
||||
d := dirs{config: filepath.Join(cfg, "Warp")}
|
||||
if runtime.GOOS == "windows" {
|
||||
// %LocalAppData%: the webview's storage is large and machine-local,
|
||||
// so it doesn't belong in the roaming profile with the settings.
|
||||
local, err := os.UserCacheDir()
|
||||
if err != nil {
|
||||
return dirs{}, err
|
||||
}
|
||||
d.webview = filepath.Join(local, "Warp", "WebView2")
|
||||
}
|
||||
return d, nil
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Reference in new issue
Block a user