w3c / manifest

Manifest for web apps
https://www.w3.org/TR/appmanifest/
Other
658 stars 160 forks source link

Add a "tabbed application" mode #737

Open mgiuca opened 5 years ago

mgiuca commented 5 years ago

A feature request to add a "tabbed" mode for installed applications. This would be similar to "standalone" in that when the application is installed, it can be opened in a separate window dedicated to that application. However, in "tabbed" mode, the user agent would divide the window into tabs, similar to a tabbed web browser, except that all the tabs belong to the app (and don't have a URL bar).

Differences to a normal web browser window:

(At the user agent's discretion), the user would be able to drag tabs around, split them out to separate application windows, drag tabs in the application scope between app windows and regular browser windows.

Essentially this lets web developers easily build multi-document interfaces for productivity applications.

Why not just let developers build their own tabbed interface in HTML?

This could be made into a library, where you embed your document pages inside an iframe. However, it would have a number of drawbacks compared to a user agent implementation:

Why can't a user agent just interpret "display: browser" as this tabbed mode?

(i.e., why do we need to spec this at all?)

Because display: browser already has a specific meaning. "Opens the web application using the platform-specific convention for opening hyperlinks in the user agent (e.g., in a browser tab or a new window)." While user agents can do whatever they want regarding UI, it would clearly be a pretty big subversion of developer expectations if "display: browser" suddenly meant "run in a separate application-specific window with no browser affordances, but a tabbed document interface".

"display: browser" is the way you opt out of being put into an application window.

Furthermore, "display: browser" is at the bottom of the fallback chain. If a user agent doesn't support, say, "display: minimal-ui", it is required to fall back to "display: browser". It doesn't make sense that a developer requesting "standalone" would get a standalone single-document window with no browser UI, while a developer requesting "minimal-ui" (i.e. asking for more browser UI) would get a standalone multi-document window with no browser UI.

User agents SHOULD NOT treat "display: browser" as a tabbed document application window.

How should this be requested, then?

The obvious answer is to add a new display mode: "display: tabbed" or "display: multidoc" (the latter would let user agents provide a different multi-document interface, in case there is a Windows 95 implementation :smile:).

One potential issue is that it doesn't fit cleanly into the fallback hierarchy. Currently, the fallback hierarchy is: fullscreen > standalone > minimal-ui > browser. If we put "tabbed" above "standalone", then that implies a user agent that doesn't support "fullscreen" should fall back to "tabbed" (bad). If we put it above "fullscreen", then that implies a user agent that doesn't support "tabbed" should fall back to "fullscreen" (also bad).

We could make the fallback hierarchy a DAG, which would look like this:

   tabbed
          \
           > standalone > minimal-ui > browser
          /
fullscreen

I think that would be reasonable, however it precludes the possibility of a "tabbed, miminal-ui" mode.

The other approach is that we make "tabbed_mode" or "multidoc_mode" a separate member that you can enable, in tandem with "display: standalone" or "display: minimal-ui" which would resolve the above issue.

kenchris commented 5 years ago

If you drag a tab out, and say into a browser, then it will change display-mode I assume? That will affect whether it makes sense to have these as separate members or not

mgiuca commented 5 years ago

I would think so. Yeah I'd want you to be able to detect whether it's in a tabbed mode (so you could implement your own tabbed interface in HTML and disable it if you're in a tabbed mode). So however we do it, I'd want to make it detectable. It seems that decoupling it from display-mode would mean we have to add more media features. So perhaps using display-mode is the easiest here.

evanw commented 5 years ago

Another reason for "Why not just let developers build their own tabbed interface in HTML?": it enables developers to create multiple child tab processes for stability, parallelism, and security isolation.

I work at Figma, an in-browser design tool, and I've been looking at using potentially making a web app manifest alternative to our Electron-based native app (which has a tabbed UI). We are unable to build a tabbed interface in HTML because each tab of ours often uses 1gb+ of memory and users often have 10+ tabs open. A HTML-based tab interface with iframes would trigger the browser's OOM killer and crash the tab. It would also run all tabs on the same thread which would be very bad for performance. We're using Electron's BrowserView API instead of iframes to accomplish this in Electron but there's currently no way to accomplish this with web APIs.

voxpelli commented 5 years ago

I would love to have something like this in the newspaper PWA we're creating at work and I would certainly push for something like this there whenever it arrives.

I myself usually read news sites in the browser rather than in an app as I then can open new articles as I scroll by them in a list and then go back and forth until I have read all of the tabs and are done for the day.

Being able to utilize the power of browsers and having it as an option in a PWA could finally enable doing that in an easy manor.

alancutter commented 5 years ago

Assuming tabbed PWAs happen would you want more control over the tabs than is currently available with browser tabs?

voxpelli commented 5 years ago

I would prefer it if I could control the tabs UI and have those tabs only be tabs that are owned by the PWA, leaving external content opened as it is today in a PWA

Then the PWA would continue to be fully styled by itself, just like a native app.

alancutter commented 5 years ago

external content opened as it is today in a PWA

In Chrome today it shows a bar indicating you've gone off scope. Is that what you had in mind? Screenshot from 2019-08-26 17-00-58

voxpelli commented 5 years ago

@alancutter Yes, as for security reasons it would not be possible to allow for those to be included in a tabbed UI styled and controlled by the PWA itself, as it could then easily masquerade as showing a site that it isn’t

AndersFriborg commented 4 years ago

Tabs in PWA is a really good feature. Is there any information on the progress of this? @mgiuca?

mgiuca commented 4 years ago

Thanks for asking. There isn't any updates on the spec side, but @alancutter is prototyping it behind a flag in Chrome. I believe it should be usable in Canary/Dev channel behind a flag soon. One of us will post an update here when it is.

AndersFriborg commented 4 years ago

Ok thanks for the update @mgiuca and keep up the prototyping @alancutter :-)

vjpr commented 4 years ago

@alancutter Is there anyway to try out desktop PWA tab strips in Chrome? What does the flag chrome://flags/#enable-desktop-pwas-tab-strip currently do? Looks like its only ChromeOS at the moment.

Would love to see this on macOS. E.g. When running productivity apps as bookmarked apps, I would like to be able to open documents as tabs in the same window.

alancutter commented 4 years ago

Currently this experimental implementation is only functional on Chrome OS 83+, the flag enables you to change the launch mode to be a tabbed window.

tomayac commented 3 years ago

I played with the Chrome OS implementation and noticed that all storage seems to be shared between all tabs. For example, if an app keeps state in localStorage, all tabs share the same state. The Windows 95 implementation you jokingly linked to in the original thread has a dedicated section on child window data, which lists two ways of storing data, for example, the name of the current file:

Will there be a platform way to do this, or are implementations expected to manage tab state themselves (and if so, what do you propose to re-identify the same tab)?

tomayac commented 3 years ago

How does this interact with display_override? The "tabbed" value should probably be an allowed value of display_override rather than be fitted into the fallback chain of display.

kenchris commented 3 years ago

How does this interact with display_override? The "tabbed" value should probably be an allowed value of display_override rather than be fitted into the fallback chain of display.

I believe this was the plan. At least that is what I have heard before and it was discussed as part of display_override

kenchris commented 3 years ago

and if so, what do you propose to re-identify the same tab

From service workers you can get access to clients (this is why the sw-launch event is so powerful and flexible, as you can find a particular window and focus it etc), so maybe a similar API could be exposed when running in tabbed mode?

kenchris commented 3 years ago

For getting everything to work like media query and existing implementations, we should add tabbed to DisplayModeType and define 'display' fallback as 'browser'. That is compatible with what we have today and will make it work in the media query.

If people want to define their own fallback order they can use display_override and that is what we should recommend.

Like setting

"display_override": ["tabbed", "standalone"],
"display": "standalone"

meaning fallback will be (manual: tabbed -> standalone) -> (automatic: standalone -> minimal-ui -> browser).

I am here assuming that if none of the values in display_override are know or supported, it will fall further back to the original display which makes the most sense (I hope that is how display_override is defined)

If you just set

"display": "tabbed"

It should work on supported browsers but fallback will be "browser" - that is compatible with what happens today.

It might even be fine defining a different fallback (as it is a fallback anyway) like what Matt originally suggested

tabbed -> standalone -> minimal-ui -> browser.

That would mean that "display": "tabbed" would have the same fallback as

"display_override": ["tabbed", "standalone"],
"display": "standalone"

as "display": "standalone" falls back to -> minimal-ui -> browser

alancutter commented 3 years ago

I played with the Chrome OS implementation and noticed that all storage seems to be shared between all tabs. For example, if an app keeps state in localStorage, all tabs share the same state.

For tab scoped storage you can store things on globalThis.

tomayac commented 3 years ago

For tab scoped storage you can store things on globalThis.

Thanks for the reply. Session storage would be another (probably preferable) alternative.

What I was after was storage that is persisted across sessions, though. To make this clearer: The user edits document data in PWA tab 1 and PWA tab 2 and wishes to persist both locally in the browser, but not in a file. Right now, the user could namespace localStorage per PWA tab, but ideally there'd be a platform way to do this.

I guess the question also includes whether developers are to think of PWA tabs conceptionally different than of regular browser tabs.

alancutter commented 3 years ago

Sounds like: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage

Edit: Sorry you already mentioned that, you mean for it to persist. When would it expire?

tomayac commented 3 years ago

Sounds like: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage

Edit: Sorry you already mentioned that, you mean for it to persist. When would it expire?

“Never” as in localStorage-never. In my ideal world each PWA tab would just magically create a tab-specific localStorage (and IDB) storage bucket. This would be different from regular tabs.

thibPG commented 3 years ago

With the current implementation, when in tabbed mode, the PWA right click menu has "open in new tab" but the active tab looses focus when doing this; Is it possible to have a behavior similar to regular browser window (use case: opening multiple document from a index page)

tomayac commented 2 years ago

Noting that Tabbed Application Mode cannot be used together with Window Controls Overlay. Tracked as https://github.com/WICG/window-controls-overlay/issues/55.

mariusheine commented 2 years ago

Is there any information about when it gets officially enabled/supported? We tested it under the experimental flags and it works great for us.

But every user must enable it by himself... That's why I am asking.

tomayac commented 2 years ago

Is there any information about when it gets officially enabled/supported? We tested it under the experimental flags and it works great for us.

This is not a spec question, but an implementation question. Could you ask on the Chromium bug instead? Thanks.

tomayac commented 2 years ago

Interlinking https://github.com/WICG/manifest-incubations/pull/55 and the present Issue.

wraiford commented 2 years ago

Because display: browser already has a specific meaning. "Opens the web application using the platform-specific convention for opening hyperlinks in the user agent (e.g., in a browser tab or a new window)." While user agents can do whatever they want regarding UI, it would clearly be a pretty big subversion of developer expectations if "display: browser" suddenly meant "run in a separate application-specific window with no browser affordances, but a tabbed document interface".

This is entirely what does NOT happen on Chrome mobile (Android). With either display: "browser" or no display setting at all, Chrome mobile adds a link that looks like it's going to open the browser - but doesn't. It opens a single-tabbed application - exactly what the above quote says would be a "pretty big subversion". And he/she is correct in my particular case.

As such, it looks like I can't use the tabs in an offline manner for any PWAs at all. Firefox for Android does not respect the service worker properly and starts giving connection errors. And Chrome mobile does indeed work offline, but it only shows one tab without the ability to even open in the Chrome Mobile browser proper. I do see that the desktop does at least allow "Open in Chrome" which would totally be fine in the mobile if not slightly annoying. But a large difference between the desktop app is that it is easier to drag bookmarks to the desktop (screen), whereas this functionality exists on mobile only as the Add to Home Screen functionality. So I can't just add a bookmark to my Android's "desktop" home screen to even work around the lack of tab functionality.

It is my understanding that the "tabbed application" is only being currently implemented on the desktop. Is that correct? Could someone point me to an issue or where to create a new issue with the Chrome mobile PWA team to at least request the ability to "Open in Chrome" as a stop gap until tabbed functionality gets extended to mobile?

EiraGe commented 2 years ago

With either display: "browser" or no display setting at all, Chrome mobile adds a link that looks like it's going to open the browser - but doesn't. It opens a single-tabbed application

I believe as for now, Chrome mobile allows only "add to homescreen" instead of "install" when display: "browser" or no display. Opening the added shortcut will open the url in a browser. Is the "a single-tabbed" you refer to sounds like the "minimal-ui" mode which opens a custom tab?

And Chrome mobile does indeed work offline, but it only shows one tab without the ability to even open in the Chrome Mobile browser proper.

Chrome mobile allows "Open in Chrome" too. It's not too obvious though. When the installed app is opened, there is a silent notification that gives the option to "Open in Chrome".

wraiford commented 2 years ago

Is the "a single-tabbed" you refer to sounds like the "minimal-ui" mode which opens a custom tab?

Hi @EiraGe I've tested many settings, including yesterday with the minimal-ui. Today I've only tested with standalone, fullscreen and browser (and none at all that goes to the default). Each time I check that the manifest.webmanifest is pulling correctly and I do everything I can to delete all cookies/site data. It correctly toggles back and forth between standalone, fullscreen and browser so I'm confident that caching is not the issue (IOW it's not from minimal-ui testing from yesterday). Rather, it simply does not open in the browser.

You're welcome to test it yourself at https://ibgib.space (with the manifest at https://ibgib.space/manifest.webmanifest not manifest.json). Just now I removed Chrome mobile PWA again, cleared cache (didn't restart but I have tried that, as well as clearing all data for the past 7 days since I usually use FF), went back to the site, "Add to Home screen", opened and there was no toast or notification, and there is no affordances outside of my app that would let me "Open in Chrome". I double-checked that the manifest.webmanifest is currently set without a display key at all, so it should have defaulted to browser. But I don't want to hijack this spec page on my troubleshooting! Unfortunately GH doesn't allow for tangents and I appreciate that this issue is for the spec. I'm just trying to influence the spec that A) Tabbed is of utmost importance, B) Mobile should be of utmost importance.

I thought perhaps someone has made changes on the mobile side that this issue wasn't aware of...but perhaps my triple+ checking was still incorrect and I've been missing something.

mgiuca commented 2 years ago

@wraiford : Based on my understanding, Chrome on Android lets you add to homescreen and the result will be based on "display". If it's "display": "browser" (or nothing), it will just act like a normal browser shortcut, opening a new tab in the Chrome browser. If it's "display": "minimal-ui" or "standalone", it will create its own window. This seems aligned with the spec. I suspect you are installing an app with "display": "minimal-ui" or "standalone".

This is fairly orthogonal to what is being proposed here, which is a separate tabbed mode inside a standalone app window. (That is the point being made in the paragraph you quoted, which is to emphasise that "display": "browser" is not appropriate for triggering the standalone tabbed mode.)

It is my understanding that the "tabbed application" is only being currently implemented on the desktop. Is that correct?

That is currently correct for Chrome, though this GitHub is in the W3C which is browser-neutral, and I can't speak for other browsers. There is nothing stopping another browser (or Chrome in the future) from implementing standalone tabbed mode on mobile, though more UX research is probably required.

Could someone point me to an issue or where to create a new issue with the Chrome mobile PWA team to at least request the ability to "Open in Chrome" as a stop gap until tabbed functionality gets extended to mobile?

Again, this isn't a Chrome issue tracker so I don't want to get too far into discussing Chrome bugs here. You can always file a bug at https://crbug.new. I don't think having tabbed application mode on mobile will help what you want. (It would mean the apps you install are getting their own mini tab interface, and only if they request "display": "tabbed".) Sites with "display": "browser" should already be doing what you want. Sites with "display": "minimal-ui" or "standalone" should open in their own window, but as @EiraGe stated, there is a pull-down notification that lets you open them in Chrome. It sounds as though things are working as intended on the Chrome side.

mgiuca commented 4 months ago

Following up this thread: tabbed app mode is incubating in the manifest-incubations repo. We have spec text in there.

Meanwhile, the feature is shipping in Chrome 126 (only on ChromeOS).

We'll keep this issue open here, as it hasn't landed in the Manifest repo (requiring a second implementation).