Popup-Fokus auf SNI-X11-Desktops: present() nach jedem Map

Muffin (Cinnamon) mappt das Popup ohne Fokus — das set_focus aus show_popup
läuft vor dem Map und fällt der Focus-Stealing-Prevention zum Opfer; ohne
initialen Fokus greift das Blur-Schließen nie. Ein map-event-Handler ruft
present(), GTK besorgt sich unter X11 dabei den echten Server-Timestamp.

Registriert nur unter X11 außerhalb von GNOME: auf GNOME/Wayland zeigt die
Extension das Popup, dort brach das Fokus-Grab den Klick-Weg (Ubuntu/Kubuntu).
Bestätigt auf Mint/Cinnamon, Ubuntu und Kubuntu.
This commit is contained in:
marcus hinz
2026-07-17 19:37:05 +02:00
parent be1e4aad3f
commit d4d455fa08
3 changed files with 21 additions and 0 deletions
+1
View File
@@ -34,6 +34,7 @@ version = "0.2.0"
dependencies = [
"base64 0.22.1",
"glib",
"gtk",
"keyring",
"ksni",
"log",
+1
View File
@@ -38,6 +38,7 @@ keyring = { version = "3", features = ["apple-native", "sync-secret-service", "w
[target.'cfg(target_os = "linux")'.dependencies]
zbus = "5"
glib = "0.18"
gtk = "0.18"
rfd = { version = "0.15", default-features = false, features = ["gtk3"] }
ksni = "0.1"
+19
View File
@@ -169,6 +169,25 @@ pub(crate) fn main_builder() -> tauri::Builder<tauri::Wry> {
app.manage(PopupBlurGuard(std::sync::Arc::new(
std::sync::atomic::AtomicBool::new(false),
)));
// Muffin (Cinnamon) mappt das Popup ohne Fokus: das set_focus aus
// show_popup läuft, bevor der WM das Fenster gemappt hat, und wird
// von der Focus-Stealing-Prevention verworfen — ohne initialen Fokus
// greift das Blur-Schließen nie. Deshalb nach jedem Map erneut
// präsentieren: present() besorgt sich unter X11 den echten
// Server-Timestamp, damit gewährt der WM den Fokus. Nur für den
// SNI-Pfad unter X11 — auf GNOME zeigt die Extension das Popup, dort
// hat das present() beim Map den Klick-Weg gebrochen (Ubuntu 17.07).
use gtk::prelude::*;
let gtk_win = app.get_webview_window("popup").unwrap().gtk_window()?;
if gtk_win.display().type_().name().starts_with("GdkX11")
&& !crate::platform::is_gnome()
{
gtk_win.connect_map_event(|w, _| {
w.present();
glib::Propagation::Proceed
});
}
}
// Der gesamte Tray-Kontrakt: Icon zeigen, Klick als Anchor melden —