Hi Boris,
thanks for sharing your ideas. In fact, they are very much in line with my current ambitions.
First, given that we have the dynamic init now, I wholeheartedly agree to relieve the existing interactive application starters (launcher, CLI monitor) from the technicalities of hosting subsystems. They should instead merely generate and update init configurations, and consume init-state reports.
Second, I definitely aim to cultivate the clean separation of the presentation and the application logic. The existing launcher already anticipates this direction. The complex rendering of dialogs or visual gimmicks like fading are implemented in the form of sandboxed menu_view or nit_fader components. The launcher merely ties those components together but does not perform any complex rendering or parsing operations. That said, in contrast to the menu_view, the current launcher is not meant to stay. As of now, it is more of an experimentation ground.
In order to shape this, we have the following ideas:
- The configuration of the menu model can be specified in XML in its
config, and be reconfigurable at runtime. Parts of this could be defined by other components as well. Examples of how this could look like is described in the attached xml file.
This is actually very similar to what the existing menu_view already gives you. It consumes a description of a dialog, and produces reports about the currently hovered item. It does not implement any program logic.
As far as I see, your menu differs from the existing menu_view in two ways:
* It introduces a form of abstraction because its dialog description talks about semantics of a menu rather than dumb UI elements (frame, label, button, hbox).
* It handles multiple dialogs (sub menus).
- Events related to the menu either trigger menu actions (in which
case the config dictates the proper response, such as showing or hiding a submenu) or trigger external actions. In the second case, the menu generates a report that for instance states a certain button has been clicked. Again, see the attachment.
I'd advise not to use the report/ROM interface to propagate events, but only state. Even though one (myself included) is sometimes intuitively tempted to mix up events and states, it calls for trouble.
In contrast to intermediate states, which are uninteresting (because superseded by more current states) and thereby can be dropped, events must never be dropped. So reporting a mouse click in the form of a report is not the right approach. In contrast, reporting the currently hovered element as a report is fine. For this reason, the existing launcher intercepts the user input of the menu view to get hold of the important input events.
This also applies for other operations like hiding/showing windows. Instead of communicating commands like (hide this, show that) between components, we should communicate states (the set of hidden windows).
The design of the window manager pretty much adheres to this principle. E.g., if a window is moved, we do not propagate the event (window has moved) but the new state (the new window layout). In contrast, nitpicker's 'session_control' interface does not (see below).
- Any (custom) component can read these reports and take certain
actions. For example, in case programs are to be started with the menu, we can add an init component that takes its config from another rom module. A subsystem management component containing a more extensive state model would read the events from the menu, change init's config based on this, and monitor the state of started subsystems and perhaps add extra context menus for these subsystems.
I see the same picture. There will be one component (you may call it subsystem manager) that will actually hold all the important strings, including the configuration of the dynamic init instance that hosts the dynamically created subsystems.
This raises the question of where does the responsibility of the menu end, and where do the responsibilities of the subsystem manager start? If we need a subsystem manager anyway, couldn't it use the menu_view(s) directly to implement menus?
The answer may depend on the complexity of the subsystem manager, which is obviously critical. Does the separation of the menu from the subsystem manager contribute to significantly lower the TCB of the subsystem manager?
When following this line of thinking, we might even end up integrating the window layouter + menu + subsystem manager in a single "desktop" component.
Another example is a shutdown button that talks to a component that can write the system state, and which could show a dialog with the options to power off or reset a systems. Perhaps it can try to gracefully stop running programs with disk state (such as virtualbox) by talking with the subsystem manager as explained above. In any case, the menu should be able to support any functionality by providing a generic interface to components such as the examples above.
These points are also closely related to the "subsystem manager", which controls the life cycle of subsystems or even the entire system. As the menu and subsystem manager are so closely related, I would intuitively tend to integrate both into a single component.
While looking at ways to implement this, we also encountered the following problems:
-As it is currently with launcher, a lot of subsystem functionality is intertwined with the interactive menu. This makes implementing such a modification a bit more difficult than replacing the subsystem management part with a reporting part. One of the issues we face is that showing and hiding windows of other components is done through the session_control function in the nitpicker session interface, but this is limited to the session of the components and its children. Children of an init component therefore cannot be affected.
The launcher in its current form is not here to stay. Some parts of its implementation may be worth reusing (e.g., the fading dialog). But its role of a runtime environment for subsystems is no more needed. Also the use of nitpicker's session-control interface should be eliminated.
When I created the launcher, I foresaw a mix of nitpicker-based (like rdesktop) and wm-based applications. The only way to manage the focus of applications of both categories was to use a nitpicker mechanism. In the meanwhile, I reached the conclusion that all regular applications of a desktop scenario should talk to the wm. Thereby, the input focus, visibility, and layout of the applications are subjected to the window layouter's policy. The show/hide toggling of applications via the menu should result in a hidden-applications report to be consumed by the layouter.
This leaves the question about the input focus. When using the wm, the focus is already defined by the window layouter via the 'focus' ROM. The window layouter, in turn, already consumes a 'focus_request' ROM to respond to externally triggered focus changes. This would be the right hook for the menu / subsystem manager.
One way to fix this is to add a policy in the window manager or nitpicker that allows the menu or some other component to execute session_control on certain or all sessions. Implementing session_control functionality in init itself does not look like a clean solution.
By following the approach outlined above, nitpicker's session-control interface becomes a mere mechanism used by the window manager but not by anyone else.
Another issue is that init does not keep track of exited children. Launcher neatly closes the corresponding menu entries by installing a signal when the child exits, but init does not have such functionality now. Perhaps init could be modified such that it generates a report when a child exits? For now, if we would quit a child with another method than through the menu, we have no way of knowing if a child exited.
The state report generated by init already contains a 'state' attribute for each child. Right now, the attribute is present only if the child is "incomplete". We could add a value "exited" that would be presented as soon as the child issued a 'Parent::exit' call. Also the exit code could be added to the report, if needed. The subsystem manager could then inspect the state reports for children with this attribute value and remove them from the init config.
Cheers Norman