Require a `StrokeKind` when painting rectangles with strokes (#5648)

This is a breaking change, requiring users to think about wether the
stroke is inside/centered/outside the rect.

When in doubt, add `egui::StrokeKind::Inside` to the function call.
This commit is contained in:
Emil Ernerfeldt 2025-01-29 15:52:49 +01:00 committed by GitHub
parent 8d2c8c203c
commit 525d435a84
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 184 additions and 73 deletions

View File

@ -5,7 +5,7 @@ use crate::{
Response, Sense, Stroke, TextStyle, TextWrapMode, Ui, Vec2, WidgetInfo, WidgetText, WidgetType,
};
use emath::GuiRounding as _;
use epaint::Shape;
use epaint::{Shape, StrokeKind};
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
@ -576,6 +576,7 @@ impl CollapsingHeader {
visuals.rounding,
visuals.weak_bg_fill,
visuals.bg_stroke,
StrokeKind::Inside,
));
}
@ -583,8 +584,13 @@ impl CollapsingHeader {
{
let rect = rect.expand(visuals.expansion);
ui.painter()
.rect(rect, visuals.rounding, visuals.bg_fill, visuals.bg_stroke);
ui.painter().rect(
rect,
visuals.rounding,
visuals.bg_fill,
visuals.bg_stroke,
StrokeKind::Inside,
);
}
{

View File

@ -474,6 +474,7 @@ fn button_frame(
visuals.rounding,
visuals.weak_bg_fill,
visuals.bg_stroke,
epaint::StrokeKind::Inside,
),
);
}

View File

@ -423,10 +423,13 @@ impl Frame {
let fill_rect = self.fill_rect(content_rect);
let widget_rect = self.widget_rect(content_rect);
let frame_shape = Shape::Rect(
epaint::RectShape::new(fill_rect, rounding, fill, stroke)
.with_stroke_kind(epaint::StrokeKind::Outside),
);
let frame_shape = Shape::Rect(epaint::RectShape::new(
fill_rect,
rounding,
fill,
stroke,
epaint::StrokeKind::Outside,
));
if shadow == Default::default() {
frame_shape

View File

@ -356,6 +356,7 @@ impl Resize {
rect,
3.0,
ui.visuals().widgets.noninteractive.bg_stroke,
epaint::StrokeKind::Inside,
));
}

View File

@ -11,7 +11,7 @@ use epaint::{
tessellator,
text::{FontInsert, FontPriority, Fonts},
util::OrderedFloat,
vec2, ClippedPrimitive, ClippedShape, Color32, ImageData, ImageDelta, Pos2, Rect,
vec2, ClippedPrimitive, ClippedShape, Color32, ImageData, ImageDelta, Pos2, Rect, StrokeKind,
TessellationOptions, TextureAtlas, TextureId, Vec2,
};
@ -1087,7 +1087,7 @@ impl Context {
let text = format!("🔥 {text}");
let color = self.style().visuals.error_fg_color;
let painter = self.debug_painter();
painter.rect_stroke(widget_rect, 0.0, (1.0, color));
painter.rect_stroke(widget_rect, 0.0, (1.0, color), StrokeKind::Outside);
let below = widget_rect.bottom() + 32.0 < screen_rect.bottom();

View File

@ -208,7 +208,12 @@ impl GridLayout {
if (debug_expand_width && too_wide) || (debug_expand_height && too_high) {
let painter = self.ctx.debug_painter();
painter.rect_stroke(rect, 0.0, (1.0, Color32::LIGHT_BLUE));
painter.rect_stroke(
rect,
0.0,
(1.0, Color32::LIGHT_BLUE),
crate::StrokeKind::Inside,
);
let stroke = Stroke::new(2.5, Color32::from_rgb(200, 0, 0));
let paint_line_seg = |a, b| painter.line_segment([a, b], stroke);

View File

@ -465,7 +465,7 @@ pub use epaint::{
text::{FontData, FontDefinitions, FontFamily, FontId, FontTweak},
textures::{TextureFilter, TextureOptions, TextureWrapMode, TexturesDelta},
ClippedPrimitive, ColorImage, FontImage, ImageData, Margin, Mesh, PaintCallback,
PaintCallbackInfo, Rounding, Shadow, Shape, Stroke, TextureHandle, TextureId,
PaintCallbackInfo, Rounding, Shadow, Shape, Stroke, StrokeKind, TextureHandle, TextureId,
};
pub mod text {

View File

@ -3,7 +3,7 @@ use std::sync::Arc;
use emath::GuiRounding as _;
use epaint::{
text::{Fonts, Galley, LayoutJob},
CircleShape, ClippedShape, PathStroke, RectShape, Rounding, Shape, Stroke,
CircleShape, ClippedShape, PathStroke, RectShape, Rounding, Shape, Stroke, StrokeKind,
};
use crate::{
@ -301,6 +301,7 @@ impl Painter {
0.0,
color.additive().linear_multiply(0.015),
(1.0, color),
StrokeKind::Outside,
);
self.text(
rect.min,
@ -407,15 +408,22 @@ impl Painter {
})
}
/// The stroke extends _outside_ the [`Rect`].
/// See also [`Self::rect_filled`] and [`Self::rect_stroke`].
pub fn rect(
&self,
rect: Rect,
rounding: impl Into<Rounding>,
fill_color: impl Into<Color32>,
stroke: impl Into<Stroke>,
stroke_kind: StrokeKind,
) -> ShapeIdx {
self.add(RectShape::new(rect, rounding, fill_color, stroke))
self.add(RectShape::new(
rect,
rounding,
fill_color,
stroke,
stroke_kind,
))
}
pub fn rect_filled(
@ -433,8 +441,9 @@ impl Painter {
rect: Rect,
rounding: impl Into<Rounding>,
stroke: impl Into<Stroke>,
stroke_kind: StrokeKind,
) -> ShapeIdx {
self.add(RectShape::stroke(rect, rounding, stroke))
self.add(RectShape::stroke(rect, rounding, stroke, stroke_kind))
}
/// Show an arrow starting at `origin` and going in the direction of `vec`, with the length `vec.length()`.

View File

@ -121,7 +121,13 @@ impl DebugRect {
Color32::LIGHT_BLUE
};
let rect_bg_color = Color32::BLUE.gamma_multiply(0.5);
painter.rect(rect, 0.0, rect_bg_color, (1.0, rect_fg_color));
painter.rect(
rect,
0.0,
rect_bg_color,
(1.0, rect_fg_color),
crate::StrokeKind::Outside,
);
}
if !callstack.is_empty() {
@ -157,7 +163,13 @@ impl DebugRect {
text_bg_color
};
let text_rect = Rect::from_min_size(text_pos, galley.size());
painter.rect(text_rect, 0.0, text_bg_color, (1.0, text_rect_stroke_color));
painter.rect(
text_rect,
0.0,
text_bg_color,
(1.0, text_rect_stroke_color),
crate::StrokeKind::Middle,
);
painter.galley(text_pos, galley, text_color);
if is_clicking {

View File

@ -281,7 +281,7 @@ impl Placer {
if let Some(grid) = &self.grid {
let rect = grid.next_cell(self.cursor(), Vec2::splat(0.0));
painter.rect_stroke(rect, 1.0, stroke);
painter.rect_stroke(rect, 1.0, stroke, epaint::StrokeKind::Inside);
let align = Align2::CENTER_CENTER;
painter.debug_text(align.pos_in_rect(&rect), align, stroke.color, text);
} else {

View File

@ -1186,7 +1186,7 @@ impl Ui {
/// # egui::__run_test_ui(|ui| {
/// let response = ui.allocate_response(egui::vec2(100.0, 200.0), egui::Sense::click());
/// if response.clicked() { /* … */ }
/// ui.painter().rect_stroke(response.rect, 0.0, (1.0, egui::Color32::WHITE));
/// ui.painter().rect_stroke(response.rect, 0.0, (1.0, egui::Color32::WHITE), egui::StrokeKind::Inside);
/// # });
/// ```
pub fn allocate_response(&mut self, desired_size: Vec2, sense: Sense) -> Response {
@ -1253,8 +1253,12 @@ impl Ui {
let debug_expand_height = self.style().debug.show_expand_height;
if (debug_expand_width && too_wide) || (debug_expand_height && too_high) {
self.painter
.rect_stroke(rect, 0.0, (1.0, Color32::LIGHT_BLUE));
self.painter.rect_stroke(
rect,
0.0,
(1.0, Color32::LIGHT_BLUE),
crate::StrokeKind::Inside,
);
let stroke = Stroke::new(2.5, Color32::from_rgb(200, 0, 0));
let paint_line_seg = |a, b| self.painter().line_segment([a, b], stroke);

View File

@ -319,6 +319,7 @@ impl Widget for Button<'_> {
frame_rounding,
frame_fill,
frame_stroke,
epaint::StrokeKind::Inside,
);
let mut cursor_x = rect.min.x + button_padding.x;

View File

@ -107,6 +107,7 @@ impl Widget for Checkbox<'_> {
visuals.rounding,
visuals.bg_fill,
visuals.bg_stroke,
epaint::StrokeKind::Inside,
));
if indeterminate {

View File

@ -7,7 +7,7 @@ use crate::{
};
use epaint::{
ecolor::{Color32, Hsva, HsvaGamma, Rgba},
pos2, vec2, Mesh, Rect, Shape, Stroke, Vec2,
pos2, vec2, Mesh, Rect, Shape, Stroke, StrokeKind, Vec2,
};
fn contrast_color(color: impl Into<Rgba>) -> Color32 {
@ -97,11 +97,16 @@ fn color_button(ui: &mut Ui, color: Color32, open: bool) -> Response {
};
let rect = rect.expand(visuals.expansion);
show_color_at(ui.painter(), color, rect);
let stroke_width = 1.0;
show_color_at(ui.painter(), color, rect.shrink(stroke_width));
let rounding = visuals.rounding.at_most(2); // Can't do more rounding because the background grid doesn't do any rounding
ui.painter()
.rect_stroke(rect, rounding, (2.0, visuals.bg_fill)); // fill is intentional, because default style has no border
ui.painter().rect_stroke(
rect,
rounding,
(stroke_width, visuals.bg_fill), // Using fill for stroke is intentional, because default style has no border
StrokeKind::Inside,
);
}
response
@ -139,7 +144,8 @@ fn color_slider_1d(ui: &mut Ui, value: &mut f32, color_at: impl Fn(f32) -> Color
ui.painter().add(Shape::mesh(mesh));
}
ui.painter().rect_stroke(rect, 0.0, visuals.bg_stroke); // outline
ui.painter()
.rect_stroke(rect, 0.0, visuals.bg_stroke, StrokeKind::Inside); // outline
{
// Show where the slider is at:
@ -208,7 +214,8 @@ fn color_slider_2d(
}
ui.painter().add(Shape::mesh(mesh)); // fill
ui.painter().rect_stroke(rect, 0.0, visuals.bg_stroke); // outline
ui.painter()
.rect_stroke(rect, 0.0, visuals.bg_stroke, StrokeKind::Inside); // outline
// Show where the slider is at:
let x = lerp(rect.left()..=rect.right(), *x_value);

View File

@ -137,8 +137,12 @@ impl Widget for ImageButton<'_> {
);
// Draw frame outline:
ui.painter()
.rect_stroke(rect.expand2(expansion), rounding, stroke);
ui.painter().rect_stroke(
rect.expand2(expansion),
rounding,
stroke,
epaint::StrokeKind::Inside,
);
}
widgets::image::texture_load_result_response(&self.image.source(ui.ctx()), &tlr, response)

View File

@ -137,7 +137,7 @@ impl Widget for ProgressBar {
let corner_radius = outer_rect.height() / 2.0;
let rounding = rounding.unwrap_or_else(|| corner_radius.into());
ui.painter()
.rect(outer_rect, rounding, visuals.extreme_bg_color, Stroke::NONE);
.rect_filled(outer_rect, rounding, visuals.extreme_bg_color);
let min_width =
2.0 * f32::max(rounding.sw as _, rounding.nw as _).at_most(corner_radius);
let filled_width = (outer_rect.width() * progress).at_least(min_width);
@ -152,13 +152,12 @@ impl Widget for ProgressBar {
bright
};
ui.painter().rect(
ui.painter().rect_filled(
inner_rect,
rounding,
Color32::from(
Rgba::from(fill.unwrap_or(visuals.selection.bg_fill)) * color_factor as f32,
),
Stroke::NONE,
);
if animate && !is_custom_rounding {

View File

@ -74,6 +74,7 @@ impl Widget for SelectableLabel {
visuals.rounding,
visuals.weak_bg_fill,
visuals.bg_stroke,
epaint::StrokeKind::Inside,
);
}

View File

@ -815,8 +815,13 @@ impl Slider<'_> {
};
let v = v + Vec2::splat(visuals.expansion);
let rect = Rect::from_center_size(center, 2.0 * v);
ui.painter()
.rect(rect, visuals.rounding, visuals.bg_fill, visuals.fg_stroke);
ui.painter().rect(
rect,
visuals.rounding,
visuals.bg_fill,
visuals.fg_stroke,
epaint::StrokeKind::Inside,
);
}
}
}

View File

@ -1,7 +1,10 @@
use std::sync::Arc;
use emath::{Rect, TSTransform};
use epaint::text::{cursor::CCursor, Galley, LayoutJob};
use epaint::{
text::{cursor::CCursor, Galley, LayoutJob},
StrokeKind,
};
use crate::{
epaint,
@ -442,6 +445,7 @@ impl TextEdit<'_> {
visuals.rounding,
background_color,
ui.visuals().selection.stroke,
StrokeKind::Inside,
)
} else {
epaint::RectShape::new(
@ -449,6 +453,7 @@ impl TextEdit<'_> {
visuals.rounding,
background_color,
visuals.bg_stroke, // TODO(emilk): we want to show something here, or a text-edit field doesn't "pop".
StrokeKind::Inside,
)
}
} else {
@ -457,6 +462,7 @@ impl TextEdit<'_> {
frame_rect,
visuals.rounding,
visuals.bg_stroke, // TODO(emilk): we want to show something here, or a text-edit field doesn't "pop".
StrokeKind::Inside,
)
};

View File

@ -75,6 +75,7 @@ impl FrameHistory {
style.rounding,
ui.visuals().extreme_bg_color,
ui.style().noninteractive().bg_stroke,
egui::StrokeKind::Inside,
)));
let rect = rect.shrink(4.0);

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e6cc6ff64eb73ddac89ecdacd07c2176f3ab952c0db4593fccf6d11f155ec392
size 103100
oid sha256:2292f0f80bfd3c80055a72eb983549ac2875d36acb333732bd0a67e51b24ae4f
size 102983

View File

@ -76,7 +76,13 @@ pub fn criterion_benchmark(c: &mut Criterion) {
let painter = ui.painter();
let rect = ui.max_rect();
b.iter(|| {
painter.rect(rect, 2.0, egui::Color32::RED, (1.0, egui::Color32::WHITE));
painter.rect(
rect,
2.0,
egui::Color32::RED,
(1.0, egui::Color32::WHITE),
egui::StrokeKind::Inside,
);
});
});
});

View File

@ -390,6 +390,7 @@ impl BoxPainting {
self.rounding,
ui.visuals().text_color().gamma_multiply(0.5),
Stroke::new(self.stroke_width, Color32::WHITE),
egui::StrokeKind::Inside,
);
}
});

View File

@ -1,6 +1,7 @@
use egui::epaint::{CubicBezierShape, PathShape, QuadraticBezierShape};
use egui::{
emath, epaint, pos2, Color32, Context, Frame, Grid, Pos2, Rect, Sense, Shape, Stroke, Ui, Vec2,
emath,
epaint::{self, CubicBezierShape, PathShape, QuadraticBezierShape},
pos2, Color32, Context, Frame, Grid, Pos2, Rect, Sense, Shape, Stroke, StrokeKind, Ui, Vec2,
Widget, Window,
};
@ -132,6 +133,7 @@ impl PaintBezier {
shape.visual_bounding_rect(),
0.0,
self.bounding_box_stroke,
StrokeKind::Outside,
));
painter.add(shape);
}
@ -143,6 +145,7 @@ impl PaintBezier {
shape.visual_bounding_rect(),
0.0,
self.bounding_box_stroke,
StrokeKind::Outside,
));
painter.add(shape);
}

View File

@ -56,8 +56,13 @@ pub fn toggle_ui(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
// All coordinates are in absolute screen coordinates so we use `rect` to place the elements.
let rect = rect.expand(visuals.expansion);
let radius = 0.5 * rect.height();
ui.painter()
.rect(rect, radius, visuals.bg_fill, visuals.bg_stroke);
ui.painter().rect(
rect,
radius,
visuals.bg_fill,
visuals.bg_stroke,
egui::StrokeKind::Inside,
);
// Paint the circle, animating it from left to right with `how_on`:
let circle_x = egui::lerp((rect.left() + radius)..=(rect.right() - radius), how_on);
let center = egui::pos2(circle_x, rect.center().y);
@ -88,8 +93,13 @@ fn toggle_ui_compact(ui: &mut egui::Ui, on: &mut bool) -> egui::Response {
let visuals = ui.style().interact_selectable(&response, *on);
let rect = rect.expand(visuals.expansion);
let radius = 0.5 * rect.height();
ui.painter()
.rect(rect, radius, visuals.bg_fill, visuals.bg_stroke);
ui.painter().rect(
rect,
radius,
visuals.bg_fill,
visuals.bg_stroke,
egui::StrokeKind::Inside,
);
let circle_x = egui::lerp((rect.left() + radius)..=(rect.right() - radius), how_on);
let center = egui::pos2(circle_x, rect.center().y);
ui.painter()

View File

@ -452,7 +452,12 @@ fn pixel_test_strokes(ui: &mut Ui) {
Pos2::new(cursor_pixel.x, cursor_pixel.y),
Vec2::splat(size as f32),
);
painter.rect_stroke(rect_points / pixels_per_point, 0.0, stroke);
painter.rect_stroke(
rect_points / pixels_per_point,
0.0,
stroke,
egui::StrokeKind::Outside,
);
cursor_pixel.x += (1 + size) as f32 + thickness_pixels * 2.0;
}
}

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7d8135b745cb95a7e7c7a26e73e160742f88ec177a2fa262215c4886d98ff172
size 24403
oid sha256:e4fef5fa8661f207bae2c58381e729cdaf77aecc8b3f178caf262dc310e3a490
size 24206

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:64fe3ef34aaf3104931954f4a39760b99944f42da13f866622ca0222b750f6be
size 17731
oid sha256:6efc59cb9908533baa1a7346b359e9e21c5faf0e373dac6fa7db5476e644233d
size 17678

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4eed8890c6d8fa6b97639197f5d1be79a72724a70470c5e5ae4b55e3447b9b88
size 35561
oid sha256:d076f5365bfa87b7e61d3808b8b9b367157ea6e55ccf665720cbd2237d53793d
size 35563

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b3dc1bf9a59007a6ad0fb66a345d6cf272bd8bdcd26b10dbf411c1280e62b6fc
size 158285
oid sha256:a291f3a5724aefc59ba7881f48752ccc826ca5e480741c221d195061f562ccc9
size 158220

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0a61ecf294d930ebbee9837611d7a75381e690348f448b1c0c8264b27f44ceb3
size 7535
oid sha256:64fd46da67cab2afae0ea8997a88fb43fd207e24cc3943086d978a8de717320f
size 7542

View File

@ -16,10 +16,8 @@ pub struct RectShape {
/// The thickness and color of the outline.
///
/// The stroke extends _outside_ the edge of [`Self::rect`],
/// i.e. using [`crate::StrokeKind::Outside`].
///
/// This means the [`Self::visual_bounding_rect`] is `rect.size() + 2.0 * stroke.width`.
/// Whether or not the stroke is inside or outside the edge of [`Self::rect`],
/// is controlled by [`Self::stroke_kind`].
pub stroke: Stroke,
/// Is the stroke on the inside, outside, or centered on the rectangle?
@ -62,20 +60,21 @@ fn rect_shape_size() {
}
impl RectShape {
/// The stroke extends _outside_ the [`Rect`].
/// See also [`Self::filled`] and [`Self::stroke`].
#[inline]
pub fn new(
rect: Rect,
rounding: impl Into<Rounding>,
fill_color: impl Into<Color32>,
stroke: impl Into<Stroke>,
stroke_kind: StrokeKind,
) -> Self {
Self {
rect,
rounding: rounding.into(),
fill: fill_color.into(),
stroke: stroke.into(),
stroke_kind: StrokeKind::Outside,
stroke_kind,
round_to_pixels: None,
blur_width: 0.0,
brush: Default::default(),
@ -88,14 +87,24 @@ impl RectShape {
rounding: impl Into<Rounding>,
fill_color: impl Into<Color32>,
) -> Self {
Self::new(rect, rounding, fill_color, Stroke::NONE)
Self::new(
rect,
rounding,
fill_color,
Stroke::NONE,
StrokeKind::Outside, // doesn't matter
)
}
/// The stroke extends _outside_ the [`Rect`].
#[inline]
pub fn stroke(rect: Rect, rounding: impl Into<Rounding>, stroke: impl Into<Stroke>) -> Self {
pub fn stroke(
rect: Rect,
rounding: impl Into<Rounding>,
stroke: impl Into<Stroke>,
stroke_kind: StrokeKind,
) -> Self {
let fill = Color32::TRANSPARENT;
Self::new(rect, rounding, fill, stroke)
Self::new(rect, rounding, fill, stroke, stroke_kind)
}
/// Set if the stroke is on the inside, outside, or centered on the rectangle.
@ -146,8 +155,12 @@ impl RectShape {
if self.fill == Color32::TRANSPARENT && self.stroke.is_empty() {
Rect::NOTHING
} else {
let Stroke { width, .. } = self.stroke; // Make sure we remember to update this if we change `stroke` to `PathStroke`
self.rect.expand(width + self.blur_width / 2.0)
let expand = match self.stroke_kind {
StrokeKind::Inside => 0.0,
StrokeKind::Middle => self.stroke.width / 2.0,
StrokeKind::Outside => self.stroke.width,
};
self.rect.expand(expand + self.blur_width / 2.0)
}
}

View File

@ -7,7 +7,7 @@ use emath::{pos2, Align2, Pos2, Rangef, Rect, TSTransform, Vec2};
use crate::{
stroke::PathStroke,
text::{FontId, Fonts, Galley},
Color32, Mesh, Rounding, Stroke, TextureId,
Color32, Mesh, Rounding, Stroke, StrokeKind, TextureId,
};
use super::{
@ -275,6 +275,7 @@ impl Shape {
Self::Ellipse(EllipseShape::stroke(center, radius, stroke))
}
/// See also [`Self::rect_stroke`].
#[inline]
pub fn rect_filled(
rect: Rect,
@ -284,14 +285,15 @@ impl Shape {
Self::Rect(RectShape::filled(rect, rounding, fill_color))
}
/// The stroke extends _outside_ the [`Rect`].
/// See also [`Self::rect_filled`].
#[inline]
pub fn rect_stroke(
rect: Rect,
rounding: impl Into<Rounding>,
stroke: impl Into<Stroke>,
stroke_kind: StrokeKind,
) -> Self {
Self::Rect(RectShape::stroke(rect, rounding, stroke))
Self::Rect(RectShape::stroke(rect, rounding, stroke, stroke_kind))
}
#[allow(clippy::needless_pass_by_value)]

View File

@ -1400,7 +1400,7 @@ impl Tessellator {
if self.options.debug_paint_text_rects {
let rect = text_shape.galley.rect.translate(text_shape.pos.to_vec2());
self.tessellate_rect(
&RectShape::stroke(rect.expand(0.5), 2.0, (0.5, Color32::GREEN)),
&RectShape::stroke(rect, 2.0, (0.5, Color32::GREEN), StrokeKind::Outside),
out,
);
}
@ -2189,7 +2189,12 @@ impl Tessellator {
.flat_map(|clipped_primitive| {
let mut clip_rect_mesh = Mesh::default();
self.tessellate_shape(
Shape::rect_stroke(clipped_primitive.clip_rect, 0.0, stroke),
Shape::rect_stroke(
clipped_primitive.clip_rect,
0.0,
stroke,
StrokeKind::Outside,
),
&mut clip_rect_mesh,
);

View File

@ -478,7 +478,7 @@ fn drop_target<R>(
ui.painter().set(
background_id,
egui::epaint::RectShape::new(rect, style.rounding, fill, stroke),
egui::epaint::RectShape::new(rect, style.rounding, fill, stroke, egui::StrokeKind::Inside),
);
egui::InnerResponse::new(ret, response)