Popup-Blur-Guard ohne Timer: Sperre fällt mit dem ersten Focused(true)
Bisher löste ein Thread die Sperre nach 350 ms (geraten gegen das spuriose Focused(false), das KDE direkt nach show/set_focus feuert). Jetzt steht die Sperre ab dem Anzeigen und fällt deterministisch mit dem ersten echten Fokus-Event des Popups.
This commit is contained in:
+15
-17
@@ -9,8 +9,9 @@ use crate::domain::watcher::spawn_session_watcher;
|
||||
use crate::platform::Anchor;
|
||||
use crate::{commands, terminal};
|
||||
|
||||
/// Sperrt das Auto-Hide des Popups bei Fokusverlust für einen Moment nach dem
|
||||
/// Anzeigen (KDE-Erststart-Race). Als Tauri-State geführt.
|
||||
/// Sperrt das Auto-Hide des Popups bei Fokusverlust nach dem Anzeigen, bis das
|
||||
/// Popup einmal Focused(true) gemeldet hat (KDE feuert nach show/set_focus ein
|
||||
/// spurioses Focused(false)). Als Tauri-State geführt.
|
||||
#[cfg(target_os = "linux")]
|
||||
pub(crate) struct PopupBlurGuard(pub(crate) std::sync::Arc<std::sync::atomic::AtomicBool>);
|
||||
|
||||
@@ -65,6 +66,7 @@ pub(crate) fn show_popup(app: &tauri::AppHandle, anchor: Anchor) {
|
||||
Anchor::Cursor => {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
// Gelöst wird die Sperre vom ersten Focused(true) im Event-Handler.
|
||||
if let Some(g) = win.try_state::<PopupBlurGuard>() {
|
||||
g.0.store(true, std::sync::atomic::Ordering::SeqCst);
|
||||
}
|
||||
@@ -74,15 +76,6 @@ pub(crate) fn show_popup(app: &tauri::AppHandle, anchor: Anchor) {
|
||||
let _ = w.center();
|
||||
}
|
||||
}
|
||||
// Guard nach kurzer Zeit lösen — danach schließt Fokusverlust wieder
|
||||
// normal.
|
||||
let g2 = win.clone();
|
||||
std::thread::spawn(move || {
|
||||
std::thread::sleep(std::time::Duration::from_millis(350));
|
||||
if let Some(g) = g2.try_state::<PopupBlurGuard>() {
|
||||
g.0.store(false, std::sync::atomic::Ordering::SeqCst);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// GNOME-Extension/KWin: der Compositor positioniert selbst.
|
||||
@@ -197,21 +190,26 @@ pub(crate) fn main_builder() -> tauri::Builder<tauri::Wry> {
|
||||
window.hide().unwrap();
|
||||
}
|
||||
// Popup schließt bei Fokusverlust.
|
||||
if let tauri::WindowEvent::Focused(false) = event {
|
||||
if let tauri::WindowEvent::Focused(focused) = event {
|
||||
if window.label() == "popup" {
|
||||
// KDE feuert direkt nach show/set_focus ein Focused(false) — ohne
|
||||
// diese kurze Sperre verschwände das Popup sofort wieder (erst der
|
||||
// zweite Klick hielte). GNOME/macOS setzen die Sperre nie.
|
||||
// KDE feuert direkt nach show/set_focus ein spurioses Focused(false),
|
||||
// vor dem echten Fokus. Die Sperre steht ab dem Anzeigen und fällt mit
|
||||
// dem ersten Focused(true) — das spuriose Blur läuft ins Leere.
|
||||
// GNOME/macOS setzen die Sperre nie.
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
use tauri::Manager;
|
||||
if let Some(g) = window.try_state::<PopupBlurGuard>() {
|
||||
if g.0.load(std::sync::atomic::Ordering::SeqCst) {
|
||||
if *focused {
|
||||
g.0.store(false, std::sync::atomic::Ordering::SeqCst);
|
||||
} else if g.0.load(std::sync::atomic::Ordering::SeqCst) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
let _ = window.hide();
|
||||
if !focused {
|
||||
let _ = window.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user