Skip to content

[Snowcap] Composable Program feedback #429

@Ph4ntomas

Description

@Ph4ntomas

I've been busy porting Glacier to the composable programs. Here are some thought/feedback from using it more than the toy tests during the Review, before pushing for upstreaming stuff.

I have some auto-hiding widgets (e.g. the prompt, various text box). I'd much prefer if they were able to return None when there's nothing to view. (I've open #427 then #428, but I'll present some thought after the overall feedback)

Right now, the plugins can opt-in to have full, constant access to the handle. This means they have 2 channels to send messages, (through signals and through the handle messages). It also causes some issues with separation of responsibility.
As an example, when activating a prompt, the widget need to be focused and the layer need to get keyboard interactivity. In my previous iteration, there was a separate Widget trait, which acted as a program-light which did not keep access to the surface outside of the update function (and even then it was only used for popup). This meant the prompt needed to forward the focus request to the Program hosting it, which then used the surface handle to focus & take keyboard interactivity. With the new design, both the 'toplevel' Program and any of it's subprogram may act on the handle to change focus & interactivity, and there's nothing to prevent that.

The UniversalMessage object & Universal trait could be improved a bit for use in toplevel program. I have a few messages handled both by the toplevel Program & the widget (e.g. for focus management), meaning my bar need to clone every universal messages to probe whether it might need to be handled or not. IMO we either need a way to test the message type (is<T>() -> bool), or to access the message content as a reference (downcast_ref<T>() -> Option<&T>)

It might be because I haven't had enough time to play with it but I feel having the same trait for both 'toplevel' program that are tightly integrated with the surface they're on and 'hosted' may lead to some issue down the line with incompatible 'hosted programs' because they expect the toplevel to act a certain way.

Some closing thought:

IMO we could improve some of this by having a Program-like trait hosted::Program, with the following changes:

  • SurfaceHandle would be replaced by a more restrictive/weak type (hosted::SurfaceHandle), so the hosted::Program can't just access the raw handle.
  • some of hosted::SurfaceHandle methods wouldn't be applied to the underlying handle, but instead bubbled-up to the hosting Program (e.g. operate, close). Less critical ones may be kept as-is (e.g. send_message, force_redraw). (Note: critical methods like operate & close could be replaced by signal, too).
  • hosted::Program::view doesn't have to return a WidgetDef (instead of merging snowcap: Make Program::view return an option #428).
  • hosted::Program can be composed from other hosted::Program only. Program may decide to forward call to the Program trait to other Program, and should otherwise properly call hosted::Program functions.
  • hosted::Program are surface-agnostics and Program agnostic, while Program may access the raw Handle that was passed during the created call.
  • standard hosted::Program are expected to use UniversalMessages. Standard Program should if they are also hosted::Program.
  • standard Program may also define their own Message type for when they're not hosted. Their custom message type must be convertible from Universal. Example use case: a Bar may an hypotetical "HideBar" which it can only use in hosting mode. When hosted, it must abide by the hosting Program Message, meaning it can't make use of it. Regardless, it must handle the UniversalMessage to forward them to its children.

This proposal shouldn't hurt composability, as Program could also implement hosted::Program and re-use most of the code but wouldn't mess with the toplevel Program expectations when hosted. Host-only program can be more tightly integrated with their surface and ensure correct behavior (e.g. focus-arbitration if the user hit tab or escape, correct order of operation if a widget discard focus while another-one has it, etc.). Hosted-only Program can be written with some expectation about the behavior of the host Program.

@Ottatop Sorry I did not spot these issue during the review. Let me know if you're interested in some POC implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions