Skip to content

Commit

Permalink
Revert "Alleviate excessive layout jittering when resizing window (fa…
Browse files Browse the repository at this point in the history
…cebook#439)" (facebook#1318)

This change reverts microsoft#459 - but still tries to address the original issues:
- microsoft#422
- microsoft#322

This also addresses an issue when programmatically resizing windows where the RCTRootContentView may end up at the wrong size because an in-flight layout gets resolved after the resize on the main thread.
We now keep sync dispatch on the shadow queue for live resizing windows (to prevent tearing) but also dispatch async (as done on iOS) so the latest new size is sure to win.
The block has a check to bail if the size doesn't change, so this isn't a perf drain running the block twice.

Co-authored-by: Scott Kyle <skyle@fb.com>
  • Loading branch information
christophpurrer and appden committed Aug 4, 2022
1 parent 2bcaeb1 commit e6482e0
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 54 deletions.
42 changes: 0 additions & 42 deletions React/Base/RCTRootView.m
Expand Up @@ -33,10 +33,6 @@
#import "RCTDevMenu.h"
#endif // ]TODO(OSS Candidate ISS#2710739)

#if TARGET_OS_OSX // [TODO(macOS GH#774)
#define RCT_LAYOUT_THROTTLE 0.25
#endif // ]TODO(macOS GH#774)

NSString *const RCTContentDidAppearNotification = @"RCTContentDidAppearNotification";

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

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

- (instancetype)initWithFrame:(CGRect)frame
Expand Down Expand Up @@ -85,10 +76,6 @@ - (instancetype)initWithFrame:(CGRect)frame
_sizeFlexibility = RCTRootViewSizeFlexibilityNone;
_minimumSize = CGSizeZero;

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

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

#if TARGET_OS_OSX // [TODO(macOS GH#774)
// 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 GH#774)

- (void)layoutSubviews
{
[super layoutSubviews];
Expand Down
37 changes: 25 additions & 12 deletions React/Modules/RCTUIManager.m
Expand Up @@ -412,21 +412,34 @@ - (void)_executeBlockWithShadowView:(void (^)(RCTShadowView *shadowView))block f
- (void)setAvailableSize:(CGSize)availableSize forRootView:(RCTUIView *)rootView // TODO(macOS ISS#3536887)
{
RCTAssertMainQueue();
[self
_executeBlockWithShadowView:^(RCTShadowView *shadowView) {
RCTAssert(
[shadowView isKindOfClass:[RCTRootShadowView class]], @"Located shadow view is actually not root view.");

RCTRootShadowView *rootShadowView = (RCTRootShadowView *)shadowView;
void (^block)(RCTShadowView *) = ^(RCTShadowView *shadowView) {
RCTAssert(
[shadowView isKindOfClass:[RCTRootShadowView class]], @"Located shadow view is actually not root view.");

if (CGSizeEqualToSize(availableSize, rootShadowView.availableSize)) {
return;
}
RCTRootShadowView *rootShadowView = (RCTRootShadowView *)shadowView;

rootShadowView.availableSize = availableSize;
[self setNeedsLayout];
}
forTag:rootView.reactTag];
if (CGSizeEqualToSize(availableSize, rootShadowView.availableSize)) {
return;
}

rootShadowView.availableSize = availableSize;
[self setNeedsLayout];
};

#if TARGET_OS_OSX // [TODO(macOS GH#744)
if (rootView.inLiveResize) {
NSNumber* tag = rootView.reactTag;
// Synchronously relayout to prevent "tearing" when resizing windows.
// Still run block asynchronously below so it "wins" after any in-flight layout.
RCTUnsafeExecuteOnUIManagerQueueSync(^{
RCTShadowView *shadowView = self->_shadowViewRegistry[tag];
block(shadowView);
});
}
#endif // ]TODO(macOS GH#744)

[self _executeBlockWithShadowView:block forTag:rootView.reactTag];
}

- (void)setLocalData:(NSObject *)localData forView:(RCTUIView *)view // TODO(macOS ISS#3536887)
Expand Down

0 comments on commit e6482e0

Please sign in to comment.