无边框窗口与自定义标题栏
系统标题栏是插件界面里唯一不属于你的部分。它在不同系统上长得不一样、占掉几十像素高度、样式你改不了。无边框窗口就是把这块壳去掉,界面完全由你掌控。
一行配置开启
把 main.frame 设为 false:
{
"id": "LB5UL2P0Q9FFF",
"version": "1.0.0",
"name": "Hello World",
"logo": "/logo.png",
"keywords": [],
"main": {
"frame": false,
"url": "index.html",
"width": 640,
"height": 480
}
}
frame 默认是 true。设为 false 后,窗口不带有任何外壳——没有边框、没有标题栏、没有系统工具栏,只剩网页内容。
代价是你必须自己补齐这些原生能力:拖拽移动窗口、最小化、最大化、关闭。少做一个,用户就会觉得「这插件怎么关不掉」。
可拖拽区:用 app-region
无边框窗口默认不可拖拽。要让用户按住某块区域移动窗口,需要用 CSS 属性 -webkit-app-region: drag 明确指定。
整窗可拖:
<body style="-webkit-app-region: drag">
</body>
更常见的做法是只让标题栏可拖:
.titlebar {
-webkit-app-region: drag;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 12px;
user-select: none;
}
关键陷阱:拖拽区和按钮互斥
这是无边框窗口最容易踩的坑。如果整个窗口或标题栏设成了 drag,里面的按钮会点不动——因为鼠标事件被窗口移动抢走了。必须在按钮上反向声明 no-drag:
.titlebar {
-webkit-app-region: drag;
}
.titlebar button,
.titlebar .interactive {
-webkit-app-region: no-drag;
}
这条规则是无边框窗口能不能用的分水岭。写了 drag 忘了写 no-drag,界面上所有按钮都会失效,而且现象很迷惑——用户能拖动窗口(说明插件在运行),但点按钮没反应。
另外注意,官方明确说明当前只支持矩形形状。所以不能做成「只有文字区域可拖、图标区域不可拖」这种不规则形状,只能按矩形块划分。
完整示例:自定义标题栏
HTML:
<body>
<div class="titlebar">
<span class="title">批量重命名</span>
<div class="window-buttons">
<button id="btn-min" title="最小化">—</button>
<button id="btn-max" title="最大化">▢</button>
<button id="btn-close" title="关闭">×</button>
</div>
</div>
<div class="content">
<p>把下面这段话放进你的插件里:</p>
</div>
</body>
CSS:
body {
margin: 0;
font-family: -apple-system, "Segoe UI", sans-serif;
background: #ffffff;
}
.titlebar {
-webkit-app-region: drag;
height: 38px;
display: flex;
align-items: center;
justify-content: space-between;
padding-left: 14px;
background: #f5f5f5;
border-bottom: 1px solid rgba(0,0,0,.08);
user-select: none;
}
.title {
font-size: 13px;
font-weight: 500;
}
/* 按钮必须脱离拖拽区 */
.window-buttons {
-webkit-app-region: no-drag;
display: flex;
}
.window-buttons button {
width: 44px;
height: 38px;
border: 0;
background: transparent;
cursor: pointer;
font-size: 13px;
color: #555;
}
.window-buttons button:hover {
background: rgba(0,0,0,.06);
}
#btn-close:hover {
background: #e81123;
color: #fff;
}
JS:
eagle.onPluginCreate(async () => {
const theme = await eagle.app.theme;
document.body.setAttribute('theme', theme);
document.querySelector('#btn-min').addEventListener('click', () => {
eagle.window.minimize();
});
document.querySelector('#btn-max').addEventListener('click', async () => {
if (await eagle.window.isMaximized()) {
await eagle.window.unmaximize();
} else {
await eagle.window.maximize();
}
});
document.querySelector('#btn-close').addEventListener('click', () => {
eagle.window.hide();
});
});
eagle.onThemeChanged((theme) => {
document.body.setAttribute('theme', theme);
});
实施步骤
- 把
main.frame设为false,main.url指向你的页面。 - 在页面顶部写
.titlebar容器,里面放标题文字和三个按钮容器。 - 给
.titlebar加-webkit-app-region: drag,给按钮容器加-webkit-app-region: no-drag。 - 在
onPluginCreate里给三个按钮分别绑定eagle.window.minimize()、maximize/unmaximize切换、eagle.window.hide()。 - 注册
eagle.onThemeChanged,让标题栏跟随主程序配色。 - 显式设置
maximizable、resizable等开关,和你的界面设计一致。 - 把
backgroundColor设成标题栏底色,避免打开瞬间白闪。 - 按
F12逐项验证:拖动窗口、点三个按钮、切换主题、缩放窗口。
配套的窗口能力开关
用了自定义标题栏后,系统的窗口按钮就没了,需要在配置层面把不该有的行为关掉:
{
"main": {
"frame": false,
"url": "index.html",
"width": 640,
"height": 480,
"minimizable": true,
"maximizable": false,
"resizable": false,
"alwaysOnTop": false,
"backgroundColor": "#f5f5f5"
}
}
backgroundColor 在无边框窗口里格外重要:无边框意味着窗口打开的第一帧就完全暴露给你,如果你没设背景色,用户会看到一团白闪,然后才变成你的界面。把 backgroundColor 设成你标题栏的颜色,视觉上是连续的。
进阶组合
无边框 + 置顶 + 鼠标穿透,可以做出桌面挂件:
{
"main": {
"frame": false,
"url": "index.html",
"width": 260,
"height": 120,
"alwaysOnTop": true,
"backgroundColor": "#00000000"
}
}
await eagle.window.setAlwaysOnTop(true);
await eagle.window.setOpacity(0.9);
await eagle.window.setIgnoreMouseEvents(true); // 鼠标穿透
// 需要交互时再关掉穿透
await eagle.window.setIgnoreMouseEvents(false);
用颜色取样器、色板显示这类小工具适合这么做。需要提醒的是:这类插件要清楚说明它会常驻屏幕,审核标准里「与核心功能无关的高权限行为」是要被检查的项。
常见坑
设了
drag却忘了no-drag,所有按钮失效。 这是无边框窗口第一大坑。规则很简单:所有可点击元素都要显式声明-webkit-app-region: no-drag。拖拽区里放了输入框。 输入框也是可交互元素,同样需要
no-drag。否则用户点输入框会变成拖动窗口,光标闪烁都不出现。延伸注意: * 忘了
-webkit-app-region不支持非矩形。 想做「圆形头像区可拖、旁边文字不可拖」是做不到的,只能切成若干矩形块。整理人:WorkBuddy
