mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-08 04:56:43 +00:00
deprecate request_focus api and make initial focus setting within the GAM
request_focus is "dangerous" because any random server could request a UX context to pop up. There is a checked version that requires a GAM token that should be used, but, this leaves the question of how does the initial app that's supposed to be focused gets set. A small mod to the UxRegistration call is made to check for the name of the default focus app, and when it is seen, a thread is fired off to request focus for that app. That allows us to deprecate this otherwise dangerous call.
This commit is contained in:
parent
583c2e172b
commit
02b2e4a6e7
5 changed files with 54 additions and 19 deletions
|
|
@ -161,9 +161,6 @@ pub(crate) enum Opcode {
|
|||
RevertFocus,
|
||||
RevertFocusNb, // non-blocking version
|
||||
|
||||
/// request an app to take the focus
|
||||
RequestFocus,
|
||||
|
||||
/// pass-through to get glyph heights to assist with layout planning, without having to create a gfx connection
|
||||
QueryGlyphProps,
|
||||
|
||||
|
|
|
|||
|
|
@ -408,7 +408,6 @@ impl ContextManager {
|
|||
// now re-check-out the new context and finalize things
|
||||
let maybe_new_focus = self.get_context_by_token(token);
|
||||
if let Some(context) = maybe_new_focus {
|
||||
self.notify_focus_change_to(gam::FocusState::Foreground, context).unwrap();
|
||||
if clear {
|
||||
context.layout.clear(gfx, canvases).expect("can't clear on context activation");
|
||||
}
|
||||
|
|
@ -422,6 +421,7 @@ impl ContextManager {
|
|||
// revert the keyboard vibe state
|
||||
self.kbd.set_vibe(context.vibe).expect("couldn't restore keyboard vibe");
|
||||
|
||||
self.notify_focus_change_to(gam::FocusState::Foreground, context).unwrap();
|
||||
log::debug!("raised focus to: {:?}", context);
|
||||
let last_token = context.app_token;
|
||||
self.last_context = self.focused_context;
|
||||
|
|
|
|||
|
|
@ -315,12 +315,6 @@ impl Gam {
|
|||
0, 0, 0, 0,)
|
||||
).map(|_| ())
|
||||
}
|
||||
pub fn request_focus(&self, token: [u32; 4]) -> Result<(), xous::Error> {
|
||||
send_message(self.conn,
|
||||
Message::new_blocking_scalar(Opcode::RequestFocus.to_usize().unwrap(),
|
||||
token[0] as usize, token[1] as usize, token[2] as usize, token[3] as usize,)
|
||||
).map(|_| ())
|
||||
}
|
||||
|
||||
pub fn glyph_height_hint(&self, glyph: GlyphStyle) -> Result<usize, xous::Error> {
|
||||
let response = send_message(self.conn,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,10 @@ use gam::{MAIN_MENU_NAME, ROOTKEY_MODAL_NAME};
|
|||
use log::info;
|
||||
use std::collections::HashMap;
|
||||
use num_traits::*;
|
||||
use core::{sync::atomic::{AtomicU32, Ordering}};
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
|
||||
/// This sets the initial app focus on boot
|
||||
const INITIAL_APP_FOCUS: &'static str = gam::APP_NAME_SHELLCHAT;
|
||||
|
||||
static CB_TO_MAIN_CONN: AtomicU32 = AtomicU32::new(0);
|
||||
fn imef_cb(s: String::<4000>) {
|
||||
|
|
@ -35,7 +38,7 @@ fn imef_cb(s: String::<4000>) {
|
|||
#[xous::xous_main]
|
||||
fn xmain() -> ! {
|
||||
log_server::init_wait().unwrap();
|
||||
log::set_max_level(log::LevelFilter::Info);
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
info!("my PID is {}", xous::process::id());
|
||||
|
||||
let xns = xous_names::XousNames::new().unwrap();
|
||||
|
|
@ -78,6 +81,9 @@ fn xmain() -> ! {
|
|||
)
|
||||
).expect("couldn't set status GID");
|
||||
|
||||
// a random number we can use to identify ourselves between API calls
|
||||
let gam_token = [trng.get_u32().unwrap(), trng.get_u32().unwrap(), trng.get_u32().unwrap(), trng.get_u32().unwrap()];
|
||||
|
||||
let mut powerdown_requested = false;
|
||||
let mut last_time: u64 = ticktimer.elapsed_ms();
|
||||
let mut did_test = false; // allow one go at the test pattern
|
||||
|
|
@ -396,6 +402,11 @@ fn xmain() -> ! {
|
|||
let mut buffer = unsafe{ Buffer::from_memory_message_mut(msg.body.memory_message_mut().unwrap()) };
|
||||
let registration = buffer.to_original::<UxRegistration, _>().unwrap();
|
||||
|
||||
let init_focus_found = if registration.app_name.as_str().unwrap_or("UTF-8 error") == INITIAL_APP_FOCUS {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
// note that we are currently assigning all Ux registrations a trust level consistent with a boot context (ultimately trusted)
|
||||
// this needs to be modified later on once we allow post-boot apps to be created
|
||||
let token = context_mgr.register(&gfx, &trng, &status_canvas, &mut canvases,
|
||||
|
|
@ -407,6 +418,22 @@ fn xmain() -> ! {
|
|||
canvases = recompute_canvases(&canvases, Rectangle::new(Point::new(0, 0), screensize));
|
||||
|
||||
buffer.replace(Return::UxToken(token)).unwrap();
|
||||
|
||||
// fire off a thread that deals with activating the initial boot context. You need this because this call has to complete before the context can respond to activation events.
|
||||
if token.is_some() & init_focus_found {
|
||||
std::thread::spawn({
|
||||
let gam_token = gam_token.clone();
|
||||
let conn = CB_TO_MAIN_CONN.load(Ordering::SeqCst);
|
||||
move || {
|
||||
let switchapp = SwitchToApp {
|
||||
token: gam_token,
|
||||
app_name: String::<128>::from_str(INITIAL_APP_FOCUS),
|
||||
};
|
||||
let buf = Buffer::into_buf(switchapp).or(Err(xous::Error::InternalError))?;
|
||||
buf.send(conn, Opcode::SwitchToApp.to_u32().unwrap()).or(Err(xous::Error::InternalError)).map(|_|())
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
Some(Opcode::SetAudioOpcode) => {
|
||||
let buffer = unsafe{ Buffer::from_memory_message(msg.body.memory_message().unwrap()) };
|
||||
|
|
@ -457,6 +484,7 @@ fn xmain() -> ! {
|
|||
Some(Opcode::RevertFocusNb) => {
|
||||
context_mgr.revert_focus(&gfx, &mut canvases);
|
||||
},
|
||||
/*
|
||||
Some(Opcode::RequestFocus) => msg_blocking_scalar_unpack!(msg, t0, t1, t2, t3, {
|
||||
// TODO: add some limitations around who can request focus
|
||||
// for now, it's the boot set so we just trust the requestor
|
||||
|
|
@ -464,7 +492,7 @@ fn xmain() -> ! {
|
|||
|
||||
// this is a blocking scalar, so return /something/ so we know to move on
|
||||
xous::return_scalar(msg.sender, 1).expect("couldn't confirm focus activation");
|
||||
}),
|
||||
}), */
|
||||
Some(Opcode::QueryGlyphProps) => msg_blocking_scalar_unpack!(msg, style, _, _, _, {
|
||||
let height = gfx.glyph_height_hint(GlyphStyle::from(style)).expect("couldn't query glyph height from gfx");
|
||||
xous::return_scalar(msg.sender, height).expect("could not return QueryGlyphProps request");
|
||||
|
|
@ -496,6 +524,10 @@ fn xmain() -> ! {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
// this message came from ourselves
|
||||
if gam_token == switchapp.token {
|
||||
context_mgr.activate(&gfx, &mut canvases, new_app_token, true);
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(Opcode::RaiseMenu) => {
|
||||
|
|
|
|||
|
|
@ -94,12 +94,9 @@ impl Repl{
|
|||
gotinput_id: Some(ShellOpcode::Line.to_u32().unwrap()),
|
||||
audioframe_id: None,
|
||||
rawkeys_id: None,
|
||||
focuschange_id: None, // shellchat will keep running in the background even if it has lost focus
|
||||
focuschange_id: Some(ShellOpcode::ChangeFocus.to_u32().unwrap()),
|
||||
}).expect("couldn't register Ux context for shellchat");
|
||||
|
||||
// we should be the first app running, so get the focus
|
||||
gam.request_focus(token.unwrap()).expect("couldn't take focus");
|
||||
|
||||
let content = gam.request_content_canvas(token.unwrap()).expect("couldn't get content canvas");
|
||||
log::trace!("content canvas {:?}", content);
|
||||
let screensize = gam.get_canvas_bounds(content).expect("couldn't get dimensions of content canvas");
|
||||
|
|
@ -278,6 +275,8 @@ enum ShellOpcode {
|
|||
Line = 0, // make sure we occupy opcodes with discriminants < 1000, as the rest are used for callbacks
|
||||
/// redraw our UI
|
||||
Redraw,
|
||||
/// change focus
|
||||
ChangeFocus,
|
||||
/// exit the application
|
||||
Quit,
|
||||
}
|
||||
|
|
@ -301,6 +300,7 @@ fn xmain() -> ! {
|
|||
let mut update_repl = false;
|
||||
let mut was_callback = false;
|
||||
|
||||
let mut allow_redraw = true;
|
||||
log::trace!("starting main loop");
|
||||
loop {
|
||||
let msg = xous::receive_message(shch_sid).unwrap();
|
||||
|
|
@ -315,9 +315,21 @@ fn xmain() -> ! {
|
|||
was_callback = false;
|
||||
}
|
||||
Some(ShellOpcode::Redraw) => {
|
||||
log::trace!("got Redraw");
|
||||
repl.redraw().expect("REPL couldn't redraw");
|
||||
if allow_redraw {
|
||||
repl.redraw().expect("REPL couldn't redraw");
|
||||
}
|
||||
}
|
||||
Some(ShellOpcode::ChangeFocus) => xous::msg_scalar_unpack!(msg, new_state_code, _, _, _, {
|
||||
let new_state = gam::FocusState::convert_focus_change(new_state_code);
|
||||
match new_state {
|
||||
gam::FocusState::Background => {
|
||||
allow_redraw = false;
|
||||
}
|
||||
gam::FocusState::Foreground => {
|
||||
allow_redraw = true;
|
||||
}
|
||||
}
|
||||
}),
|
||||
Some(ShellOpcode::Quit) => {
|
||||
log::error!("got Quit");
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in a new issue