Skip to content

Commit f99ed07

Browse files
committed
fix overlay hang default
1 parent 17cf187 commit f99ed07

5 files changed

Lines changed: 40 additions & 60 deletions

File tree

app/src/ai/agent_management/notifications/item_rendering.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -399,12 +399,6 @@ fn render_message_text(message: &str, expanded: bool, appearance: &Appearance) -
399399

400400
/// Total size of the agent avatar component rendered alongside each notification.
401401
const NOTIFICATION_AVATAR_SIZE: f32 = 32.;
402-
/// Where the status / cloud overlay's BR sits relative to the brand circle's BR edge,
403-
/// as a signed fraction of `NOTIFICATION_AVATAR_SIZE`.
404-
/// Negative values push the overlay past the circle's BR (toward the bounding box's
405-
/// BR); this surface sits slightly past the circle's edge so the badge appears to
406-
/// hang off the bottom-right corner.
407-
const NOTIFICATION_OVERLAY_OFFSET_FROM_CIRCLE_EDGE: f32 = -0.19;
408402

409403
fn render_agent_avatar(
410404
agent: NotificationSourceAgent,
@@ -426,7 +420,7 @@ fn render_agent_avatar(
426420
render_icon_with_status(
427421
variant,
428422
NOTIFICATION_AVATAR_SIZE,
429-
NOTIFICATION_OVERLAY_OFFSET_FROM_CIRCLE_EDGE,
423+
0.,
430424
theme,
431425
theme.surface_2(),
432426
)

app/src/terminal/view/pane_impl.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,6 @@ use warpui::{AppContext, Element, ModelHandle, SingletonEntity, TypedActionView,
5353
/// Sized so the component fits comfortably within `PANE_HEADER_HEIGHT` (34px) with a
5454
/// few pixels of vertical buffer.
5555
const PANE_HEADER_AGENT_SIZE: f32 = 26.;
56-
/// Where the status / cloud overlay's BR sits relative to the brand circle's BR edge,
57-
/// as a signed fraction of `PANE_HEADER_AGENT_SIZE`.
58-
/// Negative values push the overlay past the circle's BR (toward the bounding box's
59-
/// BR); this surface sits slightly past the circle's edge so the badge appears to
60-
/// hang off the bottom-right corner.
61-
const PANE_HEADER_OVERLAY_OFFSET_FROM_CIRCLE_EDGE: f32 = -0.19;
6256

6357
impl TerminalView {
6458
/// Returns a reference to the focus handle if one has been set.
@@ -305,7 +299,7 @@ impl TerminalView {
305299
render_icon_with_status(
306300
variant,
307301
PANE_HEADER_AGENT_SIZE,
308-
PANE_HEADER_OVERLAY_OFFSET_FROM_CIRCLE_EDGE,
302+
0.,
309303
theme,
310304
theme.background(),
311305
)

app/src/ui_components/icon_with_status.rs

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,28 @@ fn status_in_cloud_size(total: f32) -> f32 {
6666
total * STATUS_IN_CLOUD_RATIO
6767
}
6868

69+
/// Default overhang of the overlay's BR past the circle's BR edge (toward the box's
70+
/// BR), as a fraction of `total_size`. Baked into `corner_overlay_offset` so most
71+
/// surfaces can just pass `0.0` for their `overlay_extra_overhang_ratio`.
72+
const DEFAULT_OVERLAY_OVERHANG_PAST_CIRCLE_EDGE: f32 = 0.19;
73+
6974
/// Returns the pixel offset applied to the overlay's `BottomRight → BottomRight`
7075
/// anchor.
7176
/// The offset is measured from the bounding box's BR corner, so the returned value is
7277
/// negative whenever the overlay sits up-and-left of the box's BR (which is the only
7378
/// case we render).
7479
///
75-
/// `overlay_offset_from_circle_edge_ratio` is a signed fraction of `total` that
76-
/// positions the overlay's BR relative to the **circle's** BR corner:
77-
/// * `0.0` — overlay BR sits exactly on the circle's BR edge.
78-
/// * Positive — overlay BR is pulled further into the circle (toward the center).
79-
/// * Negative — overlay BR sits past the circle's BR edge, toward the box's BR.
80-
/// `-(1.0 - CIRCLE_RATIO)` places it exactly on the box's BR corner, which is the
81-
/// Figma-natural position where the badge appears to hang off the circle's BR.
82-
fn corner_overlay_offset(total: f32, overlay_offset_from_circle_edge_ratio: f32) -> f32 {
83-
-(1.0 - CIRCLE_RATIO) * total - overlay_offset_from_circle_edge_ratio * total
80+
/// `overlay_extra_overhang_ratio` is a signed fraction of `total` added to
81+
/// `DEFAULT_OVERLAY_OVERHANG_PAST_CIRCLE_EDGE`:
82+
/// * `0.0` — overlay BR sits `DEFAULT_OVERLAY_OVERHANG_PAST_CIRCLE_EDGE * total` past
83+
/// the circle's BR (the position most surfaces want).
84+
/// * Positive — overlay BR pushed further toward the box's BR. A value of
85+
/// `1 - CIRCLE_RATIO - DEFAULT_OVERLAY_OVERHANG_PAST_CIRCLE_EDGE` (= 0.05) lands
86+
/// exactly on the box's BR — the Figma-natural overhang.
87+
/// * Negative — overlay BR pulled inward toward the circle's center.
88+
fn corner_overlay_offset(total: f32, overlay_extra_overhang_ratio: f32) -> f32 {
89+
let total_overhang = DEFAULT_OVERLAY_OVERHANG_PAST_CIRCLE_EDGE + overlay_extra_overhang_ratio;
90+
-((1.0 - CIRCLE_RATIO) - total_overhang) * total
8491
}
8592

8693
/// What to render inside the circle.
@@ -109,18 +116,17 @@ pub(crate) enum IconWithStatusVariant {
109116
/// sub-components (brand circle, status badge, cloud lobe) are derived proportionally,
110117
/// so callers only need to pick the size they want.
111118
///
112-
/// `overlay_offset_from_circle_edge_ratio` is a signed fraction of `total_size` that
113-
/// positions the badge / cloud overlay's BR relative to the **circle's** BR corner:
114-
/// `0.0` anchors the overlay BR right on the circle's BR edge, positive values pull it
115-
/// further toward the circle's center, and negative values push it past the circle's
116-
/// BR toward the bounding box's BR (where the Figma-natural overhang lives).
119+
/// `overlay_extra_overhang_ratio` is a signed fraction of `total_size` added to the
120+
/// default overlay overhang past the circle's BR edge. Most surfaces pass `0.0` to
121+
/// get the default position; positive values push the overlay further toward the box's
122+
/// BR (more overhang) and negative values pull it inward toward the circle's center.
117123
///
118124
/// When `is_ambient` is set on an agent variant, the status badge is replaced by a
119125
/// white cloud containing the status icon.
120126
pub(crate) fn render_icon_with_status(
121127
variant: IconWithStatusVariant,
122128
total_size: f32,
123-
overlay_offset_from_circle_edge_ratio: f32,
129+
overlay_extra_overhang_ratio: f32,
124130
theme: &WarpTheme,
125131
badge_ring_background: WarpThemeFill,
126132
) -> Box<dyn Element> {
@@ -163,7 +169,7 @@ pub(crate) fn render_icon_with_status(
163169
status.as_ref(),
164170
is_ambient,
165171
total_size,
166-
overlay_offset_from_circle_edge_ratio,
172+
overlay_extra_overhang_ratio,
167173
theme,
168174
badge_ring_background,
169175
)
@@ -190,7 +196,7 @@ pub(crate) fn render_icon_with_status(
190196
status.as_ref(),
191197
is_ambient,
192198
total_size,
193-
overlay_offset_from_circle_edge_ratio,
199+
overlay_extra_overhang_ratio,
194200
theme,
195201
badge_ring_background,
196202
)
@@ -228,7 +234,7 @@ fn attach_status_overlay(
228234
status: Option<&ConversationStatus>,
229235
is_ambient: bool,
230236
total_size: f32,
231-
overlay_offset_from_circle_edge_ratio: f32,
237+
overlay_extra_overhang_ratio: f32,
232238
theme: &WarpTheme,
233239
badge_ring_background: WarpThemeFill,
234240
) -> Box<dyn Element> {
@@ -237,15 +243,15 @@ fn attach_status_overlay(
237243
circle,
238244
status,
239245
total_size,
240-
overlay_offset_from_circle_edge_ratio,
246+
overlay_extra_overhang_ratio,
241247
theme,
242248
)
243249
} else {
244250
render_with_optional_status_badge(
245251
circle,
246252
status,
247253
total_size,
248-
overlay_offset_from_circle_edge_ratio,
254+
overlay_extra_overhang_ratio,
249255
theme,
250256
badge_ring_background,
251257
)
@@ -258,7 +264,7 @@ fn render_with_cloud_status_badge(
258264
circle: Box<dyn Element>,
259265
status: Option<&ConversationStatus>,
260266
total_size: f32,
261-
overlay_offset_from_circle_edge_ratio: f32,
267+
overlay_extra_overhang_ratio: f32,
262268
theme: &WarpTheme,
263269
) -> Box<dyn Element> {
264270
let cloud_diameter = cloud_icon_size(total_size);
@@ -299,7 +305,7 @@ fn render_with_cloud_status_badge(
299305
None => cloud,
300306
};
301307

302-
let cloud_offset = corner_overlay_offset(total_size, overlay_offset_from_circle_edge_ratio);
308+
let cloud_offset = corner_overlay_offset(total_size, overlay_extra_overhang_ratio);
303309
let mut stack = Stack::new().with_child(
304310
ConstrainedBox::new(circle)
305311
.with_width(total_size)
@@ -326,7 +332,7 @@ fn render_with_optional_status_badge(
326332
circle: Box<dyn Element>,
327333
status: Option<&ConversationStatus>,
328334
total_size: f32,
329-
overlay_offset_from_circle_edge_ratio: f32,
335+
overlay_extra_overhang_ratio: f32,
330336
theme: &WarpTheme,
331337
badge_ring_background: WarpThemeFill,
332338
) -> Box<dyn Element> {
@@ -351,8 +357,7 @@ fn render_with_optional_status_badge(
351357
.with_corner_radius(CornerRadius::with_all(Radius::Percentage(50.)))
352358
.finish();
353359

354-
let badge_corner_offset =
355-
corner_overlay_offset(total_size, overlay_offset_from_circle_edge_ratio);
360+
let badge_corner_offset = corner_overlay_offset(total_size, overlay_extra_overhang_ratio);
356361
let mut stack = Stack::new().with_child(
357362
ConstrainedBox::new(circle)
358363
.with_width(total_size)

app/src/workspace/view/conversation_list/item.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,11 @@ const DIALOG_OFFSET_PIXELS: f32 = -16.;
4141
/// Total size of the agent icon-with-status component rendered in each conversation list
4242
/// row.
4343
const LIST_ITEM_AGENT_SIZE: f32 = 22.;
44-
/// Where the status overlay's BR sits relative to the brand circle's BR edge, as a
45-
/// signed fraction of `LIST_ITEM_AGENT_SIZE`.
46-
/// `-(1 - CIRCLE_RATIO) ≈ -0.24` puts the overlay's BR exactly on the bounding box's
47-
/// BR corner, so the badge appears to hang off the circle's bottom-right (matches the
48-
/// Figma natural overlap).
49-
const LIST_ITEM_OVERLAY_OFFSET_FROM_CIRCLE_EDGE: f32 = -0.24;
44+
/// Extra overhang past the default overlay position, as a fraction of
45+
/// `LIST_ITEM_AGENT_SIZE`. Pushes the badge all the way to the bounding box's BR
46+
/// corner, matching the Figma natural overlap; the conversation list reads better
47+
/// with the status sitting slightly further out than the other surfaces.
48+
const LIST_ITEM_OVERLAY_EXTRA_OVERHANG: f32 = 0.05;
5049

5150
/// Generate a position ID for a conversation list item
5251
fn conversation_item_position_id(id: &ConversationOrTaskId) -> String {
@@ -216,7 +215,7 @@ pub fn render_item(props: ItemProps<'_>, app: &AppContext) -> Box<dyn Element> {
216215
Some(variant) => render_icon_with_status(
217216
variant,
218217
LIST_ITEM_AGENT_SIZE,
219-
LIST_ITEM_OVERLAY_OFFSET_FROM_CIRCLE_EDGE,
218+
LIST_ITEM_OVERLAY_EXTRA_OVERHANG,
220219
theme,
221220
theme.background(),
222221
),

app/src/workspace/view/vertical_tabs.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,6 @@ pub(super) const VERTICAL_TABS_DETAIL_SIDECAR_POSITION_ID: &str = "vertical_tabs
111111
/// Total size of the icon-with-status component rendered for each vertical-tabs row.
112112
/// Sub-components (circle, badge, cloud) are derived inside `render_icon_with_status`.
113113
const VERTICAL_TABS_ICON_SIZE: f32 = 24.;
114-
/// Where the status / cloud overlay's BR sits relative to the brand circle's BR edge,
115-
/// as a signed fraction of `VERTICAL_TABS_ICON_SIZE`.
116-
/// Negative values push the overlay past the circle's BR (toward the bounding box's
117-
/// BR); this surface sits slightly past the circle's edge so the badge appears to
118-
/// hang off the bottom-right corner.
119-
const VERTICAL_TABS_OVERLAY_OFFSET_FROM_CIRCLE_EDGE: f32 = -0.19;
120114

121115
fn vtab_pane_row_position_id(pane_group_id: EntityId, pane_id: PaneId) -> String {
122116
format!("vertical_tabs:pane_row:{pane_group_id:?}:{pane_id}")
@@ -253,7 +247,7 @@ fn render_pane_icon_with_status(
253247
render_icon_with_status(
254248
variant,
255249
VERTICAL_TABS_ICON_SIZE,
256-
VERTICAL_TABS_OVERLAY_OFFSET_FROM_CIRCLE_EDGE,
250+
0.,
257251
theme,
258252
theme.background(),
259253
)
@@ -3585,13 +3579,7 @@ fn render_summary_pane_kind_icon_circle(
35853579
// mode). Non-ambient agent kinds and all other pane kinds fall through to the inline
35863580
// circle rendering below.
35873581
if let Some(variant) = ambient_agent_variant(&kind) {
3588-
return render_icon_with_status(
3589-
variant,
3590-
total_size,
3591-
VERTICAL_TABS_OVERLAY_OFFSET_FROM_CIRCLE_EDGE,
3592-
theme,
3593-
theme.background(),
3594-
);
3582+
return render_icon_with_status(variant, total_size, 0., theme, theme.background());
35953583
}
35963584
let icon_size = total_size * SUMMARY_INLINE_ICON_RATIO;
35973585
let padding = total_size * SUMMARY_INLINE_PADDING_RATIO;

0 commit comments

Comments
 (0)