slint
slint copied to clipboard
PopupWindow: Misleading error trying to access sub-component from another component
Given following:
export component Main2 inherits Window {
about_window := PopupWindow {
width: min(ui.preferred-width, root.width - 80px);
}
config_window := PopupWindow {
x: 100px;
y: 100px;
width: min(ui.preferred-width, root.width - 80px);
close-on-click: false;
Rectangle {
border-color: grey;
border-width: 1px;
background: grey;
}
ui := VerticalBox {
height: 100%;
width: 100%;
}
}
}
slint-build produces misleading error:
--- stderr
error: Cannot access the inside of a PopupWindow from enclosing component
--> /Users/artur.m/repos/work/evp-vehicle-authentication-service/identity-demo/ui/main.slint:312:22
|
312 | config_window := PopupWindow {
| ^
This error happens because I tried to access ui component, declared in config_window from within about_window
Thanks for filling an issue.
This is indeed a bad limitation of the PopupWindow. See the FIXME comment in https://github.com/slint-ui/slint/blob/d67f0de80815b1bf3808a4f142aea84cd196d813/internal/compiler/passes/lower_popups.rs#L106-L110 The problem is that in that part of the code we no longer know what is the span of the reference. (We probably should store it in Expression::PropertyReference and pass it along, there are other error that would benefit from that)
We could try to make it work to access these properties by moving the properties from the popup ItemTree to the parent SubComponent. But that's difficult for the properties in "native" items.
In general, the PopupWindow has many design issue. See the meta issue https://github.com/slint-ui/slint/issues/1143
Oh I see. I thought it should not be allowed to access another window's properties from withing different window. But I'm not sure what are scoping rules in slint markup language.
Is it expected for all declarations to be global within root component? I would honestly expect it to be restricted to access one sub-component from another one 🤔
Another idea would perhaps be to detect this situation (that properties from a PopupWindow are referenced from the outside) and then compile it in a way that the PopupWindow component is already instantiated. (That means 'init' will be called only once, instead of on every show() though).