Skip to content

Commit

Permalink
Alleviate excessive layout jittering when resizing window (#439)
Browse files Browse the repository at this point in the history
  • Loading branch information
tido64 authored Jun 29, 2020
1 parent 819cff0 commit 6386729
Showing 1 changed file with 42 additions and 0 deletions.
42 changes: 42 additions & 0 deletions React/Base/RCTRootView.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
#import "RCTDevMenu.h"
#endif // ]TODO(OSS Candidate ISS#2710739)

#if TARGET_OS_OSX // [TODO(macOS ISS#2323203)
#define RCT_LAYOUT_THROTTLE 0.25
#endif // ]TODO(macOS ISS#2323203)

NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotification";

@interface RCTUIManager (RCTRootView)
Expand All @@ -52,6 +56,11 @@ @implementation RCTRootView
RCTRootContentView *_contentView;
BOOL _passThroughTouches;
CGSize _intrinsicContentSize;

#if TARGET_OS_OSX // [TODO(macOS ISS#2323203)
NSDate *_lastLayout;
BOOL _throttleLayout;
#endif // ]TODO(macOS ISS#2323203)
}

- (instancetype)initWithBridge:(RCTBridge *)bridge
Expand Down Expand Up @@ -79,6 +88,10 @@ - (instancetype)initWithBridge:(RCTBridge *)bridge
_loadingViewFadeDuration = 0.25;
_sizeFlexibility = RCTRootViewSizeFlexibilityNone;

#if TARGET_OS_OSX // [TODO(macOS ISS#2323203)
_lastLayout = [NSDate new];
#endif // ]TODO(macOS ISS#2323203)

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(bridgeDidReload)
name:RCTJavaScriptWillStartLoadingNotification
Expand Down Expand Up @@ -173,6 +186,35 @@ - (CGSize)sizeThatFits:(CGSize)size
return fitSize;
}

#if TARGET_OS_OSX // [TODO(macOS ISS#2323203)
// TODO: https://github.com/microsoft/react-native-macos/issues/459
// This is a workaround for window resizing events overloading the shadow queue:
// - https://github.com/microsoft/react-native-macos/issues/322
// - https://github.com/microsoft/react-native-macos/issues/422
// We should revisit this issue when we switch over to Fabric.
- (void)layout
{
if (self.window != nil && !_throttleLayout) {
NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:_lastLayout];
if (interval >= RCT_LAYOUT_THROTTLE) {
_lastLayout = [NSDate new];
[self layoutSubviews];
} else {
_throttleLayout = YES;
__weak typeof(self) weakSelf = self;
int64_t delta = (RCT_LAYOUT_THROTTLE - interval) * NSEC_PER_SEC;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delta), dispatch_get_main_queue(), ^{
typeof(self) strongSelf = weakSelf;
if (strongSelf != nil) {
strongSelf->_throttleLayout = NO;
[strongSelf setNeedsLayout];
}
});
}
}
}
#endif // ]TODO(macOS ISS#2323203)

- (void)layoutSubviews
{
[super layoutSubviews];
Expand Down

0 comments on commit 6386729

Please sign in to comment.