diff --git a/compose/foundation/foundation/build.gradle b/compose/foundation/foundation/build.gradle index 258eed995a738..835edc10832f7 100644 --- a/compose/foundation/foundation/build.gradle +++ b/compose/foundation/foundation/build.gradle @@ -131,6 +131,7 @@ if (AndroidXComposePlugin.isMultiplatformEnabled(project)) { dependsOn(skikoMain) dependencies { implementation(libs.kotlinStdlib) + implementation(libs.jbrApi) } } nonJvmMain.dependsOn(skikoMain) diff --git a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/window/WindowDraggableArea.desktop.kt b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/window/WindowDraggableArea.desktop.kt index dda1ad5f19482..d725238035adc 100644 --- a/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/window/WindowDraggableArea.desktop.kt +++ b/compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/window/WindowDraggableArea.desktop.kt @@ -25,6 +25,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.window.WindowScope +import com.jetbrains.JBR import java.awt.MouseInfo import java.awt.Point import java.awt.Window @@ -43,18 +44,20 @@ fun WindowScope.WindowDraggableArea( modifier: Modifier = Modifier, content: @Composable () -> Unit = {} ) { - val handler = remember { DragHandler(window) } - + val windowMoveHandler = remember(window) { + // Currently (Jan 2026), isWindowMoveSupported==true only on Linux + if (JBR.isWindowMoveSupported()) JbrMoveHandler(window) else StandardMoveHandler(window) + } Box( modifier = modifier.pointerInput(Unit) { awaitEachGesture { awaitFirstDown() - handler.onDragStarted() + windowMoveHandler.startMovingTogetherWithMouse() } - } - ) { - content() - } + }, + propagateMinConstraints = true, + content = { content() } + ) } /** @@ -69,9 +72,13 @@ private fun currentPointerLocation(): IntOffset? { return MouseInfo.getPointerInfo()?.location?.toComposeOffset() } -private class DragHandler( +private interface WindowMoveHandler { + fun startMovingTogetherWithMouse() +} + +private class StandardMoveHandler( private val window: Window -) { +) : WindowMoveHandler { private var windowLocationAtDragStart: IntOffset? = null private var dragStartPoint: IntOffset? = null @@ -85,7 +92,7 @@ private class DragHandler( } } - fun onDragStarted() { + override fun startMovingTogetherWithMouse() { dragStartPoint = currentPointerLocation() ?: return windowLocationAtDragStart = window.location.toComposeOffset() @@ -100,6 +107,14 @@ private class DragHandler( val newLocation = windowLocationAtDragStart + (point - dragStartPoint) window.setLocation(newLocation.x, newLocation.y) } +} +private class JbrMoveHandler( + private val window: Window +) : WindowMoveHandler { + private val windowMove = JBR.getWindowMove() + override fun startMovingTogetherWithMouse() { + windowMove.startMovingTogetherWithMouse(window, MouseEvent.BUTTON1) + } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index be90920db03f4..dc860c4fb46da 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -40,6 +40,7 @@ hamcrestCore = "1.3" hilt = "2.49" incap = "0.2" javaxInject = "1" +jbrApi = "1.9.0" jcodec = "0.2.5" kotlin = "2.2.20" kotlinBenchmark = "0.4.11" @@ -160,6 +161,7 @@ intellijCore = { module = "com.android.tools.external.com-intellij:intellij-core intellijAnnotations = { module = "com.intellij:annotations", version = "12.0" } javapoet = { module = "com.squareup:javapoet", version = "1.13.0" } javaxInject = { module = "javax.inject:javax.inject", version.ref = "javaxInject" } +jbrApi = { module = "org.jetbrains.runtime:jbr-api", version.ref = "jbrApi" } jcodec = { module = "org.jcodec:jcodec", version.ref = "jcodec" } jcodecJavaSe = { module = "org.jcodec:jcodec-javase", version.ref = "jcodec" } johnrengelmanShadow = { module = "com.github.johnrengelman:shadow", version.ref = "shadow" }