C++: dispatch close request and activation change

This commit is contained in:
Olivier Goffart 2023-08-24 16:13:09 +02:00 committed by Olivier Goffart
parent b35ccfcc77
commit 7904493e1c
7 changed files with 71 additions and 28 deletions

View file

@ -471,6 +471,7 @@ fn gen_corelib(
"slint_windowrc_dark_color_scheme",
"slint_windowrc_dispatch_pointer_event",
"slint_windowrc_dispatch_key_event",
"slint_windowrc_dispatch_event",
"slint_new_path_elements",
"slint_new_path_events",
"slint_color_brighter",
@ -604,11 +605,18 @@ fn gen_corelib(
friend inline LayoutInfo operator+(const LayoutInfo &a, const LayoutInfo &b) { return a.merge(b); }
friend bool operator==(const LayoutInfo&, const LayoutInfo&) = default;".into(),
);
config.export.body.insert(
"WindowEvent".to_owned(),
"/* Some members of the WindowEvent enum have destructors (with SharedString), but thankfully we don't use these so we can have an empty constructor */
~WindowEvent() {}"
.into(),
);
config
.export
.body
.insert("Flickable".to_owned(), " inline Flickable(); inline ~Flickable();".into());
config.export.pre_body.insert("FlickableDataBox".to_owned(), "struct FlickableData;".into());
cbindgen::Builder::new()
.with_config(config)
.with_src(crate_dir.join("lib.rs"))

View file

@ -428,7 +428,11 @@ public:
void dispatch_resize_event(slint::LogicalSize s)
{
private_api::assert_main_thread();
cbindgen_private::slint_windowrc_dispatch_resize_event(&inner.handle(), s.width, s.height);
using slint::cbindgen_private::WindowEvent;
WindowEvent event { .resized =
WindowEvent::Resized_Body { .tag = WindowEvent::Tag::Resized,
.size = { s.width, s.height } } };
cbindgen_private::slint_windowrc_dispatch_event(&inner.handle(), &event);
}
/// The window's scale factor has changed. This can happen for example when the display's
@ -439,8 +443,39 @@ public:
void dispatch_scale_factor_change_event(float factor)
{
private_api::assert_main_thread();
cbindgen_private::slint_windowrc_dispatch_scale_factor_change_event(&inner.handle(),
factor);
using slint::cbindgen_private::WindowEvent;
WindowEvent event { .scale_factor_changed = WindowEvent::ScaleFactorChanged_Body {
.tag = WindowEvent::Tag::ScaleFactorChanged,
.scale_factor = factor } };
cbindgen_private::slint_windowrc_dispatch_event(&inner.handle(), &event);
}
/// The Window was activated or de-activated.
///
/// The backend should dispatch this event with true when the window gains focus
/// and false when the window loses focus.
void dispatch_window_active_changed_event(bool active)
{
private_api::assert_main_thread();
using slint::cbindgen_private::WindowEvent;
WindowEvent event { .window_active_changed = WindowEvent::WindowActiveChanged_Body {
.tag = WindowEvent::Tag::WindowActiveChanged, ._0 = active } };
cbindgen_private::slint_windowrc_dispatch_event(&inner.handle(), &event);
}
/// The user requested to close the window.
///
/// The backend should send this event when the user tries to close the window,for example by
/// pressing the close button.
///
/// This will have the effect of invoking the callback set in Window::on_close_requested() and
/// then hiding the window depending on the return value of the callback.
void dispatch_close_requested_event()
{
private_api::assert_main_thread();
using slint::cbindgen_private::WindowEvent;
WindowEvent event { .tag = WindowEvent::Tag::CloseRequested };
cbindgen_private::slint_windowrc_dispatch_event(&inner.handle(), &event);
}
/// Returns true if there is an animation currently active on any property in the Window.

View file

@ -194,31 +194,6 @@ pub unsafe extern "C" fn slint_windowrc_has_active_animations(
window_adapter.window().has_active_animations()
}
/// Dispatch resize event
#[no_mangle]
pub unsafe extern "C" fn slint_windowrc_dispatch_resize_event(
handle: *const WindowAdapterRcOpaque,
width: f32,
height: f32,
) {
let window_adapter = &*(handle as *const Rc<dyn WindowAdapter>);
window_adapter.window().dispatch_event(i_slint_core::platform::WindowEvent::Resized {
size: i_slint_core::api::LogicalSize { width, height },
});
}
/// Dispatch scale factor change event
#[no_mangle]
pub unsafe extern "C" fn slint_windowrc_dispatch_scale_factor_change_event(
handle: *const WindowAdapterRcOpaque,
scale_factor: f32,
) {
let window_adapter = &*(handle as *const Rc<dyn WindowAdapter>);
window_adapter
.window()
.dispatch_event(i_slint_core::platform::WindowEvent::ScaleFactorChanged { scale_factor });
}
#[no_mangle]
pub extern "C" fn slint_platform_update_timers_and_animations() {
i_slint_core::platform::update_timers_and_animations()

View file

@ -214,6 +214,12 @@ public:
update_timer();
}
void closeEvent(QCloseEvent *event) override
{
window().dispatch_close_requested_event();
event->ignore();
}
bool event(QEvent *e) override
{
if (e->type() == QEvent::UpdateRequest) {
@ -225,6 +231,12 @@ public:
} else if (e->type() == QEvent::KeyRelease) {
window().dispatch_key_release_event(key_event_text(static_cast<QKeyEvent *>(e)));
return true;
} else if (e->type() == QEvent::WindowActivate) {
window().dispatch_window_active_changed_event(true);
return true;
} else if (e->type() == QEvent::WindowDeactivate) {
window().dispatch_window_active_changed_event(false);
return true;
} else {
return QWindow::event(e);
}

View file

@ -18,6 +18,7 @@ use alloc::string::String;
/// A position represented in the coordinate space of logical pixels. That is the space before applying
/// a display device specific scale factor.
#[derive(Debug, Default, Copy, Clone, PartialEq)]
#[repr(C)]
pub struct LogicalPosition {
/// The x coordinate.
pub x: f32,
@ -109,6 +110,7 @@ impl WindowPosition {
/// A size represented in the coordinate space of logical pixels. That is the space before applying
/// a display device specific scale factor.
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, PartialEq)]
pub struct LogicalSize {
/// The width in logical pixels.

View file

@ -226,6 +226,7 @@ pub use crate::input::PointerEventButton;
#[allow(missing_docs)]
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
#[repr(u32)]
pub enum WindowEvent {
/// A pointer was pressed.
PointerPressed {

View file

@ -1292,6 +1292,16 @@ pub mod ffi {
let window_adapter = &*(handle as *const Rc<dyn WindowAdapter>);
window_adapter.window().0.process_mouse_input(event);
}
/// Dispatch a window event
#[no_mangle]
pub unsafe extern "C" fn slint_windowrc_dispatch_event(
handle: *const WindowAdapterRcOpaque,
event: &crate::platform::WindowEvent,
) {
let window_adapter = &*(handle as *const Rc<dyn WindowAdapter>);
window_adapter.window().dispatch_event(event.clone());
}
}
#[test]