-
Notifications
You must be signed in to change notification settings - Fork 16.5k
feat: customize border radius of Views #42320
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
feat: customize border radius of Views #42320
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API LGTM
r = std::min(r, size.height() / 2.f); | ||
r = std::max(r, 0.f); | ||
radius = std::floor(r); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to upstream a CL to make ash::RoundedRectCutoutPathBuilder
easier to work with, but for now I think this is simple enough to workaround here.
|
||
* `radius` Integer - Border radius size in pixels. | ||
|
||
**Note:** The area cutout of the view's border still captures clicks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't imagine this would be too difficult to fix, but I'd rather do this in a future PR if a need arises.
builder.CornerRadius(radius); | ||
view_->SetClipPath(builder.Build()); | ||
} else { | ||
view_->SetClipPath(SkPath()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any chance we could expose SetClipPath more directly? I'd generally like to err on the side of power over ease of use in the Views API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The difficulty here is that the native views use a different code path for faster clipping
https://source.chromium.org/chromium/chromium/src/+/main:ui/views/controls/native/native_view_host_aura.cc;l=349;drc=8b6aaad8027390ce6b32d82d57328e93f34bb8e5
Arguably the WebContentsView border radius is the dominant use case. The clipping for the underlying View allows us to also clip the background color.
edit: to elaborate, this fast path goes down to the renderer level which has special masking for rounded corners. See skia_renderer.cc and search for "rounded"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, afaict this code here doesn't use the fast path, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WebContentsView
is using SetCornerRadii which uses the fast path. This is required to apply a mask to the underlying views::NativeViewHost
.
This results in two implementations of setBorderRadius
View
: usesSetClipPath
to mask renderingWebContentsView
: usesSetCornerRadii
to apply the fast path render clipping to the WebView- Also calls into the View's mask rendering so its background color gets a mask applied as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we feel strongly about exposing a more powerful SetClipPath
API, we could always introduce one in the future and reimplement View.prototype.setBorderRadius
using it in an internal JS API.
Are we comfortable unblocking this? @nornagon @electron/wg-api
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough! I'll unblock this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwing a request changes on here as I feel there are unresolved questions about this API
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
API LGTM
2cc50d4
to
c31374f
Compare
test: initial setBorderRadius tests fix: robustly set border radius chore: add PAUSE_CAPTURE_TESTS for easier screencap dev feat: add view border radius support test: view border radius refactor: cleanup view code
c31374f
to
ce97b90
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes made to tests here break macOS arm64. It also appears for some reason the changes here are causing linux tests to fail with a disk out of space error.
Release Notes Persisted
|
* fix: remove InspectableWebContentsViewMac (#43033) * Revert "refactor: remove InspectableWebContentsViewMac in favor of the Views version (#41326)" This reverts commit e67ab9a. * build: fix gn check * chore: implement setCornerRadii in inspectable_web_contents_view_mac Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * fix: pass in cornerRadii value in setCornerRadii Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * fix: forward declaration * 5578714: Remove 0-arg (default) constructor for views::Widget::InitParams. https://chromium-review.googlesource.com/c/chromium/src/+/5578714 * fix: contents_web_view_ -> contents_view_ * chore: remove extraneous includes --------- Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * fix: remove custom border radius feat (#42320) * fixup! remove custom border radius feat --------- Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
* fix: remove InspectableWebContentsViewMac (#43033) * Revert "refactor: remove InspectableWebContentsViewMac in favor of the Views version (#41326)" This reverts commit e67ab9a. * build: fix gn check * chore: implement setCornerRadii in inspectable_web_contents_view_mac Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * fix: pass in cornerRadii value in setCornerRadii Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * fix: forward declaration * 5578714: Remove 0-arg (default) constructor for views::Widget::InitParams. https://chromium-review.googlesource.com/c/chromium/src/+/5578714 * fix: contents_web_view_ -> contents_view_ * chore: remove extraneous includes --------- Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> * fix: remove custom border radius feat (#42320) * fix: fix views::Widget::InitParams params --------- Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
@samuelmaddock any solution to set left-bottom and right-bottom border radius? webContentsView just as a part of my custom view. |
It's not currently possible. However, based on the implementation of gfx::RoundedCornerF, it should be possible if someone is interested in submitting a pull request. |
Description of Change
resolves #42288
resolves #33426
Adds
View.setBorderRadius(radius)
which applies a rounded corner mask to the view. Note that there are two separate implementations depending on whether it's purely a Chromium view (View/ImageView/etc.) or a native view (WebView).Border radius demo: https://gist.github.com/samuelmaddock/4905763d665905c9134447ab9a9ac283
Animated demo: https://gist.github.com/samuelmaddock/99f0c66a584d4134139d3c9608df6652
I unfortunately don't have a Linux machine setup to test this. However, that platform relies on //ui/aura, same as Windows, so I figure it'll Just Work™️
Also, maybe worth calling out that this depends on #41326 for a consistent implementation across platforms.
Checklist
npm test
passesRelease Notes
Notes: Added
View.setBorderRadius(radius)
for customizing the border radius of views—with compatibility forWebContentsView
.