feat: a11y

This commit is contained in:
Ashley Wulber 2024-11-01 08:30:48 -04:00 committed by Ashley Wulber
parent 5a0df6afb6
commit 2612282fcf
5 changed files with 97 additions and 1 deletions

9
Cargo.lock generated
View file

@ -308,6 +308,14 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "cosmic-dbus-a11y"
version = "0.1.0"
source = "git+https://github.com/pop-os/dbus-settings-bindings#62100129240d164e39fff16bda34faad520936de"
dependencies = [
"zbus",
]
[[package]]
name = "cosmic-notifications-util"
version = "0.1.0"
@ -323,6 +331,7 @@ version = "0.1.0"
dependencies = [
"async-signals",
"color-eyre",
"cosmic-dbus-a11y",
"cosmic-notifications-util",
"futures-util",
"itertools",

View file

@ -11,6 +11,8 @@ publish = false
async-signals = "0.4"
color-eyre = "0.6"
futures-util = "0.3"
cosmic-dbus-a11y = { git = "https://github.com/pop-os/dbus-settings-bindings" }
launch-pad = { git = "https://github.com/pop-os/launch-pad" }
itertools = "0.12"
#launch-pad = { git = "https://github.com/pop-os/launch-pad", branch = "remove-sync-bounds" }

View file

@ -10,6 +10,7 @@ vendor_args := if vendor == '1' { '--frozen --offline' } else { '' }
debug_args := if debug == '1' { '' } else { '--release' }
cargo_args := vendor_args + ' ' + debug_args
xdp_cosmic := '/usr/libexec/xdg-desktop-portal-cosmic'
orca := '/usr/bin/orca'
bindir := prefix + '/bin'
systemddir := prefix + '/lib/systemd/user'
@ -19,7 +20,7 @@ applicationdir := prefix + '/share/applications'
all: _extract_vendor build
build:
XDP_COSMIC={{xdp_cosmic}} cargo build {{cargo_args}}
XDP_COSMIC={{xdp_cosmic}} ORCA={{orca}} cargo build {{cargo_args}}
# Installs files into the system
install:

80
src/a11y.rs Normal file
View file

@ -0,0 +1,80 @@
use futures_util::StreamExt;
use launch_pad::ProcessManager;
use tokio::sync::mpsc;
use tracing::Instrument;
const ORCA: Option<&'static str> = option_env!("ORCA");
pub async fn start_a11y(
env_vars: Vec<(String, String)>,
pman: ProcessManager,
) -> color_eyre::Result<()> {
let (tx, mut rx) = mpsc::unbounded_channel();
let mut process_key = None;
let conn = zbus::Connection::session().await?;
let proxy = cosmic_dbus_a11y::StatusProxy::new(&conn).await?;
tokio::spawn(async move {
let mut watch_changes = proxy.receive_screen_reader_enabled_changed().await;
let mut enabled = false;
if let Ok(status) = proxy.screen_reader_enabled().await {
_ = tx.send(status);
enabled = status;
}
while let Some(change) = watch_changes.next().await {
let Ok(new_enabled) = change.get().await else {
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
continue;
};
if enabled != new_enabled {
_ = tx.send(new_enabled);
enabled = new_enabled;
}
}
});
while let Some(enabled) = rx.recv().await {
let stdout_span = info_span!(parent: None, "screen-reader");
let stderr_span = stdout_span.clone();
if enabled && process_key.is_none() {
// spawn orca
match pman
.start(
launch_pad::process::Process::new()
.with_executable(ORCA.unwrap_or("/usr/bin/orca"))
.with_env(env_vars.clone())
.with_on_stdout(move |_, _, line| {
let stdout_span = stdout_span.clone();
async move {
info!("{}", line);
}
.instrument(stdout_span)
})
.with_on_stderr(move |_, _, line| {
let stderr_span = stderr_span.clone();
async move {
warn!("{}", line);
}
.instrument(stderr_span)
}),
)
.await
{
Ok(key) => {
process_key = Some(key);
}
Err(err) => {
tracing::error!("Failed to start screen reader {err:?}");
}
}
} else if !enabled && process_key.is_some() {
// kill orca
info!("Stopping screen reader");
if let Err(err) = pman.stop_process(process_key.take().unwrap()).await {
tracing::error!("Failed to stop screen reader. {err:?}")
}
}
}
Ok(())
}

View file

@ -2,6 +2,7 @@
#[macro_use]
extern crate tracing;
mod a11y;
mod comp;
mod notifications;
mod process;
@ -194,6 +195,9 @@ async fn start(
systemd::stop_systemd_target();
}
// start a11y if configured
tokio::spawn(a11y::start_a11y(env_vars.clone(), process_manager.clone()));
let (panel_notifications_fd, daemon_notifications_fd) =
notifications::create_socket().expect("Failed to create notification socket");