Skip to content

Commit a7587e8

Browse files
committed
chore: pick a change around viewDidEndLiveResize
1 parent 98eb33d commit a7587e8

File tree

3 files changed

+41
-0
lines changed

3 files changed

+41
-0
lines changed

packages/react-native/React/Base/RCTRootView.m

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,13 @@ - (BOOL)canBecomeFirstResponder
204204
#endif // macOS]
205205
}
206206

207+
#if TARGET_OS_OSX // [macOS
208+
- (void)viewDidEndLiveResize {
209+
[super viewDidEndLiveResize];
210+
[self setNeedsLayout];
211+
}
212+
#endif // macOS]
213+
207214
- (void)setLoadingView:(RCTUIView *)loadingView // [macOS]
208215
{
209216
_loadingView = loadingView;

packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.mm

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ - (void)disableActivityIndicatorAutoHide:(BOOL)disabled
139139
_autoHideDisabled = disabled;
140140
}
141141

142+
#pragma mark - NSView
143+
144+
#if TARGET_OS_OSX // [macOS
145+
- (void)viewDidEndLiveResize {
146+
[super viewDidEndLiveResize];
147+
[self setNeedsLayout];
148+
}
149+
#endif // macOS]
150+
142151
#pragma mark - isActivityIndicatorViewVisible
143152

144153
- (void)setIsActivityIndicatorViewVisible:(BOOL)visible

packages/react-native/React/Views/ScrollView/RCTScrollView.m

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ @implementation RCTScrollView {
328328
BOOL _allowNextScrollNoMatterWhat;
329329
#if TARGET_OS_OSX // [macOS
330330
BOOL _notifyDidScroll;
331+
BOOL _disableScrollEvents;
331332
NSPoint _lastScrollPosition;
332333
#endif // macOS]
333334
CGRect _lastClippedToRect;
@@ -570,8 +571,28 @@ - (void)setRemoveClippedSubviews:(__unused BOOL)removeClippedSubviews
570571

571572
- (void)setFrame:(CGRect)frame
572573
{
574+
#if !TARGET_OS_OSX // [macOS]
575+
[super setFrame:frame];
576+
#else // [macOS
577+
/**
578+
* Setting the frame on the scroll view will randomly generate between 0 and 4 scroll events. These events happen
579+
* during the layout phase of the view which generates layout notifications that are sent through the bridge.
580+
* Because the bridge is heavily used, the scroll events are throttled and reach the JS thread with a random delay.
581+
* Because the scroll event stores the clip and content view size, delayed scroll events will submit stale layout
582+
* information that can break virtual list implemenations.
583+
* By disabling scroll events during the execution of the setFrame method and scheduling one notification on
584+
* the next run loop, we can mitigate the delayed scroll event by sending it at a time where the bridge is not busy.
585+
*/
586+
_disableScrollEvents = YES;
573587
[super setFrame:frame];
588+
_disableScrollEvents = NO;
589+
590+
if (self.window != nil && !self.window.inLiveResize) {
591+
[self performSelector:@selector(scrollViewDocumentViewBoundsDidChange:) withObject:nil afterDelay:0];
592+
}
593+
#endif // macOS]
574594
[self centerContentIfNeeded];
595+
575596
}
576597

577598
- (void)insertReactSubview:(RCTUIView *)view atIndex:(NSInteger)atIndex // [macOS]
@@ -867,6 +888,10 @@ - (void)flashScrollIndicators
867888
#if TARGET_OS_OSX // [macOS
868889
- (void)scrollViewDocumentViewBoundsDidChange:(__unused NSNotification *)notification
869890
{
891+
if (_disableScrollEvents) {
892+
return;
893+
}
894+
870895
if (_scrollView.centerContent) {
871896
// contentOffset setter dynamically centers content when _centerContent == YES
872897
[_scrollView setContentOffset:_scrollView.contentOffset];

0 commit comments

Comments
 (0)