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 @@ -381,8 +381,6 @@ internal class ComposeSceneMediator(
container.transferHandler = dragAndDropManager.transferHandler
container.dropTarget = dragAndDropManager.dropTarget

// It will be enabled dynamically. See DesktopPlatformComponent
contentComponent.enableInputMethods(false)
contentComponent.focusTraversalKeysEnabled = false

subscribe(contentComponent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package androidx.compose.ui.scene.skia
import androidx.compose.ui.scene.ComposeSceneMediator
import java.awt.Dimension
import java.awt.Graphics
import java.awt.event.FocusEvent
import javax.accessibility.Accessible
import org.jetbrains.skiko.ExperimentalSkikoApi
import org.jetbrains.skiko.SkiaLayerAnalytics
Expand Down Expand Up @@ -82,6 +83,23 @@ internal class SwingSkiaLayerComponent(
} else {
mediator.preferredSize
}

// Workaround for enableInputMethods being ignored until the component is actually focused.
// This also controls the default state, without needing it to be set from the outside.
private var inputMethodsEnabled = false

override fun processFocusEvent(e: FocusEvent?) {
super.processFocusEvent(e)

// enableInputMethods is idempotent (and quick when applying the same value),
// so it's ok to call it on every event
super.enableInputMethods(inputMethodsEnabled)
}

override fun enableInputMethods(enable: Boolean) {
inputMethodsEnabled = enable
super.enableInputMethods(enable)
}
}

override val renderApi by contentComponent::renderApi
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import androidx.compose.ui.platform.PlatformWindowContext
import androidx.compose.ui.scene.ComposeSceneMediator
import java.awt.Dimension
import java.awt.Graphics
import java.awt.event.FocusEvent
import java.awt.event.FocusListener
import javax.accessibility.Accessible
import org.jetbrains.skiko.GraphicsApi
import org.jetbrains.skiko.SkiaLayer
Expand Down Expand Up @@ -60,6 +62,14 @@ internal class WindowSkiaLayerComponent(
analytics = skiaLayerAnalytics
) {

init {
// SkiaLayer never receives focus, only its underlying canvas
canvas.addFocusListener(object : FocusListener {
override fun focusGained(e: FocusEvent?) = onFocusEvent()
override fun focusLost(e: FocusEvent?) = onFocusEvent()
})
}

private var endCompositionWorkaround: InputMethodEndCompositionWorkaround? = null

override fun getInputContext() =
Expand Down Expand Up @@ -90,6 +100,21 @@ internal class WindowSkiaLayerComponent(
} else {
mediator.preferredSize
}

// Workaround for enableInputMethods being ignored until the component is actually focused.
// This also controls the default state, without needing it to be set from the outside.
private var inputMethodsEnabled = false

private fun onFocusEvent() {
// enableInputMethods is idempotent (and quick when applying the same value),
// so it's ok to call it on every event
super.enableInputMethods(inputMethodsEnabled)
}

override fun enableInputMethods(enable: Boolean) {
inputMethodsEnabled = enable
super.enableInputMethods(enable)
}
}

override val renderApi by contentComponent::renderApi
Expand Down