TaskbarManager 是 ZerOS 内核的任务栏管理器,负责渲染任务栏,显示固定程序和正在运行的程序。提供任务栏位置管理、程序图标显示、通知徽章、固定程序管理、天气组件等功能。
ProcessManager - 进程管理器(用于获取运行中的程序)ApplicationAssetManager - 应用程序资源管理器(用于获取程序信息)GUIManager - GUI 管理器(用于窗口管理)ThemeManager - 主题管理器(用于系统图标)NotificationManager - 通知管理器(用于通知徽章)LStorage - 本地存储(用于保存任务栏位置和固定程序列表)GeographyDrive - 地理位置驱动(用于天气组件的城市名称获取,可选依赖)任务栏在系统启动时自动初始化:
TaskbarManager.init();
init()初始化任务栏。
示例:
TaskbarManager.init();
update()更新任务栏(重新渲染)。内部会清空任务栏容器后异步执行 _renderTaskbar。
防并发渲染:若在本次渲染尚未完成时再次调用 update(),不会立即启动新一轮渲染,而是设置 _pendingUpdate;当前次 _renderTaskbar 在 finally 中结束后,若存在待处理更新则会再执行一次 update(),从而避免并发渲染导致任务栏重复/错乱(例如从托盘单击后台进程恢复时触发的多次更新)。
示例:
TaskbarManager.update();
pinProgram(programName)将程序固定到任务栏。
参数:
programName (string): 程序名称返回值: Promise<boolean> - 是否成功
示例:
await TaskbarManager.pinProgram('filemanager');
unpinProgram(programName)从任务栏取消固定程序。
参数:
programName (string): 程序名称返回值: Promise<boolean> - 是否成功
示例:
await TaskbarManager.unpinProgram('filemanager');
getPinnedPrograms()获取所有固定在任务栏的程序列表。
返回值: Promise<Array<string>> - 固定程序名称列表
示例:
const pinned = await TaskbarManager.getPinnedPrograms();
console.log('固定程序:', pinned); // ['filemanager', 'browser', ...]
isPinned(programName)检查程序是否固定在任务栏。
参数:
programName (string): 程序名称返回值: Promise<boolean> - 是否固定
示例:
const isPinned = await TaskbarManager.isPinned('filemanager');
if (isPinned) {
console.log('文件管理器已固定在任务栏');
}
setPinnedPrograms(programNames)设置固定程序列表(批量操作)。
参数:
programNames (Array返回值: Promise<boolean> - 是否成功
示例:
await TaskbarManager.setPinnedPrograms(['filemanager', 'browser', 'musicplayer']);
任务栏自动显示:
pinProgram() 固定的程序(无论是否运行都显示)任务栏右侧显示天气组件,提供以下功能:
TaskbarManager._weatherCache 中天气数据来源:
GeographyDrive 低精度定位获取城市名称(不触发浏览器权限请求),失败时降级到直接调用 APIhttps://api-v1.cenguigui.cn/api/WeatherInfo/?city={城市名}城市名称获取策略:
enableHighAccuracy: false)获取城市名称,不会触发浏览器权限请求https://api-v1.cenguigui.cn/api/UserInfo/apilet.php API并发请求处理:
任务栏可展示后台进程(已转后台、窗口隐藏但未退出的程序)。用户点击后台进程图标时:
Process.registerBackgroundTrayClick 回调,任务栏都会:
ProcessManager.setProcessBackground(pid, false));GUIManager.showWindowsForPid(pid) 显示该进程的所有 GUI 窗口并聚焦第一个窗口;.taskbar-background-processes-item)上,即会弹出菜单;菜单包含系统自动添加的「退出程序」项,以及程序通过 Process.registerBackgroundTrayContextMenu 注册的自定义菜单项。因此,点击后台程序图标后,其 GUI 窗口一定会被显示并置顶;右击后台进程项一定会弹出菜单(含「退出程序」)。程序可通过 ProcessManager 文档中的 Process.registerBackgroundTrayClick / Process.registerBackgroundTrayContextMenu 注册自定义单击或右键菜单行为。调试时可在 KernelLogger 中按 [BackgroundTrayMenu] 过滤相关日志。
任务栏显示通知图标和数量徽章:
任务栏支持四个位置:
bottom - 底部(默认)top - 顶部left - 左侧right - 右侧任务栏位置会自动保存到 LStorage,并在下次启动时恢复。
// 在程序启动或关闭后更新任务栏
await ProcessManager.startProgram('myapp');
TaskbarManager.update();
// 任务栏位置存储在 TaskbarManager._taskbarPosition
// 注意:这是私有属性,通常不需要直接访问
固定程序管理 API 也可以通过 ProcessManager.callKernelAPI 调用:
// 固定程序
await ProcessManager.callKernelAPI(pid, 'Taskbar.pinProgram', ['filemanager']);
// 取消固定
await ProcessManager.callKernelAPI(pid, 'Taskbar.unpinProgram', ['filemanager']);
// 获取固定程序列表
const pinned = await ProcessManager.callKernelAPI(pid, 'Taskbar.getPinnedPrograms', []);
// 检查是否固定
const isPinned = await ProcessManager.callKernelAPI(pid, 'Taskbar.isPinned', ['filemanager']);
// 批量设置固定程序
await ProcessManager.callKernelAPI(pid, 'Taskbar.setPinnedPrograms', [['filemanager', 'browser']]);
权限要求:
Taskbar.pinProgram: 需要 DESKTOP_MANAGE 权限Taskbar.unpinProgram: 需要 DESKTOP_MANAGE 权限Taskbar.getPinnedPrograms: 不需要权限(读取操作)Taskbar.isPinned: 不需要权限(读取操作)Taskbar.setPinnedPrograms: 需要 DESKTOP_MANAGE 权限addCustomIcon(options)添加自定义图标到任务栏。
参数:
options (Object): 图标配置对象
iconId (string, 可选): 图标唯一标识符(如果未提供,将自动生成)icon (string, 必需): 图标路径或URLtitle (string, 必需): 图标标题/工具提示onClick (Function, 可选): 点击事件处理函数pid (number, 可选): 关联的进程ID(用于权限检查和自动清理)metadata (Object, 可选): 元数据返回值: Promise<string> - 图标ID
示例:
// 直接调用
const iconId = await TaskbarManager.addCustomIcon({
icon: 'D:/application/myapp/icon.png',
title: '我的应用',
onClick: (e, iconData) => {
console.log('图标被点击', iconData);
},
metadata: {
// 自定义元数据
}
});
// 通过 ProcessManager 调用
const iconId = await ProcessManager.callKernelAPI(pid, 'Taskbar.addIcon', [{
icon: 'D:/application/myapp/icon.png',
title: '我的应用',
onClick: (e, iconData) => {
console.log('图标被点击', iconData);
}
}]);
removeCustomIcon(iconId)移除自定义图标。
参数:
iconId (string): 图标ID返回值: Promise<boolean> - 是否成功
示例:
// 直接调用
await TaskbarManager.removeCustomIcon(iconId);
// 通过 ProcessManager 调用
await ProcessManager.callKernelAPI(pid, 'Taskbar.removeIcon', [iconId]);
权限要求: 需要 DESKTOP_MANAGE 权限,且只能删除自己创建的图标(通过 PID 验证)
updateCustomIcon(iconId, updates)更新自定义图标。
参数:
iconId (string): 图标IDupdates (Object): 更新内容
icon (string, 可选): 新的图标路径title (string, 可选): 新的标题onClick (Function|null, 可选): 新的点击事件处理函数metadata (Object, 可选): 新的元数据(会合并到现有元数据)返回值: Promise<boolean> - 是否成功
示例:
// 直接调用
await TaskbarManager.updateCustomIcon(iconId, {
title: '新标题',
icon: 'D:/application/myapp/new-icon.png'
});
// 通过 ProcessManager 调用
await ProcessManager.callKernelAPI(pid, 'Taskbar.updateIcon', [iconId, {
title: '新标题',
icon: 'D:/application/myapp/new-icon.png'
}]);
权限要求: 需要 DESKTOP_MANAGE 权限,且只能更新自己创建的图标(通过 PID 验证)
getCustomIcons()获取所有自定义图标列表。
返回值: Promise<Array<Object>> - 自定义图标列表,每个对象包含:
iconId (string): 图标IDicon (string): 图标路径title (string): 图标标题pid (number|null): 关联的进程IDmetadata (Object): 元数据createdAt (number): 创建时间戳示例:
// 直接调用
const icons = await TaskbarManager.getCustomIcons();
// 通过 ProcessManager 调用
const icons = await ProcessManager.callKernelAPI(pid, 'Taskbar.getCustomIcons', []);
权限要求: 不需要权限(读取操作)
getCustomIconsByPid(pid)根据 PID 获取自定义图标列表。
参数:
pid (number): 进程ID返回值: Promise<Array<Object>> - 自定义图标列表
示例:
// 直接调用
const icons = await TaskbarManager.getCustomIconsByPid(pid);
// 通过 ProcessManager 调用
const icons = await ProcessManager.callKernelAPI(pid, 'Taskbar.getCustomIconsByPid', [pid]);
权限要求: 不需要权限(读取操作)
通过 ProcessManager 调用自定义图标 API:
// 添加自定义图标
const iconId = await ProcessManager.callKernelAPI(pid, 'Taskbar.addIcon', [{
icon: 'D:/application/myapp/icon.png',
title: '我的应用',
onClick: (e, iconData) => {
console.log('图标被点击', iconData);
}
}]);
// 更新自定义图标
await ProcessManager.callKernelAPI(pid, 'Taskbar.updateIcon', [iconId, {
title: '新标题'
}]);
// 移除自定义图标
await ProcessManager.callKernelAPI(pid, 'Taskbar.removeIcon', [iconId]);
// 获取所有自定义图标
const icons = await ProcessManager.callKernelAPI(pid, 'Taskbar.getCustomIcons', []);
// 根据 PID 获取自定义图标
const myIcons = await ProcessManager.callKernelAPI(pid, 'Taskbar.getCustomIconsByPid', [pid]);
权限要求:
Taskbar.addIcon: 需要 DESKTOP_MANAGE 权限Taskbar.removeIcon: 需要 DESKTOP_MANAGE 权限,且只能删除自己创建的图标Taskbar.updateIcon: 需要 DESKTOP_MANAGE 权限,且只能更新自己创建的图标Taskbar.getCustomIcons: 不需要权限(读取操作)Taskbar.getCustomIconsByPid: 不需要权限(读取操作)注意事项:
onClick 函数无法序列化,系统重启后需要程序重新注册任务栏包含以下部分:
任务栏管理器注册了以下全局快捷键:
Ctrl + R启动运行程序(如果已运行则聚焦)。
注意: 在输入框中按下此快捷键只会阻止浏览器刷新,不会启动运行程序。
Ctrl + X启动设置程序(如果已运行则聚焦)。
注意: 在输入框中按下此快捷键不会启动设置程序。
Ctrl + L锁定屏幕,显示锁屏界面。
注意:
示例:
// 手动锁定屏幕(内部方法)
TaskbarManager._lockScreen();
Ctrl + E关闭当前焦点窗口(仅在多任务选择器未激活时)。
注意: 如果多任务选择器已激活,此快捷键由多任务选择器处理。
Ctrl + Q切换当前焦点窗口的最大化/最小化状态。
Shift + E启动文件管理器。
注意: 在输入框中按下此快捷键不会启动文件管理器。
update()ApplicationAssetManager 获取NotificationManager 提供LStorage 的 taskbar.pinnedPrograms 键中,会自动持久化EventManager 进行事件管理Ctrl + L 快捷键会调用 LockScreen 模块显示锁屏界面,需要 LockScreen 模块已加载