Files
StandardSence/.cursor/skills/cyclegui-app-development/references/terminals-and-web.md
T
zhaowei.huangandCursor 158d770c54 docs: 添加 cyclegui-app-development 项目技能
将 CycleGUI 开发技能(含 Duplicated id 防碰撞规范)纳入 .cursor/skills,并调整 gitignore 仅放行 skills 目录可提交。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 22:38:18 +08:00

3.3 KiB
Raw Blame History

终端和 Web

终端类型

  • LocalTerminal:桌面原生窗口,使用 LocalTerminal.Start()
  • WebTerminal:浏览器/WebSocket 终端,使用 WebTerminal.Use(port, ico)
  • TCPTerminalTCP 远程终端,使用 TCPTerminal.Serve(port)

本地窗口

LocalTerminal.SetTitle("MyApp");
LocalTerminal.SetIcon(icoBytes, "MyApp");
LocalTerminal.AddMenuItem("Exit", LocalTerminal.Terminate);
LocalTerminal.Start();              // 或 LocalTerminal.Start(hideAfterInit: true)
GUI.PromptPanel(CreateMainPanel(GUI.defaultTerminal));

LocalTerminal.Start() 应在 GUI.PromptPanel 之前调用。SetIcon(byte[] icoBytes, string name) 设置托盘和窗口图标。

启动后隐藏 libVRender 窗口 / 控制台

LocalTerminal.Start(bool hideAfterInit = false)hideAfterInittrue 时:libVRender 仍会启动,首帧渲染后自动隐藏主窗口(glfwHideWindow),渲染循环继续;托盘双击可恢复。这是隐藏,不是终止渲染后端。

控制台隐藏需应用自行处理(例如 Detour/Medulla 用 ShowWindow(GetConsoleWindow(), SW_HIDE)),与 hideAfterInit 无关。

常见做法是把开关放进工作目录 JSON,由静态构造函数或启动代码读取后传入 LocalTerminal.Start

应用 配置文件 字段
DetourLite detourconsole.json MinimizeToTrayHideConsoleOnStartCPort
Medulla medullaconsole.json MinimizeToTrayHideConsoleOnStart

示例(启动 libVRender 后立即隐藏主窗口):

{
  "HideConsoleOnStart": false,
  "MinimizeToTray": true
}

Detour 配置细节见 detour-configuration skillMedulla 见 medulla-startup-config skill。

WebTerminal

Terminal.RegisterRemotePanel(CreateMainPanel);
Task.Run(() => WebTerminal.Use(port: 8081, ico: icoBytes));

RegisterRemotePanel 让 Web/TCP 连接可以创建欢迎面板。ico: 是浏览器 favicon。

图标 icoBytes

SetIconWebTerminal.Use(ico:) 都接受 .ico 文件字节(不接受 PNG/JPG)。连同 csproj 的 <ApplicationIcon>exe 图标),三处统一用一个 .ico 即可。icoBytes 可从嵌入资源或磁盘读取:

static byte[] LoadIcon()  // 嵌入资源:csproj 里 <EmbeddedResource Include="app_icon.ico" />
{
    var asm = Assembly.GetExecutingAssembly();
    using var s = asm.GetManifestResourceStream(
        asm.GetManifestResourceNames().First(p => p.Contains(".ico")));
    return new BinaryReader(s).ReadBytes((int)s.Length);
}
// 或:byte[] icoBytes = File.ReadAllBytes("res/app_icon.ico");

三处图标(exe / 托盘 / web favicon)的完整设置见 project-setup-and-packaging.md 的「图标设置」。

LeastServer

WebTerminal.Use() 内部启动 LeastServer 并提供 WebSocket 路由和 webVRender 页面。可增加静态文件和简单 HTTP API:

LeastServer.AddServingFiles("/static", "path/to/htdocs");
LeastServer.AddGetHandler("/api/status", () => "OK");
LeastServer.AddPostTextHandler("/api/data", body => ProcessData(body));

多终端注意事项

  • IssueToDefault() 发给默认终端。
  • IssueToAllTerminals() 发给所有终端。
  • panel.Terminal 可用于把弹窗、Painter 或操作限定到当前终端。
  • Painter 需要终端隔离时设置 painter.terminal = specificTerminal