Repository: zng-ui/zng (language: rust)

Issue:
Separate headless from headed in `WindowCloseRequestedArgs`
The `WindowCloseRequestedArgs` windows list does not differentiate between headed and headless. Can be confusing due to render tasks being able to set the headless window parent.


Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2e9de2b00..42c7c5e03 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -42,6 +42,7 @@ fn version_0_5() -> impl UiNode {
 ```
 * **Breaking** Rename `VarCapabilities` to `VarCapability`.
 * Fix `zng::view_process::default::run_same_process` not propagating app panics.
+* Add `WindowCloseRequestedArgs::headed/headless`.
 
 # 0.4.0
 
diff --git a/crates/zng-ext-window/src/types.rs b/crates/zng-ext-window/src/types.rs
index 903ca2993..a025ddf98 100644
--- a/crates/zng-ext-window/src/types.rs
+++ b/crates/zng-ext-window/src/types.rs
@@ -24,7 +24,7 @@ use zng_view_api::{
 
 pub use zng_view_api::window::{FocusIndicator, RenderMode, VideoMode, WindowButton, WindowState};
 
-use crate::{HeadlessMonitor, WINDOW_Ext as _};
+use crate::{HeadlessMonitor, WINDOW_Ext as _, WINDOWS};
 
 /// Window root node and values.
 ///
@@ -509,7 +509,7 @@ event_args! {
     ///
     /// Requesting `propagation().stop()` on this event cancels the window close.
     pub struct WindowCloseRequestedArgs {
-        /// Windows closing.
+        /// Windows closing, headed and headless.
         ///
         /// This is at least one window, is multiple if the close operation was requested as group, cancelling the request
         /// cancels close for all windows.
@@ -622,6 +622,23 @@ impl WindowFocusChangedArgs {
         }
     }
 }
+impl WindowCloseRequestedArgs {
+    /// Gets only headed windows that will close.
+    pub fn headed(&self) -> impl Iterator<Item = WindowId> + '_ {
+        self.windows
+            .iter()
+            .copied()
+            .filter(|&id| WINDOWS.mode(id).map(|m| m.is_headed()).unwrap_or(false))
+    }
+
+    /// Gets only headless windows that will close.
+    pub fn headless(&self) -> impl Iterator<Item = WindowId> + '_ {
+        self.windows
+            .iter()
+            .copied()
+            .filter(|&id| WINDOWS.mode(id).map(|m| m.is_headless()).unwrap_or(false))
+    }
+}
 
 event! {
     /// Window moved, resized or other state changed.
diff --git a/examples/window.rs b/examples/window.rs
index 22efe179a..77bbd4f2d 100644
--- a/examples/window.rs
+++ b/examples/window.rs
@@ -713,7 +713,7 @@ fn confirm_close() -> impl WidgetHandler<WindowCloseRequestedArgs> {
                 args.propagation().stop();
                 state.set(CloseState::Asking);
 
-                let dlg = close_dialog(args.windows.iter().copied().collect(), state.clone());
+                let dlg = close_dialog(args.headed().collect(), state.clone());
                 LAYERS.insert(LayerIndex::TOP_MOST, dlg)
             }
             CloseState::Asking => args.propagation().stop(),


Test patch: