Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Screen orientation API proposal

96 views
Skip to first unread message

Mounir Lamouri

unread,
Jan 3, 2012, 9:18:33 AM1/3/12
to mozilla-d...@lists.mozilla.org, pba...@zynga.com, di...@apple.com
Hi,

I would like to move the API discussion from bug 673922 to a more public
place so we can increase the number of people able to participate. Thus,
it goes without saying that feedbacks are more than welcome.

** Ideas from the bug **

There were various proposals in the bug and amongst the ideas, there were:
1. allowing to set <meta name="viewport"
content="orientation=landscape/portrait orientation-lock=yes/no">;
2. access this trough navigator.viewport;
3. having a beforeorientationchange event that could be canceled with
.preventDefault();
4. JS API with window.lockOrientation() window.unlockOrientation().

I think allowing to set the screen orientation in the viewport meta tag
might be a bit odd. Also, the proposed API seems inadequate and having
only orientation=landscape/portrait should be enough. It's actually what
CSS Device Adaptation [2] has specified.
In one hand I believe having a declarative way would be nice because it
would allow webapps to easily set the orientation and also might prevent
screen flickering if the orientation is set after the first paint. In
the other hand, it might also be nice to keep this API contained in a JS
API. We can easily assume using JS APIs wouldn't bother too much
potential users of this API given that it doesn't aim static websites.

As far as I understand it (2) should be handled by CSS Device Adaptation
[2] specification. And again, allowing changes to the screen orientation
via navigator.viewport.orientation might be confusing.

Regarding (3), we definitely need an event but beforeorientationchange
and allowing to cancel it doesn't seem very useful. If we have a JS API
that allows a webapp to specify which are the allowed orientations, why
would an app block some orientations? In addition, such an event might
make the orientation change slower.
Unless there is an obvious use case I think we shouldn't add this to the
API (at least the first version).

Finally, we definitely need a JS API that might look like (4) proposal
but not in the global scope.

** Proposal **

partial interface DOMScreen {
// Returns the current screen orientation.
readonly attribute DOMString orientation;

// Returns whether locking the screen to |orientation| is allowed.
// Should return false if the |orientation| isn't known by the device
// or if the application can't lock the screen orientation.
boolean orientationAllowed(in DOMString orientation);

// Locks the screen to |orientation| or to the current orientation if
// no value is passed.
// Throws if the application isn't allowed to lock orientation or if
// |orientation| isn't known by the device.
// If this changes the screen orientation, an 'orientationchange'
// event will be fired.
void lockOrientation([optional] in DOMString orientation);

// Unlock the screen orientation.
// Throws if the screen orientation isn't currently locked.
// If this changes the screen orientation, an 'orientationchange'
// event will be fired.
void unlockOrientation();

attribute Function onorientationchange;
};

There are four possible orientations:
- landscape-primary
- landscape-secondary
- portrait-primary
- portrait-secondary

(Feel free to bikeshed the names. Using
landscape-reverse/portrait-reverse or portrait-upsidedown would be ok
but it seems hard to find a better name for *-primary.)

In addition, lockOrientation will accept the following orientations:
- landscape, means any landscape-* orientation;
- portrait, means any portrait-* orientation.

That way, applications will be able to allow the screen to have
different orientations. However, I don't think we need something like
allowOrientations(in DOMString[] orientation) like someone proposed in
the bug because I don't see any reason why an app would like to do that.
If it happens to be needed, we can always add this later.

** Alternatives **

My first idea was an interface with only |attribute DOMString
orientation;| where the authors would be able to set and get the
orientation. That way seems to be more JS style but that would have
created very weird situations like those:

// This might look like a no-op but it's actually locking the screen.
screen.orientation = screen.orientation;

// Setting would be async.
screen.orientation = "portrait-secondary";
alert(screen.orientation); // might be anything, will be
"portrait-secondary" when "orientationchange" event will fire.

// Unlocking would require a special value:
screen.orientation = "default";
// Which means after 'orientationchange' event, screen.orientation
wouldn't be "default" but any value.

** Open questions **

- Maybe we should use a ScreenLockRequest objects when lockOrientation()
and unlockOrientation() are called. That might make the API a bit more
heavy but might make things a bit more clearer too...
- Should we have orientation in the viewport meta tag? If we don't we
need to be sure we can easily set the orientation before the first paint.

** Notes **

CSS3 Media Queries [3] allows authors to use orientation based on
width/height comparison.

[1] https://bugzilla.mozilla.org/show_bug.cgi?id=673922
[2] http://dev.w3.org/csswg/css-device-adapt/
[3] http://www.w3.org/TR/css3-mediaqueries/

Thank you for reading,
--
Mounir

Chris Jones

unread,
Jan 3, 2012, 11:52:57 PM1/3/12
to Mounir Lamouri, pba...@zynga.com, Chris Pearce, di...@apple.com, mozilla-d...@lists.mozilla.org
----- Original Message -----
> From: "Mounir Lamouri" <mou...@lamouri.fr>
> To: mozilla-d...@lists.mozilla.org
> Cc: pba...@zynga.com, di...@apple.com
> Sent: Tuesday, January 3, 2012 6:18:33 AM
> Subject: Screen orientation API proposal
>
> I think allowing to set the screen orientation in the viewport meta
> tag
> might be a bit odd.

meta viewport should go away. I'd really prefer not to pile onto it.

> In one hand I believe having a declarative way would be nice because
> it
> would allow webapps to easily set the orientation and also might
> prevent
> screen flickering if the orientation is set after the first paint.

AFAIK having orientation be a CSS property instead of a JS API isn't better protection against flicker in general. There are still FOUCs to worry about. (Note, it might be more effective in practice.)

A CSS property seems very hard to specify to me. What happens if multiple style sheets request different orientation locks?

> Regarding (3), we definitely need an event but
> beforeorientationchange
> and allowing to cancel it doesn't seem very useful. If we have a JS
> API
> that allows a webapp to specify which are the allowed orientations,
> why
> would an app block some orientations? In addition, such an event
> might
> make the orientation change slower.
> Unless there is an obvious use case I think we shouldn't add this to
> the
> API (at least the first version).
>

I agree. Blocking an orientation change can always be implemented by requesting a preferred orientation. [Edit: and the solution below is even better IMHO! :)]

> ** Proposal **
>
> partial interface DOMScreen {
> // Returns the current screen orientation.
> readonly attribute DOMString orientation;
>
> // Returns whether locking the screen to |orientation| is allowed.
> // Should return false if the |orientation| isn't known by the
> device
> // or if the application can't lock the screen orientation.
> boolean orientationAllowed(in DOMString orientation);
>
> // Locks the screen to |orientation| or to the current orientation
> if
> // no value is passed.
> // Throws if the application isn't allowed to lock orientation or
> if
> // |orientation| isn't known by the device.
> // If this changes the screen orientation, an 'orientationchange'
> // event will be fired.
> void lockOrientation([optional] in DOMString orientation);
>
> // Unlock the screen orientation.
> // Throws if the screen orientation isn't currently locked.
> // If this changes the screen orientation, an 'orientationchange'
> // event will be fired.
> void unlockOrientation();
>

I don't like explicit lock/unlock. Instead of that, and for consistency with other APIs near here, how about

DOMOrientationRequest requestOrientationLock([optional] in DOMString orientation);

? DOMOrientationRequest would have an |unlock()| method and the usual success/error callbacks. If we had that interface, would we still need |orientationAllowed()|?

What you propose has a few issues common to these global state changes

- what happens on multiple calls to requestOrientation()? Does the last call win? Similarly for nested <iframe>s. We might want to copy the idea of the "allowfullscreen" attribute of nested <iframes>, something like "alloworientationlock".

- are orientation locks conceptually a stack? That is, does releasing orientation lock i+1 lock the orientation to what was requested in i? This is how full-screen works, AIUI, so we should probably follow that model.

- what happens if background apps request an orientation lock? Does the request fail, or does it "silently succeed" and when the page is made visible the requested orientation is set? The former seems cleaner semantically, because pages could detect successful requests that don't actually change the orientation by inspecting the screen rect. But having those requests fail also seems like more of an author burden since authors would have to write code to request the orientation lock when being un-hidden.

cpearce, how does that work for requestFullscreen()?

> attribute Function onorientationchange;

Are these global event listener hooks still considered good style? I thought they weren't. I do agree that it makes sense to fire a global event on orientation change (do we already have that?), in addition to possible success/error callbacks for a request itself.

> };
>
> There are four possible orientations:
> - landscape-primary
> - landscape-secondary
> - portrait-primary
> - portrait-secondary
>
> (Feel free to bikeshed the names. Using
> landscape-reverse/portrait-reverse or portrait-upsidedown would be ok
> but it seems hard to find a better name for *-primary.)
>

What about "portrait", "landscape", "portrait-secondary", and "landscape-secondary"? Isn't the "primary" made clear by "-secondary"?

> ** Open questions **
>
> - Maybe we should use a ScreenLockRequest objects when
> lockOrientation()
> and unlockOrientation() are called. That might make the API a bit
> more
> heavy but might make things a bit more clearer too...

I'm in favor of that both for consistency, and because I think it's a better API than global lock/unlock.

> - Should we have orientation in the viewport meta tag? If we don't we
> need to be sure we can easily set the orientation before the first
> paint.
>

AFAIK, JS running before onload has as good a chance of locking orientation before first-paint as a CSS property or meta viewport. Someone who knows more should correct me though. If so, I would really prefer not to pile onto meta viewport.

Cheers,
Chris

Chris Jones

unread,
Jan 3, 2012, 11:58:13 PM1/3/12
to Mounir Lamouri, pba...@zynga.com, Chris Pearce, di...@apple.com, mozilla-d...@lists.mozilla.org
----- Original Message -----
> From: "Chris Jones" <cjo...@mozilla.com>
> To: "Mounir Lamouri" <mou...@lamouri.fr>
> Cc: pba...@zynga.com, "Chris Pearce" <cpe...@mozilla.com>, di...@apple.com, mozilla-d...@lists.mozilla.org
> Sent: Tuesday, January 3, 2012 8:52:57 PM
> Subject: Re: Screen orientation API proposal
>
> DOMOrientationRequest requestOrientationLock([optional] in DOMString
> orientation);
>
> ? DOMOrientationRequest would have an |unlock()| method and the
> usual success/error callbacks. If we had that interface, would we
> still need |orientationAllowed()|?
>

Also worth thinking about: should we allow users to explicitly override orientation locks, like explicitly exiting fullscreen? If so, should we notify holders of existing locks that the locks are invalidated?

cpearce, does the user explicitly exiting fullscreen mode pop back to the previously-fullscreened element, or clear the entire stack? I assume the latter, but whatever fullscreen does we should probably do with orientation locks.

Cheers,
Chris

Chris Jones

unread,
Jan 4, 2012, 1:19:42 AM1/4/12
to Mounir Lamouri, pba...@zynga.com, Chris Pearce, di...@apple.com, mozilla-d...@lists.mozilla.org
----- Original Message -----
> From: "Chris Jones" <cjo...@mozilla.com>
> To: "Mounir Lamouri" <mou...@lamouri.fr>
> Cc: pba...@zynga.com, "Chris Pearce" <cpe...@mozilla.com>, di...@apple.com, mozilla-d...@lists.mozilla.org
> Sent: Tuesday, January 3, 2012 8:52:57 PM
> Subject: Re: Screen orientation API proposal
>
> ----- Original Message -----
> > From: "Mounir Lamouri" <mou...@lamouri.fr>
> > To: mozilla-d...@lists.mozilla.org
> > Cc: pba...@zynga.com, di...@apple.com
> > Sent: Tuesday, January 3, 2012 6:18:33 AM
> > Subject: Screen orientation API proposal
> >
> > In one hand I believe having a declarative way would be nice
> > because
> > it
> > would allow webapps to easily set the orientation and also might
> > prevent
> > screen flickering if the orientation is set after the first paint.
>
> AFAIK having orientation be a CSS property instead of a JS API isn't
> better protection against flicker in general. There are still FOUCs
> to worry about. (Note, it might be more effective in practice.)
>

A solution to this problem for installed apps would be to have the apps declare a preferred orientation in their manifests.

Cheers,
Chris

Chris Pearce

unread,
Jan 4, 2012, 3:00:21 AM1/4/12
to Chris Jones, pba...@zynga.com, mozilla-d...@lists.mozilla.org, di...@apple.com, Mounir Lamouri

On 4/01/2012 5:58 p.m., Chris Jones wrote:
> ----- Original Message -----
>> From: "Chris Jones"<cjo...@mozilla.com>
>> To: "Mounir Lamouri"<mou...@lamouri.fr>
>> Cc: pba...@zynga.com, "Chris Pearce"<cpe...@mozilla.com>, di...@apple.com, mozilla-d...@lists.mozilla.org
>> Sent: Tuesday, January 3, 2012 8:52:57 PM
>> Subject: Re: Screen orientation API proposal
>>
>> DOMOrientationRequest requestOrientationLock([optional] in DOMString
>> orientation);
>>
>> ? DOMOrientationRequest would have an |unlock()| method and the
>> usual success/error callbacks. If we had that interface, would we
>> still need |orientationAllowed()|?
>>
> Also worth thinking about: should we allow users to explicitly override orientation locks, like explicitly exiting fullscreen? If so, should we notify holders of existing locks that the locks are invalidated?
>
> cpearce, does the user explicitly exiting fullscreen mode pop back to the previously-fullscreened element, or clear the entire stack? I assume the latter, but whatever fullscreen does we should probably do with orientation locks.

The former. Document.mozCancelFullScreen() will restore full-screen
state to the element that was previously full-screen. If there is no
previous full-screen element in either the document or a parent document
(full-screen mode isn't restored to former full-screen elements in child
documents), then the browser will "fully-exit full-screen", and return
the browser to normal mode. That's what our implementation does, and
it's what's specified (as Document.exitFullScreen()) in the draft W3C
spec [1].

We did it this way so that you can (for example) go from a full-screen
slide deck to watching a full-screen video and then return to your
full-screen slide deck without having to transition through
non-full-screen mode, in particular in the cross-origin case. I'm not
sure if you need to worry about similar cases for your API?

Cheers,
Chris Pearce


[1] http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html

Chris Jones

unread,
Jan 4, 2012, 3:34:38 AM1/4/12
to Chris Pearce, pba...@zynga.com, mozilla-d...@lists.mozilla.org, di...@apple.com, Mounir Lamouri
Thanks for the link. I see in section 5,

If the end user instructs the user agent to end a fullscreen session initiated via requestFullscreen(), fully exit fullscreen.

IIUC, that's what I had in mind, but I may misunderstand. Do we plan on implementing that? And if not, why not.

> We did it this way so that you can (for example) go from a
> full-screen
> slide deck to watching a full-screen video and then return to your
> full-screen slide deck without having to transition through
> non-full-screen mode, in particular in the cross-origin case. I'm not
> sure if you need to worry about similar cases for your API?
>

The idea is the same, composability of the API. There's not a janky intermediate state we have to worry about with screen orientation, but I think the fullscreen model is better for authors in the cases of nested content, like your example. And you guys did the hard spec work already for fullscreen, so we can ride on your coattails :).

Cheers,
Chris

Chris Pearce

unread,
Jan 4, 2012, 3:43:52 AM1/4/12
to Chris Jones, pba...@zynga.com, mozilla-d...@lists.mozilla.org, di...@apple.com, Mounir Lamouri
At the moment pressing the escape key on desktop, or the home key on
android will fully exit full-screen. Script doesn't have a way to
fully-exit full-screen directly though.

Cheers,
Chris P.

Mounir Lamouri

unread,
Jan 4, 2012, 12:36:58 PM1/4/12
to Chris Jones, pba...@zynga.com, Chris Pearce, Boris Zbarsky, di...@apple.com, mozilla-d...@lists.mozilla.org
On 01/04/2012 05:52 AM, Chris Jones wrote:
>> In one hand I believe having a declarative way would be nice because
>> it
>> would allow webapps to easily set the orientation and also might
>> prevent
>> screen flickering if the orientation is set after the first paint.
>
> AFAIK having orientation be a CSS property instead of a JS API isn't better protection against flicker in general. There are still FOUCs to worry about. (Note, it might be more effective in practice.)
>
> A CSS property seems very hard to specify to me. What happens if multiple style sheets request different orientation locks?

FWIW, I've never been thinking of a CSS property but of meta viewport.
We agree that using a CSS property is wrong.

> I don't like explicit lock/unlock. Instead of that, and for consistency with other APIs near here, how about
>
> DOMOrientationRequest requestOrientationLock([optional] in DOMString orientation);
>
> ? DOMOrientationRequest would have an |unlock()| method and the usual success/error callbacks. If we had that interface, would we still need |orientationAllowed()|?

I'm not sure we need to have a |unlock()| method in the Request object
because that would require to keep that object around for a long time
and there is no obvious reason to require that object to call
|unlock()|. I understand it would be more consistent with other APIs but
we don't have the same requirements here I believe.

> What you propose has a few issues common to these global state changes
>
> - what happens on multiple calls to requestOrientation()? Does the last call win? Similarly for nested<iframe>s. We might want to copy the idea of the "allowfullscreen" attribute of nested<iframes>, something like "alloworientationlock".

Last call wins. And for iframes, I was hoping to get to that later but
we could indeed use a similar mechanism fullscreen is using.

> - are orientation locks conceptually a stack? That is, does releasing orientation lock i+1 lock the orientation to what was requested in i? This is how full-screen works, AIUI, so we should probably follow that model.

I would prefer not because it would make things uselessly complex. We
are not in a situation where multiple apps could interfere because this
is a per-app lock.

> - what happens if background apps request an orientation lock? Does the request fail, or does it "silently succeed" and when the page is made visible the requested orientation is set? The former seems cleaner semantically, because pages could detect successful requests that don't actually change the orientation by inspecting the screen rect. But having those requests fail also seems like more of an author burden since authors would have to write code to request the orientation lock when being un-hidden.

Orientation locks would only apply to the current tab. Which means if
APP-A requires portrait and APP-B requires landscape, APP-A will be
shown in portrtait, APP-B in landscape and APP-C using users preferences
(like sensors).

>> attribute Function onorientationchange;
>
> Are these global event listener hooks still considered good style? I thought they weren't. I do agree that it makes sense to fire a global event on orientation change (do we already have that?), in addition to possible success/error callbacks for a request itself.

Why would they be bad style? We need such an event so an app can know
when there is an orientation change. In practice, it's likely that a
resize event will be fired at the same time but even if, we want a
specific event.

>> There are four possible orientations:
>> - landscape-primary
>> - landscape-secondary
>> - portrait-primary
>> - portrait-secondary
>>
>> (Feel free to bikeshed the names. Using
>> landscape-reverse/portrait-reverse or portrait-upsidedown would be ok
>> but it seems hard to find a better name for *-primary.)
>>
>
> What about "portrait", "landscape", "portrait-secondary", and "landscape-secondary"? Isn't the "primary" made clear by "-secondary"?

I do not think this would work because portrait/landscape should be used
as a "any {portrait,landscape} orientation type".

>> - Should we have orientation in the viewport meta tag? If we don't we
>> need to be sure we can easily set the orientation before the first
>> paint.
>>
>
> AFAIK, JS running before onload has as good a chance of locking orientation before first-paint as a CSS property or meta viewport. Someone who knows more should correct me though. If so, I would really prefer not to pile onto meta viewport.

bz must know that :) (CC'd)

--
Mounir

Mounir Lamouri

unread,
Jan 4, 2012, 12:39:03 PM1/4/12
to Chris Jones, pba...@zynga.com, Chris Pearce, di...@apple.com, mozilla-d...@lists.mozilla.org
On 01/04/2012 07:19 AM, Chris Jones wrote:
>>> In one hand I believe having a declarative way would be nice
>>> because
>>> it
>>> would allow webapps to easily set the orientation and also might
>>> prevent
>>> screen flickering if the orientation is set after the first paint.
>>
>> AFAIK having orientation be a CSS property instead of a JS API isn't
>> better protection against flicker in general. There are still FOUCs
>> to worry about. (Note, it might be more effective in practice.)
>>
>
> A solution to this problem for installed apps would be to have the
apps declare a preferred orientation in their manifests.

Indeed. This is what Android and iOS do. However, we want non-installed
web apps to have a non-degraded experience so even if we should keep
that solution in mind for installed apps, this is not enough.

--
Mounir

Chris Jones

unread,
Jan 4, 2012, 7:43:33 PM1/4/12
to Mounir Lamouri, pba...@zynga.com, Chris Pearce, di...@apple.com, mozilla-d...@lists.mozilla.org
----- Original Message -----
> From: "Mounir Lamouri" <mou...@lamouri.fr>
> To: "Chris Jones" <cjo...@mozilla.com>
> Cc: pba...@zynga.com, "Chris Pearce" <cpe...@mozilla.com>, di...@apple.com, mozilla-d...@lists.mozilla.org
> Sent: Wednesday, January 4, 2012 9:39:03 AM
> Subject: Re: Screen orientation API proposal
>
Non-installed apps already have a degraded experience, sort of by definition. But I agree that we want a solution for arbitrary pages that's as good as meta viewport.

Cheers,
Chris

Chris Jones

unread,
Jan 4, 2012, 7:42:16 PM1/4/12
to Mounir Lamouri, pba...@zynga.com, Chris Pearce, Boris Zbarsky, di...@apple.com, mozilla-d...@lists.mozilla.org
----- Original Message -----
> From: "Mounir Lamouri" <mou...@lamouri.fr>
> To: "Chris Jones" <cjo...@mozilla.com>
> Cc: pba...@zynga.com, di...@apple.com, mozilla-d...@lists.mozilla.org, "Chris Pearce" <cpe...@mozilla.com>,
> "Boris Zbarsky" <bzba...@MIT.EDU>
> Sent: Wednesday, January 4, 2012 9:36:58 AM
> Subject: Re: Screen orientation API proposal
>
> On 01/04/2012 05:52 AM, Chris Jones wrote:
> > I don't like explicit lock/unlock. Instead of that, and for
> > consistency with other APIs near here, how about
> >
> > DOMOrientationRequest requestOrientationLock([optional] in
> > DOMString orientation);
> >
> > ? DOMOrientationRequest would have an |unlock()| method and the
> > usual success/error callbacks. If we had that interface, would we
> > still need |orientationAllowed()|?
>
> I'm not sure we need to have a |unlock()| method in the Request
> object
> because that would require to keep that object around for a long time
> and there is no obvious reason to require that object to call
> |unlock()|.

It represents the orientation lock that's held. I find it quite natural to release that object. The global unlock doesn't compose because of the

for (let i = 0; i < 50; ++i) screen.unlockOrientation()

issue. Which buggy nested apps would exhibit, don't care about "malicious" unlocking.

> I understand it would be more consistent with other APIs
> |but
> we don't have the same requirements here I believe.
>

Independent chunks of code are requesting global state changes. My reasoning for why I think "lock objects" are better is in https://bugzilla.mozilla.org/show_bug.cgi?id=697132#c15 . Essentially, in the simplest case, the API difference isn't noticeable, and in complex cases lock objects compose better. Why propose a worse API if it's not simpler?

> > - are orientation locks conceptually a stack? That is, does
> > releasing orientation lock i+1 lock the orientation to what was
> > requested in i? This is how full-screen works, AIUI, so we
> > should probably follow that model.
>
> I would prefer not because it would make things uselessly complex. We
> are not in a situation where multiple apps could interfere because
> this
> is a per-app lock.
>

libpdf.js might request a lock on top of main.js's, and a nested <iframe> might do that same. That's the complicated case above. A global lock/unlock means it's extremely difficult to write composable code. But the simplest case isn't simpler, so I don't see the win.

> > - what happens if background apps request an orientation lock?
> > Does the request fail, or does it "silently succeed" and when
> > the page is made visible the requested orientation is set? The
> > former seems cleaner semantically, because pages could detect
> > successful requests that don't actually change the orientation
> > by inspecting the screen rect. But having those requests fail
> > also seems like more of an author burden since authors would
> > have to write code to request the orientation lock when being
> > un-hidden.
>
> Orientation locks would only apply to the current tab. Which means if
> APP-A requires portrait and APP-B requires landscape, APP-A will be
> shown in portrtait, APP-B in landscape and APP-C using users
> preferences
> (like sensors).
>

My question was what happens when a background tab/app requests a lock. I realize now that there's a third solution, which is to remember the request but only grant it (fire the success callback) when the tab becomes visible.

> >> attribute Function onorientationchange;
> >
> > Are these global event listener hooks still considered good style?
> > I thought they weren't. I do agree that it makes sense to fire a
> > global event on orientation change (do we already have that?), in
> > addition to possible success/error callbacks for a request itself.
>
> Why would they be bad style? We need such an event so an app can know
> when there is an orientation change. In practice, it's likely that a
> resize event will be fired at the same time but even if, we want a
> specific event.
>

main.js: window.onorientationchange = foo;
libpdf.js: window.onorientationchange = bar;

Shouldn't we be using addEventListener() exclusively?

> >> There are four possible orientations:
> >> - landscape-primary
> >> - landscape-secondary
> >> - portrait-primary
> >> - portrait-secondary
> >>
> >> (Feel free to bikeshed the names. Using
> >> landscape-reverse/portrait-reverse or portrait-upsidedown would be
> >> ok
> >> but it seems hard to find a better name for *-primary.)
> >>
> >
> > What about "portrait", "landscape", "portrait-secondary", and
> > "landscape-secondary"? Isn't the "primary" made clear by
> > "-secondary"?
>
> I do not think this would work because portrait/landscape should be
> used
> as a "any {portrait,landscape} orientation type".
>

Oh, do you intend for "use any {portrait,landscape} orientation" to not change the current one if the orientation is already "{portrait-*,landscape-*}"? OK, that makes sense.

Cheers,
Chris

Chris Jones

unread,
Jan 4, 2012, 8:47:12 PM1/4/12
to Mounir Lamouri, pba...@zynga.com, Chris Pearce, di...@apple.com, mozilla-d...@lists.mozilla.org
----- Original Message -----
> From: "Chris Jones" <cjo...@mozilla.com>
> To: "Mounir Lamouri" <mou...@lamouri.fr>
> Sent: Tuesday, January 3, 2012 8:52:57 PM
> Subject: Re: Screen orientation API proposal
>
> ----- Original Message -----
> > From: "Mounir Lamouri" <mou...@lamouri.fr>
> > To: mozilla-d...@lists.mozilla.org
> > Cc: pba...@zynga.com, di...@apple.com
> > Sent: Tuesday, January 3, 2012 6:18:33 AM
> > Subject: Screen orientation API proposal
> >
> - what happens if background apps request an orientation lock? Does
> the request fail, or does it "silently succeed" and when the page
> is made visible the requested orientation is set? The former seems
> cleaner semantically, because pages could detect successful
> requests that don't actually change the orientation by inspecting
> the screen rect. But having those requests fail also seems like
> more of an author burden since authors would have to write code to
> request the orientation lock when being un-hidden.
>
> cpearce, how does that work for requestFullscreen()?
>

Full-screen requests are only granted when they're made from a user-input-event handler, which skirts this issue entirely. Orientation change isn't security sensitive, but a page wildly flipping the orientation would be an extremely effective DoS of the UI. So maybe we should use a model in which
- user-initiated requests are always granted immediately
- the first non-user-initiated request is granted immediately, but sets an interval of a few seconds in which all other non-user-initiated requests are blocked.

I think this satisfies the use cases of an
- "orientation lock" button in the UI of an ebook reader: request is always user-initiated so always granted immediately
- game that wants to load in explicit orientation: only makes one request and it's non-user-initiated, but it's granted immediately.

without hurting perceived responsiveness, but also guarding against UI DoS.

Cheers,
Chris

Mounir Lamouri

unread,
Jan 10, 2012, 11:04:30 AM1/10/12
to Chris Jones, pba...@zynga.com, Chris Pearce, Boris Zbarsky, di...@apple.com, mozilla-d...@lists.mozilla.org
On 01/05/2012 01:42 AM, Chris Jones wrote:
>> I'm not sure we need to have a |unlock()| method in the Request
>> object
>> because that would require to keep that object around for a long time
>> and there is no obvious reason to require that object to call
>> |unlock()|.
>
> It represents the orientation lock that's held. I find it quite natural to release that object. The global unlock doesn't compose because of the
>
> for (let i = 0; i< 50; ++i) screen.unlockOrientation()
>
> issue. Which buggy nested apps would exhibit, don't care about "malicious" unlocking.
>
>> [...]
>
> Independent chunks of code are requesting global state changes. My reasoning for why I think "lock objects" are better is in https://bugzilla.mozilla.org/show_bug.cgi?id=697132#c15 . Essentially, in the simplest case, the API difference isn't noticeable, and in complex cases lock objects compose better. Why propose a worse API if it's not simpler?
>
>> [...]
>
> libpdf.js might request a lock on top of main.js's, and a nested<iframe> might do that same. That's the complicated case above. A global lock/unlock means it's extremely difficult to write composable code. But the simplest case isn't simpler, so I don't see the win.

Do we really care about two libraries/iframes orientation requests being
in conflict? Seems like whatever we do here, we will end up very likely
not doing what was expected because such a situation is bogus.

I could easily be convinced to have a request object when a lock request
is done but I'm not sure unlocking trough this request object is easier
than just calling an unlock method.

However, if we happen to have that kind of pattern for other APIs, we
could probably do that for consistency. It seems like there is not a
clear agreement around that in bug 697132 yet, though.

>> Orientation locks would only apply to the current tab. Which means if
>> APP-A requires portrait and APP-B requires landscape, APP-A will be
>> shown in portrtait, APP-B in landscape and APP-C using users
>> preferences
>> (like sensors).
>>
>
> My question was what happens when a background tab/app requests a lock. I realize now that there's a third solution, which is to remember the request but only grant it (fire the success callback) when the tab becomes visible.

Yes, I think that should be per-tabs. That means if TAB-A requests
portrait mode and TAB-B requires landscape mode, and both are already
loaded, going from one to the other will not fire "orientationchange"
because the orientation of the tab wouldn't have changed. IOW, APP-A
doesn't need to know that the user went to another app with a different
orientation given that nothing changed for it.

>>> Are these global event listener hooks still considered good style?
>>> I thought they weren't. I do agree that it makes sense to fire a
>>> global event on orientation change (do we already have that?), in
>>> addition to possible success/error callbacks for a request itself.
>>
>> Why would they be bad style? We need such an event so an app can know
>> when there is an orientation change. In practice, it's likely that a
>> resize event will be fired at the same time but even if, we want a
>> specific event.
>
> main.js: window.onorientationchange = foo;
> libpdf.js: window.onorientationchange = bar;
>
> Shouldn't we be using addEventListener() exclusively?

We seem to widely add that kind of methods. I agree that it might be
error prone. I would be interesting to hear what Jonas thinks.

--
Mounir

Chris Jones

unread,
Jan 11, 2012, 5:57:39 AM1/11/12
to Mounir Lamouri, pba...@zynga.com, Chris Pearce, Boris Zbarsky, di...@apple.com, mozilla-d...@lists.mozilla.org
----- Original Message -----
> From: "Mounir Lamouri" <mou...@lamouri.fr>
> To: "Chris Jones" <cjo...@mozilla.com>
> Cc: pba...@zynga.com, "Chris Pearce" <cpe...@mozilla.com>, "Boris Zbarsky" <bzba...@MIT.EDU>, di...@apple.com,
> mozilla-d...@lists.mozilla.org
> Sent: Tuesday, January 10, 2012 8:04:30 AM
> Subject: Re: Screen orientation API proposal
>
I agree. I don't care about requests that conflict, but rather requests that are intended to nest. For example, libpdf.js locks portrait orientation, but I click a link to a video and the video-player library that's loaded in an <iframe> locks landscape. Global lock/unlock makes that harder to get right, in exchange for a benefit that I still don't see yet.

> I could easily be convinced to have a request object when a lock
> request
> is done but I'm not sure unlocking trough this request object is
> easier
> than just calling an unlock method.
>

I don't think it's any harder, and I think it's a better API.

> >> Orientation locks would only apply to the current tab. Which means
> >> if
> >> APP-A requires portrait and APP-B requires landscape, APP-A will
> >> be
> >> shown in portrtait, APP-B in landscape and APP-C using users
> >> preferences
> >> (like sensors).
> >>
> >
> > My question was what happens when a background tab/app requests a
> > lock. I realize now that there's a third solution, which is to
> > remember the request but only grant it (fire the success callback)
> > when the tab becomes visible.
>
> Yes, I think that should be per-tabs. That means if TAB-A requests
> portrait mode and TAB-B requires landscape mode, and both are already
> loaded, going from one to the other will not fire "orientationchange"
> because the orientation of the tab wouldn't have changed. IOW, APP-A
> doesn't need to know that the user went to another app with a
> different
> orientation given that nothing changed for it.
>

Well, that still doesn't quite answer the original question. What happens if TAB-A requests portrait when hidden, while TAB-B is visible? I think that going by the model of full-screen, we probably want the behavior discussed in the last message, plus a delayed firing of a orientationchange/success event when TAB-A is made visible again.

Cheers,
Chris

Mounir Lamouri

unread,
Jan 11, 2012, 6:14:43 AM1/11/12
to Chris Jones, pba...@zynga.com, Chris Pearce, Boris Zbarsky, di...@apple.com, mozilla-d...@lists.mozilla.org
On 01/11/2012 11:57 AM, Chris Jones wrote:
> Well, that still doesn't quite answer the original question. What happens if TAB-A requests portrait when hidden, while TAB-B is visible? I think that going by the model of full-screen, we probably want the behavior discussed in the last message, plus a delayed firing of a orientationchange/success event when TAB-A is made visible again.

TAB-B isn't affected if TAB-A request an orientation change while TAB-B
is visible. And TAB-A should get an event when visible again if the
orientation did actually change. Though, if TAB-A gets hidden again,
re-showing it will not fire another event.

For the lock/unlock model, I think I will follow your proposal, the use
case you gave for the inner-video convinced me.
Then, do we want to keep a method to know if an orientation is allowed
or should we expect users to try to lock? Trying to lock and using the
returned request would work (assuming an error event will be fired if
the lock isn't allowed) but it might make the API a bit more annoying
because checking for orientation availability would be async.
Though, if a lock is requested, most likely, the app will have to react
asynchronously so assuming the app will check for orientation
availability this way might be as good? Maybe we could just do that and
add a sync method later if needed?

--
Mounir

Chris Jones

unread,
Jan 11, 2012, 3:39:05 PM1/11/12
to Mounir Lamouri, pba...@zynga.com, Chris Pearce, Boris Zbarsky, di...@apple.com, mozilla-d...@lists.mozilla.org
----- Original Message -----
> From: "Mounir Lamouri" <mou...@lamouri.fr>
> To: "Chris Jones" <cjo...@mozilla.com>
> Cc: pba...@zynga.com, "Chris Pearce" <cpe...@mozilla.com>, "Boris Zbarsky" <bzba...@MIT.EDU>, di...@apple.com,
> mozilla-d...@lists.mozilla.org
> Sent: Wednesday, January 11, 2012 3:14:43 AM
> Subject: Re: Screen orientation API proposal
>
> On 01/11/2012 11:57 AM, Chris Jones wrote:
> > Well, that still doesn't quite answer the original question. What
> > happens if TAB-A requests portrait when hidden, while TAB-B is
> > visible? I think that going by the model of full-screen, we
> > probably want the behavior discussed in the last message, plus a
> > delayed firing of a orientationchange/success event when TAB-A is
> > made visible again.
>
> TAB-B isn't affected if TAB-A request an orientation change while
> TAB-B
> is visible. And TAB-A should get an event when visible again if the
> orientation did actually change. Though, if TAB-A gets hidden again,
> re-showing it will not fire another event.
>

Sounds reasonable to me.

> Then, do we want to keep a method to know if an orientation is
> allowed
> or should we expect users to try to lock?

I'm not familiar with the use cases for testing for a supported orientation. I guess one use case could be for something like an ebook reader that has a "lock orientation" button in the UI. If the screen orientation is fixed, there's no point in showing the button. But I'm not sure how I would want to write the check in that case ...

if (screen.orientationAllowed("portait") && screen.orientationAllowed("landscape"))
showLockButton();

? In that case, I would definitely want to have a synchronous capability-testing API.

I remembered one more issue: some phones will refuse to enter what's been called here a "portait-secondary" orientation, in which hardware buttons that are usually below the screen are oriented "above" the screen. So exposing a capability test for "portait-secondary", or firing an error event on attempting entering it, adds a fingerprinting bit. Since we'll need to emulate portrait-secondary for that reason, I think there will only be two possible "capability states" exposed to content
- orientation is fixed
- all orientations are supported (possibly emulated, but content can't tell)

So maybe a simpler solution for the |orientationAllowed()| API is just a

boolean isOrientationFixed;

bit. (Name tbd.)

Cheers,
Chris
0 new messages