diff --git a/Cargo.toml b/Cargo.toml index e8f131666..ec19d3174 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,8 +15,8 @@ rust-version = "1.75" async-std = ["zbus/async-io", "dep:async-fs", "dep:async-net"] default = ["async-std"] gtk4 = ["gtk4_x11", "gtk4_wayland"] -gtk4_wayland = ["gdk4wayland", "glib", "dep:gtk4"] -gtk4_x11 = ["gdk4x11", "glib", "dep:gtk4"] +gtk4_wayland = ["gdk4wayland", "glib/v2_76", "dep:gtk4"] +gtk4_x11 = ["gdk4x11", "glib/v2_76", "dep:gtk4"] raw_handle = ["raw-window-handle", "wayland"] tokio = ["zbus/tokio", "dep:tokio"] glib = ["dep:glib"] diff --git a/src/activation_token/gtk4.rs b/src/activation_token/gtk4.rs new file mode 100644 index 000000000..806d53b2c --- /dev/null +++ b/src/activation_token/gtk4.rs @@ -0,0 +1,28 @@ +use gtk4::{glib::translate::*, prelude::*}; + +use crate::ActivationToken; + +impl ActivationToken { + /// Gets an activation token from a window. + pub fn from_window(widget: &impl IsA<::gtk4::Widget>) -> Option { + let display = widget.as_ref().display(); + let context = display.app_launch_context(); + + // FIXME Call the vfunc directly since + // g_app_launch_context_get_startup_notify_id has NULL checks. + // + // See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/3933 + unsafe { + let klass: *mut gtk4::gio::ffi::GAppLaunchContextClass = + std::ptr::addr_of!((*context.class().parent()?)) as *mut _; + let get_startup_notify_id = (*klass).get_startup_notify_id.as_ref()?; + + from_glib_full::<_, Option>(get_startup_notify_id( + context.as_ptr().cast(), + std::ptr::null_mut(), + std::ptr::null_mut(), + )) + } + .map(Self::from) + } +} diff --git a/src/activation_token/mod.rs b/src/activation_token/mod.rs index 46836bb04..990971dc7 100644 --- a/src/activation_token/mod.rs +++ b/src/activation_token/mod.rs @@ -3,6 +3,9 @@ use std::ops::Deref; use serde::{Deserialize, Serialize}; use zbus::zvariant::Type; +#[cfg(any(feature = "gtk4_wayland", feature = "gtk4_x11"))] +mod gtk4; + /// A token that can be used to activate an application. /// /// No guarantees are made for the token structure.