diff --git a/crates/console/prometeu-firmware/src/firmware/firmware.rs b/crates/console/prometeu-firmware/src/firmware/firmware.rs index cc31ecdb..3bb60111 100644 --- a/crates/console/prometeu-firmware/src/firmware/firmware.rs +++ b/crates/console/prometeu-firmware/src/firmware/firmware.rs @@ -350,8 +350,8 @@ mod tests { firmware.tick(&signals, &mut hardware); assert!(matches!(firmware.state, FirmwareState::ShellRunning(_))); - assert!(firmware.os.window().focused_window().is_some()); - assert_eq!(firmware.os.window().window_count(), 1); + assert!(firmware.os.windows().focused_window().is_some()); + assert_eq!(firmware.os.windows().window_count(), 1); } #[test] diff --git a/crates/console/prometeu-firmware/src/firmware/firmware_step_load_cartridge.rs b/crates/console/prometeu-firmware/src/firmware/firmware_step_load_cartridge.rs index 3542952f..b9d033c3 100644 --- a/crates/console/prometeu-firmware/src/firmware/firmware_step_load_cartridge.rs +++ b/crates/console/prometeu-firmware/src/firmware/firmware_step_load_cartridge.rs @@ -5,8 +5,9 @@ use crate::firmware::prometeu_context::PrometeuContext; use prometeu_hal::cartridge::{AppMode, Cartridge}; use prometeu_hal::color::Color; use prometeu_hal::log::{LogLevel, LogSource}; -use prometeu_hal::window::Rect; +use prometeu_hal::primitives::Rect; use prometeu_system::CrashReport; +use prometeu_system::windows::WindowOwner; #[derive(Debug, Clone)] pub struct LoadCartridgeStep { @@ -43,17 +44,17 @@ impl LoadCartridgeStep { } if self.cartridge.app_mode == AppMode::Shell { - let id = ctx.os.window().add_window( - self.cartridge.title.clone(), - Rect { x: 40, y: 20, w: 240, h: 140 }, - Color::WHITE, - ); - ctx.os.window().set_focus(id); - let task_id = ctx .os .sessions() .create_vm_shell_task(self.cartridge.app_id, self.cartridge.title.clone()); + let id = ctx.os.windows().add_window( + self.cartridge.title.clone(), + WindowOwner::Task(task_id), + Rect { x: 40, y: 20, w: 240, h: 140 }, + Color::WHITE, + ); + ctx.os.windows().set_focus(id); return Some(FirmwareState::ShellRunning(ShellRunningStep::new(task_id))); } diff --git a/crates/console/prometeu-hal/src/lib.rs b/crates/console/prometeu-hal/src/lib.rs index cc8de0a1..2e603b6b 100644 --- a/crates/console/prometeu-hal/src/lib.rs +++ b/crates/console/prometeu-hal/src/lib.rs @@ -18,6 +18,7 @@ pub mod log; pub mod native_helpers; pub mod native_interface; pub mod pad_bridge; +pub mod primitives; pub mod sample; pub mod scene_bank; pub mod scene_layer; @@ -31,7 +32,6 @@ pub mod tile; pub mod tilemap; pub mod touch_bridge; pub mod vm_fault; -pub mod window; pub use asset_bridge::AssetBridge; pub use audio_bridge::{AudioBridge, AudioOpStatus, LoopMode}; diff --git a/crates/console/prometeu-hal/src/primitives.rs b/crates/console/prometeu-hal/src/primitives.rs new file mode 100644 index 00000000..f1f62968 --- /dev/null +++ b/crates/console/prometeu-hal/src/primitives.rs @@ -0,0 +1,7 @@ +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct Rect { + pub x: i32, + pub y: i32, + pub w: i32, + pub h: i32, +} diff --git a/crates/console/prometeu-system/src/lib.rs b/crates/console/prometeu-system/src/lib.rs index 1773a865..1bbecddc 100644 --- a/crates/console/prometeu-system/src/lib.rs +++ b/crates/console/prometeu-system/src/lib.rs @@ -10,3 +10,4 @@ pub use services::fs; pub use services::process; pub use services::task; pub use services::vm_runtime::VirtualMachineRuntime; +pub use services::windows; diff --git a/crates/console/prometeu-system/src/os/facades/window.rs b/crates/console/prometeu-system/src/os/facades/window.rs index c22e76e0..5e6c8c90 100644 --- a/crates/console/prometeu-system/src/os/facades/window.rs +++ b/crates/console/prometeu-system/src/os/facades/window.rs @@ -1,14 +1,21 @@ use crate::os::SystemOS; +use crate::windows::{Window, WindowId, WindowOwner}; use prometeu_hal::color::Color; -use prometeu_hal::window::{Rect, Window, WindowId}; +use prometeu_hal::primitives::Rect; pub struct WindowFacade<'a> { pub(in crate::os) os: &'a mut SystemOS, } impl<'a> WindowFacade<'a> { - pub fn add_window(&mut self, title: String, viewport: Rect, color: Color) -> WindowId { - self.os.window_manager.add_window(title, viewport, color) + pub fn add_window( + &mut self, + title: String, + owner: WindowOwner, + viewport: Rect, + color: Color, + ) -> WindowId { + self.os.window_manager.add_window(title, owner, viewport, color) } pub fn set_focus(&mut self, id: WindowId) { diff --git a/crates/console/prometeu-system/src/os/system_os.rs b/crates/console/prometeu-system/src/os/system_os.rs index cb451866..ed3c05a8 100644 --- a/crates/console/prometeu-system/src/os/system_os.rs +++ b/crates/console/prometeu-system/src/os/system_os.rs @@ -3,7 +3,7 @@ use crate::fs::{FsState, VirtualFS}; use crate::os::{FsFacade, LifecycleFacade, SessionsFacade, VmFacade, WindowFacade}; use crate::process::ProcessManager; use crate::services::memcard::MemcardService; -use crate::services::window_manager::WindowManager; +use crate::services::windows::WindowManager; use crate::task::TaskManager; use prometeu_hal::log::{LogEvent, LogLevel, LogService, LogSource}; use prometeu_hal::telemetry::CertificationConfig; @@ -115,7 +115,7 @@ impl SystemOS { FsFacade { os: self } } - pub fn window(&mut self) -> WindowFacade<'_> { + pub fn windows(&mut self) -> WindowFacade<'_> { WindowFacade { os: self } } diff --git a/crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs b/crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs index 7754ddb1..8c219df7 100644 --- a/crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs +++ b/crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs @@ -1,7 +1,8 @@ +use crate::windows::WindowOwner; use crate::{CrashReport, SystemOS}; use prometeu_hal::color::Color; use prometeu_hal::log::{LogLevel, LogSource}; -use prometeu_hal::window::Rect; +use prometeu_hal::primitives::Rect; use prometeu_hal::{HardwareBridge, InputSignals}; use prometeu_vm::VirtualMachine; @@ -61,15 +62,15 @@ impl PrometeuHub { } if let Some((title, rect, color)) = next_window { - let mut window = os.window(); + let mut window = os.windows(); window.remove_all_windows(); - let id = window.add_window(title, rect, color); + let id = window.add_window(title, WindowOwner::Hub, rect, color); window.set_focus(id); } } pub fn render(&mut self, os: &mut SystemOS, hw: &mut dyn HardwareBridge) { - for window in os.window().windows() { + for window in os.windows().windows() { hw.gfx_mut().fill_rect( window.viewport.x, window.viewport.y, @@ -91,9 +92,9 @@ impl PrometeuHub { self.gui_update(os, hw); - if let Some(focused_id) = os.window().focused_window() { + if let Some(focused_id) = os.windows().focused_window() { if hw.pad().start().down { - os.window().close_window(focused_id); + os.windows().close_window(focused_id); } else { crash = os.vm().tick(vm, signals, hw); } @@ -102,6 +103,9 @@ impl PrometeuHub { self.render(os, hw); hw.gfx_mut().present(); - SystemProfileUpdate { crash, focused_window_active: os.window().focused_window().is_some() } + SystemProfileUpdate { + crash, + focused_window_active: os.windows().focused_window().is_some(), + } } } diff --git a/crates/console/prometeu-system/src/services/mod.rs b/crates/console/prometeu-system/src/services/mod.rs index 53a750cd..6dbdfab5 100644 --- a/crates/console/prometeu-system/src/services/mod.rs +++ b/crates/console/prometeu-system/src/services/mod.rs @@ -3,4 +3,4 @@ pub mod memcard; pub mod process; pub mod task; pub mod vm_runtime; -pub mod window_manager; +pub mod windows; diff --git a/crates/console/prometeu-system/src/services/windows/mod.rs b/crates/console/prometeu-system/src/services/windows/mod.rs new file mode 100644 index 00000000..81973145 --- /dev/null +++ b/crates/console/prometeu-system/src/services/windows/mod.rs @@ -0,0 +1,8 @@ +mod window; +mod window_manager; +mod window_owner; + +pub use window::Window; +pub use window::WindowId; +pub use window_manager::WindowManager; +pub use window_owner::WindowOwner; diff --git a/crates/console/prometeu-hal/src/window.rs b/crates/console/prometeu-system/src/services/windows/window.rs similarity index 61% rename from crates/console/prometeu-hal/src/window.rs rename to crates/console/prometeu-system/src/services/windows/window.rs index a699b505..652cc031 100644 --- a/crates/console/prometeu-hal/src/window.rs +++ b/crates/console/prometeu-system/src/services/windows/window.rs @@ -1,12 +1,6 @@ -use crate::color::Color; - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Rect { - pub x: i32, - pub y: i32, - pub w: i32, - pub h: i32, -} +use crate::windows::WindowOwner; +use prometeu_hal::color::Color; +use prometeu_hal::primitives::Rect; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct WindowId(pub u32); @@ -14,6 +8,7 @@ pub struct WindowId(pub u32); #[derive(Debug, Clone)] pub struct Window { pub id: WindowId, + pub owner: WindowOwner, pub viewport: Rect, pub has_focus: bool, pub title: String, diff --git a/crates/console/prometeu-system/src/services/window_manager.rs b/crates/console/prometeu-system/src/services/windows/window_manager.rs similarity index 68% rename from crates/console/prometeu-system/src/services/window_manager.rs rename to crates/console/prometeu-system/src/services/windows/window_manager.rs index eaab91ad..51099ecd 100644 --- a/crates/console/prometeu-system/src/services/window_manager.rs +++ b/crates/console/prometeu-system/src/services/windows/window_manager.rs @@ -1,5 +1,7 @@ +use crate::services::windows::window::{Window, WindowId}; +use crate::windows::WindowOwner; use prometeu_hal::color::Color; -use prometeu_hal::window::{Rect, Window, WindowId}; +use prometeu_hal::primitives::Rect; /// PROMETEU Window Manager. pub struct WindowManager { @@ -7,14 +9,26 @@ pub struct WindowManager { pub focused: Option, } +impl Default for WindowManager { + fn default() -> Self { + Self::new() + } +} + impl WindowManager { pub fn new() -> Self { Self { windows: Vec::new(), focused: None } } - pub fn add_window(&mut self, title: String, viewport: Rect, color: Color) -> WindowId { + pub fn add_window( + &mut self, + title: String, + owner: WindowOwner, + viewport: Rect, + color: Color, + ) -> WindowId { let id = WindowId(self.windows.len() as u32); - let window = Window { id, viewport, has_focus: false, title, color }; + let window = Window { id, owner, viewport, has_focus: false, title, color }; self.windows.push(window); id } @@ -46,10 +60,15 @@ mod tests { #[test] fn test_window_manager_focus() { let mut wm = WindowManager::new(); - let id1 = - wm.add_window("Window 1".to_string(), Rect { x: 0, y: 0, w: 10, h: 10 }, Color::WHITE); + let id1 = wm.add_window( + "Window 1".to_string(), + WindowOwner::Hub, + Rect { x: 0, y: 0, w: 10, h: 10 }, + Color::WHITE, + ); let id2 = wm.add_window( "Window 2".to_string(), + WindowOwner::Hub, Rect { x: 10, y: 10, w: 10, h: 10 }, Color::WHITE, ); @@ -71,8 +90,12 @@ mod tests { #[test] fn test_window_manager_remove_window() { let mut wm = WindowManager::new(); - let id = - wm.add_window("Window".to_string(), Rect { x: 0, y: 0, w: 10, h: 10 }, Color::WHITE); + let id = wm.add_window( + "Window".to_string(), + WindowOwner::Hub, + Rect { x: 0, y: 0, w: 10, h: 10 }, + Color::WHITE, + ); wm.set_focus(id); assert_eq!(wm.focused, Some(id)); diff --git a/crates/console/prometeu-system/src/services/windows/window_owner.rs b/crates/console/prometeu-system/src/services/windows/window_owner.rs new file mode 100644 index 00000000..f4842529 --- /dev/null +++ b/crates/console/prometeu-system/src/services/windows/window_owner.rs @@ -0,0 +1,21 @@ +use crate::task::TaskId; + +/// Identifies the logical owner of a shell window. +/// +/// Game cartridges do not currently own WindowManager windows. Games run as +/// fullscreen firmware steps. The WindowManager is used for Hub/Home UI, +/// Shell task windows, and system overlays. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum WindowOwner { + /// Window owned by the Prometeu Hub/Home. + Hub, + + /// Window owned by a managed Shell task. + Task(TaskId), + + /// Temporary system-owned window drawn above the current context. + /// + /// Examples: notifications, crash dialogs, quick menus, debug panels, + /// permission prompts, and modal confirmations. + Overlay, +}