import 'dart:io'; import 'package:tray_manager/tray_manager.dart'; import 'package:window_manager/window_manager.dart'; import '../agent.dart'; /// 后台托盘:点窗口关闭按钮 = 隐藏窗口进后台(服务继续运行), /// 托盘常驻(mac 菜单栏 template 图标 / Windows 系统托盘彩色图标), /// 单击/双击托盘恢复窗口,右键弹菜单,退出入口只放在托盘菜单里。 class AppTray with TrayListener, WindowListener { AppTray({required this.agent}); final Agent agent; static const _menuShow = 'menu_show'; static const _menuExit = 'menu_exit'; bool _started = false; Future start() async { if (_started) return; _started = true; windowManager.addListener(this); await windowManager.setPreventClose(true); await trayManager.setIcon( Platform.isMacOS ? 'assets/tray_icon_mac.png' : 'assets/tray_icon_win.ico', ); await trayManager.setToolTip('资安信插件助手 · 饭卡打印(后台运行中)'); await trayManager.setContextMenu(_menu); trayManager.addListener(this); agent.log.write('托盘已就绪:关闭窗口将最小化到托盘,服务持续运行'); } // ---------------- 窗口事件 ---------------- @override void onWindowClose() async { // 关窗不退出:隐藏窗口,服务与托盘保持运行 await windowManager.hide(); } // ---------------- 托盘事件 ---------------- @override void onTrayIconMouseDown() => _showWindow(); @override void onTrayIconRightMouseDown() { trayManager.popUpContextMenu(); } @override void onTrayMenuItemClick(MenuItem menuItem) async { switch (menuItem.key) { case _menuShow: await _showWindow(); case _menuExit: await _exitApp(); } } Menu get _menu => Menu( items: [ MenuItem(key: _menuShow, label: '显示主界面'), MenuItem.separator(), MenuItem(key: _menuExit, label: '退出'), ], ); Future _showWindow() async { await windowManager.show(); await windowManager.focus(); } Future _exitApp() async { agent.log.write('用户从托盘退出,停止服务'); await agent.stop(); await trayManager.destroy(); await windowManager.destroy(); } }