|
|
Chromium Code Reviews
DescriptionFix form validation bubble positioning at hidpi.
Since use-zoom-for-dsf launched, when Blink converts to screen
coordinates it needs to take the device scale factor into account.
Normally it would do this by calling viewportToScreen or a similar
function. However, because the validation bubble anchor is in viewport
coordinates instead of screen coordinates, the positioning code needs to
use device scale factor explicitly.
The reason we can't just convert the anchor to screen coordinates in
Blink is because the same anchor is used for cocoa. It needs to y-flip
the anchor for OSX and converting to screen coordinates too early messes
up that calculation.
BUG=660840
Committed: https://crrev.com/5debc705a0b892bd2dcf82ec7672147268083957
Cr-Commit-Position: refs/heads/master@{#433349}
Patch Set 1 #Patch Set 2 : resolve deps issue #Patch Set 3 : override and comment in rwhv_base #
Total comments: 8
Patch Set 4 : change rwhv to render_widget_host_view #
Total comments: 1
Patch Set 5 : change dsf plumbing #
Messages
Total messages: 37 (20 generated)
Description was changed from ========== Fix form validation bubble positioning at hidpi. Since use-zoom-for-dsf launched, when Blink converts to screen coordinates it needs to take the device scale factor into account. Normally it would do this by calling viewportToScreen or a similar function. However, because the validation bubble anchor is in viewport coordinates instead of screen coordinates, the positioning code needs to use device scale factor explicitly. The reason we can't just convert the anchor to screen coordinates in Blink is because the same anchor is used for cocoa. It needs to y-flip the anchor for OSX and converting to screen coordinates too early messes up that calculation. BUG=660840 ========== to ========== Fix form validation bubble positioning at hidpi. Since use-zoom-for-dsf launched, when Blink converts to screen coordinates it needs to take the device scale factor into account. Normally it would do this by calling viewportToScreen or a similar function. However, because the validation bubble anchor is in viewport coordinates instead of screen coordinates, the positioning code needs to use device scale factor explicitly. The reason we can't just convert the anchor to screen coordinates in Blink is because the same anchor is used for cocoa. It needs to y-flip the anchor for OSX and converting to screen coordinates too early messes up that calculation. BUG=660840 ==========
bsep@chromium.org changed reviewers: + msw@chromium.org, sadrul@chromium.org
msw: chrome/browser/ui/views/ sadrul: content/ (aura) (small change)
The CQ bit was checked by bsep@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: Try jobs failed on following builders: blimp_linux_dbg on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/blimp_linux_dbg...) chromeos_amd64-generic_chromium_compile_only_ng on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/chromeos_amd64-...) chromeos_daisy_chromium_compile_only_ng on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/chromeos_daisy_...) chromeos_x86-generic_chromium_compile_only_ng on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/chromeos_x86-ge...) linux_chromium_asan_rel_ng on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_...) linux_chromium_chromeos_ozone_rel_ng on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_...) linux_chromium_chromeos_rel_ng on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_...) linux_chromium_compile_dbg_ng on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_...)
The CQ bit was checked by bsep@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was checked by bsep@chromium.org to run a CQ dry run
Dry run: CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Dry run: This issue passed the CQ dry run.
c/b/ui lgtm with nit/q https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... File chrome/browser/ui/views/validation_message_bubble_view.cc (right): https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... chrome/browser/ui/views/validation_message_bubble_view.cc:86: return gfx::ScaleToEnclosingRect(rect_in_root_view, 1 / scale) + Is there any chance this is zero? Consider adding a CHECK? https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... File chrome/browser/ui/views/validation_message_bubble_view.h (right): https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... chrome/browser/ui/views/validation_message_bubble_view.h:44: const content::RenderWidgetHostView* rwhv) const; nit: I prefer to avoid acronyms, but this one is fairly common...
https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... File chrome/browser/ui/views/validation_message_bubble_view.cc (right): https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... chrome/browser/ui/views/validation_message_bubble_view.cc:87: rwhv->GetViewBounds().origin().OffsetFromOrigin(); Can you use aura::client::ScreenPositionClient instead? That should work, and that would also mean you won't need to add to the public API of content.
https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... File chrome/browser/ui/views/validation_message_bubble_view.cc (right): https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... chrome/browser/ui/views/validation_message_bubble_view.cc:86: return gfx::ScaleToEnclosingRect(rect_in_root_view, 1 / scale) + On 2016/11/10 18:59:14, msw wrote: > Is there any chance this is zero? Consider adding a CHECK? I don't think we could reach this method if scale was zero. We would crash on browser startup. https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... chrome/browser/ui/views/validation_message_bubble_view.cc:87: rwhv->GetViewBounds().origin().OffsetFromOrigin(); On 2016/11/10 20:44:41, sadrul wrote: > Can you use aura::client::ScreenPositionClient instead? That should work, and > that would also mean you won't need to add to the public API of content. I can't get access to aura-specific methods on RenderWidgetHostView due to dependency restrictions (otherwise I could add GetDeviceScaleFactor to RenderWidgetHostViewAura without touching the public API), which means I can't get a Window to get a ScreenPositionClient instance. And re-plumbing ValidationMessageBubble is tricky because the interface is used across all platforms. Regardless of that, it's a different kind of conversion anyway: between different window spaces. I hacked the dependencies to work just to test and it gives the wrong answer. This needs a Blink->browser conversion. https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... File chrome/browser/ui/views/validation_message_bubble_view.h (right): https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... chrome/browser/ui/views/validation_message_bubble_view.h:44: const content::RenderWidgetHostView* rwhv) const; On 2016/11/10 18:59:14, msw wrote: > nit: I prefer to avoid acronyms, but this one is fairly common... Changed to render_widget_host_view everywhere in this class.
https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... File chrome/browser/ui/views/validation_message_bubble_view.cc (right): https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... chrome/browser/ui/views/validation_message_bubble_view.cc:87: rwhv->GetViewBounds().origin().OffsetFromOrigin(); On 2016/11/11 23:51:27, Bret Sepulveda wrote: > On 2016/11/10 20:44:41, sadrul wrote: > > Can you use aura::client::ScreenPositionClient instead? That should work, and > > that would also mean you won't need to add to the public API of content. > > I can't get access to aura-specific methods on RenderWidgetHostView due to > dependency restrictions (otherwise I could add GetDeviceScaleFactor to > RenderWidgetHostViewAura without touching the public API), which means I can't > get a Window to get a ScreenPositionClient instance. And re-plumbing > ValidationMessageBubble is tricky because the interface is used across all > platforms. You have the RenderWidgetHostView here. You can get the aura::Window by calling GetNativeView() on it. From there, it should be possible to use ScreenPositionClient (see, e.g. RenderWidgetHostViewAura::ConvertRectToScreen()). > Regardless of that, it's a different kind of conversion anyway: between > different window spaces. I hacked the dependencies to work just to test and it > gives the wrong answer. This needs a Blink->browser conversion. Can you explain this a bit more? What is 'root view' here? RWHVAura does some conversions on the rects blink sends to be in screen/browser space (e.g. see uses of ConvertRectToScreen()/ConvertRectFromScreen()). How is this different?
https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... File chrome/browser/ui/views/validation_message_bubble_view.cc (right): https://codereview.chromium.org/2491113002/diff/40001/chrome/browser/ui/views... chrome/browser/ui/views/validation_message_bubble_view.cc:87: rwhv->GetViewBounds().origin().OffsetFromOrigin(); On 2016/11/12 02:30:44, sadrul wrote: > On 2016/11/11 23:51:27, Bret Sepulveda wrote: > > On 2016/11/10 20:44:41, sadrul wrote: > > > Can you use aura::client::ScreenPositionClient instead? That should work, > and > > > that would also mean you won't need to add to the public API of content. > > > > I can't get access to aura-specific methods on RenderWidgetHostView due to > > dependency restrictions (otherwise I could add GetDeviceScaleFactor to > > RenderWidgetHostViewAura without touching the public API), which means I can't > > get a Window to get a ScreenPositionClient instance. And re-plumbing > > ValidationMessageBubble is tricky because the interface is used across all > > platforms. > > You have the RenderWidgetHostView here. You can get the aura::Window by calling > GetNativeView() on it. From there, it should be possible to use > ScreenPositionClient (see, e.g. > RenderWidgetHostViewAura::ConvertRectToScreen()). > > > Regardless of that, it's a different kind of conversion anyway: between > > different window spaces. I hacked the dependencies to work just to test and it > > gives the wrong answer. This needs a Blink->browser conversion. > > Can you explain this a bit more? What is 'root view' here? RWHVAura does some > conversions on the rects blink sends to be in screen/browser space (e.g. see > uses of ConvertRectToScreen()/ConvertRectFromScreen()). How is this different? Okay that plumbing does work. But as far as I can tell this whole family of methods that delegate to ScreenPositionClient give the wrong answer, they're doing the same thing the unpatched code did (i.e. not taking the device scale factor into account). I'm not very familiar with this area but I think it's because it's mostly converting mouse events. When a UI event happens it captures the mouse position, which is in the operating system's coordinate system. So all it has to do is find which window it was relative to. In this case this rectangle is the bounds of a Blink UI element, which is a different coordinate space even though until recently they were coincidentally identical.
> Okay that plumbing does work. But as far as I can tell this whole family of > methods that delegate to ScreenPositionClient give the wrong answer, they're > doing the same thing the unpatched code did (i.e. not taking the device scale > factor into account). In that case, why aren't more things broken? > I'm not very familiar with this area but I think it's because it's mostly > converting mouse events. When a UI event happens it captures the mouse position, > which is in the operating system's coordinate system. So all it has to do is > find which window it was relative to. In this case this rectangle is the bounds > of a Blink UI element, which is a different coordinate space even though until > recently they were coincidentally identical. How are other popups (e.g. <select> dropdowns) positioned correctly in high-dpi? https://codereview.chromium.org/2491113002/diff/60001/chrome/browser/ui/views... File chrome/browser/ui/views/validation_message_bubble_view.cc (right): https://codereview.chromium.org/2491113002/diff/60001/chrome/browser/ui/views... chrome/browser/ui/views/validation_message_bubble_view.cc:87: const float scale = render_widget_host_view->GetDeviceScaleFactor(); Note that if you really need this, you can also get the DSF like so: gfx::NativeView view = rwhv->GetNativeView(); display::Display display = display::Screen::GetScreen()->GetDisplayNearestWindow(view); float scale_factor = display.device_scale_factor();
On 2016/11/14 16:58:03, sadrul wrote: > > Okay that plumbing does work. But as far as I can tell this whole family of > > methods that delegate to ScreenPositionClient give the wrong answer, they're > > doing the same thing the unpatched code did (i.e. not taking the device scale > > factor into account). > > In that case, why aren't more things broken? Sorry, I wasn't clear. ScreenPositionClient is correct most of the time. It's only incorrect in cases where we're converting Blink viewport coordinates to screen coordinates. I didn't see any problematic usages of ScreenPositionClient itself, but there could be other cases like the one in this patch where the code is doing the conversion ad-hoc. > > I'm not very familiar with this area but I think it's because it's mostly > > converting mouse events. When a UI event happens it captures the mouse > position, > > which is in the operating system's coordinate system. So all it has to do is > > find which window it was relative to. In this case this rectangle is the > bounds > > of a Blink UI element, which is a different coordinate space even though until > > recently they were coincidentally identical. > > How are other popups (e.g. <select> dropdowns) positioned correctly in high-dpi? From what I can tell there are two ways popups get created: 1. Popups that are in Blink space create another little web view that enters the views hierarchy just like the normal big web view. It's positioned in DIPs and relative to its parent. This is how <select> works. 2. Popups like the bookmarks bubble are pointing at a browser UI element and so don't need to convert from a Blink coordinate space. So they use ScreenPositionClient to position themselves in screen coordinates. The validation bubble is weird because it's actually #2, but needs to be positioned relative to a web form element, not a browser UI element. I'm guessing it was done this way because popups in #1 are always rectangular and the validation bubble needed an arrow to point to the offending form element. > https://codereview.chromium.org/2491113002/diff/60001/chrome/browser/ui/views... > File chrome/browser/ui/views/validation_message_bubble_view.cc (right): > > https://codereview.chromium.org/2491113002/diff/60001/chrome/browser/ui/views... > chrome/browser/ui/views/validation_message_bubble_view.cc:87: const float scale > = render_widget_host_view->GetDeviceScaleFactor(); > Note that if you really need this, you can also get the DSF like so: > > gfx::NativeView view = rwhv->GetNativeView(); > display::Display display = > display::Screen::GetScreen()->GetDisplayNearestWindow(view); > float scale_factor = display.device_scale_factor(); Done, this plumbing is much better. I didn't really like adding a method to rwhv's API but I couldn't figure out the alternative.
On 2016/11/15 23:28:41, Bret Sepulveda wrote: > On 2016/11/14 16:58:03, sadrul wrote: > > > Okay that plumbing does work. But as far as I can tell this whole family of > > > methods that delegate to ScreenPositionClient give the wrong answer, they're > > > doing the same thing the unpatched code did (i.e. not taking the device > scale > > > factor into account). > > > > In that case, why aren't more things broken? > > Sorry, I wasn't clear. ScreenPositionClient is correct most of the time. It's > only incorrect in cases where we're converting Blink viewport coordinates to > screen coordinates. I didn't see any problematic usages of ScreenPositionClient > itself, but there could be other cases like the one in this patch where the code > is doing the conversion ad-hoc. > > > > I'm not very familiar with this area but I think it's because it's mostly > > > converting mouse events. When a UI event happens it captures the mouse > > position, > > > which is in the operating system's coordinate system. So all it has to do is > > > find which window it was relative to. In this case this rectangle is the > > bounds > > > of a Blink UI element, which is a different coordinate space even though > until > > > recently they were coincidentally identical. > > > > How are other popups (e.g. <select> dropdowns) positioned correctly in > high-dpi? > > From what I can tell there are two ways popups get created: > 1. Popups that are in Blink space create another little web view that enters the > views hierarchy just like the normal big web view. It's positioned in DIPs and > relative to its parent. This is how <select> works. > 2. Popups like the bookmarks bubble are pointing at a browser UI element and so > don't need to convert from a Blink coordinate space. So they use > ScreenPositionClient to position themselves in screen coordinates. > > The validation bubble is weird because it's actually #2, but needs to be > positioned relative to a web form element, not a browser UI element. That's the case for #1 too. The popup/dropdown ends up creating a WindowTreeHost, and positioned it at the right place relative to the blink element (that's how a long dropdown can stick out of the parent browser window). So as long as validation bubble does the same things as the <select> dropdowns, it ought to work correctly. It would be nice to understand the difference in behaviour between the two if that is not the case. (But you may have noticed that with the new change, you don't need my approval no more.) > I'm > guessing it was done this way because popups in #1 are always rectangular and > the validation bubble needed an arrow to point to the offending form element. > > > > https://codereview.chromium.org/2491113002/diff/60001/chrome/browser/ui/views... > > File chrome/browser/ui/views/validation_message_bubble_view.cc (right): > > > > > https://codereview.chromium.org/2491113002/diff/60001/chrome/browser/ui/views... > > chrome/browser/ui/views/validation_message_bubble_view.cc:87: const float > scale > > = render_widget_host_view->GetDeviceScaleFactor(); > > Note that if you really need this, you can also get the DSF like so: > > > > gfx::NativeView view = rwhv->GetNativeView(); > > display::Display display = > > display::Screen::GetScreen()->GetDisplayNearestWindow(view); > > float scale_factor = display.device_scale_factor(); > > Done, this plumbing is much better. I didn't really like adding a method to > rwhv's API but I couldn't figure out the alternative.
> > From what I can tell there are two ways popups get created: > > 1. Popups that are in Blink space create another little web view that enters > the > > views hierarchy just like the normal big web view. It's positioned in DIPs and > > relative to its parent. This is how <select> works. > > 2. Popups like the bookmarks bubble are pointing at a browser UI element and > so > > don't need to convert from a Blink coordinate space. So they use > > ScreenPositionClient to position themselves in screen coordinates. > > > > The validation bubble is weird because it's actually #2, but needs to be > > positioned relative to a web form element, not a browser UI element. > > That's the case for #1 too. The popup/dropdown ends up creating a > WindowTreeHost, and positioned it at the right place relative to the blink > element (that's how a long dropdown can stick out of the parent browser window). > So as long as validation bubble does the same things as the <select> dropdowns, > it ought to work correctly. It would be nice to understand the difference in > behaviour between the two if that is not the case. (But you may have noticed > that with the new change, you don't need my approval no more.) Yes, I meant that #2 normally doesn't position relative to web elements, so it doesn't have a mechanism to ensure it's positioned properly in that case. Which is why the validation bubble is failing here. #1 does have that mechanism, which is why those work. Anyway since msw@ approved the change to ValidationMessageBubbleView I will submit this.
The CQ bit was checked by bsep@chromium.org
The patchset sent to the CQ was uploaded after l-g-t-m from msw@chromium.org Link to the patchset: https://codereview.chromium.org/2491113002/#ps80001 (title: "change dsf plumbing")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Try jobs failed on following builders: linux_chromium_chromeos_ozone_rel_ng on master.tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/linux_chromium_...)
The CQ bit was checked by bsep@chromium.org
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
The CQ bit was unchecked by commit-bot@chromium.org
Failed to apply the patch.
The CQ bit was checked by bsep@chromium.org
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
Message was sent while issue was closed.
Description was changed from ========== Fix form validation bubble positioning at hidpi. Since use-zoom-for-dsf launched, when Blink converts to screen coordinates it needs to take the device scale factor into account. Normally it would do this by calling viewportToScreen or a similar function. However, because the validation bubble anchor is in viewport coordinates instead of screen coordinates, the positioning code needs to use device scale factor explicitly. The reason we can't just convert the anchor to screen coordinates in Blink is because the same anchor is used for cocoa. It needs to y-flip the anchor for OSX and converting to screen coordinates too early messes up that calculation. BUG=660840 ========== to ========== Fix form validation bubble positioning at hidpi. Since use-zoom-for-dsf launched, when Blink converts to screen coordinates it needs to take the device scale factor into account. Normally it would do this by calling viewportToScreen or a similar function. However, because the validation bubble anchor is in viewport coordinates instead of screen coordinates, the positioning code needs to use device scale factor explicitly. The reason we can't just convert the anchor to screen coordinates in Blink is because the same anchor is used for cocoa. It needs to y-flip the anchor for OSX and converting to screen coordinates too early messes up that calculation. BUG=660840 ==========
Message was sent while issue was closed.
Committed patchset #5 (id:80001)
Message was sent while issue was closed.
Description was changed from ========== Fix form validation bubble positioning at hidpi. Since use-zoom-for-dsf launched, when Blink converts to screen coordinates it needs to take the device scale factor into account. Normally it would do this by calling viewportToScreen or a similar function. However, because the validation bubble anchor is in viewport coordinates instead of screen coordinates, the positioning code needs to use device scale factor explicitly. The reason we can't just convert the anchor to screen coordinates in Blink is because the same anchor is used for cocoa. It needs to y-flip the anchor for OSX and converting to screen coordinates too early messes up that calculation. BUG=660840 ========== to ========== Fix form validation bubble positioning at hidpi. Since use-zoom-for-dsf launched, when Blink converts to screen coordinates it needs to take the device scale factor into account. Normally it would do this by calling viewportToScreen or a similar function. However, because the validation bubble anchor is in viewport coordinates instead of screen coordinates, the positioning code needs to use device scale factor explicitly. The reason we can't just convert the anchor to screen coordinates in Blink is because the same anchor is used for cocoa. It needs to y-flip the anchor for OSX and converting to screen coordinates too early messes up that calculation. BUG=660840 Committed: https://crrev.com/5debc705a0b892bd2dcf82ec7672147268083957 Cr-Commit-Position: refs/heads/master@{#433349} ==========
Message was sent while issue was closed.
Patchset 5 (id:??) landed as https://crrev.com/5debc705a0b892bd2dcf82ec7672147268083957 Cr-Commit-Position: refs/heads/master@{#433349} |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
