🌟 | Support this project |
---|---|
![]() |
bc1qs6qq0fkqqhp4whwq8u8zc5egprakvqxewr5pmx |
![]() |
0x3147bEE3179Df0f6a0852044BFe3C59086072e12 |
![]() |
TKznmR65yhPt5qmYCML4tNSWFeeUkgYSEV |
A template for creating custom window decorations in Jetpack Compose Desktop applications. Provides complete control over window chrome while maintaining native functionality.
-
🖼️ Complete Window Customization
- Fully customizable title bar with draggable area
- Double-click to maximize/restore
- Themed window controls
- Flexible layout options
-
🎨 Material Design Integration
- Built-in light/dark theme support
- Custom color schemes
- Adaptive icon colors
-
⚙️ Enhanced Window Controls
- Standard buttons (minimize/maximize/close)
- Theme switcher
- Custom controls section
- Responsive layout
-
🖱️ Native Behavior
- Smooth window dragging
- DPI-aware scaling
- Full multi-monitor support
- Window state management
-
Add the icons dependency:
implementation("org.jetbrains.compose.material:material-icons-extended:1.7.3")
-
Copy these components to your project:
- WindowDecoration.kt - Main decoration logic
- WindowDecorationColors.kt - Color scheme
- WindowDecorationState.kt - Window state
Important
If you use SwingPanel
, some components may not be compatible with a transparent window - in this case the background
remains transparent or flickers. Use the isTransparent = false
flag.
@Composable
fun ApplicationScope.WindowDecoration(
isDarkTheme: Boolean,
setIsDarkTheme: (Boolean) -> Unit = {},
title: String = "Untitled", /** Application name in the taskbar */
icon: Painter? = null, /** Application icon in the taskbar */
windowDecorationHeight: Dp = 32.dp,
windowDecorationColors: WindowDecorationColors = WindowDecorationColors(
decoration = {
MaterialTheme.colorScheme.surface
},
content = {
MaterialTheme.colorScheme.background
},
switchSchemeButton = {
MaterialTheme.colorScheme.primary
},
minimizeButton = {
MaterialTheme.colorScheme.primary
},
fullscreenButton = {
MaterialTheme.colorScheme.primary
},
closeButton = {
MaterialTheme.colorScheme.primary
},
),
initialWindowPosition: WindowPosition? = null,
initialWindowSize: DpSize? = null,
minimumWindowSize: DpSize? = null,
isVisible: Boolean = true,
isTransparent: Boolean = true,
isResizable: Boolean = true,
isEnabled: Boolean = true,
isFocusable: Boolean = true,
isAlwaysOnTop: Boolean = false,
onPreviewKeyEvent: (KeyEvent) -> Boolean = { false },
onKeyEvent: (KeyEvent) -> Boolean = { false },
onCloseRequest: () -> Unit = ::exitApplication,
titleContent: @Composable RowScope.() -> Unit, /** Left side of the top panel */
controlsContent: @Composable RowScope.() -> Unit = {}, /** Right side of the top panel */
windowContent: @Composable (ComposeWindow.(WindowDecorationState) -> Unit),
)
Customize colors for different parts of the window:
windowDecorationColors = WindowDecorationColors().copy(
decoration = { Color(0xFF2E3440) }, /** Window decoration background */
content = { Color(0xFF3B4252) }, /** Content area background */
switchSchemeButton = { Color.Unspecified }, /** Hide button */
closeButton = { Color.Red } /** Make close button red */
)
Access window state in your content:
content = { windowState: WindowDecorationState ->
if (windowState.isFullscreen) {
FullscreenContent()
} else {
NormalContent()
}
}
Add your own controls:
controls = {
Box(
modifier = Modifier.fillMaxHeight().aspectRatio(1f).clickable {
/* handle action */
}, contentAlignment = Alignment.Center
) {
Icon(
Icons.Default.Settings, null, tint = MaterialTheme.colorScheme.primary
)
}
}
Control window behavior:
WindowDecoration(
initialWindowPosition = WindowPosition(100.dp, 100.dp),
initialWindowSize = DpSize(800.dp, 600.dp),
minimumWindowSize = DpSize(400.dp, 300.dp),
isResizable = true,
isAlwaysOnTop = false,
// ...
)
See complete example: Application.kt