Ely Office: six offline-first desktop apps in Rust and GPUI
ElyDoc, ElyTable, ElyShow (LibreOfficeKit), ElyPDF (MuPDF), ElyTree (Git), ElyMark (Milkdown and CodeMirror in CEF). ElyMail and ElyAgent follow.
This commit is contained in:
817 files changed
+143101
No files matched your search
@@ -0,0 +1,94 @@
|
||||
use crate::{env, settings::Motion};
|
||||
|
||||
/// `ELY_REDUCE_MOTION` wins, then the setting, then the OS.
|
||||
pub fn reduce_motion(setting: Motion) -> bool {
|
||||
let (env, system) = (env::flag("ELY_REDUCE_MOTION"), os_reduce_motion());
|
||||
if env.is_none() && setting == Motion::System && system.is_none() {
|
||||
log::info!("accessibility: no reduce-motion setting found, using full motion");
|
||||
}
|
||||
reduce_motion_from(env, setting, system)
|
||||
}
|
||||
|
||||
fn reduce_motion_from(env: Option<bool>, setting: Motion, system: Option<bool>) -> bool {
|
||||
let set = match setting {
|
||||
Motion::System => None,
|
||||
Motion::Reduced => Some(true),
|
||||
Motion::Full => Some(false),
|
||||
};
|
||||
env.or(set).or(system).unwrap_or(false)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn os_reduce_motion() -> Option<bool> {
|
||||
Some(objc2_app_kit::NSWorkspace::sharedWorkspace().accessibilityDisplayShouldReduceMotion())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn os_reduce_motion() -> Option<bool> {
|
||||
let output = std::process::Command::new("gsettings")
|
||||
.args(["get", "org.gnome.desktop.interface", "enable-animations"])
|
||||
.output()
|
||||
.map_err(|error| log::debug!("accessibility: gsettings did not run: {error}"))
|
||||
.ok()?;
|
||||
if !output.status.success() {
|
||||
log::debug!("accessibility: gsettings has no enable-animations key");
|
||||
return None;
|
||||
}
|
||||
animations_enabled(&String::from_utf8_lossy(&output.stdout)).map(|enabled| !enabled)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn os_reduce_motion() -> Option<bool> {
|
||||
use windows_sys::Win32::UI::WindowsAndMessaging::{
|
||||
SPI_GETCLIENTAREAANIMATION, SystemParametersInfoW,
|
||||
};
|
||||
|
||||
let mut enabled: i32 = 1;
|
||||
// SAFETY: a live i32, the size the call expects.
|
||||
let read = unsafe {
|
||||
SystemParametersInfoW(
|
||||
SPI_GETCLIENTAREAANIMATION,
|
||||
0,
|
||||
(&mut enabled as *mut i32).cast(),
|
||||
0,
|
||||
)
|
||||
};
|
||||
(read != 0).then_some(enabled == 0)
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "linux", windows)))]
|
||||
fn os_reduce_motion() -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", test))]
|
||||
fn animations_enabled(gsettings: &str) -> Option<bool> {
|
||||
match gsettings.trim() {
|
||||
"true" => Some(true),
|
||||
"false" => Some(false),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{Motion, animations_enabled, reduce_motion_from};
|
||||
|
||||
#[test]
|
||||
fn the_env_wins_then_the_setting_then_the_os_then_full_motion() {
|
||||
assert!(reduce_motion_from(Some(true), Motion::Full, Some(false)));
|
||||
assert!(!reduce_motion_from(Some(false), Motion::Reduced, Some(true)));
|
||||
assert!(reduce_motion_from(None, Motion::Reduced, Some(false)));
|
||||
assert!(!reduce_motion_from(None, Motion::Full, Some(true)));
|
||||
assert!(reduce_motion_from(None, Motion::System, Some(true)));
|
||||
assert!(!reduce_motion_from(None, Motion::System, None));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gsettings_answers_parse_and_anything_else_is_no_answer() {
|
||||
assert_eq!(animations_enabled("true\n"), Some(true));
|
||||
assert_eq!(animations_enabled("false\n"), Some(false));
|
||||
assert_eq!(animations_enabled("uint32 7\n"), None);
|
||||
assert_eq!(animations_enabled(""), None);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user