@@ -324,36 +324,35 @@ fn handle_menu_event(event: &MenuEvent, state: &TrayState) {
324324 }
325325}
326326
327- /// Update menu texts after language change
327+ /// Update menu texts after language change by rebuilding the menu
328+ ///
329+ /// On Windows, simply updating menu item texts with set_text() and calling set_menu()
330+ /// can cause issues with the menu event handling. The safest approach is to rebuild
331+ /// the entire menu with the new texts.
328332fn update_menu_texts ( ) {
329333 if let Some ( state_mutex) = TRAY_STATE . get ( ) {
330- let state_guard = state_mutex. lock ( ) ;
331- if let Some ( ref state) = * state_guard {
332- // Update menu item texts
333- state. menu_items . open_sunshine . set_text ( get_string ( StringKey :: OpenSunshine ) ) ;
334- state. menu_items . vdd_toggle . set_text ( get_string ( StringKey :: VddMonitorToggle ) ) ;
335- state. menu_items . import_config . set_text ( get_string ( StringKey :: ImportConfig ) ) ;
336- state. menu_items . export_config . set_text ( get_string ( StringKey :: ExportConfig ) ) ;
337- state. menu_items . reset_config . set_text ( get_string ( StringKey :: ResetToDefault ) ) ;
338- state. menu_items . lang_chinese . set_text ( get_string ( StringKey :: Chinese ) ) ;
339- state. menu_items . lang_english . set_text ( get_string ( StringKey :: English ) ) ;
340- state. menu_items . lang_japanese . set_text ( get_string ( StringKey :: Japanese ) ) ;
341- state. menu_items . star_project . set_text ( get_string ( StringKey :: StarProject ) ) ;
342- state. menu_items . donate_yundi339 . set_text ( get_string ( StringKey :: DeveloperYundi339 ) ) ;
343- state. menu_items . donate_qiin . set_text ( get_string ( StringKey :: DeveloperQiin ) ) ;
344- #[ cfg( target_os = "windows" ) ]
345- state. menu_items . reset_display . set_text ( get_string ( StringKey :: ResetDisplayDeviceConfig ) ) ;
346- state. menu_items . restart . set_text ( get_string ( StringKey :: Restart ) ) ;
347- state. menu_items . quit . set_text ( get_string ( StringKey :: Quit ) ) ;
348-
349- // Update submenu texts
350- state. config_submenu . set_text ( get_string ( StringKey :: Configuration ) ) ;
351- state. language_submenu . set_text ( get_string ( StringKey :: Language ) ) ;
352- state. help_submenu . set_text ( get_string ( StringKey :: HelpUs ) ) ;
353-
354- // Re-set the menu on the tray icon to ensure click events work after text update
355- // This is necessary on Windows where menu updates don't automatically propagate
356- let _ = state. icon . set_menu ( Some ( Box :: new ( state. menu . clone ( ) ) ) ) ;
334+ let mut state_guard = state_mutex. lock ( ) ;
335+ if let Some ( ref mut state) = * state_guard {
336+ // Get the current VDD toggle state before rebuilding
337+ let vdd_checked = state. menu_items . vdd_toggle . is_checked ( ) ;
338+
339+ // Build a completely new menu with the updated language
340+ let ( new_menu, new_menu_items, new_config_submenu, new_language_submenu, new_help_submenu, new_vdd_toggle_id) = build_menu ( ) ;
341+
342+ // Restore the VDD toggle state
343+ new_menu_items. vdd_toggle . set_checked ( vdd_checked) ;
344+
345+ // Set the new menu on the tray icon
346+ // This properly detaches the old menu subclass and attaches the new one
347+ let _ = state. icon . set_menu ( Some ( Box :: new ( new_menu. clone ( ) ) ) ) ;
348+
349+ // Update the state with the new menu and items
350+ state. menu = new_menu;
351+ state. menu_items = new_menu_items;
352+ state. config_submenu = new_config_submenu;
353+ state. language_submenu = new_language_submenu;
354+ state. help_submenu = new_help_submenu;
355+ state. vdd_toggle_id = new_vdd_toggle_id;
357356 }
358357 }
359358}
0 commit comments