xous-core/services/gam/src/modal/consoleinput.rs
bunnie ffa8385e7c refactor: send response packet after context has been switched
This refactor (at least partially) fixes a "mystery delay"
sometimes required after a dialog box swaps out. The previous
implementation would send the response, and then swap the contexts.
This would often cause the recipient to start drawing its UX
before the calling app was foregrounded, causing elements to go
missing.

This refactor puts the response after the context swap. The main
downside is it requires every type of modal to have a GAM
handle to issue the redraw call, and is especially complicated
by the fact that GAM is not clone-friendly. However, the
trade-offs of either creating a handle dynamically or storing
one in the object is probably worth the benefit of removing
an open-loop delay.
2022-11-06 18:36:20 +08:00

61 lines
No EOL
2.1 KiB
Rust

use crate::*;
/// This is a specialty structure that takes input from the serial console and records it to a string.
#[derive(Debug)]
pub struct ConsoleInput {
pub action_conn: xous::CID,
pub action_opcode: u32,
pub action_payload: TextEntryPayload,
gam: Gam,
}
impl Clone for ConsoleInput {
fn clone(&self) -> Self {
ConsoleInput {
action_conn: self.action_conn,
action_opcode: self.action_opcode,
action_payload: self.action_payload,
gam: crate::Gam::new(&xous_names::XousNames::new().unwrap()).unwrap(),
}
}
}
impl ConsoleInput {
pub fn new(action_conn: xous::CID, action_opcode: u32) -> Self {
ConsoleInput {
action_conn,
action_opcode,
action_payload: TextEntryPayload::new(),
gam: crate::Gam::new(&xous_names::XousNames::new().unwrap()).unwrap(),
}
}
}
impl ActionApi for ConsoleInput {
fn set_action_opcode(&mut self, op: u32) {self.action_opcode = op}
fn height(&self, _glyph_height: i16, margin: i16) -> i16 {
margin
}
fn redraw(&self, _at_height: i16, _modal: &Modal) {
// has nothing
}
fn key_action(&mut self, k: char) -> Option<ValidatorErr> {
log::trace!("key_action: {}", k);
match k {
'\u{0}' => {
// ignore null messages
}
'∴' | '\u{d}' => {
// relinquish focus before returning the result
self.gam.relinquish_focus().unwrap();
xous::yield_slice();
let buf = Buffer::into_buf(self.action_payload).expect("couldn't convert message to payload");
buf.send(self.action_conn, self.action_opcode).map(|_| ()).expect("couldn't send action message");
return None;
}
_ => { // text entry
self.action_payload.content.push(k).expect("ran out of space storing password");
log::trace!("****update payload: {}", self.action_payload.content);
}
}
None
}
}