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

Issue:
home automation not loading
### Bug Description

```
  0:        0x1015883d0 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h6e25c13836847e70
   1:        0x100d9e534 - core::fmt::write::h37cdb50ab8af3d55
   2:        0x1015866bc - std::io::Write::write_fmt::hd4c273f34c4c0a33
   3:        0x101588270 - std::sys::backtrace::BacktraceLock::print::h1df7364dde63dc75
   4:        0x101586f2c - std::panicking::default_hook::hf65fd28e95db7176
   5:        0x101575b90 - slint_lsp::main::{{closure}}::hb6abd129f8413cb8
   6:        0x1015864e4 - std::panicking::rust_panic_with_hook::hc9e2ec2a12b10e12
   7:        0x1015b1144 - std::panicking::begin_panic_handler::{{closure}}::h3b6449e2eb83bf4c
   8:        0x1015b10b4 - std::sys::backtrace::__rust_end_short_backtrace::h38d85099ddd107a3
   9:        0x1015b1b38 - _rust_begin_unwind
  10:        0x101b554b4 - core::panicking::panic_fmt::hd4003258f6ab7b29
  11:        0x100d9db84 - core::slice::index::slice_end_index_len_fail::do_panic::runtime::hf1d7ed14e20a290e
  12:        0x101b554c0 - core::slice::index::slice_end_index_len_fail::hb5d58104add3a660
  13:        0x100ec2bdc - i_slint_compiler::passes::inlining::inline_element::h473cd18bf2b009b3
  14:        0x100e67330 - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  15:        0x100ebff00 - i_slint_compiler::passes::inlining::inline::inline_components_recursively::h1af6f3e707b580f2
  16:        0x100e66d2c - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  17:        0x100e673c8 - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  18:        0x100e673c8 - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  19:        0x100e673c8 - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  20:        0x100ebff00 - i_slint_compiler::passes::inlining::inline::inline_components_recursively::h1af6f3e707b580f2
  21:        0x100e66d2c - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  22:        0x100e673c8 - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  23:        0x100e673c8 - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  24:        0x100e673c8 - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  25:        0x100e673c8 - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  26:        0x100e673c8 - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  27:        0x100e673c8 - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  28:        0x100e673c8 - i_slint_compiler::object_tree::recurse_elem_no_borrow::h6637e5c99d5f2eba
  29:        0x100ebff00 - i_slint_compiler::passes::inlining::inline::inline_components_recursively::h1af6f3e707b580f2
  30:        0x100ebf678 - i_slint_compiler::passes::inlining::inline::h166f4e078c2e7531
  31:        0x1014cdaa8 - slint_interpreter::dynamic_item_tree::load::{{closure}}::h4ab36e0d96ee5126
  32:        0x1014c2eb8 - slint_lsp::preview::reload_timer_function::{{closure}}::hdf88087afb9beed4
  33:        0x1014c0c38 - core::ops::function::FnOnce::call_once{{vtable.shim}}::he61f909c95a27544
  34:        0x100df0b74 - <i_slint_backend_winit::event_loop::ActiveEventLoopSetterDuringEventProcessing<Handler> as winit::application::ApplicationHandler<Event>>::user_event::h5a7c27b180fea811
  35:        0x100e10504 - winit::platform::pump_events::EventLoopExtPumpEvents::pump_app_events::{{closure}}::h2eaaa16de671ed30
  36:        0x100e100cc - winit::platform_impl::macos::event_loop::map_user_event::{{closure}}::h1b14d1e0999efd4b
  37:        0x10169625c - winit::platform_impl::macos::event_handler::EventHandler::handle_event::h7d77252f6501c48c
  38:        0x101695168 - winit::platform_impl::macos::observer::control_flow_end_handler::hf96d05ff68cd1bb4
  39:        0x188373be8 - <unknown>
  40:        0x188373ad4 - <unknown>
  41:        0x1883731a4 - <unknown>
  42:        0x188372734 - <unknown>
  43:        0x1938e1530 - <unknown>
  44:        0x1938e7348 - <unknown>
  45:        0x1938e7508 - <unknown>
  46:        0x18beea848 - <unknown>
  47:        0x18c850c24 - <unknown>
  48:        0x18bedd874 - <unknown>
  49:        0x100e1382c - <i_slint_backend_winit::Backend as i_slint_core::platform::Platform>::run_event_loop::hb2d2484701cceb35
  50:        0x101573938 - slint_lsp::main::h68f4de0bbb7a71fe
  51:        0x10154cbe0 - std::sys::backtrace::__rust_begin_short_backtrace::h360d274ecba90b8a
  52:        0x1015705cc - _main
[Info  - 8:40:30 AM] Connection to server got closed. Server will restart.
true
The Slint Language Server crashed. This is a bug. Please open an issue on https://github.com/slint-ui/slint/issues
[Error - 8:40:30 AM] Server process exited with signal SIGABRT.
```


### Reproducible Code (if applicable)

```slint

```

### Environment Details

- Slint Version:
- Platform/OS:
- Programming Language:
- Backend/Renderer:


### Product Impact

_No response_


Discussion / hints:
I can reproduce:
The panic message is `range end index 3 out of range for slice of length 1`
(can also be reproduced with the viewer)
Testcase:
```slint
component Hallo {
    inner := Rectangle {
        clip: true;
        @children
        Rectangle {}
    }
}

component World inherits Hallo {
    Rectangle {}
    Rectangle {}
    Rectangle {}
}

export component Demo {
    World { }
}
```

This was already broken in 1.9.2,  but the changes in inlining made it more apparent.

The problem is that the `clip` creates a new item, but the children should be the children of the original rectangle, not the new scope.

Fix patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 94c4708fba7..4ad81a2faa5 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -514,6 +514,9 @@ jobs:
                             --skip test_interpreter_models_assign_equal_model \
                             --skip example_carousel \
                             --skip example_fancy_demo \
+                            --skip example_dial \
+                            --skip example_fancy_switches \
+                            --skip example_sprite_sheet \
                             --skip test_interpreter_elements_path_fit \
                             --skip test_interpreter_layout_path \
                             --skip test_interpreter_7guis_booker \
diff --git a/internal/compiler/passes/inlining.rs b/internal/compiler/passes/inlining.rs
index 37978c368c5..896754dceac 100644
--- a/internal/compiler/passes/inlining.rs
+++ b/internal/compiler/passes/inlining.rs
@@ -131,14 +131,16 @@ fn inline_element(
             let children = std::mem::take(&mut elem_mut.children);
             let old_count = children.len();
             if let Some(insertion_element) = mapping.get(&element_key(insertion_element.clone())) {
-                if !Rc::ptr_eq(elem, insertion_element) {
-                    debug_assert!(std::rc::Weak::ptr_eq(
-                        &insertion_element.borrow().enclosing_component,
-                        &elem_mut.enclosing_component,
-                    ));
-                    insertion_element.borrow_mut().children.splice(index..index, children);
-                } else {
-                    new_children.splice(index..index, children);
+                if old_count > 0 {
+                    if !Rc::ptr_eq(elem, insertion_element) {
+                        debug_assert!(std::rc::Weak::ptr_eq(
+                            &insertion_element.borrow().enclosing_component,
+                            &elem_mut.enclosing_component,
+                        ));
+                        insertion_element.borrow_mut().children.splice(index..index, children);
+                    } else {
+                        new_children.splice(index..index, children);
+                    }
                 }
                 let mut cip = root_component.child_insertion_point.borrow_mut();
                 if let Some(cip) = cip.as_mut() {


Test patch:
diff --git a/tests/cases/children/children_in_clip.slint b/tests/cases/children/children_in_clip.slint
new file mode 100644
index 00000000000..a5bf3297b5a
--- /dev/null
+++ b/tests/cases/children/children_in_clip.slint
@@ -0,0 +1,23 @@
+// Copyright © SixtyFPS GmbH <info@slint.dev>
+// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
+
+// TestCase from #7724
+// compilation shouldn't panic
+
+component Hallo {
+    inner := Rectangle {
+        clip: true;
+        @children
+        Rectangle {}
+    }
+}
+
+component World inherits Hallo {
+    Rectangle {}
+    Rectangle {}
+    Rectangle {}
+}
+
+export component Demo {
+    World { }
+}
\ No newline at end of file
diff --git a/tests/cases/elements/flickable.slint b/tests/cases/elements/flickable.slint
index 97715026ea0..0d40cc615b6 100644
--- a/tests/cases/elements/flickable.slint
+++ b/tests/cases/elements/flickable.slint
@@ -148,6 +148,37 @@ assert_eq!(instance.get_double_clicked(), 0);
 assert_eq!(instance.get_offset_x(), 0.);
 assert_eq!(instance.get_offset_y(), 0.);
 
+instance.set_clicked(-1);
+// - Same but over a longer period (long press) so it should be pressed
+
+// Start a press
+instance.window().dispatch_event(WindowEvent::PointerPressed { position: LogicalPosition::new(165.0, 175.0), button: PointerEventButton::Left });
+assert!(!instance.get_inner_ta_pressed());
+assert!(instance.get_inner_ta_has_hover());
+assert_eq!(instance.get_clicked(), -1);
+// make a small move
+instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(166.0, 174.0) });
+assert!(!instance.get_inner_ta_pressed());
+assert!(instance.get_inner_ta_has_hover());
+slint_testing::mock_elapsed_time(30);
+instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(167.0, 175.0) });
+assert!(!instance.get_inner_ta_pressed());
+slint_testing::mock_elapsed_time(300);
+assert!(instance.get_inner_ta_pressed(), "now we should be marked as pressed");
+instance.window().dispatch_event(WindowEvent::PointerMoved { position: LogicalPosition::new(166.0, 175.0) });
+assert!(instance.get_inner_ta_pressed(), "still pressed");
+slint_testing::mock_elapsed_time(30);
+assert!(instance.get_inner_ta_pressed(), "still pressed");
+// and release
+instance.window().dispatch_event(WindowEvent::PointerReleased { position: LogicalPosition::new(167.0, 174.0), button: PointerEventButton::Left });
+assert!(!instance.get_inner_ta_pressed());
+assert!(instance.get_inner_ta_has_hover());
+assert_eq!(instance.get_clicked(), 7_00014);
+assert_eq!(instance.get_double_clicked(), 7_00014);
+assert_eq!(instance.get_offset_x(), 0.);
+assert_eq!(instance.get_offset_y(), 0.);
+
+instance.set_double_clicked(0);
 instance.set_clicked(-1);
 
 // Start a press
diff --git a/tests/driver/interpreter/main.rs b/tests/driver/interpreter/main.rs
index f02725011d5..2b53890e3a0 100644
--- a/tests/driver/interpreter/main.rs
+++ b/tests/driver/interpreter/main.rs
@@ -40,6 +40,12 @@ test_example!(example_fancy_demo, "examples/fancy_demo/main.slint");
 test_example!(example_bash_sysinfo, "examples/bash/sysinfo.slint");
 test_example!(example_carousel, "examples/carousel/ui/carousel_demo.slint");
 test_example!(example_iot_dashboard, "examples/iot-dashboard/main.slint");
+test_example!(example_dial, "examples/dial/dial.slint");
+test_example!(example_sprite_sheet, "examples/sprite-sheet/demo.slint");
+test_example!(example_fancy_switches, "examples/fancy-switches/demo.slint");
+test_example!(example_home_automation, "demos/home-automation/ui/demo.slint");
+test_example!(example_energy_monitor, "demos/energy-monitor/ui/desktop_window.slint");
+test_example!(example_weather, "demos/weather-demo/ui/main.slint");
 
 fn main() {
     println!("Nothing to see here, please run me through cargo test :)");