+
Skip to content

Conversation

samuelmaddock
Copy link
Member

@samuelmaddock samuelmaddock commented May 30, 2024

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).

Windows Mac
image image

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

Release Notes

Notes: Added View.setBorderRadius(radius) for customizing the border radius of views—with compatibility for WebContentsView.

@electron-cation electron-cation bot added the new-pr 🌱 PR opened recently label May 30, 2024
@samuelmaddock samuelmaddock added the semver/minor backwards-compatible functionality label May 30, 2024
Copy link
Member

@erickzhao erickzhao left a 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);
}
Copy link
Member Author

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.
Copy link
Member Author

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());
Copy link
Contributor

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.

Copy link
Member Author

@samuelmaddock samuelmaddock May 31, 2024

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"

Copy link
Contributor

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?

Copy link
Member Author

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: uses SetClipPath to mask rendering
  • WebContentsView: uses SetCornerRadii 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.

Copy link
Member Author

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

Copy link
Contributor

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.

Copy link
Member

@codebytere codebytere left a comment

Choose a reason for hiding this comment

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

API LGTM

Copy link
Contributor

@nornagon nornagon left a 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

Copy link
Contributor

@nornagon nornagon left a comment

Choose a reason for hiding this comment

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

API LGTM

@samuelmaddock samuelmaddock force-pushed the feat/view-border-radius branch 2 times, most recently from 2cc50d4 to c31374f Compare July 11, 2024 20:19
samuelmaddock and others added 6 commits July 15, 2024 13:16
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
@samuelmaddock samuelmaddock force-pushed the feat/view-border-radius branch from c31374f to ce97b90 Compare July 15, 2024 17:16
Copy link
Member

@jkleinsc jkleinsc left a 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.

@samuelmaddock samuelmaddock mentioned this pull request Jul 16, 2024
5 tasks
@jkleinsc jkleinsc merged commit 778d309 into electron:main Jul 17, 2024
@release-clerk
Copy link

release-clerk bot commented Jul 17, 2024

Release Notes Persisted

Added View.setBorderRadius(radius) for customizing the border radius of views—with compatibility for WebContentsView.

@samuelmaddock samuelmaddock deleted the feat/view-border-radius branch July 17, 2024 00:17
codebytere added a commit that referenced this pull request Jul 30, 2024
* 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>
jkleinsc pushed a commit that referenced this pull request Jul 30, 2024
* 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>
@liuyike98
Copy link

@samuelmaddock any solution to set left-bottom and right-bottom border radius? webContentsView just as a part of my custom view.

@samuelmaddock
Copy link
Member Author

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature Request]: Allow rounded corners on WebContentsView [Feature Request]: Set border-radius for BrowserView.
6 participants
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载