How can I dynamically resize the window height to ...
# compose-desktop
c
How can I dynamically resize the window height to match the height of the content? I'm adding a small settings modal to my app and most mac apps I've seen seem to have a window height that perfectly matches the content? Should I just use BoxWithConstraints to get the height and set that? i.e.
c
I think you might have to do it in the AWT layer
p
Copy code
val state = rememberWindowState(
    size = DpSize(Dp.Unspecified, Dp.Unspecified)
)
i think this sets initial value of size to the content, it does not update it if changes afterwards though
c
hm. i tried pau's comment and that just made it fullscreenl ill try looking up some awt things
c
I don't think I fully understand that url. Looks like the ability for this was merged in?
Am I supposed to use window.pack() or composeLayer.preferredSize()?
a
Neither. Use Dp.Unspecified for a one-time sizing. The ticket explains it.
c
oh hm. okay. i did give that a try early based on Pau M's answer, but it didn't work. let me try on a new sample app
a
You probably have fillMaxSize in the root element
c
I did indeed! Let me retry my project then...
I feel like (because of android) I'm used to telling my root element to always fillMaxSize? Is there a different fill* that I should be using here or just omit it completely? not sure if i need an intrinsic size or something?
a
Just omit it
c
cool. That indeed worked. Thank you!
a
Make the Window non-resizable too
c
oh interesting. i thought if it was resizable the content would instead fill that container.
thank you for the hand holding. still a desktop noob so all this is still a lot to digest. 😄
c
@Colton Idle is the code for your project publicly available? Sounds like it’ll be another useful resource for future needs.
c
Started this to take note of all of these little tips and tricks https://dev.to/coltonidle/compose-for-desktop-window-tricks-55mf
🙏 1
FWIW. the one time sizing here made it a nogo for my application. Back to the drawing board to try to get something like this working.
a
There you go:
Copy code
import androidx.compose.animation.core.*
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.*
import androidx.compose.ui.unit.*
import androidx.compose.ui.window.*

fun main() = application {
    val windowState = rememberWindowState(size = DpSize(Dp.Unspecified, Dp.Unspecified))
    Window(
        onCloseRequest = ::exitApplication,
        state = windowState,
        resizable = false,
    ) {
        var tabIndex by remember { mutableIntStateOf(0) }
        LaunchedEffect(tabIndex) {
            val prefSize = window.preferredSize.let {
                DpSize(it.width.dp, it.height.dp)
            }
            // Optional animation; can just assign windowState.size immediately instead
            val animation = Animatable(
                initialValue = windowState.size,
                typeConverter = DpSizeConverter
            )
            animation.animateTo(prefSize) {
                windowState.size = value
            }
        }

        Column(
            modifier = Modifier.width(IntrinsicSize.Max),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Row(
                modifier = Modifier.fillMaxWidth().padding(16.dp),
                verticalAlignment = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.Center
            ) {
                Button(onClick = { tabIndex = 0 }) { Text("Small Tab")}
                Spacer(Modifier.width(16.dp))
                Button(onClick = { tabIndex = 1 }) { Text("Large Tab")}
            }

            when (tabIndex) {
                0 -> {
                    Box(Modifier.size(400.dp, 400.dp), contentAlignment = Alignment.Center) {
                        Text("Small Tab Content")
                    }
                }
                1 -> {
                    Box(Modifier.size(400.dp, 800.dp), contentAlignment = Alignment.Center) {
                        Text("Large Tab Content")
                    }
                }
            }
        }
    }
}

private val DpSizeConverter = TwoWayConverter<DpSize, AnimationVector2D>(
    convertToVector = { AnimationVector2D(it.width.value, it.height.value) },
    convertFromVector = { DpSize(it.v1.dp, it.v2.dp) }
)
Screen Recording 2025-03-04 at 11.03.58.mp4
No guarantees it’ll always keep working though.
c
ah. i feel like a fool for not realizing we could programatically change
windowState.size
even when resizable = false. Adding this one to my "Window tricks" doc. lol thank you!
"no guarantees it'll always keep working" is interesting. but it indeed does work now. ❤️
m
@Chris Sinco [G] Are you collecting Compose Desktop projects for something?
c
I’m not. It’s for my own curiosity when I decide to package up my own app.
👍 2