Menu Extensibility #11381
Replies: 1 comment 2 replies
-
Thanks for the heads-up, @colin-grant-work. In the Arduino IDE, we want to preserve the menu structure of the previous IDE. That is, there are "label-only" menu items for grouping. I added an example to Theia here: 9a07349.
We have to try it out with vanilla Theia. If it works and makes the Theia customization more convenient, I do not have anything against breaking the current APIs. I wanted to avoid registering a command and making it permanently disabled to show a label-only menu item. If you have any concrete proposal I can try out, I am more than happy to do it. |
Beta Was this translation helpful? Give feedback.
-
At the moment, there are a number of cases in our menu system that refer to two concrete implementations of the
MenuNode
interface,ActionMenuNode
andCompositeMenuNode
, and pass off any otherMenuNode
to a default handler. For example:theia/packages/core/src/browser/menu/browser-menu-plugin.ts
Lines 121 to 134 in 7445e23
That's an odd sort of universal special-casing, and puts us in an awkward position, because if we want to introduce any new kind of behavior, we have to continue to special-case or inherit from those exact classes - downstream applications (may) rely on the fact that anything else, regardless of interface shape, is passed into the default handler. For example, if we want to have a different kind of menu node with children (as I do in this PR with
CompositeMenuNodeWrapper
), we can't use a check for.children
and then handle it as equivalent to aCompositeMenuNode
because that might break a hypotheticalDownstreamCompositeMenuNode
that has.children
but doesn't inherit fromCompositeMenuNode
and so goes into the default handler. Instead we'd have to implement a classOtherUpstreamCompositeMenuNode
and checknode instanceof CompositeMenuNode || node instanceof OtherUpstreamCompositeMenuNode
. It's not impossible to maintain, but it's inconvenient and points to the fragility of relying on concrete implementations andinstanceof
checks. It also violates the principle that any downstream override should have higher priority than the upstream implementation: here the upstream implementation ofregisterMenu
(and the other methods with this structure) runs almost in its entirety before the method intended to serve as the override runs at all.@kittaakos, it looks like you did some of the work that added the
handleDefault
option. Can you give a sense of the concrete use cases you were aiming to support and whether there might be other ways to get there?For example, rather than overriding the
defaultHandler
, would it be possible to achieve the same result with something like (for the method above)Beta Was this translation helpful? Give feedback.
All reactions