JetBrains / compose-multiplatform

Compose Multiplatform, a modern UI framework for Kotlin that makes building performant and beautiful user interfaces easy and enjoyable.
https://jetbrains.com/lp/compose-multiplatform
Apache License 2.0
15.96k stars 1.16k forks source link

Cannot set Color.Transparent background on SwingPanel #1061

Open felixdivo opened 3 years ago

felixdivo commented 3 years ago

Using org.jetbrains.compose @ 1.0.0-alpha4-build310.

image

Minimal example to reproduce:

import androidx.compose.desktop.DesktopMaterialTheme
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.awt.SwingPanel
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
import com.arkivanov.decompose.DefaultComponentContext
import com.arkivanov.decompose.ExperimentalDecomposeApi
import com.arkivanov.decompose.extensions.compose.jetbrains.lifecycle.LifecycleController
import com.arkivanov.essenty.lifecycle.LifecycleRegistry
import javax.swing.JLabel

@OptIn(ExperimentalComposeUiApi::class, ExperimentalDecomposeApi::class)
fun main() {
    val lifecycle = LifecycleRegistry()

    application {
        val windowState = rememberWindowState()

        LifecycleController(lifecycle, windowState)

        Window(
            onCloseRequest = ::exitApplication,
            state = windowState,
        ) {

            Surface(modifier = Modifier.fillMaxSize()) {
                DesktopMaterialTheme {
                    actualContent()
                }
            }
        }
    }
}

@Composable
fun actualContent() {

    Box(modifier = Modifier.fillMaxSize().background(Color.Red)) {

        SwingPanel(
            modifier = Modifier.width(100.dp).height(100.dp).background(Color.Transparent),
            factory = {
                JLabel("Hey")
            },
        )
    }
}
felixdivo commented 2 years ago

The constructor of JPanel calls setUIProperty("opaque", Boolean.TRUE). Maybe it would be sufficient to set it to non-opaque.

rock3r commented 2 years ago

Yeah we likely need to set the JPanel's opaque property to FALSE if needed. Another case may be when Color.Unspecified is passed in, as setting it as an AWT colour will not work either.

igordmn commented 1 year ago

According to this it already works on macOS. We didn't intentionally implemented it for macOS though, but overall it is useful feature, and should be supported someday in Compose for all OS'es.

MohamedRejeb commented 4 months ago

Any updates on this? It can be helpful to use SwingPanel as a placeholder for drawing which will temporarily fix the current latency issues with Compose Desktop.

MatkovIvan commented 4 months ago

@MohamedRejeb we have a few similar issues regarding "transparent interop" for different platforms - but it's likely not to be implemented due to various kinda fundamental reasons.

Regarding this issue on desktop/swing - it might work only in the case of rendering compose to swing graphics instead of on GPU surface directly. We have such mode under compose.swing.render.on.graphics flag, but it's definitely not the thing to solve performance/latency issues.

okushnikov commented 2 months ago

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.