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

Add safe area and document coordinate systems #3890

Open
wants to merge 38 commits into
base: master
Choose a base branch
from

Conversation

madsmtm
Copy link
Member

@madsmtm madsmtm commented Aug 26, 2024

Resolves #2308, by adding Window::safe_area, which describes the area of the surface that is unobstructed by notches, bezels etc. The drawing code in the examples have been updated to draw a star inside the safe area, and the plain background outside of it.

Also renamed Window::inner_position (introduced in #430) to Window::surface_position, and changed it to from screen coordinates to window coordinates, to better align how these coordinate systems work together.

Finally, I've added some SVG images and documentation to describe how these coordinate systems work together. The images should be auto-adjusting to the page theme when viewed on docs.rs. See also #3891, whether we use window coordinates or surface coordinates is currently a bit confusing.

Completing implementation on all platforms is tracked in #3910

Fixes #1122
Fixes #2308
Fixes #3742
Fixes #2066
Fixes #2347
Fixes #2235

Copy link
Member

@kchibisov kchibisov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can macOS backend provide safe area when the transparent decorations are used? The ones where the buttons are over the main surface.

src/window.rs Outdated Show resolved Hide resolved
docs/res/coordinate-systems-desktop.svg Outdated Show resolved Hide resolved
src/window.rs Outdated Show resolved Hide resolved
@madsmtm
Copy link
Member Author

madsmtm commented Aug 26, 2024

Can macOS backend provide safe area when the transparent decorations are used? The ones where the buttons are over the main surface.

Didn't even know we had WindowAttributesExtMacOS::with_titlebar_transparent, but yeah, that should be possible.

I was kinda hoping I could define safe_area to not include CSDs, but seems like I'll have to update the docs to include it as well :/.

@kchibisov
Copy link
Member

I was kinda hoping I could define safe_area to not include CSDs, but seems like I'll have to update the docs to include it as well :/.

You just need to y offset, and that's about it from what I can say.

Base automatically changed from madsmtm/inner-to-surface to master September 4, 2024 13:04
Added `Window::safe_area`, which describes the area of the surface that
is unobstructed by notches, bezels etc. The drawing code in the examples
have been updated to draw a star inside the safe area, and the plain
background outside of it.

Also renamed `Window::inner_position` to `Window::surface_position`, and
changed it to from screen coordinates to window coordinates, to better
align how these coordinate systems work together.

Finally, added some SVG images and documentation to describe how all of
this works.
@madsmtm
Copy link
Member Author

madsmtm commented Sep 10, 2024

I have ensured that safe_area includes the title bar when with_titlebar_transparent + with_titlebar_hidden is set on macOS

Copy link
Member

@daxpedda daxpedda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great!
I will work on the Web implementation soon.

src/lib.rs Outdated Show resolved Hide resolved
src/lib.rs Outdated Show resolved Hide resolved
src/window.rs Outdated Show resolved Hide resolved
src/window.rs Outdated Show resolved Hide resolved
@daxpedda daxpedda added this to the Version 0.31.0 milestone Oct 9, 2024
Copy link
Member

@daxpedda daxpedda left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the safe area account for the virtual keyboard as well on iOS?

@nixpulvis
Copy link
Contributor

nixpulvis commented Oct 9, 2024

Does the safe area account for the virtual keyboard as well on iOS?

I found this: https://developer.apple.com/design/human-interface-guidelines/layout#iOS-keyboard-layout-guide

@daxpedda
Copy link
Member

daxpedda commented Oct 11, 2024

I implemented Web as well now.

However there is a bug when not used with viewport-fit=cover that I can't figure out on my own.
Basically Safari adds margins/padding to both sides of the viewport when holding an iPhone with a notch sideways (even though the notch is only on one side). I'm unable to detect/read this padding/margin, so the calculations are all off.

This could also be happening on Android, unfortunately I can't test it because I don't have an Android device with a notch.

@daxpedda
Copy link
Member

So I spent some more time thinking about the Web implementation.
I have come to the conclusion that implementing this for Web is kind of impossible with the current description of the API.

AFAIK on iOS you can't move the window partly off-screen, but on Web it is possible to do so.
The Window on Web can be anywhere in the viewport, so what do we report when the user scrolls?
If we start accounting for all that, its looks more like we are representing occlusion and not the safe area.
We could start defining the safe area as the safe area without any scrolling and movement (?) applied.
What do we do if the Window is bigger then the viewport? If we calculate the safe area by removing the part that's bigger then the viewport we are back at occlusion again.

A practical example:
If the canvas sits in a webpage that has text around it and can be scrolled, the safe area might be used to calculate layout. If the user starts scrolling down, the layout would suddenly starts to squish together because a part of the surface is outside the safe area.
See this Bevy example where this exact same scenario would cause problems.


It seems to me that the safe area is only useful if the Window is as big (or smaller?) than the screen and, in the case of Web, the surface can't move around in the Web Window through scrolling.
Therefor I suggest that we define the safe area on the MonitorHandle instead of on the Window.
To calculate the safe surface area, we can keep the current function, but return an Option, which would be None if our definition of "safe area" is not applicable. E.g. the Window is not as big as the screen.

I'm unsure how to implement this on Web. Probably if the canvas is not as big as the viewport or the Document is bigger than the viewport (ergo if it causes any scrolling bars), we should return None.

We might want to define a new concept like "visible surface area", which exposes the truly visible area to the user, which would account for everything: safe area, occlusion, virtual keyboard and so on.
This can be implemented on Web with the Intersection Observer API.

@kchibisov
Copy link
Member

Safe area matters for fullscreen window to not draw behind the notch, for the rest it's not used. It's also static to display coordinates (most of the time).

Like the whole purpose here is for e.g. alacritty offset it viewport to not put anything behind notch on macOS during fullscreen, nothing more, and yes, it's called safe area.

@daxpedda daxpedda added the C - nominated Nominated for discussion in the next meeting label Oct 11, 2024
@madsmtm
Copy link
Member Author

madsmtm commented Oct 25, 2024

@daxpedda and I talked about this today, and a rough conclusion was to calculate the safe area independently of the scroll position of the page, i.e. in a sort of "absolute" position of the entire document.

@MarijnS95
Copy link
Member

I haven't exactly followed this PR, but how is this "surface inside window" representation going to come together with #3942 and all future "subsurface" changes that we're going to make? Every individual surface having its position relative to the parent surface and eventually relative to the window "area" that we define here?

@madsmtm
Copy link
Member Author

madsmtm commented Nov 4, 2024

I haven't exactly followed this PR, but how is this "surface inside window" representation going to come together with #3942 and all future "subsurface" changes that we're going to make? Every individual surface having its position relative to the parent surface and eventually relative to the window "area" that we define here?

Not sure yet, but I think it makes sense to allow querying the safe area relative to each surface. In any case, I'll leave it to that PR (since I hope this one is going to merge first).

@madsmtm
Copy link
Member Author

madsmtm commented Nov 4, 2024

I have changed fn safe_area to return the insets (dpi::PhysicalInsets { top, left, bottom, right }) instead, since I belive that will be more forwards-compatible with #3911 and other improvements (discussed on Matrix today to add insets for each type of notch).

I believe the only remaining thing is for @daxpedda to fix the web wrt. scrolling, as I wrote shortly about in #3890 (comment) (if you don't have the time rn, I'm inclined to merge this fairly soon anyhow, and then track the completion of that in #3910).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C - needs discussion Direction must be ironed out C - nominated Nominated for discussion in the next meeting DS - android DS - ios DS - web S - api Design and usability S - docs Awareness, docs, examples, etc.
5 participants