Skip to content

Commit 9ea8218

Browse files
committed
CMP-9264 Expose showLayoutBounds API on ComposePanel
This exposes a showLayoutBounds property on ComposePanel (desktop only) that allows users to turn on or off the showLayoutBounds property on the root layout node owner(s). The change mostly pipes the property up to the ComposePanel, but has no public API impact. The new property is also annotated as experimental. The Skiko RootNodeOwner's showLayoutBounds is now also a state, to cause a full recomposition when the value changes and see it reflected in the UI.
1 parent 4c05dc6 commit 9ea8218

File tree

11 files changed

+85
-5
lines changed

11 files changed

+85
-5
lines changed

compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeDialog.desktop.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package androidx.compose.ui.awt
1818
import androidx.compose.runtime.Composable
1919
import androidx.compose.runtime.CompositionLocalContext
2020
import androidx.compose.ui.ExperimentalComposeUiApi
21+
import androidx.compose.ui.InternalComposeUiApi
2122
import androidx.compose.ui.Modifier
2223
import androidx.compose.ui.input.key.KeyEvent
2324
import androidx.compose.ui.layout.layoutId
@@ -341,4 +342,16 @@ class ComposeDialog : JDialog {
341342

342343
override fun removeMouseWheelListener(listener: MouseWheelListener) =
343344
composePanel.removeMouseWheelListener(listener)
345+
346+
/**
347+
* Set the visual debug option that shows bounds for all nodes in the hierarchy.
348+
*/
349+
@InternalComposeUiApi
350+
var showLayoutBounds: Boolean
351+
get() {
352+
return composePanel.showLayoutBounds
353+
}
354+
set(value) {
355+
composePanel.showLayoutBounds = value
356+
}
344357
}

compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@ package androidx.compose.ui.awt
1919
import androidx.compose.runtime.Composable
2020
import androidx.compose.ui.ComposeFeatureFlags
2121
import androidx.compose.ui.ExperimentalComposeUiApi
22+
import androidx.compose.ui.InternalComposeUiApi
2223
import androidx.compose.ui.LayerType
2324
import androidx.compose.ui.awt.RenderSettings.SkiaSurface
2425
import androidx.compose.ui.awt.RenderSettings.SwingGraphics
2526
import androidx.compose.ui.focus.FocusDirection
27+
import androidx.compose.ui.node.InternalCoreApi
2628
import androidx.compose.ui.scene.ComposeContainer
2729
import androidx.compose.ui.semantics.SemanticsOwner
2830
import androidx.compose.ui.window.WindowExceptionHandler
@@ -171,7 +173,7 @@ class ComposePanel @ExperimentalComposeUiApi constructor(
171173

172174
override fun getPreferredSize(): Dimension? = if (isPreferredSizeSet) {
173175
super.getPreferredSize()
174-
} else {
176+
} else {
175177
_composeContainer?.preferredSize ?: Dimension(0, 0)
176178
}
177179

@@ -240,6 +242,8 @@ class ComposePanel @ExperimentalComposeUiApi constructor(
240242
// content.
241243
val composeContainer = _composeContainer ?: createComposeContainer().also {
242244
_composeContainer = it
245+
@OptIn(InternalCoreApi::class)
246+
it.showLayoutBounds = showLayoutBounds
243247
val composeContent = _composeContent
244248
if (composeContent != null) {
245249
it.setContent(composeContent)
@@ -272,6 +276,7 @@ class ComposePanel @ExperimentalComposeUiApi constructor(
272276
focusManager.takeFocus(FocusDirection.Next)
273277
}
274278
}
279+
275280
else -> Unit
276281
}
277282
}
@@ -378,4 +383,17 @@ class ComposePanel @ExperimentalComposeUiApi constructor(
378383
fun renderImmediately() {
379384
_composeContainer?.renderImmediately()
380385
}
386+
387+
/**
388+
* Set the visual debug option that shows bounds for all nodes in the hierarchy.
389+
*/
390+
@InternalComposeUiApi
391+
var showLayoutBounds: Boolean = _composeContainer?.showLayoutBounds ?: false
392+
set(value) {
393+
// We're assuming we own the scene and thus this value, and nobody
394+
// else will change it from under us, so we never get out of sync.
395+
field = value
396+
@OptIn(InternalCoreApi::class)
397+
_composeContainer?.showLayoutBounds = value
398+
}
381399
}

compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindow.desktop.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package androidx.compose.ui.awt
1818
import androidx.compose.runtime.Composable
1919
import androidx.compose.runtime.CompositionLocalContext
2020
import androidx.compose.ui.ExperimentalComposeUiApi
21+
import androidx.compose.ui.InternalComposeUiApi
2122
import androidx.compose.ui.Modifier
2223
import androidx.compose.ui.input.key.KeyEvent
2324
import androidx.compose.ui.layout.layoutId
@@ -327,4 +328,16 @@ class ComposeWindow @ExperimentalComposeUiApi constructor(
327328

328329
override fun removeMouseWheelListener(listener: MouseWheelListener) =
329330
composePanel.removeMouseWheelListener(listener)
331+
332+
/**
333+
* Set the visual debug option that shows bounds for all nodes in the hierarchy.
334+
*/
335+
@InternalComposeUiApi
336+
var showLayoutBounds: Boolean
337+
get() {
338+
return composePanel.showLayoutBounds
339+
}
340+
set(value) {
341+
composePanel.showLayoutBounds = value
342+
}
330343
}

compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposeWindowPanel.desktop.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,12 @@ internal class ComposeWindowPanel(
190190
override fun removeMouseMotionListener(listener: MouseMotionListener) {
191191
contentComponent.removeMouseMotionListener(listener)
192192
}
193+
194+
var showLayoutBounds: Boolean
195+
get() {
196+
return _composeContainer?.showLayoutBounds ?: false
197+
}
198+
set(value) {
199+
_composeContainer?.showLayoutBounds = value
200+
}
193201
}

compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/scene/ComposeContainer.desktop.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ internal class ComposeContainer(
176176
val preferredSize by mediator::preferredSize
177177
val semanticsOwners by mediator::semanticsOwners
178178

179+
var showLayoutBounds by mediator::showLayoutBounds
180+
179181
private var isDisposed = false
180182
private var isDetached = true
181183
private var isMinimized = false

compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/scene/ComposeSceneMediator.desktop.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,12 @@ internal class ComposeSceneMediator(
323323
var compositionLocalContext: CompositionLocalContext?
324324
get() = scene.compositionLocalContext
325325
set(value) { scene.compositionLocalContext = value }
326+
var showLayoutBounds: Boolean
327+
get() = scene.showLayoutBounds
328+
set(value) {
329+
scene.showLayoutBounds = value
330+
}
331+
326332

327333
/**
328334
* Provides the size of ComposeScene content inside infinity constraints

compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/node/RootNodeOwner.skiko.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ internal class RootNodeOwner(
498498
override val fontLoader = androidx.compose.ui.text.platform.FontLoader()
499499
override val fontFamilyResolver = createFontFamilyResolver()
500500
override val layoutDirection get() = _layoutDirection
501-
override var showLayoutBounds = false
501+
override var showLayoutBounds by mutableStateOf(false)
502502
@InternalCoreApi
503503
set
504504

compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/BaseComposeScene.skiko.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import androidx.compose.runtime.Composable
2121
import androidx.compose.runtime.Composition
2222
import androidx.compose.runtime.CompositionContext
2323
import androidx.compose.runtime.CompositionLocalContext
24-
import androidx.compose.runtime.CompositionLocalProvider
2524
import androidx.compose.runtime.MonotonicFrameClock
2625
import androidx.compose.runtime.getValue
2726
import androidx.compose.runtime.mutableStateOf
@@ -40,8 +39,6 @@ import androidx.compose.ui.input.pointer.PointerType
4039
import androidx.compose.ui.input.rotary.RotaryScrollEvent
4140
import androidx.compose.ui.node.SnapshotInvalidationTracker
4241
import androidx.compose.ui.platform.GlobalSnapshotManager
43-
import androidx.compose.ui.platform.LocalPlatformScreenReader
44-
import androidx.compose.ui.platform.LocalPlatformWindowInsets
4542
import androidx.compose.ui.platform.ProvidePlatformCompositionLocals
4643
import androidx.compose.ui.util.trace
4744
import kotlin.concurrent.Volatile

compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/CanvasLayersComposeScene.skiko.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import androidx.compose.ui.input.pointer.PointerEventType
3838
import androidx.compose.ui.input.pointer.PointerInputEvent
3939
import androidx.compose.ui.input.pointer.PointerType
4040
import androidx.compose.ui.input.rotary.RotaryScrollEvent
41+
import androidx.compose.ui.node.InternalCoreApi
4142
import androidx.compose.ui.node.RootNodeOwner
4243
import androidx.compose.ui.platform.PlatformContext
4344
import androidx.compose.ui.platform.setContent
@@ -273,6 +274,13 @@ private class CanvasLayersComposeSceneImpl(
273274
forEachOwner { it.draw(canvas) }
274275
}
275276

277+
override var showLayoutBounds: Boolean = false
278+
@OptIn(InternalCoreApi::class)
279+
set(value) {
280+
field = value
281+
forEachOwner { it.owner.showLayoutBounds = value }
282+
}
283+
276284
/**
277285
* Find hovered owner for position of first pointer.
278286
*/
@@ -560,6 +568,8 @@ private class CanvasLayersComposeSceneImpl(
560568
private var onKeyEvent: ((KeyEvent) -> Boolean)? = null
561569

562570
init {
571+
@OptIn(InternalCoreApi::class)
572+
owner.owner.showLayoutBounds = showLayoutBounds
563573
attachLayer(this)
564574
}
565575

compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeScene.skiko.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,4 +284,9 @@ sealed interface ComposeScene : AutoCloseable {
284284
* provided by the [androidx.compose.runtime.Recomposer] of the current scene.
285285
*/
286286
suspend fun withMonotonicFrameClock(block: suspend () -> Unit)
287+
288+
/**
289+
* Set the visual debug option that shows bounds for all nodes in the hierarchy.
290+
*/
291+
var showLayoutBounds: Boolean
287292
}

0 commit comments

Comments
 (0)