Creating a MenuBar::visible property#11272
Conversation
This allows a menu bar to be invisible, but also to have menu shortcuts to function properly. This is incomplete; when we're doing menus with the `muda` crate, the `visible` property is not honored
…e to honor it Notes - Documentation added to `menubar.mdx` - Nothing is setting this property yet
|
@LeonMatthes i'm curious what can be done to pull this over the finish line. This works for the non-native menubar, but doesn't work correctly for Winit. It isn't clear to me how to properly plumb changes to the Thoughts? |
|
At first glance it appears that I have all of the correct plumbing in place, with the exception that we fail to call |
|
Hi @npwoods . Because currently the visible property will always be set to true for the native menu. It queries that data out of the menu from item tree and the menu from item tree as the name suggests must get the menu data points out of an instantiated item tree. It's sort of an adapter between the Slint item tree and the native menu bar items. So take a look at the |
|
Findings:
Of course, this is assuming that I'm not completely off base. |
|
You will probably have to call update_from_shadow_tree in the But at the moment, that won't currently evalute the closure passed to But you're right that likely you have to pass the visible property to the SetupMenubar function. So that we don't get an explosion of |
…o Rust as well as the interpreter
|
I think I got something that works! Some misgivings/concerns:
I trust the audience of this PR will be able to evaluate this work. |
MenuBar::visible propertyMenuBar::visible property
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #11272 +/- ##
=========================================
Coverage ? 73.07%
=========================================
Files ? 98
Lines ? 29086
Branches ? 0
=========================================
Hits ? 21255
Misses ? 7831
Partials ? 0
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
LeonMatthes
left a comment
There was a problem hiding this comment.
Hey @npwoods , this looks good, you just need to adjust the interpreter and C++ generator to use the same basic approach.
With your current approach of pushing BoolLiteral(true), we could also consider using fn()->bool instead of Option<fn() -> bool> to reduce the special casing. I'll leave that decision up to you.
1. I still don't quite understand how properties seem to be magically tracked when `evaluate_if_dirty()` is invoked; I could be Cargo Culting
When Slint is evaluating a binding, it will set a thread local variable to indicate, we're now evaluating the binding for this property. And then all other properties that are accessed when evaluating the binding are automatically marked as dependencies of the current binding.
This is also how bindings are implemented in the slint language itself. They just boil down to Rust properties. They are implemented in properties.rs if you're interested in the code.
2. I'm not particularly crazy about parameterizing `Option::None` with `<fn() -> bool>`
I don't really see a problem with this, as long as we can make it work with C++.
As we're now always pushing the string literals onto the argument list, we could alternatively just make it a fn()->bool and just have that evaluate the bool literal.
3. Is pushing `Expression::BoolLiteral(true)` the correct thing to do if `condition` or `visible` is not specified?>
yes, visible defaults to true, that's fine.
4. I have not touched the C++ generator
This will of course need to be implemented before we can merge this :)
Are you comfortable implementing the C++ side as well?
|
Pushed some updates!
If you guys are comfortable with this, I am too ;-)
I'm comfortable attempting to do so; hence my latest push. But full disclosure - I'm cargo-culting it.
I suppose that I could update the various handlers for |
Yes, they would still need to be lambdas, but no longer optional. Let's give this a try without the optionals, that feels much cleaner than having to special case a specific literal for saving a small property allocation. |
…and_visible()` (that does not take `Option`) and creating separate `MenuFromItemTree::new()` that does not take `condition` and `visible`
|
Sounds good - committed something 🤞 I don't really like the dummy lambdas that need to be present to serve other scenarios like the system tray; LMK how you want this handled |
|
Good catch - I believe I fixed it |
LeonMatthes
left a comment
There was a problem hiding this comment.
Hey @npwoods ,
this looks good to me now implementation-wise 🙌
Can you please add a test for this in both Rust and C++?
Maybe a test that checks that a menubar accepts a shortcut if it is visible, then make it invisible, test that the window now has a larger inner size (as the menubar has disappeared), and that the shortcut still works.
Either add it in tests/cases/elements/menubar_shortcut.slint directly, or in a new test file for the visible property.
LeonMatthes
left a comment
There was a problem hiding this comment.
Thank you for the contribution @npwoods :)
This allows a menu bar to be invisible, but also to have menu shortcuts to function properly.
This is incomplete; when we're doing menus with the
mudacrate, thevisibleproperty is not honored.For
mudato be supported, it looks like some additional plumbing would have to happen ininternal/core/window.rsassetup_menubar()is passed avtable::VRc<MenuVTable>, and after lowering themenubar-visibleproperty is onMenuBarImpl. While I'm not an expert here, it looks like something more substantial would need to be passed tosetup_menubar()as it is not just necessary to pass the property, but the facilities required to respond to changes.