Skip to content

MyGo 文档 ​

MyGo 用 Go 构建桌面应用。每个窗口显示两种界面之一,同一个应用可以同时拥有 两种窗口:

  • 网页:显示在操作系统的 webview 中(macOS 上是 WKWebView,Linux 上是 WebKitGTK,Windows 上是 WebView2),而不是捆绑一个浏览器。前端是用任意工具 构建的 HTML、CSS 和 JavaScript,通过 MyGo 从你的 Go 代码生成的 TypeScript 客户端来调用你的 Go 代码,其中带有你的 Go 结构体的类型和你方法的文档。
  • 原生 UI:由 MyGo 自己在 GPU 上绘制,仅用 Go 编写(包 ui):无需 HTML、JavaScript 或 webview,窗口即刻打开,占用内存很少。

两种窗口共用窗口选项与事件、菜单和桌面 API,整个应用是一个几兆字节的单一 Go 程序。

一个显示网页的窗口,其前端调用一个 Go 服务:

go
type Greeter struct{}

// Greet 返回一句问候。
func (Greeter) Greet(name string) string { return "Hello, " + name }

func main() {
	mygo.Bind(Greeter{})
	mygo.App.WhenReady(func() {
		mygo.NewWindow(mygo.WindowOptions{Title: "Hello", URL: "/"})
	})
	if err := mygo.App.Run(); err != nil {
		log.Fatal(err)
	}
}
ts
import { Greeter } from "./mygo"; // generated

document.body.textContent = await Greeter.greet("Ada");

一个显示原生 UI 的窗口,其视图是应用状态的一个 Go 函数:

go
type counter struct{ n int }

func (s *counter) view(c *ui.Context) {
	ui.Column(c).Fill().Center().Gap(12).Children(func() {
		ui.Text(c, fmt.Sprint(s.n)).FontSize(40).Bold()
		if ui.PrimaryButton(c, "Increment").Clicked() {
			s.n++
		}
	})
}

func main() {
	s := &counter{}
	mygo.App.WhenReady(func() {
		mygo.NewWindow(mygo.WindowOptions{
			Title:   "Counter",
			Content: ui.View(s.view),
		})
	})
	if err := mygo.App.Run(); err != nil {
		log.Fatal(err)
	}
}

网页适合丰富的文档、已有的 Web 代码以及只有浏览器才能做到的事;原生 UI 适合工具、设置、检查器和实用程序,以及必须即刻启动的应用。

入门 ​

  • 入门:安装工具,然后创建、开发和构建一个应用,用 原生 UI 或 Web 前端。

构建应用 ​

每个应用都具备的部分,无论其窗口显示原生 UI 还是网页。

  • 窗口:创建和安排两种窗口、它们的事件,以及显示网页的窗口 如何处理这些:导航、下载、权限、打印。
  • 应用程序:生命周期、退出、单实例、深度链接、文件关联、最近 文档、登录时启动、知名目录、跳转列表、浏览数据、cookie 与会话。
  • 菜单与托盘:应用菜单、上下文菜单和 Dock 菜单、快捷键和托盘 图标。
  • 文档:基于文档的应用,每个文件一个窗口,带有文件菜单、 自动保存、崩溃后恢复、关闭和退出前询问保存,以及其他应用改动的文件。
  • 语言:应用在其所附语言中的消息,带有 ICU 消息目录、带类型的 Go 和 TypeScript 函数、复数形式、MyGo 自己的字符串,以及用于测试布局的 伪区域设置。
  • 桌面 API:对话框、通知、剪贴板、shell、显示器、深色模式、 电源、网络状态、机密、文件监视和全局快捷键。
  • 剪贴板与拖拽数据:多种表示形式、文件列表、自定义 格式、惰性提供者,以及剪贴板持久化。
  • 音频:音效、流式音乐以及应用自己生成的声音,在 Go 中混音, 支持 WAV、Ogg Vorbis 和 MP3。
  • 启动器:仿照 Spotlight 和 Raycast 的应用,由快捷键在任意 应用之上唤起,用于查找并打开已安装的应用。

原生 UI ​

原生 UI有自己的文档:视图、布局、输入、导航和无障碍的 指南,以及从按钮到表格每个组件的页面。

网页 ​

  • 前端:页面在开发期间和构建产物中如何加载、mygo-runtime 包、自定义协议、自定义标题栏和拖入的文件。
  • 从前端调用 Go:绑定的服务、channel、带类型的事件和生成的 TypeScript 客户端。
  • 插件:以一个 Go 包和一个 npm 包提供的功能,如官方插件, 以及如何编写自己的插件。

发布 ​

  • 构建与分发:macOS、Windows 和 Linux 的打包应用、 签名、安装程序和磁盘镜像。
  • 自动更新:来自 GitHub releases、S3 存储桶、你自己的服务器 或应用自身更新服务的签名更新、增量更新,以及仿照 Sparkle 的更新窗口。
  • GitHub Actions:在你推送标签时构建、签名并公证各 平台的应用,并连同其更新一起发布的工作流。

官方插件 ​

  • Fetch:从 Go 发起 HTTP 请求的 fetch,不受 CORS 限制,可带任意请求头、流式请求体和取消。
  • WebSocket:连接由 Go 建立的 WebSocket,握手时 可带请求头。
  • SQLite:本地数据库,支持参数化查询与原子事务, 无需 cgo。
  • Watch:监视应用允许页面监视的目录中的文件变化。
  • Updater:仿照 Sparkle 的更新窗口,检查更新并提示 安装。
  • Terminal:面向原生 UI 的终端,基于 Ghostty 的终端 模拟器运行 shell 或任意程序。
  • Glass:为原生 UI 在所有平台上呈现 macOS 那样的 Liquid Glass,带有 macOS 的滚动边缘和背景模糊。
  • Game:游戏在普通应用之外所需的东西,按需启用:固定 步长的游戏循环及其输入、摄像机,以及统一标准布局的游戏手柄。
  • Loading:loading.dev 的 29 种加载指示器,用于 原生 UI。
  • Automation:从另一个进程驱动正在运行的应用, 如同端到端测试运行器和智能体所做的那样:它的窗口、元素、输入、菜单和 截图。

参考 ​

  • 配置:mygo.config.ts 或 mygo.json。
  • mygo CLI:命令与标志。
  • Go API:go doc -all github.com/egoist/mygo,包含每个类型和方法的文档。
  • 架构:MyGo 内部如何工作,面向贡献者,附各平台差异表。

环境要求 ​

开发应用需要 Go 1.27 或更高版本;含 Web 前端的项目, 其前端工具链还需要 Bun;纯原生 UI 项目只需 Go。MyGo 不 使用 cgo,因此无需安装 C 工具链,任何机器都能编译所有平台的应用;但 macOS 应用的签名和磁盘镜像需要一台 Mac。

应用运行于:

平台显示网页的窗口需要原生 UI 窗口需要
macOS 12 或更高无需其他东西:WKWebView 是 macOS 的一部分无需其他东西:它们用 Metal 绘制
Linux(x64、arm64)GTK 3 和 WebKitGTK 4.1(或 4.0):Debian 和 Ubuntu 上的 libwebkit2gtk-4.1-0,Fedora 上的 webkit2gtk4.1仅需 GTK 3
Windows 10 和 11(x64、arm64)WebView2 运行时,Windows 11 已内置无需其他东西:它们用 Direct3D 11 绘制

所有窗口都显示原生 UI 的应用既不需要 WebKitGTK,也不需要 WebView2 运行时。 Linux 上的托盘图标还需要 libayatana-appindicator3。

显示网页的应用可以用 mygo.WebViewAvailable() 询问本机是否有 webview (也可在 App.Run 之前调用),并在没有 webview 时打开一个原生 UI 窗口, 如表格最后一列所述。

mygo doctor 检查开发机器。