mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 18:58:36 +00:00
Introduce Window::try_dispatch_event (#7313)
That is the same as Window::dispatch_event, but it reports an error instead of panicking
This commit is contained in:
parent
19bfe926d2
commit
cfbcf0b1d7
15 changed files with 137 additions and 102 deletions
|
@ -222,7 +222,7 @@ loop {
|
|||
if let Some(event) = check_for_touch_event(/*...*/) {
|
||||
// convert the event from the driver into a `slint::platform::WindowEvent`
|
||||
// and pass it to the window.
|
||||
window.dispatch_event(event);
|
||||
window.try_dispatch_event(event).unwrap();
|
||||
}
|
||||
|
||||
// ... maybe some more application logic ...
|
||||
|
|
|
@ -154,11 +154,11 @@ impl slint::platform::Platform for EspBackend {
|
|||
let is_pointer_release_event =
|
||||
matches!(event, WindowEvent::PointerReleased { .. });
|
||||
|
||||
window.dispatch_event(event);
|
||||
window.try_dispatch_event(event)?;
|
||||
|
||||
// removes hover state on widgets
|
||||
if is_pointer_release_event {
|
||||
window.dispatch_event(WindowEvent::PointerExited);
|
||||
window.try_dispatch_event(WindowEvent::PointerExited)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -283,11 +283,11 @@ impl<
|
|||
let is_pointer_release_event =
|
||||
matches!(event, WindowEvent::PointerReleased { .. });
|
||||
|
||||
window.dispatch_event(event);
|
||||
window.try_dispatch_event(event)?;
|
||||
|
||||
// removes hover state on widgets
|
||||
if is_pointer_release_event {
|
||||
window.dispatch_event(WindowEvent::PointerExited);
|
||||
window.try_dispatch_event(WindowEvent::PointerExited)?;
|
||||
}
|
||||
// Don't go to sleep after a touch event that forces a redraw
|
||||
continue;
|
||||
|
|
|
@ -281,11 +281,11 @@ impl<
|
|||
let is_pointer_release_event =
|
||||
matches!(event, WindowEvent::PointerReleased { .. });
|
||||
|
||||
window.dispatch_event(event);
|
||||
window.try_dispatch_event(event)?;
|
||||
|
||||
// removes hover state on widgets
|
||||
if is_pointer_release_event {
|
||||
window.dispatch_event(WindowEvent::PointerExited);
|
||||
window.try_dispatch_event(WindowEvent::PointerExited)?;
|
||||
}
|
||||
// Don't go to sleep after a touch event that forces a redraw
|
||||
continue;
|
||||
|
|
|
@ -373,11 +373,11 @@ impl slint::platform::Platform for StmBackend {
|
|||
let is_pointer_release_event =
|
||||
matches!(event, slint::platform::WindowEvent::PointerReleased { .. });
|
||||
|
||||
window.dispatch_event(event);
|
||||
window.try_dispatch_event(event)?;
|
||||
|
||||
// removes hover state on widgets
|
||||
if is_pointer_release_event {
|
||||
window.dispatch_event(slint::platform::WindowEvent::PointerExited);
|
||||
window.try_dispatch_event(slint::platform::WindowEvent::PointerExited)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -308,8 +308,8 @@ impl slint::platform::Platform for Platform {
|
|||
while let Some(key) = get_key_press() {
|
||||
// EFI does not distinguish between pressed and released events.
|
||||
let text = SharedString::from(key);
|
||||
self.window.dispatch_event(WindowEvent::KeyPressed { text: text.clone() });
|
||||
self.window.dispatch_event(WindowEvent::KeyReleased { text });
|
||||
self.window.try_dispatch_event(WindowEvent::KeyPressed { text: text.clone() })?;
|
||||
self.window.try_dispatch_event(WindowEvent::KeyReleased { text })?;
|
||||
}
|
||||
// mouse handle until no input
|
||||
while let Some(mut mouse) =
|
||||
|
@ -341,10 +341,11 @@ impl slint::platform::Platform for Platform {
|
|||
mouse.relative_movement[1] = (info.resolution().1) as i32;
|
||||
}
|
||||
|
||||
self.window.dispatch_event(WindowEvent::PointerMoved { position });
|
||||
self.window.dispatch_event(WindowEvent::PointerExited {});
|
||||
self.window.dispatch_event(WindowEvent::PointerPressed { position, button });
|
||||
self.window.dispatch_event(WindowEvent::PointerReleased { position, button });
|
||||
self.window.try_dispatch_event(WindowEvent::PointerMoved { position })?;
|
||||
self.window.try_dispatch_event(WindowEvent::PointerExited {})?;
|
||||
self.window.try_dispatch_event(WindowEvent::PointerPressed { position, button })?;
|
||||
self.window
|
||||
.try_dispatch_event(WindowEvent::PointerReleased { position, button })?;
|
||||
is_mouse_move = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ impl WindowAdapter for AndroidWindowAdapter {
|
|||
fn update_window_properties(&self, properties: WindowProperties<'_>) {
|
||||
let f = properties.is_fullscreen();
|
||||
if self.fullscreen.replace(f) != f {
|
||||
self.resize();
|
||||
self.resize().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,9 +202,7 @@ impl AndroidWindowAdapter {
|
|||
}
|
||||
}
|
||||
match event {
|
||||
PollEvent::Main(MainEvent::InputAvailable) => {
|
||||
self.process_inputs().map_err(|e| PlatformError::Other(e.to_string()))?
|
||||
}
|
||||
PollEvent::Main(MainEvent::InputAvailable) => self.process_inputs()?,
|
||||
PollEvent::Main(MainEvent::InitWindow { .. }) => {
|
||||
if let Some(w) = self.app.native_window() {
|
||||
let size = PhysicalSize { width: w.width() as u32, height: w.height() as u32 };
|
||||
|
@ -214,7 +212,7 @@ impl AndroidWindowAdapter {
|
|||
|
||||
if (scale_factor - self.window.scale_factor()).abs() > f32::EPSILON {
|
||||
self.window
|
||||
.dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor });
|
||||
.try_dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor })?;
|
||||
}
|
||||
|
||||
self.renderer.set_window_handle(
|
||||
|
@ -223,7 +221,7 @@ impl AndroidWindowAdapter {
|
|||
size,
|
||||
None,
|
||||
)?;
|
||||
self.resize();
|
||||
self.resize()?;
|
||||
|
||||
// Fixes a problem for old Android versions: the soft input always prompt out on startup.
|
||||
#[cfg(feature = "native-activity")]
|
||||
|
@ -234,26 +232,27 @@ impl AndroidWindowAdapter {
|
|||
}
|
||||
PollEvent::Main(
|
||||
MainEvent::WindowResized { .. } | MainEvent::ContentRectChanged { .. },
|
||||
) => self.resize(),
|
||||
) => self.resize()?,
|
||||
PollEvent::Main(MainEvent::RedrawNeeded { .. }) => {
|
||||
self.pending_redraw.set(false);
|
||||
self.do_render()?;
|
||||
}
|
||||
PollEvent::Main(MainEvent::GainedFocus) => {
|
||||
self.window.dispatch_event(WindowEvent::WindowActiveChanged(true));
|
||||
self.window.try_dispatch_event(WindowEvent::WindowActiveChanged(true))?;
|
||||
}
|
||||
PollEvent::Main(MainEvent::LostFocus) => {
|
||||
self.window.dispatch_event(WindowEvent::WindowActiveChanged(true));
|
||||
self.window.try_dispatch_event(WindowEvent::WindowActiveChanged(true))?;
|
||||
}
|
||||
PollEvent::Main(MainEvent::ConfigChanged { .. }) => {
|
||||
let scale_factor =
|
||||
self.app.config().density().map(|dpi| dpi as f32 / 160.0).unwrap_or(1.0);
|
||||
|
||||
if (scale_factor - self.window.scale_factor()).abs() > f32::EPSILON {
|
||||
self.window.dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor });
|
||||
self.window.dispatch_event(WindowEvent::Resized {
|
||||
self.window
|
||||
.try_dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor })?;
|
||||
self.window.try_dispatch_event(WindowEvent::Resized {
|
||||
size: self.size().to_logical(scale_factor),
|
||||
});
|
||||
})?;
|
||||
}
|
||||
}
|
||||
PollEvent::Main(MainEvent::Destroy) => {
|
||||
|
@ -264,21 +263,22 @@ impl AndroidWindowAdapter {
|
|||
Ok(ControlFlow::Continue(()))
|
||||
}
|
||||
|
||||
fn process_inputs(&self) -> Result<(), android_activity::error::AppError> {
|
||||
let mut iter = self.app.input_events_iter()?;
|
||||
|
||||
fn process_inputs(&self) -> Result<(), PlatformError> {
|
||||
let mut iter =
|
||||
self.app.input_events_iter().map_err(|e| PlatformError::Other(e.to_string()))?;
|
||||
loop {
|
||||
let mut result = Ok(());
|
||||
let read_input = iter.next(|event| match event {
|
||||
InputEvent::KeyEvent(key_event) => match map_key_event(key_event) {
|
||||
Some(ev) => {
|
||||
self.window.dispatch_event(ev);
|
||||
result = self.window.try_dispatch_event(ev);
|
||||
InputStatus::Handled
|
||||
}
|
||||
None => InputStatus::Unhandled,
|
||||
},
|
||||
InputEvent::MotionEvent(motion_event) => match motion_event.action() {
|
||||
MotionAction::ButtonPress => {
|
||||
self.window.dispatch_event(WindowEvent::PointerPressed {
|
||||
result = self.window.try_dispatch_event(WindowEvent::PointerPressed {
|
||||
position: position_for_event(motion_event, self.offset.get())
|
||||
.to_logical(self.window.scale_factor()),
|
||||
button: button_for_event(motion_event, &self.last_pressed_state),
|
||||
|
@ -298,14 +298,14 @@ impl AndroidWindowAdapter {
|
|||
long_press_timeout,
|
||||
);
|
||||
self.long_press.replace(Some(LongPressDetection { position, _timer }));
|
||||
self.window.dispatch_event(WindowEvent::PointerPressed {
|
||||
result = self.window.try_dispatch_event(WindowEvent::PointerPressed {
|
||||
position,
|
||||
button: PointerEventButton::Left,
|
||||
});
|
||||
InputStatus::Handled
|
||||
}
|
||||
MotionAction::ButtonRelease => {
|
||||
self.window.dispatch_event(WindowEvent::PointerReleased {
|
||||
result = self.window.try_dispatch_event(WindowEvent::PointerReleased {
|
||||
position: position_for_event(motion_event, self.offset.get())
|
||||
.to_logical(self.window.scale_factor()),
|
||||
button: button_for_event(motion_event, &self.last_pressed_state),
|
||||
|
@ -314,13 +314,18 @@ impl AndroidWindowAdapter {
|
|||
}
|
||||
MotionAction::Up => {
|
||||
self.long_press.take();
|
||||
self.window.dispatch_event(WindowEvent::PointerReleased {
|
||||
position: position_for_event(motion_event, self.offset.get())
|
||||
.to_logical(self.window.scale_factor()),
|
||||
button: PointerEventButton::Left,
|
||||
});
|
||||
// Also send exit to avoid remaining hover state
|
||||
self.window.dispatch_event(WindowEvent::PointerExited);
|
||||
result = self
|
||||
.window
|
||||
.try_dispatch_event(WindowEvent::PointerReleased {
|
||||
position: position_for_event(motion_event, self.offset.get())
|
||||
.to_logical(self.window.scale_factor()),
|
||||
button: PointerEventButton::Left,
|
||||
})
|
||||
.and_then(|()| {
|
||||
// Also send exit to avoid remaining hover state
|
||||
self.window.try_dispatch_event(WindowEvent::PointerExited)
|
||||
});
|
||||
|
||||
InputStatus::Handled
|
||||
}
|
||||
MotionAction::Move | MotionAction::HoverMove => {
|
||||
|
@ -333,12 +338,13 @@ impl AndroidWindowAdapter {
|
|||
}) {
|
||||
*lp = None;
|
||||
}
|
||||
self.window.dispatch_event(WindowEvent::PointerMoved { position });
|
||||
result =
|
||||
self.window.try_dispatch_event(WindowEvent::PointerMoved { position });
|
||||
InputStatus::Handled
|
||||
}
|
||||
MotionAction::Cancel | MotionAction::Outside => {
|
||||
self.long_press.take();
|
||||
self.window.dispatch_event(WindowEvent::PointerExited);
|
||||
result = self.window.try_dispatch_event(WindowEvent::PointerExited);
|
||||
InputStatus::Handled
|
||||
}
|
||||
MotionAction::Scroll => todo!(),
|
||||
|
@ -382,14 +388,16 @@ impl AndroidWindowAdapter {
|
|||
_ => InputStatus::Unhandled,
|
||||
});
|
||||
|
||||
result?;
|
||||
|
||||
if !read_input {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resize(&self) {
|
||||
let Some(win) = self.app.native_window() else { return };
|
||||
fn resize(&self) -> Result<(), PlatformError> {
|
||||
let Some(win) = self.app.native_window() else { return Ok(()) };
|
||||
let (offset, size) = if self.fullscreen.get() {
|
||||
(
|
||||
Default::default(),
|
||||
|
@ -399,10 +407,11 @@ impl AndroidWindowAdapter {
|
|||
self.java_helper.get_view_rect().unwrap_or_else(|e| print_jni_error(&self.app, e))
|
||||
};
|
||||
|
||||
self.window.dispatch_event(WindowEvent::Resized {
|
||||
self.window.try_dispatch_event(WindowEvent::Resized {
|
||||
size: size.to_logical(self.window.scale_factor()),
|
||||
});
|
||||
})?;
|
||||
self.offset.set(offset);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn do_render(&self) -> Result<(), PlatformError> {
|
||||
|
|
|
@ -193,7 +193,7 @@ impl<'a> calloop::EventSource for LibInputHandler<'a> {
|
|||
.clamp(0., screen_size.height);
|
||||
self.mouse_pos.set(Some(mouse_pos));
|
||||
let event = WindowEvent::PointerMoved { position: mouse_pos };
|
||||
window.dispatch_event(event);
|
||||
window.try_dispatch_event(event).map_err(Self::Error::other)?;
|
||||
}
|
||||
input::event::PointerEvent::MotionAbsolute(abs_motion_event) => {
|
||||
let mouse_pos = LogicalPosition {
|
||||
|
@ -205,7 +205,7 @@ impl<'a> calloop::EventSource for LibInputHandler<'a> {
|
|||
};
|
||||
self.mouse_pos.set(Some(mouse_pos));
|
||||
let event = WindowEvent::PointerMoved { position: mouse_pos };
|
||||
window.dispatch_event(event);
|
||||
window.try_dispatch_event(event).map_err(Self::Error::other)?;
|
||||
}
|
||||
input::event::PointerEvent::Button(button_event) => {
|
||||
// https://github.com/torvalds/linux/blob/0dd2a6fb1e34d6dcb96806bc6b111388ad324722/include/uapi/linux/input-event-codes.h#L355
|
||||
|
@ -226,7 +226,7 @@ impl<'a> calloop::EventSource for LibInputHandler<'a> {
|
|||
WindowEvent::PointerReleased { position: mouse_pos, button }
|
||||
}
|
||||
};
|
||||
window.dispatch_event(event);
|
||||
window.try_dispatch_event(event).map_err(Self::Error::other)?;
|
||||
}
|
||||
input::event::PointerEvent::ScrollWheel(_) => todo!(),
|
||||
input::event::PointerEvent::ScrollFinger(_) => todo!(),
|
||||
|
@ -259,7 +259,7 @@ impl<'a> calloop::EventSource for LibInputHandler<'a> {
|
|||
}
|
||||
_ => None,
|
||||
} {
|
||||
window.dispatch_event(event);
|
||||
window.try_dispatch_event(event).map_err(Self::Error::other)?;
|
||||
}
|
||||
}
|
||||
input::Event::Keyboard(input::event::KeyboardEvent::Key(key_event)) => {
|
||||
|
@ -314,7 +314,7 @@ impl<'a> calloop::EventSource for LibInputHandler<'a> {
|
|||
KeyState::Pressed => WindowEvent::KeyPressed { text },
|
||||
KeyState::Released => WindowEvent::KeyReleased { text },
|
||||
};
|
||||
window.dispatch_event(event);
|
||||
window.try_dispatch_event(event).map_err(Self::Error::other)?;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -57,7 +57,7 @@ impl WindowAdapter for FullscreenWindowAdapter {
|
|||
if let Some(scale_factor) =
|
||||
std::env::var("SLINT_SCALE_FACTOR").ok().and_then(|sf| sf.parse().ok())
|
||||
{
|
||||
self.window.dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor });
|
||||
self.window.try_dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor })?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
@ -340,16 +340,22 @@ impl winit::application::ApplicationHandler<SlintUserEvent> for EventLoopState {
|
|||
window.window_state_event();
|
||||
}
|
||||
WindowEvent::CloseRequested => {
|
||||
window.window().dispatch_event(corelib::platform::WindowEvent::CloseRequested);
|
||||
self.loop_error = window
|
||||
.window()
|
||||
.try_dispatch_event(corelib::platform::WindowEvent::CloseRequested)
|
||||
.err();
|
||||
}
|
||||
WindowEvent::Focused(have_focus) => {
|
||||
let have_focus = have_focus || window.input_method_focused();
|
||||
// We don't render popups as separate windows yet, so treat
|
||||
// focus to be the same as being active.
|
||||
if have_focus != runtime_window.active() {
|
||||
window.window().dispatch_event(
|
||||
corelib::platform::WindowEvent::WindowActiveChanged(have_focus),
|
||||
);
|
||||
self.loop_error = window
|
||||
.window()
|
||||
.try_dispatch_event(corelib::platform::WindowEvent::WindowActiveChanged(
|
||||
have_focus,
|
||||
))
|
||||
.err();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,28 +390,31 @@ impl winit::application::ApplicationHandler<SlintUserEvent> for EventLoopState {
|
|||
}
|
||||
let text = i_slint_common::for_each_special_keys!(winit_key_to_char);
|
||||
|
||||
window.window().dispatch_event(match event.state {
|
||||
winit::event::ElementState::Pressed if event.repeat => {
|
||||
corelib::platform::WindowEvent::KeyPressRepeated { text }
|
||||
}
|
||||
winit::event::ElementState::Pressed => {
|
||||
if is_synthetic {
|
||||
// Synthetic event are sent when the focus is acquired, for all the keys currently pressed.
|
||||
// Don't forward these keys other than modifiers to the app
|
||||
use winit::keyboard::{Key::Named, NamedKey as N};
|
||||
if !matches!(
|
||||
key_code,
|
||||
Named(N::Control | N::Shift | N::Super | N::Alt | N::AltGraph),
|
||||
) {
|
||||
return;
|
||||
}
|
||||
self.loop_error = window
|
||||
.window()
|
||||
.try_dispatch_event(match event.state {
|
||||
winit::event::ElementState::Pressed if event.repeat => {
|
||||
corelib::platform::WindowEvent::KeyPressRepeated { text }
|
||||
}
|
||||
corelib::platform::WindowEvent::KeyPressed { text }
|
||||
}
|
||||
winit::event::ElementState::Released => {
|
||||
corelib::platform::WindowEvent::KeyReleased { text }
|
||||
}
|
||||
});
|
||||
winit::event::ElementState::Pressed => {
|
||||
if is_synthetic {
|
||||
// Synthetic event are sent when the focus is acquired, for all the keys currently pressed.
|
||||
// Don't forward these keys other than modifiers to the app
|
||||
use winit::keyboard::{Key::Named, NamedKey as N};
|
||||
if !matches!(
|
||||
key_code,
|
||||
Named(N::Control | N::Shift | N::Super | N::Alt | N::AltGraph),
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
corelib::platform::WindowEvent::KeyPressed { text }
|
||||
}
|
||||
winit::event::ElementState::Released => {
|
||||
corelib::platform::WindowEvent::KeyReleased { text }
|
||||
}
|
||||
})
|
||||
.err();
|
||||
}
|
||||
WindowEvent::Ime(winit::event::Ime::Preedit(string, preedit_selection)) => {
|
||||
let event = KeyEvent {
|
||||
|
@ -521,11 +530,12 @@ impl winit::application::ApplicationHandler<SlintUserEvent> for EventLoopState {
|
|||
}
|
||||
WindowEvent::ScaleFactorChanged { scale_factor, inner_size_writer: _ } => {
|
||||
if std::env::var("SLINT_SCALE_FACTOR").is_err() {
|
||||
window.window().dispatch_event(
|
||||
corelib::platform::WindowEvent::ScaleFactorChanged {
|
||||
self.loop_error = window
|
||||
.window()
|
||||
.try_dispatch_event(corelib::platform::WindowEvent::ScaleFactorChanged {
|
||||
scale_factor: scale_factor as f32,
|
||||
},
|
||||
);
|
||||
})
|
||||
.err();
|
||||
// TODO: send a resize event or try to keep the logical size the same.
|
||||
//window.resize_event(inner_size_writer.???)?;
|
||||
}
|
||||
|
|
|
@ -347,7 +347,7 @@ impl WinitWindowAdapter {
|
|||
.and_then(|x| x.parse::<f32>().ok())
|
||||
.filter(|f| *f > 0.)
|
||||
.unwrap_or_else(|| winit_window.scale_factor() as f32);
|
||||
self_rc.window().dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor });
|
||||
self_rc.window().try_dispatch_event(WindowEvent::ScaleFactorChanged { scale_factor })?;
|
||||
|
||||
Ok(self_rc)
|
||||
}
|
||||
|
@ -553,9 +553,9 @@ impl WinitWindowAdapter {
|
|||
let physical_size = physical_size_to_slint(&size);
|
||||
self.size.set(physical_size);
|
||||
let scale_factor = WindowInner::from_pub(self.window()).scale_factor();
|
||||
self.window().dispatch_event(WindowEvent::Resized {
|
||||
self.window().try_dispatch_event(WindowEvent::Resized {
|
||||
size: physical_size.to_logical(scale_factor),
|
||||
});
|
||||
})?;
|
||||
|
||||
// Workaround fox winit not sync'ing CSS size of the canvas (the size shown on the browser)
|
||||
// with the width/height attribute (the size of the viewport/GL surface)
|
||||
|
@ -925,9 +925,11 @@ impl WindowAdapter for WinitWindowAdapter {
|
|||
}
|
||||
|
||||
if must_resize {
|
||||
self.window().dispatch_event(WindowEvent::Resized {
|
||||
size: i_slint_core::api::LogicalSize::new(width, height),
|
||||
});
|
||||
self.window()
|
||||
.try_dispatch_event(WindowEvent::Resized {
|
||||
size: i_slint_core::api::LogicalSize::new(width, height),
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let m = properties.is_fullscreen();
|
||||
|
|
|
@ -363,7 +363,7 @@ fn generate_shared_globals(
|
|||
let apply_constant_scale_factor = if !compiler_config.const_scale_factor.approx_eq(&1.0) {
|
||||
let factor = compiler_config.const_scale_factor as f32;
|
||||
Some(
|
||||
quote!(adapter.window().dispatch_event(slint::platform::WindowEvent::ScaleFactorChanged{ scale_factor: #factor });),
|
||||
quote!(adapter.window().try_dispatch_event(slint::platform::WindowEvent::ScaleFactorChanged{ scale_factor: #factor })?;),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -554,8 +554,24 @@ impl Window {
|
|||
///
|
||||
/// Any position fields in the event must be in the logical pixel coordinate system relative to
|
||||
/// the top left corner of the window.
|
||||
// TODO: Return a Result<(), PlatformError>
|
||||
///
|
||||
/// This function panics if there is an error processing the event.
|
||||
/// Use [`Self::try_dispatch_event()`] to handle the error.
|
||||
#[track_caller]
|
||||
pub fn dispatch_event(&self, event: crate::platform::WindowEvent) {
|
||||
self.try_dispatch_event(event).unwrap()
|
||||
}
|
||||
|
||||
/// Dispatch a window event to the scene.
|
||||
///
|
||||
/// Use this when you're implementing your own backend and want to forward user input events.
|
||||
///
|
||||
/// Any position fields in the event must be in the logical pixel coordinate system relative to
|
||||
/// the top left corner of the window.
|
||||
pub fn try_dispatch_event(
|
||||
&self,
|
||||
event: crate::platform::WindowEvent,
|
||||
) -> Result<(), PlatformError> {
|
||||
match event {
|
||||
crate::platform::WindowEvent::PointerPressed { position, button } => {
|
||||
self.0.process_mouse_input(MouseEvent::Pressed {
|
||||
|
@ -615,19 +631,16 @@ impl Window {
|
|||
}
|
||||
crate::platform::WindowEvent::Resized { size } => {
|
||||
self.0.set_window_item_geometry(size.to_euclid());
|
||||
self.0
|
||||
.window_adapter()
|
||||
.renderer()
|
||||
.resize(size.to_physical(self.scale_factor()))
|
||||
.unwrap()
|
||||
self.0.window_adapter().renderer().resize(size.to_physical(self.scale_factor()))?;
|
||||
}
|
||||
crate::platform::WindowEvent::CloseRequested => {
|
||||
if self.0.request_close() {
|
||||
self.hide().unwrap();
|
||||
self.hide()?;
|
||||
}
|
||||
}
|
||||
crate::platform::WindowEvent::WindowActiveChanged(bool) => self.0.set_active(bool),
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns true if there is an animation currently active on any property in the Window; false otherwise.
|
||||
|
|
|
@ -280,7 +280,7 @@ pub use crate::input::PointerEventButton;
|
|||
/// A event that describes user input or windowing system events.
|
||||
///
|
||||
/// Slint backends typically receive events from the windowing system, translate them to this
|
||||
/// enum and deliver them to the scene of items via [`slint::Window::dispatch_event()`](`crate::api::Window::dispatch_event()`).
|
||||
/// enum and deliver them to the scene of items via [`slint::Window::try_dispatch_event()`](`crate::api::Window::try_dispatch_event()`).
|
||||
///
|
||||
/// The pointer variants describe events originating from an input device such as a mouse
|
||||
/// or a contact point on a touch-enabled surface.
|
||||
|
|
|
@ -49,20 +49,20 @@ fn previous_focus_item(item: ItemRc) -> ItemRc {
|
|||
///
|
||||
/// - When receiving messages from the windowing system about state changes, such as the window being resized,
|
||||
/// the user requested the window to be closed, input being received, etc. you need to create a
|
||||
/// [`crate::platform::WindowEvent`](enum.WindowEvent.html) and send it to Slint via [`create::Window::dispatch_event()`](../struct.Window.html#method.dispatch_event).
|
||||
/// [`WindowEvent`](crate::platform::WindowEvent) and send it to Slint via [`Window::try_dispatch_event()`].
|
||||
///
|
||||
/// - Slint sends requests to change visibility, position, size, etc. via functions such as [`Self::set_visible`],
|
||||
/// [`Self::set_size`], [`Self::set_position`], or [`Self::update_window_properties()`]. Re-implement these functions
|
||||
/// and delegate the requests to the windowing system.
|
||||
///
|
||||
/// If the implementation of this bi-directional message passing protocol is incomplete, the user may
|
||||
/// experience unexpected behavior, or the intention of the developer calling functions on the [`crate::Window`](struct.Window.html)
|
||||
/// experience unexpected behavior, or the intention of the developer calling functions on the [`Window`]
|
||||
/// API may not be fulfilled.
|
||||
///
|
||||
/// Your implementation must hold a renderer, such as [`crate::software_renderer::SoftwareRenderer`].
|
||||
/// Your implementation must hold a renderer, such as [`SoftwareRenderer`](crate::software_renderer::SoftwareRenderer).
|
||||
/// In the [`Self::renderer()`] function, you must return a reference to it.
|
||||
///
|
||||
/// It is also required to hold a [`crate::Window`](struct.Window.html) and return a reference to it in your
|
||||
/// It is also required to hold a [`Window`] and return a reference to it in your
|
||||
/// implementation of [`Self::window()`].
|
||||
///
|
||||
/// See also [`MinimalSoftwareWindow`](crate::software_renderer::MinimalSoftwareWindow)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue