MicrosoftEdge / MSEdgeExplainers

Home for explainer documents originated by the Microsoft Edge team
Creative Commons Attribution 4.0 International
1.3k stars 206 forks source link

[Side Panel] Consider using display_override instead of introducing a new member for this mode #624

Closed mgiuca closed 1 year ago

mgiuca commented 1 year ago

Side Panel API: under Alternatives Considered, you wrote:

The side panel API can be implemented as a new display mode. However, the display_mode property is an existing property in the web app manifest and it could break existing web applications on unsupported browsers. The side panel API is implemented as a new property in the web app manifest to avoid breaking existing web applications.

This is a real problem (adding things to display) but there is already a solution we designed to work around this: display_override. See: https://wicg.github.io/manifest-incubations/#display_override-member. It is explicitly designed for this exact problem:

The display_override member of the application manifest is a sequence of display mode list values including extensions like window-controls-overlay. This member represents the developer's preferred fallback chain for display modes. This field overrides the display member. If the user agent does not support any of the display modes specified here, then it falls back to considering the display member.

I believe this use case could be covered with a new display_override option, although it's slightly different to the other ones we have there (tabbed and window_controls_overlay). Consider adding a new option to that enum: side_panel, whose presence in the list would indicate support for the side_panel member. It's a little different (therefore debatable whether it should be in this list) because the other modes are listed in order of preference, whereas this one seems to be suggesting it's an alternative mode that may be offered to the user.

You would still introduce the side_panel member to add extra properties (like the preferred width), but under this design, the presence of a side_panel member would not indicate support for the side-panel feature, you would also need to list it as a display_override. This is similar to the design we have for tabbed mode (explainer) - note that there's both a new display_override as well as the tab_strip member to give additional configuration.

The reason I like this as a new display_override mode is because of this paragraph:

The developer can also control the appearance of their web application in the side panel by using Client Hints. The developer can use the Sec-CH-UA header or navigator.userAgentData.brands to detect if the web application is being displayed in the side panel.

This doesn't feel appropriate to detect a feature that you hope to standardize (those are for detecting user-agent-specific hacks). If you add side_panel as a new display_override mode, then you will - basically for free - let developers detect these the same way we detect all the other display modes: with a CSS media query. See spec - this allows developers to tell if they are in the side panel mode either in CSS or with a JS query as follows:

if (matchMedia('(display-mode: side-panel)')) {
  // The web application is being displayed in the side panel.
}

It's very useful to be able to query this with CSS because you might style the page differently when it's in the side panel mode (e.g. changing fonts, hiding elements, etc). You don't want developers to have to write JS to restyle the page.

mhochk commented 1 year ago

I agree that having a way to query this state in CSS would be ideal (though will caveat that the primary request we've heard from sites so far is a way to detect this 'mode' at request time, similar to how they currently detect Mobile).

Using display_override seems like it would accomplish this from a technical perspective and display-mode feels like a conceptual fit. It does feel a little odd that it would mean the developer was adding a value to an ordered list, but it wouldn't matter where in the list (e.g. ["side-panel", "fullscreen", "minimal-ui"] and ["fullscreen", "minimal-ui", "side-panel"] would be functionally equivalent). Probably not an odd enough behavior to warrant creating another display-related field though.

mgiuca commented 1 year ago

I see the concern (or "conceptual weirdness") @mhochk -- it doesn't really matter where side-panel would be placed in the list, since it isn't the display mode chosen when launching the app (i.e. chosen by the user agent as the first supported mode in the list), rather, it's a separate mode launched through a different surface.

I wonder if we could make it a "display mode" for the purpose of CSS media query, but not have it listed in display_override -- just the presence of the side_panel member would indicate that it is supported in that mode. Or would that be even weirder? @dmurph WDYT?

dmurph commented 1 year ago

Interesting....

Usage in media queries

This seems like a great fit for the media query. It is, quite literally, the current display mode for the site, and it is exclusive with other display modes. So I think it would be a win if we could have it be in here.

Usage in the manifest - "supported" vs "default"

The usage of display in the manifest seems to imply this is the default mode that the application appears in when navigating - which implies launching (but that section doesn't actually mention the display mode). So I would argue that side_panel doesn't make sense here because it's not a "default" display mode, it's more of a... "supported" display mode.

So - I don't think it would make sense in either of the display or display_override attributes, as these are about resolving a "default" display mode.

Should we create a way for the manifest to say it can "support" a given display mode?

This can allow a web app to specify that it can support a given display mode - which allows the user agent to use it in those display mode cases. This..... seems fairly simple? It wouldn't affect any existing web apps that don't specify it, it's an opt-in, etc.

risks?

  1. These "supported modes" end up being not mutually exclusive with display modes.
    1. Counter-point - but, in this case, it is? What should the 'display mode' be for the side_panel case? None of the current ones fit.
  2. ??
mhochk commented 1 year ago

@dmurph - do you know of any other "modes" like this that are being discussed? It would certainly help inform what a good generic solution would look like.

Without other real proposals I can imagine this evolving a few different ways. There could end up being several other modes to declare "support" for - in which case a list of additional supported modes would be great. Or there might end up being several modes within this separate surface, with the same desire for the developer to stack-rank them like they can in display_override today. There might also be a desire to allow a developer to declare preference for one of these surfaces over another (e.g. prefers side_panel, but still supports stand alone).

mgiuca commented 1 year ago

Interesting idea Dan. To make this concrete (without proposing the literal final syntax), this would be something like a new member:

  "display_supported": ["side_panel"],

And you would be able to put any display mode in there (side_panel becomes a new display mode). If you put side_panel in display_override then user agents would just skip it, since you don't directly launch apps into side panel mode. But if you put it in supported, you hint to the UA that it can offer alternative UI to open the app in that mode. You could also put other display modes in "supported" which means "don't pick this by default, but we do support it and the user agent MAY provide a way to open it into this mode". e.g. you could have tabbed in there, which means the app is willing to be presented in that mode, though not as the default.

I like this idea as it's extensible into the future. (I find that I'm a bit allergic to single boolean members like supports_side_panel because we end up littering the manifest top-level namespace with all these one-off features.)

@mhochk :

do you know of any other "modes" like this that are being discussed? It would certainly help inform what a good generic solution would look like.

I don't think there are any others being discussed yet that work like side_panel is proposed. There are the tabbed and window_controls_overlay modes that are intended to be used with display_override.

But I think there's merit to this all the same, not just for side_panel or any future "I want this but not in my default state" mode, but also for existing modes.

with the same desire for the developer to stack-rank them like they can in display_override today

In my mind, the display_supported would be a set, not a stack rank. It's just saying "I wouldn't object to being launched in this mode". (Some modes, like tabbed or window_controls_overlay, create special situations that the site needs to handle which a user agent should NOT put the site into.) So I like the idea of being able to declare "the user agent MAY put me in this mode" without actually having it on the override chain.

mhochk commented 1 year ago

@mgiuca - I share the aversion to bespoke top-level members.

tabbed is an interesting example to think about for this. If the developer wanted to declare a tabbed experience was the best for their site they would include it in the display_override. If they had no interest in tabs they would not include it anywhere, but I expect UAs would likely still offer it as a non-promoted option to the user, much like they would for sites installed as apps that don't have a manifest at all. I worry that the mid-state of the site saying it is "supported" but not "preferred" might be so granular that it doesn't have a purpose.

Stepping back, @dmurph - what makes you say side_panel wouldn't be a possible default display mode? My initial reaction was to agree with this sentiment, but on further reflection I can imagine scenarios, like link handling within the browser, where the developer (or user) may wish to indicate that the app should be "launched" in the side panel rather than a stand alone window or browser tab.

I admit it would feel a little misaligned to have a desktop shortcut launch an app via a side panel within a browser, but one could also imagine the desktop shortcut launching in a host like Edge Bar, at which point calling it a "default" display mode feels much more appropriate.

(tl;dr; I'm leaning towards @mgiuca's earlier display_override proposal)

mgiuca commented 1 year ago

I worry that the mid-state of the site saying it is "supported" but not "preferred" might be so granular that it doesn't have a purpose.

Maybe right now, but you could imagine a future where some browser just decides to tabbify all apps unless they do not support it, so you could have an app that says "I support tabbed but prefer standalone". Then again, there's already a way to say that: display_override: [standalone, tabbed]. So perhaps there isn't a good case for display_supported: tabbed.

On the flip side (re: launching directly into a side-panel mode): @mhochk do you see this being something where there's an app explicitly designed as a side-panel app that would always want to launch in this mode if possible? Or do you see it as regular apps that have side-panel mode as an extra feature? If the former, then it totally makes sense for some apps to declare display_override: [side_panel]. But we would also need such apps to be OK falling back to the non-side-panel standalone or browser modes when in a browser that doesn't support side_panel. (If we're not OK with that, then maybe side_panel is a totally different type of app that should use a different manifest entirely, so other browsers just ignore it.)

Another option, which is kind of a hack, is if you wanted to get the same semantics as display_supported without having to add a new member, just put your "supported but not on by default" modes after browser. e.g.:

  "display_override": ["standalone", "browser", "side_panel"],

means "side-panel is supported but don't launch it by default", whereas:

  "display_override": ["standalone", "browser", "side_panel"],

means prefer to always launch into the side panel mode. I think whether or not this hack makes sense depends on if it's the unusual case or the norm. If it's the norm, we probably want a deliberately designed way to say it.

If we seriously want to propose display_supported then we should take this discussion to the Manifest issue tracker. But we could also just use the ability we already have in display_override.

dmurph commented 1 year ago

Client hints

We've had a backlog item here for a long time to add display_mode client hints: https://crbug.com/1174843. I think folks are generally happy about it in chromium. So - if we use display, then implementing a display mode client hint is a win for everyone too.

"supported" vs "default"

Do we have an example & know what they want? Do they want to have a windowed experience AND a side-panel experience? What do they want to happen when the user clicks on the platform shortcut?

mhochk commented 1 year ago

do you see this being something where there's an app explicitly designed as a side-panel app that would always want to launch in this mode if possible?

Yes. These will all still be websites, so will have some level of support for browser display, but may be designed with the intention of being in a render surface like a phone or side panel.

To my understanding this is more likely to be the case for sites specific to locales where Mobile web usage is much higher than desktop web usage (e.g. parts of Asia), as they often design sites for mobile first and then maybe get around to updating the design for desktop.

just put your "supported but not on by default" modes after browser

I wouldn't expect this to be a common scenario, so would be fine with this approach.

We've had a backlog item here for a long time to add display_mode client hints

Thanks for sharing this - this does sound like a win for everyone.

Do we have an example...

The developer opinion on this I've heard so far from sites that support both desktop and mobile layouts is they want to be available in a stand-alone window or in the side panel - wherever the user wants them. Those that have only done a mobile layout would like to push the user towards the side panel for an optimal experience.

As for the desired result from clicking a platform shortcut - that feels like a user-interaction question rather than a developer intent question. If a site supports stand-alone and side-panel it should be in the users control to "install" the site to either or both "locations". If they choose to add it to only one the intent of the shortcut is clear. If they add it to both I think it would be up to the UA to decide if the user should be able to designate which location they intend, or if the UA feels empowered to make that choice on behalf of the user.

dmurph commented 1 year ago

In that case - I think it's fine to start with having it be something that lives in in display_override if the first examples are apps that want to launch there by default anyways.

If we get to the state where the app intends to launch in either - then we can talk about adding a supported_display_modes signal?

mgiuca commented 1 year ago

If a site supports stand-alone and side-panel it should be in the users control to "install" the site to either or both "locations". If they choose to add it to only one the intent of the shortcut is clear.

Right, OK. That makes sense, but it might still be nice to have the developer hint about which of these experiences is preferred (even just to inform the default selection when installing the app). I guess that is taken care of by the ordering in display_override so we could use that as a signal.

If we get to the state where the app intends to launch in either - then we can talk about adding a supported_display_modes signal?

Agreed.