diff --git a/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils.xcodeproj/project.pbxproj b/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils.xcodeproj/project.pbxproj index ae6f7b272af9d..cc39669877135 100644 --- a/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils.xcodeproj/project.pbxproj +++ b/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 55F0AA132F70000100ABC123 /* CMPFrameRateRange.m in Sources */ = {isa = PBXBuildFile; fileRef = 55F0AA122F70000100ABC123 /* CMPFrameRateRange.m */; }; 99009B7A2F322B4700518C1F /* CMPMetalLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 99009B792F322B4700518C1F /* CMPMetalLayer.m */; }; 99009B7B2F322B4700518C1F /* CMPMetalLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 99009B792F322B4700518C1F /* CMPMetalLayer.m */; }; 991A97F72E1FB99300B47130 /* CMPScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 991A97F62E1FB99300B47130 /* CMPScrollView.m */; }; @@ -79,6 +80,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 55F0AA112F70000100ABC123 /* CMPFrameRateRange.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CMPFrameRateRange.h; sourceTree = ""; }; + 55F0AA122F70000100ABC123 /* CMPFrameRateRange.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CMPFrameRateRange.m; sourceTree = ""; }; 99009B782F322B4700518C1F /* CMPMetalLayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CMPMetalLayer.h; sourceTree = ""; }; 99009B792F322B4700518C1F /* CMPMetalLayer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CMPMetalLayer.m; sourceTree = ""; }; 991A97F52E1FB99300B47130 /* CMPScrollView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CMPScrollView.h; sourceTree = ""; }; @@ -176,6 +179,8 @@ children = ( C4C07E832F57037300A9DC94 /* CMPEditMenuCustomAction.h */, C4C07E842F57037300A9DC94 /* CMPEditMenuCustomAction.m */, + 55F0AA112F70000100ABC123 /* CMPFrameRateRange.h */, + 55F0AA122F70000100ABC123 /* CMPFrameRateRange.m */, C4C07E852F57037300A9DC94 /* CMPTextInputStringTokenizer.h */, C4C07E862F57037300A9DC94 /* CMPTextInputStringTokenizer.m */, C4C07E872F57037300A9DC94 /* CMPTextInputView.h */, @@ -402,6 +407,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 55F0AA132F70000100ABC123 /* CMPFrameRateRange.m in Sources */, 997DFCDE2B18D135000B56B5 /* CMPViewController.m in Sources */, 9968C38B2D7892DF005E8DE4 /* CMPScreenEdgePanGestureRecognizer.m in Sources */, EAB33E182C12E746002CFF44 /* CMPMetalDrawablesHandler.m in Sources */, diff --git a/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPFrameRateRange.h b/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPFrameRateRange.h new file mode 100644 index 0000000000000..5f1cd364e8b80 --- /dev/null +++ b/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPFrameRateRange.h @@ -0,0 +1,31 @@ +/* + * Copyright 2026 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface CMPFrameRateRangeDefault : NSObject + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +/// Returns the default preferred frame rate for CADisplayLink on the current OS version. +@property (class, nonatomic, readonly) float preferred; + +@end + +NS_ASSUME_NONNULL_END diff --git a/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPFrameRateRange.m b/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPFrameRateRange.m new file mode 100644 index 0000000000000..8c27ce4af1c73 --- /dev/null +++ b/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPFrameRateRange.m @@ -0,0 +1,31 @@ +/* + * Copyright 2026 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "CMPFrameRateRange.h" +#import + +@implementation CMPFrameRateRangeDefault + ++ (float)preferred { + if (@available(iOS 15.0, *)) { + return CAFrameRateRangeDefault.preferred; + } else { + // `preferredFramesPerSecond = 0` is CADisplayLink's documented default + return 0.0f; + } +} + +@end diff --git a/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPUIKitUtils.h b/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPUIKitUtils.h index 7ece2b7487a3c..60c2cbeb4a3bc 100644 --- a/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPUIKitUtils.h +++ b/compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPUIKitUtils.h @@ -24,6 +24,7 @@ FOUNDATION_EXPORT const unsigned char CMPUIKitUtilsVersionString[]; #import "CMPAccessibilityElement.h" #import "CMPComposeContainerLifecycleDelegate.h" +#import "CMPFrameRateRange.h" #import "CMPDragInteractionProxy.h" #import "CMPDrawable.h" #import "CMPDropInteractionProxy.h" diff --git a/compose/ui/ui/src/iosMain/kotlin/androidx/compose/ui/window/DisplayLinkFrameRate.ios.kt b/compose/ui/ui/src/iosMain/kotlin/androidx/compose/ui/window/DisplayLinkFrameRate.ios.kt index fd1d14e252e10..ea793aa0947e6 100644 --- a/compose/ui/ui/src/iosMain/kotlin/androidx/compose/ui/window/DisplayLinkFrameRate.ios.kt +++ b/compose/ui/ui/src/iosMain/kotlin/androidx/compose/ui/window/DisplayLinkFrameRate.ios.kt @@ -17,8 +17,8 @@ package androidx.compose.ui.window import androidx.compose.ui.FrameRateCategory +import androidx.compose.ui.uikit.utils.CMPFrameRateRangeDefault import platform.QuartzCore.CADisplayLink -import platform.QuartzCore.CAFrameRateRangeDefault import platform.darwin.NSInteger /** @@ -45,7 +45,7 @@ internal class DisplayLinkFrameRate( fun voteFrameRate(frameRate: Float, frameRateCategory: Float) { val frameRateCategoryValue = when (frameRateCategory) { - FrameRateCategory.Default.value -> CAFrameRateRangeDefault.preferred + FrameRateCategory.Default.value -> CMPFrameRateRangeDefault.preferred FrameRateCategory.Normal.value -> 60f FrameRateCategory.High.value -> maximumFramesPerSecond.toFloat() else -> Float.NaN @@ -69,4 +69,4 @@ internal class DisplayLinkFrameRate( frameRateVote = Float.NaN } } -} \ No newline at end of file +}