script: Get the window rectangle from the WebViewDelegate instead of via the compositor#37960
script: Get the window rectangle from the WebViewDelegate instead of via the compositor#37960mrobinson merged 8 commits intoservo:mainfrom
WebViewDelegate instead of via the compositor#37960Conversation
|
Ah just found out one more bug.. Fixing in #37961. We would have new wpt passing when combining both! |
#37961) Previously, we only consider OS decoration height. But when testing #37960, I find that the decoration width is also non-zero. Testing: Need to wait W3C spec change web-platform-tests/wpt#53421 related to webdriver rectangle. When combined with #37960, this can fix at least `window_resizeTo.html`. Signed-off-by: Euclid Ye <[email protected]>
#37899 (comment) |
components/servo/webview_delegate.rs
Outdated
| /// Get the window rectangle. | ||
| fn window_rect(&self, _webview: WebView) -> DeviceIndependentIntRect { | ||
| DeviceIndependentIntRect::default() | ||
| } | ||
|
|
There was a problem hiding this comment.
Please do not add a new WebViewDelegate method for this, as now the embedder needs to implement two things in order to properly communicate window sizes. Instead in libservo, somehow access the RenderingContext size and the offset from the existingscreen_geometry() method.
There was a problem hiding this comment.
The hidpi_scale_factor is stored in WebViewInner as part of the WebView struct, so you should have access to it in libservo.
There was a problem hiding this comment.
Thanks. But RenderingContext/WindowRenderingContext etc. all only holds inner_size, same as the previous compositor proxy.
I also checked WebViewInner.rect, which is supposed to be inner_size rect, but currently heavily & wrongly mix-used.. (Will file an issue tomorrow)
TL;DR: It is still difficult to get outer_size without adding method to WebViewDelegate...
There was a problem hiding this comment.
now the embedder needs to implement two things in order to properly communicate window sizes.
I have a idea: remove fn window_rect from WindowPortsMethods added last week in #37812. Just move logic to our newly created WebViewDelegate::window_rect.
This way, we also supports egl.
There was a problem hiding this comment.
I see. So the issue is that we really need the outer window rect and also the inner window rect? Can you have ScreenGeometry return this information? I think it makes sense that we get all of this information in a similar place (for now) so that the person embedding Servo understands how all the parts fit together.
/// Information about a `WebView`'s screen and containing window geometry. This
/// is used for the [Screen](https://drafts.csswg.org/cssom-view/#the-screen-interface)
/// CSSOM APIs and `window.screenLeft` / `window.screenTop`.
#[derive(Clone, Copy, Debug, Default)]
pub struct ScreenGeometry {
/// The size of the screen in device pixels. This will be converted to
/// CSS pixels based on the pixel scaling of the `WebView`.
pub size: DeviceIntSize,
/// The available size of the screen in device pixels. This size is the size
/// available for web content on the screen, and should be `size` minus any system
/// toolbars, docks, and interface elements. This will be converted to
/// CSS pixels based on the pixel scaling of the `WebView`.
pub available_size: DeviceIntSize,
/// The rectangle in device pixels of the `WebView`'s containing window on the screen.
pub window_rect: DeviceIntRect,
/// The offset of the `WebView` in its containing window in device pixels..
pub offset_in_window: DeviceIntPoint,
Would that work?
7afc12c to
168d889
Compare
168d889 to
5b19044
Compare
components/servo/lib.rs
Outdated
| let pos = screen.window_offset.to_f32(); | ||
| let window_size = screen.window_size.to_f32(); | ||
|
|
||
| let pos_in_css_pixel = (pos / dpi).round().to_i32(); |
There was a problem hiding this comment.
I have an important question, given that I encountered several rounding display/layout issues before (e.g. #37243). Should we round or truncate?
They seem to be mix-used in Servo rn. Compositor always truncates. Layout sometimes rounds.
cc @Loirooriol @sagudev
Personally, I tends to keep fractional value as long as possible (like during layout calculation), and round when we have to. Never truncates.
There was a problem hiding this comment.
This can be left as an open question. I am only certain that WebDriver set window rect should always round.
Can you review this pls? @mrobinson
There was a problem hiding this comment.
This is a good question that I don't know the answer to. :/
cd4714e to
46d9125
Compare
|
🔨 Triggering try run (#16213003380) for Linux (WPT) |
|
Test results for linux-wpt from try job (#16213003380): Flaky unexpected result (18)
Stable unexpected results that are known to be intermittent (17)
|
|
✨ Try run (#16213003380) succeeded. |
mrobinson
left a comment
There was a problem hiding this comment.
Looking great. This is a nice cleanup. Just one real issue here and bunch of nits. Thanks!
components/servo/lib.rs
Outdated
| EmbedderMsg::GetWindowRect(webview_id, response_sender) => { | ||
| let window_rect = if let Some(webview) = self.get_webview_handle(webview_id) { | ||
| let dpi = webview.dpi(); | ||
| let screen = webview.delegate().screen_geometry(webview).unwrap(); |
There was a problem hiding this comment.
This unwrap means that by default Servo will panic as the default implementation of fn screen_geometry returns None. Please do this:
| let screen = webview.delegate().screen_geometry(webview).unwrap(); | |
| let Some(screen_geometry) = webview.delegate().screen_geometry(webview) else { | |
| return Default::default(); | |
| } |
There was a problem hiding this comment.
Ok. I wrote like this because all egl/desktop implementation of screen_geometry returns Some.
There was a problem hiding this comment.
Sure, but we don't have control over what other embedders do (the embedding API is meant to be generic and public) and the interface allows returning None as a valid response. We need to obey the contract the API gives.
WebViewDelegate instead of via the compositor
Signed-off-by: Euclid Ye <[email protected]>
Signed-off-by: Euclid Ye <[email protected]>
Signed-off-by: Euclid Ye <[email protected]>
Signed-off-by: Euclid Ye <[email protected]>
9e4f81e to
9e5e5a9
Compare
9e5e5a9 to
60543e5
Compare
60543e5 to
5894c7d
Compare
|
🔨 Triggering try run (#16219671511) for Android |
yezhizhen
left a comment
There was a problem hiding this comment.
Thanks! But please address the concern.
components/servo/lib.rs
Outdated
| }; | ||
|
|
||
| (screen_geometry.window_rect.to_f32() / hidpi_scale_factor) | ||
| .round_out() |
There was a problem hiding this comment.
Should round instead of round_out, because we want "as close as possible" as claimed in #37960 (comment) to be consistent with WebDriver get rect. It is ok if things don't fit in.
There was a problem hiding this comment.
I search the WebDriver spec for the text "as close as possible" and I only see that this should apply when trying to resize the window. I don't interpret this as referring to rounding floating point pixels though, but for when the operating system imposes other kinds of sizing constraints on the window. In any case, is this terminology used anywhere with regard to actually getting the window's size.
FWIW, I used round_out here as it seemed to make more sense that the rectangle contained the entire window versus just part of it.
There was a problem hiding this comment.
But if using round_out, this will start to fail some WebDriver tests. Do you suggest that I change other round to round_out in previous merged PR?
There was a problem hiding this comment.
FWIW, I used round_out here as it seemed to make more sense that the rectangle contained the entire window versus just part of it.
But this can also introduce some danger. You may try to paint on larger than available window, leading to some obscured corner. round_in would make more sense to me..
EDIT: Maybe leave as another open question, and use round() for now?
There was a problem hiding this comment.
Are these tests using floating point window sizes?
There was a problem hiding this comment.
I test on my own high DPR device with headed window. The assertion will be off by 1 with this.
For headless window, this should be fine as DPR is always 1.
| size: self.screen_size, | ||
| available_size: self.screen_size, | ||
| offset: Default::default(), | ||
| window_rect: Default::default(), |
There was a problem hiding this comment.
The window_size here wasn't 0, but self.inner_size.get().
The coordinates has always been 0 so it's ok.
There was a problem hiding this comment.
Good point. This should be fixed now.
|
✨ Try run (#16219671511) succeeded. |
5894c7d to
d6f56f6
Compare
Signed-off-by: Euclid Ye <[email protected]> Co-authored-by: Martin Robinson <[email protected]>
Signed-off-by: Euclid Ye <[email protected]>
d6f56f6 to
75fba9a
Compare
Signed-off-by: Martin Robinson <[email protected]>
|
I am not sure about the rounding solution, as I think it might be covering up some other issue, but it's okay for now. Could it be that when we change the size of the window, we need to round up as well? |
I took a closer look.
TL;DR: Will file some issues in w3c/webdriver and discuss before getting to this. EDIT: Opened in w3c/webdriver#1911 |
|
Great! Thank you for the investigation. |
…via the compositor (#38020) Similar to #37960, previously, `AvailHeight`, `AvailWidth`, `Height`, `Width` ask compositor for screen metrics. This PR moves the request to embedder. This simplifies code, and reduces workload of compositor, which is busier most of time. Testing: No behaviour change. Updated some tests. `Width/Height` matches other browsers. --------- Signed-off-by: Euclid Ye <[email protected]>
Previously,
screenX,screenY,outerHeight,outerWidth,moveBy,resizeByask compositor for window rectangle, which then return "inner" rectangle after consulting Embedder.This PR
GetClientWindowRectfrom compositor, and directly let script ask embedder.window_sizetoScreenGeometryScreenGeometryTesting:
tests\wpt\mozilla\tests\mozilla\window_resizeTo.htmlcan now pass for Headed Window.Fixes: #37824