mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 02:29:55 +02:00
feat(desktop): unify macOS window chrome
This commit is contained in:
@@ -1,6 +1,26 @@
|
||||
package com.vnidrop.app
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.text.BasicText
|
||||
import androidx.compose.foundation.window.WindowDraggableArea
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.awt.awtEventOrNull
|
||||
import androidx.compose.ui.input.pointer.PointerEventType
|
||||
import androidx.compose.ui.input.pointer.onPointerEvent
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.WindowScope
|
||||
import androidx.compose.ui.window.application
|
||||
import com.vnidrop.app.platform.DesktopAppearanceBridge
|
||||
import com.vnidrop.app.feature.send.DesktopShareBridge
|
||||
@@ -8,11 +28,13 @@ import com.vnidrop.app.feature.receive.ExternalInvitationController
|
||||
import com.vnidrop.app.feature.receive.MaxVniDropInvitationBytes
|
||||
import com.vnidrop.app.feature.receive.VniDropInvitationExtension
|
||||
import com.vnidrop.app.feature.receive.decodeInvitationBytes
|
||||
import com.vnidrop.app.ui.theme.LocalVniDropColors
|
||||
import java.awt.Desktop
|
||||
import java.io.File
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val externalInvitations = ExternalInvitationController()
|
||||
val macOs = DesktopAppearanceBridge.isMacOs()
|
||||
configureMacOsNativeAppearance()
|
||||
configureInvitationOpenHandler(externalInvitations)
|
||||
args.asSequence()
|
||||
@@ -20,7 +42,7 @@ fun main(args: Array<String>) {
|
||||
.filter { it.extension.equals(VniDropInvitationExtension, ignoreCase = true) }
|
||||
.forEach { externalInvitations.openFile(it) }
|
||||
DesktopAppearanceBridge.applyNativeAppearance = MacOsAppKitAppearance::apply
|
||||
if (System.getProperty("os.name").startsWith("Mac", ignoreCase = true)) {
|
||||
if (macOs) {
|
||||
DesktopShareBridge.shareFile = MacOsShareSheet::share
|
||||
}
|
||||
application {
|
||||
@@ -28,7 +50,16 @@ fun main(args: Array<String>) {
|
||||
onCloseRequest = ::exitApplication,
|
||||
title = "vnidrop",
|
||||
) {
|
||||
App(rememberJvmAppDependencies(externalInvitations))
|
||||
App(
|
||||
dependencies = rememberJvmAppDependencies(externalInvitations),
|
||||
windowChromeTopInset = if (macOs) MacOsTitleBarHeight else 0.dp,
|
||||
windowContentTopStartRadius = if (macOs) MacOsContentCornerRadius else 0.dp,
|
||||
windowChrome = if (macOs) {
|
||||
{ MacOsTitleBar() }
|
||||
} else {
|
||||
null
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,8 +83,47 @@ private fun ExternalInvitationController.openFile(file: File) {
|
||||
}
|
||||
|
||||
private fun configureMacOsNativeAppearance() {
|
||||
if (!System.getProperty("os.name").startsWith("Mac", ignoreCase = true)) return
|
||||
if (!DesktopAppearanceBridge.isMacOs()) return
|
||||
// AWT reads this before creating the first native window. Runtime theme
|
||||
// changes are handled in the JVM platform appearance hook.
|
||||
System.setProperty("apple.awt.application.appearance", "system")
|
||||
}
|
||||
|
||||
private val MacOsTitleBarHeight = 28.dp
|
||||
private val MacOsTrafficLightsWidth = 76.dp
|
||||
private val MacOsContentCornerRadius = 20.dp
|
||||
|
||||
@Composable
|
||||
@OptIn(ExperimentalComposeUiApi::class)
|
||||
private fun WindowScope.MacOsTitleBar() {
|
||||
val colors = LocalVniDropColors.current
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(MacOsTitleBarHeight)
|
||||
.background(colors.backgroundSurface200),
|
||||
) {
|
||||
WindowDraggableArea(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(start = MacOsTrafficLightsWidth)
|
||||
.onPointerEvent(PointerEventType.Press) { event ->
|
||||
if (event.awtEventOrNull?.clickCount == 2) {
|
||||
DesktopAppearanceBridge.toggleMaximized(window)
|
||||
}
|
||||
},
|
||||
) {
|
||||
Box(modifier = Modifier.fillMaxSize().padding(end = MacOsTrafficLightsWidth)) {
|
||||
BasicText(
|
||||
text = "vnidrop",
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
style = TextStyle(
|
||||
color = colors.foregroundDefault,
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user