Skip to content

Commit

Permalink
Bind dbus_unregister vfunc
Browse files Browse the repository at this point in the history
  • Loading branch information
swsnr committed Jan 21, 2025
1 parent 5cea9ac commit f40c7d4
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 18 deletions.
53 changes: 36 additions & 17 deletions examples/gio_dbus_register_object/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ mod imp {
<arg type='u' name='delay' direction='in'/>
<arg type='s' name='greet' direction='out'/>
</method>
<method name='GoodBye'></method>
</interface>
</node>
"#;
Expand All @@ -56,6 +57,7 @@ mod imp {
enum HelloMethod {
Hello(Hello),
SlowHello(SlowHello),
GoodBye,
}

impl DBusMethodCall for HelloMethod {
Expand All @@ -68,6 +70,7 @@ mod imp {
match method {
"Hello" => Ok(params.get::<Hello>().map(Self::Hello)),
"SlowHello" => Ok(params.get::<SlowHello>().map(Self::SlowHello)),
"GoodBye" => Ok(Some(Self::GoodBye)),
_ => Err(glib::Error::new(IOErrorEnum::Failed, "No such method")),
}
.and_then(|p| {
Expand All @@ -94,24 +97,33 @@ mod imp {
connection
.register_object("/com/github/gtk_rs/examples/HelloWorld", &example)
.typed_method_call::<HelloMethod>()
.invoke_and_return_future_local(|_, sender, call| {
println!("Method call from {sender:?}");
async {
match call {
HelloMethod::Hello(Hello { name }) => {
let greet = format!("Hello {name}!");
println!("{greet}");
Ok(Some(greet.to_variant()))
}
HelloMethod::SlowHello(SlowHello { name, delay }) => {
glib::timeout_future(Duration::from_secs(delay as u64)).await;
let greet = format!("Hello {name} after {delay} seconds!");
println!("{greet}");
Ok(Some(greet.to_variant()))
.invoke_and_return_future_local(glib::clone!(
#[weak_allow_none(rename_to = app)]
self.obj(),
move |_, sender, call| {
println!("Method call from {sender:?}");
let app = app.clone();
async move {
match call {
HelloMethod::Hello(Hello { name }) => {
let greet = format!("Hello {name}!");
println!("{greet}");
Ok(Some(greet.to_variant()))
}
HelloMethod::SlowHello(SlowHello { name, delay }) => {
glib::timeout_future(Duration::from_secs(delay as u64)).await;
let greet = format!("Hello {name} after {delay} seconds!");
println!("{greet}");
Ok(Some(greet.to_variant()))
}
HelloMethod::GoodBye => {
app.inspect(|app| app.quit());
Ok(None)
}
}
}
}
})
))
.build()
}
}
Expand Down Expand Up @@ -140,9 +152,9 @@ mod imp {
Ok(())
}

fn shutdown(&self) {
fn dbus_unregister(&self, connection: &DBusConnection, object_path: &str) {
self.parent_dbus_unregister(connection, object_path);
if let Some(id) = self.registration_id.take() {
let connection = self.obj().dbus_connection().expect("connection");
if connection.unregister_object(id).is_ok() {
println!("Unregistered object");
} else {
Expand All @@ -151,9 +163,16 @@ mod imp {
}
}

fn shutdown(&self) {
self.parent_shutdown();
println!("Good bye!");
}

fn activate(&self) {
println!("Waiting for DBus Hello method to be called. Call the following command from another terminal:");
println!("dbus-send --print-reply --dest=com.github.gtk-rs.examples.RegisterDBusObject /com/github/gtk_rs/examples/HelloWorld com.github.gtk_rs.examples.HelloWorld.Hello string:YourName");
println!("Quit with the following command:");
println!("dbus-send --print-reply --dest=com.github.gtk-rs.examples.RegisterDBusObject /com/github/gtk_rs/examples/HelloWorld com.github.gtk_rs.examples.HelloWorld.GoodBye");
}
}
}
Expand Down
35 changes: 34 additions & 1 deletion gio/src/subclass/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ pub trait ApplicationImpl:
fn dbus_register(&self, connection: &DBusConnection, object_path: &str) -> Result<(), Error> {
self.parent_dbus_register(connection, object_path)
}

fn dbus_unregister(&self, connection: &DBusConnection, object_path: &str) {
self.parent_dbus_unregister(connection, object_path)
}
}

pub trait ApplicationImplExt: ApplicationImpl {
Expand Down Expand Up @@ -297,6 +301,21 @@ pub trait ApplicationImplExt: ApplicationImpl {
}
}
}

fn parent_dbus_unregister(&self, connection: &DBusConnection, object_path: &str) {
unsafe {
let data = Self::type_data();
let parent_class = data.as_ref().parent_class() as *mut ffi::GApplicationClass;
let f = (*parent_class)
.dbus_unregister
.expect("No parent class implementation for \"dbus_unregister\"");
f(
self.obj().unsafe_cast_ref::<Application>().to_glib_none().0,
connection.to_glib_none().0,
object_path.to_glib_none().0,
);
}
}
}

impl<T: ApplicationImpl> ApplicationImplExt for T {}
Expand All @@ -317,7 +336,8 @@ unsafe impl<T: ApplicationImpl> IsSubclassable<T> for Application {
klass.shutdown = Some(application_shutdown::<T>);
klass.startup = Some(application_startup::<T>);
klass.handle_local_options = Some(application_handle_local_options::<T>);
klass.dbus_register = Some(application_dbus_register::<T>)
klass.dbus_register = Some(application_dbus_register::<T>);
klass.dbus_unregister = Some(application_dbus_unregister::<T>);
}
}

Expand Down Expand Up @@ -445,6 +465,19 @@ unsafe extern "C" fn application_dbus_register<T: ApplicationImpl>(
}
}

unsafe extern "C" fn application_dbus_unregister<T: ApplicationImpl>(
ptr: *mut ffi::GApplication,
connection: *mut ffi::GDBusConnection,
object_path: *const c_char,
) {
let instance = &*(ptr as *mut T::Instance);
let imp = instance.imp();
imp.dbus_unregister(
&from_glib_borrow(connection),
&glib::GString::from_glib_borrow(object_path),
);
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down

0 comments on commit f40c7d4

Please sign in to comment.