Fix Windows capsule box sizing

This commit is contained in:
weikeyi committed 2026-05-05 16:48:36 +08:00
1 parent 3d64dc2349
commit 9660db6336
4 files changed
+30 -4

No files matched your search

+5 -1
View File
@@ -752,8 +752,12 @@ struct CapsuleWindowBounds {
fn capsule_window_bounds(translation_active: bool) -> CapsuleWindowBounds {
#[cfg(target_os = "windows")]
{
const WINDOWS_CAPSULE_PILL_WIDTH: f64 = 196.0;
const WINDOWS_CAPSULE_SIDE_INSET: f64 = 12.0;
CapsuleWindowBounds {
width: 220.0,
// Keep the existing Windows hitbox width, but express it as
// pill width (196) + symmetric 12px side insets for shadow room.
width: WINDOWS_CAPSULE_PILL_WIDTH + WINDOWS_CAPSULE_SIDE_INSET * 2.0,
height: if translation_active { 118.0 } else { 84.0 },
bottom_inset: 12.0,
}
@@ -236,6 +236,7 @@ function Pill({ os, state, level, insertedChars, message, onCancel, onConfirm }:
padding: '0 8px',
width: metrics.width,
height: metrics.height,
boxSizing: metrics.boxSizing,
borderRadius: 999,
background: 'rgba(255, 255, 255, 0.62)',
backdropFilter: 'blur(28px) saturate(180%)',
@@ -321,6 +322,7 @@ export function Capsule() {
justifyContent: 'center',
paddingLeft: hostMetrics.horizontalInset,
paddingRight: hostMetrics.horizontalInset,
boxSizing: hostMetrics.boxSizing,
paddingTop: os === 'win'
? Math.max(0, hostMetrics.height - metrics.height - hostMetrics.bottomInset)
: 0,
@@ -14,26 +14,35 @@ const winMetrics = getCapsulePillMetrics('win');
assertEqual(winMetrics.width, 196, 'windows capsule widens pill');
assertEqual(winMetrics.height, 52, 'windows capsule increases pill height');
assertEqual(winMetrics.textWidth, 118, 'windows capsule widens text slot');
assertEqual(winMetrics.boxSizing, 'border-box', 'windows capsule pill width is an outer border-box metric');
const winHost = getCapsuleHostMetrics('win', false);
assertEqual(winHost.width, 220, 'windows capsule host keeps the current outer hitbox width');
assertEqual(winHost.height, 84, 'windows capsule host keeps regular height');
assertEqual(winHost.horizontalInset, 12, 'windows capsule host keeps symmetric shadow insets');
assertEqual(winHost.boxSizing, 'border-box', 'windows capsule host inset is reserved inside the native width');
assertEqual(
winHost.width,
winMetrics.width + winHost.horizontalInset * 2,
'windows capsule host width derives from pill width plus symmetric side insets',
);
assertEqual(
winHost.width - winHost.horizontalInset * 2,
winMetrics.width,
'windows capsule host keeps the visible pill width after reserving side insets',
);
const winHostWithTranslation = getCapsuleHostMetrics('win', true);
assertEqual(winHostWithTranslation.width, 220, 'windows translation capsule keeps the same outer width');
assertEqual(winHostWithTranslation.height, 118, 'windows translation capsule grows vertically only');
assertEqual(winHostWithTranslation.horizontalInset, 12, 'windows translation capsule keeps symmetric side insets');
assertEqual(winHostWithTranslation.boxSizing, 'border-box', 'windows translation host keeps the same inset-reserving box model');
const macMetrics = getCapsulePillMetrics('mac');
assertEqual(macMetrics.width, 176, 'mac capsule keeps existing pill width');
assertEqual(macMetrics.height, 42, 'mac capsule keeps existing pill height');
assertEqual(macMetrics.textWidth, 84, 'mac capsule keeps existing text slot');
assertEqual(macMetrics.boxSizing, 'content-box', 'mac capsule keeps the existing content-box pill model');
const winErrorLayout = getCapsuleMessageLayout('win', 'error');
assertEqual(winErrorLayout.lineClamp, 2, 'windows error message allows two lines');
+14 -3
View File
@@ -6,6 +6,7 @@ export interface CapsulePillMetrics {
width: number;
height: number;
textWidth: number;
boxSizing: 'border-box' | 'content-box';
}
export interface CapsuleHostMetrics {
@@ -14,6 +15,7 @@ export interface CapsuleHostMetrics {
horizontalInset: number;
bottomInset: number;
badgeGap: number;
boxSizing: 'border-box' | 'content-box';
}
export interface CapsuleMessageLayout {
@@ -23,10 +25,11 @@ export interface CapsuleMessageLayout {
export function getCapsulePillMetrics(os: OS): CapsulePillMetrics {
if (os === 'win') {
return { width: 196, height: 52, textWidth: 118 };
// Windows metrics describe the visible outer footprint of the pill.
return { width: 196, height: 52, textWidth: 118, boxSizing: 'border-box' };
}
return { width: 176, height: 42, textWidth: 84 };
return { width: 176, height: 42, textWidth: 84, boxSizing: 'content-box' };
}
// macOS 走 1.2.11 calc 布局,不依赖 host metrics;Windows 端要更大的 host
@@ -44,9 +47,17 @@ export function getCapsuleHostMetrics(
horizontalInset,
bottomInset: 12,
badgeGap: 8,
boxSizing: 'border-box',
};
}
return { width: 176, height: 42, horizontalInset: 0, bottomInset: 0, badgeGap: 8 };
return {
width: 176,
height: 42,
horizontalInset: 0,
bottomInset: 0,
badgeGap: 8,
boxSizing: 'content-box',
};
}
export function getCapsuleMessageLayout(