Skip to content

[Fabric] Fix onChangeText firing twice when first typing in TextInput #14786

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 20 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
789a853
Initial plan for issue
Copilot Jun 16, 2025
d3d95af
Initial analysis: Identify double onChange event in Fabric TextInput
Copilot Jun 16, 2025
1ec1f5a
Fix double onChange event in Fabric TextInput by checking m_comingFro…
Copilot Jun 16, 2025
7e50ec1
Change files
Copilot Jun 16, 2025
fecc3ef
Remove unnecessary codegen file changes unrelated to TextInput fix
Copilot Jun 16, 2025
d48bdb9
Improve TextInput onChange fix with text-based deduplication
Copilot Jun 17, 2025
1b22de5
Revert unrelated codegen changes from TextInput fix
Copilot Jun 17, 2025
f00f563
Replace expensive string comparison with code flow check using m_comi…
Copilot Jun 18, 2025
cecdb31
Improve TextInput onChange fix using event count comparison instead o…
Copilot Jun 18, 2025
0dec8fa
Remove unrelated codegen changes from TextInput onChange fix
Copilot Jun 18, 2025
5673dc3
Fix event count initialization issue in TextInput onChange
Copilot Jun 18, 2025
febb163
Fix TextInput onChange using RichEdit modify flag instead of state co…
Copilot Jun 26, 2025
508ae41
Revert to simple RichEdit modify flag approach as requested
Copilot Jun 26, 2025
2436584
Merge branch 'main' into copilot/fix-12780
HariniMalothu17 Jun 26, 2025
cb21247
Fix TextInput onChange double event issue using consistent m_comingFr…
Copilot Jun 26, 2025
2938058
Remove unnecessary codegen file changes, keep only essential TextInpu…
Copilot Jun 26, 2025
21e0c91
Fix TextInput onChange double firing using RichEdit modify flag approach
Copilot Jun 26, 2025
2c5e5d8
Simplify TextInput onChange fix to minimal approach, remove unnecessa…
Copilot Jun 26, 2025
6eb444c
Fresh fix for TextInput onChange double firing using improved RichEdi…
Copilot Jun 30, 2025
3cb971b
Restore GetContentSize and autoFocus functionality with minimal onCha…
Copilot Jun 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Fix double onChange event in Fabric TextInput by checking m_comingFromState",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
Original file line number Diff line number Diff line change
Expand Up @@ -1283,7 +1283,7 @@ void WindowsTextInputComponentView::OnTextUpdated() noexcept {

m_state->updateState(std::move(data));

if (m_eventEmitter && !m_comingFromJS) {
if (m_eventEmitter && !m_comingFromJS && !m_comingFromState) {
// call onChange event
auto emitter = std::static_pointer_cast<const facebook::react::WindowsTextInputEventEmitter>(m_eventEmitter);
facebook::react::WindowsTextInputEventEmitter::OnChange onChangeArgs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ struct WindowsTextInputComponentView
void UpdateText(const std::string &str) noexcept;
void OnTextUpdated() noexcept;
void OnSelectionChanged(LONG start, LONG end) noexcept;
std::pair<float, float> GetContentSize() const noexcept;
std::string GetTextFromRichEdit() const noexcept;
void updateCursorColor(
const facebook::react::SharedColor &cursorColor,
Expand Down
130 changes: 65 additions & 65 deletions vnext/codegen/NativeReactNativeFeatureFlagsSpec.g.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,35 @@ struct ReactNativeFeatureFlagsSpec : winrt::Microsoft::ReactNative::TurboModuleS
SyncMethod<bool() noexcept>{0, L"commonTestFlag"},
SyncMethod<bool() noexcept>{1, L"commonTestFlagWithoutNativeImplementation"},
SyncMethod<bool() noexcept>{2, L"animatedShouldSignalBatch"},
SyncMethod<bool() noexcept>{3, L"cxxNativeAnimatedEnabled"},
SyncMethod<bool() noexcept>{4, L"disableMountItemReorderingAndroid"},
SyncMethod<bool() noexcept>{5, L"enableAccumulatedUpdatesInRawPropsAndroid"},
SyncMethod<bool() noexcept>{6, L"enableBridgelessArchitecture"},
SyncMethod<bool() noexcept>{7, L"enableCppPropsIteratorSetter"},
SyncMethod<bool() noexcept>{8, L"enableEagerRootViewAttachment"},
SyncMethod<bool() noexcept>{9, L"enableFabricLogs"},
SyncMethod<bool() noexcept>{10, L"enableFabricRenderer"},
SyncMethod<bool() noexcept>{11, L"enableIOSViewClipToPaddingBox"},
SyncMethod<bool() noexcept>{12, L"enableImagePrefetchingAndroid"},
SyncMethod<bool() noexcept>{13, L"enableJSRuntimeGCOnMemoryPressureOnIOS"},
SyncMethod<bool() noexcept>{14, L"enableLayoutAnimationsOnAndroid"},
SyncMethod<bool() noexcept>{15, L"enableLayoutAnimationsOnIOS"},
SyncMethod<bool() noexcept>{16, L"enableLongTaskAPI"},
SyncMethod<bool() noexcept>{17, L"enableMainQueueModulesOnIOS"},
SyncMethod<bool() noexcept>{18, L"enableNativeCSSParsing"},
SyncMethod<bool() noexcept>{19, L"enableNewBackgroundAndBorderDrawables"},
SyncMethod<bool() noexcept>{20, L"enablePropsUpdateReconciliationAndroid"},
SyncMethod<bool() noexcept>{21, L"enableReportEventPaintTime"},
SyncMethod<bool() noexcept>{22, L"enableSynchronousStateUpdates"},
SyncMethod<bool() noexcept>{23, L"enableUIConsistency"},
SyncMethod<bool() noexcept>{24, L"enableViewCulling"},
SyncMethod<bool() noexcept>{25, L"enableViewRecycling"},
SyncMethod<bool() noexcept>{26, L"enableViewRecyclingForText"},
SyncMethod<bool() noexcept>{27, L"enableViewRecyclingForView"},
SyncMethod<bool() noexcept>{28, L"fixMappingOfEventPrioritiesBetweenFabricAndReact"},
SyncMethod<bool() noexcept>{29, L"fixMountingCoordinatorReportedPendingTransactionsOnAndroid"},
SyncMethod<bool() noexcept>{30, L"fuseboxEnabledRelease"},
SyncMethod<bool() noexcept>{31, L"fuseboxNetworkInspectionEnabled"},
SyncMethod<bool() noexcept>{3, L"disableMountItemReorderingAndroid"},
SyncMethod<bool() noexcept>{4, L"enableAccumulatedUpdatesInRawPropsAndroid"},
SyncMethod<bool() noexcept>{5, L"enableBridgelessArchitecture"},
SyncMethod<bool() noexcept>{6, L"enableCppPropsIteratorSetter"},
SyncMethod<bool() noexcept>{7, L"enableEagerRootViewAttachment"},
SyncMethod<bool() noexcept>{8, L"enableFabricLogs"},
SyncMethod<bool() noexcept>{9, L"enableFabricRenderer"},
SyncMethod<bool() noexcept>{10, L"enableIOSViewClipToPaddingBox"},
SyncMethod<bool() noexcept>{11, L"enableImagePrefetchingAndroid"},
SyncMethod<bool() noexcept>{12, L"enableJSRuntimeGCOnMemoryPressureOnIOS"},
SyncMethod<bool() noexcept>{13, L"enableLayoutAnimationsOnAndroid"},
SyncMethod<bool() noexcept>{14, L"enableLayoutAnimationsOnIOS"},
SyncMethod<bool() noexcept>{15, L"enableLongTaskAPI"},
SyncMethod<bool() noexcept>{16, L"enableNativeCSSParsing"},
SyncMethod<bool() noexcept>{17, L"enableNewBackgroundAndBorderDrawables"},
SyncMethod<bool() noexcept>{18, L"enablePropsUpdateReconciliationAndroid"},
SyncMethod<bool() noexcept>{19, L"enableReportEventPaintTime"},
SyncMethod<bool() noexcept>{20, L"enableSynchronousStateUpdates"},
SyncMethod<bool() noexcept>{21, L"enableUIConsistency"},
SyncMethod<bool() noexcept>{22, L"enableViewCulling"},
SyncMethod<bool() noexcept>{23, L"enableViewRecycling"},
SyncMethod<bool() noexcept>{24, L"enableViewRecyclingForText"},
SyncMethod<bool() noexcept>{25, L"enableViewRecyclingForView"},
SyncMethod<bool() noexcept>{26, L"fixDifferentiatorEmittingUpdatesWithWrongParentTag"},
SyncMethod<bool() noexcept>{27, L"fixMappingOfEventPrioritiesBetweenFabricAndReact"},
SyncMethod<bool() noexcept>{28, L"fixMountingCoordinatorReportedPendingTransactionsOnAndroid"},
SyncMethod<bool() noexcept>{29, L"fuseboxEnabledRelease"},
SyncMethod<bool() noexcept>{30, L"fuseboxNetworkInspectionEnabled"},
SyncMethod<bool() noexcept>{31, L"lazyAnimationCallbacks"},
SyncMethod<bool() noexcept>{32, L"removeTurboModuleManagerDelegateMutex"},
SyncMethod<bool() noexcept>{33, L"throwExceptionInsteadOfDeadlockOnTurboModuleSetupDuringSyncRenderIOS"},
SyncMethod<bool() noexcept>{34, L"traceTurboModulePromiseRejectionsOnAndroid"},
Expand Down Expand Up @@ -83,149 +83,149 @@ struct ReactNativeFeatureFlagsSpec : winrt::Microsoft::ReactNative::TurboModuleS
" REACT_SYNC_METHOD(animatedShouldSignalBatch) static bool animatedShouldSignalBatch() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
3,
"cxxNativeAnimatedEnabled",
" REACT_SYNC_METHOD(cxxNativeAnimatedEnabled) bool cxxNativeAnimatedEnabled() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(cxxNativeAnimatedEnabled) static bool cxxNativeAnimatedEnabled() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
4,
"disableMountItemReorderingAndroid",
" REACT_SYNC_METHOD(disableMountItemReorderingAndroid) bool disableMountItemReorderingAndroid() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(disableMountItemReorderingAndroid) static bool disableMountItemReorderingAndroid() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
5,
4,
"enableAccumulatedUpdatesInRawPropsAndroid",
" REACT_SYNC_METHOD(enableAccumulatedUpdatesInRawPropsAndroid) bool enableAccumulatedUpdatesInRawPropsAndroid() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableAccumulatedUpdatesInRawPropsAndroid) static bool enableAccumulatedUpdatesInRawPropsAndroid() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
6,
5,
"enableBridgelessArchitecture",
" REACT_SYNC_METHOD(enableBridgelessArchitecture) bool enableBridgelessArchitecture() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableBridgelessArchitecture) static bool enableBridgelessArchitecture() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
7,
6,
"enableCppPropsIteratorSetter",
" REACT_SYNC_METHOD(enableCppPropsIteratorSetter) bool enableCppPropsIteratorSetter() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableCppPropsIteratorSetter) static bool enableCppPropsIteratorSetter() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
8,
7,
"enableEagerRootViewAttachment",
" REACT_SYNC_METHOD(enableEagerRootViewAttachment) bool enableEagerRootViewAttachment() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableEagerRootViewAttachment) static bool enableEagerRootViewAttachment() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
9,
8,
"enableFabricLogs",
" REACT_SYNC_METHOD(enableFabricLogs) bool enableFabricLogs() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableFabricLogs) static bool enableFabricLogs() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
10,
9,
"enableFabricRenderer",
" REACT_SYNC_METHOD(enableFabricRenderer) bool enableFabricRenderer() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableFabricRenderer) static bool enableFabricRenderer() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
11,
10,
"enableIOSViewClipToPaddingBox",
" REACT_SYNC_METHOD(enableIOSViewClipToPaddingBox) bool enableIOSViewClipToPaddingBox() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableIOSViewClipToPaddingBox) static bool enableIOSViewClipToPaddingBox() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
12,
11,
"enableImagePrefetchingAndroid",
" REACT_SYNC_METHOD(enableImagePrefetchingAndroid) bool enableImagePrefetchingAndroid() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableImagePrefetchingAndroid) static bool enableImagePrefetchingAndroid() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
13,
12,
"enableJSRuntimeGCOnMemoryPressureOnIOS",
" REACT_SYNC_METHOD(enableJSRuntimeGCOnMemoryPressureOnIOS) bool enableJSRuntimeGCOnMemoryPressureOnIOS() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableJSRuntimeGCOnMemoryPressureOnIOS) static bool enableJSRuntimeGCOnMemoryPressureOnIOS() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
14,
13,
"enableLayoutAnimationsOnAndroid",
" REACT_SYNC_METHOD(enableLayoutAnimationsOnAndroid) bool enableLayoutAnimationsOnAndroid() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableLayoutAnimationsOnAndroid) static bool enableLayoutAnimationsOnAndroid() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
15,
14,
"enableLayoutAnimationsOnIOS",
" REACT_SYNC_METHOD(enableLayoutAnimationsOnIOS) bool enableLayoutAnimationsOnIOS() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableLayoutAnimationsOnIOS) static bool enableLayoutAnimationsOnIOS() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
16,
15,
"enableLongTaskAPI",
" REACT_SYNC_METHOD(enableLongTaskAPI) bool enableLongTaskAPI() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableLongTaskAPI) static bool enableLongTaskAPI() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
17,
"enableMainQueueModulesOnIOS",
" REACT_SYNC_METHOD(enableMainQueueModulesOnIOS) bool enableMainQueueModulesOnIOS() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableMainQueueModulesOnIOS) static bool enableMainQueueModulesOnIOS() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
18,
16,
"enableNativeCSSParsing",
" REACT_SYNC_METHOD(enableNativeCSSParsing) bool enableNativeCSSParsing() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableNativeCSSParsing) static bool enableNativeCSSParsing() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
19,
17,
"enableNewBackgroundAndBorderDrawables",
" REACT_SYNC_METHOD(enableNewBackgroundAndBorderDrawables) bool enableNewBackgroundAndBorderDrawables() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableNewBackgroundAndBorderDrawables) static bool enableNewBackgroundAndBorderDrawables() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
20,
18,
"enablePropsUpdateReconciliationAndroid",
" REACT_SYNC_METHOD(enablePropsUpdateReconciliationAndroid) bool enablePropsUpdateReconciliationAndroid() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enablePropsUpdateReconciliationAndroid) static bool enablePropsUpdateReconciliationAndroid() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
21,
19,
"enableReportEventPaintTime",
" REACT_SYNC_METHOD(enableReportEventPaintTime) bool enableReportEventPaintTime() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableReportEventPaintTime) static bool enableReportEventPaintTime() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
22,
20,
"enableSynchronousStateUpdates",
" REACT_SYNC_METHOD(enableSynchronousStateUpdates) bool enableSynchronousStateUpdates() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableSynchronousStateUpdates) static bool enableSynchronousStateUpdates() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
23,
21,
"enableUIConsistency",
" REACT_SYNC_METHOD(enableUIConsistency) bool enableUIConsistency() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableUIConsistency) static bool enableUIConsistency() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
24,
22,
"enableViewCulling",
" REACT_SYNC_METHOD(enableViewCulling) bool enableViewCulling() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableViewCulling) static bool enableViewCulling() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
25,
23,
"enableViewRecycling",
" REACT_SYNC_METHOD(enableViewRecycling) bool enableViewRecycling() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableViewRecycling) static bool enableViewRecycling() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
26,
24,
"enableViewRecyclingForText",
" REACT_SYNC_METHOD(enableViewRecyclingForText) bool enableViewRecyclingForText() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableViewRecyclingForText) static bool enableViewRecyclingForText() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
27,
25,
"enableViewRecyclingForView",
" REACT_SYNC_METHOD(enableViewRecyclingForView) bool enableViewRecyclingForView() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(enableViewRecyclingForView) static bool enableViewRecyclingForView() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
28,
26,
"fixDifferentiatorEmittingUpdatesWithWrongParentTag",
" REACT_SYNC_METHOD(fixDifferentiatorEmittingUpdatesWithWrongParentTag) bool fixDifferentiatorEmittingUpdatesWithWrongParentTag() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(fixDifferentiatorEmittingUpdatesWithWrongParentTag) static bool fixDifferentiatorEmittingUpdatesWithWrongParentTag() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
27,
"fixMappingOfEventPrioritiesBetweenFabricAndReact",
" REACT_SYNC_METHOD(fixMappingOfEventPrioritiesBetweenFabricAndReact) bool fixMappingOfEventPrioritiesBetweenFabricAndReact() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(fixMappingOfEventPrioritiesBetweenFabricAndReact) static bool fixMappingOfEventPrioritiesBetweenFabricAndReact() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
29,
28,
"fixMountingCoordinatorReportedPendingTransactionsOnAndroid",
" REACT_SYNC_METHOD(fixMountingCoordinatorReportedPendingTransactionsOnAndroid) bool fixMountingCoordinatorReportedPendingTransactionsOnAndroid() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(fixMountingCoordinatorReportedPendingTransactionsOnAndroid) static bool fixMountingCoordinatorReportedPendingTransactionsOnAndroid() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
30,
29,
"fuseboxEnabledRelease",
" REACT_SYNC_METHOD(fuseboxEnabledRelease) bool fuseboxEnabledRelease() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(fuseboxEnabledRelease) static bool fuseboxEnabledRelease() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
31,
30,
"fuseboxNetworkInspectionEnabled",
" REACT_SYNC_METHOD(fuseboxNetworkInspectionEnabled) bool fuseboxNetworkInspectionEnabled() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(fuseboxNetworkInspectionEnabled) static bool fuseboxNetworkInspectionEnabled() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
31,
"lazyAnimationCallbacks",
" REACT_SYNC_METHOD(lazyAnimationCallbacks) bool lazyAnimationCallbacks() noexcept { /* implementation */ }\n"
" REACT_SYNC_METHOD(lazyAnimationCallbacks) static bool lazyAnimationCallbacks() noexcept { /* implementation */ }\n");
REACT_SHOW_METHOD_SPEC_ERRORS(
32,
"removeTurboModuleManagerDelegateMutex",
Expand Down
Loading