mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 18:58:36 +00:00
Some improvements to Window visibility
- From C++, always call the Window::show() and hide() function instead of going through set_visible directly as it doesn't set the size of the WindowItem - show() should also call resize on the renderer - remove the is_visible in the WindowAdapterInternal as it is no longer needed
This commit is contained in:
parent
1721b2d1be
commit
fde561a56a
8 changed files with 30 additions and 45 deletions
|
@ -492,7 +492,7 @@ declare_types! {
|
|||
let this = cx.this();
|
||||
let window = cx.borrow(&this, |x| x.0.as_ref().cloned());
|
||||
let window_adapter = window.ok_or(()).or_else(|()| cx.throw_error("Invalid type"))?;
|
||||
window_adapter.set_visible(true).unwrap();
|
||||
window_adapter.window().show().unwrap();
|
||||
Ok(JsUndefined::new().as_value(&mut cx))
|
||||
}
|
||||
|
||||
|
@ -500,7 +500,7 @@ declare_types! {
|
|||
let this = cx.this();
|
||||
let window = cx.borrow(&this, |x| x.0.as_ref().cloned());
|
||||
let window_adapter = window.ok_or(()).or_else(|()| cx.throw_error("Invalid type"))?;
|
||||
window_adapter.set_visible(false).unwrap();
|
||||
window_adapter.window().hide().unwrap();
|
||||
Ok(JsUndefined::new().as_value(&mut cx))
|
||||
}
|
||||
|
||||
|
|
|
@ -1802,13 +1802,6 @@ impl WindowAdapterInternal for QtWindow {
|
|||
});
|
||||
ds.as_ref().get()
|
||||
}
|
||||
|
||||
fn is_visible(&self) -> bool {
|
||||
let widget_ptr = self.widget_ptr();
|
||||
cpp! {unsafe [widget_ptr as "QWidget*"] -> bool as "bool" {
|
||||
return widget_ptr->isVisible();
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
impl i_slint_core::renderer::RendererSealed for QtWindow {
|
||||
|
|
|
@ -28,8 +28,7 @@ impl i_slint_core::platform::Platform for TestingBackend {
|
|||
) -> Result<Rc<dyn WindowAdapter>, i_slint_core::platform::PlatformError> {
|
||||
Ok(Rc::new_cyclic(|self_weak| TestingWindow {
|
||||
window: i_slint_core::api::Window::new(self_weak.clone() as _),
|
||||
shown: false.into(),
|
||||
size: Default::default(),
|
||||
size: PhysicalSize::new(600, 800).into(),
|
||||
ime_requests: Default::default(),
|
||||
}))
|
||||
}
|
||||
|
@ -78,7 +77,6 @@ impl i_slint_core::platform::Platform for TestingBackend {
|
|||
|
||||
pub struct TestingWindow {
|
||||
window: i_slint_core::api::Window,
|
||||
shown: core::cell::Cell<bool>,
|
||||
size: core::cell::Cell<PhysicalSize>,
|
||||
pub ime_requests: RefCell<Vec<InputMethodRequest>>,
|
||||
}
|
||||
|
@ -88,10 +86,6 @@ impl WindowAdapterInternal for TestingWindow {
|
|||
self
|
||||
}
|
||||
|
||||
fn is_visible(&self) -> bool {
|
||||
self.shown.get()
|
||||
}
|
||||
|
||||
fn input_method_request(&self, request: i_slint_core::window::InputMethodRequest) {
|
||||
self.ime_requests.borrow_mut().push(request)
|
||||
}
|
||||
|
@ -102,11 +96,6 @@ impl WindowAdapter for TestingWindow {
|
|||
&self.window
|
||||
}
|
||||
|
||||
fn set_visible(&self, visible: bool) -> Result<(), PlatformError> {
|
||||
self.shown.set(visible);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn size(&self) -> PhysicalSize {
|
||||
self.size.get()
|
||||
}
|
||||
|
|
|
@ -662,10 +662,6 @@ impl WindowAdapterInternal for WinitWindowAdapter {
|
|||
.get()
|
||||
}
|
||||
|
||||
fn is_visible(&self) -> bool {
|
||||
self.winit_window().is_visible().unwrap_or(true)
|
||||
}
|
||||
|
||||
#[cfg(enable_accesskit)]
|
||||
fn handle_focus_change(&self, _old: Option<ItemRc>, _new: Option<ItemRc>) {
|
||||
self.accesskit_adapter.handle_focus_item_change();
|
||||
|
|
|
@ -524,11 +524,7 @@ impl Window {
|
|||
/// Returns the visibility state of the window. This function can return false even if you previously called show()
|
||||
/// on it, for example if the user minimized the window.
|
||||
pub fn is_visible(&self) -> bool {
|
||||
self.0
|
||||
.window_adapter()
|
||||
.internal(crate::InternalToken)
|
||||
.map(|w| w.is_visible())
|
||||
.unwrap_or(false)
|
||||
self.0.is_visible()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -200,12 +200,6 @@ pub trait WindowAdapterInternal {
|
|||
fn dark_color_scheme(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Get the visibility of the window
|
||||
// todo: replace with WindowEvent::VisibilityChanged and require backend to dispatch event
|
||||
fn is_visible(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// This is the parameter from [`WindowAdapterInternal::input_method_request()`] which lets the editable text input field
|
||||
|
@ -349,7 +343,8 @@ struct WindowPinnedFields {
|
|||
pub struct WindowInner {
|
||||
window_adapter_weak: Weak<dyn WindowAdapter>,
|
||||
component: RefCell<ComponentWeak>,
|
||||
strong_component_ref: RefCell<Option<ComponentRc>>, // When the window is visible, keep a strong reference
|
||||
/// When the window is visible, keep a strong reference
|
||||
strong_component_ref: RefCell<Option<ComponentRc>>,
|
||||
mouse_input_state: Cell<MouseInputState>,
|
||||
pub(crate) modifiers: Cell<InternalKeyboardModifierState>,
|
||||
|
||||
|
@ -782,10 +777,9 @@ impl WindowInner {
|
|||
self.window_adapter().set_visible(true)?;
|
||||
// Make sure that the window's inner size is in sync with the root window item's
|
||||
// width/height.
|
||||
self.set_window_item_geometry(
|
||||
self.window_adapter().size().to_logical(self.scale_factor()).to_euclid(),
|
||||
);
|
||||
|
||||
let size = self.window_adapter().size();
|
||||
self.set_window_item_geometry(size.to_logical(self.scale_factor()).to_euclid());
|
||||
self.window_adapter().renderer().resize(size).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -919,6 +913,11 @@ impl WindowInner {
|
|||
self.pinned_fields.text_input_focused.set(value)
|
||||
}
|
||||
|
||||
/// Returns true if the window is visible
|
||||
pub fn is_visible(&self) -> bool {
|
||||
self.strong_component_ref.borrow().is_some()
|
||||
}
|
||||
|
||||
/// Returns the window item that is the first item in the component.
|
||||
pub fn window_item(&self) -> Option<VRcMapped<ComponentVTable, crate::items::WindowItem>> {
|
||||
self.try_component().and_then(|component_rc| {
|
||||
|
@ -1025,14 +1024,14 @@ pub mod ffi {
|
|||
pub unsafe extern "C" fn slint_windowrc_show(handle: *const WindowAdapterRcOpaque) {
|
||||
let window_adapter = &*(handle as *const Rc<dyn WindowAdapter>);
|
||||
|
||||
window_adapter.set_visible(true).unwrap();
|
||||
window_adapter.window().show().unwrap();
|
||||
}
|
||||
|
||||
/// Spins an event loop and renders the items of the provided component in this window.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn slint_windowrc_hide(handle: *const WindowAdapterRcOpaque) {
|
||||
let window_adapter = &*(handle as *const Rc<dyn WindowAdapter>);
|
||||
window_adapter.set_visible(false).unwrap();
|
||||
window_adapter.window().hide().unwrap();
|
||||
}
|
||||
|
||||
/// Returns the visibility state of the window. This function can return false even if you previously called show()
|
||||
|
@ -1042,7 +1041,7 @@ pub mod ffi {
|
|||
handle: *const WindowAdapterRcOpaque,
|
||||
) -> bool {
|
||||
let window = &*(handle as *const Rc<dyn WindowAdapter>);
|
||||
window.internal(crate::InternalToken).map_or(false, |w| w.is_visible())
|
||||
window.window().is_visible()
|
||||
}
|
||||
|
||||
/// Returns the window scale factor.
|
||||
|
|
|
@ -561,7 +561,10 @@ pub extern "C" fn slint_interpreter_component_instance_show(
|
|||
) {
|
||||
generativity::make_guard!(guard);
|
||||
let comp = inst.unerase(guard);
|
||||
comp.borrow_instance().window_adapter().set_visible(is_visible).unwrap();
|
||||
match is_visible {
|
||||
true => comp.borrow_instance().window_adapter().window().show().unwrap(),
|
||||
false => comp.borrow_instance().window_adapter().window().hide().unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a window for the component
|
||||
|
|
|
@ -169,6 +169,7 @@ Hello := Rectangle {
|
|||
|
||||
property <string> arrow_down_commands: "M21.8,311.1l84.2-82.1c15.7-15.2,41-15.2,56.7,0l341.1,304.1l333.7-297.5c15.5-15.2,41-15.2,56.6,0l84.3,82.1c15.6,15.2,15.6,40,0,55.2L531.7,771c-15.7,15.3-41,15.3-56.7,0l-6.9-6.7L21.8,366.3C6.1,351,6.1,326.3,21.8,311.1z";
|
||||
property <string> funky_shape_commands: "M 100 300 Q 150 50 250 150 C 250 300 300 300 300 450 A 50 50 0 1 0 450 450 L 550 300";
|
||||
property <length> width2 <=> root.width;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -177,8 +178,12 @@ Hello := Rectangle {
|
|||
auto handle = Hello::create();
|
||||
const Hello &instance = *handle;
|
||||
assert(!instance.window().is_visible());
|
||||
assert_eq(instance.get_width2(), 0); //Before it is shown, no size is set
|
||||
instance.window().show();
|
||||
assert(instance.window().is_visible());
|
||||
assert(instance.get_width2() > 0); // default size from the backend
|
||||
instance.window().set_size(slint::LogicalSize({123., 456.}));
|
||||
assert_eq(instance.get_width2(), 123.);
|
||||
instance.window().hide();
|
||||
assert(!instance.window().is_visible());
|
||||
```
|
||||
|
@ -187,8 +192,12 @@ assert(!instance.window().is_visible());
|
|||
```rust
|
||||
let instance = Hello::new().unwrap();
|
||||
assert!(!instance.window().is_visible());
|
||||
assert_eq!(instance.get_width2(), 0.);
|
||||
instance.window().show().unwrap();
|
||||
assert!(instance.window().is_visible());
|
||||
assert!(instance.get_width2() > 0.); // default size from the backend
|
||||
instance.window().set_size(slint::LogicalSize::new(123., 456.));
|
||||
assert_eq!(instance.get_width2(), 123.);
|
||||
instance.window().hide().unwrap();
|
||||
assert!(!instance.window().is_visible());
|
||||
```
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue