diff --git a/Cargo.toml b/Cargo.toml index 7458daf5d..a1e799f80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,9 +38,9 @@ futures = "0.3" tracing = {version = "0.1", optional = true} libc = {version = "0.2.94", optional = true} raw-window-handle = {version = "0.4", optional = true} -wayland-client = {version = "0.30.0-beta.3", optional = true} -wayland-protocols = {version = "0.30.0-beta.3", optional = true, features = ["unstable", "client", "staging"]} -wayland-backend = {version = "0.1.0-beta.3", optional = true, features = ["client_system"]} +wayland-client = {version = "0.30.0-beta.4", optional = true} +wayland-protocols = {version = "0.30.0-beta.4", optional = true, features = ["unstable", "client", "staging"]} +wayland-backend = {version = "0.1.0-beta.4", optional = true, features = ["client_system"]} async-std = {version = "1.11", optional = true} tokio = {version = "1.17", features = ["fs", "io-util"], optional = true, default-features = false} diff --git a/src/activation_token/gtk4.rs b/src/activation_token/gtk4.rs index 1948752f6..98b7bb0bb 100644 --- a/src/activation_token/gtk4.rs +++ b/src/activation_token/gtk4.rs @@ -8,11 +8,9 @@ pub struct Gtk4ActivationToken { impl Gtk4ActivationToken { pub fn from_native>(native: &N) -> Option { match native.backend() { - gdk::Backend::Wayland => native - .startup_notification_id() - .map(|token| Self { - token: token.to_string(), - }), + gdk::Backend::Wayland => native.startup_notification_id().map(|token| Self { + token: token.to_string(), + }), gdk::Backend::X11 => todo!(), _ => None, } diff --git a/src/activation_token/wayland.rs b/src/activation_token/wayland.rs index 2b30c6eed..3966bcb97 100644 --- a/src/activation_token/wayland.rs +++ b/src/activation_token/wayland.rs @@ -1,4 +1,7 @@ -use wayland_client::{protocol::wl_surface::WlSurface, Proxy, QueueHandle}; +use wayland_client::{ + protocol::{wl_registry, wl_surface::WlSurface}, + Proxy, QueueHandle, +}; use wayland_protocols::xdg::activation::v1::client::{ xdg_activation_token_v1::{Event, XdgActivationTokenV1}, xdg_activation_v1::XdgActivationV1, @@ -6,41 +9,53 @@ use wayland_protocols::xdg::activation::v1::client::{ #[derive(Debug, Default)] pub struct WaylandActivationToken { - pub token: String, - // We use a option to transform Self into Gtk4ActivationToken. - pub(super) inner: Option, + pub(crate) token: String, + wl_activation: Option, + wl_token: Option, } +// Is this ok? impl Drop for WaylandActivationToken { fn drop(&mut self) { - if let Some(wl_token) = self.inner.take() { + if let Some(wl_token) = self.wl_token.take() { wl_token.destroy(); } + + if let Some(wl_activation) = self.wl_activation.take() { + wl_activation.destroy(); + } } } impl WaylandActivationToken { + // Can be changed to display. pub fn from_surface(surface: &WlSurface) -> Result> { - let cnx = wayland_client::Connection::connect_to_env().unwrap(); - let wl_activation = XdgActivationV1::from_id(&cnx, surface.id()).unwrap(); - let mut queue = cnx.new_event_queue(); - let queue_handle = queue.handle(); - let inner = wl_activation - .get_activation_token(&queue_handle, ()) - .unwrap(); - let mut exported_token = ExportedActivationToken::default(); - queue.blocking_dispatch(&mut exported_token).unwrap(); - - Ok(Self { - token: exported_token.0, - inner: Some(inner), - }) + let backend = surface.backend().upgrade().unwrap(); + let cnx = wayland_client::Connection::from_backend(backend); + let display = cnx.display(); + let mut event_queue = cnx.new_event_queue(); + let qhandle = event_queue.handle(); + display.get_registry(&qhandle, ())?; + + let mut state = WaylandActivationToken::default(); + event_queue.sync_roundtrip(&mut state).unwrap(); + + let wl_activation = state.wl_activation.take().unwrap(); + let wl_token = wl_activation.get_activation_token(&qhandle, ())?; + // Maybe we can destroy this after getting the token as str? + state.wl_token = Some(wl_token); + // Maybe we can destroy this? + state.wl_activation = Some(wl_activation); + + event_queue.sync_roundtrip(&mut state).unwrap(); + + Ok(state) } } #[derive(Default)] struct ExportedActivationToken(String); -impl wayland_client::Dispatch for ExportedActivationToken { +impl wayland_client::Dispatch for WaylandActivationToken { fn event( &mut self, _proxy: &XdgActivationTokenV1, @@ -51,9 +66,47 @@ impl wayland_client::Dispatch for ExportedActivationTo ) { match event { Event::Done { token } => { - self.0 = token; + self.token = token; } _ => unreachable!(), } } } + +impl wayland_client::Dispatch for WaylandActivationToken { + fn event( + &mut self, + registry: &wl_registry::WlRegistry, + event: wl_registry::Event, + _: &(), + _: &wayland_client::Connection, + qhandle: &QueueHandle, + ) { + if let wl_registry::Event::Global { + name, + interface, + version, + } = event + { + println!("[{}] {} (v{})", name, interface, version); + if &interface == "xdg_activation_v1" { + let activation = registry + .bind::(name, 1, qhandle, ()) + .unwrap(); + self.wl_activation = Some(activation); + } + } + } +} + +impl wayland_client::Dispatch for WaylandActivationToken { + fn event( + &mut self, + _activation: &XdgActivationV1, + _event: wayland_protocols::xdg::activation::v1::client::xdg_activation_v1::Event, + _: &(), + _: &wayland_client::Connection, + _qhandle: &QueueHandle, + ) { + } +}