Arne Stockmans.be

Blog - About - Contact

Build and run Jetpack Compose for Desktop

At Google I/O 2019, Google announced the first preview of Jetpack Compose: A modern toolkit for building native Android UI, similar to the idea behind Flutter and React. Initially, we had to checkout AOSP and build the samples ourselves, while today we have dev binaries available which are used in tons of sample projects.

A little while ago, however, something caught my eye. JetBrains posted a job vacancy for a "UI Framework Developer (JetBrains Compose Toolkit Team)". And in the description, we can find an interesting note:

Jetpack Compose is a modern Kotlin GUI toolkit for Android. Our team is working to port it to desktop and other platforms

It appears that Jetpack Compose won't be limited to Android, but will expand to other platforms as well. This isn't such a big surprise, as the team always claimed it wasn't tied to Android.

But it doesn't stop with the job vacancy - we can already checkout their progress! And this in exactly the same way as we could follow their initial progress: by following AOSP.

Let's get started!

To checkout the latest source code, we need a tool called repo. "Repo unifies Git repositories when necessary, performs uploads to the Gerrit revision control system, and automates parts of the Android development workflow." - according to their official web page. So first you'll have to follow the Installing Repo guide before we move on.

Once we have our repo tool set up, we can download the source code. You'll need the androidx-master-dev branch for this:

repo init -u https://android.googlesource.com/platform/manifest -b androidx-master-dev
repo sync

You can find all compose related code in androidx/frameworks/support/ui. Note that if you want to open it in Android Studio, chances are very high that you'll get an error saying you're using an incompatible version. To solve this, you can use a bundled version of Android Studio by running ./studiow in the previously mentioned folder.

Running the first sample

Now that we have the source code on our machine, it's time to look at the samples! You can find all of them in the ui-desktop/samples/src/jvmMain/kotlin/ folder. The first one demoes several basic composables like Column, Text, Button, Slider, TextField,...

// example1/Main.kt

...

AppWindow(title, IntSize(1024, 768)).show {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text(title) }
            )
        },
        floatingActionButton = { ... },
        bodyContent = {
            val amount = remember { mutableStateOf(0) }
            val animation = remember { mutableStateOf(true) }
            val text = remember {
                mutableStateOf("Hello \uD83E\uDDD1\uD83C\uDFFF\u200D\uD83E\uDDB0\nПривет")
            }
            Column(Modifier.fillMaxSize(), Arrangement.SpaceEvenly) {
                Text(
                    text = "Привет! 你好! Desktop Compose ${amount.value}",
                    color = Color.Black,
                    modifier = Modifier
                        .background(Color.Blue)
                        .preferredHeight(56.dp)
                        .wrapContentSize(Alignment.Center)
                )

                ...

                Button(onClick = {
                    amount.value++
                }) {
                    Text("Base")
                }

                Row(modifier = Modifier.padding(vertical = 10.dp),
                    verticalGravity = Alignment.CenterVertically) {
                    Button(
                        onClick = {
                        animation.value = !animation.value
                    }) {
                        Text("Toggle")
                    }

                    if (animation.value) {
                        CircularProgressIndicator()
                    }
                }

                Slider(value = amount.value.toFloat() / 100f,
                    onValueChange = { amount.value = (it * 100).toInt() })
                TextField(
                    value = amount.value.toString(),
                    onValueChange = { amount.value = it.toIntOrNull() ?: 42 },
                    label = { Text(text = "Input1") }
                )
                ...
            }
        }
    )
}
...

When we have a quick glance at the source code, you would say it's a simple Android app using Jetpack Compose. The only difference is that it's wrapped in a AppWindow composable instead of an Activity. You can see it in action by running this command:

./gradlew :compose:desktop:desktop:samples:run1

Jetpack Compose Desktop sample 1

The second sample shows us the Canvas composable:

./gradlew :compose:desktop:desktop:samples:run2

Jetpack Compose Desktop sample 2

And the third one show us how to use popups and dialogs:

./gradlew :compose:desktop:desktop:samples:run3

Jetpack Compose Desktop sample 3

What if you see a different result?

The README.md file in the ui-desktop folder currently mentions:

WIP desktop port of Compose. Only works on macOS at the moment.

So if you're on a different OS, you're out of luck for now.

Also, know that the source code is constantly evolving. At the time I write this post, I see that the current git commit sha is 258706f0a6. If you run git status and see a different sha, you can see different results. But don't worry, you can simply run git checkout 258706f0a6 to see the same version as I have right now.

© 2020 Arne Stockmans, Built with Gatsby