GUIManager 是 ZerOS 内核的 GUI 窗口管理器,统一管理所有 GUI 程序的窗口层叠显示和焦点管理。提供统一的窗口样式和控件(最小化、最大化、关闭),以及模态对话框功能。
ThemeManager - 主题管理器(用于窗口样式和图标)ProcessManager - 进程管理器(用于获取程序信息)TaskbarManager - 任务栏管理器(用于更新任务栏)GUI 管理器在系统启动时自动初始化,也可以手动调用:
GUIManager.init();
registerWindow(pid, windowElement, options)注册窗口到 GUIManager。
参数:
pid (number): 进程 IDwindowElement (HTMLElement): 窗口元素options (Object): 选项对象
title (string): 窗口标题icon (string): 窗口图标路径(可选)onClose (Function): 关闭回调 () => {}。重要:此回调在窗口关闭时被调用,用于执行清理工作。回调不应调用 GUIManager.unregisterWindow() 或 GUIManager._closeWindow(),因为窗口关闭流程由 GUIManager 统一管理。如果回调中已经关闭了窗口(通过 unregisterWindow),GUIManager 会检测到并跳过后续关闭流程。GUIManager 会在窗口关闭后自动检查该 PID 是否还有其他窗口,如果没有且不是 Exploit 程序(PID 10000),会自动 kill 进程。支持「关闭转后台」:若程序支持「点击关闭时转为后台」而不真正退出,可在 onClose 中设置 GUIManager.getWindowInfo(windowId)._backgroundRequested = true、隐藏窗口并调用 Process.requestBackground;GUIManager 检测到 _backgroundRequested 后将只隐藏窗口、不注销不 kill 进程,用户可从托盘单击该后台进程再次恢复窗口并转为前台。onMinimize (Function): 最小化回调(可选)() => {}onMaximize (Function): 最大化回调(可选)(isMaximized: boolean) => {}。参数 isMaximized 表示窗口是否最大化(true 为最大化,false 为还原)windowId (string): 窗口 ID(可选,如果不提供则自动生成)noTitleBar (boolean): 是否不使用系统标题栏;为 true 时由应用自行绘制标题栏,需同时提供 dragHandle 以支持拖拽dragHandle (HTMLElement): 当 noTitleBar 为 true 时,用于拖拽窗口的 DOM 元素(如自定义标题栏容器)borderless (boolean): 是否使用无边框样式(无可见边框、默认无阴影,仅焦点时极轻阴影;最大化时无阴影)titleBarHeight (number): 系统标题栏高度(像素),仅在不使用 noTitleBar 时生效,默认 40titleBarPadding (string): 系统标题栏内边距(CSS 值),仅在不使用 noTitleBar 时生效,默认 '0 16px'返回值: Object|null - 窗口信息对象
{
windowId: string,
window: HTMLElement,
pid: number,
zIndex: number,
isFocused: boolean,
isMinimized: boolean,
isMaximized: boolean,
isMainWindow: boolean,
title: string,
icon: string|null,
createdAt: number
}
示例:
GUIManager.registerWindow(pid, windowElement, {
title: '我的应用',
icon: 'application/myapp/myapp.svg',
onClose: () => {
// onClose 回调只用于执行清理工作,不应调用 unregisterWindow 或 _closeWindow
// 窗口关闭流程由 GUIManager 统一管理
// GUIManager 会在窗口关闭后自动检查该 PID 是否还有其他窗口
// 如果没有且不是 Exploit 程序(PID 10000),会自动 kill 进程
},
onMinimize: () => {
console.log('窗口已最小化');
},
onMaximize: (isMaximized) => {
console.log('窗口已最大化:', isMaximized);
}
});
无边框 + 自定义标题栏示例(如磁盘管理程序):
var titleBar = windowElement.querySelector('.my-custom-titlebar');
GUIManager.registerWindow(pid, windowElement, {
title: '磁盘管理',
noTitleBar: true,
dragHandle: titleBar,
borderless: true,
onClose: () => {},
onMinimize: () => { /* 自定义最小化 */ },
onMaximize: (isMaximized) => { /* 自定义最大化/还原 */ }
});
此时窗口会添加类 zos-window-borderless,无系统标题栏,拖拽由 dragHandle 提供。
unregisterWindow(windowIdOrPid)注销窗口。
参数:
windowIdOrPid (string|number): 窗口 ID 或进程 ID返回值: boolean - 是否成功
示例:
// 通过窗口 ID 注销
GUIManager.unregisterWindow('window_1234_1234567890_abc');
// 通过进程 ID 注销(会注销该进程的所有窗口)
GUIManager.unregisterWindow(pid);
focusWindow(windowIdOrPid)将窗口置于最前并获得焦点。
参数:
windowIdOrPid (string|number): 窗口 ID 或进程 ID返回值: boolean - 是否成功
示例:
GUIManager.focusWindow('window_1234_1234567890_abc');
// 或
GUIManager.focusWindow(pid);
showWindowsForPid(pid)显示某进程的所有窗口并聚焦第一个窗口。用于从后台恢复:将该 PID 下所有被设为 display:none 的窗口恢复显示,并将焦点给该进程的第一个窗口。任务栏在用户点击后台进程托盘项时会调用此方法,确保点击后 GUI 窗口一定会出现。
参数:
pid (number): 进程 ID返回值: 无
示例:
GUIManager.showWindowsForPid(pid);
minimizeWindow(windowIdOrPid)最小化窗口。
参数:
windowIdOrPid (string|number): 窗口 ID 或进程 ID返回值: boolean - 是否成功
示例:
GUIManager.minimizeWindow(pid);
restoreWindow(windowIdOrPid, autoFocus)恢复窗口。
参数:
windowIdOrPid (string|number): 窗口 ID 或进程 IDautoFocus (boolean): 是否自动获得焦点(默认 true)返回值: boolean - 是否成功
示例:
GUIManager.restoreWindow(pid, true);
toggleMaximize(windowIdOrPid)切换最大化状态。
参数:
windowIdOrPid (string|number): 窗口 ID 或进程 ID返回值: boolean - 是否成功
示例:
GUIManager.toggleMaximize(pid);
getWindowsByPid(pid)获取进程的所有窗口。
参数:
pid (number): 进程 ID返回值: Array<Object> - 窗口信息数组
示例:
const windows = GUIManager.getWindowsByPid(pid);
windows.forEach(win => {
console.log(`窗口: ${win.title}, ID: ${win.windowId}`);
});
getWindowLogs(windowId, options)获取窗口日志。
参数:
windowId (string): 窗口 IDoptions (Object): 选项对象
limit (number): 限制返回数量(可选)action (string): 按操作类型过滤(可选)返回值: Array<Object> - 日志条目数组
示例:
// 获取所有日志
const logs = GUIManager.getWindowLogs(windowId);
// 获取最近 10 条日志
const recentLogs = GUIManager.getWindowLogs(windowId, { limit: 10 });
// 获取特定操作的日志
const focusLogs = GUIManager.getWindowLogs(windowId, { action: 'focus' });
showAlert(message, title, type)显示提示框(替代 alert())。
参数:
message (string): 提示消息title (string): 标题(可选,默认:'提示')type (string): 类型(可选,默认:'info')
'info': 信息提示'success': 成功提示'warning': 警告提示'error': 错误提示返回值: Promise<void>
示例:
await GUIManager.showAlert('操作成功', '提示', 'success');
showConfirm(message, title, type)显示确认对话框(替代 confirm())。
参数:
message (string): 确认消息title (string): 标题(可选,默认:'确认')type (string): 类型(可选,默认:'warning')返回值: Promise<boolean> - true 表示确认,false 表示取消
示例:
const confirmed = await GUIManager.showConfirm('确定要删除吗?', '确认删除', 'warning');
if (confirmed) {
// 执行删除操作
}
showPrompt(message, title, defaultValue)显示输入对话框(替代 prompt())。
参数:
message (string): 提示消息title (string): 标题(可选,默认:'输入')defaultValue (string): 默认值(可选,默认:'')返回值: Promise<string|null> - 用户输入的值,取消返回 null
示例:
const input = await GUIManager.showPrompt('请输入文件名:', '新建文件', 'untitled.txt');
if (input) {
console.log(`文件名: ${input}`);
}
__init__: async function(pid, initArgs) {
this.pid = pid;
// 创建窗口元素
const window = document.createElement('div');
window.className = 'myapp-window zos-gui-window';
window.dataset.pid = pid.toString();
// 注册到 GUIManager
const windowInfo = GUIManager.registerWindow(pid, window, {
title: '我的应用',
icon: 'application/myapp/myapp.svg',
onClose: () => {
// onClose 回调只用于执行清理工作,不应调用 unregisterWindow 或 _closeWindow
// 窗口关闭流程由 GUIManager 统一管理
// GUIManager 会在窗口关闭后自动检查该 PID 是否还有其他窗口
// 如果没有且不是 Exploit 程序(PID 10000),会自动 kill 进程
}
});
// 保存窗口信息
this.windowId = windowInfo.windowId;
this.window = window;
}
// 最小化窗口
GUIManager.minimizeWindow(this.windowId);
// 恢复窗口
GUIManager.restoreWindow(this.windowId);
// 最大化/还原窗口
GUIManager.toggleMaximize(this.windowId);
// 获得焦点
GUIManager.focusWindow(this.windowId);
// 显示提示
await GUIManager.showAlert('文件已保存', '成功', 'success');
// 显示确认
const confirmed = await GUIManager.showConfirm('确定要退出吗?');
if (confirmed) {
ProcessManager.killProgram(this.pid);
}
// 显示输入
const filename = await GUIManager.showPrompt('请输入文件名:', '新建文件');
if (filename) {
await Disk.createFile(`C:/${filename}`, '');
}
窗口有以下状态:
isFocused: 是否获得焦点isMinimized: 是否最小化isMaximized: 是否最大化isMainWindow: 是否为主窗口(进程的第一个窗口)GUIManager 自动管理窗口的 z-index:
GUIManager 自动为每个窗口创建统一的控制按钮:
onClose 回调按钮图标会根据当前主题样式自动更新。
当窗口关闭时(用户点击关闭按钮或调用 unregisterWindow),GUIManager 会执行以下流程:
调用 onClose 回调(如果存在):
onClose 引用,避免递归调用unregisterWindow,GUIManager 会检测到并跳过后续关闭流程执行关闭动画:
注销窗口:
检查进程终止:
ProcessManager.killProgram(pid) 终止进程重要提示:
onClose 回调只用于执行清理工作,不应调用 unregisterWindow 或 _closeWindowposition: fixed 或 position: absolutewindowId,GUIManager 会自动生成唯一 IDonClose 回调不应调用 unregisterWindow 或 _closeWindow,窗口关闭由 GUIManager 统一管理