Skip to content

桌面端差异化 (Desktop)

Compose for Desktop 赋予了我们在 PC (Windows/macOS/Linux) 上构建原生应用的能力。与移动端不同,桌面端有鼠标、键盘快捷键和多窗口系统。

1. 窗口管理 (Window)

桌面应用的入口是 Window Composable,而不是 Activity。

基础窗口

kotlin
fun main() = application {
    Window(
        onCloseRequest = ::exitApplication,
        title = "我的桌面应用",
        state = rememberWindowState(width = 800.dp, height = 600.dp),
        icon = painterResource("icon.png") // 设置任务栏图标
    ) {
        App()
    }
}

无边框窗口 (Undecorated)

用于自定义标题栏或异形窗口。

kotlin
Window(
    onCloseRequest = ::exitApplication,
    undecorated = true, // 去掉系统标题栏
    transparent = true  // 支持透明背景
) {
    Surface(
        shape = RoundedCornerShape(16.dp), // 圆角窗口
        color = MaterialTheme.colorScheme.surface
    ) {
        // 自定义标题栏区域,支持拖拽窗口
        WindowDraggableArea {
            Box(Modifier.fillMaxWidth().height(40.dp).background(Color.Gray)) {
                Text("自定义标题", Modifier.align(Alignment.Center))
            }
        }
        // 内容...
    }
}

2. 鼠标交互

移动端只有触摸,而桌面端有鼠标悬停、右键等操作。

悬停 (Hover) & 移入移出

kotlin
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun HoverButton() {
    var isHovered by remember { mutableStateOf(false) }

    Box(
        modifier = Modifier
            .size(100.dp)
            .background(if (isHovered) Color.Blue else Color.Gray)
            .onPointerEvent(PointerEventType.Enter) { isHovered = true }
            .onPointerEvent(PointerEventType.Exit) { isHovered = false }
            // 改变鼠标指针样式 (变成小手)
            .pointerHoverIcon(PointerIcon.Hand) 
    )
}

右键菜单 (Context Menu)

Compose Desktop 提供了原生的 Swing 风格右键菜单,也可以自定义。

kotlin
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun RightClickArea() {
    Box(
        modifier = Modifier.size(200.dp).background(Color.LightGray)
    ) {
        // 自动处理右键点击的区域
        ContextMenuArea(
            items = {
                ContextMenuItem("复制") { /* Copy */ }
                ContextMenuItem("粘贴") { /* Paste */ }
            }
        ) {
            Text("在此处右键")
        }
    }
}

3. 键盘与快捷键

桌面应用重度依赖键盘操作。

kotlin
Window(
    onCloseRequest = ::exitApplication,
    // 监听全局键盘事件
    onKeyEvent = { keyEvent ->
        if (keyEvent.key == Key.Escape) {
            // 按 ESC 关闭窗口
            exitApplication()
            true
        } else false
    }
) {
   // ...
}

4. 系统菜单栏 (MenuBar)

macOS 顶部的菜单栏或 Windows 窗口顶部的菜单。

kotlin
Window(...) {
    MenuBar {
        Menu("文件") {
            Item("新建", onClick = { }, shortcut = KeyShortcut(Key.N, meta = true))
            Item("打开", onClick = { }, shortcut = KeyShortcut(Key.O, meta = true))
            Separator()
            Item("退出", onClick = ::exitApplication)
        }
        Menu("帮助") {
            Item("关于", onClick = { })
        }
    }
    App()
}

5. 系统托盘 (Tray)

让应用最小化到系统托盘区。

kotlin
fun main() = application {
    // 托盘图标
    Tray(
        icon = painterResource("tray_icon.png"),
        menu = {
            Item("显示主窗口", onClick = { /* open window */ })
            Item("退出", onClick = ::exitApplication)
        }
    )
    
    // ... Window
}