From 0a9eb8a02708a7067aeaf0ad07e93aae277b68be Mon Sep 17 00:00:00 2001 From: Phillip Tennen Date: Sun, 27 Nov 2022 18:55:57 +0000 Subject: [PATCH] [awm2] Allow windows to update their titles --- rust_programs/Cargo.lock | 1 + rust_programs/awm2/Cargo.toml | 1 + rust_programs/awm2/src/desktop.rs | 50 ++++++++++++++++++++------- rust_programs/awm2/src/main_axle.rs | 18 ++++++++-- rust_programs/awm2/src/main_std.rs | 10 ++++-- rust_programs/awm_messages/src/lib.rs | 7 ++-- 6 files changed, 65 insertions(+), 22 deletions(-) diff --git a/rust_programs/Cargo.lock b/rust_programs/Cargo.lock index 64523b8b2..9afdeb74f 100644 --- a/rust_programs/Cargo.lock +++ b/rust_programs/Cargo.lock @@ -75,6 +75,7 @@ dependencies = [ "awm_messages", "axle_rt", "axle_rt_derive", + "file_manager_messages", "image", "kb_driver_messages", "lazy_static", diff --git a/rust_programs/awm2/Cargo.toml b/rust_programs/awm2/Cargo.toml index 9f0072fba..e2b980043 100644 --- a/rust_programs/awm2/Cargo.toml +++ b/rust_programs/awm2/Cargo.toml @@ -16,6 +16,7 @@ awm_messages = {path = "../awm_messages" } libgui = { path = "../libgui", default-features = false } mouse_driver_messages = {path = "../mouse_driver_messages" } kb_driver_messages = {path = "../kb_driver_messages" } +file_manager_messages = {path = "../file_manager_messages" } # PT: Just for holding a global RNG for random colors, not vital... rand = { version = "0.8.5", default-features = false, features = ["small_rng"] } lazy_static = { version = "1.4.0", default-features = false, features = ["spin_no_std"] } diff --git a/rust_programs/awm2/src/desktop.rs b/rust_programs/awm2/src/desktop.rs index 20ec6e5ed..a6cc4c34f 100644 --- a/rust_programs/awm2/src/desktop.rs +++ b/rust_programs/awm2/src/desktop.rs @@ -11,13 +11,14 @@ use alloc::rc::Rc; use alloc::string::{String, ToString}; use alloc::vec; use alloc::vec::Vec; -use awm_messages::AwmCreateWindow; +use awm_messages::{AwmCreateWindow, AwmWindowUpdateTitle}; use axle_rt::core_commands::AmcSharedMemoryCreateRequest; use core::cell::RefCell; use core::cmp::{max, min}; use core::fmt::{Display, Formatter}; use mouse_driver_messages::MousePacket; +use file_manager_messages::str_from_u8_nul_utf8_unchecked; use kb_driver_messages::{KeyEventType, KeyboardPacket}; use lazy_static::lazy_static; use rand::rngs::SmallRng; @@ -67,6 +68,7 @@ pub struct Window { pub owner_service: String, layer: RefCell, pub content_layer: RefCell, + title: RefCell>, } impl Window { @@ -80,6 +82,7 @@ impl Window { owner_service: owner_service.to_string(), layer: RefCell::new(SingleFramebufferLayer::new(total_size)), content_layer: RefCell::new(window_layer), + title: RefCell::new(None), } } @@ -87,7 +90,11 @@ impl Window { *self.frame.borrow_mut() = frame } - fn redraw_title_bar(&self) { + fn set_title(&self, new_title: &str) { + *self.title.borrow_mut() = Some(new_title.to_string()) + } + + fn redraw_title_bar(&self) -> Rect { let title_bar_frame = Rect::with_size(Size::new( self.frame().width(), Self::TITLE_BAR_HEIGHT as isize, @@ -97,7 +104,9 @@ impl Window { // Draw the window title let font_size = Size::new(8, 12); - let window_title = &self.owner_service; + let maybe_window_title = self.title.borrow(); + let window_title = maybe_window_title.as_ref().unwrap_or(&self.owner_service); + println!("Found title {window_title}"); let title_len = window_title.len(); let mut cursor = title_bar_frame.midpoint() - Point::new( @@ -105,10 +114,12 @@ impl Window { (((font_size.height as f64) / 2.0) - 1.0) as isize, ); let title_text_color = Color::new(50, 50, 50); - for ch in self.name().chars() { + for ch in window_title.chars() { title_bar_slice.draw_char(ch, cursor, title_text_color, font_size); cursor.x += font_size.width; } + + title_bar_frame.replace_origin(self.frame.borrow().origin) } pub fn render_remote_layer(&self) { @@ -624,7 +635,6 @@ impl Desktop { request: &AwmCreateWindow, origin: Option, ) -> Rc { - // Make a copy of the source service early as it's shared amc memory let source = source.to_string(); println!("Creating window of size {:?} for {}", request.size, source); @@ -787,19 +797,35 @@ impl Desktop { self.mouse_state.pos = pos } - pub fn handle_window_requested_redraw(&mut self, window_owner: &str) { - // Find the window - let window = { - // PT: Assumes a single window per client + fn window_for_owner(&self, window_owner: &str) -> Rc { + // PT: Assumes a single window per client + Rc::clone( self.windows .iter() .find(|w| w.owner_service == window_owner) - .expect(format!("Failed to find window for {}", window_owner).as_str()) - }; + .expect(format!("Failed to find window for {}", window_owner).as_str()), + ) + } + + pub fn handle_window_requested_redraw(&mut self, window_owner: &str) { + let window = self.window_for_owner(window_owner); // Render the framebuffer to the visible window layer window.render_remote_layer(); self.compositor_state - .queue_composite(Rc::clone(window) as Rc) + .queue_composite(Rc::clone(&window) as Rc) + } + + pub fn handle_window_updated_title(&self, window_owner: &str, update: &AwmWindowUpdateTitle) { + let new_title = str_from_u8_nul_utf8_unchecked(&update.title); + println!("Window for {window_owner} updated title to {new_title}"); + let window = self.window_for_owner(window_owner); + window.set_title(new_title); + let title_bar_frame = window.redraw_title_bar(); + println!("Queueing extra draw {title_bar_frame}"); + self.compositor_state.queue_extra_draw( + Rc::clone(&window) as Rc, + title_bar_frame, + ); } pub fn test(&mut self) { diff --git a/rust_programs/awm2/src/main_axle.rs b/rust_programs/awm2/src/main_axle.rs index 88de46000..96410f42e 100644 --- a/rust_programs/awm2/src/main_axle.rs +++ b/rust_programs/awm2/src/main_axle.rs @@ -20,7 +20,9 @@ use agx_definitions::{ Color, Drawable, Layer, LayerSlice, LikeLayerSlice, Line, NestedLayerSlice, Point, Rect, RectInsets, SingleFramebufferLayer, Size, StrokeThickness, }; -use awm_messages::{AwmCreateWindow, AwmCreateWindowResponse, AwmWindowRedrawReady}; +use awm_messages::{ + AwmCreateWindow, AwmCreateWindowResponse, AwmWindowRedrawReady, AwmWindowUpdateTitle, +}; use kb_driver_messages::KB_DRIVER_SERVICE_NAME; use mouse_driver_messages::{MousePacket, MOUSE_DRIVER_SERVICE_NAME}; @@ -118,8 +120,12 @@ pub fn main() { // // Wrap the whole thing in an unsafe block to reduce // boilerplate in each match arm. + // + // Make a copy of the message source to pass around so that callers don't need to worry + // about its validity + let msg_source = msg_unparsed.source().to_string(); unsafe { - match msg_unparsed.source() { + match msg_source.as_str() { MOUSE_DRIVER_SERVICE_NAME => match event { MousePacket::EXPECTED_EVENT => { desktop.handle_mouse_update(body_as_type_unchecked(raw_body)) @@ -141,7 +147,7 @@ pub fn main() { // Keyboard events AwmCreateWindow::EXPECTED_EVENT => { desktop.spawn_window( - msg_unparsed.source(), + &msg_source, body_as_type_unchecked(raw_body), None, ); @@ -150,6 +156,12 @@ pub fn main() { //println!("Window said it was ready to redraw!"); desktop.handle_window_requested_redraw(msg_unparsed.source()); } + AwmWindowUpdateTitle::EXPECTED_EVENT => { + desktop.handle_window_updated_title( + &msg_source, + body_as_type_unchecked(raw_body), + ); + } _ => { println!("Awm ignoring message with unknown event type: {event}"); } diff --git a/rust_programs/awm2/src/main_std.rs b/rust_programs/awm2/src/main_std.rs index b2f4aee94..230b4a730 100644 --- a/rust_programs/awm2/src/main_std.rs +++ b/rust_programs/awm2/src/main_std.rs @@ -1,7 +1,7 @@ use crate::desktop::{Desktop, RenderStrategy}; use agx_definitions::{Color, Layer, LikeLayerSlice, Point, Rect, Size}; use alloc::rc::Rc; -use awm_messages::AwmCreateWindow; +use awm_messages::{AwmCreateWindow, AwmWindowUpdateTitle}; use libgui::PixelLayer; use mouse_driver_messages::MousePacket; use pixels::{Error, Pixels, SurfaceTexture}; @@ -146,7 +146,13 @@ pub fn main() -> Result<(), Box> { } => { if let Some(key_code) = input.virtual_keycode { match key_code { - VirtualKeyCode::A => w1.render_remote_layer(), + VirtualKeyCode::A => { + w1.render_remote_layer(); + desktop.handle_window_updated_title( + "Window 0", + &AwmWindowUpdateTitle::new("New Title"), + ); + } VirtualKeyCode::B => w2.render_remote_layer(), VirtualKeyCode::C => w3.render_remote_layer(), VirtualKeyCode::D => desktop.test(), diff --git a/rust_programs/awm_messages/src/lib.rs b/rust_programs/awm_messages/src/lib.rs index 4b768f980..9e8dee939 100644 --- a/rust_programs/awm_messages/src/lib.rs +++ b/rust_programs/awm_messages/src/lib.rs @@ -82,19 +82,16 @@ impl ExpectsEventField for AwmWindowRedrawReady { #[repr(C)] #[derive(Debug, ContainsEventField)] -#[cfg(target_os = "axle")] pub struct AwmWindowUpdateTitle { event: u32, - title_len: u32, - title: [u8; 64], + pub title_len: u32, + pub title: [u8; 64], } -#[cfg(target_os = "axle")] impl ExpectsEventField for AwmWindowUpdateTitle { const EXPECTED_EVENT: u32 = 813; } -#[cfg(target_os = "axle")] impl AwmWindowUpdateTitle { pub fn new(title: &str) -> Self { let mut title_buf = [0; 64];