Unverified Commit bb735606 authored by Igor Demin's avatar Igor Demin Committed by GitHub

Merge pull request #81 from JetBrains/fix_dialog_bugs

Fix dialog bugs
parents bc43ce21 d5dc4fc5
...@@ -2,9 +2,8 @@ package org.jetbrains.skiko ...@@ -2,9 +2,8 @@ package org.jetbrains.skiko
import java.awt.Canvas import java.awt.Canvas
import java.awt.Graphics import java.awt.Graphics
import java.awt.event.HierarchyEvent
abstract class HardwareLayer : Canvas() { internal open class HardwareLayer : Canvas() {
companion object { companion object {
init { init {
Library.load() Library.load()
...@@ -14,17 +13,17 @@ abstract class HardwareLayer : Canvas() { ...@@ -14,17 +13,17 @@ abstract class HardwareLayer : Canvas() {
// getDpiScale is expensive operation on some platforms, so we cache it // getDpiScale is expensive operation on some platforms, so we cache it
private var _contentScale: Float? = null private var _contentScale: Float? = null
internal fun defineContentScale() { fun defineContentScale() {
_contentScale = getDpiScale() _contentScale = getDpiScale()
} }
override fun paint(g: Graphics) {} override fun paint(g: Graphics) {}
internal open fun init() { open fun init() {
useDrawingSurfacePlatformInfo(::nativeInit) useDrawingSurfacePlatformInfo(::nativeInit)
} }
internal fun dispose() { fun dispose() {
nativeDispose() nativeDispose()
} }
...@@ -32,7 +31,7 @@ abstract class HardwareLayer : Canvas() { ...@@ -32,7 +31,7 @@ abstract class HardwareLayer : Canvas() {
private external fun nativeDispose() private external fun nativeDispose()
// TODO checkContentScale is called before init. it is ok, but when we fix getDpiScale on Linux we should check [isInit] // TODO checkContentScale is called before init. it is ok, but when we fix getDpiScale on Linux we should check [isInit]
internal fun checkContentScale(): Boolean { fun checkContentScale(): Boolean {
val contentScale = getDpiScale() val contentScale = getDpiScale()
if (contentScale != _contentScale) { if (contentScale != _contentScale) {
_contentScale = contentScale _contentScale = contentScale
......
package org.jetbrains.skiko package org.jetbrains.skiko
import org.jetbrains.skija.Canvas import org.jetbrains.skija.*
import org.jetbrains.skija.ClipMode
import org.jetbrains.skija.Picture
import org.jetbrains.skija.PictureRecorder
import org.jetbrains.skija.Rect
import org.jetbrains.skiko.context.ContextHandler import org.jetbrains.skiko.context.ContextHandler
import org.jetbrains.skiko.context.createContextHandler import org.jetbrains.skiko.context.createContextHandler
import org.jetbrains.skiko.redrawer.Redrawer import org.jetbrains.skiko.redrawer.Redrawer
import java.awt.event.InputMethodListener
import java.awt.event.KeyListener
import java.awt.event.MouseListener
import java.awt.event.MouseMotionListener
import java.awt.event.MouseWheelListener
import java.awt.Graphics import java.awt.Graphics
import java.awt.event.HierarchyEvent import java.awt.event.*
import javax.swing.JPanel import javax.swing.JPanel
import javax.swing.SwingUtilities.invokeLater
import javax.swing.SwingUtilities.isEventDispatchThread import javax.swing.SwingUtilities.isEventDispatchThread
interface SkiaRenderer { interface SkiaRenderer {
...@@ -29,12 +19,23 @@ open class SkiaLayer( ...@@ -29,12 +19,23 @@ open class SkiaLayer(
private val properties: SkiaLayerProperties = SkiaLayerProperties() private val properties: SkiaLayerProperties = SkiaLayerProperties()
) : JPanel() { ) : JPanel() {
val backedLayer : HardwareLayer internal val backedLayer : HardwareLayer
init { init {
setOpaque(false) setOpaque(false)
layout = null layout = null
backedLayer = object : HardwareLayer() { } backedLayer = object : HardwareLayer() {
override fun paint(g: Graphics) {
// 1. JPanel.paint is not always called (in rare cases).
// For example if we call 'jframe.isResizable = false` on Ubuntu
//
// 2. HardwareLayer.paint is also not always called.
// For example, on macOs when we resize window or change DPI
//
// 3. to avoid double paint in one single frame, use needRedraw instead of redrawImmediately
redrawer?.needRedraw()
}
}
add(backedLayer) add(backedLayer)
@Suppress("LeakingThis") @Suppress("LeakingThis")
backedLayer.addHierarchyListener { backedLayer.addHierarchyListener {
...@@ -45,6 +46,7 @@ open class SkiaLayer( ...@@ -45,6 +46,7 @@ open class SkiaLayer(
} }
private var isInited = false private var isInited = false
private var isRendering = false
private fun checkIsShowing() { private fun checkIsShowing() {
if (!isInited && isShowing) { if (!isInited && isShowing) {
...@@ -115,7 +117,18 @@ open class SkiaLayer( ...@@ -115,7 +117,18 @@ open class SkiaLayer(
contentScaleChanged() contentScaleChanged()
} }
redrawer?.syncSize() redrawer?.syncSize()
redrawer?.redrawImmediately()
// `paint` can be called when we already inside `draw` method.
//
// 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 {
redrawer?.redrawImmediately()
}
} }
override fun addInputMethodListener(l: InputMethodListener) { override fun addInputMethodListener(l: InputMethodListener) {
...@@ -169,7 +182,12 @@ open class SkiaLayer( ...@@ -169,7 +182,12 @@ open class SkiaLayer(
canvas.clipRectBy(component) canvas.clipRectBy(component)
} }
renderer?.onRender(canvas, pictureWidth, pictureHeight, nanoTime) try {
isRendering = true
renderer?.onRender(canvas, pictureWidth, pictureHeight, nanoTime)
} finally {
isRendering = false
}
// we can dispose layer during onRender // we can dispose layer during onRender
if (!isDisposed) { if (!isDisposed) {
......
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