Skip to content

Commit

Permalink
Fix bounds of ComposePanel in IntelliJ on macOs
Browse files Browse the repository at this point in the history
Fixes https://youtrack.jetbrains.com/issue/CMP-5856/Desktop-ComposePanel-size-breaks-with-.fillMax-modifiers#focus=Comments-27-10632441.0-0

Fixes https://youtrack.jetbrains.com/issue/CMP-5968/Compose-content-is-rendered-in-the-wrong-place-in-IJ-when-using-AWT-compositing

Regression after https://github.com/JetBrains/skiko/pull/661/files#diff-910a6e28fda20a00bc98c6a8a04f74ab701d79e841b9baddf146b810e610572fR363

When a panel changes its bounds, `doLayout` isn't called because the content itself wasn't changed. But we still need to update the bounds of the underlying layer.

Docs:
```
> doLayout
Causes this container to lay out its components

>
```

## Testing
https://youtrack.jetbrains.com/issue/CMP-5856/Desktop-ComposePanel-size-breaks-with-.fillMax-modifiers#focus=Comments-27-10632441.0-0 isn't reproducible after the fix

## Release Notes
### Fixes
- Fix bounds of ComposePanel in IntelliJ
  • Loading branch information
igordmn committed Sep 16, 2024
1 parent e2bf12b commit 4ea6aab
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 11 deletions.
12 changes: 8 additions & 4 deletions skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ actual open class SkiaLayer internal constructor(
addPropertyChangeListener("graphicsContextScaleTransform") {
Logger.debug { "graphicsContextScaleTransform changed for $this" }
latestReceivedGraphicsContextScaleTransform = it.newValue as AffineTransform
redrawer?.syncSize()
redrawer?.syncBounds()
notifyChange(PropertyKind.ContentScale)

// Workaround for JBR-5259
Expand Down Expand Up @@ -191,7 +191,7 @@ actual open class SkiaLayer internal constructor(
redrawer?.setVisible(isShowing)
}
if (isShowing) {
redrawer?.syncSize()
redrawer?.syncBounds()
repaint()
}
}
Expand Down Expand Up @@ -252,7 +252,7 @@ actual open class SkiaLayer internal constructor(
private val redrawerManager = RedrawerManager<Redrawer>(properties.renderApi) { renderApi, oldRedrawer ->
oldRedrawer?.dispose()
val newRedrawer = renderFactory.createRedrawer(this, renderApi, analytics, properties)
newRedrawer.syncSize()
newRedrawer.syncBounds()
newRedrawer
}

Expand Down Expand Up @@ -331,14 +331,18 @@ actual open class SkiaLayer internal constructor(
override fun setBounds(x: Int, y: Int, width: Int, height: Int) {
super.setBounds(x, y, width, height)

Logger.debug { "setBounds on $this" }
backedLayer.setBounds(0, 0, roundSize(width), roundSize(height))
backedLayer.validate()
redrawer?.syncBounds()

// To avoid visual artifacts on Windows/Direct3D,
// redrawing should be performed immediately, without scheduling to "later".
// Subscribing to events instead of overriding this method won't help too.
//
// Please note that calling redraw during layout might break software renderers,
// so applying this fix only for Direct3D case.
if (renderApi == GraphicsApi.DIRECT3D && isShowing) {
redrawer?.syncSize()
tryRedrawImmediately()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ internal class MetalRedrawer(
}
}

override fun syncSize() = synchronized(drawLock) {
override fun syncBounds() = synchronized(drawLock) {
check(isEventDispatchThread()) { "Method should be called from AWT event dispatch thread" }
val rootPane = getRootPane(layer)
val globalPosition = convertPoint(layer.backedLayer, 0, 0, rootPane)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ internal interface Redrawer {
fun dispose()
fun needRedraw()
fun redrawImmediately()
fun syncSize() = Unit
fun syncBounds() = Unit
fun setVisible(isVisible: Boolean) = Unit
val renderInfo: String
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ actual open class SkiaLayer {
private val nsViewObserver = object : NSObject() {
@ObjCAction
fun frameDidChange(notification: NSNotification) {
redrawer?.syncSize()
redrawer?.syncBounds()
redrawer?.redrawImmediately()
}

@ObjCAction
fun windowDidChangeBackingProperties(notification: NSNotification) {
redrawer?.syncSize()
redrawer?.syncBounds()
redrawer?.redrawImmediately()
}

Expand Down Expand Up @@ -126,7 +126,7 @@ actual open class SkiaLayer {
nsView.postsFrameChangedNotifications = true
nsViewObserver.addObserver()
redrawer = createNativeRedrawer(this, renderApi).apply {
syncSize()
syncBounds()
needRedraw()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ internal class MacOsMetalRedrawer(
/**
* Synchronizes the [metalLayer] size with the size of underlying nsView
*/
override fun syncSize() {
override fun syncBounds() {
syncContentScale()
val osFrame = skiaLayer.nsView.frame
val (w, h) = osFrame.useContents {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ internal class MacOsOpenGLRedrawer(
glLayer.dispose()
}

override fun syncSize() {
override fun syncBounds() {
syncContentScale()
skiaLayer.nsView.frame.useContents {
glLayer.setFrame(
Expand Down

0 comments on commit 4ea6aab

Please sign in to comment.