SpatialMainPanel

Functions summary

Unit
@Composable
@SubspaceComposable
SpatialMainPanel(
    modifier: SubspaceModifier,
    shape: SpatialShape,
    dragPolicy: DragPolicy?,
    resizePolicy: ResizePolicy?,
    interactionPolicy: InteractionPolicy?
)

A composable that renders the Activity's main window's 2D UI content, defined in androidx.activity.compose.setContent, as a panel in a Subspace.

Functions

SpatialMainPanel

@Composable
@SubspaceComposable
fun SpatialMainPanel(
    modifier: SubspaceModifier = SubspaceModifier,
    shape: SpatialShape = SpatialPanelDefaults.shape,
    dragPolicy: DragPolicy? = null,
    resizePolicy: ResizePolicy? = null,
    interactionPolicy: InteractionPolicy? = null
): Unit

A composable that renders the Activity's main window's 2D UI content, defined in androidx.activity.compose.setContent, as a panel in a Subspace.

This composable acts as the bridge between the traditional 2D Android UI hierarchy and the 3D Subspace environment. Unlike SpatialPanel, which renders its own specific composable content, SpatialMainPanel takes the entire view hierarchy from the Activity's main window and presents it on a movable, resizable panel in the Compose for XR's Spatial Scene Graph.

For the main window to be visible when androidx.xr.compose.spatial.Subspace is present in the UI hierarchy, a SpatialMainPanel must be included in the Subspace composition. If it is not composed, the underlying main panel entity is disabled by default. When SpatialMainPanel is removed from the composition, it will again be disable (hidden).

How It Works

SpatialMainPanel is backed by a single shared instance that will move to the main content to its active usage. When the main content panel moves inside the composition, its state moves with it regardless of whether it is in a androidx.compose.runtime.MovableContent block or not. Components that depend on the main panel's state (such as androidx.xr.compose.spatial.Orbiter), will always access a single deterministic instance of the panel.

Only the first SpatialMainPanel added to the composition will be granted ownership of the main panel at any point in time. Subsequent instances of SpatialMainPanel will be queued to be shown, but will not be granted ownership of the main panel until the first instance is removed from composition. If the original owner is removed from and added back to composition, it will be added to the back of the queue.

The size of the panel in the Subspace is controlled by the standard Compose layout system, driven by the SubspaceModifier applied to it. Modifiers like SubspaceModifier.width directly dictate the panel's dimensions, following the same measurement and layout rules as other SubspaceComposable. To ensure stability, if the panel's layout size results in a width or height of zero, it will be automatically disabled to prevent crashes.

Manifest Configuration

This panel requires the following specific configuration in the AndroidManifest.xml on the base activity for proper sizing and resizing behavior. Without it, resizing the main panel will

cause a crash.

<activity android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize">
...
</activity>
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.xr.compose.spatial.Subspace
import androidx.xr.compose.subspace.SpatialMainPanel
import androidx.xr.compose.subspace.SpatialPanel
import androidx.xr.compose.subspace.SpatialRow

@Composable
fun MainPanelContent() {
    Text("Main panel")
}

@Composable
fun AppContent() {
    // 2D Content rendered to the main panel.
    MainPanelContent()

    // Spatial content rendered in full space mode.
    Subspace {
        SpatialRow {
            SpatialPanel { Text("Spatial panel") }
            SpatialMainPanel()
        }
    }
}
Parameters
modifier: SubspaceModifier = SubspaceModifier

The SubspaceModifier to be applied to this panel, controlling its layout, size, and position within the parent.

shape: SpatialShape = SpatialPanelDefaults.shape

The shape of this Spatial Panel.

dragPolicy: DragPolicy? = null

An optional DragPolicy that defines the motion behavior of the SpatialPanel. This can be either a MovePolicy for free movement or an AnchorPolicy for anchoring to real-world surfaces. If a policy is provided, draggable UI controls will be shown, allowing the user to manipulate the panel in 3D space. If null, no motion behavior is applied.

resizePolicy: ResizePolicy? = null

An optional ResizePolicy configuration object that resizing behavior of this SpatialPanel. The draggable UI controls will be shown that allow the user to resize the element in 3D space. If null, there is no resize behavior applied to the element.

interactionPolicy: InteractionPolicy? = null

An optional InteractionPolicy that can be set to detect 3D input events. Setting this will not intercept 2D input events and is intended to provide additional spatial input information.