forked from bilelmoussaoui/ashpd
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fixes: bilelmoussaoui#55
- Loading branch information
Showing
10 changed files
with
335 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
use super::wayland::WaylandActivationToken; | ||
use gtk3::glib::translate::ToGlibPtr; | ||
use gtk3::prelude::*; | ||
use gtk3::{gdk, glib}; | ||
use wayland_client::{ | ||
backend::ObjectId, | ||
protocol::{__interfaces::WL_SURFACE_INTERFACE, wl_surface::WlSurface}, | ||
Proxy, | ||
}; | ||
use wayland_protocols::xdg::activation::v1::client::xdg_activation_token_v1::XdgActivationTokenV1; | ||
|
||
#[derive(Debug)] | ||
pub struct Gtk3ActivationToken { | ||
pub token: String, | ||
inner: XdgActivationTokenV1, | ||
} | ||
|
||
impl Gtk3ActivationToken { | ||
pub fn from_window(window: &impl glib::IsA<gdk::Window>) -> Option<Self> { | ||
let display = window.as_ref().display(); | ||
match display.backend() { | ||
gdk::Backend::Wayland => { | ||
let cnx = wayland_client::Connection::connect_to_env().unwrap(); | ||
let wayland_window = window | ||
.as_ref() | ||
.downcast_ref::<gdk3wayland::WaylandWindow>() | ||
.unwrap(); | ||
let surface_id = unsafe { | ||
let ptr = gdk3wayland::ffi::gdk_wayland_window_get_wl_surface( | ||
wayland_window.to_glib_none().0, | ||
); | ||
|
||
ObjectId::from_ptr(&WL_SURFACE_INTERFACE, ptr as *mut _).unwrap() | ||
}; | ||
let wl_surface = WlSurface::from_id(&cnx, surface_id).unwrap(); | ||
let wl = WaylandActivationToken::from_surface(&wl_surface).ok()?; | ||
|
||
Some(Self::from(wl)) | ||
} | ||
// TODO Can this be implemented for X11? | ||
_ => None, | ||
} | ||
} | ||
} | ||
|
||
impl From<WaylandActivationToken> for Gtk3ActivationToken { | ||
fn from(mut wl_token: WaylandActivationToken) -> Self { | ||
let token = std::mem::take(&mut wl_token.token); | ||
// NOTE Safe unwrap, WlActivationToken has a inner set at construction. | ||
let inner = wl_token.inner.take().unwrap(); | ||
|
||
Self { inner, token } | ||
} | ||
} | ||
|
||
impl Drop for Gtk3ActivationToken { | ||
fn drop(&mut self) { | ||
self.inner.destroy(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
use super::wayland::WaylandActivationToken; | ||
use gtk4::{gdk, glib::translate::ToGlibPtr, prelude::*}; | ||
use wayland_client::{ | ||
backend::ObjectId, | ||
protocol::{__interfaces::WL_SURFACE_INTERFACE, wl_surface::WlSurface}, | ||
Proxy, | ||
}; | ||
use wayland_protocols::xdg::activation::v1::client::xdg_activation_token_v1::XdgActivationTokenV1; | ||
|
||
#[derive(Debug)] | ||
pub struct Gtk4ActivationToken { | ||
pub token: String, | ||
inner: XdgActivationTokenV1, | ||
} | ||
|
||
impl Gtk4ActivationToken { | ||
pub fn from_native(native: &impl ::gtk4::glib::IsA<::gtk4::Native>) -> Option<Self> { | ||
let surface = native.surface(); | ||
match surface.display().backend() { | ||
gdk::Backend::Wayland => { | ||
// TODO use WaylandSurface::wl_surface(), see | ||
// https://github.com/gtk-rs/gtk4-rs/pull/1053 | ||
let cnx = wayland_client::Connection::connect_to_env().unwrap(); | ||
let surface_id = unsafe { | ||
let ptr = gdk4wayland::ffi::gdk_wayland_surface_get_wl_surface( | ||
surface | ||
.downcast_ref::<gdk4wayland::WaylandSurface>() | ||
.unwrap() | ||
.to_glib_none() | ||
.0, | ||
); | ||
|
||
ObjectId::from_ptr(&WL_SURFACE_INTERFACE, ptr as *mut _).unwrap() | ||
}; | ||
let wl_surface = WlSurface::from_id(&cnx, surface_id).unwrap(); | ||
|
||
let wl = WaylandActivationToken::from_surface(&wl_surface).ok()?; | ||
|
||
Some(Self::from(wl)) | ||
} | ||
// TODO Can this be implemented for X11? | ||
_ => None, | ||
} | ||
} | ||
} | ||
|
||
impl From<WaylandActivationToken> for Gtk4ActivationToken { | ||
fn from(mut wl_token: WaylandActivationToken) -> Self { | ||
let token = std::mem::take(&mut wl_token.token); | ||
// NOTE Safe unwrap, WlActivationToken has a inner set at construction. | ||
let inner = wl_token.inner.take().unwrap(); | ||
|
||
Self { inner, token } | ||
} | ||
} | ||
|
||
impl Drop for Gtk4ActivationToken { | ||
fn drop(&mut self) { | ||
self.inner.destroy(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
#[cfg(all(feature = "gtk3", feature = "wayland"))] | ||
mod gtk3; | ||
#[cfg(all(feature = "gtk3", feature = "wayland"))] | ||
pub use self::gtk3::Gtk3ActivationToken; | ||
|
||
#[cfg(all(feature = "gtk4", feature = "wayland"))] | ||
mod gtk4; | ||
#[cfg(all(feature = "gtk4", feature = "wayland"))] | ||
pub use self::gtk4::Gtk4ActivationToken; | ||
|
||
#[cfg(any(feature = "wayland"))] | ||
mod wayland; | ||
#[cfg(feature = "wayland")] | ||
pub use wayland::WaylandActivationToken; | ||
|
||
use serde::{ser::Serializer, Serialize}; | ||
use zbus::zvariant::Type; | ||
|
||
// TODO | ||
/// See https://wayland.app/protocols/xdg-activation-v1 | ||
#[derive(Type)] | ||
#[zvariant(signature = "s")] | ||
#[derive(Debug)] | ||
pub enum ActivationToken { | ||
#[cfg(feature = "wayland")] | ||
#[doc(hidden)] | ||
Wayland(WaylandActivationToken), | ||
#[cfg(all(feature = "gtk4", feature = "wayland"))] | ||
#[doc(hidden)] | ||
Gtk4(Gtk4ActivationToken), | ||
#[cfg(all(feature = "gtk3", feature = "wayland"))] | ||
#[doc(hidden)] | ||
Gtk3(Gtk3ActivationToken), | ||
#[doc(hidden)] | ||
Raw(String), | ||
} | ||
|
||
impl Serialize for ActivationToken { | ||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||
where | ||
S: Serializer, | ||
{ | ||
serializer.serialize_str(self.as_str()) | ||
} | ||
} | ||
|
||
impl ActivationToken { | ||
#[cfg(feature = "wayland")] | ||
pub fn from_surface( | ||
surface: &wayland_client::protocol::wl_surface::WlSurface, | ||
) -> Result<Self, Box<dyn std::error::Error>> { | ||
let token = WaylandActivationToken::from_surface(surface)?; | ||
|
||
Ok(Self::Wayland(token)) | ||
} | ||
|
||
#[cfg(all(feature = "gtk4", feature = "wayland"))] | ||
pub fn from_native(native: &impl ::gtk4::glib::IsA<::gtk4::Native>) -> Option<Self> { | ||
let token = Gtk4ActivationToken::from_native(native)?; | ||
|
||
Some(Self::Gtk4(token)) | ||
} | ||
|
||
#[cfg(all(feature = "gtk3", feature = "wayland"))] | ||
pub fn from_window(window: &impl ::gtk3::glib::IsA<::gtk3::gdk::Window>) -> Option<Self> { | ||
let token = Gtk3ActivationToken::from_window(window)?; | ||
|
||
Some(Self::Gtk3(token)) | ||
} | ||
|
||
pub fn as_str(&self) -> &str { | ||
match self { | ||
#[cfg(feature = "wayland")] | ||
Self::Wayland(activation_token) => activation_token.token.as_str(), | ||
#[cfg(all(feature = "gtk4", feature = "wayland"))] | ||
Self::Gtk4(activation_token) => activation_token.token.as_str(), | ||
#[cfg(all(feature = "gtk3", feature = "wayland"))] | ||
Self::Gtk3(activation_token) => activation_token.token.as_str(), | ||
Self::Raw(string) => string.as_str(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
use once_cell::sync::OnceCell; | ||
use wayland_client::{protocol::wl_surface::WlSurface, Proxy, QueueHandle}; | ||
use wayland_protocols::xdg::activation::v1::client::{ | ||
xdg_activation_token_v1::{Event, XdgActivationTokenV1}, | ||
xdg_activation_v1::XdgActivationV1, | ||
}; | ||
|
||
#[derive(Debug, Default)] | ||
pub struct WaylandActivationToken { | ||
pub token: String, | ||
// We use a cell to transform Self into Gtk4ActivationToken. | ||
pub(super) inner: OnceCell<XdgActivationTokenV1>, | ||
} | ||
|
||
impl Drop for WaylandActivationToken { | ||
fn drop(&mut self) { | ||
if let Some(wl_token) = self.inner.take() { | ||
wl_token.destroy(); | ||
} | ||
} | ||
} | ||
|
||
impl WaylandActivationToken { | ||
pub fn from_surface(surface: &WlSurface) -> Result<Self, Box<dyn std::error::Error>> { | ||
let cnx = wayland_client::Connection::connect_to_env()?; | ||
let wl_activation = XdgActivationV1::from_id(&cnx, surface.id())?; | ||
let mut queue = cnx.new_event_queue(); | ||
let queue_handle = queue.handle(); | ||
let inner = wl_activation.get_activation_token(&queue_handle, ())?; | ||
let mut exported_token = ExportedActivationToken::default(); | ||
queue.blocking_dispatch(&mut exported_token)?; | ||
|
||
Ok(Self { | ||
token: exported_token.0, | ||
inner: OnceCell::with_value(inner), | ||
}) | ||
} | ||
} | ||
|
||
#[derive(Default)] | ||
struct ExportedActivationToken(String); | ||
impl wayland_client::Dispatch<XdgActivationTokenV1, ()> for ExportedActivationToken { | ||
fn event( | ||
&mut self, | ||
_proxy: &XdgActivationTokenV1, | ||
event: <XdgActivationTokenV1 as Proxy>::Event, | ||
_data: &(), | ||
_connhandle: &wayland_client::Connection, | ||
_qhandle: &QueueHandle<Self>, | ||
) { | ||
match event { | ||
Event::Done { token } => { | ||
self.0 = token; | ||
} | ||
_ => unreachable!(), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.