screen-orientation icon indicating copy to clipboard operation
screen-orientation copied to clipboard

Add can-lock-orientation media feature to detect if locking is possible

Open makotokato opened this issue 3 years ago • 24 comments

(If this is already discussed, please close this)

When I look this spec, I cannot find feature detection section. Even If orientation.lock isn't supported, Blink and Gecko have this method in orientation. Then when calling it, NotSupportedError is throw if browser doesn't support it.

For feature detection of orientation.lock, is there a way of feature detection without using orientation.lock like following? And I hope that we add feature detection section for lock.

async function isLockSupport() {
  try {
    await orientation.lock('any');
    orientation.unlock();
    return true;
  } catch (e) {
  }
  return false;
}

makotokato avatar Jan 31 '22 04:01 makotokato

Cannot. Blink and Gecko implement window.screen.orientation object even if Desktop version that is "lock" is unsupported, so it doesn't work.

-- Makoto

2022年1月31日(月) 16:14 Thomas Steiner @.***>:

Window.orientation https://developer.mozilla.org/en-US/docs/Web/API/Window/orientation is deprecated. You should instead use Screen.orientation https://developer.mozilla.org/en-US/docs/Web/API/Screen/orientation, which you can properly feature-detect via the snippet below:

if ('ScreenOrientation' in window) { // Supported.} `

— Reply to this email directly, view it on GitHub https://github.com/w3c/screen-orientation/issues/206#issuecomment-1025443201, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHLVWVBD4VILBZCD7DWZ4DUYYZGDANCNFSM5NFHUPBQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you authored the thread.Message ID: @.***>

makotokato avatar Jan 31 '22 07:01 makotokato

Sorry, yes, I realized this as well, which is why I deleted the comment. I guess it really boils down to try..catching.

tomayac avatar Jan 31 '22 07:01 tomayac

The only way to allow this would be to add a new method. However, this may never succeed for a variety of reasons. For example, the user may prevent the screen from being rotated for accessibility reasons. Then, privacy, we wouldn't want to reveal that fact about the user.

I think we should also consider gating this API on a user gesture, but it's a separate issue.

marcoscaceres avatar Oct 07 '22 06:10 marcoscaceres

So yeah, I think at a minimum, we might need a supportsLocking boolean or something, because locking to "any" is still a kind of locking.

The use case being, if you are building a UI that has rotate buttons, it doesn't make sense to enable them or show them if you can't rotate the screen.

Alternatively (I'm not sure this is better): we could tell user agents to not expose the .lock() on platforms they are sure don't support locking at all (e.g., most desktops).

marcoscaceres avatar Oct 10 '22 05:10 marcoscaceres

Alternatively (I'm not sure this is better): we could tell user agents to not expose the .lock() on platforms they are sure don't support locking at all (e.g., most desktops).

We might want to build a pattern for this. Could be great if we can have a list of APIs that always fail on certain session-permanent situation (that never changes in the current session).

saschanaz avatar Oct 10 '22 15:10 saschanaz

@domenic is pushing a pattern of sorts whereby we use supports() static methods (see HTMLScriptElement for instance). That seems somewhat reasonable here. Could maybe also be used to determine whether a platform supports multiple portrait orientations or not (needs use cases first).

annevk avatar Oct 10 '22 17:10 annevk

Cool, but I mean specifically for things that always fail, since it doesn't quite make sense to have functions that are never going to work.

saschanaz avatar Oct 10 '22 17:10 saschanaz

That pattern is more for things which are not detectable in other ways, e.g. declarative markup features. In this case, just trying to call the function and seeing if it fails seems better... try/catch is just as good as if/else, in general.

domenic avatar Oct 11 '22 01:10 domenic

@domenic, the problem here is that:

  • a web app might need to provide significant UI (rotate button(s)) before it knows if it can even rotate.
  • the only way to know if it will change orientation is by actually changing orientation.

So, imagine (this would be really bad for users):

// lets' figure out what's supported
const supported = [];
for (const o in orientations) {
   try {
       await screen.orientation.lock(o);
       supported.push(o);
    } catch { continue; }
}
screen.orientation.unlock();
showUI(supported);

marcoscaceres avatar Oct 11 '22 01:10 marcoscaceres

Indeed, try/catch only works if you're guaranteed the try never side effects. That's not the case here. Anyway, it sounds like ScreenOrientation.supports() is a thing we could do.

annevk avatar Oct 11 '22 06:10 annevk

Just thinking out loud here... a .canLock() method could be an alternative.

To return true, the .canLock() method presupposes that:

  • all orientations are supported in one way or another (e.g, "portrait-secondary" is treated as "portrait-primary").
  • all pre-lock conditions are met (e.g., is in full screen).
  • The OS supports locking and/or there isn't something else that would prevent the lock (without revealing what "something else" is, for privacy reasons).
  • The document fully active.

(The only thing it wouldn't check for is transient activation)

Additionally, I think all the preconditions of .canLock() can be checked synchronously: it would basically perform all the synchronous checks that .lock() performs before doing its "in parallel" steps.

marcoscaceres avatar Oct 18 '22 06:10 marcoscaceres

Wouldn't that prevent using the API when you're not fullscreen to detect if you can go fullscreen and change the orientation?

annevk avatar Oct 18 '22 07:10 annevk

yes, indeed. Ok, so scratch checking the preconditions.

If we assume the following invariant:

.lock() must support all orientations in one way or another, even if those orientations get mapped to something else (e.g., landscape-secondary -> landscape-primary, natural -> portrait-primary).

Then that only requires a single check: ".canProbablyLock" (boolean) which would be: "they're nothing preventing user agent from attempting to lock the screen orientation".

On desktop platforms, this would return false: it's not common convention to support lock()'ing.

On other platforms, it would return true - but .lock() might still fail for a number of reasons.

marcoscaceres avatar Oct 27 '22 07:10 marcoscaceres

Some down sides:

  • people might use it to detect "mobile browsers". It's literally what people were doing with the old API: https://stackoverflow.com/questions/11381673/detecting-a-mobile-browser
  • it's a fingerprinting bit - but might be unavoidable.
  • It's basically the same as not exposing .lock() at all.

marcoscaceres avatar Oct 27 '22 07:10 marcoscaceres

Just noting that it is hypothetically possible that a user could transfer the document from one "desktop class" screen to a mobile device, which could allow changing orientation. So this may require a companion event.

marcoscaceres avatar Nov 14 '22 05:11 marcoscaceres

It might be prudent to go down the CSS route with this, as the primary use case revolves around showing/hiding bits of UI.

Would it be fair to say that the ability to change orientation is really describing a media feature? Like, can-lock-orientation:

@media screen and (can-lock-orientation) {
    
}

marcoscaceres avatar Nov 15 '22 00:11 marcoscaceres

Doesn't seem entirely unreasonable. 😊

annevk avatar Nov 15 '22 08:11 annevk

@makotokato, what do you think? Should we pursue the CSS media feature route?

marcoscaceres avatar Nov 16 '22 03:11 marcoscaceres

@makotokato, gentle ping. Would like gauge your level of interest before I set about specifying it.

marcoscaceres avatar Nov 28 '22 02:11 marcoscaceres

I guess that it may not better to use media query. If using media query, I guess it is better to add orientation-lock media feature like display-mode of full screen. orientation feature doesn't have all information of orientation lock.

I vote orientation.canLock.

makotokato avatar Nov 28 '22 04:11 makotokato

While I'm agnostic to the method used, it does seem potentially useful to expose a 'can probably lock' signal. Based on my novice reading of underlying OS APIs, user agents may be incapable of representing signals stronger than 'probably', right?

michaelwasserman avatar May 10 '23 00:05 michaelwasserman

@makotokato, do you still feel strongly that this should be an API over the media query? Or are you ok with us going down the media query route?

marcoscaceres avatar Sep 27 '24 22:09 marcoscaceres

TPAC 2024: Media query is ok with @michaelwasserman from Chromium and @marcoscaceres from WebKit. @marcoscaceres is following up with Mozilla.

dmurph avatar Sep 27 '24 22:09 dmurph

do you still feel strongly that this should be an API over the media query? Or are you ok with us going down the media query route?

It is also OK as media query.

makotokato avatar Oct 18 '24 09:10 makotokato