mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
test
This commit is contained in:
parent
757986dd39
commit
130bc5203a
@ -254,6 +254,13 @@ FLUTTER_DARWIN_EXPORT
|
||||
*/
|
||||
@property(nonatomic, readonly) BOOL engineAllowHeadlessExecution;
|
||||
|
||||
/**
|
||||
* Controls whether the created view can be sized based on its content.
|
||||
*
|
||||
* Default is `NO`.
|
||||
*/
|
||||
@property(nonatomic, getter=isAutoResizable) BOOL autoResizable;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -667,6 +667,21 @@ static CGRect GetCGRectFromDlRect(const DlRect& clipDlRect) {
|
||||
|
||||
// No platform views to render; we're done.
|
||||
if (self.flutterView == nil || (self.compositionOrder.empty() && !self.hadPlatformViews)) {
|
||||
// No platform views to render but there is a Flutter view and therefore may have a resize
|
||||
if (self.flutterView != nil) {
|
||||
// If the raster thread isn't merged, resize the view on the platform thread and block until
|
||||
// complete.
|
||||
auto latch = std::make_shared<fml::CountDownLatch>(1u);
|
||||
fml::TaskRunner::RunNowOrPostTask(self.platformTaskRunner,
|
||||
[self, frameSize = self.frameSize, latch]() mutable {
|
||||
[self performResize:frameSize];
|
||||
latch->CountDown();
|
||||
});
|
||||
if (![[NSThread currentThread] isMainThread]) {
|
||||
latch->Wait();
|
||||
}
|
||||
}
|
||||
// No platform views to render; we're done.
|
||||
self.hadPlatformViews = NO;
|
||||
return background_frame->Submit();
|
||||
}
|
||||
@ -753,13 +768,16 @@ static CGRect GetCGRectFromDlRect(const DlRect& clipDlRect) {
|
||||
self.layerPool->RemoveUnusedLayers();
|
||||
self.layerPool->RecycleLayers();
|
||||
|
||||
// If the raster thread isn't merged, wait for the platform thread to finish submitting the frame.
|
||||
auto latch = std::make_shared<fml::CountDownLatch>(1u);
|
||||
auto task = [self, //
|
||||
platformViewLayers = std::move(platformViewLayers), //
|
||||
currentCompositionParams = self.currentCompositionParams, //
|
||||
viewsToRecomposite = self.viewsToRecomposite, //
|
||||
compositionOrder = self.compositionOrder, //
|
||||
unusedLayers = std::move(unusedLayers), //
|
||||
surfaceFrames = std::move(surfaceFrames) //
|
||||
surfaceFrames = std::move(surfaceFrames), //
|
||||
latch //
|
||||
]() mutable {
|
||||
[self performSubmit:platformViewLayers
|
||||
currentCompositionParams:currentCompositionParams
|
||||
@ -767,10 +785,14 @@ static CGRect GetCGRectFromDlRect(const DlRect& clipDlRect) {
|
||||
compositionOrder:compositionOrder
|
||||
unusedLayers:unusedLayers
|
||||
surfaceFrames:surfaceFrames];
|
||||
latch->CountDown();
|
||||
};
|
||||
|
||||
fml::TaskRunner::RunNowOrPostTask(self.platformTaskRunner, fml::MakeCopyable(std::move(task)));
|
||||
|
||||
if (![[NSThread currentThread] isMainThread]) {
|
||||
latch->Wait();
|
||||
}
|
||||
return didEncode;
|
||||
}
|
||||
|
||||
@ -799,6 +821,17 @@ static CGRect GetCGRectFromDlRect(const DlRect& clipDlRect) {
|
||||
}
|
||||
}
|
||||
|
||||
- (void)performResize:(const flutter::DlISize&)frameSize {
|
||||
TRACE_EVENT0("flutter", "PlatformViewsController::PerformResize");
|
||||
FML_DCHECK([[NSThread currentThread] isMainThread]);
|
||||
if (self.flutterView != nil) {
|
||||
FML_LOG(ERROR) << "RESIZE RENDER STEP 9: \n setIntrinsicContentSize " << frameSize.width << "x"
|
||||
<< frameSize.height;
|
||||
[(FlutterView*)self.flutterView
|
||||
setIntrinsicContentSize:CGSizeMake(frameSize.width, frameSize.height)];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)performSubmit:(const LayersMap&)platformViewLayers
|
||||
currentCompositionParams:
|
||||
(std::unordered_map<int64_t, flutter::EmbeddedViewParams>&)currentCompositionParams
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
- (void)flutterViewAccessibilityDidCall;
|
||||
@end
|
||||
|
||||
@interface FlutterAutoResizeLayoutConstraint : NSLayoutConstraint
|
||||
@end
|
||||
|
||||
@interface FlutterView : UIView
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
@ -42,6 +45,9 @@
|
||||
|
||||
- (UIScreen*)screen;
|
||||
- (MTLPixelFormat)pixelFormat;
|
||||
- (void)setIntrinsicContentSize:(CGSize)size;
|
||||
- (void)resetIntrinsicContentSize;
|
||||
@property(nonatomic, assign, readwrite) BOOL autoResizable;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@ -14,8 +14,12 @@ FLUTTER_ASSERT_ARC
|
||||
@property(nonatomic, weak) id<FlutterViewEngineDelegate> delegate;
|
||||
@end
|
||||
|
||||
@implementation FlutterAutoResizeLayoutConstraint
|
||||
@end
|
||||
|
||||
@implementation FlutterView {
|
||||
BOOL _isWideGamutEnabled;
|
||||
CGSize _intrinsicSize;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
@ -37,6 +41,69 @@ FLUTTER_ASSERT_ARC
|
||||
return self.window.windowScene.screen;
|
||||
}
|
||||
|
||||
|
||||
// iOS has a concept of "intrinsicContentSize", which indicates the size a view would like to be
|
||||
// based on its content. When an intrinsicContentSize is set, iOS will automatically add Auto Layout
|
||||
// constraints for the width and/or height. However, the constraints use a private API. There are
|
||||
// situations where we may want to filter these constraints. To avoid using a private API, Flutter
|
||||
// creates a custom constraint called FlutterAutoResizeLayoutConstraint to add a width/height
|
||||
// constraint that reflects the intrinsicContentSize.
|
||||
- (void)setIntrinsicContentSize:(CGSize)size {
|
||||
if (!self.autoResizable) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGFloat scale = self.window.windowScene.screen.scale;
|
||||
CGSize scaledSize = CGSizeMake(size.width / scale, size.height / scale);
|
||||
|
||||
// If the size has not changed, don't update constraints.
|
||||
if (CGSizeEqualToSize(_intrinsicSize, scaledSize)) {
|
||||
return;
|
||||
}
|
||||
_intrinsicSize = scaledSize;
|
||||
|
||||
self.translatesAutoresizingMaskIntoConstraints = false;
|
||||
|
||||
// Remove any existing FlutterAutoResizeLayoutConstraint
|
||||
[self removeAutoResizeLayoutConstraints];
|
||||
|
||||
FlutterAutoResizeLayoutConstraint* widthConstraint =
|
||||
[FlutterAutoResizeLayoutConstraint constraintWithItem:self
|
||||
attribute:NSLayoutAttributeWidth
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:nil
|
||||
attribute:NSLayoutAttributeNotAnAttribute
|
||||
multiplier:1.0
|
||||
constant:scaledSize.width];
|
||||
|
||||
FlutterAutoResizeLayoutConstraint* heightConstraint =
|
||||
[FlutterAutoResizeLayoutConstraint constraintWithItem:self
|
||||
attribute:NSLayoutAttributeHeight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:nil
|
||||
attribute:NSLayoutAttributeNotAnAttribute
|
||||
multiplier:1.0
|
||||
constant:scaledSize.height];
|
||||
|
||||
// widthConstraint.priority = UILayoutPriorityDefaultLow;
|
||||
// heightConstraint.priority = UILayoutPriorityDefaultLow;
|
||||
[NSLayoutConstraint activateConstraints:@[ widthConstraint, heightConstraint ]];
|
||||
[self setNeedsLayout];
|
||||
}
|
||||
|
||||
- (void)resetIntrinsicContentSize {
|
||||
_intrinsicSize = CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric);
|
||||
[self removeAutoResizeLayoutConstraints];
|
||||
}
|
||||
|
||||
- (void)removeAutoResizeLayoutConstraints {
|
||||
for (NSLayoutConstraint* constraint in self.constraints) {
|
||||
if ([constraint isKindOfClass:[FlutterAutoResizeLayoutConstraint class]]) {
|
||||
constraint.active = NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (MTLPixelFormat)pixelFormat {
|
||||
if ([self.layer isKindOfClass:[CAMetalLayer class]]) {
|
||||
// It is a known Apple bug that CAMetalLayer incorrectly reports its supported
|
||||
@ -77,6 +144,8 @@ FLUTTER_ASSERT_ARC
|
||||
_delegate = delegate;
|
||||
_isWideGamutEnabled = isWideGamutEnabled;
|
||||
self.layer.opaque = opaque;
|
||||
_autoResizable = NO;
|
||||
_intrinsicSize = CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric);
|
||||
}
|
||||
|
||||
return self;
|
||||
|
||||
@ -129,6 +129,8 @@ typedef struct MouseState {
|
||||
/// the same with frame rate of rendering.
|
||||
@property(nonatomic, strong) VSyncClient* touchRateCorrectionVSyncClient;
|
||||
|
||||
@property(nonatomic, assign) CGSize sizeBeforeAutoResized;
|
||||
|
||||
/*
|
||||
* Mouse and trackpad gesture recognizers
|
||||
*/
|
||||
@ -168,6 +170,8 @@ typedef struct MouseState {
|
||||
@synthesize viewOpaque = _viewOpaque;
|
||||
@synthesize displayingFlutterUI = _displayingFlutterUI;
|
||||
|
||||
@synthesize autoResizable = _autoResizable;
|
||||
|
||||
// TODO(dkwingsmt): https://github.com/flutter/flutter/issues/138168
|
||||
// No backing ivar is currently required; when multiple views are supported, we'll need to
|
||||
// synthesize the ivar and store the view identifier.
|
||||
@ -1435,6 +1439,7 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch)
|
||||
_viewportMetrics.device_pixel_ratio = scale;
|
||||
[self setViewportMetricsSize];
|
||||
[self setViewportMetricsPaddings];
|
||||
[self updateAutoResizeConstraints];
|
||||
[self updateViewportMetricsIfNeeded];
|
||||
|
||||
// There is no guarantee that UIKit will layout subviews when the application/scene is active.
|
||||
@ -1460,6 +1465,61 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch)
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)isAutoResizable {
|
||||
return _autoResizable;
|
||||
}
|
||||
|
||||
- (void)setAutoResizable:(BOOL)value {
|
||||
_autoResizable = value;
|
||||
self.flutterView.autoResizable = value;
|
||||
}
|
||||
|
||||
- (void)updateAutoResizeConstraints {
|
||||
if (!self.isAutoResizable) {
|
||||
return;
|
||||
}
|
||||
|
||||
// When viewDidLayoutSubviews is called (which is where this method is called),
|
||||
// the view has finished laying out its subviews and has applied any auto layout constraints.
|
||||
// Therefore, we're able to use the frame to determine what size is allowed by layout constraints.
|
||||
// However, we're only able to use this value if Flutter hasn't already applied any
|
||||
// FlutterAutoResizeLayoutConstraint constraints. Once Flutter applies constraints, that will
|
||||
// determine the frame. This imposes a limitation on content resizing that layout constraints
|
||||
// updated after an auto-resize has been applied may not work properly.
|
||||
BOOL hasBeenAutoResized = NO;
|
||||
for (NSLayoutConstraint* constraint in self.view.constraints) {
|
||||
if ([constraint isKindOfClass:[FlutterAutoResizeLayoutConstraint class]]) {
|
||||
hasBeenAutoResized = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasBeenAutoResized) {
|
||||
self.sizeBeforeAutoResized = self.view.frame.size;
|
||||
}
|
||||
|
||||
CGFloat maxWidth = self.sizeBeforeAutoResized.width;
|
||||
CGFloat maxHeight = self.sizeBeforeAutoResized.height;
|
||||
CGFloat minWidth = self.sizeBeforeAutoResized.width;
|
||||
CGFloat minHeight = self.sizeBeforeAutoResized.height;
|
||||
|
||||
// maxWidth or maxHeight may be 0 when the width/height are ambiguous.
|
||||
if (maxWidth == 0) {
|
||||
maxWidth = DBL_MAX;
|
||||
}
|
||||
if (maxHeight == 0) {
|
||||
maxHeight = DBL_MAX;
|
||||
}
|
||||
_viewportMetrics.physical_min_width_constraint = minWidth * _viewportMetrics.device_pixel_ratio;
|
||||
_viewportMetrics.physical_max_width_constraint = maxWidth * _viewportMetrics.device_pixel_ratio;
|
||||
_viewportMetrics.physical_min_height_constraint = minHeight * _viewportMetrics.device_pixel_ratio;
|
||||
_viewportMetrics.physical_max_height_constraint = maxHeight * _viewportMetrics.device_pixel_ratio;
|
||||
|
||||
// NSLog(@"Updated auto-resize constraints: maxWidth = %f, maxHeight = %f, minWidth = %f, "
|
||||
// @"minHeight = %f",
|
||||
// maxWidth, maxHeight, minWidth, minHeight);
|
||||
}
|
||||
|
||||
- (void)viewSafeAreaInsetsDidChange {
|
||||
@ -2201,6 +2261,11 @@ static flutter::PointerData::DeviceKind DeviceKindFromTouchType(UITouch* touch)
|
||||
- (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection {
|
||||
[super traitCollectionDidChange:previousTraitCollection];
|
||||
[self onUserSettingsChanged:nil];
|
||||
|
||||
// Size changes when certain traits change, such as orientation or scale.
|
||||
if (self.isAutoResizable) {
|
||||
[self.flutterView resetIntrinsicContentSize];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onUserSettingsChanged:(NSNotification*)notification {
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
{
|
||||
"name": "fake-vs-code-install-for-tests",
|
||||
"version": "1.2.3"
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user