Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ internal interface DesktopNativeViewLayoutTarget {
/** 请求 AWT 重新执行布局。 */
fun revalidate()

/**
* 以当前边界重新设置原生视图尺寸。
*
* JCEF 的 windowed 视图会在自身的 `setBounds()` 中将尺寸同步给 Chromium。Compose SwingPanel
* 可能在浏览器创建前已经完成过一次布局,因此首次原生浏览器就绪后需要无尺寸变化地重新执行该路径。
*/
fun synchronizeNativeViewSize()

/** 同步进入原生 Swing 视图的绘制流程。 */
fun paintImmediately()

Expand Down Expand Up @@ -109,6 +117,10 @@ internal class ComponentDesktopNativeViewLayoutTarget(
component.revalidate()
}

override fun synchronizeNativeViewSize() {
component.setBounds(component.bounds)
}

/**
* 同步绘制 JCEF 暴露的 JPanel,触发其内部的 `doUpdate()` 与原生浏览器子窗口绑定。
*
Expand Down Expand Up @@ -301,6 +313,7 @@ internal class DesktopInitialNativeViewLayoutCoordinator(
isSynchronizing = true
try {
target.revalidate()
target.synchronizeNativeViewSize()
target.paintImmediately()
target.repaint()
isInitialLayoutSynchronized = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ class DesktopInitialNativeViewLayoutCoordinatorTest {
@Test
fun `视图尚未 showing 时不会立即同步`() {
val target = FakeDesktopNativeViewLayoutTarget(isShowing = false)
val coordinator = DesktopInitialNativeViewLayoutCoordinator(target, { false })
val coordinator = DesktopInitialNativeViewLayoutCoordinator(
target = target,
isControllerDisposed = { false },
scheduleDelayedRetry = {},
)

coordinator.registerShowingListener()
coordinator.requestInitialNativeViewLayout()
Expand All @@ -21,7 +25,11 @@ class DesktopInitialNativeViewLayoutCoordinatorTest {
@Test
fun `收到 showing 事件后按同步顺序绘制一次`() {
val target = FakeDesktopNativeViewLayoutTarget(isShowing = false)
val coordinator = DesktopInitialNativeViewLayoutCoordinator(target, { false })
val coordinator = DesktopInitialNativeViewLayoutCoordinator(
target = target,
isControllerDisposed = { false },
scheduleDelayedRetry = {},
)

coordinator.registerShowingListener()
coordinator.requestInitialNativeViewLayout()
Expand All @@ -30,10 +38,11 @@ class DesktopInitialNativeViewLayoutCoordinatorTest {
target.dispatchShowingChanged()

assertEquals(1, target.revalidateCount)
assertEquals(1, target.nativeViewSizeSynchronizationCount)
assertEquals(1, target.immediatePaintCount)
assertEquals(1, target.repaintCount)
assertEquals(
listOf("revalidate", "paintImmediately", "repaint"),
listOf("revalidate", "synchronizeNativeViewSize", "paintImmediately", "repaint"),
target.synchronizationOperations,
)
}
Expand Down Expand Up @@ -61,7 +70,11 @@ class DesktopInitialNativeViewLayoutCoordinatorTest {
width = 0,
height = 0,
)
val coordinator = DesktopInitialNativeViewLayoutCoordinator(target, { false })
val coordinator = DesktopInitialNativeViewLayoutCoordinator(
target = target,
isControllerDisposed = { false },
scheduleDelayedRetry = {},
)

coordinator.registerShowingListener()
coordinator.requestInitialNativeViewLayout()
Expand All @@ -70,10 +83,11 @@ class DesktopInitialNativeViewLayoutCoordinatorTest {
target.dispatchLayoutChanged()

assertEquals(1, target.revalidateCount)
assertEquals(1, target.nativeViewSizeSynchronizationCount)
assertEquals(1, target.immediatePaintCount)
assertEquals(1, target.repaintCount)
assertEquals(
listOf("revalidate", "paintImmediately", "repaint"),
listOf("revalidate", "synchronizeNativeViewSize", "paintImmediately", "repaint"),
target.synchronizationOperations,
)
}
Expand Down Expand Up @@ -112,6 +126,17 @@ class DesktopInitialNativeViewLayoutCoordinatorTest {
assertSynchronizationPerformedOnce(target)
}

@Test
fun `JCEF 就绪后会重新同步当前尺寸`() {
val target = FakeDesktopNativeViewLayoutTarget(isShowing = true)
val coordinator = DesktopInitialNativeViewLayoutCoordinator(target, { false })

coordinator.registerShowingListener()
coordinator.requestInitialNativeViewLayout()

assertEquals(1, target.nativeViewSizeSynchronizationCount)
}

@Test
fun `初始同步完成后多次 resize 不会重复绘制`() {
val target = FakeDesktopNativeViewLayoutTarget(isShowing = true)
Expand Down Expand Up @@ -181,10 +206,11 @@ class DesktopInitialNativeViewLayoutCoordinatorTest {

private fun assertSynchronizationPerformedOnce(target: FakeDesktopNativeViewLayoutTarget) {
assertEquals(1, target.revalidateCount)
assertEquals(1, target.nativeViewSizeSynchronizationCount)
assertEquals(1, target.immediatePaintCount)
assertEquals(1, target.repaintCount)
assertEquals(
listOf("revalidate", "paintImmediately", "repaint"),
listOf("revalidate", "synchronizeNativeViewSize", "paintImmediately", "repaint"),
target.synchronizationOperations,
)
}
Expand All @@ -208,6 +234,8 @@ private class FakeDesktopNativeViewLayoutTarget(
private set
var revalidateCount = 0
private set
var nativeViewSizeSynchronizationCount = 0
private set
var immediatePaintCount = 0
private set
var repaintCount = 0
Expand Down Expand Up @@ -239,6 +267,11 @@ private class FakeDesktopNativeViewLayoutTarget(
synchronizationOperations += "revalidate"
}

override fun synchronizeNativeViewSize() {
nativeViewSizeSynchronizationCount++
synchronizationOperations += "synchronizeNativeViewSize"
}

override fun paintImmediately() {
immediatePaintCount++
synchronizationOperations += "paintImmediately"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ private class FakeAttachmentTarget(

override fun revalidate() = Unit

override fun synchronizeNativeViewSize() = Unit

override fun paintImmediately() = Unit

override fun repaint() = Unit
Expand Down
Loading