瀏覽代碼

clean build log of warnings

Milan Jurkulak 3 月之前
父節點
當前提交
da11bb56a8
共有 100 個文件被更改,包括 834 次插入 和 542 次删除
  1. 2 1
      .claude/settings.local.json
  2. 57 27
      androidApp/androidApp.gradle.kts
  3. 175 116
      build.gradle.kts
  4. 143 93
      compositor/compositor.gradle.kts
  5. 4 1
      compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/Clog.kt
  6. 13 13
      compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/GeometryStore.kt
  7. 110 71
      compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/Ipc.kt
  8. 93 42
      compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/Main.kt
  9. 28 19
      compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/Policy.kt
  10. 9 5
      compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/Session.kt
  11. 12 14
      compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/WindowModel.kt
  12. 31 10
      desktopApp/desktopApp.gradle.kts
  13. 11 12
      desktopApp/src/main/kotlin/org/mjdev/desktop/main/Main.kt
  14. 8 7
      gradle.properties
  15. 18 0
      gradle/libs.versions.toml
  16. 13 12
      settings.gradle.kts
  17. 20 14
      shared/shared.gradle.kts
  18. 1 1
      shared/src/androidMain/kotlin/org/mjdev/desktop/context/DesktopContext.kt
  19. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/adb/AdbScreenMirror.kt
  20. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/appbar/AppBar.kt
  21. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/appsmenu/AppsMenu.kt
  22. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/appsmenu/components/AppsBottomBar.kt
  23. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/appsmenu/components/AppsList.kt
  24. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/appsmenu/components/AppsMenuActions.kt
  25. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/appsmenu/components/AppsMenuApp.kt
  26. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/appsmenu/components/AppsMenuCategory.kt
  27. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/background/BackgroundImage.kt
  28. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/blur/BlurPanel.kt
  29. 2 2
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/blur/BlurPanelHaze.kt
  30. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/button/ButtonPrimary.kt
  31. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/button/ButtonSecondary.kt
  32. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/button/TransparentButton.kt
  33. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/Card.kt
  34. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/CardContent.kt
  35. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/ClassicCard.kt
  36. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/CompactCard.kt
  37. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/FocusableCard.kt
  38. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/ItemCard.kt
  39. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/PhotoCard.kt
  40. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/WideClassicCard.kt
  41. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/chart/DonutChart.kt
  42. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/chromecast/ChromecastView.kt
  43. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/ControlCenter.kt
  44. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/base/ControlCenterPage.kt
  45. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/base/PageHeader.kt
  46. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/about/AboutPage.kt
  47. 3 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/ai/AIPage.kt
  48. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/bluetooth/BluetoothSettingsPage.kt
  49. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/desktop/DesktopSettingsPage.kt
  50. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/devices/Devices.kt
  51. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/display/DisplaySettingsPage.kt
  52. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/ethernet/EthSettingsPage.kt
  53. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/main/MainSettingsPage.kt
  54. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/remotes/RemotesSettingsPage.kt
  55. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/sound/SoundSettingsPage.kt
  56. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/theme/ThemeSettingsPage.kt
  57. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/wifi/WifiRow.kt
  58. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/wifi/WifiSettingsPage.kt
  59. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/settings/SettingsSection.kt
  60. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/settings/SettingsSelectRow.kt
  61. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/settings/SettingsSliderRow.kt
  62. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/settings/SettingsSwitchRow.kt
  63. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/BrushedLayout.kt
  64. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/Clock.kt
  65. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/DateTime.kt
  66. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/MeasureUnconstrainedView.kt
  67. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/NeonCircle.kt
  68. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/PowerBlock.kt
  69. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/VerticalScrollableBox.kt
  70. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktop/Desktop.kt
  71. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktop/widgets/MemoryChart.kt
  72. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/DesktopPanel.kt
  73. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopMenuIcon.kt
  74. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopPanelDateTime.kt
  75. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopPanelFavoriteApps.kt
  76. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopPanelIcon.kt
  77. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopPanelLanguage.kt
  78. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopPanelText.kt
  79. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopPanelTray.kt
  80. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/draggable/DraggableView.kt
  81. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/file/FolderIcon.kt
  82. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/file/FolderView.kt
  83. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/fonticon/FontIcon.kt
  84. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/gallery/BoxWithControls.kt
  85. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/gallery/Gallery.kt
  86. 2 2
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/gallery/ItemInfo.kt
  87. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/greeter/Greeter.kt
  88. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/grid/GridPlaced.kt
  89. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/guide/GuideView.kt
  90. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/icon/ShapedIcon.kt
  91. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/icon/WifiLevelIcon.kt
  92. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/image/GifView.kt
  93. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/image/ImageAny.kt
  94. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/image/PhotoImage.kt
  95. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/immersivelist/ImmersiveList.kt
  96. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/info/Info.kt
  97. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/input/PasswordTextView.kt
  98. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/input/SearchFieldPassive.kt
  99. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/input/SelectableOutlineEditText.kt
  100. 1 1
      shared/src/commonMain/kotlin/org/mjdev/desktop/components/installer/Installer.kt

+ 2 - 1
.claude/settings.local.json

@@ -38,7 +38,8 @@
       "Bash(xargs ls -la)",
       "Bash(./gradlew :compositor:help --task installDesktop -q)",
       "Bash(git ls-tree *)",
-      "Bash(grep -iE \"iso|live-build|debootstrap|\\\\.sh$\")"
+      "Bash(grep -iE \"iso|live-build|debootstrap|\\\\.sh$\")",
+      "Bash(echo \"EXIT: $?\")"
     ]
   }
 }

+ 57 - 27
androidApp/androidApp.gradle.kts

@@ -6,19 +6,39 @@ plugins {
 
 android {
     namespace = "org.mjdev.desktop"
-    compileSdk = libs.versions.android.compile.sdk.get().toInt()
+    compileSdk =
+        libs.versions.android.compile.sdk
+            .get()
+            .toInt()
     // shared resources packaged into the APK (lost when composeApp was split):
     //  - assets  <- commonMain/resources (icon fonts, translations, widgets, …)
     //  - resources <- commonMain/composeResources
-    sourceSets["main"].assets.srcDirs(rootDir.resolve("shared/src/commonMain/resources"))
-    sourceSets["main"].resources.srcDirs(rootDir.resolve("shared/src/commonMain/composeResources"))
+    sourceSets["main"].assets.directories.add(rootDir.resolve("shared/src/commonMain/resources").path)
+    sourceSets["main"].resources.directories.add(rootDir.resolve("shared/src/commonMain/composeResources").path)
     defaultConfig {
         applicationId = "org.mjdev.desktop"
-        minSdk = libs.versions.android.min.sdk.get().toInt()
-        targetSdk = libs.versions.android.target.sdk.get().toInt()
-        versionCode = libs.versions.app.pkg.version.get().replace(".", "").toInt()
-        versionName = libs.versions.app.pkg.version.get()
-        resValue("string", "app_name", libs.versions.app.name.get())
+        minSdk =
+            libs.versions.android.min.sdk
+                .get()
+                .toInt()
+        targetSdk =
+            libs.versions.android.target.sdk
+                .get()
+                .toInt()
+        versionCode =
+            libs.versions.app.pkg.version
+                .get()
+                .replace(".", "")
+                .toInt()
+        versionName =
+            libs.versions.app.pkg.version
+                .get()
+        resValue(
+            "string",
+            "app_name",
+            libs.versions.app.name
+                .get(),
+        )
     }
     packaging {
         resources {
@@ -33,18 +53,25 @@ android {
     // properties (local ~/.gradle/gradle.properties) — never hardcoded. When no release
     // keystore is configured we fall back to the debug key so the release APK is still
     // *signed* and installable (an unsigned APK is rejected by Android on install).
-    val releaseStoreFile = (providers.environmentVariable("ANDROID_KEYSTORE_FILE").orNull
-        ?: providers.gradleProperty("android.keystore.file").orNull)?.let(::file)
-    val releaseStorePassword = providers.environmentVariable("ANDROID_KEYSTORE_PASSWORD").orNull
-        ?: providers.gradleProperty("android.keystore.password").orNull
-    val releaseKeyAlias = providers.environmentVariable("ANDROID_KEY_ALIAS").orNull
-        ?: providers.gradleProperty("android.key.alias").orNull
-    val releaseKeyPassword = providers.environmentVariable("ANDROID_KEY_PASSWORD").orNull
-        ?: providers.gradleProperty("android.key.password").orNull
-    val hasReleaseKeystore = releaseStoreFile?.exists() == true &&
-        !releaseStorePassword.isNullOrBlank() &&
-        !releaseKeyAlias.isNullOrBlank() &&
-        !releaseKeyPassword.isNullOrBlank()
+    val releaseStoreFile =
+        (
+            providers.environmentVariable("ANDROID_KEYSTORE_FILE").orNull
+                ?: providers.gradleProperty("android.keystore.file").orNull
+        )?.let(::file)
+    val releaseStorePassword =
+        providers.environmentVariable("ANDROID_KEYSTORE_PASSWORD").orNull
+            ?: providers.gradleProperty("android.keystore.password").orNull
+    val releaseKeyAlias =
+        providers.environmentVariable("ANDROID_KEY_ALIAS").orNull
+            ?: providers.gradleProperty("android.key.alias").orNull
+    val releaseKeyPassword =
+        providers.environmentVariable("ANDROID_KEY_PASSWORD").orNull
+            ?: providers.gradleProperty("android.key.password").orNull
+    val hasReleaseKeystore =
+        releaseStoreFile?.exists() == true &&
+            !releaseStorePassword.isNullOrBlank() &&
+            !releaseKeyAlias.isNullOrBlank() &&
+            !releaseKeyPassword.isNullOrBlank()
 
     signingConfigs {
         if (hasReleaseKeystore) {
@@ -74,18 +101,21 @@ android {
     buildFeatures {
         compose = true
         buildConfig = true
+        // app_name resValue above — declared per-module so the deprecated global
+        // android.defaults.buildfeatures.resvalues property could be dropped
+        resValues = true
     }
 }
 
 dependencies {
     implementation(projects.shared)
-    implementation(compose.runtime)
-    implementation(compose.foundation)
-    implementation(compose.material3)
-    implementation(compose.materialIconsExtended)
-    implementation(compose.ui)
-    implementation(compose.components.resources)
-    implementation(compose.components.uiToolingPreview)
+    implementation(libs.compose.runtime)
+    implementation(libs.compose.foundation)
+    implementation(libs.compose.material3)
+    implementation(libs.compose.material.icons.extended)
+    implementation(libs.compose.ui)
+    implementation(libs.compose.components.resources)
+    implementation(libs.compose.components.ui.tooling.preview)
     implementation(libs.androidx.activity.compose)
     implementation(libs.androidx.core.ktx)
     implementation(libs.androidx.lifecycle.viewmodel)

+ 175 - 116
build.gradle.kts

@@ -78,7 +78,11 @@ val collectKtlintReports by tasks.registering(Copy::class) {
     into(reportsDir.dir("ktlint"))
     duplicatesStrategy = DuplicatesStrategy.INCLUDE
     // ensure reports are produced before we collect them
-    mustRunAfter(allprojects.flatMap { p -> p.tasks.matching { it.name == "ktlintCheck" || it.name == "ktlintFormat" } })
+    mustRunAfter(
+        allprojects.flatMap { p ->
+            p.tasks.matching { it.name == "ktlintCheck" || it.name == "ktlintFormat" }
+        },
+    )
 }
 
 // Runs after every build: auto-format, ktlint report, and (gated) dependency-update report -> /reports
@@ -98,7 +102,7 @@ allprojects {
     }
 }
 
-//buildConfig {
+// buildConfig {
 //    generateAtSync = true
 //    sourceSets  {
 //        main {
@@ -123,13 +127,13 @@ allprojects {
 //    buildConfigField("FILE", File("aFile"))
 //    buildConfigField("URI", uri("https://example.io"))
 //    buildConfigField("com.github.gmazzo.buildconfig.demos.kts.SomeData", "DATA", "SomeData(\"a\", 1)")
-//}
+// }
 
-//dependencies {
+// dependencies {
 //    kover(project(":composeApp"))
-//}
+// }
 
-//kover { reports { total { xml { onCheck = true } } } }
+// kover { reports { total { xml { onCheck = true } } } }
 
 // Aggregate task: build every distributable that this host can produce.
 //  - desktop: Deb + AppImage + Rpm (per the targetFormats in composeApp), release mode
@@ -137,31 +141,37 @@ allprojects {
 //  - ios:     only when an iOS Kotlin target is configured AND the host is macOS
 //             (Kotlin/Native for iOS cannot build on Linux/Windows) — wired below if present.
 // captured at configuration time -> all the tasks below stay configuration-cache safe
-val appNameV = libs.versions.app.name.get()
-val versionV = libs.versions.app.pkg.version.get()
+val appNameV =
+    libs.versions.app.name
+        .get()
+val versionV =
+    libs.versions.app.pkg.version
+        .get()
 val pkgDirV = rootDir.resolve("packages/main-release")
 val appImageToolPath = rootDir.resolve(".gradle/tools/appimagetool-x86_64.AppImage").absolutePath
 
 // Downloads appimagetool before the build (only if not already present / on PATH).
-val ensureAppImageTool = tasks.register<EnsureAppImageToolTask>("ensureAppImageTool") {
-    group = "mjdev"
-    description = "Downloads appimagetool (single-file .AppImage builder) if not already present."
-    toolPath.set(appImageToolPath)
-    outputs.file(appImageToolPath)
-}
+val ensureAppImageTool =
+    tasks.register<EnsureAppImageToolTask>("ensureAppImageTool") {
+        group = "mjdev"
+        description = "Downloads appimagetool (single-file .AppImage builder) if not already present."
+        toolPath.set(appImageToolPath)
+        outputs.file(appImageToolPath)
+    }
 
 // Wraps the jpackage app-image directory into a single, CLI-runnable .AppImage file.
-val packageAppImageFile = tasks.register<PackageAppImageTask>("packageAppImageFile") {
-    group = "mjdev"
-    description = "Builds a single-file .AppImage from the jpackage app-image (skips if appimagetool unavailable)."
-    dependsOn(ensureAppImageTool, ":desktopApp:packageReleaseAppImage")
-    appName.set(appNameV)
-    appImagePath.set(pkgDirV.resolve("app/$appNameV").absolutePath)
-    outputPath.set(pkgDirV.resolve("appimage/$appNameV.AppImage").absolutePath)
-    toolPath.set(appImageToolPath)
-    inputs.dir(pkgDirV.resolve("app/$appNameV"))
-    outputs.file(pkgDirV.resolve("appimage/$appNameV.AppImage"))
-}
+val packageAppImageFile =
+    tasks.register<PackageAppImageTask>("packageAppImageFile") {
+        group = "mjdev"
+        description = "Builds a single-file .AppImage from the jpackage app-image (skips if appimagetool unavailable)."
+        dependsOn(ensureAppImageTool, ":desktopApp:packageReleaseAppImage")
+        appName.set(appNameV)
+        appImagePath.set(pkgDirV.resolve("app/$appNameV").absolutePath)
+        outputPath.set(pkgDirV.resolve("appimage/$appNameV.AppImage").absolutePath)
+        toolPath.set(appImageToolPath)
+        inputs.dir(pkgDirV.resolve("app/$appNameV"))
+        outputs.file(pkgDirV.resolve("appimage/$appNameV.AppImage"))
+    }
 
 // Turns the jpackage desktop .deb into a *complete, self-installable* package: injects the
 // compositor + session + wayland-sessions entry and declares the wayland runtime stack in
@@ -169,40 +179,60 @@ val packageAppImageFile = tasks.register<PackageAppImageTask>("packageAppImageFi
 // xwayland/mesa/... and the desktop actually starts. Overwrites the deb in place so every
 // downstream consumer (collectReleases, makeIso, installDesktop) uses the full deb.
 // runtime wayland stack from the version catalog (single source of truth — not hardcoded here).
-val compositorRuntimeDeps = libs.versions.app.compositor.runtime.deps.get().trim().split(Regex("\\s+"))
-val packageFullDeb = tasks.register<PackageFullDebTask>("packageFullDeb") {
-    group = "mjdev"
-    description = "Repacks the desktop .deb with the compositor + session + wayland runtime Depends (self-installable)."
-    dependsOn(":desktopApp:packageReleaseDeb", ":compositor:stageSession")
-    debDir.set(pkgDirV.resolve("deb").absolutePath)
-    sessionDir.set(rootDir.resolve("compositor/build/session-install").absolutePath)
-    runtimeDepends.set(compositorRuntimeDeps)
-    inputs.dir(rootDir.resolve("compositor/build/session-install"))
-    outputs.dir(pkgDirV.resolve("deb"))
-}
+val compositorRuntimeDeps =
+    libs.versions.app.compositor.runtime.deps
+        .get()
+        .trim()
+        .split(Regex("\\s+"))
+val packageFullDeb =
+    tasks.register<PackageFullDebTask>("packageFullDeb") {
+        group = "mjdev"
+        description =
+            "Repacks the desktop .deb with the compositor + session + wayland runtime Depends (self-installable)."
+        dependsOn(":desktopApp:packageReleaseDeb", ":compositor:stageSession")
+        debDir.set(pkgDirV.resolve("deb").absolutePath)
+        sessionDir.set(rootDir.resolve("compositor/build/session-install").absolutePath)
+        runtimeDepends.set(compositorRuntimeDeps)
+        inputs.dir(rootDir.resolve("compositor/build/session-install"))
+        outputs.dir(pkgDirV.resolve("deb"))
+    }
 
 // Copies all distributables into releases/ with version in the filename
 // (mjdev-desktop-<version>.<ext>). Copy = configuration-cache safe.
-val collectReleases = tasks.register<Copy>("collectReleases") {
-    group = "mjdev"
-    description = "Copies the built distributables into releases/ (versioned filenames)."
-    dependsOn(
-        ":desktopApp:packageReleaseDistributionForCurrentOS",
-        ":androidApp:assembleRelease",
-        packageAppImageFile,
-        packageFullDeb,
-    )
-    // local copies so the rename closures capture plain Strings (configuration-cache safe)
-    val base = "$appNameV-$versionV"
-    into(layout.projectDirectory.dir("releases"))
-    from(pkgDirV.resolve("deb")) { include("*.deb"); rename { "$base.deb" } }
-    from(pkgDirV.resolve("rpm")) { include("*.rpm"); rename { "$base.rpm" } }
-    from(pkgDirV.resolve("exe")) { include("*.exe"); rename { "$base.exe" } } // present only on a Windows host
-    from(pkgDirV.resolve("appimage")) { include("*.AppImage"); rename { "$base.AppImage" } }
-    from(rootDir.resolve("androidApp/build/outputs/apk/release")) {
-        include("*.apk"); rename { "$base.apk" }
+val collectReleases =
+    tasks.register<Copy>("collectReleases") {
+        group = "mjdev"
+        description = "Copies the built distributables into releases/ (versioned filenames)."
+        dependsOn(
+            ":desktopApp:packageReleaseDistributionForCurrentOS",
+            ":androidApp:assembleRelease",
+            packageAppImageFile,
+            packageFullDeb,
+        )
+        // local copies so the rename closures capture plain Strings (configuration-cache safe)
+        val base = "$appNameV-$versionV"
+        into(layout.projectDirectory.dir("releases"))
+        from(pkgDirV.resolve("deb")) {
+            include("*.deb")
+            rename { "$base.deb" }
+        }
+        from(pkgDirV.resolve("rpm")) {
+            include("*.rpm")
+            rename { "$base.rpm" }
+        }
+        from(pkgDirV.resolve("exe")) {
+            include("*.exe")
+            rename { "$base.exe" }
+        } // present only on a Windows host
+        from(pkgDirV.resolve("appimage")) {
+            include("*.AppImage")
+            rename { "$base.AppImage" }
+        }
+        from(rootDir.resolve("androidApp/build/outputs/apk/release")) {
+            include("*.apk")
+            rename { "$base.apk" }
+        }
     }
-}
 
 // Builds the bootable live ISO (releases/<app>-<ver>.iso) from the freshly built
 // desktop deb + compositor/session + the theme debs in deb-packages/, via make-iso.sh.
@@ -210,60 +240,84 @@ val collectReleases = tasks.register<Copy>("collectReleases") {
 // the script directly; otherwise pkexec shows a graphical password dialog (sudo cannot
 // prompt without a TTY). If the iso toolchain isn't installed the task logs a skip and
 // returns 0, so it never breaks buildAll on a plain dev machine.
-val makeIso = tasks.register("makeIso") {
-    group = "mjdev"
-    description = "Builds the minimal bootable mjdev desktop live ISO into releases/ (needs root / pkexec)."
-    dependsOn(packageFullDeb)
-    // capture plain Strings at configuration time — the doLast closure must not reference
-    // script-level vals (that captures the script instance, which is null under the
-    // configuration cache -> "Cannot invoke getDebDirV() because this$0 is null").
-    val isoOutPath = rootDir.resolve("releases/$appNameV-$versionV.iso").absolutePath
-    val makeIsoScriptPath = rootDir.resolve("make-iso.sh").absolutePath
-    val debDirPath = pkgDirV.resolve("deb").absolutePath
-    val sessionStagePath = rootDir.resolve("compositor/build/session-install").absolutePath
-    val extraDebsPath = rootDir.resolve("deb-packages").absolutePath
-    inputs.dir(pkgDirV.resolve("deb"))
-    inputs.dir(rootDir.resolve("compositor/build/session-install"))
-    inputs.dir(rootDir.resolve("deb-packages"))
-    outputs.file(isoOutPath)
-    doLast {
-        val isoTools = listOf("debootstrap", "mksquashfs", "xorriso", "grub-mkrescue")
-        // debootstrap/grub-mkrescue live in /usr/sbin — which is often absent from the Gradle
-        // daemon's PATH (notably on CI), so search the sbin dirs too or makeIso wrongly skips.
-        val toolDirs = (System.getenv("PATH").orEmpty().split(File.pathSeparator) +
-            listOf("/usr/sbin", "/sbin", "/usr/local/sbin")).filter { it.isNotEmpty() }
-        val missing = isoTools.filter { tool -> toolDirs.none { dir -> File(dir, tool).canExecute() } }
-        if (missing.isNotEmpty()) {
-            logger.warn("::warning::makeIso: skipping ISO — missing tools: ${missing.joinToString(" ")} " +
-                "(apt install debootstrap squashfs-tools xorriso grub-common grub-pc-bin grub-efi-amd64-bin)")
-            return@doLast
-        }
-        val deb = File(debDirPath).listFiles { f -> f.extension == "deb" }?.firstOrNull()
-            ?: error("desktop .deb not found in $debDirPath — run :desktopApp:packageReleaseDeb")
-        val args = mutableListOf<String>()
-        val isRoot = (System.getenv("USER") == "root") ||
-            runCatching { ProcessBuilder("id", "-u").start().inputStream.bufferedReader().readText().trim() == "0" }.getOrDefault(false)
-        when {
-            isRoot -> {}
-            File("/usr/bin/pkexec").canExecute() && !System.getenv("DISPLAY").isNullOrBlank() -> args += "pkexec"
-            else -> args += "sudo"
-        }
-        args += listOf("/bin/bash", makeIsoScriptPath,
-            "--deb", deb.absolutePath,
-            "--compositor-bin", File(sessionStagePath, "mjdevc").absolutePath,
-            "--session-dir", sessionStagePath,
-            "--extra-debs", extraDebsPath,
-            "--out", isoOutPath)
-        logger.lifecycle("makeIso: ${args.joinToString(" ")}")
-        val code = ProcessBuilder(args).inheritIO().start().waitFor()
-        if (code != 0) {
-            logger.warn(
-                "::warning::makeIso: make-iso.sh failed (exit $code) — ISO skipped; " +
-                    "other distributables are still published",
-            )
+val makeIso =
+    tasks.register("makeIso") {
+        group = "mjdev"
+        description = "Builds the minimal bootable mjdev desktop live ISO into releases/ (needs root / pkexec)."
+        dependsOn(packageFullDeb)
+        // capture plain Strings at configuration time — the doLast closure must not reference
+        // script-level vals (that captures the script instance, which is null under the
+        // configuration cache -> "Cannot invoke getDebDirV() because this$0 is null").
+        val isoOutPath = rootDir.resolve("releases/$appNameV-$versionV.iso").absolutePath
+        val makeIsoScriptPath = rootDir.resolve("make-iso.sh").absolutePath
+        val debDirPath = pkgDirV.resolve("deb").absolutePath
+        val sessionStagePath = rootDir.resolve("compositor/build/session-install").absolutePath
+        val extraDebsPath = rootDir.resolve("deb-packages").absolutePath
+        inputs.dir(pkgDirV.resolve("deb"))
+        inputs.dir(rootDir.resolve("compositor/build/session-install"))
+        inputs.dir(rootDir.resolve("deb-packages"))
+        outputs.file(isoOutPath)
+        doLast {
+            val isoTools = listOf("debootstrap", "mksquashfs", "xorriso", "grub-mkrescue")
+            // debootstrap/grub-mkrescue live in /usr/sbin — which is often absent from the Gradle
+            // daemon's PATH (notably on CI), so search the sbin dirs too or makeIso wrongly skips.
+            val toolDirs =
+                (
+                    System.getenv("PATH").orEmpty().split(File.pathSeparator) +
+                        listOf("/usr/sbin", "/sbin", "/usr/local/sbin")
+                ).filter { it.isNotEmpty() }
+            val missing = isoTools.filter { tool -> toolDirs.none { dir -> File(dir, tool).canExecute() } }
+            if (missing.isNotEmpty()) {
+                logger.warn(
+                    "::warning::makeIso: skipping ISO — missing tools: ${missing.joinToString(" ")} " +
+                        "(apt install debootstrap squashfs-tools xorriso grub-common grub-pc-bin grub-efi-amd64-bin)",
+                )
+                return@doLast
+            }
+            val deb =
+                File(debDirPath).listFiles { f -> f.extension == "deb" }?.firstOrNull()
+                    ?: error("desktop .deb not found in $debDirPath — run :desktopApp:packageReleaseDeb")
+            val args = mutableListOf<String>()
+            val isRoot =
+                (System.getenv("USER") == "root") ||
+                    runCatching {
+                        ProcessBuilder("id", "-u")
+                            .start()
+                            .inputStream
+                            .bufferedReader()
+                            .readText()
+                            .trim() == "0"
+                    }.getOrDefault(false)
+            when {
+                isRoot -> {}
+                File("/usr/bin/pkexec").canExecute() && !System.getenv("DISPLAY").isNullOrBlank() -> args += "pkexec"
+                else -> args += "sudo"
+            }
+            args +=
+                listOf(
+                    "/bin/bash",
+                    makeIsoScriptPath,
+                    "--deb",
+                    deb.absolutePath,
+                    "--compositor-bin",
+                    File(sessionStagePath, "mjdevc").absolutePath,
+                    "--session-dir",
+                    sessionStagePath,
+                    "--extra-debs",
+                    extraDebsPath,
+                    "--out",
+                    isoOutPath,
+                )
+            logger.lifecycle("makeIso: ${args.joinToString(" ")}")
+            val code = ProcessBuilder(args).inheritIO().start().waitFor()
+            if (code != 0) {
+                logger.warn(
+                    "::warning::makeIso: make-iso.sh failed (exit $code) — ISO skipped; " +
+                        "other distributables are still published",
+                )
+            }
         }
     }
-}
 
 // Boots the built ISO in QEMU (no root needed).
 tasks.register("runIsoQemu") {
@@ -280,22 +334,27 @@ tasks.register("runIsoQemu") {
 // make-iso.sh is slow or fails; makeIso never fails the aggregate (warn-only on error).
 makeIso.configure { mustRunAfter(collectReleases) }
 
-val buildAll = tasks.register("buildAll") {
-    group = "mjdev"
-    description = "Builds all distributables this host can produce, collects them into releases/ (stable names), and generates reports into reports/ — like every build."
-    dependsOn(collectReleases, makeIso, postBuildCodeCheck)
-}
+val buildAll =
+    tasks.register("buildAll") {
+        group = "mjdev"
+        description =
+            "Builds all distributables this host can produce, collects them into releases/ (stable names), and generates reports into reports/ — like every build."
+        dependsOn(collectReleases, makeIso, postBuildCodeCheck)
+    }
 
 // Attach iOS framework build only when an iOS target actually exists in composeApp
 // (it never does on a Linux/Windows host — Kotlin/Native iOS requires macOS + Xcode).
 project(":shared").afterEvaluate {
-    val iosTask = tasks.names.firstOrNull {
-        it.startsWith("linkReleaseFrameworkIos") || it == "embedAndSignAppleFrameworkForXcode"
-    }
+    val iosTask =
+        tasks.names.firstOrNull {
+            it.startsWith("linkReleaseFrameworkIos") || it == "embedAndSignAppleFrameworkForXcode"
+        }
     if (iosTask != null) {
         buildAll.configure { dependsOn("${this@afterEvaluate.path}:$iosTask") }
         logger.lifecycle("buildAll: iOS target found — wiring ${this@afterEvaluate.path}:$iosTask")
     } else {
-        logger.info("buildAll: no iOS target configured (needs macOS + Xcode + an ios* target in composeApp) — iOS skipped")
+        logger.info(
+            "buildAll: no iOS target configured (needs macOS + Xcode + an ios* target in composeApp) — iOS skipped",
+        )
     }
 }

+ 143 - 93
compositor/compositor.gradle.kts

@@ -24,72 +24,88 @@ val protocolsDir = layout.buildDirectory.dir("generated/protocols")
 val shimDir = layout.buildDirectory.dir("shim")
 
 // pkg-config is queried lazily and never fails configuration,
-// so the JVM desktop build stays usable on machines without wlroots
+// so the JVM desktop build stays usable on machines without wlroots.
+// providers.exec (not ProcessBuilder) keeps the call configuration-cache compatible —
+// gradle records it as a build input instead of reporting an external-process problem.
 fun pkgConfig(vararg args: String): List<String> = runCatching {
-    val process = ProcessBuilder(listOf("pkg-config") + args)
-        .redirectErrorStream(false)
-        .start()
-    val out = process.inputStream.bufferedReader().readText()
-    if (process.waitFor() != 0) emptyList()
-    else out.trim().split(Regex("\\s+")).filter { it.isNotBlank() }
+    val exec =
+        providers.exec {
+            commandLine(listOf("pkg-config") + args)
+            isIgnoreExitValue = true
+        }
+    if (exec.result.get().exitValue != 0) {
+        emptyList()
+    } else {
+        exec.standardOutput.asText
+            .get()
+            .trim()
+            .split(Regex("\\s+"))
+            .filter { it.isNotBlank() }
+    }
 }.getOrElse { emptyList() }
 
 val wlrPackages = arrayOf("wlroots-0.18", "wayland-server", "xkbcommon", "pixman-1")
 val wlrCflags: List<String>
     get() = pkgConfig("--cflags", *wlrPackages)
 val wlrLibs: List<String>
-    get() = pkgConfig("--libs", *wlrPackages).ifEmpty {
-        listOf("-lwlroots-0.18", "-lwayland-server", "-lxkbcommon")
-    }
+    get() =
+        pkgConfig("--libs", *wlrPackages).ifEmpty {
+            listOf("-lwlroots-0.18", "-lwayland-server", "-lxkbcommon")
+        }
 
 // the kotlin/native bundled linker does not search the system lib dirs
-val systemLibDirs = listOf(
-    "/usr/lib/x86_64-linux-gnu",
-    "/usr/lib",
-    "/usr/local/lib",
-).filter { file(it).isDirectory }.map { "-L$it" }
+val systemLibDirs =
+    listOf(
+        "/usr/lib/x86_64-linux-gnu",
+        "/usr/lib",
+        "/usr/local/lib",
+    ).filter { file(it).isDirectory }.map { "-L$it" }
 
-val generateProtocols = tasks.register<Exec>("generateProtocols") {
-    group = "mjdev"
-    description = "Generates wayland protocol headers used by the compositor shim."
-    val outDir = protocolsDir.get().asFile
-    val xdgShellXml = "/usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml"
-    inputs.files(xdgShellXml).optional()
-    outputs.dir(outDir)
-    commandLine(
-        "bash", "-c",
-        "mkdir -p '$outDir' && " +
-                "wayland-scanner server-header '$xdgShellXml' '$outDir/xdg-shell-protocol.h'"
-    )
-}
-
-val compileShim = tasks.register<Exec>("compileShim") {
-    group = "mjdev"
-    description = "Compiles the C shim over wlroots into a static library."
-    dependsOn(generateProtocols)
-    // capture everything as local values at configuration time so the doFirst closure
-    // never reaches back into the build script (required for configuration-cache safety)
-    val shimC = nativeDir.resolve("shim.c")
-    val shimH = nativeDir.resolve("shim.h")
-    val outDir = shimDir.get().asFile
-    val protoDir = protocolsDir.get().asFile
-    val includeDir = nativeDir
-    val cflags = wlrCflags.joinToString(" ")
-    inputs.files(shimC, shimH)
-    outputs.file(outDir.resolve("libmjcshim.a"))
-    doFirst {
+val generateProtocols =
+    tasks.register<Exec>("generateProtocols") {
+        group = "mjdev"
+        description = "Generates wayland protocol headers used by the compositor shim."
+        val outDir = protocolsDir.get().asFile
+        val xdgShellXml = "/usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml"
+        inputs.files(xdgShellXml).optional()
+        outputs.dir(outDir)
         commandLine(
-            "bash", "-c",
+            "bash",
+            "-c",
             "mkdir -p '$outDir' && " +
+                "wayland-scanner server-header '$xdgShellXml' '$outDir/xdg-shell-protocol.h'",
+        )
+    }
+
+val compileShim =
+    tasks.register<Exec>("compileShim") {
+        group = "mjdev"
+        description = "Compiles the C shim over wlroots into a static library."
+        dependsOn(generateProtocols)
+        // capture everything as local values at configuration time so the doFirst closure
+        // never reaches back into the build script (required for configuration-cache safety)
+        val shimC = nativeDir.resolve("shim.c")
+        val shimH = nativeDir.resolve("shim.h")
+        val outDir = shimDir.get().asFile
+        val protoDir = protocolsDir.get().asFile
+        val includeDir = nativeDir
+        val cflags = wlrCflags.joinToString(" ")
+        inputs.files(shimC, shimH)
+        outputs.file(outDir.resolve("libmjcshim.a"))
+        doFirst {
+            commandLine(
+                "bash",
+                "-c",
+                "mkdir -p '$outDir' && " +
                     "cc -O2 -fPIC -DWLR_USE_UNSTABLE -std=c11 " +
                     "-I'$protoDir' -I'$includeDir' $cflags " +
                     "-c '$shimC' -o '$outDir/shim.o' && " +
-                    "ar rcs '$outDir/libmjcshim.a' '$outDir/shim.o'"
-        )
+                    "ar rcs '$outDir/libmjcshim.a' '$outDir/shim.o'",
+            )
+        }
+        // placeholder, replaced in doFirst (Exec requires a commandLine at configuration)
+        commandLine("true")
     }
-    // placeholder, replaced in doFirst (Exec requires a commandLine at configuration)
-    commandLine("true")
-}
 
 kotlin {
     linuxX64 {
@@ -105,18 +121,28 @@ kotlin {
                 entryPoint = "eu.mjdev.compositor.main"
                 // link against the system glibc instead of the old bundled
                 // sysroot, system libs (wlroots & co) need modern symbols
-                val gccVersion = file("/usr/lib/gcc/x86_64-linux-gnu")
-                    .listFiles()?.map { it.name }?.maxByOrNull { it.toIntOrNull() ?: 0 }
+                val gccVersion =
+                    file("/usr/lib/gcc/x86_64-linux-gnu")
+                        .listFiles()
+                        ?.map { it.name }
+                        ?.maxByOrNull { it.toIntOrNull() ?: 0 }
                 if (gccVersion != null) {
-                    freeCompilerArgs += listOf(
-                        "-Xoverride-konan-properties=" +
+                    freeCompilerArgs +=
+                        listOf(
+                            "-Xoverride-konan-properties=" +
                                 "targetSysRoot.linux_x64=/;" +
                                 "libGcc.linux_x64=/usr/lib/gcc/x86_64-linux-gnu/$gccVersion;" +
-                                "crtFilesLocation.linux_x64=usr/lib/x86_64-linux-gnu"
-                    )
+                                "crtFilesLocation.linux_x64=usr/lib/x86_64-linux-gnu",
+                        )
                 }
                 linkerOpts(systemLibDirs)
-                linkerOpts(shimDir.get().asFile.resolve("libmjcshim.a").absolutePath)
+                linkerOpts(
+                    shimDir
+                        .get()
+                        .asFile
+                        .resolve("libmjcshim.a")
+                        .absolutePath,
+                )
                 linkerOpts(wlrLibs)
                 // the shim queries GL_RENDERER via EGL to decide hardware vs software GL for the
                 // shell (SKIKO_RENDER_API), so link the EGL + GLES2 dispatchers explicitly.
@@ -140,7 +166,8 @@ kotlin {
 // (you would keep running a stale executable).
 tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink>().configureEach {
     dependsOn(compileShim)
-    inputs.file(shimDir.map { it.file("libmjcshim.a") })
+    inputs
+        .file(shimDir.map { it.file("libmjcshim.a") })
         .withPropertyName("mjcShimLibrary")
 }
 // note: cinterop parses only the self contained shim.h,
@@ -166,11 +193,15 @@ tasks.register<Copy>("stageSession") {
 // stays configuration-cache safe (the function itself is never captured in the task action).
 // the wayland runtime stack mjdevc needs — from the version catalog (single source of truth,
 // shared with the deb Depends and make-iso.sh), never hardcoded here.
-val compositorRuntimeDeps: String = libs.versions.app.compositor.runtime.deps.get()
+val compositorRuntimeDeps: String =
+    libs.versions.app.compositor.runtime.deps
+        .get()
 
 // apt-get on the host must WAIT for the dpkg lock (unattended-upgrades, a parallel build, …)
 // instead of failing with "Could not get lock /var/lib/dpkg/lock-frontend" — catalog-driven.
-val aptLockTimeout: String = libs.versions.app.apt.lock.timeout.get()
+val aptLockTimeout: String =
+    libs.versions.app.apt.lock.timeout
+        .get()
 val aptGet = "apt-get -o DPkg::Lock::Timeout=$aptLockTimeout"
 
 fun sessionInstallLines(staged: File): List<String> = listOf(
@@ -183,7 +214,7 @@ fun sessionInstallLines(staged: File): List<String> = listOf(
     // (incl. llvmpipe software fallback). Without these mjdevc fails to even load -> black screen.
     "$aptGet update || true",
     "$aptGet install --no-install-recommends -y $compositorRuntimeDeps seatd || " +
-            "echo 'WARN: apt could not install the wayland runtime stack (offline or non-debian?) — the desktop may not start'",
+        "echo 'WARN: apt could not install the wayland runtime stack (offline or non-debian?) — the desktop may not start'",
     // the compositor opens /dev/dri/card0 + the seatd socket (group video); seatd must run and
     // the logged-in user must be in video/input/render (+ seat if present) or the session is black.
     "systemctl enable --now seatd 2>/dev/null || true",
@@ -194,8 +225,8 @@ fun sessionInstallLines(staged: File): List<String> = listOf(
     "install -Dm755 '${staged.resolve("mjdev-session")}' /usr/local/bin/mjdev-session",
     "install -Dm644 '${staged.resolve("mjdev.desktop")}' /usr/share/wayland-sessions/mjdev.desktop",
     "rm -f /usr/share/xsessions/mjdev-desktop.desktop " +
-            "/usr/share/gnome-session/sessions/mjdev-desktop.session " +
-            "/usr/share/applications/mjdev-desktop-mjdev-desktop.desktop",
+        "/usr/share/gnome-session/sessions/mjdev-desktop.session " +
+        "/usr/share/applications/mjdev-desktop-mjdev-desktop.desktop",
 )
 
 // sudo can't read a password from the Gradle daemon (no TTY), so these tasks don't exec it —
@@ -205,7 +236,11 @@ tasks.register("installSession") {
     group = "mjdev"
     description = "Stages the compositor + wayland session, prints the sudo install command."
     dependsOn("stageSession")
-    val staged = layout.buildDirectory.dir("session-install").get().asFile
+    val staged =
+        layout.buildDirectory
+            .dir("session-install")
+            .get()
+            .asFile
     val lines = sessionInstallLines(staged)
     doLast {
         val script = staged.resolve("install.sh")
@@ -223,25 +258,32 @@ tasks.register<Exec>("installDesktop") {
     group = "mjdev"
     description = "Builds compositor + session + app .deb and installs it via a pkexec authentication dialog."
     dependsOn("stageSession", ":desktopApp:packageReleaseDeb", ":packageFullDeb")
-    val staged = layout.buildDirectory.dir("session-install").get().asFile
+    val staged =
+        layout.buildDirectory
+            .dir("session-install")
+            .get()
+            .asFile
     val lines = sessionInstallLines(staged)
     // desktopApp overrides compose outputBaseDir to <root>/packages, so the .deb is written
     // to packages/main-release/deb (not desktopApp/build/compose/binaries/…)
     val debDir = rootProject.rootDir.resolve("packages/main-release/deb")
     isIgnoreExitValue = false
     doFirst {
-        val deb = debDir.listFiles { f -> f.extension == "deb" }?.firstOrNull()
-            ?: error("desktop .deb not found in $debDir — run :desktopApp:packageReleaseDeb")
+        val deb =
+            debDir.listFiles { f -> f.extension == "deb" }?.firstOrNull()
+                ?: error("desktop .deb not found in $debDir — run :desktopApp:packageReleaseDeb")
         val script = staged.resolve("install-desktop.sh")
         // install the deb via apt so its Depends (the wayland runtime stack baked in by
         // packageFullDeb) are resolved; fall back to dpkg + apt -f if the apt form is unavailable.
-        val installDeb = "$aptGet install --no-install-recommends -y '${deb.absolutePath}' || " +
+        val installDeb =
+            "$aptGet install --no-install-recommends -y '${deb.absolutePath}' || " +
                 "{ dpkg -i '${deb.absolutePath}' || true; $aptGet install -f -y; }"
         script.writeText((lines + installDeb).joinToString("\n") + "\n")
         // pkexec pops a graphical polkit auth dialog and runs the script as root; needs a polkit
         // agent in the session but no terminal. Fall back to a printed sudo command if absent.
-        val pkexec = listOf("/usr/bin/pkexec", "/usr/local/bin/pkexec")
-            .firstOrNull { File(it).canExecute() }
+        val pkexec =
+            listOf("/usr/bin/pkexec", "/usr/local/bin/pkexec")
+                .firstOrNull { File(it).canExecute() }
         if (pkexec != null) {
             println("Installing the mjdev desktop — approve the authentication dialog…")
             commandLine(pkexec, "sh", script.absolutePath)
@@ -259,9 +301,11 @@ tasks.register<Exec>("runNested") {
     description = "Runs the compositor nested inside the current Wayland session."
     dependsOn("linkMjdevcDebugExecutableLinuxX64")
     val shellCmd = (project.findProperty("shellCmd") as String?)
-    val binary = layout.buildDirectory
-        .file("bin/linuxX64/mjdevcDebugExecutable/mjdevc.kexe")
-        .get().asFile.absolutePath
+    val binary =
+        layout.buildDirectory
+            .file("bin/linuxX64/mjdevcDebugExecutable/mjdevc.kexe")
+            .get()
+            .asFile.absolutePath
     // x11 backend -> the host window manager decorates the nested window (frame + close +
     // move); 16:9 nested output (the compositor locks it against resize)
     environment("WLR_BACKENDS", "x11")
@@ -271,15 +315,16 @@ tasks.register<Exec>("runNested") {
         // the detached Gradle daemon often lacks a valid XAUTHORITY, and mutter writes a
         // per-session, randomly-suffixed auth file under XDG_RUNTIME_DIR
         environment("DISPLAY", System.getenv("DISPLAY") ?: ":0")
-        val xauthCandidates = buildList {
-            System.getenv("XAUTHORITY")?.let { add(File(it)) }
-            System.getenv("XDG_RUNTIME_DIR")?.let { dir ->
-                File(dir).listFiles()?.forEach { f ->
-                    if (f.name.startsWith(".mutter-Xwaylandauth.")) add(f)
+        val xauthCandidates =
+            buildList {
+                System.getenv("XAUTHORITY")?.let { add(File(it)) }
+                System.getenv("XDG_RUNTIME_DIR")?.let { dir ->
+                    File(dir).listFiles()?.forEach { f ->
+                        if (f.name.startsWith(".mutter-Xwaylandauth.")) add(f)
+                    }
                 }
+                add(File(System.getProperty("user.home"), ".Xauthority"))
             }
-            add(File(System.getProperty("user.home"), ".Xauthority"))
-        }
         xauthCandidates.firstOrNull { it.isFile }?.let { environment("XAUTHORITY", it.absolutePath) }
         val args = mutableListOf(binary)
         if (shellCmd != null) {
@@ -297,9 +342,11 @@ tasks.register<Exec>("runNestedDesktop") {
     group = "mjdev"
     description = "Runs the mjdev desktop app as a client inside the nested compositor."
     dependsOn("linkMjdevcDebugExecutableLinuxX64", ":desktopApp:createDistributable")
-    val binary = layout.buildDirectory
-        .file("bin/linuxX64/mjdevcDebugExecutable/mjdevc.kexe")
-        .get().asFile.absolutePath
+    val binary =
+        layout.buildDirectory
+            .file("bin/linuxX64/mjdevcDebugExecutable/mjdevc.kexe")
+            .get()
+            .asFile.absolutePath
     // desktopApp overrides outputBaseDir to <root>/packages, so createDistributable
     // writes the app image to packages/main/app/<name>/bin/<name> (not build/compose/…)
     val appDir = rootProject.rootDir.resolve("packages/main/app")
@@ -311,19 +358,22 @@ tasks.register<Exec>("runNestedDesktop") {
         // the detached Gradle daemon often lacks a valid XAUTHORITY, and mutter writes a
         // per-session, randomly-suffixed auth file under XDG_RUNTIME_DIR
         environment("DISPLAY", System.getenv("DISPLAY") ?: ":0")
-        val xauthCandidates = buildList {
-            System.getenv("XAUTHORITY")?.let { add(File(it)) }
-            System.getenv("XDG_RUNTIME_DIR")?.let { dir ->
-                File(dir).listFiles()?.forEach { f ->
-                    if (f.name.startsWith(".mutter-Xwaylandauth.")) add(f)
+        val xauthCandidates =
+            buildList {
+                System.getenv("XAUTHORITY")?.let { add(File(it)) }
+                System.getenv("XDG_RUNTIME_DIR")?.let { dir ->
+                    File(dir).listFiles()?.forEach { f ->
+                        if (f.name.startsWith(".mutter-Xwaylandauth.")) add(f)
+                    }
                 }
+                add(File(System.getProperty("user.home"), ".Xauthority"))
             }
-            add(File(System.getProperty("user.home"), ".Xauthority"))
-        }
         xauthCandidates.firstOrNull { it.isFile }?.let { environment("XAUTHORITY", it.absolutePath) }
-        val launcher = appDir.walkTopDown()
-            .firstOrNull { it.isFile && it.parentFile?.name == "bin" && it.canExecute() }
-            ?: error("desktop launcher not found under $appDir — run :desktopApp:createDistributable")
+        val launcher =
+            appDir
+                .walkTopDown()
+                .firstOrNull { it.isFile && it.parentFile?.name == "bin" && it.canExecute() }
+                ?: error("desktop launcher not found under $appDir — run :desktopApp:createDistributable")
         commandLine(binary, "--shell-cmd", launcher.absolutePath)
     }
     commandLine("true")

+ 4 - 1
compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/Clog.kt

@@ -33,7 +33,10 @@ object Clog {
     }
 
     /** medium-verbose: pointer is sampled, the rest is dropped to keep logs readable */
-    fun pointer(x: Int, y: Int) {
+    fun pointer(
+        x: Int,
+        y: Int,
+    ) {
         if (!verbose) return
         if (pointerCount++ % POINTER_SAMPLE == 0L) {
             println("mjdevc: pointer ($x, $y) [#$pointerCount, 1/$POINTER_SAMPLE sampled]")

+ 13 - 13
compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/GeometryStore.kt

@@ -10,11 +10,11 @@
 
 package eu.mjdev.compositor
 
+import kotlinx.cinterop.ByteVar
 import kotlinx.cinterop.ExperimentalForeignApi
 import kotlinx.cinterop.IntVar
 import kotlinx.cinterop.alloc
 import kotlinx.cinterop.allocArray
-import kotlinx.cinterop.ByteVar
 import kotlinx.cinterop.memScoped
 import kotlinx.cinterop.ptr
 import kotlinx.cinterop.toKString
@@ -38,7 +38,6 @@ import platform.posix.mkdir
  * across compositor restarts, so windows reopen where the user left them.
  */
 class GeometryStore {
-
     private val json = Json { ignoreUnknownKeys = true }
     private val serializer =
         MapSerializer(String.serializer(), ListSerializer(Int.serializer()))
@@ -47,8 +46,9 @@ class GeometryStore {
 
     init {
         val home = getenv("HOME")?.toKString() ?: "/tmp"
-        val stateBase = getenv("XDG_STATE_HOME")?.toKString()
-            ?: "$home/.local/state"
+        val stateBase =
+            getenv("XDG_STATE_HOME")?.toKString()
+                ?: "$home/.local/state"
         val dir = "$stateBase/mjdev"
         mkdir(stateBase, DIR_MODE)
         mkdir(dir, DIR_MODE)
@@ -91,21 +91,21 @@ class GeometryStore {
         }
     }
 
-    private fun keyOf(info: WindowInfo): String? =
-        info.appId?.lowercase()?.takeIf { it.isNotBlank() }
+    private fun keyOf(info: WindowInfo): String? = info.appId?.lowercase()?.takeIf { it.isNotBlank() }
 
     private fun load() {
         val file = fopen(path, "r") ?: return
         try {
-            val content = buildString {
-                memScoped {
-                    val buffer = allocArray<ByteVar>(READ_CHUNK)
-                    while (true) {
-                        val line = fgets(buffer, READ_CHUNK, file) ?: break
-                        append(line.toKString())
+            val content =
+                buildString {
+                    memScoped {
+                        val buffer = allocArray<ByteVar>(READ_CHUNK)
+                        while (true) {
+                            val line = fgets(buffer, READ_CHUNK, file) ?: break
+                            append(line.toKString())
+                        }
                     }
                 }
-            }
             if (content.isNotBlank()) {
                 entries.putAll(json.decodeFromString(serializer, content))
             }

+ 110 - 71
compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/Ipc.kt

@@ -19,27 +19,27 @@ import kotlinx.serialization.json.JsonArray
 import kotlinx.serialization.json.JsonNull
 import kotlinx.serialization.json.JsonObject
 import kotlinx.serialization.json.buildJsonObject
-import kotlinx.serialization.json.jsonObject
 import kotlinx.serialization.json.int
+import kotlinx.serialization.json.jsonObject
 import kotlinx.serialization.json.jsonPrimitive
 import kotlinx.serialization.json.long
 import kotlinx.serialization.json.put
 import mjdev.compositor.shim.MJC_EVENT_ERROR
 import mjdev.compositor.shim.MJC_EVENT_HANGUP
 import mjdev.compositor.shim.MJC_EVENT_READABLE
+import mjdev.compositor.shim.mjc_key
 import mjdev.compositor.shim.mjc_loop_add_fd
 import mjdev.compositor.shim.mjc_loop_remove_fd
-import mjdev.compositor.shim.mjc_key
 import mjdev.compositor.shim.mjc_pointer_button
 import mjdev.compositor.shim.mjc_pointer_move
-import mjdev.compositor.shim.mjc_view_focus
+import mjdev.compositor.shim.mjc_unix_accept
+import mjdev.compositor.shim.mjc_unix_listen
 import mjdev.compositor.shim.mjc_view_close
+import mjdev.compositor.shim.mjc_view_focus
 import mjdev.compositor.shim.mjc_view_is_maximized
 import mjdev.compositor.shim.mjc_view_set_maximized
 import mjdev.compositor.shim.mjc_view_set_minimized
 import mjdev.compositor.shim.mjc_view_set_position
-import mjdev.compositor.shim.mjc_unix_accept
-import mjdev.compositor.shim.mjc_unix_listen
 import platform.posix.EAGAIN
 import platform.posix.EWOULDBLOCK
 import platform.posix.close
@@ -74,9 +74,12 @@ private const val BTN_LEFT = 0x110
  *   {"event":"window-title","window":{...}}
  *   {"event":"focus-changed","window":{...}|null}
  */
-class IpcServer(private val c: Compositor) {
-
-    private class Client(val fd: Int) {
+class IpcServer(
+    private val c: Compositor,
+) {
+    private class Client(
+        val fd: Int,
+    ) {
         val buffer = StringBuilder()
         var subscribed = false
     }
@@ -106,7 +109,10 @@ class IpcServer(private val c: Compositor) {
         }
     }
 
-    fun handleFd(fd: Int, mask: UInt): Int {
+    fun handleFd(
+        fd: Int,
+        mask: UInt,
+    ): Int {
         if (fd == serverFd) {
             acceptClients()
             return 0
@@ -129,8 +135,9 @@ class IpcServer(private val c: Compositor) {
             clients[fd] = Client(fd)
             Clog.v("ipc client connected fd=$fd (clients=${clients.size})")
             mjc_loop_add_fd(
-                c.server, fd,
-                (MJC_EVENT_READABLE or MJC_EVENT_HANGUP or MJC_EVENT_ERROR).convert()
+                c.server,
+                fd,
+                (MJC_EVENT_READABLE or MJC_EVENT_HANGUP or MJC_EVENT_ERROR).convert(),
             )
         }
     }
@@ -139,9 +146,10 @@ class IpcServer(private val c: Compositor) {
         val client = clients[fd] ?: return
         val chunk = ByteArray(4096)
         while (true) {
-            val n = chunk.usePinned { pinned ->
-                read(fd, pinned.addressOf(0), chunk.size.convert()).toInt()
-            }
+            val n =
+                chunk.usePinned { pinned ->
+                    read(fd, pinned.addressOf(0), chunk.size.convert()).toInt()
+                }
             when {
                 n > 0 -> client.buffer.append(chunk.decodeToString(0, n))
                 n == 0 -> {
@@ -174,69 +182,90 @@ class IpcServer(private val c: Compositor) {
             val line = text.substring(0, newline).trim()
             client.buffer.deleteRange(0, newline + 1)
             if (line.isNotEmpty()) {
-                val response = runCatching { handleRequest(client, line) }
-                    .getOrElse { error ->
-                        buildJsonObject {
-                            put("ok", false)
-                            put("error", error.message ?: "invalid request")
+                val response =
+                    runCatching { handleRequest(client, line) }
+                        .getOrElse { error ->
+                            buildJsonObject {
+                                put("ok", false)
+                                put("error", error.message ?: "invalid request")
+                            }
                         }
-                    }
                 send(client.fd, response)
             }
         }
     }
 
-    private fun handleRequest(client: Client, line: String): JsonObject {
+    private fun handleRequest(
+        client: Client,
+        line: String,
+    ): JsonObject {
         val request = json.parseToJsonElement(line).jsonObject
-        val cmd = request["cmd"]?.jsonPrimitive?.content
-            ?: return error("missing cmd")
+        val cmd =
+            request["cmd"]?.jsonPrimitive?.content
+                ?: return error("missing cmd")
         Clog.v("ipc <- fd=${client.fd}: $line")
         return when (cmd) {
             "list-windows" -> {
                 val all = request["all"]?.jsonPrimitive?.content?.toBoolean() == true
-                val windows = if (all) {
-                    c.windows.all().filter { it.mapped }
-                } else {
-                    c.windows.listed()
-                }
+                val windows =
+                    if (all) {
+                        c.windows.all().filter { it.mapped }
+                    } else {
+                        c.windows.listed()
+                    }
                 ok { put("windows", JsonArray(windows.map { it.toJson() })) }
             }
 
             "windows-for-app" -> {
-                val appId = request["app_id"]?.jsonPrimitive?.content
-                    ?: return error("missing app_id")
+                val appId =
+                    request["app_id"]?.jsonPrimitive?.content
+                        ?: return error("missing app_id")
                 ok {
-                    put("windows", JsonArray(
-                        c.windows.listed().filter {
-                            it.appId?.contains(appId, ignoreCase = true) == true
-                        }.map { it.toJson() }
-                    ))
+                    put(
+                        "windows",
+                        JsonArray(
+                            c.windows
+                                .listed()
+                                .filter {
+                                    it.appId?.contains(appId, ignoreCase = true) == true
+                                }.map { it.toJson() },
+                        ),
+                    )
                 }
             }
 
-            "activate" -> withWindow(request) { info ->
-                if (info.minimized) {
-                    mjc_view_set_minimized(info.ptr, false)
-                    info.minimized = false
+            "activate" ->
+                withWindow(request) { info ->
+                    if (info.minimized) {
+                        mjc_view_set_minimized(info.ptr, false)
+                        info.minimized = false
+                    }
+                    mjc_view_focus(info.ptr)
                 }
-                mjc_view_focus(info.ptr)
-            }
 
             "close" -> withWindow(request) { mjc_view_close(it.ptr) }
 
-            "minimize" -> withWindow(request) { info ->
-                val minimized = request["minimized"]
-                    ?.jsonPrimitive?.content?.toBoolean() ?: true
-                mjc_view_set_minimized(info.ptr, minimized)
-                info.minimized = minimized
-            }
+            "minimize" ->
+                withWindow(request) { info ->
+                    val minimized =
+                        request["minimized"]
+                            ?.jsonPrimitive
+                            ?.content
+                            ?.toBoolean() ?: true
+                    mjc_view_set_minimized(info.ptr, minimized)
+                    info.minimized = minimized
+                }
 
-            "maximize" -> withWindow(request) { info ->
-                val maximized = request["maximized"]
-                    ?.jsonPrimitive?.content?.toBoolean()
-                    ?: !mjc_view_is_maximized(info.ptr)
-                mjc_view_set_maximized(info.ptr, maximized)
-            }
+            "maximize" ->
+                withWindow(request) { info ->
+                    val maximized =
+                        request["maximized"]
+                            ?.jsonPrimitive
+                            ?.content
+                            ?.toBoolean()
+                            ?: !mjc_view_is_maximized(info.ptr)
+                    mjc_view_set_maximized(info.ptr, maximized)
+                }
 
             "subscribe" -> {
                 client.subscribed = true
@@ -300,7 +329,7 @@ class IpcServer(private val c: Compositor) {
 
     private inline fun withWindow(
         request: JsonObject,
-        block: (WindowInfo) -> Unit
+        block: (WindowInfo) -> Unit,
     ): JsonObject {
         val id = request["id"]?.jsonPrimitive?.long ?: return error("missing id")
         val info = c.windows.byId(id) ?: return error("no window $id")
@@ -308,43 +337,53 @@ class IpcServer(private val c: Compositor) {
         return ok { }
     }
 
-    private inline fun ok(block: kotlinx.serialization.json.JsonObjectBuilder.() -> Unit) =
-        buildJsonObject {
-            put("ok", true)
-            block()
-        }
+    private inline fun ok(block: kotlinx.serialization.json.JsonObjectBuilder.() -> Unit) = buildJsonObject {
+        put("ok", true)
+        block()
+    }
 
     private fun error(message: String) = buildJsonObject {
         put("ok", false)
         put("error", message)
     }
 
-    fun broadcastEvent(event: String, info: WindowInfo?) {
+    fun broadcastEvent(
+        event: String,
+        info: WindowInfo?,
+    ) {
         val subscribers = clients.values.count { it.subscribed }
         if (subscribers == 0) {
             return
         }
         Clog.v("ipc -> $event to $subscribers subscriber(s): ${info?.describe() ?: "null"}")
-        val payload = buildJsonObject {
-            put("event", event)
-            put("window", info?.toJson() ?: JsonNull)
-        }
+        val payload =
+            buildJsonObject {
+                put("event", event)
+                put("window", info?.toJson() ?: JsonNull)
+            }
         clients.values.filter { it.subscribed }.forEach { send(it.fd, payload) }
     }
 
-    fun broadcastPointer(x: Int, y: Int) {
+    fun broadcastPointer(
+        x: Int,
+        y: Int,
+    ) {
         if (clients.values.none { it.subscribed }) {
             return
         }
-        val payload = buildJsonObject {
-            put("event", "pointer")
-            put("x", x)
-            put("y", y)
-        }
+        val payload =
+            buildJsonObject {
+                put("event", "pointer")
+                put("x", x)
+                put("y", y)
+            }
         clients.values.filter { it.subscribed }.forEach { send(it.fd, payload) }
     }
 
-    private fun send(fd: Int, payload: JsonObject) {
+    private fun send(
+        fd: Int,
+        payload: JsonObject,
+    ) {
         val data = (payload.toString() + "\n").encodeToByteArray()
         data.usePinned { pinned ->
             var offset = 0

+ 93 - 42
compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/Main.kt

@@ -54,7 +54,7 @@ class Config(
                     "--socket" -> socket = args[++i]
                     "--help", "-h" -> {
                         println(
-                            "mjdevc [--shell-cmd CMD] [--startup CMD]... [--session] [--socket PATH]"
+                            "mjdevc [--shell-cmd CMD] [--startup CMD]... [--session] [--socket PATH]",
                         )
                         platform.posix.exit(0)
                     }
@@ -72,9 +72,12 @@ class Config(
     }
 }
 
-class Compositor(val config: Config) {
-    val server: CPointer<mjc_server> = mjc_create()
-        ?: error("mjdevc: cannot allocate server")
+class Compositor(
+    val config: Config,
+) {
+    val server: CPointer<mjc_server> =
+        mjc_create()
+            ?: error("mjdevc: cannot allocate server")
     val windows = WindowModel()
     val policy = Policy(this)
     val ipc = IpcServer(this)
@@ -87,22 +90,23 @@ class Compositor(val config: Config) {
         signal(SIGPIPE, SIG_IGN)
         val ref = StableRef.create(this)
         self = ref
-        val started = memScoped {
-            val cbs = alloc<mjc_callbacks>()
-            cbs.view_new = staticCFunction(::cbViewNew)
-            cbs.view_map = staticCFunction(::cbViewMap)
-            cbs.view_unmap = staticCFunction(::cbViewUnmap)
-            cbs.view_destroy = staticCFunction(::cbViewDestroy)
-            cbs.view_title = staticCFunction(::cbViewTitle)
-            cbs.view_app_id = staticCFunction(::cbViewAppId)
-            cbs.focus_change = staticCFunction(::cbFocusChange)
-            cbs.key = staticCFunction(::cbKey)
-            cbs.fd_event = staticCFunction(::cbFdEvent)
-            cbs.child_exit = staticCFunction(::cbChildExit)
-            cbs.ready = staticCFunction(::cbReady)
-            cbs.pointer = staticCFunction(::cbPointer)
-            mjc_start(server, cbs.ptr, ref.asCPointer())
-        }
+        val started =
+            memScoped {
+                val cbs = alloc<mjc_callbacks>()
+                cbs.view_new = staticCFunction(::cbViewNew)
+                cbs.view_map = staticCFunction(::cbViewMap)
+                cbs.view_unmap = staticCFunction(::cbViewUnmap)
+                cbs.view_destroy = staticCFunction(::cbViewDestroy)
+                cbs.view_title = staticCFunction(::cbViewTitle)
+                cbs.view_app_id = staticCFunction(::cbViewAppId)
+                cbs.focus_change = staticCFunction(::cbFocusChange)
+                cbs.key = staticCFunction(::cbKey)
+                cbs.fd_event = staticCFunction(::cbFdEvent)
+                cbs.child_exit = staticCFunction(::cbChildExit)
+                cbs.ready = staticCFunction(::cbReady)
+                cbs.pointer = staticCFunction(::cbPointer)
+                mjc_start(server, cbs.ptr, ref.asCPointer())
+            }
         if (!started) {
             Clog.log("backend failed to start")
             ref.dispose()
@@ -126,7 +130,10 @@ class Compositor(val config: Config) {
 
     // callback dispatch ------------------------------------------------
 
-    fun onViewNew(view: CPointer<mjc_view>, xwayland: Boolean) {
+    fun onViewNew(
+        view: CPointer<mjc_view>,
+        xwayland: Boolean,
+    ) {
         val info = windows.add(view, xwayland)
         Clog.v("view new: ${info.describe()}")
     }
@@ -161,7 +168,10 @@ class Compositor(val config: Config) {
         }
     }
 
-    fun onViewTitle(view: CPointer<mjc_view>, title: String?) {
+    fun onViewTitle(
+        view: CPointer<mjc_view>,
+        title: String?,
+    ) {
         val info = windows.get(view) ?: return
         info.title = title
         policy.apply(info)
@@ -170,7 +180,10 @@ class Compositor(val config: Config) {
         }
     }
 
-    fun onViewAppId(view: CPointer<mjc_view>, appId: String?) {
+    fun onViewAppId(
+        view: CPointer<mjc_view>,
+        appId: String?,
+    ) {
         val info = windows.get(view) ?: return
         info.appId = appId
         policy.apply(info)
@@ -184,44 +197,68 @@ class Compositor(val config: Config) {
         ipc.broadcastEvent("focus-changed", info)
     }
 
-    fun onKey(keysym: UInt, modifiers: UInt, pressed: Boolean): Boolean =
-        policy.handleKey(keysym, modifiers, pressed)
+    fun onKey(
+        keysym: UInt,
+        modifiers: UInt,
+        pressed: Boolean,
+    ): Boolean = policy.handleKey(keysym, modifiers, pressed)
 
-    fun onFdEvent(fd: Int, mask: UInt): Int = ipc.handleFd(fd, mask)
+    fun onFdEvent(
+        fd: Int,
+        mask: UInt,
+    ): Int = ipc.handleFd(fd, mask)
 
-    fun onChildExit(pid: Int, status: Int) = session.onChildExit(pid, status)
+    fun onChildExit(
+        pid: Int,
+        status: Int,
+    ) = session.onChildExit(pid, status)
 
     fun onReady() = session.onReady()
 
-    fun onPointer(x: Int, y: Int) {
+    fun onPointer(
+        x: Int,
+        y: Int,
+    ) {
         Clog.pointer(x, y)
         ipc.broadcastPointer(x, y)
     }
 }
 
-private fun ctx(ud: COpaquePointer?): Compositor =
-    ud!!.asStableRef<Compositor>().get()
+private fun ctx(ud: COpaquePointer?): Compositor = ud!!.asStableRef<Compositor>().get()
 
-private fun cbViewNew(ud: COpaquePointer?, view: CPointer<mjc_view>?, xwayland: Boolean) {
+private fun cbViewNew(
+    ud: COpaquePointer?,
+    view: CPointer<mjc_view>?,
+    xwayland: Boolean,
+) {
     ctx(ud).onViewNew(view ?: return, xwayland)
 }
 
-private fun cbViewMap(ud: COpaquePointer?, view: CPointer<mjc_view>?) {
+private fun cbViewMap(
+    ud: COpaquePointer?,
+    view: CPointer<mjc_view>?,
+) {
     ctx(ud).onViewMap(view ?: return)
 }
 
-private fun cbViewUnmap(ud: COpaquePointer?, view: CPointer<mjc_view>?) {
+private fun cbViewUnmap(
+    ud: COpaquePointer?,
+    view: CPointer<mjc_view>?,
+) {
     ctx(ud).onViewUnmap(view ?: return)
 }
 
-private fun cbViewDestroy(ud: COpaquePointer?, view: CPointer<mjc_view>?) {
+private fun cbViewDestroy(
+    ud: COpaquePointer?,
+    view: CPointer<mjc_view>?,
+) {
     ctx(ud).onViewDestroy(view ?: return)
 }
 
 private fun cbViewTitle(
     ud: COpaquePointer?,
     view: CPointer<mjc_view>?,
-    title: CPointer<kotlinx.cinterop.ByteVar>?
+    title: CPointer<kotlinx.cinterop.ByteVar>?,
 ) {
     ctx(ud).onViewTitle(view ?: return, title?.toKString())
 }
@@ -229,12 +266,15 @@ private fun cbViewTitle(
 private fun cbViewAppId(
     ud: COpaquePointer?,
     view: CPointer<mjc_view>?,
-    appId: CPointer<kotlinx.cinterop.ByteVar>?
+    appId: CPointer<kotlinx.cinterop.ByteVar>?,
 ) {
     ctx(ud).onViewAppId(view ?: return, appId?.toKString())
 }
 
-private fun cbFocusChange(ud: COpaquePointer?, view: CPointer<mjc_view>?) {
+private fun cbFocusChange(
+    ud: COpaquePointer?,
+    view: CPointer<mjc_view>?,
+) {
     ctx(ud).onFocusChange(view)
 }
 
@@ -242,13 +282,20 @@ private fun cbKey(
     ud: COpaquePointer?,
     keysym: UInt,
     modifiers: UInt,
-    pressed: Boolean
+    pressed: Boolean,
 ): Boolean = ctx(ud).onKey(keysym, modifiers, pressed)
 
-private fun cbFdEvent(ud: COpaquePointer?, fd: Int, mask: UInt): Int =
-    ctx(ud).onFdEvent(fd, mask)
+private fun cbFdEvent(
+    ud: COpaquePointer?,
+    fd: Int,
+    mask: UInt,
+): Int = ctx(ud).onFdEvent(fd, mask)
 
-private fun cbChildExit(ud: COpaquePointer?, pid: Int, status: Int) {
+private fun cbChildExit(
+    ud: COpaquePointer?,
+    pid: Int,
+    status: Int,
+) {
     ctx(ud).onChildExit(pid, status)
 }
 
@@ -256,7 +303,11 @@ private fun cbReady(ud: COpaquePointer?) {
     ctx(ud).onReady()
 }
 
-private fun cbPointer(ud: COpaquePointer?, x: Int, y: Int) {
+private fun cbPointer(
+    ud: COpaquePointer?,
+    x: Int,
+    y: Int,
+) {
     ctx(ud).onPointer(x, y)
 }
 

+ 28 - 19
compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/Policy.kt

@@ -25,23 +25,26 @@ import mjdev.compositor.shim.mjc_view_set_layer
  *   a "mjdev::<role>" title prefix) are placed into dedicated layers
  * - everything else is a normal app window
  */
-class Policy(private val c: Compositor) {
-
-    private val shellClasses = setOf(
-        "mjdev-desktop",
-        "org.mjdev.desktop",
-        "eu.mjdev.desktop",
-        // default AWT WM_CLASS of the Compose desktop main class
-        "eu-mjdev-desktop-mainkt",
-    )
+class Policy(
+    private val c: Compositor,
+) {
+    private val shellClasses =
+        setOf(
+            "mjdev-desktop",
+            "org.mjdev.desktop",
+            "eu.mjdev.desktop",
+            // default AWT WM_CLASS of the Compose desktop main class
+            "eu-mjdev-desktop-mainkt",
+        )
 
     fun apply(info: WindowInfo) {
         val appId = info.appId?.lowercase().orEmpty()
-        val titleRole = info.title
-            ?.takeIf { it.startsWith(TITLE_PREFIX) }
-            ?.removePrefix(TITLE_PREFIX)
-            ?.substringBefore(' ')
-            ?.lowercase()
+        val titleRole =
+            info.title
+                ?.takeIf { it.startsWith(TITLE_PREFIX) }
+                ?.removePrefix(TITLE_PREFIX)
+                ?.substringBefore(' ')
+                ?.lowercase()
         val isShell = appId in shellClasses || titleRole != null
         info.shell = isShell
         if (!isShell) {
@@ -51,7 +54,8 @@ class Policy(private val c: Compositor) {
         when (info.role) {
             // ChromeWindow names: DesktopWindow/FullScreenWindow carry the wallpaper
             "wallpaper", "background", "desktop",
-            "desktopwindow", "fullscreenwindow" -> {
+            "desktopwindow", "fullscreenwindow",
+            -> {
                 mjc_view_set_layer(info.ptr, MJC_LAYER_BACKGROUND)
                 mjc_view_set_focusable(info.ptr, false)
             }
@@ -70,7 +74,11 @@ class Policy(private val c: Compositor) {
         }
     }
 
-    fun handleKey(keysym: UInt, modifiers: UInt, pressed: Boolean): Boolean {
+    fun handleKey(
+        keysym: UInt,
+        modifiers: UInt,
+        pressed: Boolean,
+    ): Boolean {
         if (!pressed) {
             return false
         }
@@ -93,9 +101,10 @@ class Policy(private val c: Compositor) {
     }
 
     private fun focusNext() {
-        val cycle = c.windows.all().filter {
-            it.mapped && !it.minimized && !it.shell
-        }
+        val cycle =
+            c.windows.all().filter {
+                it.mapped && !it.minimized && !it.shell
+            }
         if (cycle.isEmpty()) {
             return
         }

+ 9 - 5
compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/Session.kt

@@ -23,8 +23,9 @@ import platform.posix.setenv
  * optional extra startup commands. Ends the compositor when the
  * shell exits cleanly or keeps restarting it after crashes.
  */
-class Session(private val c: Compositor) {
-
+class Session(
+    private val c: Compositor,
+) {
     private var shellPid = -1
     private var crashRestarts = 0
 
@@ -39,8 +40,8 @@ class Session(private val c: Compositor) {
         mjc_spawn(
             c.server,
             "dbus-update-activation-environment --systemd " +
-                    "WAYLAND_DISPLAY DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_TYPE " +
-                    "2>/dev/null || true"
+                "WAYLAND_DISPLAY DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_TYPE " +
+                "2>/dev/null || true",
         )
 
         if (c.config.sessionMode) {
@@ -60,7 +61,10 @@ class Session(private val c: Compositor) {
         println("mjdevc: shell started pid=$shellPid: $cmd")
     }
 
-    fun onChildExit(pid: Int, status: Int) {
+    fun onChildExit(
+        pid: Int,
+        status: Int,
+    ) {
         if (pid != shellPid || shellPid < 0) {
             return
         }

+ 12 - 14
compositor/src/linuxX64Main/kotlin/eu/mjdev/compositor/WindowModel.kt

@@ -43,7 +43,7 @@ class WindowInfo(
     var shell: Boolean = false
     var role: String? = null
 
-    /* pulls current strings/pid from the native view */
+    // pulls current strings/pid from the native view
     fun refresh() {
         appId = mjc_view_app_id(ptr)?.toKString() ?: appId
         title = mjc_view_title(ptr)?.toKString() ?: title
@@ -61,9 +61,8 @@ class WindowInfo(
     }
 
     /** short identity for log lines */
-    fun describe(): String =
-        "id=$id app=${appId ?: "-"} title=\"${title ?: "-"}\" pid=$pid " +
-            "shell=$shell xwayland=$xwayland geom=[${geometry()}]"
+    fun describe(): String = "id=$id app=${appId ?: "-"} title=\"${title ?: "-"}\" pid=$pid " +
+        "shell=$shell xwayland=$xwayland geom=[${geometry()}]"
 
     fun toJson(): JsonObject = buildJsonObject {
         put("id", id.toLong())
@@ -93,24 +92,23 @@ class WindowInfo(
 class WindowModel {
     private val byPtr = LinkedHashMap<Long, WindowInfo>()
 
-    fun add(view: CPointer<mjc_view>, xwayland: Boolean): WindowInfo {
+    fun add(
+        view: CPointer<mjc_view>,
+        xwayland: Boolean,
+    ): WindowInfo {
         val info = WindowInfo(view, mjc_view_id(view), xwayland)
         byPtr[view.rawValue.toLong()] = info
         return info
     }
 
-    fun get(view: CPointer<mjc_view>): WindowInfo? =
-        byPtr[view.rawValue.toLong()]
+    fun get(view: CPointer<mjc_view>): WindowInfo? = byPtr[view.rawValue.toLong()]
 
-    fun remove(view: CPointer<mjc_view>): WindowInfo? =
-        byPtr.remove(view.rawValue.toLong())
+    fun remove(view: CPointer<mjc_view>): WindowInfo? = byPtr.remove(view.rawValue.toLong())
 
-    fun byId(id: Long): WindowInfo? =
-        byPtr.values.firstOrNull { it.id.toLong() == id }
+    fun byId(id: Long): WindowInfo? = byPtr.values.firstOrNull { it.id.toLong() == id }
 
     fun all(): List<WindowInfo> = byPtr.values.toList()
 
-    /* windows visible to clients of the IPC api (no shell internals) */
-    fun listed(): List<WindowInfo> =
-        byPtr.values.filter { it.mapped && !it.shell }
+    // windows visible to clients of the IPC api (no shell internals)
+    fun listed(): List<WindowInfo> = byPtr.values.filter { it.mapped && !it.shell }
 }

+ 31 - 10
desktopApp/desktopApp.gradle.kts

@@ -7,7 +7,11 @@ plugins {
 }
 
 kotlin {
-    jvmToolchain(libs.versions.java.language.version.get().toInt())
+    jvmToolchain(
+        libs.versions.java.language.version
+            .get()
+            .toInt(),
+    )
 }
 
 dependencies {
@@ -35,19 +39,36 @@ compose.desktop {
             System.getenv("JAVA_HOME"),
             "/usr/lib/jvm/java-21-openjdk-amd64",
             "/usr/lib/jvm/java-17-openjdk-amd64",
-        ).filterNotNull().firstOrNull { rootProject.file("$it/bin/jpackage").canExecute() }
+        ).filterNotNull()
+            .firstOrNull { rootProject.file("$it/bin/jpackage").canExecute() }
             ?.let { javaHome = it }
         nativeDistributions {
-            packageName = libs.versions.app.name.get()
-            packageVersion = libs.versions.app.pkg.version.get()
-            description = libs.versions.app.description.get()
-            copyright = libs.versions.app.copyright.get()
+            packageName =
+                libs.versions.app.name
+                    .get()
+            packageVersion =
+                libs.versions.app.pkg.version
+                    .get()
+            description =
+                libs.versions.app.description
+                    .get()
+            copyright =
+                libs.versions.app.copyright
+                    .get()
             outputBaseDir.set(rootProject.rootDir.resolve("packages"))
             linux {
-                appCategory = libs.versions.app.category.get()
-                debMaintainer = libs.versions.app.maintainer.get()
-                menuGroup = libs.versions.app.menu.group.get()
-                vendor = libs.versions.app.vendor.get()
+                appCategory =
+                    libs.versions.app.category
+                        .get()
+                debMaintainer =
+                    libs.versions.app.maintainer
+                        .get()
+                menuGroup =
+                    libs.versions.app.menu.group
+                        .get()
+                vendor =
+                    libs.versions.app.vendor
+                        .get()
             }
             // macOS code signing + notarization. Requires a paid Apple Developer ID certificate
             // installed in the build keychain — credentials come from env (CI secrets), never

+ 11 - 12
desktopApp/src/main/kotlin/org/mjdev/desktop/main/Main.kt

@@ -4,19 +4,18 @@ import org.mjdev.desktop.components.main.MainWindow
 import org.mjdev.desktop.helpers.application.application
 import org.mjdev.desktop.log.Log
 
-fun main(args: Array<String>) =
-    application(
-        args = args.toList(),
-        exitProcessOnExit = true,
-        onStart = {
-            Log.init()
-        },
-        onExit = {
-        },
-    ) {
-        MainWindow()
+fun main(args: Array<String>) = application(
+    args = args.toList(),
+    exitProcessOnExit = true,
+    onStart = {
+        Log.init()
+    },
+    onExit = {
+    },
+) {
+    MainWindow()
 //    Notify(
 //        message = "Hello World!",
 //        duration = NotificationDuration.LONG
 //    )
-    }
+}

+ 8 - 7
gradle.properties

@@ -17,10 +17,11 @@ org.gradle.kotlin.dsl.caching.buildcache=true
 #kotlin.mpp.androidGradlePluginCompatibility.nowarn=true
 # android options
 android.nonTransitiveRClass=true
-android.defaults.buildfeatures.resvalues=true
-android.defaults.buildfeatures.shaders=false
 android.enableJetifier=false
 android.useAndroidX=true
+# silences the AGP "excludeLibraryComponentsFromConstraints improves performance" build warning
+# (the documented suppression while android.dependency.useConstraints stays enabled)
+android.generateSyncIssueWhenLibraryConstraintsAreEnabled=false
 # kotlin Multiplatform
 kotlin.mpp.enableCInteropCommonization=true
 # ktor developement value
@@ -40,15 +41,15 @@ platformType = AI
 platformVersion = 2025.1.1.7
 platformPlugins =
 platformBundledPlugins =
-android.sdk.defaultTargetSdkToCompileSdkIfUnset=false
-android.enableAppCompileTimeRClass=false
-android.usesSdkInManifest.disallowed=false
 android.uniquePackageNames=false
 android.dependency.useConstraints=true
 android.r8.strictFullModeForKeepRules=false
-android.r8.optimizedResourceShrinking=false
 # android.builtInKotlin must be enabled (AGP 9 default) so androidApp's own Kotlin
 # (App, MainActivity) compiles — with it false the entry classes were missing from the APK.
 # android.builtInKotlin=false
-android.newDsl=false
+# NOTE: the deprecated AGP escape hatches (android.newDsl, android.r8.optimizedResourceShrinking,
+# android.enableAppCompileTimeRClass, android.usesSdkInManifest.disallowed,
+# android.sdk.defaultTargetSdkToCompileSdkIfUnset, android.defaults.buildfeatures.*) were removed —
+# every one only re-enabled a default or guarded a case this project does not hit, and each
+# printed a deprecation WARNING into every build log.
 ####################################################################################################

+ 18 - 0
gradle/libs.versions.toml

@@ -36,6 +36,9 @@ androidx-ui-tooling = "1.8.3"
 app-icon = "1.2.6"
 coil = "3.2.0"
 compose-plugin = "1.10.0"
+# CMP artifacts with decoupled versioning (what the deprecated compose.* accessors resolve to)
+compose-material3 = "1.9.0-beta03"
+compose-material-icons = "1.7.3"
 core-splash-screen = "1.0.1"
 generative-ai = "0.9.0-1.1.0"
 gettext-lib = "1.11.0"
@@ -92,6 +95,21 @@ gradle = { module = "com.android.tools.build:gradle", version.ref = "gradle" }
 gradle-api = { module = "com.android.tools.build:gradle-api", version.ref = "gradle" }
 gradle-kotlin-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
 #gradle-kotlinter = { module = "org.jmailen.gradle:kotlinter-gradle", version.ref = "gradle-kotlinter" }
+# compose multiplatform artifacts for the android-only module — the compose.* DSL accessors
+# are deprecated in plain android modules ("Specify dependency directly"), so androidApp
+# declares the same coordinates the accessors resolved to, versioned here.
+compose-runtime = { module = "org.jetbrains.compose.runtime:runtime", version.ref = "compose-plugin" }
+compose-foundation = { module = "org.jetbrains.compose.foundation:foundation", version.ref = "compose-plugin" }
+compose-material = { module = "org.jetbrains.compose.material:material", version.ref = "compose-plugin" }
+compose-animation = { module = "org.jetbrains.compose.animation:animation", version.ref = "compose-plugin" }
+compose-animation-graphics = { module = "org.jetbrains.compose.animation:animation-graphics", version.ref = "compose-plugin" }
+compose-ui-tooling = { module = "org.jetbrains.compose.ui:ui-tooling", version.ref = "compose-plugin" }
+compose-ui-tooling-preview = { module = "org.jetbrains.compose.ui:ui-tooling-preview", version.ref = "compose-plugin" }
+compose-material3 = { module = "org.jetbrains.compose.material3:material3", version.ref = "compose-material3" }
+compose-material-icons-extended = { module = "org.jetbrains.compose.material:material-icons-extended", version.ref = "compose-material-icons" }
+compose-ui = { module = "org.jetbrains.compose.ui:ui", version.ref = "compose-plugin" }
+compose-components-resources = { module = "org.jetbrains.compose.components:components-resources", version.ref = "compose-plugin" }
+compose-components-ui-tooling-preview = { module = "org.jetbrains.compose.components:components-ui-tooling-preview", version.ref = "compose-plugin" }
 # androidx
 androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity-compose" }
 androidx-lifecycle-viewmodel = { module = "org.jetbrains.androidx.lifecycle:lifecycle-viewmodel", version.ref = "androidx-lifecycle" }

+ 13 - 12
settings.gradle.kts

@@ -1,14 +1,15 @@
 @file:Suppress("UnstableApiUsage")
 
-//<editor-fold desc="root project">-----------------------------------------------------------------
+// <editor-fold desc="root project">-----------------------------------------------------------------
+
 rootProject.name = "mjdev-desktop"
-//</editor-fold>------------------------------------------------------------------------------------
+// </editor-fold>------------------------------------------------------------------------------------
 
-//<editor-fold desc="features">---------------------------------------------------------------------
+// <editor-fold desc="features">---------------------------------------------------------------------
 enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
-//</editor-fold>------------------------------------------------------------------------------------
+// </editor-fold>------------------------------------------------------------------------------------
 
-//<editor-fold desc="plugin management">------------------------------------------------------------
+// <editor-fold desc="plugin management">------------------------------------------------------------
 pluginManagement {
     repositories {
         mavenLocal()
@@ -42,9 +43,9 @@ pluginManagement {
 plugins {
     id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
 }
-//</editor-fold>------------------------------------------------------------------------------------
+// </editor-fold>------------------------------------------------------------------------------------
 
-//<editor-fold desc="dependency management">--------------------------------------------------------
+// <editor-fold desc="dependency management">--------------------------------------------------------
 dependencyResolutionManagement {
     repositories {
         mavenLocal()
@@ -75,16 +76,16 @@ dependencyResolutionManagement {
         google()
     }
 }
-//</editor-fold>------------------------------------------------------------------------------------
+// </editor-fold>------------------------------------------------------------------------------------
 
-//<editor-fold desc="includes">---------------------------------------------------------------------
+// <editor-fold desc="includes">---------------------------------------------------------------------
 include(":shared")
 include(":androidApp")
 include(":desktopApp")
 include(":compositor")
-//</editor-fold>------------------------------------------------------------------------------------
+// </editor-fold>------------------------------------------------------------------------------------
 
-//<editor-fold desc="rename gradle build files">----------------------------------------------------
+// <editor-fold desc="rename gradle build files">----------------------------------------------------
 // Configure modules to use their own name as the build file name
 // app/build.gradle.kts → app/app.gradle.kts
 // features/home/build.gradle.kts → features/home/home.gradle.kts
@@ -97,4 +98,4 @@ rootProject.children.forEach { project ->
     }
     configureProject(project)
 }
-//</editor-fold>------------------------------------------------------------------------------------
+// </editor-fold>------------------------------------------------------------------------------------

+ 20 - 14
shared/shared.gradle.kts

@@ -123,6 +123,11 @@ targets {
 // <editor-fold desc="source sets / dependencies">---------------------------------------------------
 
 kotlin {
+    // expect/actual classes are used across the source sets by design; the flag silences
+    // the per-file "expect/actual classes are in Beta" build warning (KT-61573)
+    compilerOptions {
+        freeCompilerArgs.add("-Xexpect-actual-classes")
+    }
 //    linuxX64 {
 //        compilations.getByName("main") {
 //            cinterops {
@@ -150,18 +155,19 @@ kotlin {
                 // reflection
                 implementation(kotlin("reflect"))
                 // preview
-                implementation(compose.components.uiToolingPreview)
-                // base
-                implementation(compose.runtime)
-                implementation(compose.foundation)
-                implementation(compose.material)
-                implementation(compose.material3)
-                implementation(compose.materialIconsExtended)
-                implementation(compose.ui)
-                implementation(compose.animation)
-                implementation(compose.animationGraphics)
-                implementation(compose.components.resources)
-                implementation(compose.components.uiToolingPreview)
+                implementation(libs.compose.components.ui.tooling.preview)
+                // the non-deprecated androidx.compose.ui.tooling.preview.Preview annotation
+                implementation(libs.compose.ui.tooling.preview)
+                // base (direct coordinates — the compose.* accessors are deprecated)
+                implementation(libs.compose.runtime)
+                implementation(libs.compose.foundation)
+                implementation(libs.compose.material)
+                implementation(libs.compose.material3)
+                implementation(libs.compose.material.icons.extended)
+                implementation(libs.compose.ui)
+                implementation(libs.compose.animation)
+                implementation(libs.compose.animation.graphics)
+                implementation(libs.compose.components.resources)
                 // lifecycles
                 implementation(libs.androidx.lifecycle.viewmodel)
                 implementation(libs.androidx.lifecycle.runtime.compose)
@@ -279,7 +285,7 @@ kotlin {
                 // preview
 //                implementation(compose.components.uiToolingPreview)
                 // preview rendering in the IDE (org.jetbrains.compose.ui:ui-tooling)
-                implementation(compose.uiTooling)
+                implementation(libs.compose.ui.tooling)
                 // activity
                 implementation(libs.androidx.activity.compose)
                 // network client
@@ -303,7 +309,7 @@ kotlin {
                 // reflection
                 implementation(kotlin("reflect"))
                 // preview
-                implementation(compose.components.uiToolingPreview)
+                implementation(libs.compose.components.ui.tooling.preview)
                 // desktop
                 implementation(compose.desktop.currentOs)
                 // coroutines

+ 1 - 1
shared/src/androidMain/kotlin/org/mjdev/desktop/context/DesktopContext.kt

@@ -49,7 +49,7 @@ import kotlin.reflect.full.companionObject
 
 @Suppress("unused", "MemberVisibilityCanBePrivate")
 class DesktopContext(
-    @SuppressLint("RestrictedApi")
+    @param:SuppressLint("RestrictedApi")
     val context: ComponentActivity? = null,
     override val scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
     override val imageLoader: ImageLoader? = null,

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/adb/AdbScreenMirror.kt

@@ -11,6 +11,7 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.ImageBitmap
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.tooling.preview.Preview
 import com.sun.jna.Platform.isAndroid
 import dadb.Dadb
 import kotlinx.coroutines.CoroutineScope
@@ -19,7 +20,6 @@ import kotlinx.coroutines.Job
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.isActive
 import kotlinx.coroutines.launch
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.adb.DeviceState.Companion.rememberDeviceState
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.decodeImage

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/appbar/AppBar.kt

@@ -29,8 +29,8 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.UiComposable
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.debugInspectorInfo
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 import org.mjdev.desktop.extensions.Modifier.conditional
 import org.mjdev.desktop.helpers.compose.Orientation

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/appsmenu/AppsMenu.kt

@@ -27,11 +27,11 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.DpOffset
 import androidx.compose.ui.unit.dp
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.appsmenu.AppsMenuState.Companion.rememberAppsMenuState
 import org.mjdev.desktop.components.appsmenu.components.AppsBottomBar
 import org.mjdev.desktop.components.appsmenu.components.AppsList

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/appsmenu/components/AppsBottomBar.kt

@@ -10,9 +10,9 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.appbar.AppBar
 import org.mjdev.desktop.components.icon.ShapedIcon
 import org.mjdev.desktop.components.input.SearchFieldPassive

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/appsmenu/components/AppsList.kt

@@ -24,10 +24,10 @@ import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.launch
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.context.DesktopContextScope
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.data.Category

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/appsmenu/components/AppsMenuActions.kt

@@ -17,8 +17,8 @@ import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.icon.ShapedIcon
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Colors.SuperDarkGray

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/appsmenu/components/AppsMenuApp.kt

@@ -14,12 +14,12 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.TextUnit
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.fonticon.FontIcon
 import org.mjdev.desktop.components.text.TextAny
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/appsmenu/components/AppsMenuCategory.kt

@@ -15,12 +15,12 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.TextUnit
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.fonticon.FontIcon
 import org.mjdev.desktop.components.text.TextAny
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/background/BackgroundImage.kt

@@ -14,8 +14,8 @@ import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Color.Companion.Transparent
 import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.tooling.preview.Preview
 import kotlinx.coroutines.delay
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.image.ImageAny
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Colors.ContrastColorFilter

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/blur/BlurPanel.kt

@@ -22,11 +22,11 @@ import androidx.compose.ui.draw.blur
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import org.jetbrains.compose.resources.DrawableResource
 import org.jetbrains.compose.resources.painterResource
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.image.ImageAny
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Colors.alpha

+ 2 - 2
shared/src/commonMain/kotlin/org/mjdev/desktop/components/blur/BlurPanelHaze.kt

@@ -18,11 +18,11 @@ import androidx.compose.material3.TopAppBarDefaults
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import dev.chrisbanes.haze.HazeState
 import dev.chrisbanes.haze.hazeEffect
 import dev.chrisbanes.haze.hazeSource
 import dev.chrisbanes.haze.rememberHazeState
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.text.TextAny
 
 @OptIn(ExperimentalMaterial3Api::class)
@@ -42,7 +42,7 @@ fun BlurPanelHaze(
         }
         LargeTopAppBar(
             // Need to make app bar transparent to see the content behind
-            colors = TopAppBarDefaults.largeTopAppBarColors(Color.Transparent),
+            colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent),
             title = {
                 TextAny("Test Blur Panel Haze")
             },

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/button/ButtonPrimary.kt

@@ -3,7 +3,7 @@ package org.mjdev.desktop.components.button
 import androidx.compose.material.Button
 import androidx.compose.material.ButtonDefaults
 import androidx.compose.runtime.Composable
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.text.TextAny
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/button/ButtonSecondary.kt

@@ -3,7 +3,7 @@ package org.mjdev.desktop.components.button
 import androidx.compose.material.Button
 import androidx.compose.material.ButtonDefaults
 import androidx.compose.runtime.Composable
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.text.TextAny
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/button/TransparentButton.kt

@@ -16,8 +16,8 @@ import androidx.compose.material.Icon
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.ButtonDefaults.noElevation
 import org.mjdev.desktop.extensions.ButtonDefaults.transparent
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/Card.kt

@@ -15,8 +15,8 @@ import androidx.compose.foundation.layout.size
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.card.base.CardBorder
 import org.mjdev.desktop.components.card.base.CardColors
 import org.mjdev.desktop.components.card.base.CardDefaults

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/CardContent.kt

@@ -8,7 +8,7 @@ import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.graphicsLayer
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.card.base.CardDefaults.DescriptionAlpha
 import org.mjdev.desktop.components.card.base.CardDefaults.SubtitleAlpha
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/ClassicCard.kt

@@ -13,8 +13,8 @@ import androidx.compose.foundation.layout.*
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.card.base.*
 import org.mjdev.desktop.components.image.ImageAny
 import org.mjdev.desktop.components.surface.base.Glow

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/CompactCard.kt

@@ -20,8 +20,8 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.drawWithCache
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.card.base.CardBorder
 import org.mjdev.desktop.components.card.base.CardColors
 import org.mjdev.desktop.components.card.base.CardDefaults

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/FocusableCard.kt

@@ -26,9 +26,9 @@ import androidx.compose.ui.focus.onFocusChanged
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.RectangleShape
 import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.card.base.CardBorder
 import org.mjdev.desktop.components.card.base.CardColors
 import org.mjdev.desktop.components.card.base.CardDefaults

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/ItemCard.kt

@@ -19,9 +19,9 @@ import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.FocusState
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.card.base.CardBorder
 import org.mjdev.desktop.components.card.base.CardColors
 import org.mjdev.desktop.components.card.base.CardDefaults

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/PhotoCard.kt

@@ -11,9 +11,9 @@ import androidx.compose.ui.focus.FocusRequester
 import androidx.compose.ui.focus.FocusState
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.card.base.CardDefaults
 import org.mjdev.desktop.components.card.base.CardDefaults.HorizontalImageAspectRatio
 import org.mjdev.desktop.components.card.base.CardScale

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/card/WideClassicCard.kt

@@ -13,8 +13,8 @@ import androidx.compose.foundation.layout.*
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.card.base.*
 import org.mjdev.desktop.components.image.ImageAny
 import org.mjdev.desktop.components.surface.base.Glow

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/chart/DonutChart.kt

@@ -6,12 +6,12 @@ import androidx.compose.runtime.*
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.tooling.preview.Preview
 import com.aay.compose.baseComponents.model.LegendPosition
 import com.aay.compose.donutChart.DonutChart
 import com.aay.compose.donutChart.model.PieChartData
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.isActive
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 import org.mjdev.desktop.extensions.System.currentTimeMillis
 

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/chromecast/ChromecastView.kt

@@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Box
 import androidx.compose.material.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 
 // todo
 @Composable

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/ControlCenter.kt

@@ -26,9 +26,9 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.blur.BlurPanel
 import org.mjdev.desktop.components.sliding.SlidingPanel
 import org.mjdev.desktop.components.sliding.base.VisibilityState

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/base/ControlCenterPage.kt

@@ -9,7 +9,7 @@ import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.vector.ImageVector
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPageScope.Companion.withControlCenterPageScope
 import org.mjdev.desktop.context.IDesktopContext
 import org.mjdev.desktop.interfaces.IControlCenterPageDataSaver

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/base/PageHeader.kt

@@ -19,10 +19,10 @@ import androidx.compose.foundation.layout.wrapContentHeight
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.appbar.AppBar
 import org.mjdev.desktop.components.image.ImageAny
 import org.mjdev.desktop.components.text.TextAny

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/about/AboutPage.kt

@@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPage
 import org.mjdev.desktop.context.IDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview

+ 3 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/ai/AIPage.kt

@@ -1,3 +1,5 @@
+@file:Suppress("DEPRECATION") // ClipboardManager -> suspend Clipboard migration pending
+
 package org.mjdev.desktop.components.controlcenter.pages.ai
 
 import androidx.compose.foundation.background
@@ -20,6 +22,7 @@ import androidx.compose.ui.platform.ClipboardManager
 import androidx.compose.ui.platform.LocalClipboardManager
 import androidx.compose.ui.text.AnnotatedString
 import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import com.pushpal.jetlime.EventPointType
 import com.pushpal.jetlime.ItemsList
@@ -27,7 +30,6 @@ import com.pushpal.jetlime.JetLimeColumn
 import com.pushpal.jetlime.JetLimeDefaults
 import com.pushpal.jetlime.JetLimeEvent
 import com.pushpal.jetlime.JetLimeEventDefaults
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.button.TransparentButton
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPage
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPageScope.Companion.remember

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/bluetooth/BluetoothSettingsPage.kt

@@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPage
 import org.mjdev.desktop.context.IDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/desktop/DesktopSettingsPage.kt

@@ -18,9 +18,9 @@ import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPage
 import org.mjdev.desktop.components.controlcenter.settings.SettingsSection
 import org.mjdev.desktop.components.controlcenter.settings.SettingsSelectRow

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/devices/Devices.kt

@@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPage
 import org.mjdev.desktop.context.IDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/display/DisplaySettingsPage.kt

@@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPage
 import org.mjdev.desktop.context.IDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/ethernet/EthSettingsPage.kt

@@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPage
 import org.mjdev.desktop.context.IDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/main/MainSettingsPage.kt

@@ -9,9 +9,9 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPage
 import org.mjdev.desktop.components.custom.DateTime
 import org.mjdev.desktop.components.custom.PowerBlock

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/remotes/RemotesSettingsPage.kt

@@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPage
 import org.mjdev.desktop.context.IDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/sound/SoundSettingsPage.kt

@@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPage
 import org.mjdev.desktop.context.IDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/theme/ThemeSettingsPage.kt

@@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPage
 import org.mjdev.desktop.context.IDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/wifi/WifiRow.kt

@@ -17,9 +17,9 @@ import androidx.compose.ui.draw.alpha
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.text.input.KeyboardType
 import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import kotlinx.coroutines.launch
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.icon.WifiLevelIcon
 import org.mjdev.desktop.components.text.KeyValueText
 import org.mjdev.desktop.components.text.TextAny

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/pages/wifi/WifiSettingsPage.kt

@@ -7,8 +7,8 @@ import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.runtime.*
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPage
 import org.mjdev.desktop.components.controlcenter.base.ControlCenterPageScope.Companion.rememberComputed
 import org.mjdev.desktop.components.controlcenter.base.PersistentPageSaver

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/settings/SettingsSection.kt

@@ -9,9 +9,9 @@ import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.text.TextAny
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Colors.alpha

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/settings/SettingsSelectRow.kt

@@ -20,9 +20,9 @@ import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.text.TextAny
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Colors.alpha

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/settings/SettingsSliderRow.kt

@@ -10,9 +10,9 @@ import androidx.compose.material3.SliderDefaults
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.text.TextAny
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Colors.alpha

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/controlcenter/settings/SettingsSwitchRow.kt

@@ -9,9 +9,9 @@ import androidx.compose.material3.SwitchDefaults
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.text.TextAny
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Colors.alpha

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/BrushedLayout.kt

@@ -13,7 +13,7 @@ import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 
 @Composable

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/Clock.kt

@@ -11,9 +11,9 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.TextUnit
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.text.TextWithShadow
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/DateTime.kt

@@ -7,11 +7,11 @@ import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.TextUnit
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 import org.mjdev.desktop.extensions.Modifier.size
 

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/MeasureUnconstrainedView.kt

@@ -5,10 +5,10 @@ import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.SubcomposeLayout
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.text.TextAny
 import org.mjdev.desktop.extensions.Compose.preview
 

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/NeonCircle.kt

@@ -5,7 +5,7 @@ package org.mjdev.desktop.components.custom
 // import androidx.compose.ui.graphics.Color
 // import androidx.compose.ui.unit.Dp
 // import androidx.compose.ui.unit.dp
-// import org.jetbrains.compose.ui.tooling.preview.Preview
+// import androidx.compose.ui.tooling.preview.Preview
 
 // @Composable
 // fun NeonCircle(

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/PowerBlock.kt

@@ -31,7 +31,7 @@ import org.mjdev.desktop.extensions.Modifier.clipCircle
 // import org.mjdev.desktop.extensions.rectShadow
 import org.mjdev.desktop.helpers.shape.BarShape
 import org.mjdev.desktop.icons.system.PowerOff
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 
 @Composable
 fun PowerBlock(

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/custom/VerticalScrollableBox.kt

@@ -15,7 +15,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 import org.mjdev.desktop.extensions.Compose.verticalTouchScrollable
 

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktop/Desktop.kt

@@ -12,8 +12,8 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.adb.AdbScreenMirror
 import org.mjdev.desktop.components.background.BackgroundImage
 import org.mjdev.desktop.components.file.FolderView

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktop/widgets/MemoryChart.kt

@@ -5,9 +5,9 @@ import androidx.compose.animation.core.TweenSpec
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import com.aay.compose.baseComponents.model.LegendPosition
 import com.aay.compose.donutChart.model.PieChartData
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.chart.DonutChart
 import org.mjdev.desktop.components.draggable.DraggableView
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/DesktopPanel.kt

@@ -25,10 +25,10 @@ import androidx.compose.ui.draw.shadow
 import androidx.compose.ui.graphics.Brush
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.onPlaced
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.blur.BlurPanel
 import org.mjdev.desktop.components.desktoppanel.applets.DesktopMenuIcon
 import org.mjdev.desktop.components.desktoppanel.applets.DesktopPanelDateTime

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopMenuIcon.kt

@@ -6,9 +6,9 @@ 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.tooling.preview.Preview
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 
 @Suppress("FunctionName")

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopPanelDateTime.kt

@@ -10,11 +10,11 @@ import androidx.compose.runtime.Composable
 import androidx.compose.runtime.MutableState
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.TextUnit
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.custom.DateTime
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.ButtonDefaults.color

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopPanelFavoriteApps.kt

@@ -12,10 +12,10 @@ import androidx.compose.runtime.getValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview
 import org.mjdev.desktop.extensions.LaunchedEffect.flowBlock

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopPanelIcon.kt

@@ -14,9 +14,9 @@ import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.fonticon.FontIcon
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.ButtonDefaults.color

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopPanelLanguage.kt

@@ -2,7 +2,7 @@ package org.mjdev.desktop.components.desktoppanel.applets
 
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview
 

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopPanelText.kt

@@ -12,8 +12,8 @@ import androidx.compose.runtime.MutableState
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.ButtonDefaults.color
 import org.mjdev.desktop.extensions.ButtonDefaults.noElevation

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/desktoppanel/applets/DesktopPanelTray.kt

@@ -8,9 +8,9 @@ import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.extensions.Compose.preview
 

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/draggable/DraggableView.kt

@@ -16,9 +16,9 @@ import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.zIndex
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 import org.mjdev.desktop.extensions.Modifier.conditional
 import org.mjdev.desktop.extensions.MutableStateExt.rememberState

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/file/FolderIcon.kt

@@ -14,10 +14,10 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.text.font.FontWeight
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.text.style.TextOverflow.Companion.Ellipsis
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
 import okio.Path
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.draggable.DraggableView
 import org.mjdev.desktop.components.fonticon.FontIcon
 import org.mjdev.desktop.components.text.TextWithShadow

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/file/FolderView.kt

@@ -10,11 +10,11 @@ import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
 import okio.Path
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.custom.MeasureUnconstrainedView
 import org.mjdev.desktop.components.grid.GridPlaced
 import org.mjdev.desktop.components.grid.base.GridPlacedCells

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/fonticon/FontIcon.kt

@@ -14,10 +14,10 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.icon.ShapedIcon
 import org.mjdev.desktop.components.text.AutoResizeText
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/gallery/BoxWithControls.kt

@@ -1,6 +1,6 @@
 package org.mjdev.desktop.components.gallery
 
-// import org.jetbrains.compose.ui.tooling.preview.Preview
+// import androidx.compose.ui.tooling.preview.Preview
 
 // @Composable
 // fun BoxWithControls(

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/gallery/Gallery.kt

@@ -40,7 +40,7 @@ package org.mjdev.desktop.components.gallery
 // import org.mjdev.desktop.extensions.Compose.preview
 // import org.mjdev.desktop.extensions.FocusState.rememberFocusRequester
 // import org.mjdev.desktop.extensions.MutableStateExt.rememberDerivedState
-// import org.jetbrains.compose.ui.tooling.preview.Preview
+// import androidx.compose.ui.tooling.preview.Preview
 //
 // // todo
 // @Composable

+ 2 - 2
shared/src/commonMain/kotlin/org/mjdev/desktop/components/gallery/ItemInfo.kt

@@ -3,7 +3,7 @@ package org.mjdev.desktop.components.gallery
 // import androidx.compose.animation.AnimatedVisibility
 // import androidx.compose.animation.slideInVertically
 // import androidx.compose.animation.slideOutVertically
-// import androidx.compose.desktop.ui.tooling.preview.Preview
+// import androidx.compose.ui.tooling.preview.Preview
 // import androidx.compose.foundation.background
 // import androidx.compose.foundation.layout.Box
 // import androidx.compose.foundation.layout.Column
@@ -25,7 +25,7 @@ package org.mjdev.desktop.components.gallery
 // import org.mjdev.desktop.extensions.Colors.invert
 // import org.mjdev.desktop.extensions.Compose.preview
 // import org.mjdev.desktop.helpers.compose.Gravity
-// import org.jetbrains.compose.ui.tooling.preview.Preview
+// import androidx.compose.ui.tooling.preview.Preview
 //
 // // todo
 // @Composable

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/greeter/Greeter.kt

@@ -11,8 +11,8 @@ import androidx.compose.runtime.setValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.input.PasswordTextView
 import org.mjdev.desktop.components.user.UserAvatar
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/grid/GridPlaced.kt

@@ -3,8 +3,8 @@ package org.mjdev.desktop.components.grid
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Constraints
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.grid.base.GridPlacedCells
 import org.mjdev.desktop.components.grid.base.GridPlacedContent
 import org.mjdev.desktop.components.grid.base.GridPlacedItemScopeImpl

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/guide/GuideView.kt

@@ -16,10 +16,10 @@ import androidx.compose.ui.UiComposable
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.StrokeCap
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 import kotlin.math.max
 

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/icon/ShapedIcon.kt

@@ -11,9 +11,9 @@ import androidx.compose.ui.draw.clip
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 import org.mjdev.desktop.extensions.Modifier.onLeftClick
 import org.mjdev.desktop.extensions.Modifier.onMousePress

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/icon/WifiLevelIcon.kt

@@ -14,9 +14,9 @@ import androidx.compose.runtime.Composable
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 import org.mjdev.desktop.extensions.MutableStateExt.rememberComputed
 import org.mjdev.desktop.icons.wifi.level.Wifi_Level_0

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/image/GifView.kt

@@ -6,6 +6,7 @@ import androidx.compose.runtime.*
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.ImageBitmap
 import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.tooling.preview.Preview
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.async
@@ -14,7 +15,6 @@ import kotlinx.coroutines.delay
 import kotlinx.coroutines.isActive
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.image.GifViewState.Companion.rememberGifViewState
 import org.mjdev.desktop.context.DesktopContextScope.Companion.withDesktopContext
 import org.mjdev.desktop.context.IDesktopContext

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/image/ImageAny.kt

@@ -22,10 +22,10 @@ import androidx.compose.ui.graphics.drawscope.DrawScope.Companion.DefaultFilterQ
 import androidx.compose.ui.graphics.painter.Painter
 import androidx.compose.ui.graphics.vector.ImageVector
 import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.tooling.preview.Preview
 import coil3.ImageLoader
 import coil3.compose.AsyncImage
 import okio.Path
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.video.VideoView
 import org.mjdev.desktop.extensions.Compose.preview
 import org.mjdev.desktop.extensions.Compose.runAsync

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/image/PhotoImage.kt

@@ -21,9 +21,9 @@ import androidx.compose.ui.graphics.ColorFilter
 import androidx.compose.ui.graphics.DefaultAlpha
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 import org.mjdev.desktop.icons.image.BrokenImage
 

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/immersivelist/ImmersiveList.kt

@@ -13,7 +13,7 @@ import androidx.compose.ui.Modifier
 import androidx.compose.ui.focus.FocusDirection
 import androidx.compose.ui.focus.onFocusChanged
 import androidx.compose.ui.platform.LocalFocusManager
-import org.jetbrains.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.immersivelist.base.ImmersiveListBackgroundScope
 import org.mjdev.desktop.components.immersivelist.base.ImmersiveListScope
 import org.mjdev.desktop.extensions.Compose.preview

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/info/Info.kt

@@ -14,8 +14,8 @@ import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.text.font.FontStyle
 import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.background.BackgroundImage
 import org.mjdev.desktop.components.button.ButtonPrimary
 import org.mjdev.desktop.components.sliding.base.VisibilityState

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/input/PasswordTextView.kt

@@ -17,9 +17,9 @@ import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.text.input.KeyboardType
 import androidx.compose.ui.text.input.PasswordVisualTransformation
 import androidx.compose.ui.text.input.VisualTransformation
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 import org.mjdev.desktop.extensions.Modifier.onMousePress
 import org.mjdev.desktop.icons.text.Send

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/input/SearchFieldPassive.kt

@@ -19,10 +19,10 @@ import androidx.compose.runtime.mutableStateOf
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.TextUnit
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Colors.alpha
 import org.mjdev.desktop.extensions.Compose.preview
 import org.mjdev.desktop.extensions.Modifier.onMousePress

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/input/SelectableOutlineEditText.kt

@@ -13,8 +13,8 @@ import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.text.TextStyle
 import androidx.compose.ui.text.input.TextFieldValue
 import androidx.compose.ui.text.input.VisualTransformation
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.TextUnit
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.extensions.Compose.preview
 
 @Composable

+ 1 - 1
shared/src/commonMain/kotlin/org/mjdev/desktop/components/installer/Installer.kt

@@ -9,8 +9,8 @@ import androidx.compose.foundation.layout.height
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
-import org.jetbrains.compose.ui.tooling.preview.Preview
 import org.mjdev.desktop.components.background.BackgroundImage
 import org.mjdev.desktop.components.sliding.base.VisibilityState
 import org.mjdev.desktop.components.sliding.base.VisibilityState.Companion.rememberVisibilityState

Some files were not shown because too many files changed in this diff