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

Titlebar Customization: Event for knowing any time the size changes #184

Closed
Garbee opened this issue Jan 30, 2020 · 6 comments
Closed

Titlebar Customization: Event for knowing any time the size changes #184

Garbee opened this issue Jan 30, 2020 · 6 comments
Assignees

Comments

@Garbee
Copy link

Garbee commented Jan 30, 2020

The explainer covers using the resize event for detecting bounds changes that need to be accounted for within an application. However, there are situations that can trigger the bounds to be changed that aren't surfaced with that event. For example, display scale changes (at least on MacOS.)

Test case:

  • Open DevTools
  • Navigate to console panel
  • window.addEventListener('resize', (event) => console.log(event)) in the console to see events.
  • Resize the window to confirm it is logging
  • Clear console
  • Go to your OS display settings and change the scale.
  • (At least on MacOS) notice no resize events fire, yet the size and location of the window did change, along with the size of the titlebar of the browser.

Perhaps one solution (which kinda works in tandem with some of the issues in #177 to alleviate the need for introducing CSS additions up front) is for a new event to be introduced.

  1. The application must be using this type of titlebar to receive this event. (Unless we find some compelling use-case for it externally.)
  2. When any size of the control bounds occurs, the browser shall fire a controlsOverlayResized event.
  3. The event shall contain the new bounds rect data. (Avoiding the need for a developer to make a call for it.)

If we could also get a new debounce option added to EventTarget.addEventListener for this, that could mean the engine can handle not firing this off too often (in case that were to somehow happen.) For example:

const resizeHandler = function(event) {
  // Update page titlebar bounds to match new overlay bounds.
};

window.addEventListener('controlsOverlayResized', resizeHandler, {debounce: 500});

This would make the engine not fire the event until the given number of milliseconds after last event trigger has happened. Giving developers an efficient way to keep up to date with JS without thrashing with every minor resize of a window.


That being said, I still think a CSS solution (as #177 is discussing) is the best long-term solution. If we can't get much headway on a course there in CSS however, something along these lines in JS could be a more amicable (and robust) solution to get in front of developers sooner.

@bathos
Copy link

bathos commented Jan 31, 2020

Has there been consideration of alternatives wherein the usable titlebar area is not considered part of the viewport, but is instead realized as a frame in its own right — something like how the picture-in-picture media API is being realized?

I ask because it seems like if that were the case, existing APIs like ResizeObserver, media queries — or typically, just width: 100%! — would already cover these needs.

@Garbee
Copy link
Author

Garbee commented Jan 31, 2020

not considered part of the viewport

I'm slightly confused. It currently isn't a part of the viewport and is kept z-indexed on top of it. Hence why content can flow underneath it in the viewport. If it were attached to the viewport so it was technically in the content area, that introduces some slight logistical issues that now the viewport isn't a rectangle shape. (I may be mis-understanding the definition/scope of viewport here with what I as a developer generally see as the viewport compared to what a browser engine counts as a part of it.)

However, we currently have this (non-standardized) with the new iPhones and Androids with notches. That type of situation is discussed over in #177 already.

If we can standardize some method of handling these non-rectangular viewport shapes and how devs can style around them, then that would be a bigger achievement that tackles more use-cases but supplements the work being done with this type of window control system.

@amandabaker
Copy link
Member

@Garbee I'm seeing events fired on Chrome Canary when changing the scale on both Mac and Windows, so I'm not sure what's happening there. Maybe it's a bug? I would also expect a resize to be fired on scale factor changes since the title bar would change in height, which would in turn adjust the size of the viewport.

We've also internally discussed the security implications of using a unique event, and decide that firing resize is a safer option. Consider the situation where a malicious app wants to pretend to be your bank. When the app is first launched, the overlay will display the origin of the app for the first few seconds, then it hides. In most cases, the first time the overlay changes sizes would be when this origin is hidden, so if we fire a unique event, controlsOverlayResized, then the app would just have to listen to the first firing of the event. Then its easy for the site to immediately fill in that space with a spoofed origin 'yourbank.com' to deceive users into believing that the app is from a trusted source.

This spoof is still possible with the resize event, but it just takes a couple more steps and may be less responsive:

  1. Store values of window.menubar.controlsOverlay.getBoundingRect()
  2. Register for resize event
  3. On resize, compare the new boundingRect to the old.
    1. If the new rect is smaller, then spoof the origin
    2. If not, wait for the next resize and try again

Also, we would still love a CSS solution, but new CSS variables would need to be standardized, so it may be a slow process getting that approved (if it gets approved at all). In the meantime, JS can get the job done, albeit not as smoothly or conveniently.


@bathos We have considered other options, but went with the current solution for a few reasons:

  1. It's similar to working around a notch, which developers are already doing
  2. We weren't sure if there would be unexpected security issues with placing an extra frame in the title bar.
  3. It's a fairly simple solution, and as such, it's potentially less buggy once implemented.

Unfortunately, without the CSS variables, it does place a bit more burden on the developer, but hopefully we can work out a solution for that.

@Garbee
Copy link
Author

Garbee commented Jan 31, 2020

Hmm, interesting. Just tested again. It seems the resize event (on Mojave, not Catalina this time) is firing only when going between the two "bigger text" options. If I go to either "More space" option it doesn't fire, and default it will when coming down from bigger text, but not up from more space.

The abuse case presented however is very compelling. Having a very explicit way of getting that first hit on the titlebar is troublesome. However, there is one thing that quickly comes to mind that could get by it.

evilsite.com could implement their page where the spoof target bank.com is just placed by default under the compact titlebar. Then (assuming no extensions or other padding) when the domain evilsite.com is hidden it would reveal the target spoof naturally.

This has the primary assumption of no extensions. I don't have any details on how common extensions are for the platform so even if 1 showing in the space is normal then this point could be moot. (However an attacker could just plan for up to 2-3 extension icon sizes and it could work too.)

This vector is still attackable pretty easily and in such a way most end users would probably never notice. Especially if they're the type of user to click to open something, then look away/focus on another app and return once it is fully loaded. Unless a user is giving their absolute focus to an app in this context, an attacker can bypass the protections easily enough even if janky.

That being said, I do not have enough data to support anything except conjecture. I don't feel like this kind of event is necessary, it would just be a better developer experience/ergonomics given the situation. So if it is something that is entirely out of the question due to the proposed attack vector, feel free to close this on out since it isn't something that can be acted on in the proposal.

@bathos
Copy link

bathos commented Feb 12, 2020

It currently isn't a part of the viewport and is kept z-indexed on top of it. Hence why content can flow underneath it in the viewport. If it were attached to the viewport so it was technically in the content area, that introduces some slight logistical issues that now the viewport isn't a rectangle shape. (I may be mis-understanding the definition/scope of viewport here with what I as a developer generally see as the viewport compared to what a browser engine counts as a part of it.)

I think this is just a terminology disconnect — what you describe is what I mean by ”part of the viewport.” I might be using the wrong word. What I meant to contrast the current proposed approach with wasn’t a model that was polygon-aware, but rather one where the area within the titlebar that’s actually available to devs was realized as its own window/frame, as in the Picture in Picture API. The window would begin below this, as it normally would, and nothing would end up overlaid.

I’m confused by:

introduces some slight logistical issues that now the viewport isn't a rectangle shape

— since that’s exactly the reason I asked; the current proposal appears to introduce that issue, or at least ... intensify it? The significance of whether effectively eliminated portions of the viewport happen to be implemented (unobservably) in terms of z-index overlays at the browser chrome level or something else isn’t clear to me; that is a polygon, it’s just one that platform APIs will be lying to us about (whereas two frames would seemingly mean two “honest“ rects).

(I’m not sure what I’m asking about / suggesting is a great solution or anything, but I couldn’t find anything about it so far and it would seem to solve a lot of the css problems.)

@amandabaker
Copy link
Member

Currently, we're working on ironing out the the CSS env() solution: #177 #203 and it seems the "resize" event should suffice for anyone relying on the JavaScript APIs for layout, so it seems like this issue has been resolved. Feel free to reopen if there's something I missed

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

No branches or pull requests

4 participants