Fix rendering of the Qt platform example with high-dpi

- Provide a C++ platform event for the scale factor change and send it
- Report the correct logical and physical sizes to Slint
This commit is contained in:
Simon Hausmann 2023-05-24 15:33:37 +02:00 committed by Simon Hausmann
parent 459f810bd8
commit dd61890e23
3 changed files with 34 additions and 12 deletions

View file

@ -140,6 +140,15 @@ public:
} }
} }
/// Notifies the platform about a change in the device pixel ratio.
void dispatch_scale_factor_change_event(float factor)
{
private_api::assert_main_thread();
if (was_initialized) {
cbindgen_private::slint_windowrc_dispatch_scale_factor_change_event(&self, factor);
}
}
/// Returns true if the window is currently animating /// Returns true if the window is currently animating
bool has_active_animations() const bool has_active_animations() const
{ {

View file

@ -139,7 +139,7 @@ pub unsafe extern "C" fn slint_windowrc_has_active_animations(
window_adapter.window().has_active_animations() window_adapter.window().has_active_animations()
} }
/// Dispatch a key pressed or release event /// Dispatch resize event
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn slint_windowrc_dispatch_resize_event( pub unsafe extern "C" fn slint_windowrc_dispatch_resize_event(
handle: *const WindowAdapterRcOpaque, handle: *const WindowAdapterRcOpaque,
@ -152,6 +152,18 @@ pub unsafe extern "C" fn slint_windowrc_dispatch_resize_event(
}); });
} }
/// 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] #[no_mangle]
pub extern "C" fn slint_platform_update_timers_and_animations() { pub extern "C" fn slint_platform_update_timers_and_animations() {
i_slint_core::platform::update_timers_and_animations() i_slint_core::platform::update_timers_and_animations()

View file

@ -56,8 +56,7 @@ class MyWindow : public QWindow, public slint_platform::WindowAdapter
public: public:
MyWindow(QWindow *parentWindow = nullptr) : QWindow(parentWindow) MyWindow(QWindow *parentWindow = nullptr) : QWindow(parentWindow)
{ {
m_renderer.emplace(window_handle_for_qt_window(this), m_renderer.emplace(window_handle_for_qt_window(this), physical_size());
slint::PhysicalSize({ uint32_t(width()), uint32_t(height()) }));
} }
slint_platform::AbstractRenderer &renderer() override { return m_renderer.value(); } slint_platform::AbstractRenderer &renderer() override { return m_renderer.value(); }
@ -71,8 +70,7 @@ public:
{ {
slint_platform::update_timers_and_animations(); slint_platform::update_timers_and_animations();
auto windowSize = slint::PhysicalSize({ uint32_t(width()), uint32_t(height()) }); m_renderer->render(window(), physical_size());
m_renderer->render(window(), windowSize);
if (has_active_animations()) { if (has_active_animations()) {
requestUpdate(); requestUpdate();
@ -91,6 +89,8 @@ public:
void show() const override void show() const override
{ {
const_cast<WindowAdapter *>(static_cast<const WindowAdapter *>(this))
->dispatch_scale_factor_change_event(devicePixelRatio());
auto window = const_cast<QWindow *>(static_cast<const QWindow *>(this)); auto window = const_cast<QWindow *>(static_cast<const QWindow *>(this));
window->QWindow::show(); window->QWindow::show();
m_renderer->show(); m_renderer->show();
@ -102,21 +102,22 @@ public:
} }
slint::PhysicalSize physical_size() const override slint::PhysicalSize physical_size() const override
{ {
auto s = size(); auto windowSize = slint::LogicalSize({ float(width()), float(height()) });
return slint::PhysicalSize({ uint32_t(s.width()), uint32_t(s.height()) }); float scale_factor = devicePixelRatio();
return slint::PhysicalSize({ uint32_t(windowSize.width * scale_factor),
uint32_t(windowSize.height * scale_factor) });
} }
void request_redraw() const override { const_cast<MyWindow *>(this)->requestUpdate(); } void request_redraw() const override { const_cast<MyWindow *>(this)->requestUpdate(); }
void resizeEvent(QResizeEvent *ev) override void resizeEvent(QResizeEvent *ev) override
{ {
auto windowSize = slint::PhysicalSize( auto logicalSize = ev->size();
{ uint32_t(ev->size().width()), uint32_t(ev->size().height()) });
m_renderer->resize(windowSize);
float scale_factor = devicePixelRatio(); float scale_factor = devicePixelRatio();
m_renderer->resize(slint::PhysicalSize({ uint32_t(logicalSize.width() * scale_factor),
uint32_t(logicalSize.height() * scale_factor) }));
WindowAdapter::dispatch_resize_event( WindowAdapter::dispatch_resize_event(
slint::LogicalSize({ float(windowSize.width) / scale_factor, slint::LogicalSize({ float(logicalSize.width()), float(logicalSize.height()) }));
float(windowSize.height) / scale_factor }));
} }
void mousePressEvent(QMouseEvent *event) override void mousePressEvent(QMouseEvent *event) override