diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 00cd9d1..84aedd4 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -623,6 +623,16 @@ pub trait PlatformWindow: HasWindowHandle + HasDisplayHandle { answers: &[PromptButton], ) -> Option>; fn activate(&self); + /// Activate with an externally-generated xdg-activation token. + /// Wayland: issues `xdg_activation_v1.activate(token, surface)` directly, + /// bypassing this client's own (possibly stale) serial. The caller is + /// responsible for obtaining a token that carries a valid grab serial — + /// e.g. from GTK's `GdkAppLaunchContext::startup_notify_id()` on the + /// connection that received the user gesture. + /// Non-Wayland backends: ignore the token and fall back to `activate()`. + fn activate_with_token(&self, _token: &str) { + self.activate(); + } fn is_active(&self) -> bool; fn is_hovered(&self) -> bool; fn background_appearance(&self) -> WindowBackgroundAppearance; diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 659a34d..4b49aef 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -4883,6 +4883,15 @@ impl Window { self.platform_window.activate(); } + /// Focus the current window using an externally-generated xdg-activation token. + /// On Wayland this issues `xdg_activation_v1.activate(token, surface)`, which + /// Mutter honors when the token carries a valid grab serial (e.g. minted by + /// GTK on the connection that received the user gesture). On other platforms + /// this is equivalent to [`activate_window`](Self::activate_window). + pub fn activate_with_token(&self, token: &str) { + self.platform_window.activate_with_token(token); + } + /// Minimize the current window at the platform level. pub fn minimize_window(&self) { self.platform_window.minimize(); diff --git a/crates/gpui_linux/src/linux/wayland/window.rs b/crates/gpui_linux/src/linux/wayland/window.rs index 59db9dd..5cf07a5 100644 --- a/crates/gpui_linux/src/linux/wayland/window.rs +++ b/crates/gpui_linux/src/linux/wayland/window.rs @@ -1263,6 +1263,22 @@ impl PlatformWindow for WaylandWindow { } } + fn activate_with_token(&self, token: &str) { + // Activate using a token minted externally (e.g. by GTK on the + // connection that received the tray-click gesture). We pass it straight + // to `xdg_activation_v1.activate(token, surface)` — Mutter honors it + // because the token carries a valid grab serial + the focused surface, + // unlike `activate()` above which may use a stale serial. + let state = self.borrow(); + if let Some(activation) = &state.globals.activation { + activation.activate(token.to_string(), &state.surface); + } else { + // No xdg-activation global (e.g. older compositor): best-effort fallback. + drop(state); + self.activate(); + } + } + fn is_active(&self) -> bool { self.borrow().active }