Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
49adb70
Move Clipboard, ClipboardManager, AccessibilityManager, AutofillTree,…
ApoloApps Jul 12, 2026
4ab3396
Added forgotten imports in ComposeSceneMediator
ApoloApps Jul 12, 2026
e012328
Reroute Autofill issue to non-duplicate one
ApoloApps Jul 13, 2026
46ee8cf
Merge branch 'JetBrains:jb-main' into movePlatformObjects
ApoloApps Jul 14, 2026
2c249fa
Revert changes unifying AccessibilityManager and PlatformScreenReader…
ApoloApps Jul 14, 2026
c60c27e
Merge branch 'JetBrains:jb-main' into movePlatformObjects
ApoloApps Jul 14, 2026
2d1575c
Merge branch 'JetBrains:jb-main' into movePlatformObjects
ApoloApps Jul 20, 2026
3b0db01
Add import for toDpSize function
ApoloApps Jul 20, 2026
a48a40a
Merge branch 'jb-main' into movePlatformObjects
ApoloApps Jul 22, 2026
e472d4a
Remove unneeded import after rebase
ApoloApps Jul 22, 2026
0e206f0
Merge branch 'JetBrains:jb-main' into movePlatformObjects
ApoloApps Jul 28, 2026
2f98273
Add UriHandler to PlatformContext. It serves as to reuse across Owner…
ApoloApps Jul 28, 2026
bc95d11
Remove ambiguous import causing tests and ApiCheck failures
ApoloApps Jul 29, 2026
a5f28ba
Merge branch 'jb-main' into movePlatformObjects
ApoloApps Jul 29, 2026
e18901b
Merge branch 'JetBrains:jb-main' into movePlatformObjects
ApoloApps Aug 14, 2026
d25a75c
Merge branch 'jb-main' into movePlatformObjects
ApoloApps Sep 1, 2026
7bec7c8
Refactor uriHandler property to use platformContext
ApoloApps Sep 1, 2026
bf7d30d
Merge branch 'JetBrains:jb-main' into movePlatformObjects
ApoloApps Sep 4, 2026
f18584b
Add forgotten UriHandler import
ApoloApps Sep 4, 2026
0d50105
Move font loader and resolver to PlatformContext to reuse them across…
ApoloApps Sep 4, 2026
53f1e5c
Add SoundEffect to PlatformContext to be able to reuse it across Owne…
ApoloApps Sep 4, 2026
b55f261
Merge branch 'JetBrains:jb-main' into movePlatformObjects
ApoloApps Sep 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ package androidx.compose.foundation.lazy

import androidx.compose.runtime.Composable
import androidx.compose.ui.InternalComposeUiApi
import androidx.compose.ui.platform.LocalPlatformScreenReader
import androidx.compose.ui.platform.LocalAccessibilityManager
import androidx.compose.ui.platform.PlatformAccessibilityManager

/**
* A minimum number of preloaded elements to allow the iOS accessibility engine to traverse the
Expand All @@ -29,7 +30,8 @@ private const val SCREEN_READER_BEYOND_BOUNDS_ITEM_COUNT = 3
@OptIn(InternalComposeUiApi::class)
@Composable
internal actual fun defaultLazyListBeyondBoundsItemCount(): Int {
return if (LocalPlatformScreenReader.current.isActive) {
val accessibilityManager = LocalAccessibilityManager.current
Comment thread
ASalavei marked this conversation as resolved.
Outdated
return if (accessibilityManager is PlatformAccessibilityManager && accessibilityManager.isScreenReaderActive) {
SCREEN_READER_BEYOND_BOUNDS_ITEM_COUNT
} else {
0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ import androidx.compose.ui.input.pointer.PointerType
import androidx.compose.ui.isClearFocusOnMouseDownEnabled
import androidx.compose.ui.navigationevent.BackNavigationEventInput
import androidx.compose.ui.platform.AwtDragAndDropManager
import androidx.compose.ui.platform.Clipboard
import androidx.compose.ui.platform.ClipboardManager
import androidx.compose.ui.platform.DefaultInputModeManager
import androidx.compose.ui.platform.DelegateRootForTestListener
import androidx.compose.ui.platform.DesktopTextInputService
Expand All @@ -63,6 +65,8 @@ import androidx.compose.ui.platform.PlatformWindowContext
import androidx.compose.ui.platform.ViewConfiguration
import androidx.compose.ui.platform.WindowInfo
import androidx.compose.ui.platform.a11y.ComposeSceneAccessibility
import androidx.compose.ui.platform.createPlatformClipboard
import androidx.compose.ui.platform.createPlatformClipboardManager
import androidx.compose.ui.scene.skia.SkiaLayerComponent
import androidx.compose.ui.semantics.SemanticsOwner
import androidx.compose.ui.unit.Constraints
Expand Down Expand Up @@ -862,6 +866,13 @@ internal class ComposeSceneMediator(
DefaultInputModeManager()
}

override val clipboard: Clipboard by lazy(LazyThreadSafetyMode.NONE) {
createPlatformClipboard()
}
override val clipboardManager: ClipboardManager by lazy(LazyThreadSafetyMode.NONE) {
createPlatformClipboardManager()
}

override val textInputService get() = this@ComposeSceneMediator.textInputService

override suspend fun startInputMethod(request: PlatformTextInputMethodRequest): Nothing {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ import androidx.compose.ui.platform.DefaultInputModeManager
import androidx.compose.ui.platform.FrameRecomposer
import androidx.compose.ui.platform.PlatformArchitectureComponentsOwner
import androidx.compose.ui.platform.PlatformContext
import androidx.compose.ui.platform.PlatformScreenReader
import androidx.compose.ui.platform.PlatformTextInputMethodRequest
import androidx.compose.ui.platform.PlatformWindowContext
import androidx.compose.ui.platform.UIKitIdleTimerManager
Expand All @@ -74,6 +73,11 @@ import androidx.compose.ui.input.pointer.isAltPressed
import androidx.compose.ui.input.pointer.isCtrlPressed
import androidx.compose.ui.input.pointer.isMetaPressed
import androidx.compose.ui.input.pointer.isShiftPressed
import androidx.compose.ui.platform.Clipboard
import androidx.compose.ui.platform.ClipboardManager
import androidx.compose.ui.platform.PlatformAccessibilityManager
import androidx.compose.ui.platform.createPlatformClipboard
import androidx.compose.ui.platform.createPlatformClipboardManager
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.IntRect
Expand All @@ -85,7 +89,6 @@ import androidx.compose.ui.unit.roundToIntRect
import androidx.compose.ui.unit.roundToIntSize
import androidx.compose.ui.unit.toDpOffset
import androidx.compose.ui.unit.toDpRect
import androidx.compose.ui.unit.toDpSize
import androidx.compose.ui.unit.toOffset
import androidx.compose.ui.unit.toSize
import androidx.compose.ui.viewinterop.LocalInteropContainer
Expand All @@ -107,9 +110,6 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.isActive
import kotlinx.coroutines.job
import kotlinx.coroutines.launch
import org.jetbrains.skiko.OS
import org.jetbrains.skiko.OSVersion
import org.jetbrains.skiko.available
import platform.CoreGraphics.CGPoint
import platform.QuartzCore.CACurrentMediaTime
import platform.QuartzCore.CATransaction
Expand Down Expand Up @@ -209,8 +209,17 @@ internal class ComposeSceneMediator(

private var onKeyEvent: (KeyEvent) -> Boolean = { false }
private var animateKeyboardOffsetChanges by mutableStateOf(false)
private var platformScreenReader = object : PlatformScreenReader {
override var isActive by mutableStateOf(false)
private var platformAccessibilityManager = object : PlatformAccessibilityManager {
var isActive by mutableStateOf(false)
override val isScreenReaderActive: Boolean
get() = isActive

override fun calculateRecommendedTimeoutMillis(
originalTimeoutMillis: Long,
containsIcons: Boolean,
containsText: Boolean,
containsControls: Boolean
): Long = originalTimeoutMillis
}

private val coroutineScope = CoroutineScope(coroutineContext)
Expand Down Expand Up @@ -377,7 +386,7 @@ internal class ComposeSceneMediator(

down || up
},
onScreenReaderActive = { platformScreenReader.isActive = it }
onScreenReaderActive = { platformAccessibilityManager.isActive = it }
)
}

Expand Down Expand Up @@ -849,12 +858,21 @@ internal class ComposeSceneMediator(
private inner class PlatformContextImpl : PlatformContext {
override val windowInfo: WindowInfo get() = windowContext.windowInfo
override val architectureComponentsOwner get() = this@ComposeSceneMediator.architectureComponentsOwner
override val screenReader: PlatformScreenReader get() = platformScreenReader

override val accessibilityManager: PlatformAccessibilityManager
get() = platformAccessibilityManager

override val hapticFeedback: HapticFeedback by lazy(LazyThreadSafetyMode.NONE) {
CupertinoHapticFeedback()
}

override val clipboard: Clipboard by lazy(LazyThreadSafetyMode.NONE) {
createPlatformClipboard()
}
override val clipboardManager: ClipboardManager by lazy(LazyThreadSafetyMode.NONE) {
createPlatformClipboardManager()
}

override fun convertLocalToWindowPosition(localPosition: Offset): Offset =
windowContext.convertLocalToWindowPosition(_overlayView, localPosition)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,13 @@ import androidx.compose.ui.input.rotary.RotaryScrollEvent
import androidx.compose.ui.layout.RootMeasurePolicy
import androidx.compose.ui.layout.RulerProviderModifierElement
import androidx.compose.ui.modifier.ModifierLocalManager
import androidx.compose.ui.platform.DefaultAccessibilityManager
import androidx.compose.ui.platform.DelegatingSoftwareKeyboardController
import androidx.compose.ui.platform.PlatformContext
import androidx.compose.ui.platform.PlatformRootForTest
import androidx.compose.ui.platform.PlatformTextInputMethodRequest
import androidx.compose.ui.platform.PlatformTextInputSessionScope
import androidx.compose.ui.platform.PlatformWindowInsets
import androidx.compose.ui.platform.PlatformWindowInsetsProviderNode
import androidx.compose.ui.platform.createPlatformClipboard
import androidx.compose.ui.platform.createPlatformClipboardManager
import androidx.compose.ui.scene.ComposeScene
import androidx.compose.ui.scene.ComposeSceneInputHandler
import androidx.compose.ui.scene.ComposeScenePointer
Expand Down Expand Up @@ -468,21 +465,21 @@ internal class RootNodeOwner(
override val rootForTest get() = this@RootNodeOwner.rootForTest
override val hapticFeedBack get() = platformContext.hapticFeedback
override val inputModeManager get() = platformContext.inputModeManager
override val clipboardManager = createPlatformClipboardManager()
override val clipboard = createPlatformClipboard()
override val accessibilityManager = DefaultAccessibilityManager()
override val clipboardManager get() = platformContext.clipboardManager
override val clipboard get() = platformContext.clipboard
override val accessibilityManager get() = platformContext.accessibilityManager
override val graphicsContext get() = this@RootNodeOwner.graphicsContext
override val textToolbar get() = platformContext.textToolbar

@Suppress("DEPRECATION")
override val autofillTree = androidx.compose.ui.autofill.AutofillTree()
override val autofillTree get() = platformContext.autofillTree

@Suppress("DEPRECATION")
override val autofill: androidx.compose.ui.autofill.Autofill?
get() = null
get() = platformContext.autofill

// TODO https://youtrack.jetbrains.com/issue/CMP-1572
override val autofillManager: AutofillManager? get() = null
override val autofillManager: AutofillManager? get() = platformContext.autofillManager
override val density get() = this@RootNodeOwner.density
override val textInputService by lazy(LazyThreadSafetyMode.NONE) {
TextInputService(platformContext.textInputService)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,6 @@ import androidx.savedstate.compose.LocalSavedStateRegistryOwner
)
actual val LocalLifecycleOwner get() = androidx.lifecycle.compose.LocalLifecycleOwner

/**
* The CompositionLocal that provides information about Screen Reader state associated with
* the current scene.
*/
@InternalComposeUiApi
val LocalPlatformScreenReader = staticCompositionLocalOf<PlatformScreenReader> {
error("CompositionLocal LocalPlatformScreenReader not present")
}

// TODO: Remove as part of https://youtrack.jetbrains.com/issue/CMP-9379
/**
Expand Down Expand Up @@ -91,7 +83,6 @@ internal fun ProvidePlatformCompositionLocals(

CompositionLocalProvider(
*values,
LocalPlatformScreenReader provides platformContext.screenReader,
LocalPlatformWindowInsets provides platformContext.windowInsets,
LocalPlatformPrefetchScheduler provides platformContext.prefetchScheduler,
androidx.lifecycle.compose.LocalLifecycleOwner provides platformContext.architectureComponentsOwner.lifecycleOwner,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2025 The Android Open Source Project
* 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.
Expand All @@ -19,9 +19,9 @@ package androidx.compose.ui.platform
import androidx.compose.ui.InternalComposeUiApi

/**
* Provides information about Screen Reader state
* Provides information about Screen Reader and Accessibility state
*/
@InternalComposeUiApi
interface PlatformScreenReader {
val isActive: Boolean
interface PlatformAccessibilityManager : AccessibilityManager {
val isScreenReaderActive: Boolean
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import androidx.compose.ui.ComposeUiFlags
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.FrameRateCategory
import androidx.compose.ui.InternalComposeUiApi
import androidx.compose.ui.autofill.AutofillManager
import androidx.compose.ui.autofill.AutofillTree
import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.geometry.Offset
Expand Down Expand Up @@ -62,11 +64,6 @@ interface PlatformContext {
*/
val windowInfo: WindowInfo

/**
* The value that will be provided to [LocalPlatformScreenReader] by default.
*/
val screenReader: PlatformScreenReader get() = EmptyPlatformScreenReader

/**
* Provider of platform owners such as [LifecycleOwner] or [ViewModelStoreOwner].
*/
Expand Down Expand Up @@ -217,6 +214,25 @@ interface PlatformContext {
*/
val prefetchScheduler: PlatformPrefetchScheduler get() = NoOpPlatformPrefetchScheduler

val accessibilityManager: PlatformAccessibilityManager get() = NoOpPlatformAccessibilityManager

val clipboard : Clipboard

@Suppress("DEPRECATION")
val clipboardManager : ClipboardManager

@Suppress("DEPRECATION")
val autofillTree : AutofillTree
get() = AutofillTree()

@Suppress("DEPRECATION")
val autofill: androidx.compose.ui.autofill.Autofill?
get() = null

// TODO https://youtrack.jetbrains.com/issue/CMP-1572
Comment thread
ASalavei marked this conversation as resolved.
Outdated
val autofillManager: AutofillManager?
get() = null

interface RootForTestListener {
fun onRootForTestCreated(root: PlatformRootForTest)
fun onRootForTestDisposed(root: PlatformRootForTest)
Expand Down Expand Up @@ -267,6 +283,12 @@ interface PlatformContext {
override val inputModeManager: InputModeManager by lazy(LazyThreadSafetyMode.NONE) {
DefaultInputModeManager()
}
override val clipboard: Clipboard by lazy(LazyThreadSafetyMode.NONE) {
createPlatformClipboard()
}
override val clipboardManager: ClipboardManager by lazy(LazyThreadSafetyMode.NONE) {
createPlatformClipboardManager()
}
}

// This object must be immutable because it is used as a delegate in other ViewConfiguration
Expand All @@ -288,8 +310,16 @@ interface PlatformContext {
}
}

private object EmptyPlatformScreenReader : PlatformScreenReader {
override val isActive: Boolean = false
private object NoOpPlatformAccessibilityManager : PlatformAccessibilityManager {
override fun calculateRecommendedTimeoutMillis(
originalTimeoutMillis: Long,
containsIcons: Boolean,
containsText: Boolean,
containsControls: Boolean
): Long = originalTimeoutMillis

override val isScreenReaderActive: Boolean
get() = false
}

private object NoOpPlatformPrefetchScheduler : PlatformPrefetchScheduler {
Expand Down