Make WindowAdaptor::request_redraw public

This commit is contained in:
Olivier Goffart 2023-06-13 17:30:38 +02:00 committed by Olivier Goffart
parent ff6653c77e
commit 4dd10f4a78
7 changed files with 39 additions and 59 deletions

View file

@ -56,6 +56,10 @@ impl WindowAdapter for CppWindowAdapter {
fn internal(&self, _: i_slint_core::InternalToken) -> Option<&dyn WindowAdapterInternal> { fn internal(&self, _: i_slint_core::InternalToken) -> Option<&dyn WindowAdapterInternal> {
Some(self) Some(self)
} }
fn request_redraw(&self) {
unsafe { (self.request_redraw)(self.user_data) }
}
} }
impl WindowAdapterInternal for CppWindowAdapter { impl WindowAdapterInternal for CppWindowAdapter {
@ -67,10 +71,6 @@ impl WindowAdapterInternal for CppWindowAdapter {
unsafe { (self.hide)(self.user_data) } unsafe { (self.hide)(self.user_data) }
Ok(()) Ok(())
} }
fn request_redraw(&self) {
unsafe { (self.request_redraw)(self.user_data) }
}
} }
#[no_mangle] #[no_mangle]

View file

@ -1562,6 +1562,13 @@ impl WindowAdapter for QtWindow {
i_slint_core::api::PhysicalSize::new(s.width as _, s.height as _) i_slint_core::api::PhysicalSize::new(s.width as _, s.height as _)
} }
fn request_redraw(&self) {
let widget_ptr = self.widget_ptr();
cpp! {unsafe [widget_ptr as "QWidget*"] {
return widget_ptr->update();
}}
}
fn internal(&self, _: i_slint_core::InternalToken) -> Option<&dyn WindowAdapterInternal> { fn internal(&self, _: i_slint_core::InternalToken) -> Option<&dyn WindowAdapterInternal> {
Some(self) Some(self)
} }
@ -1611,13 +1618,6 @@ impl WindowAdapterInternal for QtWindow {
Ok(()) Ok(())
} }
fn request_redraw(&self) {
let widget_ptr = self.widget_ptr();
cpp! {unsafe [widget_ptr as "QWidget*"] {
return widget_ptr->update();
}}
}
/// Apply windows property such as title to the QWidget* /// Apply windows property such as title to the QWidget*
fn apply_window_properties(&self, window_item: Pin<&items::WindowItem>) { fn apply_window_properties(&self, window_item: Pin<&items::WindowItem>) {
let widget_ptr = self.widget_ptr(); let widget_ptr = self.widget_ptr();

View file

@ -309,17 +309,17 @@ impl WindowAdapter for WinitWindowAdapter {
physical_size_to_slint(&self.winit_window().inner_size()) physical_size_to_slint(&self.winit_window().inner_size())
} }
fn request_redraw(&self) {
self.pending_redraw.set(true);
self.with_window_handle(&mut |window| window.request_redraw())
}
fn internal(&self, _: corelib::InternalToken) -> Option<&dyn WindowAdapterInternal> { fn internal(&self, _: corelib::InternalToken) -> Option<&dyn WindowAdapterInternal> {
Some(self) Some(self)
} }
} }
impl WindowAdapterInternal for WinitWindowAdapter { impl WindowAdapterInternal for WinitWindowAdapter {
fn request_redraw(&self) {
self.pending_redraw.set(true);
self.with_window_handle(&mut |window| window.request_redraw())
}
fn apply_window_properties(&self, window_item: Pin<&i_slint_core::items::WindowItem>) { fn apply_window_properties(&self, window_item: Pin<&i_slint_core::items::WindowItem>) {
let winit_window = self.winit_window(); let winit_window = self.winit_window();

View file

@ -394,9 +394,7 @@ impl Window {
/// This function issues a request to the windowing system to redraw the contents of the window. /// This function issues a request to the windowing system to redraw the contents of the window.
pub fn request_redraw(&self) { pub fn request_redraw(&self) {
if let Some(x) = self.0.window_adapter().internal(crate::InternalToken) { self.0.window_adapter().request_redraw()
x.request_redraw()
}
} }
/// This function returns the scale factor that allows converting between logical and /// This function returns the scale factor that allows converting between logical and

View file

@ -18,7 +18,7 @@ use crate::lengths::{
}; };
use crate::renderer::{Renderer, RendererSealed}; use crate::renderer::{Renderer, RendererSealed};
use crate::textlayout::{AbstractFont, FontMetrics, TextParagraphLayout}; use crate::textlayout::{AbstractFont, FontMetrics, TextParagraphLayout};
use crate::window::{WindowAdapter, WindowAdapterInternal, WindowInner}; use crate::window::{WindowAdapter, WindowInner};
use crate::{Brush, Color, Coord, ImageInner, StaticTextures}; use crate::{Brush, Color, Coord, ImageInner, StaticTextures};
use alloc::rc::{Rc, Weak}; use alloc::rc::{Rc, Weak};
use alloc::{vec, vec::Vec}; use alloc::{vec, vec::Vec};
@ -2012,19 +2012,6 @@ impl MinimalSoftwareWindow {
} }
} }
impl WindowAdapterInternal for MinimalSoftwareWindow {
fn request_redraw(&self) {
self.needs_redraw.set(true);
}
fn unregister_component<'a>(
&self,
_component: crate::component::ComponentRef,
_items: &mut dyn Iterator<Item = Pin<crate::items::ItemRef<'a>>>,
) {
}
}
impl WindowAdapter for MinimalSoftwareWindow { impl WindowAdapter for MinimalSoftwareWindow {
fn window(&self) -> &Window { fn window(&self) -> &Window {
&self.window &self.window
@ -2043,8 +2030,8 @@ impl WindowAdapter for MinimalSoftwareWindow {
.dispatch_event(crate::platform::WindowEvent::Resized { size: size.to_logical(1.) }) .dispatch_event(crate::platform::WindowEvent::Resized { size: size.to_logical(1.) })
} }
fn internal(&self, _: crate::InternalToken) -> Option<&dyn WindowAdapterInternal> { fn request_redraw(&self) {
Some(self) self.needs_redraw.set(true);
} }
} }

View file

@ -92,6 +92,18 @@ pub trait WindowAdapter {
/// Return the size of the Window on the screen /// Return the size of the Window on the screen
fn size(&self) -> PhysicalSize; fn size(&self) -> PhysicalSize;
/// Issues a request to the windowing system to re-render the contents of the window.
///
/// This request is typically asynchronous.
/// It is called when a property that was used during window rendering is marked as dirty.
///
/// An implementation should simply post an event and perform the drawing in a subsequent iteration of the event loop.
/// It is important not to query any Slint properties to avoid introducing a dependency loop in the properties,
/// including the use of the render function, which itself queries properties.
///
/// See also [`Window::request_redraw()`]
fn request_redraw(&self) {}
/// Return the renderer. /// Return the renderer.
/// ///
/// The `Renderer` trait is an internal trait that you are not expected to implement. /// The `Renderer` trait is an internal trait that you are not expected to implement.
@ -127,12 +139,6 @@ pub trait WindowAdapterInternal {
Ok(()) Ok(())
} }
/// Issue a request to the windowing system to re-render the contents of the window. This is typically an asynchronous
/// request.
// TODO: make public, but document clearly that an implementation cannot query other properties, etc. - we call it from
// a property tracker.
fn request_redraw(&self) {}
/// This function is called by the generated code when a component and therefore its tree of items are created. /// This function is called by the generated code when a component and therefore its tree of items are created.
fn register_component(&self) {} fn register_component(&self) {}
@ -245,9 +251,7 @@ struct WindowRedrawTracker {
impl crate::properties::PropertyDirtyHandler for WindowRedrawTracker { impl crate::properties::PropertyDirtyHandler for WindowRedrawTracker {
fn notify(&self) { fn notify(&self) {
if let Some(window_adapter) = self.window_adapter_weak.upgrade() { if let Some(window_adapter) = self.window_adapter_weak.upgrade() {
if let Some(window_adapter) = window_adapter.internal(crate::InternalToken) { window_adapter.request_redraw();
window_adapter.request_redraw();
}
}; };
} }
} }
@ -377,9 +381,7 @@ impl WindowInner {
default_font_size_prop.set(window_adapter.renderer().default_font_size()); default_font_size_prop.set(window_adapter.renderer().default_font_size());
} }
} }
if let Some(window_adapter) = window_adapter.internal(crate::InternalToken) { window_adapter.request_redraw();
window_adapter.request_redraw();
}
let weak = Rc::downgrade(&window_adapter); let weak = Rc::downgrade(&window_adapter);
crate::timers::Timer::single_shot(Default::default(), move || { crate::timers::Timer::single_shot(Default::default(), move || {
if let Some(window_adapter) = weak.upgrade() { if let Some(window_adapter) = weak.upgrade() {
@ -538,10 +540,10 @@ impl WindowInner {
/// Sets the focus to the item pointed to by item_ptr. This will remove the focus from any /// Sets the focus to the item pointed to by item_ptr. This will remove the focus from any
/// currently focused item. /// currently focused item.
pub fn set_focus_item(&self, focus_item: &ItemRc) { pub fn set_focus_item(&self, focus_item: &ItemRc) {
let old = self.take_focus_item();
let new = self.move_focus(focus_item.clone(), next_focus_item);
let window_adapter = self.window_adapter(); let window_adapter = self.window_adapter();
if let Some(window_adapter) = window_adapter.internal(crate::InternalToken) { if let Some(window_adapter) = window_adapter.internal(crate::InternalToken) {
let old = self.take_focus_item();
let new = self.move_focus(focus_item.clone(), next_focus_item);
window_adapter.handle_focus_change(old, new); window_adapter.handle_focus_change(old, new);
} }
} }
@ -808,9 +810,7 @@ impl WindowInner {
.and_then(|x| x.create_popup(LogicalRect::new(position, size))) .and_then(|x| x.create_popup(LogicalRect::new(position, size)))
{ {
None => { None => {
if let Some(x) = self.window_adapter().internal(crate::InternalToken) { self.window_adapter().request_redraw();
x.request_redraw();
}
PopupWindowLocation::ChildWindow(position) PopupWindowLocation::ChildWindow(position)
} }
@ -842,9 +842,7 @@ impl WindowInner {
if !popup_region.is_empty() { if !popup_region.is_empty() {
let window_adapter = self.window_adapter(); let window_adapter = self.window_adapter();
window_adapter.renderer().mark_dirty_region(popup_region.to_box2d()); window_adapter.renderer().mark_dirty_region(popup_region.to_box2d());
if let Some(window_adapter) = window_adapter.internal(crate::InternalToken) { window_adapter.request_redraw();
window_adapter.request_redraw();
}
} }
} }
} }
@ -1183,9 +1181,7 @@ pub mod ffi {
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn slint_windowrc_request_redraw(handle: *const WindowAdapterRcOpaque) { pub unsafe extern "C" fn slint_windowrc_request_redraw(handle: *const WindowAdapterRcOpaque) {
let window_adapter = &*(handle as *const Rc<dyn WindowAdapter>); let window_adapter = &*(handle as *const Rc<dyn WindowAdapter>);
if let Some(window_adapter) = window_adapter.internal(crate::InternalToken) { window_adapter.request_redraw();
window_adapter.request_redraw();
}
} }
/// Returns the position of the window on the screen, in physical screen coordinates and including /// Returns the position of the window on the screen, in physical screen coordinates and including

View file

@ -16,7 +16,6 @@ use i_slint_core::{
platform::PlatformError, platform::PlatformError,
renderer::RendererSealed, renderer::RendererSealed,
software_renderer::{LineBufferProvider, MinimalSoftwareWindow}, software_renderer::{LineBufferProvider, MinimalSoftwareWindow},
window::WindowAdapterInternal,
}; };
pub struct SwrTestingBackend { pub struct SwrTestingBackend {