Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should we handle the launch event in the ServiceWorker or an Open Window. #3

Open
fallaciousreasoning opened this Issue Feb 6, 2019 · 5 comments

Comments

Projects
None yet
3 participants
@fallaciousreasoning
Copy link
Collaborator

fallaciousreasoning commented Feb 6, 2019

Currently we haven't decided as to where to handle the event, there are advantages and disadvantages to both approaches.

ServiceWorker

  • If there are multiple app instances/tabs open you can decide what one to use (or open a new one)
  • Might be slow: we have to spin up the SW before handling the event
  • Could potentially be swallowed silently (why isn't my file opening?)

Current Window

  • This works well for the single instance app
  • If there are multiple windows, how do we decide which one to use?
  • What if it should be handled in a different one? We might have to send a message to the ServiceWorker.

Opinions

I'm partial to sending the event to the service worker, and letting it decide what to do, as it is the only place you can inspect all app windows (and so this seems a natural place to handle it), though I understand some people have privacy concerns.

@fallaciousreasoning

This comment has been minimized.

Copy link
Collaborator Author

fallaciousreasoning commented Feb 18, 2019

@marcoscaceres @aliams do you have any thoughts on this?

@marcoscaceres

This comment has been minimized.

Copy link
Member

marcoscaceres commented Feb 19, 2019

@fallaciousreasoning thanks for pinging me. Unfortunately, I've not kept up with this work or service workers in a long while, so I don't feel qualified to give an opinion :( I'd maybe drag in some of the folks from the Service Workers WG... @jakearchibald can probably recommend some additional folks that might be good to ask.

@aliams

This comment has been minimized.

Copy link

aliams commented Feb 19, 2019

I think we should try to better understand the use case from a web developer's perspective and how valuable and useful it would be to have the extra control over which instance receives a file launch in a multi-instance app scenario. Do we have examples of apps that would want to be able to do this today that might be able to speak to this?

I would say that we can achieve both options above depending on web developer needs here.

We can have an activation event on the current window or in the service worker. In the case of the current window, it would be worthwhile investigating if having the last instance open a file for multi-instance app scenarios would suffice.

In either case, I would suggest having different types of activations, such as:

  • an app launched as a result of the app's icon being clicked
  • an app launched as a result of a file being opened whose file type the app is registered to handle
  • an app launched as a result of a URI being accessed whose scheme name the app is registered to handle
@fallaciousreasoning

This comment has been minimized.

Copy link
Collaborator Author

fallaciousreasoning commented Mar 1, 2019

Mitigating Concerns with ServiceWorker LaunchEvents

I think we can mitigate some of the concerns with the ServiceWorker launch event.

Slowness

If the browser isn't open, the time to spin up the ServiceWorker is likely to be fairly small compared to the amount of time we'll need to spin up the browser, so it probably won't have much effect on this case. The one we're really concerned about is when the browser/app are open when we fire off the event and nothing happens. It still seems like this time is probably not going to be that significant compared to the I/O required to actually open the file.

Another potential cause of slowness would be that developers decide to do some heavy pre-processing in the ServiceWorker, before starting a client, so users don't get immediate feedback that something is happening. We could reduce this by putting a small timeout on the LaunchEvent (say, 1 second), which would encourage developers to pass on the FileHandle as quickly as possible.

Silence

In order to ensure that users actually see something happen we could make it a requirement that client.focus() is called in a FileHandler, and, if it is not, the browser selects an open client, or opens a new client. In addition, a UserAgent could choose to black list apps that don't open a client, to discourage bad behavior.

On Control and Instances

Off the top of my head:

An (Image|Document) editor probably wants to open each new file in a new client (as they do on Windows and Mac), but there shouldn't be multiple editors for a single file (so the existing client for the file should be focused).

VS Code opens each file in a new tab of the last active editor. However, folders are opened in a new Window.

Different Activation Events

This seems like it might be a more appropriate discussion for the sw-launch repository but I kind of envisioned some kind of discriminated type union

interface IconLaunch {
  cause: 'icon';
}

interface FileLaunch {
  cause: 'file';
  files: WritablefileHandles[];
}

interface UrlLaunch {
  cause: 'url';
  request: FetchAPIRequest;
}

type LaunchEvent = IconLaunch | FileLaunch | UrlLaunch;

where cause lets you infer what properties will be available, but I haven't thought about it that much (and I don't know if we can do something like that explicitly in WebIDLs).

Usage would be something like this:

self.addEventListener('launch', event => {
    event.waitUntil(async () => {
        switch (event.cause) {
            case "icon":
                 // icon launch stuff.
                 break;
             case "file":
                 // file launch stuff.
                 break;
              case "url":
                  // url launch stuff
                  break;
        }
    }());
});

or

self.addEventListener('launch', event => {
    event.waitUntil(async () => {
        if (event.files) {
             // file launch stuff
        }
    }());
});
@fallaciousreasoning

This comment has been minimized.

Copy link
Collaborator Author

fallaciousreasoning commented Mar 1, 2019

PR #6 adds a section with these mitigations, what are your thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.