Git Product home page Git Product logo

compose-multiplatform-file-picker's People

Contributors

menkalian avatar renovate[bot] avatar ruyut avatar shahriyar13 avatar shalva97 avatar vinceglb avatar wavesonics avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

compose-multiplatform-file-picker's Issues

Could not resolve all dependencies for configuration ':iosArm64CompileKlibraries'

Hello, faced such an issue while trying to implement your lib into my project
in common target I get such a Gradle error, but in android target everything works perfectly fine

Could not resolve com.darkrockstudios:mpfilepicker:2.1.0.
Required by:
project :composeApp > project :features:comments:ui
> No matching variant of com.darkrockstudios:mpfilepicker:2.1.0 was found. The consumer was configured to find a library for use during 'kotlin-api', preferably optimized for non-jvm, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native', attribute 'org.jetbrains.kotlin.native.target' with value 'ios_arm64' but:
- Variant 'jsApiElements-published' capability com.darkrockstudios:mpfilepicker:2.1.0 declares a library for use during 'kotlin-api':
- Incompatible because this component declares a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'js' and the consumer needed a component, as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'
- Other compatible attributes:
- Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
- Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_arm64')
- Variant 'jsRuntimeElements-published' capability com.darkrockstudios:mpfilepicker:2.1.0 declares a library:
- Incompatible because this component declares a component for use during 'kotlin-runtime', as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'js' and the consumer needed a component for use during 'kotlin-api', as well as attribute 'org.jetbrains.kotlin.platform.type' with value 'native'
- Other compatible attributes:
- Doesn't say anything about its target Java environment (preferred optimized for non-jvm)
- Doesn't say anything about org.jetbrains.kotlin.native.target (required 'ios_arm64')

Support multiple file extensions

At least on Windows it's possible to filter for multiple file extensions. Would be nice if fileExtension was a list instead of a string to reflect that 😁

Can not run jvm variant

At first it complains about JVM versions

Execution failed for task ':examples:jvm:compileKotlinJvm'.
> 'compileJava' task (current target is 17) and 'compileKotlinJvm' task (current target is 11) jvm target compatibility should be set to the same Java version.
  Consider using JVM toolchain: https://kotl.in/gradle/jvm/toolchain

I have tried to change kotlinOptions.jvmTarget = "11" to 17, then I get another error, which I cant fix

Caused by: org.jetbrains.skiko.LibraryLoadException: Cannot find libskiko-macos-x64.dylib.sha256, proper native dependency missing.

Add version catalogs

I think version catalogs are much cleaner way to keep versions. For example here is a catalog from my app

[versions]
minSdk = "24"
targetSdk = "33"
compileSdk = "33"
versionCode = "9"
versionName = "1.3.1"
composeCompiler = "1.2.0"

[libraries]
kiwi-icons = "kiwi.orbit.compose:icons:0.24.0"
kiwi-ui = "kiwi.orbit.compose:ui:0.24.0"
kiwi-illustrations = "kiwi.orbit.compose:illustrations:0.24.0"

androidx-compose-navigation-hilt = "androidx.hilt:hilt-navigation-compose:1.0.0"
androidx-compose-foundation = "androidx.compose.foundation:foundation:1.3.1"
androidx-compose-viewmodel-lifecycle = "androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1"
androidx-compose-ui = "androidx.compose.ui:ui:1.3.3"
androidx-compose-material = "androidx.compose.material:material:1.3.1"
androidx-compose-material-icons-extended = "androidx.compose.material:material-icons-extended:1.3.1"
androidx-compose-constraintlayout = "androidx.constraintlayout:constraintlayout-compose:1.0.1"
androidx-tooling = "androidx.compose.ui:ui-tooling:1.3.3"
androidx-tooling-preview = "androidx.compose.ui:ui-tooling-preview:1.3.3"

raamcosta-destinations = 'io.github.raamcosta.compose-destinations:core:1.4.4-beta'
raamcosta-destinations-animations = 'io.github.raamcosta.compose-destinations:animations-core:1.4.4-beta'
raamcosta-destinations-ksp = 'io.github.raamcosta.compose-destinations:ksp:1.4.4-beta'

[bundles]
kiwi = [
    "kiwi-icons",
    "kiwi-ui",
    "kiwi-illustrations"
]

androidx = [
    "androidx-lifecycle",
    "androidx-compose-activity",
    "androidx-datastore-preferences",
    "androidx-datastore-core",
    "androidx-datastore",
    "androidx-core",
    "androidx-appcompat",
    "androidx-room-runtime",
    "androidx-room-ktx",
]

on macOS cannot choose json file

version: v2.0.2
operating system: macOS Monterey v12.6.1
JDK: IBM OpenJ9, version: 17.0.8

demo:

import androidx.compose.foundation.layout.Column
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application
import com.darkrockstudios.libraries.mpfilepicker.FilePicker


fun main() = application {
    var show1 by remember { mutableStateOf(false) }
    var show2 by remember { mutableStateOf(false) }
    var pathChosen1 by remember { mutableStateOf("") }
    var pathChosen2 by remember { mutableStateOf("") }


    Window(onCloseRequest = ::exitApplication) {
        Column {
            Button(onClick = {
                show1 = true
            }) {
                Text("Choose File 1")
            }
            Text("File Chosen 1: $pathChosen1")

            /////////////////////////////////////////////////////////////////
            Button(onClick = {
                show2 = true
            }) {
                Text("Choose File 2")
            }
            Text("File Chosen 2: $pathChosen2")

        }

        // if set one json file extension, cannot choose json files
        FilePicker(show1, fileExtensions = listOf("json")) { file ->
            pathChosen1 = file?.path ?: "none selected"
            show1 = false
        }
        // if set multiple file extensions, can choose json files
        FilePicker(show2, fileExtensions = listOf("json", "txt")) { file ->
            pathChosen2 = file?.path ?: "none selected"
            show2 = false
        }
    }

}

Bug with .onExternalDrag modifier

I'm making a windows application that works with excel files. I added an option to add files: both drag and drop, and use file picker (by clicking on DnD box). I found out that FilePicker does not work properly with .onExternalDrag modifier: the application totally freezes after you try to drag any element out of File chooser dialog. That happens only if at least once any element with .onExternalDrag modifier is used.
Upd: I mean it's happens even if you change screen. And even if on this screen are no elements with that modifier.

It looks like this:
image

At this point the application just does not respond and there are no ways to do something to it. If I comment an .onExternalDrag and try to launch application, everything works just fine:
image

I have this modifier only in one element. It's code:

@OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class)
@Composable
fun DragAndDropFileBox(navigator: Navigator, modifier: Modifier = Modifier) {
    var isDragging by remember { mutableStateOf(false) }
    val dragNDropColor = if (isDragging) Colors.active else Colors.default
    var localPath by remember { mutableStateOf("") }

    Box(
        modifier = modifier
            .border(border = BorderStroke(5.dp, Color.Magenta), shape = RectangleShape)
            .onExternalDrag(
                onDragStart = { isDragging = true },
                onDragExit = { },
                onDrop = { value ->
                    isDragging = false
                    val dragData = value.dragData
                    if (dragData is DragData.FilesList) {
                        val draggedList = DragDataList(dragData)
                        localPath = draggedList.receiveFilePath()
                        isDragging = false
                        navigator.replaceAll(MainScreen(localPath))
                    }
                })
            .onClick {
                navigator.replace(FilePickerScreen())
            }
    ) {
        Column(modifier = Modifier.align(Alignment.Center)) {
            DragAndDropDescription(
                modifier = Modifier.align(Alignment.CenterHorizontally),
                color = dragNDropColor
            )
        }
    }
}

Java awt file picker does not have this problem, but I don't really won't use it (mostly because of it's appearance and not really native look).

P.S.
I'm not a native speaker, so my apologies if I spoke out not totally clear.

Why platformFile of MPFile is generic?

When I debug my project in Windows, if found that the type of plaformFile is always the File of java.io. So I wonder if it is necessary to make it generic? Is it possible to have another type of file?

Thankyou

Provide an option to specifiy the title

I like to have a title on macOS & Windows for the bar that says something like "Choose a directory that contains your photos" instead of "Choose folder". Please provide a way to specify this. It's a property that could be ignored for platforms where this is not applicable.

WASM/WASI target?

Given that there is already a JavaScript target, I was curious about the possibility of incorporating the WASM and WASI targets, which have recently been promoted to alpha. While it's not a requirement for me, it's just an idea I wanted to explore.

Allow to customize the window title

It would be nice if the window's title could be customized (e.g. from "Open File" on Linux / KDE) to any custom text (like "Open Image").

Error

I get the following error when trying to run my app:

Exception in thread "main" java.lang.UnsatisfiedLinkError: 'void org.jetbrains.skia.CanvasKt._nTranslate(long, float, float)'
	at org.jetbrains.skia.CanvasKt._nTranslate(Native Method)
	at org.jetbrains.skia.CanvasKt.access$_nTranslate(Canvas.kt:1)
	at org.jetbrains.skia.Canvas.translate(Canvas.kt:1091)
	at androidx.compose.ui.graphics.SkiaBackedCanvas.translate(SkiaBackedCanvas.skiko.kt:84)
	at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:357)
	at androidx.compose.ui.node.LayoutNode.draw$ui(LayoutNode.kt:922)
	at androidx.compose.ui.platform.SkiaBasedOwner.draw(SkiaBasedOwner.skiko.kt:352)
	at androidx.compose.ui.ComposeScene.render(ComposeScene.skiko.kt:463)
	at androidx.compose.ui.awt.ComposeBridge$skikoView$1$onRender$1.invoke(ComposeBridge.desktop.kt:153)
	at androidx.compose.ui.awt.ComposeBridge$skikoView$1$onRender$1.invoke(ComposeBridge.desktop.kt:152)
	at androidx.compose.ui.awt.ComposeBridge.catchExceptions(ComposeBridge.desktop.kt:126)
	at androidx.compose.ui.awt.ComposeBridge.access$catchExceptions(ComposeBridge.desktop.kt:59)
	at androidx.compose.ui.awt.ComposeBridge$skikoView$1.onRender(ComposeBridge.desktop.kt:152)
	at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.awt.kt:548)
	at org.jetbrains.skiko.redrawer.AWTRedrawer.update(AWTRedrawer.kt:54)
	at org.jetbrains.skiko.redrawer.Direct3DRedrawer.redrawImmediately(Direct3DRedrawer.kt:73)
	at org.jetbrains.skiko.SkiaLayer.paint(SkiaLayer.awt.kt:388)
	at androidx.compose.ui.awt.WindowComposeBridge$component$1.paint(WindowComposeBridge.desktop.kt:59)
	at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:961)
	at java.desktop/javax.swing.JComponent.paint(JComponent.java:1137)
	at java.desktop/javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
	at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:961)
	at java.desktop/javax.swing.JComponent.paint(JComponent.java:1137)
	at androidx.compose.ui.window.Window_desktopKt$Window$12$1.invoke(Window.desktop.kt:430)
	at androidx.compose.ui.window.Window_desktopKt$Window$12$1.invoke(Window.desktop.kt:416)
	at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$3.invoke(AwtWindow.desktop.kt:82)
	at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$3.invoke(AwtWindow.desktop.kt:80)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2$performUpdate$1.invoke(UpdateEffect.desktop.kt:59)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2$performUpdate$1.invoke(UpdateEffect.desktop.kt:55)
	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2300)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:471)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:234)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke$performUpdate(UpdateEffect.desktop.kt:55)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke(UpdateEffect.desktop.kt:64)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke(UpdateEffect.desktop.kt:47)
	at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:81)
	at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1137)
	at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:828)
	at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:849)
	at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1041)
	at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:520)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:219)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:108)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

My dependencies:

implementation(compose.desktop.currentOs)
implementation("org.xerial:sqlite-jdbc:3.42.0.0")
implementation(compose.material3)
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.6.0")
implementation("com.darkrockstudios:mpfilepicker:2.1.0")

Also, something strange happened with the compose library when I installed this library. In ModifierNodeElement class, the function abstract fun update is changed from abstract fun update(node: N): N to abstract fun update(node: N).

Support modal dialog

Would it be possible, at least in desktop, that when the file picker opens it's as a modal dialog, so you cannot interact with the original app window?

Android photo chooser

Hi
Please add an option that when i want to only choose photo in android
open file chooser like following image:
telegram-cloud-photo-size-4-5825822451114819424-y

Issue fetching files on Android

Hi using the latest version of the multiple file picker (3.1.0) using the following snippet of code:

MultipleFilePicker(
    show = //showFilePicker,
    fileExtensions = //file extensions
) { assets ->
    if(!assets.isNullOrEmpty()) {
        val assetsPath = mutableListOf<File>()
        assets.forEach { asset ->
            assetsPath.add(File(asset.path))
        }
        if(assetsPath.isNotEmpty()) {
            // do code
        }
    }
}

will be thrown the following exception:
Caused by: java.io.FileNotFoundException: /document/msf:59701: open failed: ENOENT (No such file or directory).

There is a way to get directly the file from the Android's storage? Because using the asset.path it looks like does not get the complete path to get the file

refactor jvmMain/FileChooser

When I ook at the FileChooser class it gives me flashbacks from Java. Also having a fallback chooseFileSwing looks extra

Here are my ideas

  • remove FileChooser class, because it has no state and is not injected anywhere.
  • Remove Swing Dialog, because if chooseFileNative fails and users see non-native dialog they may think that this library does not show native dialogs (yes, there is a println for this error, but still) and may switch to another library.
  • Then remove all println() calls, or at least turn them off by default.
  • remove CallType and directly call File or Directory chooser

I think after all this, code will be twice as cleaner. Let me know if you agree and will send PR

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • Update dependency org.jetbrains.kotlin.multiplatform to v2

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/publish.yml
  • actions/checkout v4
  • actions/setup-java v4
  • gradle/wrapper-validation-action v2.1.1
  • gradle/gradle-build-action v3.1.0
.github/workflows/run-checks.yml
  • actions/checkout v4
  • gradle/wrapper-validation-action v2
  • actions/setup-java v4
  • gradle/actions v3
  • actions/checkout v4
  • gradle/wrapper-validation-action v2
  • actions/setup-java v4
  • gradle/actions v3
gradle
gradle.properties
settings.gradle.kts
build.gradle.kts
gradle/libs.versions.toml
  • androidx.appcompat:appcompat 1.6.1
  • androidx.core:core-ktx 1.12.0
  • androidx.activity:activity-compose 1.8.2
  • org.jetbrains.kotlinx:kotlinx-coroutines-core 1.8.0
  • org.jetbrains.kotlinx:kotlinx-coroutines-android 1.8.0
  • org.jetbrains.kotlinx:kotlinx-coroutines-swing 1.8.0
  • org.jetbrains.kotlinx:kotlinx-html 0.11.0
  • junit:junit 4.13.2
  • com.android.application 8.3.0
  • com.android.library 8.3.0
  • org.jetbrains.compose 1.6.1
  • org.jetbrains.kotlin.multiplatform 1.9.22
mpfilepicker/build.gradle.kts
gradle-wrapper
gradle/wrapper/gradle-wrapper.properties
  • gradle 8.6

  • Check this box to trigger a request for Renovate to run again on this repository

Publish failure

Looks like our publish task is failing now with the JS target:

 A problem was found with the configuration of task ':mpfilepicker:publishAndroidReleasePublicationToMavenRepository' (type 'PublishToMavenRepository').
  - Gradle detected a problem with the following location: '/home/runner/work/compose-multiplatform-file-picker/compose-multiplatform-file-picker/mpfilepicker/build/libs/mpfilepicker-2.0.0-javadoc.jar.asc'.
    
    Reason: Task ':mpfilepicker:publishAndroidReleasePublicationToMavenRepository' uses this output of task ':mpfilepicker:signJsPublication' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed.
    
    Possible solutions:
      1. Declare task ':mpfilepicker:signJsPublication' as an input of ':mpfilepicker:publishAndroidReleasePublicationToMavenRepository'.
      2. Declare an explicit dependency on ':mpfilepicker:signJsPublication' from ':mpfilepicker:publishAndroidReleasePublicationToMavenRepository' using Task#dependsOn.
      3. Declare an explicit dependency on ':mpfilepicker:signJsPublication' from ':mpfilepicker:publishAndroidReleasePublicationToMavenRepository' using Task#mustRunAfter.
    

https://github.com/Wavesonics/compose-multiplatform-file-picker/actions/runs/5432985513/jobs/9880387821

Lower android minSdk to 21

Hi, just found this lib and it'll be of great use for my multiplatform app i'm developing. One problem I've found is that the library has its minSdk set to 24, and my app is minSdk 21. I inspected the code and there doesn't appear to be anything preventing it from being dropped down. Perhaps I overlooked something but otherwise I'm certain the minSdk can be lowered to 21. Compose min sdk is also 21.

Use spaces instead of tabs

According to default style guide of Kotlin, it should be written with spaces.

For example, tabs are a bit inconsistent, if I copy a line with tabs and paste it somewhere else, it looks like this

						println("A call to chooseDirectorySwing failed ${swingException.message}")

and in spaces its like this

                        println("A call to chooseDirectorySwing failed ${swingException.message}")

and in Intellij it looks like this (with a bit of custom settings)

Screenshot 2023-06-23 at 18 48 10

And in Vim or Emacs it will also be different.

So, lets follow default style guide and switch to spaces

Exception on Android

I have code that's working fine in other Compose clients but on Android I'm getting following when calling getFileByteArray

01-14 19:37:45.657 22788 22788 E AndroidRuntime: java.lang.IllegalArgumentException: Uri lacks 'file' scheme: content://com.android.providers.media.documents/document/image%3A1000050843
01-14 19:37:45.657 22788 22788 E AndroidRuntime: 	at androidx.core.net.UriKt.toFile(Uri.kt:43)
01-14 19:37:45.657 22788 22788 E AndroidRuntime: 	at com.darkrockstudios.libraries.mpfilepicker.AndroidFile.getFileByteArray(AndroidFilePicker.kt:15)

following is code I have

    val coroutineScope = rememberCoroutineScope()

    val fileExtensions = listOf("jpg", "png")
    FilePicker(show = show, fileExtensions = fileExtensions) { file ->
        coroutineScope.launch {
            val data = file?.getFileByteArray()
            data?.let {
                ....
            }
        }
    }

ios image picker

Thanks for iOS supported add.
But we can't select from iPhone Photos.

Why do you call JVM variant "desktop"

It is confusing. There is line in gradle file jvm("desktop") and the sourceSet is called desktopMain. I think if it had its original name then it would be more intuitive

iOS selection unresponsive

After signing with a certificate, a view for selecting files pops up, but there is no response when clicking the target.

Clashes with LWJGL on Linux

I have a very specific problem and may be related to #30? I'm unfortunately not very knowledgeable about how the JVM interacts with native system calls, so this is a little out of my league.

My application requires LWJGL to operate. I have a Compose application that launches a jMonkeyEngine application—this is dependent on LWJGL. When LWJGL2 is on the classpath, attempts to open the file picker open an old, legacy file chooser:

image

This is also printed to the console: A call to chooseDirectoryNative failed: 'org.lwjgl.system.CustomBuffer org.lwjgl.PointerBuffer.rewind()'


If I instead package LWJGL3, the true, native picker is opened:

image

However, the JVM will sometimes crash when selecting a file. (Seemingly randomly, it happens maybe half the time?) When it crashes the JVM does a memory dump, so I've attached that here.


I package LWJGL by adding either of these dependencies to my Gradle build script: implementation("org.jmonkeyengine:jme3-lwjgl:3.5.2-stable") or implementation("org.jmonkeyengine:jme3-lwjgl3:3.5.2-stable").


Therefore, I expect the file picker to load the native file picker (as seen in the second screenshot) without crashing. But—depending on the LWJGL version on the classpath—it either loads a legacy file picker, or randomly crashes.

If there's any other information I can provide, let me know.

Heap Corruption crash after using File Picker

Showing the FilePicker component seems to cause heap corruption and cause the entire Compose application to crash at random times with error code 0xC0000374 (ERROR_HEAP_CORRUPTION) on a Windows machine. Given that it seems that Windows itself is killing the process, no JVM error log nor any mini dumps are produced, and the code that is being executed when the application is terminated seems to be random, unrelated to the file picker library itself. Nevertheless, preventing the file picker from showing up consistently solves the issue.

I have managed to replicate the issue somewhat consistently by trying to load Bitmap images through AWT immediately after the file picker is closed: a minimal reproducible test-case is attached below. It does seem that the size of the image does not matter, although the bigger the image is the more likely an error occurs immediately. I have been testing with this Bitmap and it seems to trigger the error immediately around 90% of the time.

private class C {
    var p by mutableStateOf(false)
    var i by mutableStateOf(false)
}

fun main() {
    application {
        val state = remember { C() }
        Window(onCloseRequest = ::exitApplication) {
            if (state.i) { Image(ImageIO.read(Path("./bridge.bmp").inputStream()).toComposeImageBitmap(), null) }
            Button(onClick = {
                state.p = true
                state.i = false
            }) { Text("Click Me") }
        }
        FilePicker(show = state.p) {
            state.p = false
            state.i = true
        }
    }
}

The described behavior can be triggered by clicking on the button and then either choosing a file or canceling the file picking action. Setting state.i to true by default shows that the image is usually loaded without problems if the file picker is not involved.

These tests have been performed with version 1.2.0 of this library along with Compose 1.2.0 with Kotlin 1.8.21 (requires manually specifying version 1.4.7 of the Compose compiler in the project settings) on Java 17.

java.lang.UnsatisfiedLinkError: 'long org.jetbrains.skiko.MetalApiKt.openAutoreleasepool()'

this happens at runtime on macOS apple silicon, just by adding the dependency

Exception in thread "main" java.lang.UnsatisfiedLinkError: 'long org.jetbrains.skiko.MetalApiKt.openAutoreleasepool()'
	at org.jetbrains.skiko.MetalApiKt.openAutoreleasepool(Native Method)
	at org.jetbrains.skiko.MetalApiKt.access$openAutoreleasepool(MetalApi.kt:1)
	at org.jetbrains.skiko.redrawer.MetalRedrawer.performDraw(MetalRedrawer.kt:251)
	at org.jetbrains.skiko.redrawer.MetalRedrawer.redrawImmediately(MetalRedrawer.kt:117)
	at org.jetbrains.skiko.SkiaLayer.paint(SkiaLayer.awt.kt:388)
	at androidx.compose.ui.awt.WindowComposeBridge$component$1.paint(WindowComposeBridge.desktop.kt:59)
	at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:952)
	at java.desktop/javax.swing.JComponent.paint(JComponent.java:1128)
	at java.desktop/javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
	at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:952)
	at java.desktop/javax.swing.JComponent.paint(JComponent.java:1128)
	at androidx.compose.ui.window.Window_desktopKt$Window$12$1.invoke(Window.desktop.kt:430)
	at androidx.compose.ui.window.Window_desktopKt$Window$12$1.invoke(Window.desktop.kt:416)
	at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$3.invoke(AwtWindow.desktop.kt:82)
	at androidx.compose.ui.window.AwtWindow_desktopKt$AwtWindow$3.invoke(AwtWindow.desktop.kt:80)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2$performUpdate$1.invoke(UpdateEffect.desktop.kt:59)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2$performUpdate$1.invoke(UpdateEffect.desktop.kt:55)
	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2300)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:471)
	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:234)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke$performUpdate(UpdateEffect.desktop.kt:55)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke(UpdateEffect.desktop.kt:64)
	at androidx.compose.ui.util.UpdateEffect_desktopKt$UpdateEffect$2.invoke(UpdateEffect.desktop.kt:47)
	at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:81)
	at androidx.compose.runtime.CompositionImpl$RememberEventDispatcher.dispatchRememberObservers(Composition.kt:1137)
	at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:828)
	at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:849)
	at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1041)
	at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:520)
	at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:219)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Issue with folder picker in Android

I'm using folder picker and it works properly in desktop but in Android, i have some troubles.

When user clicks on a fab, i will show the folder picker dialog, and user choose the target folder, the path returned to my app is something like this:

content://com.android.externalstorage.documents/tree/primary%3ADownload/MyApp

After that i'm checking is that folder exists or not:

val file = File(path)
val isExists = file.exists()

In desktop it returns true but in Android it always returns false.

what if we expose "fun FilePicker" without compose dependency

In a way it feels extra to have those functions as composable. Since it is multiplatform, one might not want compose, maybe they have React and now they will need to be using compose too. Or maybe in future if we have a native library that is compiled to native, then it might be called not from Kotlin, but from many different languages....

Similar thing happened here #17, i had to add a separate module, bucause then I get error :mpfilepicker:mingwX64Main: Could not resolve org.jetbrains.compose.foundation:foundation:1.3.0.

There could be 2 kinds of library maybe, one without compose and one with compose? something like implementation("com.darkrockstudios:mpfilepicker:1.1.0") and implementation("com.darkrockstudios:mpfilepicker-compose:1.1.0").

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.