Port all dbus server/client to to zbus
Seems to generally be working well. May still need a few fixes.
This commit is contained in:
parent
8b5e1a7f12
commit
8b2a9c6359
13 changed files with 592 additions and 821 deletions
|
|
@ -1,106 +1,70 @@
|
|||
use gtk4::{
|
||||
gio,
|
||||
glib::{self, clone},
|
||||
prelude::*,
|
||||
};
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use zbus::{dbus_interface, MessageHeader, Result, SignalContext};
|
||||
|
||||
static STATUS_NOTIFIER_XML: &str = "
|
||||
<node name='/StatusNotifierWatcher'>
|
||||
<interface name='org.kde.StatusNotifierWatcher'>
|
||||
<method name='RegisterStatusNotifierItem'>
|
||||
<arg name='service' type='s' direction='in' />
|
||||
</method>
|
||||
use crate::dbus_service;
|
||||
|
||||
<method name='RegisterStatusNotifierHost'>
|
||||
<arg name='service' type='s' direction='in' />
|
||||
</method>
|
||||
|
||||
<property name='RegisteredStatusNotifierItems' type='as' access='read' />
|
||||
<property name='IsStatusNotifierHostRegistered' type='b' access='read' />
|
||||
<property name='ProtocolVersion' type='i' access='read' />
|
||||
|
||||
<signal name='StatusNotifierItemRegistered'>
|
||||
<arg type='s' name='service' direction='out' />
|
||||
</signal>
|
||||
|
||||
<signal name='StatusNotifierItemUnregistered'>
|
||||
<arg type='s' name='service' direction='out' />
|
||||
</signal>
|
||||
|
||||
<signal name='StatusNotifierHostRegistered' />
|
||||
|
||||
<signal name='StatusNotifierHostUnregistered' />
|
||||
</interface>
|
||||
</node>
|
||||
";
|
||||
|
||||
pub fn start() {
|
||||
gio::bus_own_name(
|
||||
gio::BusType::Session,
|
||||
"org.kde.StatusNotifierWatcher",
|
||||
gio::BusNameOwnerFlags::NONE,
|
||||
bus_acquired,
|
||||
name_acquired,
|
||||
name_lost,
|
||||
);
|
||||
#[derive(Default)]
|
||||
struct StatusNotifierWatcher {
|
||||
items: Arc<Mutex<Vec<String>>>,
|
||||
}
|
||||
|
||||
fn bus_acquired(_connection: gio::DBusConnection, _name: &str) {}
|
||||
|
||||
fn name_acquired(connection: gio::DBusConnection, _name: &str) {
|
||||
let introspection_data = gio::DBusNodeInfo::for_xml(STATUS_NOTIFIER_XML).unwrap();
|
||||
let interface_info = introspection_data
|
||||
.lookup_interface("org.kde.StatusNotifierWatcher")
|
||||
.unwrap();
|
||||
let items = Arc::new(Mutex::new(Vec::<String>::new()));
|
||||
let method_call = clone!(@strong items => move |connection: gio::DBusConnection,
|
||||
sender: &str,
|
||||
path: &str,
|
||||
interface: &str,
|
||||
method: &str,
|
||||
args: glib::Variant,
|
||||
invocation: gio::DBusMethodInvocation| {
|
||||
match method {
|
||||
"RegisterStatusNotifierItem" => {
|
||||
let (service,) = args.get::<(String,)>().unwrap();
|
||||
let service = format!("{}{}", sender, service);
|
||||
connection.emit_signal(None, path, interface, "StatusNotifierItemRegistered", Some(&(&service,).to_variant())).unwrap();
|
||||
// XXX emit unreigstered
|
||||
items.lock().unwrap().push(service);
|
||||
invocation.return_value(None);
|
||||
}
|
||||
"RegisterStatusNotifierHost" => {
|
||||
let (_service,) = args.get::<(String,)>().unwrap();
|
||||
// XXX emit registed/unregistered
|
||||
invocation.return_value(None);
|
||||
}
|
||||
_ => unreachable!()
|
||||
}
|
||||
});
|
||||
let get_property = clone!(@strong items => move |_: gio::DBusConnection, _sender: &str, _path: &str, _interface: &str, prop: &str| {
|
||||
match prop {
|
||||
"RegisteredStatusNotifierItems" => items.lock().unwrap().to_variant(),
|
||||
"IsStatusNotifierHostRegistered" => true.to_variant(),
|
||||
"ProtocolVersion" => 0i32.to_variant(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
});
|
||||
let set_property = |_: gio::DBusConnection,
|
||||
_sender: &str,
|
||||
_path: &str,
|
||||
_interface: &str,
|
||||
_prop: &str,
|
||||
_value: glib::Variant| { unreachable!() };
|
||||
if let Err(err) = connection.register_object(
|
||||
"/StatusNotifierWatcher",
|
||||
&interface_info,
|
||||
method_call,
|
||||
get_property,
|
||||
set_property,
|
||||
#[dbus_interface(name = "org.kde.StatusNotifierWatcher")]
|
||||
impl StatusNotifierWatcher {
|
||||
async fn RegisterStatusNotifierItem(
|
||||
&self,
|
||||
service: &str,
|
||||
#[zbus(header)] hdr: MessageHeader<'_>,
|
||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
||||
) {
|
||||
eprintln!("Failed to register object: {}", err);
|
||||
let service = format!("{}{}", hdr.sender().unwrap().unwrap(), service);
|
||||
Self::StatusNotifierItemRegistered(&ctxt, &service)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// XXX emit unreigstered
|
||||
self.items.lock().unwrap().push(service);
|
||||
}
|
||||
|
||||
fn RegisterStatusNotifierHost(&self, _service: &str) {
|
||||
// XXX emit registed/unregistered
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
fn RegisteredStatusNotifierItems(&self) -> Vec<String> {
|
||||
self.items.lock().unwrap().clone()
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
fn IsStatusNotifierHostRegistered(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
fn ProtocolVersion(&self) -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
async fn StatusNotifierItemRegistered(ctxt: &SignalContext<'_>, service: &str) -> Result<()>;
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
async fn StatusNotifierItemUnregistered(ctxt: &SignalContext<'_>, service: &str) -> Result<()>;
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
async fn StatusNotifierHostRegistered(ctxt: &SignalContext<'_>) -> Result<()>;
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
async fn StatusNotifierHostUnregistered(ctxt: &SignalContext<'_>) -> Result<()>;
|
||||
}
|
||||
|
||||
pub async fn start() {
|
||||
if let Err(err) = dbus_service::create("org.kde.StatusNotifierWatcher", |builder| {
|
||||
builder.serve_at("/StatusNotifierWatcher", StatusNotifierWatcher::default())
|
||||
})
|
||||
.await
|
||||
{
|
||||
eprintln!("Failed to start `StatusNotifierWatcher` service: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
fn name_lost(_connection: Option<gio::DBusConnection>, _name: &str) {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue