LaunchUS

本指南目前只有简体中文版。 This guide is only in Chinese for now.

LaunchUS 插件

插件是 LaunchUS 本体之外的可选功能:想用才装,不占本体的体积。插件有两种:

小组件插件 能力插件
是什么 放进网格里的小组件,用 HTML / CSS / JavaScript 写 给系统加一种能力,比如「刘海暂存区」
文件夹后缀 .launchuswidget .launchusplugin
谁来干活 插件自己的页面(在一个受限的网页视图里) LaunchUS 里的一小段官方代码,插件包只负责说明
规范 小组件插件规范 下面
装在哪 ~/Library/Application Support/LaunchUS/Widgets/ ~/Library/Application Support/LaunchUS/Plugins/

安装

任选一种,从官网下载的 .zip 不用自己解压:

  1. 设置 › 插件 › 「安装插件…」,选 .zip 或解压出来的文件夹;
  2. 把 .zip 或文件夹拖进小组件库;
  3. 直接放进上面的文件夹,LaunchUS 会监视它,增删立刻生效。

LaunchUS 会自己解压 .zip,找到里面的 .launchuswidget 或 .launchusplugin 文件夹装好;压缩包里只有一个带 manifest.json 的文件夹也行。解压出来的东西不会被运行,只是复制。

能力插件

一个以 .launchusplugin 结尾的文件夹,里面只有一个 manifest.json:

{
  "spec": 1,
  "id": "com.launchus.notch-shelf",
  "capability": "notch-shelf",
  "name": { "en": "Notch Shelf", "zh-Hans": "刘海暂存区" },
  "description": { "en": "Drag files to the notch to park them there." },
  "version": "1.0.0",
  "author": "LaunchUS",
  "symbol": "tray.and.arrow.down"
}
字段 必需 说明
spec 否 规范版本,目前是 1。比 App 支持的新时插件不载入。
id 是 反向域名,至少两段,只用 ASCII 字母、数字、-、_,不能以 launchus. 开头。同一个 id 装两次会替换旧的。
capability 是 要打开的能力,见下表。LaunchUS 不认识这个能力时,插件会列在「已安装的插件」里,但不起作用(需要更新 LaunchUS)。
name、description name 必需 字符串,或「语言代码 → 文字」的对象,按 Mac 的首选语言匹配,找不到用 en。
version、author、symbol 否 显示在设置 › 插件。

能力的代码在 LaunchUS 里,插件包不带可执行内容,所以装一个能力插件不会让第三方代码在你的 Mac 上运行。新的能力随 LaunchUS 更新加入;想要新的能力,到论坛提出来。

现有的能力

不需要任何权限提示:它只读你正在拖的文件,只在你拖动时出现。


小组件插件规范(第 1 版)

插件有两种:小组件插件(本文)和给系统加能力的能力插件,见 PLUGINS.md。

LaunchUS 的小组件和 App 图标一起放在网格里,占 2×2、4×2 或 4×4 格,可以拖动、改大小、移除。 小组件分两种:

在启动台空白处右键 →「添加小组件…」打开小组件库,或者用链接 launchus://widgets。库里列出全部系统小组件和已安装的插件,可以预览每种尺寸,再添加到当前页。

1. 插件包

一个插件是一个以 .launchuswidget 结尾的文件夹:

weekend.launchuswidget/
├── manifest.json   必需:插件说明
├── index.html      必需:画小组件的页面(文件名可在 manifest 里改)
├── icon.png        可选:小组件库里显示的图标,建议 256×256
└── …               页面用到的其他文件(CSS、JS、图片、字体)

安装

任选一种:

  1. 小组件库里点「安装插件…」,选中插件文件夹;
  2. 把插件文件夹拖进小组件库;
  3. 直接放进 ~/Library/Application Support/LaunchUS/Widgets/(库里点「打开插件文件夹」)。

LaunchUS 会监视这个文件夹,增删插件立刻生效。改了插件里的文件后,打开一次小组件库就会重新扫描,网格上的页面也会重新载入。 安装同一个 id 的插件会替换旧的(旧的移到废纸篓)。库里可以把插件「移到废纸篓」;网格上用了这个插件的小组件会显示「未安装的小组件」,装回来就恢复。

2. manifest.json

{
  "spec": 1,
  "id": "com.example.weekend",
  "name": { "en": "Weekend", "zh-Hans": "周末倒计时", "ja": "週末まで" },
  "description": { "en": "Days left until the weekend.", "zh-Hans": "离周末还有几天。" },
  "version": "1.0.0",
  "author": "Example",
  "homepage": "https://example.com",
  "icon": "icon.png",
  "symbol": "calendar.badge.clock",
  "sizes": ["small", "medium"],
  "entry": "index.html",
  "refresh": 60,
  "permissions": [],
  "open": "https://example.com"
}
字段 必需 说明
spec 否 规范版本,目前是 1,省略按 1。比 App 支持的新时插件不载入,库里提示需要更新 LaunchUS。
id 是 反向域名,至少两段,只用 ASCII 字母、数字、-、_,不超过 128 字符。不能以 launchus. 开头(留给系统小组件)。网格上的小组件靠它找到插件,发布后不要改。
name 是 名字。字符串,或「语言代码 → 文字」的对象。按 Mac 的首选语言匹配(zh-Hans-CN → zh-Hans → zh),找不到用 en,再找不到用任意一个。
description 否 一两句说明,格式同 name,显示在小组件库。
version、author、homepage 否 显示在小组件库。
icon 否 插件文件夹里的图片路径。
symbol 否 没有 icon 时用的 SF Symbol 名字,默认 puzzlepiece.extension。
sizes 是 支持的尺寸,small(2×2)、medium(4×2)、large(4×4)中的一个或几个。不认识的值会被忽略;一个都不剩时插件不载入。
entry 否 页面路径,默认 index.html,必须在插件文件夹里。
refresh 否 秒数。启动台打开期间每隔这么久发一次 refresh 事件(最少 1 秒)。
permissions 否 权限列表,见第 4 节。不认识的权限会被忽略。
open 否 点击小组件时打开的链接,https: 或其他 App 的 URL scheme。不允许 file:、javascript:、data:。
openApp 否 点击小组件时打开的 App 的 bundle ID,比 open 优先。

没有 open 和 openApp 时点击小组件不做任何事。

3. 页面

页面在一个不接收鼠标的网页视图里显示,铺满整张卡片:

页面拿到的 CSS 变量和属性

LaunchUS 在页面脚本运行之前给 <html> 设好:

名字 例子 说明
--launchus-unit 78px 一格的尺度。小尺寸卡片宽约 2 unit,中尺寸约 4 × 2 unit。系统小组件的正文是 0.12–0.16 unit,大数字 0.5 unit。
--launchus-width / --launchus-height 156px 卡片的宽高。
data-size small 当前尺寸,可以写 html[data-size="medium"] .detail { display: block }。
data-theme dark dark 或 light。

window.launchus

interface LaunchUS {
  readonly spec: 1
  readonly size: "small" | "medium" | "large"
  readonly width: number        // 卡片宽,pt
  readonly height: number       // 卡片高,pt
  readonly unit: number         // 同 --launchus-unit,pt
  readonly theme: "dark" | "light"
  readonly locale: string       // Mac 的首选语言,如 "zh-Hans-CN"
  readonly visible: boolean     // 启动台是否打开着
  on(event: "change" | "show" | "hide" | "refresh", fn: (detail?: any) => void): void
  off(event: string, fn: Function): void
  system(): Promise<SystemSample>   // 需要 "system" 权限
}

interface SystemSample {
  cpu: number                                   // 0–1,全部核心
  memory: { used: number, total: number }       // 字节
  disk:   { used: number, total: number }       // 字节,启动磁盘
  battery: { level: number, charging: boolean } | null   // level 0–1;没有电池时为 null
  network: { download: number, upload: number } // 字节 / 秒
  uptime: number                                // 开机以来的秒数
}

事件:

事件 什么时候
change 尺寸、卡片大小或深浅色变了,参数是新的状态。
show / hide 启动台打开 / 收起。收起期间请停掉动画和轮询。
refresh 启动台打开期间每 refresh 秒一次(manifest 里设了才有)。

launchus 在页面任何脚本之前就已存在,不需要等待。

4. 权限

权限 允许 不声明时
network 访问网络:fetch、XMLHttpRequest、WebSocket、远程图片和字体。 一切 http(s)、ws(s)、ftp 请求都被拦下。
system 调用 launchus.system() 读 CPU、内存、磁盘、电池和网速。 launchus.system() 返回被拒绝的 Promise。

小组件库会把插件的权限显示给用户(「可以联网」「不联网」「读取系统状态」)。只申请真正用到的权限。

插件拿不到的东西:本地文件(自己文件夹以外)、日历、通讯录、剪贴板、启动台的布局和 App 列表、打开链接或 App(只能由用户点击触发 open / openApp)。

5. 性能

6. 版本兼容

7. 示例

docs/widgets/ 里有两个能直接安装的示例:

最小可用的插件:

{ "id": "com.example.hello", "name": "Hello", "sizes": ["small"] }
<!doctype html>
<meta charset="utf-8">
<style>
  body { margin: 0; height: 100vh; display: grid; place-items: center;
         font: 600 calc(var(--launchus-unit) * 0.3) -apple-system, sans-serif; color: white; }
  html[data-theme="light"] body { color: black; }
</style>
<body>Hello</body>

← 插件社区