work around Gnome focus-stealing prevention
This commit is contained in:
		@@ -108,6 +108,10 @@ async fn setup(app: &mut App) -> Result<(), Box<dyn Error>> {
 | 
			
		||||
        setup_errors.push("Failed to register hotkeys. Hotkey settings have been disabled.".into());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let desktop_is_gnome = std::env::var("XDG_CURRENT_DESKTOP")
 | 
			
		||||
        .map(|names| names.split(':').any(|n| n == "GNOME"))
 | 
			
		||||
        .unwrap_or(false);
 | 
			
		||||
 | 
			
		||||
    // if session is empty, this is probably the first launch, so don't autohide
 | 
			
		||||
    if !conf.start_minimized || is_first_launch {
 | 
			
		||||
        app.get_window("main")
 | 
			
		||||
@@ -115,7 +119,7 @@ async fn setup(app: &mut App) -> Result<(), Box<dyn Error>> {
 | 
			
		||||
            .show()?;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let state = AppState::new(conf, session, pool, setup_errors);
 | 
			
		||||
    let state = AppState::new(conf, session, pool, setup_errors, desktop_is_gnome);
 | 
			
		||||
    app.manage(state);
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -39,13 +39,22 @@ impl Visibility {
 | 
			
		||||
            .ok_or(WindowError::NoMainWindow)?;
 | 
			
		||||
 | 
			
		||||
        self.leases += 1;
 | 
			
		||||
        // `original` represents the visibility of the window before any leases were acquired
 | 
			
		||||
        // None means we don't know, Some(false) means it was previously hidden,
 | 
			
		||||
        // Some(true) means it was previously visible
 | 
			
		||||
        if self.original.is_none() {
 | 
			
		||||
            let is_visible = window.is_visible()?;
 | 
			
		||||
            self.original = Some(is_visible);
 | 
			
		||||
            if !is_visible {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let state = app.state::<AppState>();
 | 
			
		||||
        if matches!(self.original, Some(true)) && state.desktop_is_gnome {
 | 
			
		||||
            // Gnome has a really annoying "focus-stealing prevention" behavior means we
 | 
			
		||||
            // can't just pop up when the window is already visible, so to work around it
 | 
			
		||||
            // we hide and then immediately unhide the window
 | 
			
		||||
            window.hide()?;
 | 
			
		||||
        }
 | 
			
		||||
        window.show()?;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        window.set_focus()?;
 | 
			
		||||
 | 
			
		||||
        let (tx, rx) = oneshot::channel();
 | 
			
		||||
@@ -95,8 +104,9 @@ pub struct AppState {
 | 
			
		||||
    pub request_count: RwLock<u64>,
 | 
			
		||||
    pub waiting_requests: RwLock<HashMap<u64, Sender<Approval>>>,
 | 
			
		||||
    pub pending_terminal_request: RwLock<bool>,
 | 
			
		||||
    // setup_errors is never modified and so doesn't need to be wrapped in RwLock
 | 
			
		||||
    // these are never modified and so don't need to be wrapped in RwLocks
 | 
			
		||||
    pub setup_errors: Vec<String>,
 | 
			
		||||
    pub desktop_is_gnome: bool,
 | 
			
		||||
    pool: sqlx::SqlitePool,
 | 
			
		||||
    visibility: RwLock<Visibility>,
 | 
			
		||||
}
 | 
			
		||||
@@ -107,6 +117,7 @@ impl AppState {
 | 
			
		||||
        session: Session,
 | 
			
		||||
        pool: SqlitePool,
 | 
			
		||||
        setup_errors: Vec<String>,
 | 
			
		||||
        desktop_is_gnome: bool,
 | 
			
		||||
    ) -> AppState {
 | 
			
		||||
        AppState {
 | 
			
		||||
            config: RwLock::new(config),
 | 
			
		||||
@@ -115,6 +126,7 @@ impl AppState {
 | 
			
		||||
            waiting_requests: RwLock::new(HashMap::new()),
 | 
			
		||||
            pending_terminal_request: RwLock::new(false),
 | 
			
		||||
            setup_errors,
 | 
			
		||||
            desktop_is_gnome,
 | 
			
		||||
            pool,
 | 
			
		||||
            visibility: RwLock::new(Visibility::new()),
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user