@@ -27,6 +27,28 @@ fn http_get_then_emit(url: String, app: AppHandle, event: &'static str) {
2727 } ) ;
2828}
2929
30+ /// Shows the popup window, emits refresh events, and sets focus.
31+ /// Used by both the tray left-click handler and the "Show Window" menu item.
32+ /// Sets `expect_focus_gain` so the focus-loss handler won't hide us until
33+ /// the window actually receives `Focused(true)`.
34+ fn show_popup_window ( app : & AppHandle ) {
35+ if let Some ( window) = app. get_webview_window ( "main" ) {
36+ // Set flag so the focus-loss handler won't hide us until the window actually
37+ // receives Focused(true). This suppresses the spurious Focused(false) that
38+ // fires on Linux/X11 (and occasionally Windows) before focus arrives.
39+ if let Some ( state) = app. try_state :: < crate :: AppState > ( ) {
40+ if let Ok ( mut e) = state. expect_focus_gain . lock ( ) {
41+ * e = true ;
42+ }
43+ }
44+ let _ = window. show ( ) ;
45+ let _ = window. set_focus ( ) ;
46+ let _ = app. emit ( "monitors-changed" , ( ) ) ;
47+ let _ = app. emit ( "dark-mode-changed" , ( ) ) ;
48+ let _ = app. emit ( "volume-changed" , ( ) ) ;
49+ }
50+ }
51+
3052/// Builds the system tray icon, context menu, and event handlers.
3153/// Handles left-click (toggle popup) and menu actions (dark/light mode, profiles, debug, quit).
3254pub fn setup_tray ( app : & mut tauri:: App ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
@@ -38,6 +60,7 @@ pub fn setup_tray(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>
3860 }
3961 } ;
4062
63+ let show_window = MenuItemBuilder :: with_id ( "show_window" , "Show Window" ) . build ( app) ?;
4164 let dark_mode = MenuItemBuilder :: with_id ( "dark_mode" , "Dark Mode" ) . build ( app) ?;
4265 let light_mode = MenuItemBuilder :: with_id ( "light_mode" , "Light Mode" ) . build ( app) ?;
4366
@@ -93,6 +116,8 @@ pub fn setup_tray(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>
93116 let quit = MenuItemBuilder :: with_id ( "quit" , "Quit" ) . build ( app) ?;
94117
95118 let menu = MenuBuilder :: new ( app)
119+ . item ( & show_window)
120+ . separator ( )
96121 . items ( & [ & dark_mode, & light_mode] )
97122 . separator ( )
98123 . item ( & profiles_submenu)
@@ -110,6 +135,9 @@ pub fn setup_tray(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>
110135 . menu ( & menu)
111136 . show_menu_on_left_click ( false )
112137 . on_menu_event ( move |app, event| match event. id ( ) . as_ref ( ) {
138+ "show_window" => {
139+ show_popup_window ( app) ;
140+ }
113141 "bridge" => {
114142 let url = base_url ( ) ;
115143 let _ = open:: that ( & url) ;
@@ -207,12 +235,7 @@ pub fn setup_tray(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>
207235 ) ;
208236 }
209237 }
210- let _ = window. show ( ) ;
211- let _ = window. set_focus ( ) ;
212- // Emit refresh events so frontend fetches latest monitor/dark-mode/volume state
213- let _ = app. emit ( "monitors-changed" , ( ) ) ;
214- let _ = app. emit ( "dark-mode-changed" , ( ) ) ;
215- let _ = app. emit ( "volume-changed" , ( ) ) ;
238+ show_popup_window ( app) ;
216239 }
217240 }
218241 }
0 commit comments