Skip to content
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

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

Open
frivoal opened this issue Sep 5, 2022 · 15 comments
Open

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

frivoal opened this issue Sep 5, 2022 · 15 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 alice@igalia.com 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants