feat(display): input routed via display server to focused app; input Subscribe; uses caps badged + Delegate
This commit is contained in:
56
crates/servers/display-server/src/focus.rs
Normal file
56
crates/servers/display-server/src/focus.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
//! Who gets input: the display server is the input server's only client
|
||||
//! and passes events on to the app in focus, the one that subscribed last.
|
||||
//! Apps out of focus get nothing.
|
||||
|
||||
/// Events received and not yet polled by the app in focus.
|
||||
const QUEUED: usize = 32;
|
||||
|
||||
pub struct Focus<N: Copy> {
|
||||
/// The app in focus: its badge and the notification it gave to be told.
|
||||
holder: Option<(usize, N)>,
|
||||
events: [[usize; 4]; QUEUED],
|
||||
head: usize,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl<N: Copy> Focus<N> {
|
||||
pub const fn new() -> Self {
|
||||
Self { holder: None, events: [[0; 4]; QUEUED], head: 0, len: 0 }
|
||||
}
|
||||
|
||||
/// `badge` takes focus; what the last holder had not read is dropped.
|
||||
pub fn subscribe(&mut self, badge: usize, notify: N) {
|
||||
self.holder = Some((badge, notify));
|
||||
self.len = 0;
|
||||
}
|
||||
|
||||
/// Queues an event (as the input server sends it) for the holder;
|
||||
/// returns whom to tell. With no holder the event goes nowhere.
|
||||
pub fn push(&mut self, event: [usize; 4]) -> Option<N> {
|
||||
let (_, notify) = self.holder?;
|
||||
if self.len == QUEUED {
|
||||
self.head = (self.head + 1) % QUEUED;
|
||||
self.len -= 1;
|
||||
}
|
||||
self.events[(self.head + self.len) % QUEUED] = event;
|
||||
self.len += 1;
|
||||
Some(notify)
|
||||
}
|
||||
|
||||
/// The next event for `badge`, if it is in focus and one is queued.
|
||||
pub fn poll(&mut self, badge: usize) -> Option<[usize; 4]> {
|
||||
if self.holder.is_none_or(|(b, _)| b != badge) || self.len == 0 {
|
||||
return None;
|
||||
}
|
||||
let event = self.events[self.head];
|
||||
self.head = (self.head + 1) % QUEUED;
|
||||
self.len -= 1;
|
||||
Some(event)
|
||||
}
|
||||
}
|
||||
|
||||
impl<N: Copy> Default for Focus<N> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user