@@ -2,14 +2,17 @@ use anyrender::WindowRenderer;
22use blitz_shell:: { BlitzApplication , View } ;
33use dioxus_core:: { provide_context, ScopeId } ;
44use dioxus_history:: { History , MemoryHistory } ;
5+ use std:: cell:: RefCell ;
56use std:: rc:: Rc ;
67use std:: sync:: Arc ;
78use winit:: application:: ApplicationHandler ;
89use winit:: event:: { StartCause , WindowEvent } ;
910use winit:: event_loop:: { ActiveEventLoop , EventLoopProxy } ;
1011use winit:: window:: WindowId ;
1112
12- use crate :: windowing:: { DioxusWindowHandle , DioxusWindowQueue , DioxusWindowTemplate } ;
13+ use crate :: windowing:: {
14+ DioxusWindowHandle , DioxusWindowInfo , DioxusWindowQueue , DioxusWindowTemplate ,
15+ } ;
1316use crate :: DioxusNativeWindowRenderer ;
1417use crate :: { contexts:: DioxusNativeDocument , BlitzShellEvent , DioxusDocument , WindowConfig } ;
1518
@@ -22,6 +25,12 @@ pub enum DioxusNativeEvent {
2225 /// Internal signal to create queued windows.
2326 SpawnQueuedWindows ,
2427
28+ /// Focus an existing window by id.
29+ FocusWindow { window_id : WindowId } ,
30+
31+ /// Update a window's title.
32+ SetWindowTitle { window_id : WindowId , title : String } ,
33+
2534 /// Create a new head element from the Link and Title elements
2635 ///
2736 /// todo(jon): these should probabkly be synchronous somehow
@@ -34,26 +43,29 @@ pub enum DioxusNativeEvent {
3443}
3544
3645pub struct DioxusNativeApplication {
37- pending_window : Option < WindowConfig < DioxusNativeWindowRenderer > > ,
46+ pending_window : Option < ( WindowConfig < DioxusNativeWindowRenderer > , String ) > ,
3847 inner : BlitzApplication < DioxusNativeWindowRenderer > ,
3948 proxy : EventLoopProxy < BlitzShellEvent > ,
4049 window_template : Arc < DioxusWindowTemplate > ,
4150 window_queue : Rc < DioxusWindowQueue > ,
51+ window_registry : Rc < RefCell < Vec < DioxusWindowInfo > > > ,
4252}
4353
4454impl DioxusNativeApplication {
4555 pub ( crate ) fn new (
4656 proxy : EventLoopProxy < BlitzShellEvent > ,
47- config : WindowConfig < DioxusNativeWindowRenderer > ,
57+ pending_window : ( WindowConfig < DioxusNativeWindowRenderer > , String ) ,
4858 window_template : Arc < DioxusWindowTemplate > ,
4959 window_queue : Rc < DioxusWindowQueue > ,
60+ window_registry : Rc < RefCell < Vec < DioxusWindowInfo > > > ,
5061 ) -> Self {
5162 Self {
52- pending_window : Some ( config ) ,
63+ pending_window : Some ( pending_window ) ,
5364 inner : BlitzApplication :: new ( proxy. clone ( ) ) ,
5465 proxy,
5566 window_template,
5667 window_queue,
68+ window_registry,
5769 }
5870 }
5971
@@ -64,6 +76,7 @@ impl DioxusNativeApplication {
6476 fn spawn_window (
6577 & mut self ,
6678 config : WindowConfig < DioxusNativeWindowRenderer > ,
79+ label : String ,
6780 event_loop : & ActiveEventLoop ,
6881 auto_resume : bool ,
6982 ) {
@@ -76,6 +89,7 @@ impl DioxusNativeApplication {
7689 }
7790 }
7891 let window_id = window. window_id ( ) ;
92+ self . register_window ( window_id, label) ;
7993 self . inner . windows . insert ( window_id, window) ;
8094 }
8195
@@ -94,6 +108,7 @@ impl DioxusNativeApplication {
94108 self . proxy . clone ( ) ,
95109 Arc :: clone ( & self . window_template ) ,
96110 Rc :: clone ( & self . window_queue ) ,
111+ Rc :: clone ( & self . window_registry ) ,
97112 ) ;
98113 doc. vdom
99114 . in_scope ( ScopeId :: ROOT , || provide_context ( window_handle. clone ( ) ) ) ;
@@ -114,8 +129,29 @@ impl DioxusNativeApplication {
114129 }
115130
116131 fn drain_window_queue ( & mut self , event_loop : & ActiveEventLoop ) {
117- for config in self . window_queue . drain ( ) {
118- self . spawn_window ( config, event_loop, true ) ;
132+ for queued in self . window_queue . drain ( ) {
133+ self . spawn_window ( queued. config , queued. title , event_loop, true ) ;
134+ }
135+ }
136+
137+ fn register_window ( & self , window_id : WindowId , title : String ) {
138+ self . window_registry . borrow_mut ( ) . push ( DioxusWindowInfo {
139+ id : window_id,
140+ title,
141+ } ) ;
142+ }
143+
144+ fn unregister_window ( & self , window_id : WindowId ) {
145+ let mut registry = self . window_registry . borrow_mut ( ) ;
146+ registry. retain ( |info| info. id != window_id) ;
147+ }
148+
149+ fn update_window_title ( & self , window_id : WindowId , title : String ) {
150+ for info in self . window_registry . borrow_mut ( ) . iter_mut ( ) {
151+ if info. id == window_id {
152+ info. title = title. clone ( ) ;
153+ break ;
154+ }
119155 }
120156 }
121157
@@ -164,6 +200,19 @@ impl DioxusNativeApplication {
164200 }
165201 }
166202
203+ DioxusNativeEvent :: FocusWindow { window_id } => {
204+ if let Some ( window) = self . inner . windows . get_mut ( window_id) {
205+ window. window . focus_window ( ) ;
206+ }
207+ }
208+
209+ DioxusNativeEvent :: SetWindowTitle { window_id, title } => {
210+ if let Some ( window) = self . inner . windows . get_mut ( window_id) {
211+ window. window . set_title ( title) ;
212+ self . update_window_title ( * window_id, title. to_string ( ) ) ;
213+ }
214+ }
215+
167216 DioxusNativeEvent :: SpawnQueuedWindows => {
168217 self . drain_window_queue ( event_loop) ;
169218 }
@@ -184,8 +233,8 @@ impl ApplicationHandler<BlitzShellEvent> for DioxusNativeApplication {
184233 #[ cfg( feature = "tracing" ) ]
185234 tracing:: debug!( "Injecting document provider into all windows" ) ;
186235
187- if let Some ( config) = self . pending_window . take ( ) {
188- self . spawn_window ( config, event_loop, false ) ;
236+ if let Some ( ( config, label ) ) = self . pending_window . take ( ) {
237+ self . spawn_window ( config, label , event_loop, false ) ;
189238 }
190239
191240 self . drain_window_queue ( event_loop) ;
@@ -206,6 +255,9 @@ impl ApplicationHandler<BlitzShellEvent> for DioxusNativeApplication {
206255 window_id : WindowId ,
207256 event : WindowEvent ,
208257 ) {
258+ if matches ! ( event, WindowEvent :: CloseRequested ) {
259+ self . unregister_window ( window_id) ;
260+ }
209261 self . inner . window_event ( event_loop, window_id, event) ;
210262 }
211263
0 commit comments