Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update atspi v0.22.0 #149

Merged
merged 35 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
ac469e7
Additional type fixups, handling of legacy cache item
TTWNO Apr 21, 2024
eac59eb
Desugar AFIT for send bounds enforcement
TTWNO Apr 21, 2024
11e1c28
children_num i32 -> usize
TTWNO Apr 22, 2024
b2522e1
Re-add old text interfaces to cache
TTWNO Apr 22, 2024
00244c5
i32 -> usize for string positioning
TTWNO Apr 22, 2024
83df5ac
Add clippy exceptions for cache crate
TTWNO Apr 22, 2024
2c24792
Fix clippy issues
TTWNO Apr 22, 2024
a6cf72e
Fix test compiles
TTWNO Apr 22, 2024
af3766c
Fix deps
TTWNO Apr 26, 2024
4dc666f
Remove the old code in state
TTWNO Apr 26, 2024
bcc54e1
Fix tests
TTWNO Apr 26, 2024
6592710
formatting
TTWNO Apr 26, 2024
371145e
Various cleanups
TTWNO May 8, 2024
e0a9830
Change debug level, and use question mark syntax
TTWNO May 8, 2024
f8f0849
Remove unused trait
TTWNO May 8, 2024
40300f7
Remove unused dep
TTWNO May 8, 2024
dd20e58
Remove config from state as it is unused
TTWNO May 8, 2024
15363e0
Thank clippy for its service
TTWNO May 8, 2024
cbbc034
Update notify for latest atspi
TTWNO May 8, 2024
94ecfc4
Remove atspi-client from deps
TTWNO May 13, 2024
5dce87c
Remove atspi-client from deps
TTWNO May 13, 2024
cf5bf16
Update to latest traits
TTWNO May 13, 2024
d627688
Upgrade to new atspi traits
TTWNO May 23, 2024
66a9734
Update cargo lock
TTWNO May 23, 2024
0bf03de
Fix test message building
TTWNO May 24, 2024
ec98d6a
default_features -> default-features
TTWNO May 24, 2024
831afee
Fix doc issues
TTWNO May 24, 2024
7c6c8e1
fmt
TTWNO May 24, 2024
c565bd6
Update to use live version of atspi
TTWNO May 24, 2024
3f0dc6e
Remove unused feature
TTWNO May 24, 2024
aaf214d
Merge branch 'main' into update-atspi-v0.22.0
TTWNO May 24, 2024
2562501
Remove unused deps
TTWNO May 24, 2024
910d537
fmt
TTWNO May 24, 2024
a8f20b8
Remove .expect and propagate errors up
TTWNO May 30, 2024
a20b3c2
Merge branch 'main' into update-atspi-v0.22.0
TTWNO May 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
936 changes: 485 additions & 451 deletions Cargo.lock

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,10 @@ pre-release-hook = ["cargo", "fmt"]
dependent-version = "upgrade"

[workspace.dependencies]
atspi = { version = "0.21.0", default-features = false, features = ["tokio"] }
atspi-client = { version = "0.1.0", default-features = false, features = ["tokio"] }
atspi-proxies = { version = "0.5.0", default-features = false, features = ["tokio"] }
atspi-common = { version = "0.5.0", default-features = false, features = ["tokio"] }
atspi-connection = { version = "0.5.0", default-features = false, features = ["tokio"] }
atspi = { version = "0.22.0", default-features = false, features = ["tokio"] }
atspi-proxies = { version = "0.6.0", default-features = false, features = ["tokio"] }
atspi-common = { version = "0.6.0", default-features = false, features = ["tokio"] }
atspi-connection = { version = "0.6.0", default-features = false, features = ["tokio"] }
odilia-common = { version = "0.3.0", path = "./common" }
odilia-cache = { version = "0.3.0", path = "./cache" }
eyre = "0.6.8"
Expand All @@ -50,7 +49,7 @@ tracing-log = "^0.1.3"
tracing-subscriber = { version = "0.3.16", default-features = false, features = ["env-filter", "parking_lot"] }
tracing-error = "^0.2.0"
tracing-tree = "^0.2.2"
zbus = { version = "3.14.1", features = ["tokio"] }
zbus = { version = "4.2", features = ["tokio"] }
serde_plain = "1.0.1"

xdg = "2.5.2"
2 changes: 1 addition & 1 deletion cache/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ categories = ["accessibility"]
atspi.workspace = true
atspi-proxies.workspace = true
atspi-common.workspace = true
atspi-client.workspace = true
odilia-common.workspace = true
dashmap = "5.4.0"
serde = "1.0.147"
Expand All @@ -24,6 +23,7 @@ tracing.workspace = true
zbus.workspace = true
fxhash = "0.2.1"
smartstring = { version = "1.0.1", features = ["serde"] }
serde_plain.workspace = true

[dev-dependencies]
criterion = { version = "0.4.0", features = ["async_tokio", "html_reports"] }
Expand Down
11 changes: 6 additions & 5 deletions cache/src/accessible_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@ impl AccessibleExt for AccessibleProxy<'_> {
{
let or: ObjectRef = self.get_application().await?;
let io: AccessiblePrimitive = or.into();
Ok(io.into_accessible(self.connection()).await?)
Ok(io.into_accessible(self.as_ref().connection()).await?)
}
async fn get_parent_ext<'a>(&self) -> Result<AccessibleProxy<'a>, Self::Error>
where
Self: Sized,
{
let or: ObjectRef = self.parent().await?;
let io: AccessiblePrimitive = or.into();
Ok(io.into_accessible(self.connection()).await?)
Ok(io.into_accessible(self.as_ref().connection()).await?)
}
async fn get_children_indexes<'a>(&self) -> Result<Vec<i32>, Self::Error> {
let mut indexes = Vec::new();
Expand All @@ -109,7 +109,7 @@ impl AccessibleExt for AccessibleProxy<'_> {
let children_refs = self.get_children().await?;
let mut children = Vec::new();
for child_refs in children_refs {
let acc = AccessibleProxy::builder(self.connection())
let acc = AccessibleProxy::builder(self.as_ref().connection())
.destination(child_refs.name)?
.cache_properties(CacheProperties::No)
.path(child_refs.path)?
Expand Down Expand Up @@ -273,8 +273,9 @@ impl AccessibleExt for AccessibleProxy<'_> {
let mut related_vec = Vec::new();
for related in relation.1 {
let related_ap: AccessiblePrimitive = related.into();
let ap: AccessibleProxy<'_> =
related_ap.into_accessible(self.connection()).await?;
let ap: AccessibleProxy<'_> = related_ap
.into_accessible(self.as_ref().connection())
.await?;
related_vec.push(ap);
}
relations.insert(relation.0, related_vec);
Expand Down
37 changes: 22 additions & 15 deletions cache/src/convertable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,48 @@ use atspi_proxies::{
table_cell::TableCellProxy, text::TextProxy, value::ValueProxy,
};
use std::future::Future;
use std::ops::Deref;
use zbus::{CacheProperties, Error, Proxy, ProxyBuilder, ProxyDefault};
use zbus::{proxy::ProxyImpl, CacheProperties, Error, Proxy, ProxyBuilder, ProxyDefault};

#[allow(clippy::module_name_repetitions)]
pub trait Convertable {
pub trait Convertable<'a> {
type Error: std::error::Error;

/// Creates an [`Self::Accessible`] from the existing accessible item.
/// Creates an [`AccessibleProxy`] from the existing accessible item.
/// # Errors
///
/// This may fail based on the implementation of.
/// Generally, it fails if the accessible item does not implement to accessible interface.
/// This shouldn't be possible, but this function may fail for other reasons.
/// For example, to convert a [`zbus::Proxy`] into a [`Self::Accessible`], it may fail to create the new [`atspi_proxies::accessible::AccessibleProxy`].
/// For example, to convert a [`zbus::Proxy`] into a [`AccessibleProxy`], it may fail to create the new [`atspi_proxies::accessible::AccessibleProxy`].
fn to_accessible(
&self,
) -> impl Future<Output = Result<AccessibleProxy, Self::Error>> + Send;
/// Creates an [`Self::Action`] from the existing accessible item.
/// Creates an [`ActionProxy`] from the existing accessible item.
/// # Errors
///
/// This may fail based on the implementation.
/// Generally, it fails if the accessible item does not implement to action interface.
fn to_action(&self) -> impl Future<Output = Result<ActionProxy, Self::Error>> + Send;
/// Creates an [`Self::Application`] from the existing accessible item.

/// Creates an [`ApplicationProxy`] from the existing accessible item.
/// # Errors
///
/// This may fail based on the implementation.
/// Generally, it fails if the accessible item does not implement to application interface.
fn to_application(
&self,
) -> impl Future<Output = Result<ApplicationProxy, Self::Error>> + Send;
/// Creates an [`Collection`] from the existing accessible item.

/// Creates an [`CollectionProxy`] from the existing accessible item.
/// # Errors
///
/// This may fail based on the implementation.
/// it fails if the accessible item does not implement to collection interface.
fn to_collection(
&self,
) -> impl Future<Output = Result<CollectionProxy, Self::Error>> + Send;
/// Creates an [`Component`] from the existing accessible item.

/// Creates an [`ComponentProxy`] from the existing accessible item.
/// # Errors
///
/// This may fail based on the implementation.
Expand All @@ -72,10 +74,12 @@ async fn convert_to_new_type<
'a,
'b,
T: From<Proxy<'b>> + ProxyDefault,
U: Deref<Target = Proxy<'a>> + ProxyDefault,
U: ProxyImpl<'a> + ProxyDefault,
>(
from: &U,
) -> zbus::Result<T> {
let from = from.inner();

// first thing is first, we need to creat an accessible to query the interfaces.
let accessible = AccessibleProxy::builder(from.connection())
.destination(from.destination())?
Expand All @@ -84,24 +88,27 @@ async fn convert_to_new_type<
.build()
.await?;
// if the interface we're trying to convert to is not available as an interface; this can be problematic because the interface we're passing in could potentially be different from what we're converting to.
let new_interface_name = Interface::try_from(<T as ProxyDefault>::INTERFACE)
.map_err(|_| Error::InterfaceNotFound)?;
let new_interface_name: Interface = serde_plain::from_str(
<T as ProxyDefault>::INTERFACE.ok_or(Error::InterfaceNotFound)?,
)
.map_err(|_| Error::InterfaceNotFound)?;
if !accessible.get_interfaces().await?.contains(new_interface_name) {
return Err(Error::InterfaceNotFound);
}
// otherwise, make a new Proxy with the related type.
let path = from.path().to_owned();
let dest = from.destination().to_owned();
ProxyBuilder::<'b, T>::new_bare(from.connection())
.interface(<T as ProxyDefault>::INTERFACE)?

ProxyBuilder::<T>::new(from.connection())
.interface(<T as ProxyDefault>::INTERFACE.ok_or(Error::InterfaceNotFound)?)?
.destination(dest)?
.cache_properties(CacheProperties::No)
.path(path)?
.build()
.await
}

impl<'a, T: Deref<Target = Proxy<'a>> + ProxyDefault + Sync> Convertable for T {
impl<'a, T: ProxyImpl<'a> + ProxyDefault + Sync> Convertable<'a> for T {
type Error = zbus::Error;
/* no guard due to assumption it is always possible */
async fn to_accessible(&self) -> zbus::Result<AccessibleProxy> {
Expand Down
44 changes: 17 additions & 27 deletions cache/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use std::{
};

use atspi_common::{
object_ref::ObjectRef, ClipType, CoordType, GenericEvent, Granularity, InterfaceSet,
object_ref::ObjectRef, ClipType, CoordType, EventProperties, Granularity, InterfaceSet,
RelationType, Role, StateSet,
};
use atspi_proxies::{accessible::AccessibleProxy, text::TextProxy};
Expand Down Expand Up @@ -110,7 +110,7 @@ impl AccessiblePrimitive {
/// # Errors
/// The errors are self-explanitory variants of the [`odilia_common::errors::AccessiblePrimitiveConversionError`].
#[tracing::instrument(skip_all, level = "trace", ret, err)]
pub fn from_event<'a, T: GenericEvent<'a>>(
pub fn from_event<T: EventProperties>(
event: &T,
) -> Result<Self, AccessiblePrimitiveConversionError> {
let sender = event.sender();
Expand All @@ -125,6 +125,7 @@ impl From<ObjectRef> for AccessiblePrimitive {
tuple_converter.into()
}
}

impl From<(OwnedUniqueName, OwnedObjectPath)> for AccessiblePrimitive {
fn from(so: (OwnedUniqueName, OwnedObjectPath)) -> AccessiblePrimitive {
let accessible_id = so.1;
Expand All @@ -149,6 +150,7 @@ impl<'a> TryFrom<&AccessibleProxy<'a>> for AccessiblePrimitive {

#[tracing::instrument(level = "trace", ret, err)]
fn try_from(accessible: &AccessibleProxy<'_>) -> Result<AccessiblePrimitive, Self::Error> {
let accessible = accessible.inner();
let sender = accessible.destination().as_str().into();
let id = accessible.path().as_str().into();
Ok(AccessiblePrimitive { id, sender })
Expand All @@ -159,6 +161,7 @@ impl<'a> TryFrom<AccessibleProxy<'a>> for AccessiblePrimitive {

#[tracing::instrument(level = "trace", ret, err)]
fn try_from(accessible: AccessibleProxy<'_>) -> Result<AccessiblePrimitive, Self::Error> {
let accessible = accessible.inner();
let sender = accessible.destination().as_str().into();
let id = accessible.path().as_str().into();
Ok(AccessiblePrimitive { id, sender })
Expand Down Expand Up @@ -218,7 +221,7 @@ impl CacheItem {
/// 2. We are unable to convert the [`AccessiblePrimitive`] to an [`atspi_proxies::accessible::AccessibleProxy`].
/// 3. The `accessible_to_cache_item` function fails for any reason. This also shouldn't happen.
#[tracing::instrument(level = "trace", skip_all, ret, err)]
pub async fn from_atspi_event<'a, T: GenericEvent<'a>>(
pub async fn from_atspi_event<T: EventProperties>(
event: &T,
cache: Weak<Cache>,
connection: &zbus::Connection,
Expand Down Expand Up @@ -304,7 +307,7 @@ impl CacheItem {
.collect(),
})
}
// Same as [`Accessible::get_children`], just offered as a non-async version.
// Same as [`AccessibleProxy::get_children`], just offered as a non-async version.
/// Get a `Vec` of children with the same type as `Self`.
/// # Errors
/// 1. Will return an `Err` variant if `self.cache` does not reference an active cache. This should never happen, but it is technically possible.
Expand Down Expand Up @@ -379,14 +382,14 @@ fn strong_cache(weak_cache: &Weak<Cache>) -> OdiliaResult<Arc<Cache>> {
}

impl CacheItem {
/// See [`atspi_proxies::accessible::Accessible::get_application`]
/// See [`atspi_proxies::accessible::AccessibleProxy::get_application`]
/// # Errors
/// - [`CacheError::NoItem`] if application is not in cache
pub fn get_application(&self) -> Result<Self, OdiliaError> {
let derefed_cache: Arc<Cache> = strong_cache(&self.cache)?;
derefed_cache.get(&self.app).ok_or(CacheError::NoItem.into())
}
/// See [`atspi_proxies::accessible::Accessible::parent`]
/// See [`atspi_proxies::accessible::AccessibleProxy::parent`]
/// # Errors
/// - [`CacheError::NoItem`] if application is not in cache
pub fn parent(&self) -> Result<Self, OdiliaError> {
Expand All @@ -396,31 +399,31 @@ impl CacheItem {
.or_else(|| self.cache.upgrade()?.get(&self.parent.key));
parent_item.ok_or(CacheError::NoItem.into())
}
/// See [`atspi_proxies::accessible::Accessible::get_attributes`]
/// See [`atspi_proxies::accessible::AccessibleProxy::get_attributes`]
/// # Errors
/// - If the item is no longer available over the AT-SPI connection.
pub async fn get_attributes(&self) -> Result<HashMap<String, String>, OdiliaError> {
Ok(as_accessible(self).await?.get_attributes().await?)
}
/// See [`atspi_proxies::accessible::Accessible::name`]
/// See [`atspi_proxies::accessible::AccessibleProxy::name`]
/// # Errors
/// - If the item is no longer available over the AT-SPI connection.
pub async fn name(&self) -> Result<String, OdiliaError> {
Ok(as_accessible(self).await?.name().await?)
}
/// See [`atspi_proxies::accessible::Accessible::locale`]
/// See [`atspi_proxies::accessible::AccessibleProxy::locale`]
/// # Errors
/// - If the item is no longer available over the AT-SPI connection.
pub async fn locale(&self) -> Result<String, OdiliaError> {
Ok(as_accessible(self).await?.locale().await?)
}
/// See [`atspi_proxies::accessible::Accessible::description`]
/// See [`atspi_proxies::accessible::AccessibleProxy::description`]
/// # Errors
/// - If the item is no longer available over the AT-SPI connection.
pub async fn description(&self) -> Result<String, OdiliaError> {
Ok(as_accessible(self).await?.description().await?)
}
/// See [`atspi_proxies::accessible::Accessible::get_realtion_set`]
/// See [`atspi_proxies::accessible::AccessibleProxy::get_relation_set`]
/// # Errors
/// - If the item is no longer available over the AT-SPI connection.
/// - The items mentioned are not in the cache.
Expand Down Expand Up @@ -451,7 +454,7 @@ impl CacheItem {
.map(|(relation, result_selfs)| Ok((relation, result_selfs?)))
.collect::<Result<Vec<(RelationType, Vec<Self>)>, OdiliaError>>()
}
/// See [`atspi_proxies::accessible::Accessible::get_child_at_index`]
/// See [`atspi_proxies::accessible::AccessibleProxy::get_child_at_index`]
/// # Errors
/// - The items mentioned are not in the cache.
pub fn get_child_at_index(&self, idx: i32) -> Result<Self, OdiliaError> {
Expand Down Expand Up @@ -621,22 +624,9 @@ impl CacheItem {
// this variation does NOT get a semantic line. It gets a visual line.
let dbus_version = as_text(self)
.await?
.get_string_at_offset(
offset.try_into().expect("Can not convert between usize and i32"),
granularity,
)
.get_string_at_offset(offset.try_into()?, granularity)
.await?;
Ok((
dbus_version.0,
dbus_version
.1
.try_into()
.expect("Can not convert between usize and i32"),
dbus_version
.2
.try_into()
.expect("Can not convert between usize and i32"),
))
Ok((dbus_version.0, dbus_version.1.try_into()?, dbus_version.2.try_into()?))
}
pub fn get_text(
&self,
Expand Down
2 changes: 1 addition & 1 deletion input/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ nix.workspace = true
odilia-common.workspace = true
once_cell = "1.16.0"
serde_json.workspace = true
sysinfo = { version = "0.26.8", default_features = false }
sysinfo = { version = "0.26.8", default-features = false }
tokio.workspace = true
tokio-util.workspace=true
tracing.workspace = true
5 changes: 2 additions & 3 deletions odilia-notify/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ pub async fn listen_to_dbus_notifications() -> Result<impl Stream<Item = Notific
.build();
debug!(?notify_rule, "finished generating rule");
info!("listening for notifications");
let notify_rule = notify_rule.to_string();
monitor.become_monitor(&[notify_rule.as_str()], 0).await?;
monitor.become_monitor(&[notify_rule], 0).await?;

let stream = MessageStream::from(monitor.connection()).filter_map(move |message| async {
let stream = MessageStream::from(connection).filter_map(move |message| async {
let notification = message.ok()?.try_into().ok()?;
debug!(?notification, "adding notification to stream");
Some(notification)
Expand Down
Loading
Loading