Merge branch 'master_jammy' of github.com:pop-os/cosmic-applets into master_jammy
This commit is contained in:
commit
9859c153f8
5 changed files with 155 additions and 93 deletions
77
Cargo.lock
generated
77
Cargo.lock
generated
|
|
@ -368,7 +368,7 @@ dependencies = [
|
|||
"relm4-macros",
|
||||
"tokio",
|
||||
"tracker",
|
||||
"zbus",
|
||||
"zbus 2.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -381,7 +381,7 @@ dependencies = [
|
|||
"libcosmic",
|
||||
"libcosmic-applet",
|
||||
"relm4",
|
||||
"zbus",
|
||||
"zbus 2.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -395,7 +395,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"relm4-macros",
|
||||
"tokio",
|
||||
"zbus",
|
||||
"zbus 2.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -413,7 +413,7 @@ dependencies = [
|
|||
"relm4-macros",
|
||||
"slotmap",
|
||||
"tokio",
|
||||
"zbus",
|
||||
"zbus 2.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -430,7 +430,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"relm4-macros",
|
||||
"serde",
|
||||
"zbus",
|
||||
"zbus 2.3.2",
|
||||
"zbus_names",
|
||||
"zvariant",
|
||||
]
|
||||
|
|
@ -449,7 +449,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"relm4-macros",
|
||||
"tokio",
|
||||
"zbus",
|
||||
"zbus 2.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -464,8 +464,7 @@ dependencies = [
|
|||
"libcosmic-applet",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"zbus",
|
||||
"zbus_names",
|
||||
"zbus 3.1.0",
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
|
|
@ -482,7 +481,7 @@ dependencies = [
|
|||
"libcosmic-applet",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"zbus",
|
||||
"zbus 2.3.2",
|
||||
"zbus_names",
|
||||
"zvariant",
|
||||
]
|
||||
|
|
@ -521,7 +520,7 @@ dependencies = [
|
|||
"derive_builder",
|
||||
"procfs",
|
||||
"time 0.3.13",
|
||||
"zbus",
|
||||
"zbus 2.3.2",
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
|
|
@ -1713,7 +1712,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c03958f20018a20963daf0c16ada4f271ae2da3e0017fb40caa8b0e3dc5b0226"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"zbus",
|
||||
"zbus 2.3.2",
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
|
|
@ -1761,7 +1760,7 @@ dependencies = [
|
|||
"serde",
|
||||
"thiserror",
|
||||
"time 0.3.13",
|
||||
"zbus",
|
||||
"zbus 2.3.2",
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
|
|
@ -3179,7 +3178,46 @@ dependencies = [
|
|||
"tracing",
|
||||
"uds_windows",
|
||||
"winapi",
|
||||
"zbus_macros",
|
||||
"zbus_macros 2.3.2",
|
||||
"zbus_names",
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d37e0d34b881934b987b72a91fdc1daba9ebc90c1f91b7944c680991c4443fc6"
|
||||
dependencies = [
|
||||
"async-broadcast",
|
||||
"async-channel",
|
||||
"async-executor",
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"async-recursion",
|
||||
"async-task",
|
||||
"async-trait",
|
||||
"byteorder",
|
||||
"derivative",
|
||||
"dirs 4.0.0",
|
||||
"enumflags2",
|
||||
"event-listener",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"hex",
|
||||
"nix 0.24.2",
|
||||
"once_cell",
|
||||
"ordered-stream",
|
||||
"rand",
|
||||
"serde",
|
||||
"serde_repr",
|
||||
"sha1",
|
||||
"static_assertions",
|
||||
"tracing",
|
||||
"uds_windows",
|
||||
"winapi",
|
||||
"zbus_macros 3.1.0",
|
||||
"zbus_names",
|
||||
"zvariant",
|
||||
]
|
||||
|
|
@ -3197,6 +3235,19 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus_macros"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba7905f7c665ea41828bd69112902daa131191a85131fef0f60f7cc3bc2fbec4"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zbus_names"
|
||||
version = "2.2.0"
|
||||
|
|
|
|||
|
|
@ -13,6 +13,5 @@ libcosmic = { git = "https://github.com/pop-os/libcosmic", default-features = fa
|
|||
libcosmic-applet = { path = "../../libcosmic-applet" }
|
||||
once_cell = "1.12"
|
||||
serde = "1"
|
||||
zbus = "2.0.1"
|
||||
zbus_names = "2"
|
||||
zbus = "3"
|
||||
zvariant = "3"
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
use futures::prelude::*;
|
||||
use gtk4::glib::{self, clone};
|
||||
use std::cell::Cell;
|
||||
use zbus::fdo::{DBusProxy, RequestNameFlags, RequestNameReply};
|
||||
use zbus_names::WellKnownName;
|
||||
|
||||
pub async fn create<
|
||||
F: Fn(zbus::ConnectionBuilder<'static>) -> zbus::Result<zbus::ConnectionBuilder<'static>>,
|
||||
>(
|
||||
well_known_name: &'static str,
|
||||
serve_cb: F,
|
||||
) -> zbus::Result<zbus::Connection> {
|
||||
let well_known_name = WellKnownName::try_from(well_known_name)?;
|
||||
|
||||
let connection = serve_cb(zbus::ConnectionBuilder::session()?)?
|
||||
.build()
|
||||
.await?;
|
||||
let dbus_proxy = DBusProxy::new(&connection).await?;
|
||||
let mut name_owner_changed_stream = dbus_proxy.receive_name_owner_changed().await?;
|
||||
|
||||
let flags = RequestNameFlags::AllowReplacement.into();
|
||||
match dbus_proxy
|
||||
.request_name(well_known_name.as_ref(), flags)
|
||||
.await?
|
||||
{
|
||||
RequestNameReply::InQueue => {
|
||||
eprintln!("Bus name '{}' already owned", well_known_name);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
glib::MainContext::default().spawn_local(clone!(@strong connection => async move {
|
||||
let have_bus_name = Cell::new(false);
|
||||
let unique_name = connection.unique_name().map(|x| x.as_ref());
|
||||
while let Some(evt) = name_owner_changed_stream.next().await {
|
||||
let args = match evt.args() {
|
||||
Ok(args) => args,
|
||||
Err(_) => { continue; },
|
||||
};
|
||||
if args.name.as_ref() == well_known_name {
|
||||
if args.new_owner.as_ref() == unique_name.as_ref() {
|
||||
eprintln!("Acquired bus name: {}", well_known_name);
|
||||
have_bus_name.set(true);
|
||||
} else if have_bus_name.get() {
|
||||
eprintln!("Lost bus name: {}", well_known_name);
|
||||
have_bus_name.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
Ok(connection)
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
use cascade::cascade;
|
||||
use gtk4::{glib, prelude::*};
|
||||
|
||||
mod dbus_service;
|
||||
mod deref_cell;
|
||||
mod status_area;
|
||||
mod status_menu;
|
||||
|
|
|
|||
|
|
@ -1,74 +1,140 @@
|
|||
#![allow(non_snake_case)]
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use zbus::{dbus_interface, MessageHeader, Result, SignalContext};
|
||||
use futures::prelude::*;
|
||||
use gtk4::glib::{self, clone};
|
||||
use std::cell::Cell;
|
||||
use zbus::{
|
||||
dbus_interface,
|
||||
fdo::{DBusProxy, RequestNameFlags, RequestNameReply},
|
||||
names::{BusName, UniqueName, WellKnownName},
|
||||
MessageHeader, Result, SignalContext,
|
||||
};
|
||||
|
||||
use crate::dbus_service;
|
||||
const OBJECT_PATH: &str = "/StatusNotifierWatcher";
|
||||
|
||||
#[derive(Default)]
|
||||
struct StatusNotifierWatcher {
|
||||
items: Arc<Mutex<Vec<String>>>,
|
||||
items: Vec<(UniqueName<'static>, String)>,
|
||||
}
|
||||
|
||||
#[dbus_interface(name = "org.kde.StatusNotifierWatcher")]
|
||||
impl StatusNotifierWatcher {
|
||||
async fn RegisterStatusNotifierItem(
|
||||
&self,
|
||||
async fn register_status_notifier_item(
|
||||
&mut self,
|
||||
service: &str,
|
||||
#[zbus(header)] hdr: MessageHeader<'_>,
|
||||
#[zbus(signal_context)] ctxt: SignalContext<'_>,
|
||||
) {
|
||||
let sender = hdr.sender().unwrap().unwrap();
|
||||
let service = if service.starts_with('/') {
|
||||
format!("{}{}", hdr.sender().unwrap().unwrap(), service)
|
||||
format!("{}{}", sender, service)
|
||||
} else {
|
||||
service.to_string()
|
||||
};
|
||||
Self::StatusNotifierItemRegistered(&ctxt, &service)
|
||||
Self::status_notifier_item_registered(&ctxt, &service)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
// XXX emit unreigstered
|
||||
self.items.lock().unwrap().push(service);
|
||||
self.items.push((sender.to_owned(), service));
|
||||
}
|
||||
|
||||
fn RegisterStatusNotifierHost(&self, _service: &str) {
|
||||
fn register_status_notifier_host(&self, _service: &str) {
|
||||
// XXX emit registed/unregistered
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
fn RegisteredStatusNotifierItems(&self) -> Vec<String> {
|
||||
self.items.lock().unwrap().clone()
|
||||
fn registered_status_notifier_items(&self) -> Vec<String> {
|
||||
self.items.iter().map(|(_, x)| x.clone()).collect()
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
fn IsStatusNotifierHostRegistered(&self) -> bool {
|
||||
fn is_status_notifier_host_registered(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[dbus_interface(property)]
|
||||
fn ProtocolVersion(&self) -> i32 {
|
||||
fn protocol_version(&self) -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
async fn StatusNotifierItemRegistered(ctxt: &SignalContext<'_>, service: &str) -> Result<()>;
|
||||
async fn status_notifier_item_registered(ctxt: &SignalContext<'_>, service: &str)
|
||||
-> Result<()>;
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
async fn StatusNotifierItemUnregistered(ctxt: &SignalContext<'_>, service: &str) -> Result<()>;
|
||||
async fn status_notifier_item_unregistered(
|
||||
ctxt: &SignalContext<'_>,
|
||||
service: &str,
|
||||
) -> Result<()>;
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
async fn StatusNotifierHostRegistered(ctxt: &SignalContext<'_>) -> Result<()>;
|
||||
async fn status_notifier_host_registered(ctxt: &SignalContext<'_>) -> Result<()>;
|
||||
|
||||
#[dbus_interface(signal)]
|
||||
async fn StatusNotifierHostUnregistered(ctxt: &SignalContext<'_>) -> Result<()>;
|
||||
async fn status_notifier_host_unregistered(ctxt: &SignalContext<'_>) -> Result<()>;
|
||||
}
|
||||
|
||||
async fn create_service() -> zbus::Result<zbus::Connection> {
|
||||
let well_known_name = WellKnownName::try_from("org.kde.StatusNotifierWatcher")?;
|
||||
|
||||
let connection = zbus::ConnectionBuilder::session()?.build().await?;
|
||||
connection
|
||||
.object_server()
|
||||
.at(OBJECT_PATH, StatusNotifierWatcher::default())
|
||||
.await?;
|
||||
let interface = connection
|
||||
.object_server()
|
||||
.interface::<_, StatusNotifierWatcher>(OBJECT_PATH)
|
||||
.await
|
||||
.unwrap();
|
||||
let dbus_proxy = DBusProxy::new(&connection).await?;
|
||||
let mut name_owner_changed_stream = dbus_proxy.receive_name_owner_changed().await?;
|
||||
|
||||
let flags = RequestNameFlags::AllowReplacement.into();
|
||||
match dbus_proxy
|
||||
.request_name(well_known_name.as_ref(), flags)
|
||||
.await?
|
||||
{
|
||||
RequestNameReply::InQueue => {
|
||||
eprintln!("Bus name '{}' already owned", well_known_name);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
glib::MainContext::default().spawn_local(clone!(@strong connection => async move {
|
||||
let have_bus_name = Cell::new(false);
|
||||
let unique_name = connection.unique_name().map(|x| x.as_ref());
|
||||
while let Some(evt) = name_owner_changed_stream.next().await {
|
||||
let args = match evt.args() {
|
||||
Ok(args) => args,
|
||||
Err(_) => { continue; },
|
||||
};
|
||||
if args.name.as_ref() == well_known_name {
|
||||
if args.new_owner.as_ref() == unique_name.as_ref() {
|
||||
eprintln!("Acquired bus name: {}", well_known_name);
|
||||
have_bus_name.set(true);
|
||||
} else if have_bus_name.get() {
|
||||
eprintln!("Lost bus name: {}", well_known_name);
|
||||
have_bus_name.set(false);
|
||||
}
|
||||
} else if let BusName::Unique(name) = &args.name {
|
||||
let mut interface = interface.get_mut().await;
|
||||
if let Some(idx) = interface.items.iter().position(|(unique_name, _)| unique_name == name) {
|
||||
let ctxt = zbus::SignalContext::new(&connection, OBJECT_PATH).unwrap();
|
||||
let service = interface.items.remove(idx).1;
|
||||
StatusNotifierWatcher::status_notifier_item_unregistered(&ctxt, &service)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
Ok(connection)
|
||||
}
|
||||
|
||||
pub async fn start() {
|
||||
if let Err(err) = dbus_service::create("org.kde.StatusNotifierWatcher", |builder| {
|
||||
builder.serve_at("/StatusNotifierWatcher", StatusNotifierWatcher::default())
|
||||
})
|
||||
.await
|
||||
{
|
||||
if let Err(err) = create_service().await {
|
||||
eprintln!("Failed to start `StatusNotifierWatcher` service: {}", err);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue