fullscreen icon indicating copy to clipboard operation
fullscreen copied to clipboard

Decide on wanted behavior for request+exit or exit+request together

Open foolip opened this issue 8 years ago • 8 comments

Working on Fullscreen in Blink, the situation has come up where we're transition in or out of fullscreen when a call to go in the opposite direction happens. Test case:

<!doctype html>
<div>
 <button>request</button>
 <button>exit</button>
 <button>request+exit</button>
 <button>exit+request</button>
</div>
</div>
<script>
var div = document.querySelector('div');
div.addEventListener('click', function(event) {
  if (event.target.localName != 'button')
    return;
  for (var action of event.target.textContent.split('+')) {
    if (action == 'request') {
      if (div.requestFullscreen) {
        div.requestFullscreen();
      } else if (div.webkitRequestFullscreen) {
        div.webkitRequestFullscreen();
      } else {
        div.mozRequestFullScreen();
      }
    } else if (action == 'exit') {
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
      } else {
        document.mozCancelFullScreen();
      }
    } else {
      throw 'unknown action';
    }
  }
});
</script>

Current behavior:

request+exit exit+request request then request+exit request then exit+request
Spec'd enter enter ??? ???
Chrome 55 enters+exits quickly enters exits exits
Edge 14 enters+exits quickly enters exits exits+enters quickly
Firefox 51 enters enters exits exits

Safari 10 behaved strangely when testing in BrowserStack, seemingly hanging, so I don't trust what I saw.

Exit fullscreen has an early return in the spec, which makes the first two cases simple. For the last two, it's not obviously well defined, because two "resizes" are racing "in parallel."

@upsuper @jernoble

foolip avatar Nov 21 '16 13:11 foolip

@aliams too

foolip avatar Nov 21 '16 13:11 foolip

Possible models:

  1. All requestFullscren() and exitFullscreen() calls go on a single cue, and are processed in order. (Would match Edge in the simple cases tested.)
  2. Keep track of pending resizes and reject any attempt to go in the other direction until done. (Would match Firefox in the simple cases tested.)
  3. In requestFullscreen(), attempt no resize if pending's top-level browsing context’s active document’s fullscreen element is not null, so that if already in fullscreen or if currently exiting, it does nothing. Then handle the "unexpected" case of having already exited in the animation frame task. (Would also match Firefox in the simple cases tested.)

Others?

The first is simple in some sense, but would enable long series of transitions in and out of fullscreen, pointless from the user's perspective. The second or third seems simpler to implement in Blink at this time.

foolip avatar Nov 21 '16 14:11 foolip

I agree with the third. We should not trigger resize if we are already in fullscreen.

The first is only simple in concept. I think that would require impls to have an additional queue for that, but it doesn't make anything better for normal usecases. I'm against adding impl complexity like that without a good reason.

upsuper avatar Nov 21 '16 23:11 upsuper

@upsuper, can you take a look at https://github.com/whatwg/fullscreen/pull/64?

Not all error cases are handled, and even figuring out what they all are is tricky. I'll try to tinker with this in Blink, it might be useful to enumerate all the ways that things can go wrong in Gecko and how you'd like to handle them.

foolip avatar Nov 22 '16 11:11 foolip

A request can fail with a fullscreenerror event, so I've also tested what events are fired for the "request then exit+request" case after clicking "exit+request" with a variation on the original script:

Chrome 55 on Linux fullscreenchange, fullscreenchange, fullscreenchange, resize
Edge 15 on Window 10 fullscreenchange, fullscreenchange, resize, resize
Firefox Nightly (53) on Linux fullscreenchange, resize

(With unprefixed API manually enabled.)

So, at least no existing browser fires a fullscreenerror event in this case. The only sensible thing for the promise is to reject it, but it would be possible to fire no events.

Opinions?

foolip avatar Nov 28 '16 15:11 foolip

@annevk, do you care either way about how all of this behaves, or is anything fine as long as we get interop?

foolip avatar Nov 29 '16 14:11 foolip

I don't think I care strongly, but it would be nice if what we end up with was principled somehow.

annevk avatar Nov 29 '16 14:11 annevk

Yeah. I think the first option from https://github.com/whatwg/fullscreen/issues/63#issuecomment-261948581 has a simplicity of sorts, but avoiding cycles of entering and exiting would require some ugly checks that make it pointless.

Another pretty simple option is to say that globally there can only be one pending fullscreen call at a time, but that doesn't mix well with multi-process. Will continue to fiddle with tests and spec text and ask for review when I'm satisfied.

foolip avatar Nov 29 '16 14:11 foolip