Skip to content

[cssom-view] No event to track window position #7693

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

Closed
frivoal opened this issue Sep 5, 2022 · 18 comments
Closed

[cssom-view] No event to track window position #7693

frivoal opened this issue Sep 5, 2022 · 18 comments

Comments

@frivoal
Copy link
Collaborator

frivoal commented Sep 5, 2022

The window object exposes attributes to find the position (and size) of the window. However, there are no corresponding event, so anyone interested in tracking these must do so by actively polling, which is wasteful and/or laggy, depending on how frequently you poll.

A use case for doing this is when a parent page pops up an child window, and wants to keep it positioned to a particular spot relative to the parent window. That's currently doable, but it takes active polling. Being able to switch to an event would be good.

We already do have the resize event on the Window object, but that only solves half the problem, as there's no equivalent for the position.

So, can we get

window.addEventListener('move', callback);

to go along with

window.addEventListener('resize', callback);

?


cc: @emilio @mrego

@Loirooriol
Copy link
Contributor

AFAIK the resize event can easily be awful for perf since it's sync and fires lots of times during the resize.
It seems move would have the same problem. An async observer may be a better idea?

@emilio
Copy link
Collaborator

emilio commented Sep 6, 2022

Resize doesn't fire sync afaik (though it fires very frequently). In any case the other potential issue I see is that the window resize event fires everywhere (like iframes) but we probably don't want that here. Resize reflects inner size, but it seems here you are interested in outer window position (not inner one).

@frivoal
Copy link
Collaborator Author

frivoal commented Sep 9, 2022

An async observer would be equaly fine for the usecase, and preferable if that enables better performance.

The point about iframes is interesting. I suppose tracking the inner position would be a security issue as it would leak information about the parent content, but I don't think tracking the outer window position would be an issue, would it? If it is, I suppose it's an acceptable restriction for this to just not work from within iframes.

@Loirooriol
Copy link
Contributor

I guess in iframes it should just track changes to the screenLeft or screenTop of the iframe's contentWindow? Which seem to be the same values as for the top window.

@alice
Copy link

alice commented Feb 22, 2023

A use case for doing this is when a parent page pops up an child window, and wants to keep it positioned to a particular spot relative to the parent window.

I had a play with doing something like this, and discovered that not being able to make an always-on-top popup window (is there a way to do this that I've missed?) makes the tracking popup case pretty limited in usefulness. (It might be useful if you have a popup that doesn't overlap its parent, I guess?)

https://people.igalia.com/alice/test/popup/

Also, writing the logic to position the popup relative to the window was extremely involved, and it still only sort of works, and seems to be subtly different between browsers and operating systems.

How realistic is a tracking popup window as a use case?

@frivoal
Copy link
Collaborator Author

frivoal commented Jun 12, 2023

(It might be useful if you have a popup that doesn't overlap its parent, I guess?)

The case I had heard of was that indeed. It kept windows docked next to each other, and had the "side panel" windows follow the main one.

I do agree that this is a little convoluted, and fraught with cross-platform challenges. At the same time, we do expose that information already, so it's not really a question of whether to have the ability at all. Given that we do have it, and that people occasionally do use, if it wouldn't be terribly difficult to expose an observer, that could be a cheap boost to performance / battery life.

@alice
Copy link

alice commented Jun 12, 2023

Sure, that makes sense. I could see it being something that's specced with reference to the web-exposed screen area, so user agents may make the same choices with regard to what precisely is exposed as they do in that case.

@alice
Copy link

alice commented Aug 22, 2023

I spent some time looking in to this lately, particularly the observer/event question.

The TAG design principles do include guidance on this specific issue (and there was an earlier discussion thread):

In general, use EventTarget and notification Events, rather than an Observer pattern, unless an EventTarget can’t work well for your feature.

...

If using events causes problems, such as unavoidable recursion, consider using an Observer pattern instead.

This seems to me to indicate that an event is probably what we want here. I'm not sure what we'd gain from having this be an Observer instead.

I see that in Blink, resize fires at most once per animation frame, and that seems like a good design particularly for this use case, since the point is to have a secondary window "follow" the main window around.

I'm not sure exactly where this discussion landed on iframes - would iframes not have window.move events fired at all, or would they fire when the top window moves?

I'm planning to start writing some tentative WPT tests to cover my exploratory implementation; should I also have a go at writing some spec language, or would someone else like to take that?

@frivoal
Copy link
Collaborator Author

frivoal commented Aug 25, 2023

I'm not sure what we'd gain from having this be an Observer instead.

The suggestion was that it would have better performance characteristics. If an Event can be performant, that's just as well in my book.

I'm not sure exactly where this discussion landed on iframes - would iframes not have window.move events fired at all, or would they fire when the top window moves?

I am not sure we concluded with certainty. I think firing when the top window moves gives a bit more power if it doesn't bring excess complexity. As long as we don't fire when the iframe itself gets resized / moved by within parent document, I think we avoid cross site security problems.

should I also have a go at writing some spec language, or would someone else like to take that?

It's probably fresh in your mind, so I think it would make sense if you wrote it, in which case I'd be happy to review. But if you'd prefer the other way around, I'm happy to oblige.

@alice
Copy link

alice commented Sep 22, 2023

I finally managed to have a go at writing some spec text for this. I more or less copied the strategy used by the resize event: hooking directly into the event loop such that the event fires at most once per frame.

The CSS side is here, and the HTML side is here.

@frivoal If you could take a first look at those and let me know if you have any feedback on the text, I can make any edits you think might be needed and then make some more formal PRs, if we feel like this is a good direction.

@frivoal
Copy link
Collaborator Author

frivoal commented Oct 6, 2023

@alice I just reviewed your proposed text, and this does look good to me. Simple and to the point.

Given the WHATWG's policies, I don't know if HTML would land this prior to having 2 implementations, which might make it a little tricky temporarily from a spec dependency point of view: assuming the CSSWG supports your edits, our approach would be to land your PR into a draft prior to implementations existing, so that the spec can guide those implementations. But only landing the CSS half without the HTML half doesn't make much sense here.

If we accept this, I wonder if we should temporarily monkey-patch HTML, describing the change we would make to HTML in the CSS spec, until HTML itself lands it, at which point we could remove that from the CSS side. Luckily the change to HTML is minimal. We should probably ask the WHATWG how they prefer to deal with this.

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 29, 2023
There is a proposal [1] to add a new WindowEventHandler element to track
the the attributes exposed by the window object to indicate its position
and size.

There are PRs for the HTML and CSS specs to describe the behavior of
this new handler, which have positive feedback although still under
discussion.

This CL provides also the required WPT to cover the new functonality.

[1] w3c/csswg-drafts#7693

Change-Id: I67f770d425b5db5852851fb4609a5ba7980dda77
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Nov 29, 2023
There is a proposal [1] to add a new WindowEventHandler element to track
the the attributes exposed by the window object to indicate its position
and size.

There are PRs for the HTML and CSS specs to describe the behavior of
this new handler, which have positive feedback although still under
discussion.

This CL is based on the one [2] from [email protected] and provides also the required WPT to cover the new functionality.

[1] w3c/csswg-drafts#7693
[2] https://crrev.com/c/4279461

Change-Id: I67f770d425b5db5852851fb4609a5ba7980dda77
@javifernandez
Copy link
Contributor

Hi @frivoal

@alice I just reviewed your proposed text, and this does look good to me. Simple and to the point.

If we accept this, I wonder if we should temporarily monkey-patch HTML, describing the change we would make to HTML in the CSS spec, until HTML itself lands it, at which point we could remove that from the CSS side. Luckily the change to HTML is minimal. We should probably ask the WHATWG how they prefer to deal with this.

I took over the work @alice has been doing here and, following your advice, I created the PR 9664, adding a reference to the HTML event loop there.

Also, I'll try to gather opinions from the WHATWG on whether they think there is a better approach to integrate the changes in both specs.

@zcorpan
Copy link
Member

zcorpan commented Dec 13, 2023

@javifernandez @alice IMO it's better to make the change in both specs directly (assuming no opposition to add the event).

@css-meeting-bot
Copy link
Member

css-meeting-bot commented Jan 4, 2024

The CSS Working Group just discussed [cssom-view] No event to track window position, and agreed to the following:

  • RESOLVED: Pursue event to make tracking window position more ergonomic
The full IRC log of that discussion <frances_> florian: window attribute has objects and event when size changes but not when position changes, proposal to add move event that works similar to resize event
<frances_> florian: nuance while position attribute is on object, browsers are not required to report or have a global coordinate system and hide them, not reliably available
<frances_> florian: if not possible to land html patch, might differ things, could possibly land them in css patch
<khush> q+
<frances_> Alan: Alice's prs are closed why?
<frances_> florian: suspected glitch of rebasing, sat for a while and appears closed
<astearns> ack khush
<frances_> khush: Do all os's have this event? Are we expecting all browsers to behave similarly?
<frances_> Florian: fickle to speak of all os's, not finite, up to implementation detail and html loop in rendering, not need to pull more frequently
<frances_> florian: theres a limit on how frequently
<frances_> khush: if window position is changing, how can we minimize wakeups on the screen and not rely on it in case os is not giving the event
<frances_> Alan: possibly resize event has timing specified
<frances_> florian: specified similarly
<frances_> khush: doubt to have the problem on the os when window is resized
<frances_> florian: as mentioned, linux on Wayland does not have os tell changes on coordinates, windows are composited, no requirement to report numbers
<frances_> florian: up to implementation discretion, numbers are already exposed
<frances_> Alan: Igalia is possibly looking for an okay and no objections to adding the event
<frances_> florian: possible limited appetite to the event, make it convenient to not waste energy in actively pulling
<frances_> Alan: any other comments or thoughts?
<frances_> Daniel: is it set in such a way to detect whether you will ever get a callback or expect it?
<frances_> florian: there is nothing on the event itself, possible window attributes maybe undefined
<frances_> florian: spec should give an answer
<frances_> Daniel: that is my only concerned, sort of imperfect, might not return anything, need to make it ergonomic with the known limitation
<frances_> Alan: put something on the spec such as exposing window position and does it get updated, put event on the window object or it shouldn't be there to add the existence of the event
<frances_> florian: trying to find part of the spec to find where the information is, spec says you don't have to report. Does anyone remember?
<frances_> Alan: these are details that we can work out
<frances_> Daniel: Wayland limitation is possibly substantial, might never work it is an important constraint to be aware of
<frances_> florian: important on window object itself
<frances_> Daniel: we already expose possibly bad information, need to be more ergonomic
<frances_> florian: trying to find the part of spec, possibly open separate issue to track and detect
<frances_> florian: is it relevant to know difference between 0 0 corner? open issue and track
<frances_> Alan: should we land a spec for the event and then ask for a privacy review or vice versa?
<frances_> florian: event doesn't make information worse, need to add way to report information with privacy considerations
<frances_> Alan: information available but hard to use, might make it detrimented
<frances_> florian: might make it inefficient for the programmer
<frances_> Ian: trivial, not difficult to access
<frances_> Daniel: agreed
<vmpstr> this says 0 if not available, not sure if that's the right spot https://drafts.csswg.org/cssom-view/#dom-window-screenleft
<frances_> Alan: let's finish up discussion
<frances_> RESOLVED: PURSUE EVENT TO MAKE REPORTS MORE ERGONOMIC TO USE
<frances_> florian: should pull request wait?
<chrishtr> Agree to land a PR
<frances_> Alan: pull request then work on detials
<frances_> florian: move on css or pursue html request from get go?
<frances_> Alan: do both in both specs directly
<frances_> florian: agreed
<frances_> Alan: no objections
<frances_> Alan: next issue. Zoom issues for Chris.
<frances_> Alan: issue 9644 on iframes

@javifernandez
Copy link
Contributor

@javifernandez @alice IMO it's better to make the change in both specs directly (assuming no opposition to add the event).

The problem is that PRs for the HTML spec would require 2 implementations, and as far as I know only Chrome is interested for now.

@mrego
Copy link
Member

mrego commented Jun 21, 2024

JFYI, tests have been added at web-platform-tests/wpt#44020

frivoal added a commit to frivoal/html that referenced this issue Nov 27, 2024
UAs expose the coordinates of a window (window.screenX, window.screenY),
enabling authors to track window movement and react to it. Without a
corresponding event though, they have to resort to active polling, which
is wasteful of resources, especially if done often enough to have a
responsive UI.

As resolved by the CSSWG (See w3c/csswg-drafts#7693),
this adds an onmove event handler to keep track changes in window
position without such need for active polling. The definition of the
event itself goes to CSSOM-View, along with the geometric attributes
whose changes it tracks.

The privacy concerns related to exposing the window position in the
first place are handled in CSSOM-View, which allows UAs to return fake
information. The addition of the event doesn't change that: UAs that
don't expose the real information continue not to (and the event won't
fire).

See explainer at https://github.com/Igalia/explainers/blob/main/onmove-event-handler/README.md

CSS Part of the change: w3c/csswg-drafts#11278

Tests: web-platform-tests/wpt#49390

Implemented experimentally in Chrome: https://chromium-review.googlesource.com/c/chromium/src/+/6035050
@annevk
Copy link
Member

annevk commented Dec 13, 2024

I would like the CSS WG to revisit this resolution. Popups have all kinds of privacy problems and some browsers are slowly moving toward exposing less of these fingerprintable bits on Window and Screen. We should not be adding functionality that builds upon technology that would not get agreement if it were to be proposed today.

Marking agenda+ as suggested by @fantasai.

@annevk annevk added the Agenda+ label Dec 13, 2024
@astearns astearns moved this to FTF agenda items in CSSWG January 2025 meeting Jan 22, 2025
@astearns astearns moved this from FTF agenda items to Regular agenda items in CSSWG January 2025 meeting Jan 22, 2025
@astearns astearns moved this to Regular agenda in CSSWG April 2025 meeting agenda Mar 27, 2025
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [cssom-view] No event to track window position, and agreed to the following:

  • RESOLVED: remove the event
The full IRC log of that discussion <TabAtkins> q+
<JoshT> fantasai: Our team has reviewed this and is opposed to new APIs relying on window position. privacy problems
<JoshT> ... we don't want to add to API surface
<Rossen5> q?
<JoshT> florian: This doesn't expose anything new. Just adds a convienience, so you don't need to actively pull it.
<emilio> q+
<JoshT> ... if you don't expose anything, it doesn't affect you. but for people using it, they can be more efficient.
<JoshT> ... there are projects to see about doing it declaritively, which would be better, but this has been talked about for a while.
<JoshT> ... there is an opt-out so I don't understand concerns
<JoshT> TabAtkins: I agree generally. this is no new surface, a small easy change that makes a known use case from Bloomburg more efficient.
<emilio> s/Bloomburg/Bloomberg
<JoshT> ... I agree we shouldn't go to large expense supporting, but in this case synchronising API wise with event for window.size, this does not seem worth objecting to
<JoshT> ... I support keeping the resolution as it is
<Rossen5> ack TabAtkins
<Rossen5> ack emilio
<JoshT> emilio: did we define what happens with iframes? they do change screenX, screenY as well
<JoshT> ... but they could have cross-origin behaviour
<JoshT> florian: there are some cases where it is not useful. to make it useful, you are in breach of privacy
<JoshT> TabAtkins: I saw comment on issue that it should be OK to make it fine for iframes
<TabAtkins> s/make it fine/make it not work/
<JoshT> emilio: I'm curious about particular use case. popups?
<PaulG> q+
<JoshT> florian: Yes I think it was primerily for popups. And moving windows that are side-by-side together to remain together.
<JoshT> emilio: implications for popups are trickier. let's say you don't move the window but user adds a toolbar or menu bar
<JoshT> ... that moves the page down and you should get... screenX exposes the top window, so is it useful?
<JoshT> florian: if we had a declarative API to make the browser deal with it, that would be great. but we don't have that.
<JoshT> ... we have an non-great API that could be made more convienient. not a huge win to do this, but it's a small improvement.
<JoshT> emilio: if it's easier to make something work on windows but macOS and linux get screwed...?
<JoshT> florian: but how?
<JoshT> emilio: it makes something that's not platform independent easier to use
<JoshT> ... can we make--
<JoshT> PaulG: I work for a competitor to Bloomberg. we break up the app into a PWA and you could have the app tile maybe up to five monitors. get things to respond to size, shape and placement.
<JoshT> ... simulates a console app environment
<JoshT> ... PWA speeds up development, so I can see how this would be helpful
<JoshT> emilio: but how will screenX on monitor a be compatible with monitor b?
<smfr> q+
<JoshT> ... I'm not sure if we expose stuff like the size of the window borders?
<schenney> q+
<PaulG> q-
<dholbert> s/monitor b/monitor b particularly if they have different devicePixelRatio/
<TabAtkins> Remember: this information already exists and is actively used by these tools. Any complexities or issues are things they're already dealing with. This whole API suggestion was solely to let them stop using *polling* and start using an async event instead, so it's a little more efficient.
<JoshT> ... but the details of these APIs are not a great fit for the use case. only works if there's no sidebar, for example.
<JoshT> ... I'm concerned about making it easier to use
<JoshT> florian: we have exposed the info everywhere but we want to make it easier to pull
<JoshT> emilio: the common case of a full width window is easy to handle, but if you add stuff on top. the Firefox UI has complex calculations to see where the windows go, and I've seen many bugs
<JoshT> ... can people see all the edge cases?
<JoshT> Rossen: I think your point is well understood about making the ease of it increasing the badness of it
<Rossen5> ack smfr
<JoshT> smfr: this also requires leaking the origin of the screen. very fingerprintable
<TabAtkins> Again, this information is already "leaked", and to wahtever extent you censor or reduce it, it'll apply to this as well.
<JoshT> ... we want to actually lie about this to treduce fingerprinting
<JoshT> ... we want to discourage new use of these values
<flackr> q+
<Rossen5> ack schenney
<JoshT> schenney: if they want a popup window outside of the browser chrome, and it contains info relative to the main window, and they want to move with the main window, then the multi-screen thing is still a concern?
<Rossen5> ack flackr
<JoshT> flackr: I want to respond to smfr. Why not just lie with 0?
<JoshT> smfr: It might be 0, but they may not be accurate
<keithamus> q+
<JoshT> jensimmons: if you say 0 to everyone, it may not be an ideal solution
<TabAtkins> randomly fluctuating position would be just as noticeable as constant-0, fwiw.
<keithamus> q-
<JoshT> emilio: 0 seems non-fingerprintable to me. but sites depend on these, so do you increase the web compat impact on this?
<JoshT> flackr: if you do moves consistent with the lie then it should be fine
<emilio> q+
<JoshT> florian: the spec does already call out you can lie about this
<JoshT> ... if you do want to lie with randomisation and jumping around, then that may be a problem
<JoshT> ... I understand why browsers would not want to ship this, but the web platform is used as a runtime for a bunch of things
<JoshT> ... if you can detect you are on one environment, it is useful to achieve these things
<Rossen5> ack emilio
<JoshT> emilio: with web compat, let's say we do get them to react to screen pos values, on some platforms, we do lie because we can't do anything better
<JoshT> ... on Wayland, screenX is always 0
<JoshT> ... if you ???? then sites will break
<JoshT> TabAtkins: but this is not a commentary on the existing screenX and Y things
<JoshT> ... the polling is easy but it's not efficient for users computers
<fantasai> +1 emilio
<JoshT> emilio: but maybe instead of the polling, I just don't use them because polling is inefficient
<JoshT> IanK: but you do have a lot of large websites doing the polling, so I don't think it discourages anyone
<JoshT> Rossen: what if we did a poll here (pun, haha) and see what the group thinks. Is it half and half about whether to add it?
<JoshT> TabAtkins: we already have a resolution to do it
<JoshT> florian: we need to change both HTML and CSS specs to do it and HTML won't merge if one browser objects
<JoshT> ... Safari objects
<smfr> Anne points to https://w3ctag.github.io/design-principles/#leave-the-web-better: "The existence of a defect in one part of the platform must not be used to excuse an addition or extension to the defect"
<JoshT> Rossen: so the question here is: do we remove it or not?
<schenney> q+
<JoshT> ... emilio and WebKit folks say we should remove it. chrome folks mostly saying keep it.
<JoshT> ... the poll will show the same thing, so we could try to force resolution in a different way
<JoshT> schenney: Bloomberg are not so interested in this any more.
<JoshT> ... so between those two points, I would say we should remove it
<JoshT> Rossen: I could poll or call for a resolution right now
<JoshT> ... let's call for a resolution for objections without poll
<JoshT> ... does anyone object on removing this event?
<JoshT> florian: Unfortunate but I don't object
<JoshT> RESOLVED: remove the event
<JoshT> Rossen: As editor, you will have to remove it. I am sorry.
<JoshT> florian: it's not a huge thing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Regular agenda
Status: Regular agenda items
Development

No branches or pull requests

9 participants