Skip to content

Commit

Permalink
fix issue with iOS boundsInWindow incorrect size (#1093)
Browse files Browse the repository at this point in the history
  • Loading branch information
dima-avdeev-jb committed Feb 12, 2024
1 parent 29bdcb7 commit 0ab187d
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ interface ComposeScene {
* The size is used to impose constraints on the content. If the size is undefined, it can be
* set to `null`. In such a case, the content will be laid out without any restrictions and
* the window size will be utilized to bounds verification.
*
* TODO split boundsInWindow and size https://youtrack.jetbrains.com/issue/COMPOSE-964
*/
var boundsInWindow: IntRect?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@
package androidx.compose.ui.platform

import androidx.compose.ui.input.pointer.PointerKeyboardModifiers
import androidx.compose.ui.toDpOffset
import androidx.compose.ui.uikit.systemDensity
import androidx.compose.ui.toDpRect
import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.roundToIntRect
import androidx.compose.ui.unit.round
import androidx.compose.ui.unit.toOffset
import kotlinx.cinterop.cValue
import kotlinx.cinterop.useContents
import platform.UIKit.UIView

Expand Down Expand Up @@ -57,25 +59,23 @@ internal class PlatformWindowContext {
}

/**
* Calculates the bounds of the given [container] within the window.
* Calculates the offset of the given [container] within the window.
* It uses [_windowContainer] as a reference for window coordinate space.
*
* @param container The container component whose bounds need to be calculated.
* @return The bounds of the container within the window as an [IntRect] object.
* @param container The container component whose offset needs to be calculated.
* @return The offset of the container within the window as an [IntOffset] object.
*/
fun boundsInWindow(container: UIView): IntRect {
fun offsetInWindow(container: UIView): IntOffset {
val density = container.systemDensity
return if (_windowContainer != null && _windowContainer != container) {
container.convertRect(
rect = container.bounds,
container.convertPoint(
point = cValue { container.bounds.useContents { origin } },
toView = _windowContainer,
)
} else {
container.bounds
cValue { container.bounds.useContents { origin } }
}.useContents {
with(density) {
toDpRect().toRect().roundToIntRect()
}
toDpOffset().toOffset(density).round()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import androidx.compose.ui.uikit.LocalKeyboardOverlapHeight
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.DpRect
import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.round
import androidx.compose.ui.unit.roundToIntRect
Expand Down Expand Up @@ -107,7 +108,7 @@ private class SemanticsOwnerListenerImpl(
private val container: UIView,
private val coroutineContext: CoroutineContext,
private val getAccessibilitySyncOptions: () -> AccessibilitySyncOptions
): PlatformContext.SemanticsOwnerListener {
) : PlatformContext.SemanticsOwnerListener {
var current: Pair<SemanticsOwner, AccessibilityMediator>? = null

override fun onSemanticsOwnerAppended(semanticsOwner: SemanticsOwner) {
Expand Down Expand Up @@ -143,7 +144,7 @@ private class RenderingUIViewDelegateImpl(
private val interopContext: UIKitInteropContext,
private val getBoundsInPx: () -> IntRect,
private val scene: ComposeScene
): RenderingUIView.Delegate {
) : RenderingUIView.Delegate {
override fun retrieveInteropTransaction(): UIKitInteropTransaction =
interopContext.retrieve()

Expand All @@ -158,7 +159,7 @@ private class RenderingUIViewDelegateImpl(

private class NativeKeyboardVisibilityListener(
private val keyboardVisibilityListener: KeyboardVisibilityListenerImpl
): NSObject() {
) : NSObject() {
@Suppress("unused")
@ObjCAction
fun keyboardWillShow(arg: NSNotification) {
Expand All @@ -172,7 +173,7 @@ private class NativeKeyboardVisibilityListener(
}
}

private class ComposeSceneMediatorRootUIView: UIView(CGRectZero.readValue()) {
private class ComposeSceneMediatorRootUIView : UIView(CGRectZero.readValue()) {
override fun hitTest(point: CValue<CGPoint>, withEvent: UIEvent?): UIView? {
// forwards touches forward to the children, is never a target for a touch
val result = super.hitTest(point, withEvent)
Expand Down Expand Up @@ -498,8 +499,21 @@ internal class ComposeSceneMediator(
//TODO: Current code updates layout based on rootViewController size.
// Maybe we need to rewrite it for SingleLayerComposeScene.

val boundsInWindow = windowContext.boundsInWindow(container)
val offsetInWindow = windowContext.offsetInWindow(container)
val size = container.bounds.useContents {
with(density) {
toDpRect().toRect().roundToIntRect()
}
}
val boundsInWindow = IntRect(
offset = offsetInWindow,
size = IntSize(
width = size.width,
height = size.height,
)
)
scene.density = density // TODO: Maybe it is wrong to set density to scene here?
// TODO: it should be updated on any container bounds change: resize or move itself or any parent
scene.boundsInWindow = boundsInWindow
onComposeSceneInvalidate()
}
Expand Down

0 comments on commit 0ab187d

Please sign in to comment.