Android: implement Window::safe_area#4506
Android: implement Window::safe_area#4506nicoburns wants to merge 1 commit intorust-windowing:masterfrom
Window::safe_area#4506Conversation
19e5226 to
11166d1
Compare
Window::safe_area for androidWindow::safe_area
Signed-off-by: Nico Burns <nico@nicoburns.com>
11166d1 to
bd06339
Compare
There was a problem hiding this comment.
I'd like to hear from @MarijnS95, but if he hasn't found time for it in two weeks, ping me then, I'd be comfortable merging this, in any case it's better than nothing.
| MainEvent::ContentRectChanged { .. } => { | ||
| warn!("TODO: find a way to notify application of content rect change"); | ||
| }, | ||
| MainEvent::ContentRectChanged { .. } => pending_redraw = true, |
There was a problem hiding this comment.
I think this should be resized = true? That'd better match what we (somewhat) guarantee on macOS (that changes to the safe area trigger a resize event).
There was a problem hiding this comment.
We definitely could do a resize event. I want to react to "safe area" changes very differently to surface resizes (notably, I don't want to resize the underlying texture, because at least on Android I still want to render a background color into the safe area). But I could implement this using an equality check on the "surface size" and "safe area" in the resize handler.
There was a problem hiding this comment.
I think we'll want #4507, but for now the behavior we have on iOS and macOS is to emit a resize event so let's match that on Android too.
(To be clear, the resize will still contain the surface size as before, it's just a signal to the app to update other things that depend on the safe area, I know Alacritty relies on it).
There was a problem hiding this comment.
Wait nvmd, iOS only requests a redraw. So I'm fine with only doing that here too.
madsmtm
left a comment
There was a problem hiding this comment.
Re semantics, content_rect() differs from iOS in that it includes changes to the soft keyboard, doesn't it? If so, I'm not sure we should use that, I don't think you'd want to render your content differently depending on if the keyboard is present on screen or not? If it overflows, you should instead provide a scroll bar.
Yes, this is correct, and a good point.
I definitely do want to render my content differently depending on whether the keyboard is present on the screen or not (at least sometimes). Consider how the URL bar of mobile browsers typically works (when it is at the bottom of the screen), or how some apps have an extra toolbar above the keyboard. However, I probably want to separately react to this "content area" and the "safe area" that is taken up by non-keyboard stuff (on Android this is the toolbars). Is there a way to get the "content area" (modified by keyboard) on iOS? Perhaps we could expose both of these separately on both platforms? See also https://reactnative.dev/docs/keyboardavoidingview
How can I know if it overflows if I don't know the "keyboard avoiding size"? |
|
I agree that you want to do things differently depending on whether the soft keyboard is open or not, I meant more that "safe area is probably the wrong tool for this". For example, opening the keyboard is animated, you might want to animate your content with it. I'm also reading this, Then again, SwiftUI provides So maybe the right thing to do would be to include it on iOS too (and later allow querying the size of the soft keyboard to "opt out"). |
Yes, I believe so.
Yes, I would want to animate my content. And in testing I found I was able to so by rerendering with a new size in response to
Is there a way to query (and subscribe to) the If so, then perhaps we should model that API in Winit, as I think that ought to be implementable on Android too. If the sizes are (non-statefully) separately queryable and subscribable, then it may make sense to just subscribe to both and notify when either changes? |
|
Don't look too hard at SwiftUI, I'm using it mostly as a reference for "how could we design the API", not "what data is actually available". I think the way to do this (while supporting animations) on iOS would be to:
|
|
For just querying it: if we do step 1 and 2 (set Do you wanna take a stab at implementing this? If not, I can probably try. |
I would, but I'm already lost in the documentation. So perhaps you should try. |
|
I've put up #4528 with my work on that, won't get to finishing it today. |
|
I think it might make sense to consider whether/how we might expose the keyboard insets separately from the device/systemBars insets? Like, what would such an API look like? Something like this: trait Window {
fn keyboard_insets(&self) -> PhysicalInsets<u32>,
}Wouldn't really work, because |
|
Do you know how to query the other kinds of insets on Android with |
No. I had a quick look, and it doesn't look to me like there is a way. A lot of Rust GUI apps/toolkits are using custom activities on Android. Dioxus Native does. Slint does. GPUI (unofficial mobile port) does. It may be worth looking at doing a Java-based backend for Winit... |
Agree. As a user, this is what I would like!
I was imagining that there would be two methods returning |
So And then |
Implements
Window::safe_areafor Android. This replaces the platform-specificWindowExtAndroid::content_rectmethod.Android provides the
topandrightcoordinates as offsets from the top left (0, 0) point rather than as insets from the nearest side. So these are subtracted from the outer size to normalize them according the existing semantics ofWindow::safe_area.changelogmodule if knowledge of this change could be valuable to users