diff --git a/openless-all/app/src/components/Capsule.tsx b/openless-all/app/src/components/Capsule.tsx index 4c669598..2c8cb987 100644 --- a/openless-all/app/src/components/Capsule.tsx +++ b/openless-all/app/src/components/Capsule.tsx @@ -318,7 +318,9 @@ export function Capsule() { position: 'relative', display: 'flex', alignItems: 'center', - justifyContent: os === 'win' ? 'flex-end' : 'center', + justifyContent: 'center', + paddingLeft: hostMetrics.horizontalInset, + paddingRight: hostMetrics.horizontalInset, paddingTop: os === 'win' ? Math.max(0, hostMetrics.height - metrics.height - hostMetrics.bottomInset) : 0, @@ -336,7 +338,7 @@ export function Capsule() { position: 'absolute', left: '50%', // macOS / Linux:胶囊窗口 220×110、pill 居中,badge 锚到 pill 中线上方 21+8。 - // Windows:pill 不居中(带 12pt 阴影 inset),用 hostMetrics 量到底部 inset + pill 高 + gap。 + // Windows:host 比 pill 多出左右 12px / 底部 12px 的阴影空间,pill 仍保持居中。 bottom: os === 'win' ? `${hostMetrics.bottomInset + metrics.height + hostMetrics.badgeGap}px` : 'calc(50% + 21px + 8px)', diff --git a/openless-all/app/src/lib/capsuleLayout.test.ts b/openless-all/app/src/lib/capsuleLayout.test.ts index 9fe675cb..2466301e 100644 --- a/openless-all/app/src/lib/capsuleLayout.test.ts +++ b/openless-all/app/src/lib/capsuleLayout.test.ts @@ -1,4 +1,5 @@ import { + getCapsuleHostMetrics, getCapsuleMessageLayout, getCapsulePillMetrics, } from './capsuleLayout.ts'; @@ -14,6 +15,21 @@ 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'); +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.width, + winMetrics.width + winHost.horizontalInset * 2, + 'windows capsule host width derives from pill width plus symmetric 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'); + const macMetrics = getCapsulePillMetrics('mac'); assertEqual(macMetrics.width, 176, 'mac capsule keeps existing pill width'); assertEqual(macMetrics.height, 42, 'mac capsule keeps existing pill height'); diff --git a/openless-all/app/src/lib/capsuleLayout.ts b/openless-all/app/src/lib/capsuleLayout.ts index 7e8c8db7..28bb4344 100644 --- a/openless-all/app/src/lib/capsuleLayout.ts +++ b/openless-all/app/src/lib/capsuleLayout.ts @@ -11,6 +11,7 @@ export interface CapsulePillMetrics { export interface CapsuleHostMetrics { width: number; height: number; + horizontalInset: number; bottomInset: number; badgeGap: number; } @@ -35,9 +36,17 @@ export function getCapsuleHostMetrics( translationActive: boolean, ): CapsuleHostMetrics { if (os === 'win') { - return { width: 220, height: translationActive ? 118 : 84, bottomInset: 12, badgeGap: 8 }; + const horizontalInset = 12; + const pill = getCapsulePillMetrics(os); + return { + width: pill.width + horizontalInset * 2, + height: translationActive ? 118 : 84, + horizontalInset, + bottomInset: 12, + badgeGap: 8, + }; } - return { width: 176, height: 42, bottomInset: 0, badgeGap: 8 }; + return { width: 176, height: 42, horizontalInset: 0, bottomInset: 0, badgeGap: 8 }; } export function getCapsuleMessageLayout(