From a22c29c5f9b0d444b7f418cabfe0d6a09704ce36 Mon Sep 17 00:00:00 2001 From: Francisco Gonzalez Date: Thu, 9 Oct 2025 17:26:23 +0200 Subject: [PATCH] gpui: Fix partial dashed border rendering (#38190) Closes #38189 - Fixed border dashed for diverse scenarios, as demonstrated in the images below. - This change has no impact on the rendering of solid borders, as it was implemented inside an if block for dashed styles Release Notes: - N/A ## Before Images
click to expand (small top border, medium right border, large bottom border) Screenshot From 2025-09-15 13-28-14
click to expand (Same size pairs of borders) Screenshot From 2025-09-15 13-32-22 Screenshot From 2025-09-15 13-33-24
## After Images
click to expand (small top border, medium right border, large bottom border) Screenshot From 2025-09-15 13-17-28
click to expand (same size pairs of borders) Screenshot From 2025-09-15 13-37-59 Screenshot From 2025-09-15 13-36-34
--- crates/gpui/src/platform/blade/shaders.wgsl | 19 ++++++++++++++++++- crates/gpui/src/platform/mac/shaders.metal | 10 +++++++++- crates/gpui/src/platform/windows/shaders.hlsl | 9 ++++++++- 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/crates/gpui/src/platform/blade/shaders.wgsl b/crates/gpui/src/platform/blade/shaders.wgsl index d00e596c1043c4df3ed7cf1e38943496fcebbda2..1de8ad442018624b4322901136ec777e66d96b18 100644 --- a/crates/gpui/src/platform/blade/shaders.wgsl +++ b/crates/gpui/src/platform/blade/shaders.wgsl @@ -683,7 +683,24 @@ fn fs_quad(input: QuadVarying) -> @location(0) vec4 { let is_horizontal = corner_center_to_point.x < corner_center_to_point.y; - let border_width = select(border.y, border.x, is_horizontal); + + // When applying dashed borders to just some, not all, the sides. + // The way we chose border widths above sometimes comes with a 0 width value. + // So we choose again to avoid division by zero. + // TODO: A better solution exists taking a look at the whole file. + // this does not fix single dashed borders at the corners + let dashed_border = vec2( + max( + quad.border_widths.bottom, + quad.border_widths.top, + ), + max( + quad.border_widths.right, + quad.border_widths.left, + ) + ); + + let border_width = select(dashed_border.y, dashed_border.x, is_horizontal); dash_velocity = dv_numerator / border_width; t = select(point.y, point.x, is_horizontal) * dash_velocity; max_t = select(size.y, size.x, is_horizontal) * dash_velocity; diff --git a/crates/gpui/src/platform/mac/shaders.metal b/crates/gpui/src/platform/mac/shaders.metal index 37ec7b530a9cbdf562c179ee10cc4c82af07f0d2..7c3886031ab915e674469a6d85ef368c35b2b759 100644 --- a/crates/gpui/src/platform/mac/shaders.metal +++ b/crates/gpui/src/platform/mac/shaders.metal @@ -245,7 +245,15 @@ fragment float4 quad_fragment(QuadFragmentInput input [[stage_in]], // out on each straight line, rather than around the whole // perimeter. This way each line starts and ends with a dash. bool is_horizontal = corner_center_to_point.x < corner_center_to_point.y; - float border_width = is_horizontal ? border.x : border.y; + + // Choosing the right border width for dashed borders. + // TODO: A better solution exists taking a look at the whole file. + // this does not fix single dashed borders at the corners + float2 dashed_border = float2( + fmax(quad.border_widths.bottom, quad.border_widths.top), + fmax(quad.border_widths.right, quad.border_widths.left)); + + float border_width = is_horizontal ? dashed_border.x : dashed_border.y; dash_velocity = dv_numerator / border_width; t = is_horizontal ? point.x : point.y; t *= dash_velocity; diff --git a/crates/gpui/src/platform/windows/shaders.hlsl b/crates/gpui/src/platform/windows/shaders.hlsl index 1915802d08d8c22c9bfc893f087bd61d0a1de331..c3ad2952dbf7122672104135f432e0257471642d 100644 --- a/crates/gpui/src/platform/windows/shaders.hlsl +++ b/crates/gpui/src/platform/windows/shaders.hlsl @@ -660,7 +660,14 @@ float4 quad_fragment(QuadFragmentInput input): SV_Target { // out on each straight line, rather than around the whole // perimeter. This way each line starts and ends with a dash. bool is_horizontal = corner_center_to_point.x < corner_center_to_point.y; - float border_width = is_horizontal ? border.x : border.y; + // Choosing the right border width for dashed borders. + // TODO: A better solution exists taking a look at the whole file. + // this does not fix single dashed borders at the corners + float2 dashed_border = float2( + max(quad.border_widths.bottom, quad.border_widths.top), + max(quad.border_widths.right, quad.border_widths.left) + ); + float border_width = is_horizontal ? dashed_border.x : dashed_border.y; dash_velocity = dv_numerator / border_width; t = is_horizontal ? the_point.x : the_point.y; t *= dash_velocity;