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

Issue:
Issues with offscreen items inside `ListView`
### Bug Description

Strange things happen when there are too many items inside a `ListView` widget: keyboard navigation ignores the list view and a panic can be triggered.

## To reproduce

- Modify the `crud` example so that it has 5 items instead of 3
- Run the app
- Press the Tab key twice: the focus should go to the "Filter prefix" input and then the first item of the list view, ovserve that the list view is skipped and focus is placed on the "Name" input
- Now that the focus is on the "Name" input, use the mouse to scroll down the list view a bit and press Shift+Tab: this should put the focus on the first list view item but it panics instead:

```
thread 'main' panicked at d:\repos\slint\internal\core\model.rs:1252:18:
attempt to subtract with overflow
stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/9c707a8b769523bb6768bf58e74fa2c39cc24844/library\std\src\panicking.rs:681
   1: core::panicking::panic_fmt
             at /rustc/9c707a8b769523bb6768bf58e74fa2c39cc24844/library\core\src\panicking.rs:75
   2: core::panicking::panic_const::panic_const_sub_overflow
             at /rustc/9c707a8b769523bb6768bf58e74fa2c39cc24844/library\core\src\panicking.rs:178
   3: i_slint_core::model::Repeater<crud::slint_generatedMainWindow::InnerComponent_empty_13>::instance_at<crud::slint_generatedMainWindow::InnerComponent_empty_13>
             at .\internal\core\model.rs:1252
   4: crud::slint_generatedMainWindow::InnerStandardListView_root_10::subtree_component
             at .\examples\7guis\crud.rs:7
   5: crud::slint_generatedMainWindow::InnerMainWindow::subtree_component
             at .\examples\7guis\crud.rs:7
   6: crud::slint_generatedMainWindow::impl$33::get_subtree
             at .\examples\7guis\crud.rs:7
   7: crud::slint_generatedMainWindow::_::VT::get_subtree<crud::slint_generatedMainWindow::InnerMainWindow>
             at .\internal\core\item_tree.rs:44
   8: i_slint_core::item_tree::ItemTree_vtable_mod::ItemTreeTO::get_subtree
             at .\internal\core\item_tree.rs:44
   9: i_slint_core::item_tree::ItemRc::find_sibling
             at .\internal\core\item_tree.rs:553
  10: i_slint_core::item_tree::ItemRc::previous_sibling
             at .\internal\core\item_tree.rs:586
  11: i_slint_core::item_tree::impl$2::previous_focus_item::closure$1
             at .\internal\core\item_tree.rs:699
  12: i_slint_core::item_tree::ItemRc::move_focus
             at .\internal\core\item_tree.rs:633
  13: i_slint_core::item_tree::ItemRc::previous_focus_item
             at .\internal\core\item_tree.rs:695
  14: i_slint_core::window::previous_focus_item
             at .\internal\core\window.rs:41
  15: core::ops::function::Fn::call<i_slint_core::item_tree::ItemRc (*)(i_slint_core::item_tree::ItemRc),tuple$<i_slint_core::item_tree::ItemRc> >
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:79
  16: i_slint_core::window::WindowInner::move_focus<i_slint_core::item_tree::ItemRc (*)(i_slint_core::item_tree::ItemRc)>
             at .\internal\core\window.rs:856
  17: i_slint_core::window::WindowInner::focus_previous_item
             at .\internal\core\window.rs:893
  18: i_slint_core::window::WindowInner::process_key_input
             at .\internal\core\window.rs:744
  19: i_slint_core::api::Window::try_dispatch_event
             at .\internal\core\api.rs:607
  20: i_slint_backend_winit::event_loop::impl$6::window_event
             at .\internal\backends\winit\event_loop.rs:383
  21: winit::application::impl$0::window_event<i_slint_backend_winit::event_loop::EventLoopState,i_slint_backend_winit::SlintUserEvent>
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\application.rs:250
  22: i_slint_backend_winit::event_loop::impl$7::window_event::closure$0<i_slint_backend_winit::SlintUserEvent,ref_mut$<i_slint_backend_winit::event_loop::EventLoopState> >
             at .\internal\backends\winit\event_loop.rs:635
  23: i_slint_backend_winit::event_loop::CURRENT_WINDOW_TARGET::set<i_slint_backend_winit::event_loop::impl$7::window_event::closure_env$0<i_slint_backend_winit::SlintUserEvent,ref_mut$<i_slint_backend_winit::event_loop::EventLoopState> >,tuple$<> >
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\scoped-tls-hkt-0.1.5\src\lib.rs:258
  24: i_slint_backend_winit::event_loop::impl$7::window_event<i_slint_backend_winit::SlintUserEvent,ref_mut$<i_slint_backend_winit::event_loop::EventLoopState> >
             at .\internal\backends\winit\event_loop.rs:634
  25: winit::event_loop::dispatch_event_for_app
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\event_loop.rs:642
  26: winit::platform::run_on_demand::EventLoopExtRunOnDemand::run_app_on_demand::closure$0<winit::event_loop::EventLoop<i_slint_backend_winit::SlintUserEvent>,i_slint_backend_winit::event_loop::ActiveEventLoopSetterDuringEventProcessing<ref_mut$<i_slint_backend
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform\run_on_demand.rs:76
  27: winit::platform_impl::windows::event_loop::impl$3::run_on_demand::closure$0<i_slint_backend_winit::SlintUserEvent,winit::platform::run_on_demand::EventLoopExtRunOnDemand::run_app_on_demand::closure_env$0<winit::event_loop::EventLoop<i_slint_backend_winit::
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform_impl\windows\event_loop.rs:264
  28: alloc::boxed::impl$29::call_mut<tuple$<enum2$<winit::event::Event<winit::platform_impl::windows::event_loop::UserEventPlaceholder> > >,dyn$<core::ops::function::FnMut<tuple$<enum2$<winit::event::Event<winit::platform_impl::windows::event_loop::UserEventPla
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\alloc\src\boxed.rs:1977
  29: winit::platform_impl::windows::event_loop::runner::impl$3::call_event_handler::closure$0<winit::platform_impl::windows::event_loop::UserEventPlaceholder>
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform_impl\windows\event_loop\runner.rs:236
  30: core::panic::unwind_safe::impl$25::call_once<tuple$<>,winit::platform_impl::windows::event_loop::runner::impl$3::call_event_handler::closure_env$0<winit::platform_impl::windows::event_loop::UserEventPlaceholder> >
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\panic\unwind_safe.rs:272
  31: std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::windows::event_loop::runner::impl$3::call_event_handler::closure_env$0<winit::platform_impl::windows::event_loop::UserEventPlaceholder> >,tuple$<> >
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:573
  32: std::panicking::try
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:536
  33: std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::windows::event_loop::runner::impl$3::call_event_handler::closure_env$0<winit::platform_impl::windows::event_loop::UserEventPlaceholder> >,tuple$<> >
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:358
  34: winit::platform_impl::windows::event_loop::runner::EventLoopRunner<winit::platform_impl::windows::event_loop::UserEventPlaceholder>::catch_unwind<winit::platform_impl::windows::event_loop::UserEventPlaceholder,tuple$<>,winit::platform_impl::windows::event_
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform_impl\windows\event_loop\runner.rs:173
  35: winit::platform_impl::windows::event_loop::runner::EventLoopRunner<winit::platform_impl::windows::event_loop::UserEventPlaceholder>::call_event_handler<winit::platform_impl::windows::event_loop::UserEventPlaceholder>
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform_impl\windows\event_loop\runner.rs:230
  36: winit::platform_impl::windows::event_loop::runner::EventLoopRunner<winit::platform_impl::windows::event_loop::UserEventPlaceholder>::send_event<winit::platform_impl::windows::event_loop::UserEventPlaceholder>
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform_impl\windows\event_loop\runner.rs:220
  37: winit::platform_impl::windows::event_loop::WindowData::send_event
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform_impl\windows\event_loop.rs:129
  38: winit::platform_impl::windows::event_loop::public_window_callback_inner::closure$2
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform_impl\windows\event_loop.rs:1141
  39: core::ops::function::FnOnce::call_once<winit::platform_impl::windows::event_loop::public_window_callback_inner::closure_env$2,tuple$<> >
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:250
  40: core::panic::unwind_safe::impl$25::call_once<tuple$<>,winit::platform_impl::windows::event_loop::public_window_callback_inner::closure_env$2>
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\panic\unwind_safe.rs:272
  41: std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::windows::event_loop::public_window_callback_inner::closure_env$2>,tuple$<> >
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:573
  42: std::panicking::try
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:536
  43: std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<winit::platform_impl::windows::event_loop::public_window_callback_inner::closure_env$2>,tuple$<> >
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:358
  44: winit::platform_impl::windows::event_loop::runner::EventLoopRunner<winit::platform_impl::windows::event_loop::UserEventPlaceholder>::catch_unwind<winit::platform_impl::windows::event_loop::UserEventPlaceholder,tuple$<>,winit::platform_impl::windows::event_
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform_impl\windows\event_loop\runner.rs:173
  45: winit::platform_impl::windows::event_loop::public_window_callback_inner
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform_impl\windows\event_loop.rs:1151
  46: winit::platform_impl::windows::event_loop::public_window_callback
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform_impl\windows\event_loop.rs:1098
  47: CallWindowProcW
  48: CallWindowProcW
  49: wglSwapLayerBuffers
  50: CallWindowProcW
  51: CallWindowProcW
  52: windows::Win32::UI::WindowsAndMessaging::CallWindowProcW<windows::Win32::Foundation::HWND,windows::Win32::Foundation::WPARAM,windows::Win32::Foundation::LPARAM>
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\windows-0.58.0\src\Windows\Win32\UI\WindowsAndMessaging\mod.rs:118
  53: accesskit_windows::subclass::wnd_proc
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\accesskit_windows-0.24.1\src\subclass.rs:73
  54: CallWindowProcW
  55: IsWindowUnicode
  56: winit::platform_impl::windows::event_loop::EventLoop<i_slint_backend_winit::SlintUserEvent>::dispatch_peeked_messages<i_slint_backend_winit::SlintUserEvent>
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform_impl\windows\event_loop.rs:419
  57: winit::platform_impl::windows::event_loop::EventLoop<i_slint_backend_winit::SlintUserEvent>::run_on_demand<i_slint_backend_winit::SlintUserEvent,winit::platform::run_on_demand::EventLoopExtRunOnDemand::run_app_on_demand::closure_env$0<winit::event_loop::Ev
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform_impl\windows\event_loop.rs:277
  58: winit::platform::run_on_demand::impl$0::run_on_demand<i_slint_backend_winit::SlintUserEvent,winit::platform::run_on_demand::EventLoopExtRunOnDemand::run_app_on_demand::closure_env$0<winit::event_loop::EventLoop<i_slint_backend_winit::SlintUserEvent>,i_slin
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform\run_on_demand.rs:89
  59: winit::platform::run_on_demand::EventLoopExtRunOnDemand::run_app_on_demand<winit::event_loop::EventLoop<i_slint_backend_winit::SlintUserEvent>,i_slint_backend_winit::event_loop::ActiveEventLoopSetterDuringEventProcessing<ref_mut$<i_slint_backend_winit::eve
             at C:\Users\arnol\.cargo\registry\src\index.crates.io-6f17d22bba15001f\winit-0.30.8\src\platform\run_on_demand.rs:75
  60: i_slint_backend_winit::event_loop::EventLoopState::run
             at .\internal\backends\winit\event_loop.rs:713
  61: i_slint_backend_winit::impl$2::run_event_loop
             at .\internal\backends\winit\lib.rs:461
  62: slint::run_event_loop::closure$0
             at .\api\rs\slint\lib.rs:246
  63: i_slint_backend_selector::with_platform::closure$0<tuple$<>,slint::run_event_loop::closure_env$0>
             at .\internal\backends\selector\lib.rs:141
  64: i_slint_core::context::with_global_context::closure$0<enum2$<core::result::Result<tuple$<>,enum2$<i_slint_core::api::PlatformError> > >,i_slint_backend_selector::with_global_context::closure_env$0<enum2$<core::result::Result<tuple$<>,enum2$<i_slint_core::a
             at .\internal\core\context.rs:103
  65: std::thread::local::LocalKey<once_cell::unsync::OnceCell<i_slint_core::context::SlintContext> >::try_with<once_cell::unsync::OnceCell<i_slint_core::context::SlintContext>,i_slint_core::context::with_global_context::closure_env$0<enum2$<core::result::Result
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\local.rs:308
  66: std::thread::local::LocalKey<once_cell::unsync::OnceCell<i_slint_core::context::SlintContext> >::with<once_cell::unsync::OnceCell<i_slint_core::context::SlintContext>,i_slint_core::context::with_global_context::closure_env$0<enum2$<core::result::Result<tup
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\local.rs:272
  67: i_slint_core::context::with_global_context<enum2$<core::result::Result<tuple$<>,enum2$<i_slint_core::api::PlatformError> > >,i_slint_backend_selector::with_global_context::closure_env$0<enum2$<core::result::Result<tuple$<>,enum2$<i_slint_core::api::Platfor
             at .\internal\core\context.rs:102
  68: i_slint_backend_selector::with_global_context<enum2$<core::result::Result<tuple$<>,enum2$<i_slint_core::api::PlatformError> > >,i_slint_backend_selector::with_platform::closure_env$0<tuple$<>,slint::run_event_loop::closure_env$0> >
             at .\internal\backends\selector\lib.rs:148
  69: i_slint_backend_selector::with_platform<tuple$<>,slint::run_event_loop::closure_env$0>
             at .\internal\backends\selector\lib.rs:141
  70: slint::run_event_loop
             at .\api\rs\slint\lib.rs:246
  71: crud::slint_generatedMainWindow::impl$36::run
             at .\examples\7guis\crud.rs:7
  72: crud::main
             at .\examples\7guis\crud.rs:89
  73: core::ops::function::FnOnce::call_once<void (*)(),tuple$<> >
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:250
  74: core::hint::black_box
             at C:\Users\arnol\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\hint.rs:389
```

Interestingly, the panic only happens when walking back the focus chain. If you scroll down the list view and use the Tab key to reach it, then it will just be skipped.

As far as I can tell, if you resize the window so that the list view is big enough to display all items, the bug seem to never show up.

### Reproducible Code (if applicable)

```slint
diff --git a/examples/7guis/crud.rs b/examples/7guis/crud.rs
index 6fef8b4b8..04d792ea6 100644
--- a/examples/7guis/crud.rs
+++ b/examples/7guis/crud.rs
@@ -21,6 +21,8 @@ pub fn main() {
         Name { first: "Hans".to_string(), last: "Emil".to_string() },
         Name { first: "Max".to_string(), last: "Mustermann".to_string() },
         Name { first: "Roman".to_string(), last: "Tisch".to_string() },
+        Name { first: "Simon".to_string(), last: "Hausmann".to_string() },
+        Name { first: "Olivier".to_string(), last: "Goffart".to_string() },
     ]));

     let filtered_model = Rc::new(
```


### Environment Details

- Slint Version: commit 57f42c087001628ba17fd70008d93fcc439c1dc6 (the bug was already there when I worked on #6148)
- Platform/OS: Windows 11
- Programming Language: Rust
- Backend/Renderer: winit


### Product Impact

_No response_


Discussion / hints:
I can reproduce this.

```rust
    pub fn instance_at(&self, index: usize) -> Option<ItemTreeRc<C>> {
        let inner = self.0.inner.borrow();
        inner
            .instances
            .get(index - inner.offset) /// <-- `attempt to subtract with overflow`
            .map(|c| c.1.clone().expect("That was updated before!"))
    }
```
I guess the fix would be to do ` .get(index.checked_sub(inner.offset)?)`
The good news is that this bug shouldn't happen in release mode


Fix patch:
diff --git a/internal/core/item_tree.rs b/internal/core/item_tree.rs
index c0c2fce047a..b770f898de9 100644
--- a/internal/core/item_tree.rs
+++ b/internal/core/item_tree.rs
@@ -330,8 +330,13 @@ impl ItemRc {
     /// false for `Clip` elements with the `clip` property evaluating to true.
     pub fn is_visible(&self) -> bool {
         let (clip, geometry) = self.absolute_clip_rect_and_geometry();
-        let intersection = geometry.intersection(&clip).unwrap_or_default();
-        !intersection.is_empty() || (geometry.is_empty() && clip.contains(geometry.center()))
+        let clip = clip.to_box2d();
+        let geometry = geometry.to_box2d();
+        !clip.is_empty()
+            && clip.max.x >= geometry.min.x
+            && clip.max.y >= geometry.min.y
+            && clip.min.x <= geometry.max.x
+            && clip.min.y <= geometry.max.y
     }
 
     /// Returns the clip rect that applies to this item (in window coordinates) as well as the
diff --git a/internal/core/model.rs b/internal/core/model.rs
index ab655791aee..5efb240521d 100644
--- a/internal/core/model.rs
+++ b/internal/core/model.rs
@@ -1251,7 +1251,7 @@ impl<C: RepeatedItemTree + 'static> Repeater<C> {
         let inner = self.0.inner.borrow();
         inner
             .instances
-            .get(index - inner.offset)
+            .get(index.checked_sub(inner.offset)?)
             .map(|c| c.1.clone().expect("That was updated before!"))
     }
 


Test patch:
diff --git a/tests/cases/focus/listview-hidden.slint b/tests/cases/focus/listview-hidden.slint
new file mode 100644
index 00000000000..e5f6f3b2034
--- /dev/null
+++ b/tests/cases/focus/listview-hidden.slint
@@ -0,0 +1,93 @@
+// 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
+
+// Issue #7341
+// Check that changing focus while the current item is hidden does not panic
+
+import { LineEdit, StandardListView } from "std-widgets.slint";
+export component TestCase inherits Window {
+    width: 300px;
+    height: 300px;
+
+    forward-focus: l1;
+    out property l1-has-focus <=> l1.has-focus;
+    out property l2-has-focus <=> l2.has-focus;
+    out property lv-has-focus <=> lv.has-focus;
+    out property current-item <=> lv.current-item;
+    out property viewport-y <=> lv.viewport-y;
+    out property <length> item-height: lv.viewport-height / lv.model.length;
+
+
+    VerticalLayout {
+        l1 := LineEdit {}
+        lv := StandardListView {
+            model: [ { text: "a"}, { text: "b"}, { text: "c"}, { text: "d"}, { text: "e"}, { text: "f"}, { text: "g"}, { text: "h"}, { text: "i"}, { text: "j"}, { text: "k"}, { text: "l"}, { text: "m"}, { text: "n"}, { text: "o"}, { text: "p"}, { text: "q"}, { text: "r"}, { text: "s"}, { text: "t"}, { text: "u"}, { text: "v"}, { text: "w"}, { text: "x"}, { text: "y"}, { text: "z"} ];
+           current-item-changed(current-item) => {
+               debug("current-item-changed", current-item);
+           }
+        }
+        l2 := LineEdit {}
+    }
+
+}
+
+/*
+```rust
+use slint::{LogicalPosition, SharedString};
+use slint::platform::{Key, WindowEvent};
+let instance = TestCase::new().unwrap();
+assert!(instance.get_l1_has_focus());
+assert!(!instance.get_lv_has_focus());
+assert!(!instance.get_l2_has_focus());
+assert_eq!(instance.get_current_item(), -1);
+slint_testing::send_keyboard_string_sequence(&instance, "\t");
+assert!(!instance.get_l1_has_focus());
+assert!(instance.get_lv_has_focus());
+assert!(!instance.get_l2_has_focus());
+assert_eq!(instance.get_current_item(), 0);
+slint_testing::send_keyboard_string_sequence(&instance, &SharedString::from(Key::DownArrow));
+assert_eq!(instance.get_current_item(), 1);
+
+slint_testing::send_keyboard_string_sequence(&instance, "\t");
+assert!(!instance.get_l1_has_focus());
+assert!(!instance.get_lv_has_focus());
+assert!(instance.get_l2_has_focus());
+assert_eq!(instance.get_current_item(), 1);
+
+let delta_y = -600.0;
+
+assert_eq!(instance.get_viewport_y(), 0.0);
+instance.window().dispatch_event(WindowEvent::PointerScrolled { position: LogicalPosition::new(150.0, 150.0), delta_x: -0.0, delta_y });
+assert_eq!(instance.get_viewport_y(), delta_y);
+assert_eq!(instance.get_current_item(), 1);
+slint_testing::send_keyboard_string_sequence(&instance, &SharedString::from(Key::Backtab));
+assert!(!instance.get_l1_has_focus());
+assert!(instance.get_lv_has_focus());
+assert!(!instance.get_l2_has_focus());
+assert_eq!(instance.get_current_item(), 1);
+slint_testing::send_keyboard_string_sequence(&instance, &SharedString::from(Key::Backtab));
+assert!(instance.get_l1_has_focus());
+assert!(!instance.get_lv_has_focus());
+assert!(!instance.get_l2_has_focus());
+assert_eq!(instance.get_current_item(), 1);
+slint_testing::send_keyboard_string_sequence(&instance, "\t");
+assert!(!instance.get_l1_has_focus());
+assert!(instance.get_lv_has_focus());
+assert!(!instance.get_l2_has_focus());
+assert_eq!(instance.get_current_item(), 1);
+
+slint_testing::send_keyboard_string_sequence(&instance, &SharedString::from(Key::UpArrow));
+let mut x = (-delta_y / instance.get_item_height()).round() as i32 - 1;
+assert_eq!(instance.get_current_item(), x);
+while x > 0 {
+    slint_testing::send_keyboard_string_sequence(&instance, &SharedString::from(Key::UpArrow));
+    x -= 1;
+    assert_eq!(instance.get_current_item(), x);
+}
+slint_testing::send_keyboard_string_sequence(&instance, &SharedString::from(Key::UpArrow));
+assert_eq!(instance.get_current_item(), 0);
+```
+
+
+
+*/