From c66eebc2c23a8b41eb618c715296c2a7dd135f43 Mon Sep 17 00:00:00 2001 From: Ivan Matkov Date: Tue, 28 May 2024 19:39:01 +0200 Subject: [PATCH] Redraw immediately on panel size change (#923) Fixes a couple of issues like: https://github.com/JetBrains/compose-multiplatform/issues/4744 (TODO: collect all references) Before (slow-mo) https://github.com/JetBrains/skiko/assets/1836384/5768b139-d08f-4142-8c14-2969107807f9 After (slow-mo) https://github.com/JetBrains/skiko/assets/1836384/cc9a5103-3d30-412e-a5a4-baf590d657b8 --- .../org/jetbrains/skiko/SkiaLayer.awt.kt | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt index 8720ee486..80bbf59ea 100644 --- a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt +++ b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/SkiaLayer.awt.kt @@ -229,8 +229,6 @@ actual open class SkiaLayer internal constructor( jComponent.add(this) } - private var keyEvent: KeyEvent? = null - val clipComponents = mutableListOf() @Volatile @@ -312,13 +310,32 @@ actual open class SkiaLayer internal constructor( override fun paint(g: java.awt.Graphics) { Logger.debug { "Paint called on: $this" } checkContentScale() + tryRedrawImmediately() + } + + override fun setBounds(x: Int, y: Int, width: Int, height: Int) { + super.setBounds(x, y, width, height) + + // 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) { + redrawer?.syncSize() + tryRedrawImmediately() + } + } - // `paint` can be called when we already inside `draw` method. + private fun tryRedrawImmediately() { + if (!isShowing) return + + // It might be called inside `renderDelegate`, + // so to avoid recursive call (not supported) just schedule redrawing. // // For example if we call some AWT function inside renderer.onRender, // such as `jframe.isEnabled = false` on Linux - // - // To avoid recursive call of `draw` (we don't support recursive calls) we just schedule redrawing. if (isRendering) { redrawer?.needRedraw() } else {