Skip to content

Conversation

@m-sasha
Copy link
Member

@m-sasha m-sasha commented Aug 6, 2025

Focusable layers do not currently request focus upon being attached, and in fact, the wrong component is being made focusable.

This PR makes the ComposeMediator.contentComponent focusable when the layer is, and requests focus on it when attached.

This fixes, for example, pressing ESC to close a focusable popup when it's used from a ComposePanel whose windowContainer has been set to the parent window's layered pane.

Testing

Added a unit test, and also tested manually with:

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.onClick
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.awt.ComposePanel
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Popup
import androidx.compose.ui.window.PopupProperties
import java.awt.BorderLayout
import javax.swing.BorderFactory
import javax.swing.JFrame
import javax.swing.JPanel
import javax.swing.SwingUtilities
import kotlinx.coroutines.delay

@OptIn(ExperimentalFoundationApi::class, ExperimentalComposeUiApi::class)
fun main() = SwingUtilities.invokeLater {
    System.setProperty("compose.swing.render.on.graphics", "true")
    System.setProperty("compose.layers.type", "COMPONENT")

    val window = JFrame()
    val composePanel = ComposePanel()
    composePanel.setContent {
        var showPopup by remember { mutableStateOf(false) }
        Box(Modifier
            .size(100.dp)
            .background(Color.Yellow)
            .onClick { showPopup = true }
        )
        if (showPopup) {
            Popup(
                alignment = Alignment.Center,
                properties = PopupProperties(focusable = true),
                onDismissRequest = { showPopup = false }
            ) {
                Box(Modifier.size(200.dp).background(Color.Blue))
            }
        }

        LaunchedEffect(Unit) {
            while (true) {
                println(window.focusOwner)
                delay(1000)
            }
        }
    }
    composePanel.windowContainer = window.layeredPane

    val panel = JPanel().also {
        it.add(composePanel, BorderLayout.CENTER)
        it.border = BorderFactory.createEmptyBorder(100, 100, 100, 100)
    }

    window.contentPane.add(panel, BorderLayout.CENTER)
    window.pack()
    window.isVisible = true
}

Release Notes

Fixes - Desktop

  • Request initial focus for focusable popups when used from ComposePanel in some cases.

@m-sasha m-sasha requested a review from MatkovIvan August 6, 2025 12:05
@m-sasha
Copy link
Member Author

m-sasha commented Aug 6, 2025

The real changes are in WindowComposeSceneLayer.desktop.kt and SwingComposeSceneLayer.desktop.kt.
The rest is just minor code improvements.

@m-sasha m-sasha force-pushed the m-sasha/request-initial-focus-for-focusable-layers branch 2 times, most recently from 031c8b3 to e10e0a5 Compare August 6, 2025 23:24
@m-sasha m-sasha force-pushed the m-sasha/request-initial-focus-for-focusable-layers branch from e10e0a5 to a4bb2d4 Compare August 7, 2025 07:45
@m-sasha m-sasha requested a review from MatkovIvan August 7, 2025 09:28
* on each re-draw, which may result in some performance penalty (proportional to the size)
* compared to [SkiaSurface].
*/
@Suppress("CanSealedSubClassBeObject")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems it's not required after the revert

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

@m-sasha m-sasha requested a review from MatkovIvan August 7, 2025 10:50
@m-sasha m-sasha merged commit 25d1c4b into jb-main Aug 7, 2025
10 checks passed
@m-sasha m-sasha deleted the m-sasha/request-initial-focus-for-focusable-layers branch August 7, 2025 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants