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

Issue:
Qt backend: Escape does not close PopupWindow
### Bug Description

The escape key should close a PopupWindow. It does with winit and WASM, but nothing happens with the Qt backend.

### Reproducible Code (if applicable)

```slint
export component AppWindow inherits Window {
    width: 100px;
    height: 100px;

    popup := PopupWindow {
        Rectangle {
            background: yellow;
        }

        x: 10px;
        y: 10px;
        height: 50px;
        width: 50px;
    }


    TouchArea {
        clicked => {
            popup.show();
        }
    }
}
```


### Environment Details

- Slint Version: 1.9.1
- Platform/OS: Linux
- Backend/Renderer: Qt


### Product Impact

_No response_


Discussion / hints:
Thanks for the bug report. I can reproduce.
The problem is that with the Qt backend, the key event are processed on the `WindowInner` for the PopupWindow (the winit backend don't create separate window for this)
So the `self` in this line https://github.com/slint-ui/slint/blob/57f42c087001628ba17fd70008d93fcc439c1dc6/internal/core/window.rs#L749 is the popup window itself and therefore doesn't have child popup to close.
Interesting, so perhaps active_popups should be Rc and shared?

Fix patch:
diff --git a/internal/core/window.rs b/internal/core/window.rs
index b61207858dc..ce4fa58ec89 100644
--- a/internal/core/window.rs
+++ b/internal/core/window.rs
@@ -746,7 +746,18 @@ impl WindowInner {
             && event.text.starts_with(key_codes::Escape)
         {
             // Closes top most popup on esc key pressed when policy is not no-auto-close
-            let close_on_escape = if let Some(popup) = self.active_popups.borrow().last() {
+
+            // Try to get the parent window in case `self` is the popup itself
+            let mut adapter = self.window_adapter();
+            let item_tree = self.component();
+            let mut a = None;
+            ItemTreeRc::borrow_pin(&item_tree).as_ref().window_adapter(false, &mut a);
+            if let Some(a) = a {
+                adapter = a;
+            }
+            let window = WindowInner::from_pub(adapter.window());
+
+            let close_on_escape = if let Some(popup) = window.active_popups.borrow().last() {
                 popup.close_policy == PopupClosePolicy::CloseOnClick
                     || popup.close_policy == PopupClosePolicy::CloseOnClickOutside
             } else {
@@ -754,7 +765,7 @@ impl WindowInner {
             };
 
             if close_on_escape {
-                self.close_top_popup();
+                window.close_top_popup();
             }
         }
         crate::properties::ChangeTracker::run_change_handlers();


Test patch: