diff --git a/Cargo.lock b/Cargo.lock index 83b93c5..5b8fc47 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -706,6 +706,15 @@ dependencies = [ "memoffset", ] +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + [[package]] name = "num_enum" version = "0.7.3" @@ -727,6 +736,25 @@ dependencies = [ "syn", ] +[[package]] +name = "objc2-core-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +dependencies = [ + "bitflags", +] + +[[package]] +name = "objc2-io-kit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a" +dependencies = [ + "libc", + "objc2-core-foundation", +] + [[package]] name = "object" version = "0.36.7" @@ -1042,6 +1070,7 @@ dependencies = [ "serde", "serde_json", "strum", + "sysinfo", "tempfile", "tokio", "tokio-stream", @@ -1088,6 +1117,20 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sysinfo" +version = "0.35.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3ffa3e4ff2b324a57f7aeb3c349656c7b127c3c189520251a648102a92496e" +dependencies = [ + "libc", + "memchr", + "ntapi", + "objc2-core-foundation", + "objc2-io-kit", + "windows", +] + [[package]] name = "system-deps" version = "7.0.5" @@ -1357,6 +1400,108 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections", + "windows-core", + "windows-future", + "windows-link", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core", + "windows-link", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core", + "windows-link", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -1415,6 +1560,15 @@ dependencies = [ "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" diff --git a/Cargo.toml b/Cargo.toml index 956a1ee..7f7b42a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ regex = "1" serde = { version = "1.0", default-features = false, features = ["derive"] } serde_json = "1.0" strum = { version = "0.27", features = ["derive"] } +sysinfo = "0.35" tempfile = "3" tokio = { version = "1", default-features = false, features = ["fs", "io-std", "io-util", "macros", "process", "rt-multi-thread", "signal", "sync"] } tokio-stream = { version = "0.1", default-features = false } diff --git a/src/bin/steamosctl.rs b/src/bin/steamosctl.rs index c1bc142..04b5054 100644 --- a/src/bin/steamosctl.rs +++ b/src/bin/steamosctl.rs @@ -8,7 +8,7 @@ use anyhow::Result; use clap::{ArgAction, Parser, Subcommand}; use itertools::Itertools; -use nix::time::ClockId; +use nix::time::{clock_gettime, ClockId}; use std::collections::HashMap; use std::io::Cursor; use steamos_manager::cec::HdmiCecState; @@ -633,9 +633,10 @@ async fn main() -> Result<()> { } Commands::TriggerScreenReaderAction { action } => { let proxy = ScreenReader0Proxy::new(&conn).await?; - let timestamp = nix::time::clock_gettime(ClockId::CLOCK_MONOTONIC_RAW)?; + let timestamp = clock_gettime(ClockId::CLOCK_MONOTONIC_RAW)?; + let now = timestamp.tv_sec() * 1000000000 + timestamp.tv_nsec(); proxy - .trigger_action(*action as u32, timestamp.tv_nsec().try_into()?) + .trigger_action(*action as u32, now.try_into()?) .await?; } } diff --git a/src/screenreader.rs b/src/screenreader.rs index 547dad3..8d6f3a1 100644 --- a/src/screenreader.rs +++ b/src/screenreader.rs @@ -5,6 +5,7 @@ * SPDX-License-Identifier: MIT */ +use ::sysinfo::System; use anyhow::{anyhow, bail, ensure, Result}; use gio::{prelude::SettingsExt, Settings}; #[cfg(test)] @@ -15,6 +16,8 @@ use input_linux::{EventTime, Key, KeyEvent, KeyState, SynchronizeEvent}; use lazy_static::lazy_static; #[cfg(not(test))] use nix::fcntl::{fcntl, FcntlArg, OFlag}; +use nix::sys::signal; +use nix::unistd::Pid; use num_enum::TryFromPrimitive; use serde_json::{Map, Value}; use std::collections::HashMap; @@ -358,8 +361,8 @@ impl<'dbus> OrcaManager<'dbus> { match action { ScreenReaderAction::StopSpeaking => { // TODO: Use dbus method to stop orca from speaking instead once that's in a release/steamos package. - self.keyboard.key_down(Key::LeftCtrl)?; - self.keyboard.key_up(Key::LeftCtrl)?; + let pid = self.get_orca_pid()?; + signal::kill(pid, signal::Signal::SIGUSR2)?; } ScreenReaderAction::ReadNextWord => { self.keyboard.key_down(Key::LeftCtrl)?; @@ -420,6 +423,16 @@ impl<'dbus> OrcaManager<'dbus> { Ok(()) } + fn get_orca_pid(&self) -> Result { + let mut system = System::new(); + system.refresh_all(); + + let mut p = system.processes_by_name("orca".as_ref()); + + let pid = p.next().expect("No orca process found"); + Ok(Pid::from_raw(pid.pid().as_u32().try_into()?)) + } + async fn set_orca_enabled(&mut self, enabled: bool) -> Result<()> { // Change json file let data = read_to_string(self.settings_path()?).await?;