Skip to content

Commit dc2a7ab

Browse files
committed
Handle split screens
1 parent 547fc3a commit dc2a7ab

2 files changed

Lines changed: 37 additions & 17 deletions

File tree

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/runtime/ReactSurfaceView.kt

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import android.graphics.Rect
1515
import android.view.KeyEvent
1616
import android.view.MotionEvent
1717
import android.view.View
18+
import androidx.core.view.ViewCompat
19+
import androidx.core.view.WindowInsetsCompat
1820
import com.facebook.common.logging.FLog
1921
import com.facebook.react.ReactRootView
2022
import com.facebook.react.bridge.ReactContext
@@ -48,19 +50,31 @@ public class ReactSurfaceView(context: Context?, internal val surface: ReactSurf
4850

4951
private val viewportOffset: Point
5052
get() {
51-
val locationInWindow = IntArray(2)
52-
getLocationInWindow(locationInWindow)
53+
val locationOnScreen = IntArray(2)
54+
getLocationOnScreen(locationOnScreen)
5355

54-
if (!isEdgeToEdgeFeatureFlagOn) {
55-
// When not in edge-to-edge mode, subtract the visible window frame to get the offset
56-
// relative to the content area (below the status bar).
57-
val visibleWindowFrame = Rect()
58-
getWindowVisibleDisplayFrame(visibleWindowFrame)
59-
locationInWindow[0] -= visibleWindowFrame.left
60-
locationInWindow[1] -= visibleWindowFrame.top
56+
// we need to subtract visibleWindowCoords - to subtract possible window insets, split
57+
// screen or multi window
58+
val visibleWindowFrame = Rect()
59+
getWindowVisibleDisplayFrame(visibleWindowFrame)
60+
locationOnScreen[0] -= visibleWindowFrame.left
61+
locationOnScreen[1] -= visibleWindowFrame.top
62+
63+
if (isEdgeToEdgeFeatureFlagOn) {
64+
// In edge-to-edge mode the viewport spans the full window, so add the top system bar
65+
// insets back to convert the content-area offset above into a window-relative offset.
66+
ViewCompat.getRootWindowInsets(this)?.apply {
67+
val insets =
68+
getInsets(
69+
WindowInsetsCompat.Type.statusBars() or WindowInsetsCompat.Type.displayCutout()
70+
)
71+
72+
locationOnScreen[0] += insets.left
73+
locationOnScreen[1] += insets.top
74+
}
6175
}
6276

63-
return Point(locationInWindow[0], locationInWindow[1])
77+
return Point(locationOnScreen[0], locationOnScreen[1])
6478
}
6579

6680
init {

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/uimanager/RootViewUtil.kt

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@
88
package com.facebook.react.uimanager
99

1010
import android.graphics.Point
11-
import android.graphics.Rect
1211
import android.view.View
1312
import androidx.annotation.UiThread
13+
import androidx.core.view.ViewCompat
14+
import androidx.core.view.WindowInsetsCompat
1415
import com.facebook.infer.annotation.Assertions
1516
import com.facebook.react.views.view.isEdgeToEdgeFeatureFlagOn
1617

@@ -36,12 +37,17 @@ public object RootViewUtil {
3637
v.getLocationInWindow(locationInWindow)
3738

3839
if (!isEdgeToEdgeFeatureFlagOn) {
39-
// When not in edge-to-edge mode, subtract the visible window frame to get the offset
40-
// relative to the content area (below the status bar).
41-
val visibleWindowFrame = Rect()
42-
v.getWindowVisibleDisplayFrame(visibleWindowFrame)
43-
locationInWindow[0] -= visibleWindowFrame.left
44-
locationInWindow[1] -= visibleWindowFrame.top
40+
// When not in edge-to-edge mode, subtract the top system bar insets so the offset is
41+
// relative to the content area (below the status bar / cutout).
42+
ViewCompat.getRootWindowInsets(v)?.apply {
43+
val insets =
44+
getInsets(
45+
WindowInsetsCompat.Type.statusBars() or WindowInsetsCompat.Type.displayCutout()
46+
)
47+
48+
locationInWindow[0] -= insets.left
49+
locationInWindow[1] -= insets.top
50+
}
4551
}
4652

4753
return Point(locationInWindow[0], locationInWindow[1])

0 commit comments

Comments
 (0)