1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4#pragma once
5
6#include "slint_internal.h"
7
8#ifndef SLINT_FEATURE_FREESTANDING
9# include <thread>
10# include <iostream>
11#endif
12
13namespace slint {
14#if !defined(DOXYGEN)
15namespace platform {
16class SkiaRenderer;
17class SoftwareRenderer;
18}
19#endif
20
21namespace private_api {
22/// Internal function that checks that the API that must be called from the main
23/// thread is indeed called from the main thread, or abort the program otherwise
24///
25/// Most API should be called from the main thread. When using thread one must
26/// use slint::invoke_from_event_loop
27inline void assert_main_thread()
28{
29#ifndef SLINT_FEATURE_FREESTANDING
30# ifndef NDEBUG
31 static auto main_thread_id = std::this_thread::get_id();
32 if (main_thread_id != std::this_thread::get_id()) {
33 std::cerr << "A function that should be only called from the main thread was called from a "
34 "thread."
35 << std::endl;
36 std::cerr << "Most API should be called from the main thread. When using thread one must "
37 "use slint::invoke_from_event_loop."
38 << std::endl;
39 std::abort();
40 }
41# endif
42#endif
43}
44
45using ItemTreeRc = vtable::VRc<cbindgen_private::ItemTreeVTable>;
46using slint::LogicalPosition;
47
48class WindowAdapterRc
49{
50public:
51 explicit WindowAdapterRc(cbindgen_private::WindowAdapterRcOpaque adopted_inner)
52 {
53 assert_main_thread();
54 cbindgen_private::slint_windowrc_clone(source: &adopted_inner, target: &inner);
55 }
56 WindowAdapterRc() { cbindgen_private::slint_windowrc_init(out: &inner); }
57 ~WindowAdapterRc() { cbindgen_private::slint_windowrc_drop(handle: &inner); }
58 WindowAdapterRc(const WindowAdapterRc &other) : WindowAdapterRc(other.inner) { }
59 WindowAdapterRc(WindowAdapterRc &&) = delete;
60 WindowAdapterRc &operator=(WindowAdapterRc &&) = delete;
61 WindowAdapterRc &operator=(const WindowAdapterRc &other)
62 {
63 assert_main_thread();
64 if (this != &other) {
65 cbindgen_private::slint_windowrc_drop(handle: &inner);
66 cbindgen_private::slint_windowrc_clone(source: &other.inner, target: &inner);
67 }
68 return *this;
69 }
70
71 void show() const { slint_windowrc_show(handle: &inner); }
72 void hide() const { slint_windowrc_hide(handle: &inner); }
73 bool is_visible() const { return slint_windowrc_is_visible(handle: &inner); }
74
75 float scale_factor() const { return slint_windowrc_get_scale_factor(handle: &inner); }
76 void set_scale_factor(float value) const { slint_windowrc_set_scale_factor(handle: &inner, value); }
77
78 cbindgen_private::ColorScheme color_scheme() const
79 {
80 return slint_windowrc_color_scheme(&inner);
81 }
82 bool supports_native_menu_bar() const
83 {
84 return slint_windowrc_supports_native_menu_bar(&inner);
85 }
86
87 template<typename Component, typename SubMenu, typename Activated>
88 void setup_native_menu_bar(Component component, SubMenu submenu, Activated activated) const
89 {
90 if (!supports_native_menu_bar()) {
91 return;
92 }
93 struct MenuWrapper
94 {
95 Component component;
96 SubMenu submenu;
97 Activated activated;
98 };
99 static cbindgen_private::MenuVTable menu_vtable = {
100 .drop = [](auto data) { delete reinterpret_cast<MenuWrapper *>(data.instance); },
101 .sub_menu =
102 [](auto data, const cbindgen_private::MenuEntry *entry,
103 slint::SharedVector<cbindgen_private::MenuEntry> *result) {
104 auto wrapper = reinterpret_cast<MenuWrapper *>(data.instance);
105 auto model = wrapper->submenu(wrapper->component, entry);
106 result->clear();
107 if (model) {
108 auto count = model->row_count();
109 for (size_t i = 0; i < count; ++i) {
110 result->push_back(*model->row_data(i));
111 }
112 }
113 },
114 .activate =
115 [](auto data, const cbindgen_private::MenuEntry *entry) {
116 auto wrapper = reinterpret_cast<MenuWrapper *>(data.instance);
117 wrapper->activated(wrapper->component, *entry);
118 },
119 };
120 auto instance = new MenuWrapper { component, std::move(submenu), std::move(activated) };
121 cbindgen_private::slint_windowrc_setup_native_menu_bar(&inner, &menu_vtable, instance);
122 }
123
124 bool text_input_focused() const { return slint_windowrc_get_text_input_focused(handle: &inner); }
125 void set_text_input_focused(bool value) const
126 {
127 slint_windowrc_set_text_input_focused(handle: &inner, value);
128 }
129
130 template<typename Component, typename ItemArray>
131 void unregister_item_tree(Component *c, ItemArray items) const
132 {
133 cbindgen_private::slint_unregister_item_tree(
134 component: vtable::VRef<cbindgen_private::ItemTreeVTable> { &Component::static_vtable, c },
135 item_array: items, window_handle: &inner);
136 }
137
138 void set_focus_item(const ItemTreeRc &component_rc, uint32_t item_index, bool set_focus)
139 {
140 cbindgen_private::ItemRc item_rc { .item_tree: component_rc, .index: item_index };
141 cbindgen_private::slint_windowrc_set_focus_item(&inner, &item_rc, set_focus);
142 }
143
144 void set_component(const cbindgen_private::ItemTreeWeak &weak) const
145 {
146 auto item_tree_rc = (*weak.lock()).into_dyn();
147 slint_windowrc_set_component(handle: &inner, component: &item_tree_rc);
148 }
149
150 template<typename Component, typename Parent, typename PosGetter>
151 uint32_t show_popup(const Parent *parent_component, PosGetter pos,
152 cbindgen_private::PopupClosePolicy close_policy,
153 cbindgen_private::ItemRc parent_item) const
154 {
155 auto popup = Component::create(parent_component);
156 auto p = pos(popup);
157 auto popup_dyn = popup.into_dyn();
158 auto id = cbindgen_private::slint_windowrc_show_popup(handle: &inner, popup: &popup_dyn, position: p, close_on_click: close_policy,
159 parent_item: &parent_item, false);
160 popup->user_init();
161 return id;
162 }
163
164 void close_popup(uint32_t popup_id) const
165 {
166 if (popup_id > 0) {
167 cbindgen_private::slint_windowrc_close_popup(&inner, popup_id);
168 }
169 }
170
171 template<typename Component, typename SharedGlobals, typename InitFn>
172 uint32_t show_popup_menu(SharedGlobals *globals, LogicalPosition pos,
173 cbindgen_private::ItemRc context_menu_rc, InitFn init) const
174 {
175 // if (cbindgen_private::slint_windowrc_show_native_context_menu(....)) { return }
176
177 auto popup = Component::create(globals);
178 init(&*popup);
179 auto popup_dyn = popup.into_dyn();
180 auto id = cbindgen_private::slint_windowrc_show_popup(
181 &inner, &popup_dyn, pos, cbindgen_private::PopupClosePolicy::CloseOnClickOutside,
182 &context_menu_rc, true);
183 popup->user_init();
184 return id;
185 }
186
187 template<std::invocable<RenderingState, GraphicsAPI> F>
188 std::optional<SetRenderingNotifierError> set_rendering_notifier(F callback) const
189 {
190 auto actual_cb = [](RenderingState state, GraphicsAPI graphics_api, void *data) {
191 (*reinterpret_cast<F *>(data))(state, graphics_api);
192 };
193 SetRenderingNotifierError err;
194 if (cbindgen_private::slint_windowrc_set_rendering_notifier(
195 handle: &inner, callback: actual_cb,
196 drop_user_data: [](void *user_data) { delete reinterpret_cast<F *>(user_data); },
197 user_data: new F(std::move(callback)), error: &err)) {
198 return {};
199 } else {
200 return err;
201 }
202 }
203
204 // clang-format off
205 template<std::invocable F>
206 requires(std::is_convertible_v<std::invoke_result_t<F>, CloseRequestResponse>)
207 void on_close_requested(F callback) const
208 // clang-format on
209 {
210 auto actual_cb = [](void *data) { return (*reinterpret_cast<F *>(data))(); };
211 cbindgen_private::slint_windowrc_on_close_requested(
212 handle: &inner, callback: actual_cb, drop_user_data: [](void *user_data) { delete reinterpret_cast<F *>(user_data); },
213 user_data: new F(std::move(callback)));
214 }
215
216 void request_redraw() const { cbindgen_private::slint_windowrc_request_redraw(handle: &inner); }
217
218 slint::PhysicalPosition position() const
219 {
220 slint::PhysicalPosition pos;
221 cbindgen_private::slint_windowrc_position(handle: &inner, pos: &pos);
222 return pos;
223 }
224
225 void set_logical_position(const slint::LogicalPosition &pos)
226 {
227 cbindgen_private::slint_windowrc_set_logical_position(handle: &inner, pos: &pos);
228 }
229
230 void set_physical_position(const slint::PhysicalPosition &pos)
231 {
232 cbindgen_private::slint_windowrc_set_physical_position(handle: &inner, pos: &pos);
233 }
234
235 slint::PhysicalSize size() const
236 {
237 return slint::PhysicalSize(cbindgen_private::slint_windowrc_size(handle: &inner));
238 }
239
240 void set_logical_size(const slint::LogicalSize &size)
241 {
242 cbindgen_private::slint_windowrc_set_logical_size(handle: &inner, size: &size);
243 }
244
245 void set_physical_size(const slint::PhysicalSize &size)
246 {
247 cbindgen_private::slint_windowrc_set_physical_size(handle: &inner, size: &size);
248 }
249
250 /// Send a pointer event to this window
251 void dispatch_pointer_event(const cbindgen_private::MouseEvent &event)
252 {
253 private_api::assert_main_thread();
254 cbindgen_private::slint_windowrc_dispatch_pointer_event(handle: &inner, event);
255 }
256
257 /// Registers a font by the specified path. The path must refer to an existing
258 /// TrueType font.
259 /// \returns an empty optional on success, otherwise an error string
260 inline std::optional<SharedString> register_font_from_path(const SharedString &path)
261 {
262 SharedString maybe_err;
263 cbindgen_private::slint_register_font_from_path(win: &inner, path: &path, error_str: &maybe_err);
264 if (!maybe_err.empty()) {
265 return maybe_err;
266 } else {
267 return {};
268 }
269 }
270
271 /// Registers a font by the data. The data must be valid TrueType font data.
272 /// \returns an empty optional on success, otherwise an error string
273 inline std::optional<SharedString> register_font_from_data(const uint8_t *data, std::size_t len)
274 {
275 SharedString maybe_err;
276 cbindgen_private::slint_register_font_from_data(
277 win: &inner, data: { const_cast<uint8_t *>(data), len }, error_str: &maybe_err);
278 if (!maybe_err.empty()) {
279 return maybe_err;
280 } else {
281 return {};
282 }
283 }
284
285 /// Registers a bitmap font for use with the software renderer.
286 inline void register_bitmap_font(const cbindgen_private::BitmapFont &font)
287 {
288 cbindgen_private::slint_register_bitmap_font(win: &inner, font_data: &font);
289 }
290
291 inline float default_font_size() const
292 {
293 return cbindgen_private::slint_windowrc_default_font_size(&inner);
294 }
295
296 /// \private
297 const cbindgen_private::WindowAdapterRcOpaque &handle() const { return inner; }
298
299private:
300 friend class slint::platform::SkiaRenderer;
301 friend class slint::platform::SoftwareRenderer;
302 cbindgen_private::WindowAdapterRcOpaque inner;
303};
304
305}
306
307/// This class represents a window towards the windowing system, that's used to render the
308/// scene of a component. It provides API to control windowing system specific aspects such
309/// as the position on the screen.
310class Window
311{
312public:
313 /// \private
314 /// Internal function used by the generated code to construct a new instance of this
315 /// public API wrapper.
316 explicit Window(const private_api::WindowAdapterRc &windowrc) : inner(windowrc) { }
317 Window(const Window &other) = delete;
318 Window &operator=(const Window &other) = delete;
319 Window(Window &&other) = delete;
320 Window &operator=(Window &&other) = delete;
321 /// Destroys this window. Window instances are explicitly shared and reference counted.
322 /// If this window instance is the last one referencing the window towards the windowing
323 /// system, then it will also become hidden and destroyed.
324 ~Window() = default;
325
326 /// Shows the window on the screen. An additional strong reference on the
327 /// associated component is maintained while the window is visible.
328 ///
329 /// Call hide() to make the window invisible again, and drop the additional
330 /// strong reference.
331 void show()
332 {
333 private_api::assert_main_thread();
334 inner.show();
335 }
336 /// Hides the window, so that it is not visible anymore. The additional strong
337 /// reference on the associated component, that was created when show() was called, is
338 /// dropped.
339 void hide()
340 {
341 private_api::assert_main_thread();
342 inner.hide();
343 }
344
345 /// Returns the visibility state of the window. This function can return false even if you
346 /// previously called show() on it, for example if the user minimized the window.
347 bool is_visible() const
348 {
349 private_api::assert_main_thread();
350 return inner.is_visible();
351 }
352
353 /// This function allows registering a callback that's invoked during the different phases of
354 /// rendering. This allows custom rendering on top or below of the scene.
355 ///
356 /// The provided callback must be callable with a slint::RenderingState and the
357 /// slint::GraphicsAPI argument.
358 ///
359 /// On success, the function returns a std::optional without value. On error, the function
360 /// returns the error code as value in the std::optional.
361 template<std::invocable<RenderingState, GraphicsAPI> F>
362 std::optional<SetRenderingNotifierError> set_rendering_notifier(F &&callback) const
363 {
364 private_api::assert_main_thread();
365 return inner.set_rendering_notifier(std::forward<F>(callback));
366 }
367
368 /// This function allows registering a callback that's invoked when the user tries to close
369 /// a window.
370 /// The callback has to return a CloseRequestResponse.
371 // clang-format off
372 template<std::invocable F>
373 requires(std::is_convertible_v<std::invoke_result_t<F>, CloseRequestResponse>)
374 void on_close_requested(F &&callback) const
375 // clang-format on
376 {
377 private_api::assert_main_thread();
378 return inner.on_close_requested(std::forward<F>(callback));
379 }
380
381 /// This function issues a request to the windowing system to redraw the contents of the window.
382 void request_redraw() const
383 {
384 private_api::assert_main_thread();
385 inner.request_redraw();
386 }
387
388 /// Returns the position of the window on the screen, in physical screen coordinates and
389 /// including a window frame (if present).
390 slint::PhysicalPosition position() const
391 {
392 private_api::assert_main_thread();
393 return inner.position();
394 }
395
396 /// Sets the position of the window on the screen, in physical screen coordinates and including
397 /// a window frame (if present).
398 /// Note that on some windowing systems, such as Wayland, this functionality is not available.
399 void set_position(const slint::LogicalPosition &pos)
400 {
401 private_api::assert_main_thread();
402 inner.set_logical_position(pos);
403 }
404 /// Sets the position of the window on the screen, in physical screen coordinates and including
405 /// a window frame (if present).
406 /// Note that on some windowing systems, such as Wayland, this functionality is not available.
407 void set_position(const slint::PhysicalPosition &pos)
408 {
409 private_api::assert_main_thread();
410 inner.set_physical_position(pos);
411 }
412
413 /// Returns the size of the window on the screen, in physical screen coordinates and excluding
414 /// a window frame (if present).
415 slint::PhysicalSize size() const
416 {
417 private_api::assert_main_thread();
418 return inner.size();
419 }
420
421 /// Resizes the window to the specified size on the screen, in logical pixels and excluding
422 /// a window frame (if present).
423 void set_size(const slint::LogicalSize &size)
424 {
425 private_api::assert_main_thread();
426 inner.set_logical_size(size);
427 }
428 /// Resizes the window to the specified size on the screen, in physical pixels and excluding
429 /// a window frame (if present).
430 void set_size(const slint::PhysicalSize &size)
431 {
432 private_api::assert_main_thread();
433 inner.set_physical_size(size);
434 }
435
436 /// This function returns the scale factor that allows converting between logical and
437 /// physical pixels.
438 float scale_factor() const
439 {
440 private_api::assert_main_thread();
441 return inner.scale_factor();
442 }
443
444 /// Returns if the window is currently fullscreen
445 bool is_fullscreen() const
446 {
447 private_api::assert_main_thread();
448 return cbindgen_private::slint_windowrc_is_fullscreen(handle: &inner.handle());
449 }
450 /// Set or unset the window to display fullscreen.
451 void set_fullscreen(bool fullscreen)
452 {
453 private_api::assert_main_thread();
454 cbindgen_private::slint_windowrc_set_fullscreen(handle: &inner.handle(), value: fullscreen);
455 }
456
457 /// Returns if the window is currently maximized
458 bool is_maximized() const
459 {
460 private_api::assert_main_thread();
461 return cbindgen_private::slint_windowrc_is_maximized(handle: &inner.handle());
462 }
463 /// Maximize or unmaximize the window.
464 void set_maximized(bool maximized)
465 {
466 private_api::assert_main_thread();
467 cbindgen_private::slint_windowrc_set_maximized(handle: &inner.handle(), value: maximized);
468 }
469
470 /// Returns if the window is currently minimized
471 bool is_minimized() const
472 {
473 private_api::assert_main_thread();
474 return cbindgen_private::slint_windowrc_is_minimized(handle: &inner.handle());
475 }
476 /// Minimize or unminimze the window.
477 void set_minimized(bool minimized)
478 {
479 private_api::assert_main_thread();
480 cbindgen_private::slint_windowrc_set_minimized(handle: &inner.handle(), value: minimized);
481 }
482
483 /// Dispatch a key press event to the scene.
484 ///
485 /// Use this when you're implementing your own backend and want to forward user input events.
486 ///
487 /// The \a text is the unicode representation of the key.
488 void dispatch_key_press_event(const SharedString &text)
489 {
490 private_api::assert_main_thread();
491 cbindgen_private::slint_windowrc_dispatch_key_event(
492 handle: &inner.handle(), event_type: cbindgen_private::KeyEventType::KeyPressed, text: &text, repeat: false);
493 }
494
495 /// Dispatch an auto-repeated key press event to the scene.
496 ///
497 /// Use this when you're implementing your own backend and want to forward user input events.
498 ///
499 /// The \a text is the unicode representation of the key.
500 void dispatch_key_press_repeat_event(const SharedString &text)
501 {
502 private_api::assert_main_thread();
503 cbindgen_private::slint_windowrc_dispatch_key_event(
504 handle: &inner.handle(), event_type: cbindgen_private::KeyEventType::KeyPressed, text: &text, repeat: true);
505 }
506
507 /// Dispatch a key release event to the scene.
508 ///
509 /// Use this when you're implementing your own backend and want to forward user input events.
510 ///
511 /// The \a text is the unicode representation of the key.
512 void dispatch_key_release_event(const SharedString &text)
513 {
514 private_api::assert_main_thread();
515 cbindgen_private::slint_windowrc_dispatch_key_event(
516 handle: &inner.handle(), event_type: cbindgen_private::KeyEventType::KeyReleased, text: &text, repeat: false);
517 }
518
519 /// Dispatches a pointer or mouse press event to the scene.
520 ///
521 /// Use this function when you're implementing your own backend and want to forward user
522 /// pointer/mouse events.
523 ///
524 /// \a pos represents the logical position of the pointer relative to the window.
525 /// \a button is the button that was pressed.
526 void dispatch_pointer_press_event(LogicalPosition pos, PointerEventButton button)
527 {
528 private_api::assert_main_thread();
529 using slint::cbindgen_private::MouseEvent;
530 MouseEvent event { .tag = MouseEvent::Tag::Pressed,
531 .pressed = MouseEvent::Pressed_Body { .position = { .x: pos.x, .y: pos.y },
532 .button = button,
533 .click_count = 0 } };
534 inner.dispatch_pointer_event(event);
535 }
536 /// Dispatches a pointer or mouse release event to the scene.
537 ///
538 /// Use this function when you're implementing your own backend and want to forward user
539 /// pointer/mouse events.
540 ///
541 /// \a pos represents the logical position of the pointer relative to the window.
542 /// \a button is the button that was released.
543 void dispatch_pointer_release_event(LogicalPosition pos, PointerEventButton button)
544 {
545 private_api::assert_main_thread();
546 using slint::cbindgen_private::MouseEvent;
547 MouseEvent event { .tag = MouseEvent::Tag::Released,
548 .released = MouseEvent::Released_Body { .position = { .x: pos.x, .y: pos.y },
549 .button = button,
550 .click_count = 0 } };
551 inner.dispatch_pointer_event(event);
552 }
553 /// Dispatches a pointer exit event to the scene.
554 ///
555 /// Use this function when you're implementing your own backend and want to forward user
556 /// pointer/mouse events.
557 ///
558 /// This event is triggered when the pointer exits the window.
559 void dispatch_pointer_exit_event()
560 {
561 private_api::assert_main_thread();
562 using slint::cbindgen_private::MouseEvent;
563 MouseEvent event { .tag = MouseEvent::Tag::Exit, .moved = {} };
564 inner.dispatch_pointer_event(event);
565 }
566
567 /// Dispatches a pointer move event to the scene.
568 ///
569 /// Use this function when you're implementing your own backend and want to forward user
570 /// pointer/mouse events.
571 ///
572 /// \a pos represents the logical position of the pointer relative to the window.
573 void dispatch_pointer_move_event(LogicalPosition pos)
574 {
575 private_api::assert_main_thread();
576 using slint::cbindgen_private::MouseEvent;
577 MouseEvent event { .tag = MouseEvent::Tag::Moved,
578 .moved = MouseEvent::Moved_Body { .position = { .x: pos.x, .y: pos.y } } };
579 inner.dispatch_pointer_event(event);
580 }
581
582 /// Dispatches a scroll (or wheel) event to the scene.
583 ///
584 /// Use this function when you're implementing your own backend and want to forward user wheel
585 /// events.
586 ///
587 /// \a parameter represents the logical position of the pointer relative to the window.
588 /// \a delta_x and \a delta_y represent the scroll delta values in the X and Y
589 /// directions in logical pixels.
590 void dispatch_pointer_scroll_event(LogicalPosition pos, float delta_x, float delta_y)
591 {
592 private_api::assert_main_thread();
593 using slint::cbindgen_private::MouseEvent;
594 MouseEvent event { .tag = MouseEvent::Tag::Wheel,
595 .wheel = MouseEvent::Wheel_Body { .position = { .x: pos.x, .y: pos.y },
596 .delta_x = delta_x,
597 .delta_y = delta_y } };
598 inner.dispatch_pointer_event(event);
599 }
600
601 /// Set the logical size of this window after a resize event
602 ///
603 /// The backend must send this event to ensure that the `width` and `height` property of the
604 /// root Window element are properly set.
605 void dispatch_resize_event(slint::LogicalSize s)
606 {
607 private_api::assert_main_thread();
608 using slint::cbindgen_private::WindowEvent;
609 WindowEvent event { .resized =
610 WindowEvent::Resized_Body { .tag = WindowEvent::Tag::Resized,
611 .size = { .width: s.width, .height: s.height } } };
612 cbindgen_private::slint_windowrc_dispatch_event(handle: &inner.handle(), event: &event);
613 }
614
615 /// The window's scale factor has changed. This can happen for example when the display's
616 /// resolution changes, the user selects a new scale factor in the system settings, or the
617 /// window is moved to a different screen. Platform implementations should dispatch this event
618 /// also right after the initial window creation, to set the initial scale factor the windowing
619 /// system provided for the window.
620 void dispatch_scale_factor_change_event(float factor)
621 {
622 private_api::assert_main_thread();
623 using slint::cbindgen_private::WindowEvent;
624 WindowEvent event { .scale_factor_changed = WindowEvent::ScaleFactorChanged_Body {
625 .tag = WindowEvent::Tag::ScaleFactorChanged,
626 .scale_factor = factor } };
627 cbindgen_private::slint_windowrc_dispatch_event(handle: &inner.handle(), event: &event);
628 }
629
630 /// The Window was activated or de-activated.
631 ///
632 /// The backend should dispatch this event with true when the window gains focus
633 /// and false when the window loses focus.
634 void dispatch_window_active_changed_event(bool active)
635 {
636 private_api::assert_main_thread();
637 using slint::cbindgen_private::WindowEvent;
638 WindowEvent event { .window_active_changed = WindowEvent::WindowActiveChanged_Body {
639 .tag = WindowEvent::Tag::WindowActiveChanged, ._0 = active } };
640 cbindgen_private::slint_windowrc_dispatch_event(handle: &inner.handle(), event: &event);
641 }
642
643 /// The user requested to close the window.
644 ///
645 /// The backend should send this event when the user tries to close the window,for example by
646 /// pressing the close button.
647 ///
648 /// This will have the effect of invoking the callback set in Window::on_close_requested() and
649 /// then hiding the window depending on the return value of the callback.
650 void dispatch_close_requested_event()
651 {
652 private_api::assert_main_thread();
653 using slint::cbindgen_private::WindowEvent;
654 WindowEvent event { .tag = WindowEvent::Tag::CloseRequested };
655 cbindgen_private::slint_windowrc_dispatch_event(handle: &inner.handle(), event: &event);
656 }
657
658 /// Returns true if there is an animation currently active on any property in the Window.
659 bool has_active_animations() const
660 {
661 private_api::assert_main_thread();
662 return cbindgen_private::slint_windowrc_has_active_animations(handle: &inner.handle());
663 }
664
665 /// Takes a snapshot of the window contents and returns it as RGBA8 encoded pixel buffer.
666 ///
667 /// Note that this function may be slow to call as it may need to re-render the scene.
668 std::optional<SharedPixelBuffer<Rgba8Pixel>> take_snapshot() const
669 {
670 SharedPixelBuffer<Rgba8Pixel> result;
671 if (cbindgen_private::slint_windowrc_take_snapshot(&inner.handle(), &result.m_data,
672 &result.m_width, &result.m_height)) {
673 return result;
674 } else {
675 return {};
676 }
677 }
678
679 /// \private
680 private_api::WindowAdapterRc &window_handle() { return inner; }
681 /// \private
682 const private_api::WindowAdapterRc &window_handle() const { return inner; }
683
684private:
685 private_api::WindowAdapterRc inner;
686};
687
688}
689

source code of slint/api/cpp/include/slint_window.h