@@ -30,7 +30,6 @@ use std::{
3030 atomic:: { AtomicBool , Ordering } ,
3131 Arc , Mutex ,
3232 } ,
33- time:: Duration ,
3433} ;
3534use tao:: event_loop:: EventLoop ;
3635use tray_icon:: MouseButton ;
@@ -142,50 +141,7 @@ fn main() {
142141 let comp_level = settings. sundry . comp_level ;
143142 let scale_level = settings. sundry . scale_level ;
144143
145- // 托盘事件和菜单事件统一处理线程
146- // 使用轮询方式处理托盘图标点击和右键菜单事件
147- let running_event = running. clone ( ) ;
148- let proxy_event = proxy. clone ( ) ;
149- let _event_handler = std:: thread:: spawn ( move || {
150- let tray_receiver = tray_icon:: TrayIconEvent :: receiver ( ) . to_owned ( ) ;
151- let menu_receiver = tray_icon:: menu:: MenuEvent :: receiver ( ) . to_owned ( ) ;
152-
153- while running_event. load ( Ordering :: SeqCst ) {
154- // 处理托盘图标事件(左键双击截图,单次左键不响应)
155- while let Ok ( tray_icon:: TrayIconEvent :: DoubleClick { button, .. } ) =
156- tray_receiver. try_recv ( )
157- {
158- if button == MouseButton :: Left {
159- let args = build_capture_args ( comp_level, scale_level, & save_path, false ) ;
160- spawn_capture ( & exe_path, args, gui. clone ( ) ) ;
161- }
162- }
163-
164- // 处理右键菜单事件
165- while let Ok ( event) = menu_receiver. try_recv ( ) {
166- if event. id == capture_id {
167- // 菜单:截图
168- let args = build_capture_args ( comp_level, scale_level, & save_path, false ) ;
169- spawn_capture ( & exe_path, args, gui. clone ( ) ) ;
170- } else if event. id == long_capture_id {
171- // 菜单:长截图
172- let args = build_capture_args ( comp_level, scale_level, & save_path, true ) ;
173- spawn_capture ( & exe_path, args, gui. clone ( ) ) ;
174- } else if event. id == open_config_id {
175- // 菜单:设置
176- operate_exe ( & exe_path, "conf" , std:: collections:: HashMap :: new ( ) ) ;
177- } else if event. id == exit_id {
178- // 菜单:退出
179- println ! ( "Menu: Exit requested" ) ;
180- running_event. store ( false , Ordering :: SeqCst ) ;
181- proxy_event. send_event ( ( ) ) . ok ( ) ;
182- break ;
183- }
184- }
185-
186- std:: thread:: sleep ( Duration :: from_millis ( 10 ) ) ;
187- }
188- } ) ;
144+ let conf_path = path_infos. conf_path . clone ( ) ;
189145
190146 // 设置全局热键并获取控制句柄
191147 let ( handler_hotkeys, hotkey_exit_tx) =
@@ -201,10 +157,50 @@ fn main() {
201157
202158 // 主事件循环
203159 event_loop. run ( move |event, _, control_flow| {
204- * control_flow = tao:: event_loop:: ControlFlow :: Wait ;
160+ // 定时唤醒,用于轮询托盘和菜单事件
161+ * control_flow =
162+ tao:: event_loop:: ControlFlow :: WaitUntil ( std:: time:: Instant :: now ( ) + T_SEC_1_100 ) ;
163+
164+ // 处理托盘图标事件(左键双击截图)
165+ while let Ok ( tray_event) = tray_icon:: TrayIconEvent :: receiver ( ) . try_recv ( ) {
166+ if let tray_icon:: TrayIconEvent :: DoubleClick {
167+ button : MouseButton :: Left ,
168+ ..
169+ } = tray_event
170+ {
171+ let args = build_capture_args ( comp_level, scale_level, & save_path, false ) ;
172+ spawn_capture ( & exe_path, args, gui. clone ( ) ) ;
173+ }
174+ }
175+
176+ // 处理右键菜单事件
177+ while let Ok ( menu_event) = tray_icon:: menu:: MenuEvent :: receiver ( ) . try_recv ( ) {
178+ if menu_event. id == capture_id {
179+ // 菜单:截图
180+ println ! ( "Menu Event: Capture" ) ;
181+ let args = build_capture_args ( comp_level, scale_level, & save_path, false ) ;
182+ spawn_capture ( & exe_path, args, gui. clone ( ) ) ;
183+ } else if menu_event. id == long_capture_id {
184+ // 菜单:长截图
185+ println ! ( "Menu Event: Long Capture" ) ;
186+ let args = build_capture_args ( comp_level, scale_level, & save_path, true ) ;
187+ spawn_capture ( & exe_path, args, gui. clone ( ) ) ;
188+ } else if menu_event. id == open_config_id {
189+ // 菜单:设置
190+ println ! ( "Menu Event: Open Config" ) ;
191+ operate_exe ( & conf_path, "conf" , std:: collections:: HashMap :: new ( ) ) ;
192+ } else if menu_event. id == exit_id {
193+ // 菜单:退出
194+ println ! ( "Menu Event: Exit requested" ) ;
195+ running. store ( false , Ordering :: SeqCst ) ;
196+ proxy. send_event ( ( ) ) . ok ( ) ;
197+ }
198+ }
205199
206- // 检查是否收到退出信号(来自菜单退出或热键退出)
207- let should_exit = matches ! ( event, tao:: event:: Event :: UserEvent ( ( ) ) ) ;
200+ // 检查退出条件(来自菜单退出或热键退出)
201+ let from_user_event = matches ! ( event, tao:: event:: Event :: UserEvent ( ( ) ) ) ;
202+ let running_now = running. load ( Ordering :: SeqCst ) ;
203+ let should_exit = from_user_event || !running_now;
208204
209205 if should_exit {
210206 // 通知所有线程退出
@@ -213,15 +209,20 @@ fn main() {
213209 // 清理热键线程
214210 if let Some ( handle) = handler_hotkeys. lock ( ) . unwrap ( ) . take ( ) {
215211 hotkey_exit_tx. send ( ( ) ) . ok ( ) ;
216- if handle. join ( ) . is_ok ( ) {
217- println ! ( "Hotkey handler thread terminated." ) ;
212+ let wait_deadline =
213+ std:: time:: Instant :: now ( ) + std:: time:: Duration :: from_millis ( 300 ) ;
214+ while !handle. is_finished ( ) && std:: time:: Instant :: now ( ) < wait_deadline {
215+ std:: thread:: sleep ( T_SEC_1_100 ) ;
216+ }
217+
218+ if handle. is_finished ( ) {
219+ handle. join ( ) . ok ( ) ;
218220 }
219221 }
220222
221223 // 显式 drop 托盘管理器以清理系统托盘图标
222224 if let Some ( tm) = tray_manager. take ( ) {
223225 drop ( tm) ;
224- println ! ( "Tray manager cleaned up." ) ;
225226 }
226227
227228 * control_flow = tao:: event_loop:: ControlFlow :: Exit ;
0 commit comments