From 1e1db4791ee24d545a4bdf07dceeb71dc3562975 Mon Sep 17 00:00:00 2001 From: Jeremy Whiting Date: Tue, 27 May 2025 15:45:55 -0600 Subject: [PATCH] screenreader: Use gio crate to set gnome screen-reader-enabled setting. --- Cargo.lock | 193 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/screenreader.rs | 32 +++----- 3 files changed, 207 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91225db..1f332b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -105,6 +105,16 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +[[package]] +name = "cfg-expr" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34e221e91c7eb5e8315b5c9cf1a61670938c0626451f954a51693ed44b37f45" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -295,12 +305,32 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + [[package]] name = "futures-core" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.31" @@ -320,12 +350,43 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "getrandom" version = "0.2.16" @@ -355,6 +416,91 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "gio" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2a5c3829f5794cb15120db87707b2ec03720edff7ad09eb7b711b532e3fe747" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio-sys" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521e93a7e56fc89e84aea9a52cfc9436816a4b363b030260b699950ff1336c83" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "windows-sys 0.59.0", +] + +[[package]] +name = "glib" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c501c495842c2b23cdacead803a5a343ca2a5d7a7ddaff14cc5f6cf22cfb92c2" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe6dc9ce29887c4b3b74d78d5ba473db160a258ae7ed883d23632ac7fed7bc9" +dependencies = [ + "heck", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ab79e1ed126803a8fb827e3de0e2ff95191912b8db65cee467edb56fc4cc215" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec9aca94bb73989e3cfdbf8f2e0f1f6da04db4d291c431f444838925c4c63eda" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -602,6 +748,12 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkg-config" version = "0.3.32" @@ -807,6 +959,21 @@ dependencies = [ "libc", ] +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + [[package]] name = "socket2" version = "0.5.9" @@ -831,6 +998,7 @@ dependencies = [ "async-trait", "clap", "config", + "gio", "inotify", "itertools", "lazy_static", @@ -887,6 +1055,25 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "system-deps" +version = "7.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4be53aa0cba896d2dc615bd42bbc130acdcffa239e0a2d965ea5b3b2a86ffdb" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" + [[package]] name = "tempfile" version = "3.20.0" @@ -1094,6 +1281,12 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index c60a604..6d5ef1d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ anyhow = "1" async-trait = "0.1" clap = { version = "4.5", default-features = false, features = ["derive", "help", "std", "usage"] } config = { version = "0.15", default-features = false, features = ["async", "ini", "toml"] } +gio = "0.20" inotify = { version = "0.11", default-features = false, features = ["stream"] } itertools = "0.14" lazy_static = "1" diff --git a/src/screenreader.rs b/src/screenreader.rs index 1075f7e..84121e5 100644 --- a/src/screenreader.rs +++ b/src/screenreader.rs @@ -6,12 +6,12 @@ */ use anyhow::{anyhow, bail, ensure, Result}; +use gio::{prelude::SettingsExt, Settings}; use lazy_static::lazy_static; use serde_json::{Map, Value}; use std::collections::HashMap; use std::ops::RangeInclusive; use std::path::PathBuf; -use std::process::Command; use tokio::fs::{read_to_string, write}; use tracing::{debug, error, info, trace, warn}; #[cfg(not(test))] @@ -29,6 +29,9 @@ const RATE_SETTING: &str = "rate"; const VOLUME_SETTING: &str = "gain"; const ENABLE_SETTING: &str = "enableSpeech"; +const A11Y_SETTING: &str = "org.gnome.desktop.a11y.applications"; +const SCREEN_READER_SETTING: &str = "screen-reader-enabled"; + const PITCH_DEFAULT: f64 = 5.0; const RATE_DEFAULT: f64 = 50.0; const VOLUME_DEFAULT: f64 = 10.0; @@ -62,6 +65,8 @@ impl<'dbus> OrcaManager<'dbus> { .load_values() .await .inspect_err(|e| warn!("Failed to load orca configuration: {e}")); + let a11ysettings = Settings::new(A11Y_SETTING); + manager.enabled = a11ysettings.boolean(SCREEN_READER_SETTING); Ok(manager) } @@ -88,29 +93,18 @@ impl<'dbus> OrcaManager<'dbus> { return Ok(()); } + { + let a11ysettings = Settings::new(A11Y_SETTING); + a11ysettings + .set_boolean(SCREEN_READER_SETTING, enable) + .map_err(|e| anyhow!("Unable to set screen reader enabled gsetting, {}", e))?; + // Settings::sync(); + } if enable { - // Enable screen reader gsettings - Command::new("gsettings") - .args([ - "set", - "org.gnome.desktop.a11y.applications", - "screen-reader-enabled", - "true", - ]) - .spawn()?; // Set orca enabled also self.set_orca_enabled(true).await?; self.restart_orca().await?; } else { - // Disable screen reader gsettings - Command::new("gsettings") - .args([ - "set", - "org.gnome.desktop.a11y.applications", - "screen-reader-enabled", - "false", - ]) - .spawn()?; // Set orca disabled also self.set_orca_enabled(false).await?; self.stop_orca().await?;