-
Notifications
You must be signed in to change notification settings - Fork 25
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
Putting the event target behind a permission #30
Comments
Dude, I did a happy dance when I saw you had cycles to drop by and give your always valuable feedback. Please keep being "that guy" |
Here's a sketch that keeps the array separate, and has a 'basic' permission that just exposes const basicScreenDetails = await getScreenDetails();
basicScreenDetails.hasMultilpleScreens; // boolean.
basicScreenDetails.screens[0]; // Primary ScreenInfo.
basicScreenDetails.screens[1]; // Undefined, even if there are multiple screens.
basicScreenDetails.addEventListener('change', () => {
// hasMultilpleScreens or screens[0] has changed.
});
const screenDetails = await getScreenDetails({ allScreens: true });
screenDetails.hasMultilpleScreens; // boolean.
screenDetails.screens[0]; // Primary ScreenInfo.
screenDetails.screens[1]; // ScreenInfo for second screen, or undefined.
screenDetails.addEventListener('change', () => {
// One or many of the entries in screenDetails.screens has changed.
}); |
I'm very happy to get your API design input; thanks! I hope we'll get to chat; some initial qs:
I really appreciate the feedback, and do think a new interface/namespace may be warranted. |
Mostly because I couldn't think of any other part of the platform that behaves that way. Although, now I think about it, that's how device orientation works, although it's really badly spec'd – it mentions permissions, but not of the event-dispatching parts of the spec check for the permission. I think maybe permissions were kinda stuck on afterwards there. Most APIs seem to follow a pattern where the developer asks for a thing, and if they're allowed the thing they're given the thing, and that thing is the thing they didn't have before. If we decide it's ok to keep the event on the global, then the information should be on the global too. The weirdness right now is that some parts of the API are behind a promise solely for permission purposes, but other parts aren't. It should be one or the other. @kenchris I'm interested in your take here. It didn't come up in TAG review, but it seems like an important part of platform consistency.
Right now, the problem is that the event fires, but the information isn't available. However, I don't think the solution is to add that information to the event. In fact, the TAG recommends against it. I think the information should be available synchronously once permission is granted. I would only subclass the event if you want to provide information beyond current state. For example, it might be appropriate for the event to have information around what changed vs the previous state, but I don't think that's urgent.
If it's a seperate permission, I guess you would. It seems bad for interop to have some browsers put that behind a permission and others not. If it was one way or the other, the design problem goes away. I guess you could have something like: const basicScreenDetails = await getScreenDetails();
const allScreenDetails = await getScreenDetails({ allScreens: true }); Where basic screen details would have less info.
Yes 😄 sorry, I've updated it.
I think we try to avoid having not-quite-arrays these days, in favour of real arrays.
If re-adding the permission brings all of the live objects back to life, then I guess the permission API is fine. |
I've updated #30 (comment) to cater for two levels of permission. |
We have discussed before in the TAG, that we really don't want methods to sometimes return arrays and others times objects - this came up with native file system as well |
@kenchris I agree, but none of the proposals here do that |
This indeed sounds weird. I also think that a "change" event on what is returned from the method makes more sense. In that case we need to return an object and that would then have the array associated. In many ways this is not that different from something like say the OrientationSensor (it is constructed and can throw, but it could have been returned by an async getter instead). That has the values attached as properties and an event that fires when they change. interface ScreenInfo : EventTarget {
readonly attribute FrozenArray<Screen> screens;
attribute EventHandler onchange;
};
``` |
Your example in this comment #30 (comment) did, depending on objects given to the method |
Agreed. I was looking at those specs for inspiration. Any idea what happened with device orientation, which does seem to be a global event gated behind a permission? I assume it's just a legacy mess.
🤔 I don't think it did. It's gone though a few edits, but it always returned an object that has a |
OK then I misunderstood
That to me indicated that the basicScreenDetails represented the first screen (it even has properties like primary and screens is undefined). That seems messy. So the objects represents a screen itself, or sometimes it instead holds an array of screens. In this case |
If you don't have permission the constructors will fail, if I recall correctly |
The Generic Sensors kind of have the difference in that you need to call "start" before they check the permission and then you get an error if that is the case. OrientationSensor is based on that https://www.w3.org/TR/orientation-sensor/ |
Ohh, good call. I've updated the sketch.
That spec doesn't have any constructors (aside from the event constructors). You might be thinking of orientation sensor rather than device orientation.
Yeah, I don't think the constructor model makes sense for this API, because there aren't advantages to start/stop. You're just getting info that's readily available, but behind a permission. As in, there's no battery impact to observing this stuff, unlike a gyroscope. |
|
The idea is that a basic permission would tell you there are multiple screens, but wouldn't give you the details. If It does create a weird situation where |
That seems very confusing. We are not getting of |
Which part is confusing? I think the idea is for some browsers in some situations to provide |
But that is kind of a trap, because people often change configuration and add and remove screens, like when plugging/unplugging laptop. And this is also adding additional entropy to fingerprinting (I am sure that will come up in privacy reviews). |
What's the trap?
I guess that's why it's potentially behind a permission. It isn't clear to me yet what the conditions are for this being auto-granted. |
As it can change, the site would have to listen to a kind of "screen change" event and act when "isMultipleScreens" becomes true, but you want to guard the event behind the permission, so... |
The event is already described in the sketch: const basicScreenDetails = await getScreenDetails();
basicScreenDetails.hasMultilpleScreens; // boolean.
basicScreenDetails.screens[0]; // Primary ScreenInfo.
basicScreenDetails.screens[1]; // Undefined, even if there are multiple screens.
basicScreenDetails.addEventListener('change', () => {
// hasMultilpleScreens or screens[0] has changed.
}); For example, the values on the sensors API can change, and you need an event to know when that happens, and I wouldn't call that a 'trap'. |
I guess that I don't get the point about the permissions. As I read, you want to avoid permission and still know whether there are more than one screen connected as well as listen to a change event. But in order to actually get the info about multiple screens you would need a permission and call the exact same API. To me that feels a bit counter intuitive and developer hostile, but maybe I need to think more about this |
I also don't think that the name "hasMultipleScreens" is that fitting. It is not always "has" because it is not always permanent as they are most likely external displays. For dual screen devices so far we consider them one screen and one viewport, and changing that whether the browser/PWA/window spans across both physical screens is probably going to be quite confusing - @zouhir @darktears We really need to figure out how to handle this properly. Currently I see a dual screen as one virtual screen (and one viewport) where apps might be able to layout at one part. If apps really want different windows per screen instead, we need to figure out how to handle that. On the other hand I have seen new laptops that have an actual screen in the trackpad, but in order for developers to actually use that they would need to know that it is a track pad screen and not just another external display. |
There are two levels of permission that gain you different amounts of detail:
In particular trusted situations, it seems like 1 will be auto granted. In fact, there are cases where we already expose this. If two windows from the same origin are given different If we're pushing this discussion as far as 'hostility', it seems bad to put the user through a permission prompt only to gain details you already know. If I was to point to an element of counter-intuitivity here, it would be that. If the developer already has access to |
'has' doesn't infer immutability. I have 5 apples. I give 5 apples away. I no longer have 5 apples.
That isn't what this spec is about. I recommend reading the explainer. One example I'm personally interested in: When I give a talk I have a notes window. I have to manually drag this across to the secondary screen and maximize it. This is a real pain as the secondary screen is often behind me. This API would allow window placement on an auxiliary screen.
That isn't typically how operating systems behave.
This spec appears to have figured a lot of that out and has been reviewed by the TAG. I'm just filing issues to clear up some of the details.
Is window placement typically possible in those situations? |
Good point that some of this can already be inferred today, thought maybe not in a reliable way as it does require the user to have windows from the same origin on different screens, which is not always the case. I really would like to better understand the privacy and security issues associated with exposing this info, as well as what is already exposed today - or which can be inferred in certain cases. I also think that there is a difference between screens being internal or external |
There is a bit for that https://webscreens.github.io/window-placement/#dom-screeninfo-internal, but doesn't seem documented. |
That might be, but it has been one of the feedback we have given and what we have heard from elsewhere - this spec and the foldables specs needs to be able to work together in harmony. These things are changing rapidly. Laptops are getting multiple screens (many models in the pipeline for the coming years) and even external ones are still being connected.
Those things are changing :-) I have insights that I unfortunately cannot share here. But a public example is the Surface Duo that works exactly that way, as well as the postponed Surface Neo.
As you can attack external displays and projectors, yes it is still very relevant. |
I meant, can you place a browser window on your trackpad? |
To be honest, I am not sure at this point, but it might very well be possible or at least in the future. @darktears might know |
This spec is about aiding placement of browser windows on auxiliary screens. |
Just checked, you can indeed. It can be used as an auxiliary screen - the new ASUS laptops allow that |
Nice! If general window placement is possible there, then it seems like this spec has it covered. |
Microsoft proposed the Window Segmentation API (@zouhir), but it is actually more a screen segmentation API, so I wonder whether a screen could have a "hasSegments" property and a getter for those. We might not consider that external displays have folds and segments right now, as on macOS you can use an iPad as external display, so I could imagine a future where you would use your Surface Duo (or Neo) as an external display for your main PC/laptop. OK, filed an issue for that |
can I know if the screen is mirroring |
@rainke: Currently, only the source screen is exposed and there's no property indicating that it's mirrored. |
Our updated proposal in EXPLAINER.md should address the concerns raised here, and CHANGES.md describes most changes from the earlier proposal; please take a look. I'm going to close this issue, but feel free to reopen it or file other issues as appropriate. Thank you for your advice and patience! |
Ugh I'm kinda being 'that guy' with a "what if this looked entirely different?" issue, so feel free to ignore me.
The current design has some weirdness:
isMultiScreen
andgetScreens
are async due to the potential need for permissions.screenschange
event sits on the window object. It isn't clear how this interacts with permissions. It's weird for it to start/stop depending on permissions. It's equally weird for it to fire when permission isn't given.isMultiScreen
resolves to true,getScreens
may still return one item, due to race conditions.To avoid this, an object representing screen state could be behind an async method:
You might also want an event for when the permission is revoked, at which point the object stops being live.
This would solve #28 and #12.
If part of the API doesn't require permissions, eg change information on the primary screen, or the presence of multiple screens, that could go on
Screen
:The text was updated successfully, but these errors were encountered: