Fix rem support

After commit e04f028c91, the
default-font-size property on WindowItem isn't set anymore by default,
so BuiltinFunction::GetWindowDefaultFontSize, which reads it, would
return zero.

Instead, delegate to a run-time function where we can fall back to the
default from the renderer.

This patch changes rem.slint to use the newer syntax. The main change to
the test case though is to removal of the explicit default-font-size
property setting, so that we fall back to the value provided by the
renderer. This test relies on being run with the testing backend.

Fixes #8961
This commit is contained in:
Simon Hausmann 2025-08-18 16:00:58 +02:00 committed by Simon Hausmann
parent 007cfd26b9
commit 18740aa826
14 changed files with 57 additions and 23 deletions

View file

@ -563,7 +563,7 @@ fn gen_corelib(
"slint_windowrc_supports_native_menu_bar",
"slint_windowrc_setup_native_menu_bar",
"slint_windowrc_show_native_popup_menu",
"slint_windowrc_default_font_size",
"slint_windowrc_resolved_default_font_size",
"slint_windowrc_dispatch_pointer_event",
"slint_windowrc_dispatch_key_event",
"slint_windowrc_dispatch_event",

View file

@ -230,9 +230,9 @@ public:
cbindgen_private::slint_register_bitmap_font(&inner, &font);
}
inline float default_font_size() const
inline float resolved_default_font_size() const
{
return cbindgen_private::slint_windowrc_default_font_size(&inner);
return cbindgen_private::slint_windowrc_resolved_default_font_size(&inner);
}
/// \private

View file

@ -2400,6 +2400,16 @@ impl i_slint_core::renderer::RendererSealed for QtWindow {
Ok(())
}
fn default_font_size(&self) -> LogicalLength {
let default_font_size = cpp!(unsafe[] -> i32 as "int" {
return QFontInfo(qApp->font()).pixelSize();
});
// Ideally this would return the value from another property with a binding that's updated
// as a FontChange event is received. This is relevant for the case of using the Qt backend
// with a non-native style.
LogicalLength::new(default_font_size as f32)
}
fn free_graphics_resources(
&self,
component: ItemTreeRef,

View file

@ -235,6 +235,10 @@ impl RendererSealed for TestingWindow {
Ok(())
}
fn default_font_size(&self) -> LogicalLength {
LogicalLength::new(10.)
}
fn set_window_adapter(&self, _window_adapter: &Rc<dyn WindowAdapter>) {
// No-op since TestingWindow is also the WindowAdapter
}

View file

@ -3560,7 +3560,7 @@ fn compile_builtin_function_call(
format!("{}.scale_factor()", access_window_field(ctx))
}
BuiltinFunction::GetWindowDefaultFontSize => {
format!("{}.default_font_size()", access_window_field(ctx))
format!("{}.resolved_default_font_size()", access_window_field(ctx))
}
BuiltinFunction::AnimationTick => "slint::cbindgen_private::slint_animation_tick()".into(),
BuiltinFunction::Debug => {

View file

@ -3022,7 +3022,7 @@ fn compile_builtin_function_call(
}
BuiltinFunction::GetWindowDefaultFontSize => {
let window_adapter_tokens = access_window_adapter_field(ctx);
quote!(sp::WindowInner::from_pub(#window_adapter_tokens.window()).window_item().unwrap().as_pin_ref().default_font_size().get())
quote!(sp::WindowItem::resolved_default_font_size(&sp::WindowInner::from_pub(#window_adapter_tokens.window()).window_item_rc().unwrap()).get())
}
BuiltinFunction::AnimationTick => {
quote!(sp::animation_tick())

View file

@ -1325,6 +1325,11 @@ impl WindowItem {
}
}
pub fn resolved_default_font_size(self_rc: &ItemRc) -> LogicalLength {
Self::resolve_font_property(&self_rc, Self::font_size)
.unwrap_or_else(|| self_rc.window_adapter().unwrap().renderer().default_font_size())
}
fn resolve_font_property<T>(
self_rc: &ItemRc,
property_fn: impl Fn(Pin<&Self>) -> Option<T>,

View file

@ -118,6 +118,8 @@ pub trait RendererSealed {
fn set_window_adapter(&self, _window_adapter: &Rc<dyn WindowAdapter>);
fn default_font_size(&self) -> LogicalLength;
fn resize(&self, _size: crate::api::PhysicalSize) -> Result<(), PlatformError> {
Ok(())
}

View file

@ -883,6 +883,10 @@ impl RendererSealed for SoftwareRenderer {
self::fonts::systemfonts::register_font_from_path(path)
}
fn default_font_size(&self) -> LogicalLength {
self::fonts::DEFAULT_FONT_SIZE
}
fn set_window_adapter(&self, window_adapter: &Rc<dyn WindowAdapter>) {
*self.maybe_window_adapter.borrow_mut() = Some(Rc::downgrade(window_adapter));
self.partial_rendering_state.clear_cache();

View file

@ -1521,6 +1521,7 @@ pub mod ffi {
use crate::api::{RenderingNotifier, RenderingState, SetRenderingNotifierError};
use crate::graphics::Size;
use crate::graphics::{IntSize, Rgba8Pixel};
use crate::items::WindowItem;
use crate::SharedVector;
/// This enum describes a low-level access to specific graphics APIs used
@ -1900,11 +1901,12 @@ pub mod ffi {
/// Return the default-font-size property of the WindowItem
#[unsafe(no_mangle)]
pub unsafe extern "C" fn slint_windowrc_default_font_size(
pub unsafe extern "C" fn slint_windowrc_resolved_default_font_size(
handle: *const WindowAdapterRcOpaque,
) -> f32 {
let window_adapter = &*(handle as *const Rc<dyn WindowAdapter>);
window_adapter.window().0.window_item().unwrap().as_pin_ref().default_font_size().get()
WindowItem::resolved_default_font_size(&window_adapter.window().0.window_item_rc().unwrap())
.get()
}
/// Dispatch a key pressed or release event

View file

@ -22,7 +22,7 @@ use i_slint_compiler::namedreference::NamedReference;
use i_slint_compiler::object_tree::ElementRc;
use i_slint_core as corelib;
use i_slint_core::input::FocusReason;
use i_slint_core::items::ItemRc;
use i_slint_core::items::{ItemRc, WindowItem};
use smol_str::SmolStr;
use std::collections::HashMap;
use std::rc::Rc;
@ -432,7 +432,7 @@ fn call_builtin_function(
),
BuiltinFunction::GetWindowDefaultFontSize => {
Value::Number(local_context.component_instance.access_window(|window| {
window.window_item().unwrap().as_pin_ref().default_font_size().get()
WindowItem::resolved_default_font_size(&window.window_item_rc().unwrap()).get()
}) as _)
}
BuiltinFunction::AnimationTick => {

View file

@ -428,6 +428,10 @@ impl<B: GraphicsBackend> RendererSealed for FemtoVGRenderer<B> {
sharedfontdb::register_font_from_path(path)
}
fn default_font_size(&self) -> LogicalLength {
self::fonts::DEFAULT_FONT_SIZE
}
fn set_rendering_notifier(
&self,
callback: Box<dyn i_slint_core::api::RenderingNotifier>,

View file

@ -899,6 +899,10 @@ impl i_slint_core::renderer::RendererSealed for SkiaRenderer {
}
}
fn default_font_size(&self) -> LogicalLength {
self::textlayout::DEFAULT_FONT_SIZE
}
fn free_graphics_resources(
&self,
component: i_slint_core::item_tree::ItemTreeRef,

View file

@ -1,26 +1,25 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
global SomeGlobal := {
property<relative-font-size> global_rem: 4rem;
global SomeGlobal {
out property <relative-font-size> global_rem: 4rem;
}
TestCase := Window {
default-font-size: 10px;
property<length> normal: 1rem;
property<length> double: 2rem;
property<length> half: 0.5rem;
property <relative-font-size> four_rem: 4rem;
property<length> four: four_rem;
export component TestCase inherits Window {
out property <length> normal: 1rem;
out property <length> double: 2rem;
out property <length> half: 0.5rem;
out property <relative-font-size> four_rem: 4rem;
out property <length> four: four_rem;
property<physical-length> phys-pixel-size: 1rem;
out property <physical-length> phys-pixel-size: 1rem;
property <relative-font-size> px_to_rem: 20px;
property <relative-font-size> phx_to_rem: 20phx;
out property <relative-font-size> px_to_rem: 20px;
out property <relative-font-size> phx_to_rem: 20phx;
property <bool> cmp_test: normal < 1rem && double > 1rem;
out property <bool> cmp_test: normal < 1rem && double > 1rem;
property<bool> test:(normal == 10px && double == 20px && half == 5px && four_rem == 40px && SomeGlobal.global_rem == 40px && phys-pixel-size == 10phx && px_to_rem == 2rem);
out property <bool> test:(normal == 10px && double == 20px && half == 5px && four_rem == 40px && SomeGlobal.global_rem == 40px && phys-pixel-size == 10phx && px_to_rem == 2rem);
}
/*