The presets menu at the foot of the tool rail is a PopupWindow, and showing a popup takes focus off the develop view until it closes. The menu held nothing focusable, so Android's Back gesture, pressed to dismiss it, found no focus item, went unanswered, and the platform closed the application. Slint closes a popup on Escape by itself but not on Back. The menu now holds a key scope, as the film list does, that closes it on Back or Escape. The next Back leaves develop for the grid.
70 lines
2.4 KiB
Rust
70 lines
2.4 KiB
Rust
// TRACES: FR-UI-5
|
|
//! Back closes the presets menu, and the next Back returns to the grid.
|
|
//!
|
|
//! The menu at the foot of the tool rail is a `PopupWindow`, and showing a
|
|
//! popup takes focus off the develop view until it closes. The menu had
|
|
//! nothing focusable of its own, so a Back pressed while it was up had no
|
|
//! focus item to bubble from, went unanswered, and on Android an unanswered
|
|
//! Back is the platform's: it closed the application from develop. Dismissing
|
|
//! a menu with the back gesture is the ordinary thing to do, which is why this
|
|
//! was seen often.
|
|
//!
|
|
//! Runs on Slint's testing backend, as `film_list_reaches_every_stock` does.
|
|
#![cfg(debug_assertions)]
|
|
|
|
use std::cell::Cell;
|
|
use std::rc::Rc;
|
|
|
|
use dr_ui::{AppWindow, Develop};
|
|
use i_slint_backend_testing::{init_no_event_loop, ElementHandle};
|
|
use slint::platform::{Key, PointerEventButton, WindowEvent};
|
|
use slint::{ComponentHandle, SharedString};
|
|
|
|
const MANAGE: &str = "Save or manage…";
|
|
|
|
fn key(app: &AppWindow, k: Key) {
|
|
let text: SharedString = k.into();
|
|
app.window()
|
|
.dispatch_event(WindowEvent::KeyPressed { text: text.clone() });
|
|
app.window()
|
|
.dispatch_event(WindowEvent::KeyReleased { text });
|
|
}
|
|
|
|
fn menu_open(app: &AppWindow) -> bool {
|
|
ElementHandle::find_by_accessible_label(app, MANAGE)
|
|
.next()
|
|
.is_some()
|
|
}
|
|
|
|
#[test]
|
|
fn back_closes_the_presets_menu_then_leaves_develop() {
|
|
init_no_event_loop();
|
|
let app = AppWindow::new().expect("the window builds on the testing backend");
|
|
app.window().set_size(slint::LogicalSize::new(1600., 1200.));
|
|
app.global::<Develop>().set_enabled(true);
|
|
// The rail offers presets only with a photograph to apply them to.
|
|
app.set_total(3);
|
|
let asked = Rc::new(Cell::new(0));
|
|
app.on_back_requested({
|
|
let asked = asked.clone();
|
|
move || {
|
|
asked.set(asked.get() + 1);
|
|
true
|
|
}
|
|
});
|
|
app.show().unwrap();
|
|
|
|
ElementHandle::find_by_accessible_label(&app, "Presets")
|
|
.next()
|
|
.expect("the tool rail's presets entry is on screen")
|
|
.mock_single_click(PointerEventButton::Left);
|
|
assert!(menu_open(&app), "clicking Presets opens the menu");
|
|
|
|
key(&app, Key::Back);
|
|
assert!(!menu_open(&app), "Back closes the menu");
|
|
assert_eq!(asked.get(), 0, "closing the menu is the whole step");
|
|
|
|
key(&app, Key::Back);
|
|
assert_eq!(asked.get(), 1, "the next Back reaches the shell");
|
|
}
|