TRAE 创造大赛 · 2026 参赛作品

PasteTodo

桌面悬浮待办 · 粘贴即添加

一个 45×45 的悬浮球,藏着一整座高效。
粘贴多行清单 → Ctrl/Cmd+Enter 一键拆分 → 勾选即完成。
始终悬浮在你桌面上——哪怕是在全屏应用之上,随用随点,零打扰。

PasteTodo · 悬浮待办 Demo
PasteTodo 一贴即办
◀ 点击悬浮球
+
面板:收起 · 悬浮球就绪 INTERACTIVE
45×45
悬浮球像素
340
面板宽度 px
2
窗口 (ball+panel)
0
前端依赖
全屏也悬浮
形态特性

一球一板 · 一贴即办

悬浮球模式

45×45 圆形窗口,屏幕右侧随手位置;可自由拖拽到屏幕任意位置,边界自动 clamp。

展开面板

340×500 半透明待办面板,紧贴悬浮球左侧/右侧;透明沉浸,不遮挡视线。

全屏悬浮

setAlwaysOnTop(true,'screen-saver') + visibleOnFullScreen,全屏应用下也丝滑悬浮。

透明沉浸

frame:false + transparent:true,CSS 渐变实现毛玻璃效果;面板透明度 20%~100% 可调。

拖拽排序

右键悬浮球开启,待办项拖拽调整顺序,带平滑占位动画。

一键复制

鼠标悬停待办项显示复制按钮,点击立即进入系统剪贴板。

零打扰

showInactive() 打开面板不抢焦点,不触发 macOS 全屏空间切换。

热更新开发

基于 electronmon 的热重载,JS/HTML/CSS 文件改动自动生效。

核心功能流程

三步 · 粘贴即办

Step 1

Ctrl/Cmd + V 粘贴

把微信、网页、邮件里复制过来的多行清单直接粘贴进文本框,支持带序号、破折号、项目符号的文本。

Step 2

Ctrl/Cmd + Enter 拆分

一键将所有行解析为待办项,自动去除行首序号 1./1)/-/•,干净清爽。

Step 3

勾选即完成

点击圆形复选框立刻划线变灰;一键清空所有已完成;随时在底部再追加一条。

Electron 双窗口架构

主进程统一调度 · 两个 BrowserWindow · IPC 白名单通信

ballWin

45×45
圆形悬浮球
始终显示

主进程 IPC
contextBridge 白名单

panelWin

340×500
半透明面板
按需展开

技术亮点

Electron 原生双窗口架构 · 零前端依赖

🪟 双窗口联动

同一进程两个 BrowserWindow:ballWin 悬浮球 + panelWin 待办面板,主进程统一调度 show/hide/bounds。

🎨 无边框透明

frame:false + transparent:true + backgroundColor:'#00000000',CSS 渐变实现悬浮球与毛玻璃面板。

🎯 pointer-events 精确

窗口 body pointer-events:none,仅圆形元素 pointer-events:auto;严格 45×45 对齐,杜绝透明边框遮挡。

🔒 contextIsolation 安全

contextBridge 白名单暴露 11 个 API,nodeIntegration:false,fs 操作主进程 try/catch 兜底。

🧭 screen-saver 顶层

两个窗口均 setAlwaysOnTop(true,'screen-saver') + visibleOnAllWorkspaces,全屏应用下也丝滑悬浮。

💾 JSON 持久化

todos.json + settings.json 存于 app.getPath('userData'),关闭重启不丢失;零前端依赖。

✉️ IPC 白名单通信

contextBridge.exposeInMainWorld('todoAPI', { getTodos, savetodos, togglePanel, moveBall… }) — 安全可控。

🎮 showInactive 零打扰

用 showInactive() 代替 show()+focus(),打开面板不抢焦点,不触发 macOS 全屏空间切换。

代码速览

主进程 · 渲染进程 · IPC

main.js — 悬浮球窗口
const ballWin = new BrowserWindow({ width: 45, height: 45, frame: false, transparent: true, backgroundColor: '#00000000', alwaysOnTop: true, skipTaskbar: true, webPreferences: { preload: path.join(__dirname, 'preload.js'), contextIsolation: true, nodeIntegration: false } }); ballWin.setAlwaysOnTop(true, 'screen-saver'); ballWin.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
main.js — 面板切换 & 不抢焦点
ipcMain.handle('togglepanel', () => { if (panelVisible) { panelWin.hide(); panelVisible = false; } else { const [bx, by] = ballWin.getPosition(); const pos = computePanelPosition(bx, by); panelWin.setBounds({ x: pos.x, y: pos.y, width: 340, height: 500 }); // showInactive: 不激活窗口,不抢焦点 panelWin.showInactive(); panelVisible = true; } });
preload.js — 安全白名单
contextBridge.exposeInMainWorld('todoAPI', { getTodos: () => ipcRenderer.invoke('getTodos'), savetodos: (d) => ipcRenderer.invoke('savetodos', d), getsettings: () => ipcRenderer.invoke('getsettings'), savesettings: (d) => ipcRenderer.invoke('savesettings', d), togglePanel: () => ipcRenderer.invoke('togglepanel'), moveBall: (dx, dy) => ipcRenderer.invoke('moveball', dx, dy), copyText: (t) => ipcRenderer.invoke('copytext', t), openMenu: () => ipcRenderer.send('openballmenu'), onSettingsChanged: (cb) => ipcRenderer.on('settings-updated', cb) });
ball.css — 悬浮球精确像素
html, body { width: 45px; height: 45px; background: transparent; pointer-events: none; } #ball { width: 45px; height: 45px; border-radius: 50%; pointer-events: auto; background: radial-gradient( circle at 30% 25%, #a78bfa 0%, #6366f1 42%, #22d3ee 100%); box-shadow: 0 10px 30px rgba(99,102,241, .6); }
TRAE 创造大赛 · 2026

试试 PasteTodo — 一贴即办

macOS 用户可直接下载 .dmg 体验 · 也可直接 clone 源码开发