From b9b5d687d4d79d433953c82858eac14df91c8469 Mon Sep 17 00:00:00 2001 From: Prateek batra Date: Thu, 12 Mar 2026 12:16:25 +0530 Subject: [PATCH 1/6] feat: adds new snippet region tag for DesktopWindowing --- .../adaptivelayouts/DesktopWindowing.kt | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt new file mode 100644 index 000000000..7658963d6 --- /dev/null +++ b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt @@ -0,0 +1,48 @@ +package com.example.compose.snippets.adaptivelayouts + +import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.captionBar +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.isCaptionBarVisible +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.windowInsetsTopHeight +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp + +// [START android_compose_desktop_window_insets_title] +@OptIn(ExperimentalLayoutApi::class) +@Composable +fun CaptionBar() { + if (WindowInsets.isCaptionBarVisible) { + Row( + modifier = Modifier + .windowInsetsTopHeight(WindowInsets.captionBar) + .fillMaxWidth() + .background( + if (isSystemInDarkTheme()) + Color.White + else Color.Black + + ), + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + "Caption Bar Title", + style = MaterialTheme.typography.titleMedium, + modifier = Modifier.padding(4.dp) + ) + } + } +} +// [END android_compose_desktop_window_insets_title] \ No newline at end of file From 78eba091511dfb4938abc11416257437b8e71297 Mon Sep 17 00:00:00 2001 From: prateekbatra-g <237188927+prateekbatra-g@users.noreply.github.com> Date: Thu, 12 Mar 2026 16:29:55 +0000 Subject: [PATCH 2/6] Apply Spotless --- .../snippets/adaptivelayouts/DesktopWindowing.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt index 7658963d6..199b2b4c1 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt @@ -1,3 +1,19 @@ +/* + * Copyright 2026 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.example.compose.snippets.adaptivelayouts import androidx.compose.foundation.background From 0f1c809a832619fd49a4edddd013673ebad4e1e0 Mon Sep 17 00:00:00 2001 From: Prateek batra Date: Fri, 20 Mar 2026 16:33:13 +0530 Subject: [PATCH 3/6] feat: adds drag and drop snippets for DesktopWindowing * Adds `DragAndDropSource` snippet region * Adds `DragAndDropTarget` snippet region --- .../adaptivelayouts/DesktopWindowing.kt | 95 +++++++++++++++++-- 1 file changed, 86 insertions(+), 9 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt index 199b2b4c1..f46a9b2a7 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -16,7 +16,15 @@ package com.example.compose.snippets.adaptivelayouts +import android.app.Activity +import android.app.PendingIntent +import android.content.ClipData +import android.content.ClipDescription +import android.content.Intent +import android.view.View import androidx.compose.foundation.background +import androidx.compose.foundation.draganddrop.dragAndDropSource +import androidx.compose.foundation.draganddrop.dragAndDropTarget import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.ExperimentalLayoutApi @@ -32,9 +40,17 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draganddrop.DragAndDropEvent +import androidx.compose.ui.draganddrop.DragAndDropTarget +import androidx.compose.ui.draganddrop.DragAndDropTransferData +import androidx.compose.ui.draganddrop.toAndroidDragEvent import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp +import androidx.core.app.ActivityCompat.requestDragAndDropPermissions +/** + * A custom Title Bar that respects the system caption bar insets. + */ // [START android_compose_desktop_window_insets_title] @OptIn(ExperimentalLayoutApi::class) @Composable @@ -44,21 +60,82 @@ fun CaptionBar() { modifier = Modifier .windowInsetsTopHeight(WindowInsets.captionBar) .fillMaxWidth() - .background( - if (isSystemInDarkTheme()) - Color.White - else Color.Black - - ), + .background(if (isSystemInDarkTheme()) Color.White else Color.Black), horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically ) { Text( - "Caption Bar Title", + text = "Caption Bar Title", style = MaterialTheme.typography.titleMedium, modifier = Modifier.padding(4.dp) ) } } } -// [END android_compose_desktop_window_insets_title] \ No newline at end of file +// [END android_compose_desktop_window_insets_title] + +/** + * Simple drag source for plain text data. + */ +// [START android_compose_desktop_drag_drop_source] +fun Modifier.dragAndDropSourceModifier(): Modifier = this.dragAndDropSource { _ -> + DragAndDropTransferData( + clipData = ClipData.newPlainText("label", "Your data"), + flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION + ) +} +// [END android_compose_desktop_drag_drop_source] + +/** + * Custom drag source that launches a new Activity instance when dropped. + */ +// [START android_compose_desktop_drag_drop_source_unhandled_flag] +fun Modifier.customDragAndDropSource(activity: Activity, itemId: String): Modifier = this.then( + Modifier.dragAndDropSource { _ -> + val intent = Intent.makeMainActivity(activity.componentName).apply { + putExtra("EXTRA_ITEM_ID", itemId) + flags = Intent.FLAG_ACTIVITY_NEW_TASK or + Intent.FLAG_ACTIVITY_MULTIPLE_TASK or + Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT + } + + val pendingIntent = PendingIntent.getActivity( + activity, 0, intent, PendingIntent.FLAG_IMMUTABLE + ) + + val data = ClipData( + "Item $itemId", + arrayOf(ClipDescription.MIMETYPE_TEXT_INTENT), + ClipData.Item.Builder().setIntentSender(pendingIntent.intentSender).build() + ) + + DragAndDropTransferData( + clipData = data, + flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION or + View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG, + ) + } +) +// [END android_compose_desktop_drag_drop_source_unhandled_flag] + +/** + * A target modifier configured to receive plain text drag events. + */ +// [START android_compose_desktop_drag_drop_target] +fun Modifier.dragAndDropTargetModifier(activity: Activity): Modifier = this.dragAndDropTarget( + shouldStartDragAndDrop = { event -> + event.toAndroidDragEvent().clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN) + }, + target = object : DragAndDropTarget { + override fun onDrop(event: DragAndDropEvent): Boolean { + requestDragAndDropPermissions(activity, event.toAndroidDragEvent()) + val clipData = event.toAndroidDragEvent().clipData + val item = clipData?.getItemAt(0)?.text + if (item != null) { + // Process the dropped text item here + } + return item != null + } + } +) +// [END android_compose_desktop_drag_drop_target] \ No newline at end of file From d2b42f49d4c1fb824f88b81894595de2b7f2e7fe Mon Sep 17 00:00:00 2001 From: prateekbatra-g <237188927+prateekbatra-g@users.noreply.github.com> Date: Tue, 24 Mar 2026 07:44:27 +0000 Subject: [PATCH 4/6] Apply Spotless --- .../compose/snippets/adaptivelayouts/DesktopWindowing.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt index f46a9b2a7..fe508e1a3 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt @@ -5,7 +5,7 @@ * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * https://www.apache.org/licenses/LICENSE-2.0 + * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, From 5912010775e3e3f5aa14b3db23c71e501211caaf Mon Sep 17 00:00:00 2001 From: Prateek batra Date: Fri, 27 Mar 2026 14:54:03 +0530 Subject: [PATCH 5/6] feat: adds transparent caption bar snippet for DesktopWindowing * Adds `TransparentActionBar` snippet region to demonstrate configuring transparent caption bar backgrounds via `WindowInsetsController`. --- .../snippets/adaptivelayouts/DesktopWindowing.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt index fe508e1a3..31658c89f 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt @@ -22,6 +22,7 @@ import android.content.ClipData import android.content.ClipDescription import android.content.Intent import android.view.View +import android.view.WindowInsetsController import androidx.compose.foundation.background import androidx.compose.foundation.draganddrop.dragAndDropSource import androidx.compose.foundation.draganddrop.dragAndDropTarget @@ -74,6 +75,20 @@ fun CaptionBar() { } // [END android_compose_desktop_window_insets_title] +/** + * Transparent System Caption Bar + */ +fun TransparentActionBar(activity: Activity) { + with(activity) { + // [START android_compose_desktop_window_transparent_caption] + window.insetsController?.setSystemBarsAppearance( + WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND, + WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND + ) + // [END android_compose_desktop_window_transparent_caption] + } +} + /** * Simple drag source for plain text data. */ From 17f067ba64da913bf603e333411c777aca09484a Mon Sep 17 00:00:00 2001 From: Prateek batra Date: Tue, 7 Apr 2026 18:10:11 +0530 Subject: [PATCH 6/6] refactor: update desktop windowing snippets * Wrap transparent action bar logic in `TransparentActionBarActivity` * Convert drag-and-drop source and target extension functions to standard functions --- .../adaptivelayouts/DesktopWindowing.kt | 65 ++++++++++--------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt index 31658c89f..3acb19319 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/adaptivelayouts/DesktopWindowing.kt @@ -21,6 +21,7 @@ import android.app.PendingIntent import android.content.ClipData import android.content.ClipDescription import android.content.Intent +import android.os.Bundle import android.view.View import android.view.WindowInsetsController import androidx.compose.foundation.background @@ -78,8 +79,9 @@ fun CaptionBar() { /** * Transparent System Caption Bar */ -fun TransparentActionBar(activity: Activity) { - with(activity) { +class TransparentActionBarActivity : Activity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) // [START android_compose_desktop_window_transparent_caption] window.insetsController?.setSystemBarsAppearance( WindowInsetsController.APPEARANCE_TRANSPARENT_CAPTION_BAR_BACKGROUND, @@ -89,23 +91,26 @@ fun TransparentActionBar(activity: Activity) { } } + /** * Simple drag source for plain text data. */ -// [START android_compose_desktop_drag_drop_source] -fun Modifier.dragAndDropSourceModifier(): Modifier = this.dragAndDropSource { _ -> - DragAndDropTransferData( - clipData = ClipData.newPlainText("label", "Your data"), - flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION - ) +fun dragAndDropSourceModifier() { + // [START android_compose_desktop_drag_drop_source] + Modifier.dragAndDropSource { _ -> + DragAndDropTransferData( + clipData = ClipData.newPlainText("label", "Your data"), + flags = View.DRAG_FLAG_GLOBAL_SAME_APPLICATION + ) + } + // [END android_compose_desktop_drag_drop_source] } -// [END android_compose_desktop_drag_drop_source] /** * Custom drag source that launches a new Activity instance when dropped. */ -// [START android_compose_desktop_drag_drop_source_unhandled_flag] -fun Modifier.customDragAndDropSource(activity: Activity, itemId: String): Modifier = this.then( +fun customDragAndDropSource(activity: Activity, itemId: String) { + // [START android_compose_desktop_drag_drop_source_unhandled_flag] Modifier.dragAndDropSource { _ -> val intent = Intent.makeMainActivity(activity.componentName).apply { putExtra("EXTRA_ITEM_ID", itemId) @@ -130,27 +135,29 @@ fun Modifier.customDragAndDropSource(activity: Activity, itemId: String): Modifi View.DRAG_FLAG_START_INTENT_SENDER_ON_UNHANDLED_DRAG, ) } -) -// [END android_compose_desktop_drag_drop_source_unhandled_flag] + // [END android_compose_desktop_drag_drop_source_unhandled_flag] +} /** * A target modifier configured to receive plain text drag events. */ -// [START android_compose_desktop_drag_drop_target] -fun Modifier.dragAndDropTargetModifier(activity: Activity): Modifier = this.dragAndDropTarget( - shouldStartDragAndDrop = { event -> - event.toAndroidDragEvent().clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN) - }, - target = object : DragAndDropTarget { - override fun onDrop(event: DragAndDropEvent): Boolean { - requestDragAndDropPermissions(activity, event.toAndroidDragEvent()) - val clipData = event.toAndroidDragEvent().clipData - val item = clipData?.getItemAt(0)?.text - if (item != null) { - // Process the dropped text item here +fun dragAndDropTargetModifier(activity: Activity) { + // [START android_compose_desktop_drag_drop_target] + Modifier.dragAndDropTarget( + shouldStartDragAndDrop = { event -> + event.toAndroidDragEvent().clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN) + }, + target = object : DragAndDropTarget { + override fun onDrop(event: DragAndDropEvent): Boolean { + requestDragAndDropPermissions(activity, event.toAndroidDragEvent()) + val clipData = event.toAndroidDragEvent().clipData + val item = clipData?.getItemAt(0)?.text + if (item != null) { + // Process the dropped text item here + } + return item != null } - return item != null } - } -) -// [END android_compose_desktop_drag_drop_target] \ No newline at end of file + ) + // [END android_compose_desktop_drag_drop_target] +}