Unverified Commit 555dcff9 authored by Alexander Maryanovsky's avatar Alexander Maryanovsky Committed by GitHub

Avoid calling SkiaLayer.revalidate() when the window itself is moved. (#1010)

parent 0e039620
......@@ -8,6 +8,7 @@ import org.jetbrains.skiko.redrawer.Redrawer
import org.jetbrains.skiko.redrawer.RedrawerManager
import java.awt.Color
import java.awt.Component
import java.awt.Point
import java.awt.event.*
import java.awt.geom.AffineTransform
import java.awt.im.InputMethodRequests
......@@ -20,7 +21,6 @@ import javax.swing.SwingUtilities.isEventDispatchThread
import javax.swing.UIManager
import javax.swing.event.AncestorEvent
import javax.swing.event.AncestorListener
import kotlin.math.ceil
import kotlin.math.floor
actual open class SkiaLayer internal constructor(
......@@ -138,12 +138,34 @@ actual open class SkiaLayer internal constructor(
add(backedLayer)
addAncestorListener(object : AncestorListener {
override fun ancestorAdded(event: AncestorEvent?) = Unit
override fun ancestorRemoved(event: AncestorEvent?) = Unit
private var positionInWindow: Point? = null
private val zeroPoint = Point(0, 0)
private fun computePositionInWindow(): Point? {
val window = SwingUtilities.getWindowAncestor(this@SkiaLayer)
return if (window == null) {
null
} else {
SwingUtilities.convertPoint(this@SkiaLayer, zeroPoint, window)
}
}
override fun ancestorAdded(event: AncestorEvent?) {
positionInWindow = computePositionInWindow()
}
override fun ancestorRemoved(event: AncestorEvent?) {
positionInWindow = null
}
override fun ancestorMoved(event: AncestorEvent?) {
revalidate()
val newPosition = computePositionInWindow()
if ((positionInWindow != null) && (positionInWindow != newPosition)) {
revalidate()
}
positionInWindow = newPosition
}
})
......@@ -190,7 +212,6 @@ actual open class SkiaLayer internal constructor(
init(isInited)
}
actual fun detach() {
dispose()
}
......
package org.jetbrains.skiko
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.yield
import kotlinx.coroutines.*
import org.jetbrains.skia.*
import org.jetbrains.skia.Canvas
import org.jetbrains.skia.FontMgr
import org.jetbrains.skia.Paint
import org.jetbrains.skia.Rect
import org.jetbrains.skia.paragraph.FontCollection
import org.jetbrains.skia.paragraph.ParagraphBuilder
import org.jetbrains.skia.paragraph.ParagraphStyle
......@@ -24,9 +20,8 @@ import org.junit.Assume.assumeTrue
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import java.awt.BorderLayout
import java.awt.*
import java.awt.Color
import java.awt.Dimension
import java.awt.event.*
import javax.swing.Box
import javax.swing.JFrame
......@@ -941,6 +936,37 @@ class SkiaLayerTest {
}
}
@Test
fun `content not relaid out on window move`() = uiTest {
var layoutCount = 0
val window = UiTestWindow {
contentPane.layout = object: BorderLayout() {
override fun layoutContainer(parent: Container?) {
super.layoutContainer(parent)
layoutCount++
}
}
contentPane.add(layer)
}
window.size = Dimension(400, 400)
window.isVisible = true
repeat(20) {
window.location = window.location.let {
java.awt.Point(it.x + 10, it.y + 10)
}
delay(50)
}
// Ideally, layoutCount would be just 1, but Swing appears to call layout one extra time, so it ends up being 2.
// Compare to 3 just to avoid a false-failure if there's another layout for whatever reason.
// What we're interested to validate is that there's no layout occurring on every window move.
assert(layoutCount <= 3) {
"Layout count: $layoutCount"
}
}
private class RectRenderer(
private val layer: SkiaLayer,
var rectWidth: Int,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment