use crate::reactive::global::GlobalSignal;
use crate::reactive::{RwSignal, Signal};
use crate::widgets::Modifiers;
static MODIFIERS: GlobalSignal<Modifiers> = GlobalSignal::new(Modifiers::default);
fn modifiers_signal() -> RwSignal<Modifiers> {
MODIFIERS.get()
}
pub fn keyboard_modifiers() -> Signal<Modifiers> {
modifiers_signal().read_only()
}
pub(crate) fn set_keyboard_modifiers(modifiers: Modifiers) {
let signal = modifiers_signal();
if signal.get_untracked() != modifiers {
signal.set(modifiers);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_state_starts_empty_and_follows_the_platform() {
modifiers_signal().set(Modifiers::default());
assert_eq!(keyboard_modifiers().get_untracked(), Modifiers::default());
let latched = Modifiers {
caps_lock: true,
..Default::default()
};
set_keyboard_modifiers(latched);
assert_eq!(keyboard_modifiers().get_untracked(), latched);
}
#[test]
fn the_first_reader_does_not_get_to_own_it() {
use crate::reactive::owner::{create_root_owner, dispose_owner_now, with_owner};
create_root_owner();
modifiers_signal().set(Modifiers::default());
let (_, scope) = with_owner(|| keyboard_modifiers().get_untracked());
dispose_owner_now(scope);
assert_eq!(
keyboard_modifiers().get_untracked(),
Modifiers::default(),
"the state has to outlive whichever scope happened to read it first"
);
set_keyboard_modifiers(Modifiers {
caps_lock: true,
..Default::default()
});
assert!(keyboard_modifiers().get_untracked().caps_lock);
}
#[test]
fn a_new_app_does_not_inherit_the_last_one_s_state() {
set_keyboard_modifiers(Modifiers {
caps_lock: true,
..Default::default()
});
assert!(keyboard_modifiers().get_untracked().caps_lock);
crate::reactive::storage::discard_all_signals();
assert_eq!(keyboard_modifiers().get_untracked(), Modifiers::default());
}
}