diff --git a/decorated-window/api/decorated-window.api b/decorated-window/api/decorated-window.api index d84dece450..5264dffd10 100644 --- a/decorated-window/api/decorated-window.api +++ b/decorated-window/api/decorated-window.api @@ -49,6 +49,13 @@ public abstract interface class com/jetbrains/WindowMove { public abstract fun startMovingTogetherWithMouse (Ljava/awt/Window;I)V } +public final class org/jetbrains/jewel/window/ComposableSingletons$TitleBarKt { + public static final field INSTANCE Lorg/jetbrains/jewel/window/ComposableSingletons$TitleBarKt; + public static field lambda-1 Lkotlin/jvm/functions/Function2; + public fun ()V + public final fun getLambda-1$decorated_window ()Lkotlin/jvm/functions/Function2; +} + public final class org/jetbrains/jewel/window/DecoratedWindowKt { public static final fun DecoratedWindow (Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/window/WindowState;ZLjava/lang/String;Landroidx/compose/ui/graphics/painter/Painter;ZZZZLkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lorg/jetbrains/jewel/window/styling/DecoratedWindowStyle;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;III)V } diff --git a/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.MacOS.kt b/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.MacOS.kt index 4d46f32b11..2db0326332 100644 --- a/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.MacOS.kt +++ b/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.MacOS.kt @@ -1,6 +1,8 @@ package org.jetbrains.jewel.window import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier @@ -64,22 +66,30 @@ internal fun DecoratedWindowScope.TitleBarOnMacOs( } } + // These properties also have a typoed name, so just in case, we set them both. if (newFullscreenControls) { - System.setProperty("apple.awt.newFullScreeControls", true.toString()) + System.setProperty("apple.awt.newFullScreeControls", "true") + System.setProperty("apple.awt.newFullScreenControls", "true") System.setProperty( "apple.awt.newFullScreeControls.background", "${style.colors.fullscreenControlButtonsBackground.toArgb()}", ) + System.setProperty( + "apple.awt.newFullScreenControls.background", + "${style.colors.fullscreenControlButtonsBackground.toArgb()}", + ) MacUtil.updateColors(window) } else { System.clearProperty("apple.awt.newFullScreeControls") + System.clearProperty("apple.awt.newFullScreenControls") System.clearProperty("apple.awt.newFullScreeControls.background") + System.clearProperty("apple.awt.newFullScreenControls.background") } val titleBar = remember { JBR.getWindowDecorations().createCustomTitleBar() } TitleBarImpl( - modifier = modifier.customTitleBarMouseEventHandler(titleBar), + modifier = modifier, gradientStartColor = gradientStartColor, style = style, applyTitleBar = { height, state -> @@ -95,6 +105,7 @@ internal fun DecoratedWindowScope.TitleBarOnMacOs( PaddingValues(start = titleBar.leftInset.dp, end = titleBar.rightInset.dp) } }, + backgroundContent = { Spacer(modifier = modifier.fillMaxSize().customTitleBarMouseEventHandler(titleBar)) }, content = content, ) } diff --git a/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.Windows.kt b/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.Windows.kt index efef53dea4..88dde47b44 100644 --- a/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.Windows.kt +++ b/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.Windows.kt @@ -7,14 +7,8 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.pointer.PointerEventPass -import androidx.compose.ui.input.pointer.PointerEventType -import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.unit.dp import com.jetbrains.JBR -import com.jetbrains.WindowDecorations.CustomTitleBar -import kotlinx.coroutines.currentCoroutineContext -import kotlinx.coroutines.isActive import org.jetbrains.jewel.foundation.theme.JewelTheme import org.jetbrains.jewel.ui.util.isDark import org.jetbrains.jewel.window.styling.TitleBarStyle @@ -38,33 +32,7 @@ internal fun DecoratedWindowScope.TitleBarOnWindows( JBR.getWindowDecorations().setCustomTitleBar(window, titleBar) PaddingValues(start = titleBar.leftInset.dp, end = titleBar.rightInset.dp) }, - backgroundContent = { - Spacer(modifier = modifier.fillMaxSize().customTitleBarMouseEventHandler(titleBar)) - }, + backgroundContent = { Spacer(modifier = modifier.fillMaxSize().customTitleBarMouseEventHandler(titleBar)) }, content = content, ) } - -internal fun Modifier.customTitleBarMouseEventHandler(titleBar: CustomTitleBar): Modifier = - pointerInput(Unit) { - val currentContext = currentCoroutineContext() - awaitPointerEventScope { - var inUserControl = false - while (currentContext.isActive) { - val event = awaitPointerEvent(PointerEventPass.Main) - event.changes.forEach { - if (!it.isConsumed && !inUserControl) { - titleBar.forceHitTest(false) - } else { - if (event.type == PointerEventType.Press) { - inUserControl = true - } - if (event.type == PointerEventType.Release) { - inUserControl = false - } - titleBar.forceHitTest(true) - } - } - } - } - } diff --git a/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.kt b/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.kt index a5559a4187..9a6a91db48 100644 --- a/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.kt +++ b/decorated-window/src/main/kotlin/org/jetbrains/jewel/window/TitleBar.kt @@ -20,6 +20,9 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.isUnspecified import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.input.pointer.PointerEventPass +import androidx.compose.ui.input.pointer.PointerEventType +import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.Layout import androidx.compose.ui.layout.Measurable import androidx.compose.ui.layout.MeasurePolicy @@ -40,8 +43,12 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.offset +import com.jetbrains.WindowDecorations.CustomTitleBar import java.awt.Window +import kotlin.collections.forEach import kotlin.math.max +import kotlinx.coroutines.currentCoroutineContext +import kotlinx.coroutines.isActive import org.jetbrains.jewel.foundation.theme.JewelTheme import org.jetbrains.jewel.foundation.theme.LocalContentColor import org.jetbrains.jewel.foundation.theme.OverrideDarkMode @@ -106,13 +113,14 @@ internal fun DecoratedWindowScope.TitleBarImpl( } Box( - modifier = modifier - .background(backgroundBrush) - .focusProperties { canFocus = false } - .layoutId(TITLE_BAR_LAYOUT_ID) - .height(style.metrics.height) - .onSizeChanged { with(density) { applyTitleBar(it.height.toDp(), state) } } - .fillMaxWidth() + modifier = + modifier + .background(backgroundBrush) + .focusProperties { canFocus = false } + .layoutId(TITLE_BAR_LAYOUT_ID) + .height(style.metrics.height) + .onSizeChanged { with(density) { applyTitleBar(it.height.toDp(), state) } } + .fillMaxWidth() ) { backgroundContent() Layout( @@ -280,3 +288,28 @@ private class TitleBarChildDataNode(var horizontalAlignment: Alignment.Horizonta ParentDataModifierNode, Modifier.Node() { override fun Density.modifyParentData(parentData: Any?) = this@TitleBarChildDataNode } + +internal fun Modifier.customTitleBarMouseEventHandler(titleBar: CustomTitleBar): Modifier = + pointerInput(Unit) { + val currentContext = currentCoroutineContext() + awaitPointerEventScope { + var inUserControl = false + while (currentContext.isActive) { + val event = awaitPointerEvent(PointerEventPass.Main) + event.changes.forEach { change -> + if (!change.isConsumed && !inUserControl) { + titleBar.forceHitTest(false) + } else { + if (event.type == PointerEventType.Press) { + inUserControl = true + } else if (event.type == PointerEventType.Release) { + inUserControl = false + } + + titleBar.forceHitTest(true) + } + change.toString() + } + } + } + }