mirror of
				https://github.com/yuezk/GlobalProtect-openconnect.git
				synced 2025-05-20 07:26:58 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			74 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			74 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use std::{process::ExitStatus, time::Duration};
 | |
| 
 | |
| use anyhow::bail;
 | |
| use log::info;
 | |
| use tauri::WebviewWindow;
 | |
| use tokio::process::Command;
 | |
| 
 | |
| pub trait WindowExt {
 | |
|   fn raise(&self) -> anyhow::Result<()>;
 | |
| }
 | |
| 
 | |
| impl WindowExt for WebviewWindow {
 | |
|   fn raise(&self) -> anyhow::Result<()> {
 | |
|     raise_window(self)
 | |
|   }
 | |
| }
 | |
| 
 | |
| pub fn raise_window(win: &WebviewWindow) -> anyhow::Result<()> {
 | |
|   let is_wayland = std::env::var("XDG_SESSION_TYPE").unwrap_or_default() == "wayland";
 | |
| 
 | |
|   if is_wayland {
 | |
|     win.hide()?;
 | |
|     win.show()?;
 | |
|   } else {
 | |
|     if !win.is_visible()? {
 | |
|       win.show()?;
 | |
|     }
 | |
|     let title = win.title()?;
 | |
|     tokio::spawn(async move {
 | |
|       if let Err(err) = wmctrl_raise_window(&title).await {
 | |
|         info!("Window not raised: {}", err);
 | |
|       }
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   // Calling window.show() on Windows will cause the menu to be shown.
 | |
|   // We need to hide it again.
 | |
|   win.hide_menu()?;
 | |
| 
 | |
|   Ok(())
 | |
| }
 | |
| 
 | |
| async fn wmctrl_raise_window(title: &str) -> anyhow::Result<()> {
 | |
|   let mut counter = 0;
 | |
| 
 | |
|   loop {
 | |
|     if let Ok(exit_status) = wmctrl_try_raise_window(title).await {
 | |
|       if exit_status.success() {
 | |
|         info!("Window raised after {} attempts", counter + 1);
 | |
|         return Ok(());
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if counter >= 10 {
 | |
|       bail!("Failed to raise window: {}", title)
 | |
|     }
 | |
| 
 | |
|     counter += 1;
 | |
|     tokio::time::sleep(Duration::from_millis(100)).await;
 | |
|   }
 | |
| }
 | |
| 
 | |
| async fn wmctrl_try_raise_window(title: &str) -> anyhow::Result<ExitStatus> {
 | |
|   let exit_status = Command::new("wmctrl")
 | |
|     .arg("-F")
 | |
|     .arg("-a")
 | |
|     .arg(title)
 | |
|     .spawn()?
 | |
|     .wait()
 | |
|     .await?;
 | |
| 
 | |
|   Ok(exit_status)
 | |
| }
 |