Single-line TextInput text is drawn below center and clipped on ARM64 (New Architecture)
维护者通常 2 天内回复
评估
调研方向
The issue identifies WindowsTextInputComponentView::GetContentSize() as the source of the incorrect height, in the New Architecture Windows text input component. First inspect its TxGetNaturalSize extent and the linked pull request #16482. Done means ARM64 reports a sensible content size and single-line text and placeholders are vertically centered without clipping; verify the multiline onContentSizeChange result too.
由索引模型根据 Issue 内容生成。
描述
Problem Description
On the New Architecture (Fabric) on ARM64, a single-line TextInput that is taller than its text draws the text and placeholder starting at the vertical middle of the box, not centered in it. The top half of the input is empty, and in shorter inputs the bottom of the text is clipped.
This comes from #15754 ("Center single line textinputs"), which centers single-line text using the height returned by WindowsTextInputComponentView::GetContentSize(). On ARM64 that height is always about 0, so the centering offset becomes half the box height.
Root cause: GetContentSize() calls ITextServices::TxGetNaturalSize with this extent:
SIZE extentHimetric = {
static_cast<LONG>(availableWidth * scale * HIMETRIC_PER_INCH / dpi),
static_cast<LONG>(std::numeric_limits<LONG>::max() * HIMETRIC_PER_INCH / dpi)};
psizelExtent is the extent used for zooming the control, not a layout constraint. A very large positive height therefore scales the returned natural size down to about 0. I measured this in a 40px-tall input with fontSize: 18 at 96 DPI (ARM64):
extentHimetric.cy passed |
natural size returned (px) |
|---|---|
LONG_MAX scaled (saturates to 2147483647) |
(2, 0) |
1000000 |
(2, 0) |
frame height (1058) |
(3, 1) |
-1 |
(74, 24) (correct) |
With contentHeight = 0, calculateContentVerticalOffset() computes (40 - 0) / 2 = 20 px, so the 24px-tall text is drawn from y=20 to y=44 in a 40px box.
Steps To Reproduce
-
Create an app with the New Architecture
cpp-apptemplate:npx @react-native-community/[email protected] init RnwRepro --version 0.81.5 cd RnwRepro npm install [email protected] npx @react-native-community/cli init-windows --template cpp-app --overwrite -
Replace
App.tsxwith the code below. Each input is tinted so you can compare its box with where its text is drawn. -
On an ARM64 Windows device, run
npx react-native run-windows --arch ARM64. -
Compare the text in inputs 1–5 and 7 with their tinted boxes, and read the
contentSizeline under input 6.
import React, { useEffect, useState } from 'react';
import { PixelRatio, StyleSheet, Text, TextInput, View } from 'react-native';
// Each TextInput is tinted so a screenshot shows its box against where its text is drawn.
// Single-line text should be vertically centered in its box.
const App = () => {
const [measured, setMeasured] = useState('type in the multiline box');
// Case 7 gets its text from JS after mount, so the native side sees a text change.
const [late, setLate] = useState('');
useEffect(() => {
const timer = setTimeout(() => setLate('Set from JS Hg'), 2000);
return () => clearTimeout(timer);
}, []);
return (
<View style={styles.screen}>
<Text style={styles.info}>
PixelRatio {PixelRatio.get()} · fontScale {PixelRatio.getFontScale()}
</Text>
<Text style={styles.label}>1. Height 40, fontSize 18, placeholder</Text>
<TextInput style={[styles.input, styles.h40]} placeholder="Placeholder Hg" />
<Text style={styles.label}>2. Height 40, fontSize 18, value</Text>
<TextInput style={[styles.input, styles.h40]} defaultValue="Value Hg" />
<Text style={styles.label}>3. Height 80, fontSize 18, value</Text>
<TextInput style={[styles.input, styles.h80]} defaultValue="Value Hg" />
<Text style={styles.label}>4. Default height, fontSize 18, value</Text>
<TextInput style={styles.input} defaultValue="Value Hg" />
<Text style={styles.label}>5. Default height and font, value</Text>
<TextInput style={styles.tint} defaultValue="Value Hg" />
<Text style={styles.label}>
6. Multiline, fontSize 18: onContentSizeChange reports GetContentSize()
</Text>
<TextInput
multiline
style={[styles.input, styles.h80]}
defaultValue="Value Hg"
onContentSizeChange={(e) => {
const { width, height } = e.nativeEvent.contentSize;
const text = `contentSize ${width.toFixed(1)} x ${height.toFixed(1)}`;
console.log(text);
setMeasured(text);
}}
/>
<Text style={styles.info}>{measured}</Text>
<Text style={styles.label}>7. Height 40, fontSize 18, value set from JS after 2 s</Text>
<TextInput style={[styles.input, styles.h40]} value={late} placeholder="Waiting" onChangeText={setLate} />
</View>
);
};
const styles = StyleSheet.create({
screen: { flex: 1, padding: 16, backgroundColor: 'white' },
info: { fontSize: 14, marginVertical: 4 },
label: { fontSize: 12, marginTop: 12, marginBottom: 2, color: '#555' },
tint: { backgroundColor: 'rgba(255,0,0,0.25)' },
input: { backgroundColor: 'rgba(255,0,0,0.25)', fontSize: 18 },
h40: { height: 40 },
h80: { height: 80 },
});
export default App;
Expected Results
Text and placeholder in each single-line TextInput are vertically centered in the tinted box, as intended by #15754.
Actual Results
In each single-line input, the top of the text sits at the vertical middle of the box. In the 40px inputs (1, 2, 7) the descenders are cut off. In the default-height inputs (4, 5) only the top half of the text is visible. The multiline input (6) is drawn correctly because multiline skips the centering code, but its onContentSizeChange reports contentSize 1.0 x 2.0.
RNW 0.81.36, ARM64, 96 DPI:
CLI version
20.0.0
Environment
System:
OS: Windows 11 10.0.26100
CPU: (6) arm64 virt-10.0
Memory: 5.24 GB / 15.99 GB
Binaries:
Node:
version: 22.14.0
Yarn:
version: 1.22.22
npm:
version: 10.9.2
Watchman: Not Found
SDKs:
Windows SDK:
AllowDevelopmentWithoutDevLicense: Enabled
AllowAllTrustedApps: Enabled
Versions:
- 10.0.19041.0
- 10.0.22621.0
- 10.0.26100.0
IDEs:
Visual Studio:
- 18.10.12217.157 (Visual Studio Professional 2026)
npmPackages:
"@react-native-community/cli":
installed: 20.0.0
react:
installed: 19.1.4
react-native:
installed: 0.81.5
react-native-windows:
installed: 0.81.36
Community Modules
none
Target React Native Architecture
New Architecture (WinAppSDK) Only
Target Platform Version
10.0.26100
Visual Studio Version
Visual Studio 2026
Build Configuration
Debug
Snack, code example, screenshot, or link to a repository
repro code is is reproduction steps
Additional notes
- Reproduced on
react-native-windows0.81.36 (ARM64, 96 DPI). The same code is still onmain. x64 builds are not affected. - Why only ARM64:
LONG_MAX * 2540 / 96doesn't fit in aLONG, and the out-of-range float-to-LONGconversion differs by architecture. On x64 it gives-2147483648, and a negative extent means "unconstrained" to RichEdit, so centering works there; the existing e2e snapshots on x64 CI show a correctly centered caret. On ARM64 it saturates to2147483647, which is used as a zoom reference and shrinks the height to 0. - Multiline
onContentSizeChangealso usesGetContentSize(), so on ARM64 it reports1.0 x 2.0(input 6 in the screenshot).
- 主要语言
- C++
- 星标
- 17.4k
- 派生
- 1.2k
- 平均合并
- 3 天 10 分钟
- 30 天内合并 PR
- 14
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
microsoft/react-native-windows 的其他 Issue
-
Needs: Triage :mag:
难度 2/5 1-3 小时 新手友好度 82/100
microsoft/react-native-windows#16340 ·
维护者通常 2 天内回复
-
bug Needs: Triage :mag:
难度 2/5 1-3 小时 新手友好度 68/100
microsoft/react-native-windows#16321 · 1 条评论 ·
维护者通常 2 天内回复
-
bug Needs: Triage :mag:
难度 3/5 1-2 天 新手友好度 48/100
microsoft/react-native-windows#16479 ·
维护者通常 2 天内回复
-
Needs: Triage :mag:
难度 5/5 一周以上 新手友好度 30/100
microsoft/react-native-windows#16442 · 2 条评论 ·
维护者通常 2 天内回复
-
Fabric: activating the window doesn't announce the window or the focused control to a screen reader未关闭Needs: Triage :mag:
难度 4/5 3-5 天 新手友好度 48/100
microsoft/react-native-windows#16435 ·
维护者通常 2 天内回复
查看 microsoft/react-native-windows 的全部 Issue
相似的 Issue
-
bug
难度 2/5 1-3 小时 新手友好度 66/100
leanprover/lean4#15683 ·
维护者通常 1 天内回复
-
llvm.memcpy with destination align but no source align asserts "Missed Source alignment!"可能已有人在做 @pvelesko 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 72/100
KhronosGroup/SPIRV-LLVM-Translator#4093 ·
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 66/100
维护者通常 1 天内回复
-
SIMQ silently truncates multi-query batch search to the first query可能已有人在做 @LHT129 今天认领。 未关闭kind/bug module/index needs-triage
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
难度 2/5 半天 新手友好度 68/100
维护者通常 1 天内回复