0.4.5 计划在 contributions 中新增四个可选数组,让插件出现在侧栏面板以外的位置:独立窗口、一级页面、个人信息条和编辑器。它们都引用已声明的 workspaces[].id,加载该工作区的入口页面,并继承它的权限授予。安装页会新增「这个插件会出现在……」分组,逐项列出这些位置。
新增贡献一览
| 字段 | 数量上限 | 位置 |
|---|---|---|
windows | 8 | 独立窗口 |
pages | 1 | 一级导航入口加整页 |
profile_items | 2 | 个人信息条中的状态项和菜单 |
editors | 8 | 按扩展名打开文件的编辑器(0.4.5 仅声明) |
第一期限制
- 不支持 Agent 绑定和
agent.trigger:新位置中调用agent.*会返回PLUGIN_WORKSPACE_PERMISSION_DENIED。需要与 Agent 联动的功能,请继续放在侧栏工作区中。 - 窗口只能加载包内页面:0.4.5 的窗口只能打开清单中声明的 workspace 页面;加载外部网页留到 0.4.6。打开外链仍使用
ui.open_external。 - editors 只做声明:0.4.5 只校验
editors并在安装页「会出现在……」中展示,真正用插件打开文件要到 0.4.6。
windows:独立窗口
{
"id": "float",
"title": "悬浮计时器",
"workspace": "main",
"chrome": "none",
"resizable": false,
"taskbar": true,
"always_on_top": true,
"transparent": true,
"shadow": false,
"size": { "width": 320, "height": 200 },
"min_size": { "width": 64, "height": 64 },
"max_size": { "width": 640, "height": 400 },
"position": "bottom_right",
"remember_bounds": true,
"single_instance": true,
"layouts": [
{ "id": "orb", "size": { "width": 64, "height": 64 }, "anchor": "bottom_right" },
{ "id": "card", "size": { "width": 320, "height": 200 }, "anchor": "bottom_right" }
]
}
| 字段 | 取值 | 说明 |
|---|---|---|
id | 本地标识 | 插件内唯一。 |
title | 1–80 | 窗口标题。 |
workspace | workspace id | 窗口加载的工作区,必须已声明。 |
chrome | app | none | app:应用统一样式的标题栏;none:无框,除宿主关闭角标外全部像素交给插件。 |
resizable | 默认 true | 是否可调整大小。 |
taskbar | 默认 true | 是否显示任务栏项;设为 false 需要 ui.window.hide_taskbar。 |
always_on_top | 默认 false | 是否置顶;设为 true 需要 ui.window.always_on_top。 |
transparent | 默认 false | 是否透明;只有 chrome 为 none 时可以设为 true,需要 ui.window.transparent。 |
shadow | 默认 true | 是否显示窗口阴影。 |
size / min_size / max_size | { width, height } | 初始尺寸、最小尺寸、最大尺寸(逻辑像素)。 |
position | cascade(默认)| center | top_left | top_right | bottom_left | bottom_right | 初始位置:跟随打开者层叠、居中或屏幕四角。不接受绝对坐标。 |
remember_bounds | 默认 true | 重新打开时恢复上次的位置和尺寸;越界时回退到 position。 |
single_instance | 默认 true | 重复打开时只聚焦已有窗口。 |
layouts | ≤8 项 { id, size, anchor } | 可切换的预设布局;anchor 是切换时保持不动的角或 center。 |
尺寸边界
chrome为none时,size、min_size、max_size和layouts[].size的宽高取 48–3840;为app(以及待定的system)时取 120–3840。- 必须满足
min_size≤size≤max_size;layouts[].size也必须落在min_size和max_size之间。悬浮小球类窗口需要把min_size声明得足够小。 - 运行时宿主还会把窗口夹紧到所在显示器的工作区内,不允许覆盖全屏。
- 每个插件同时最多打开 4 个窗口,全局最多 12 个。
宿主兜底
chrome 为 none 的窗口右上角保留一块插件无法遮挡的热区,鼠标移入时显示宿主的关闭角标。所有插件窗口(包括隐藏了任务栏项的)都会出现在宿主的「插件窗口」列表中,用户可以从那里找到并关闭。插件停用、卸载、升级或权限变更时,它的窗口立即关闭;退出登录时所有插件窗口关闭。
pages:一级页面
最多 1 项:{ id, title, workspace, icon? }。title 为 1–32 字符,icon 引用 resources 中的资源 id。宿主在一级导航中增加入口,并整页渲染该工作区。
profile_items:个人信息条
最多 2 项:{ id, label, icon?, menu }。label 为 1–32 字符;menu 最多 6 项,每项 { id, label, opens: { kind, id } },kind 取 workspace、window 或 page,id 必须引用已声明的对应项。状态文字在运行时通过 profile.set_status 更新,不超过 48 字,宿主按纯文本显示,不嵌入 iframe。
editors:编辑器(仅声明)
最多 8 项:{ id, title, workspace, extensions, priority, mode }。extensions 为 1–16 个扩展名(^[a-z0-9]{1,16}$);priority 取 default 或 option;mode 取 readonly 或 readwrite。
readwrite 可以通过校验,但按只读处理。真正用插件打开文件要到 0.4.6。新增权限
四项都是 Workspace 作用域权限,worker 写 host,授权按窗口引用的工作区记录。三项敏感权限建议声明为可选,安装页会单独勾选并提示风险(可能被用来仿冒系统或宿主界面)。
| 权限 | 何时需要 | 未授权时 |
|---|---|---|
ui.window | windows 非空 | window.open 返回 PLUGIN_WINDOW_PERMISSION_DENIED |
ui.window.always_on_top | 有窗口设置 always_on_top: true | 降级为不置顶 |
ui.window.hide_taskbar | 有窗口设置 taskbar: false | 降级为显示任务栏项 |
ui.window.transparent | 有窗口设置 transparent: true | 降级为不透明 |
声明了需要敏感权限的字段却没有申请对应权限时,安装会以 PLUGIN_MANIFEST_INVALID 拒绝。降级后的实际效果可以通过 window.capabilities 查询。
窗口 API
| Bridge 方法 | SDK(stabledgePlugin.window.*) | 说明 |
|---|---|---|
window.open | window.open | 参数 { window_id, user_activated },必须在用户操作中调用;single_instance 时已打开则聚焦并返回原句柄。 |
window.close | window.close | 省略句柄时关闭自己,只能关闭本插件的窗口。 |
window.focus | window.focus | 需要用户激活,防止抢焦点。 |
window.set_title | window.setTitle | 不超过 80 字,纯文本,同时影响任务栏标题。 |
window.set_layout | window.setLayout | 只能切换到 layouts 中声明的布局。 |
window.start_drag | window.startDragging | 开始拖动窗口。 |
window.capabilities | window.capabilities | 返回实际生效的能力:platform、chrome、transparent、always_on_top、taskbar、rounded_corners、layouts。 |
profile.set_status | — | 参数 { item_id, text },更新个人信息条状态文字。 |
SDK 会在窗口内自动把带 [data-se-drag-region] 属性的元素设为拖动区域,带 [data-se-no-drag] 的元素除外。窗口句柄是不透明字符串。
事件(通过 window.on 订阅):window.opened、window.closed(reason 取 user、plugin、disabled、logout、host_exit、crashed)、window.focus_changed。
错误码:PLUGIN_WINDOW_NOT_DECLARED、PLUGIN_WINDOW_LIMIT_REACHED、PLUGIN_WINDOW_PERMISSION_DENIED、PLUGIN_WINDOW_NOT_FOUND、PLUGIN_WINDOW_LAYOUT_NOT_DECLARED、PLUGIN_WINDOW_USER_ACTIVATION_REQUIRED、PLUGIN_WINDOW_OPEN_FAILED。
插件名保留名单
安装和升级时,插件的 name(包括各语言的展示名)会经过规范化(去掉首尾空白、统一全半角和大小写、去掉空格和常见分隔符)后,与两级保留名单比对:
- A 级:应用名(如 StablEdge 及其中文名)和系统窗口名(如任务管理器、系统设置、用户账户控制等及其英文名)。名称与之相同、以它们开头或以它们结尾,都会拒绝。
- B 级:宿主界面的短词(如设置、插件、技能、知识库、登录及对应英文)。只拒绝完全相同的名称,「翻译插件」这类正常名字不受影响。
命中时安装以 PLUGIN_MANIFEST_INVALID 拒绝,并说明命中的保留名。内置插件和通过官方公钥验签的插件豁免。只对新安装和升级生效,已经安装的插件不追溯。
待定事项
chrome取"system"(使用系统原生标题栏);取这个值时不允许透明。待定- 权限
ui.window.position:允许插件指定窗口坐标。待定 - 窗口标题由宿主强制加上「插件名 · 」前缀,插件只能修改后半段。待定