vinceglb / FileKit

Pick and save Files, Medias and Folder for Kotlin Multiplatform / KMP and Compose Multiplatform / CMP
https://vinceglb.github.io/FileKit/
MIT License
483 stars 16 forks source link

NPE on Linux when close/choosen file dialog #99

Closed hondogo closed 1 week ago

hondogo commented 2 weeks ago

FileKit version 0.8.2

On Linux (Jvm target) when closing file chooser dialog (cancelling or choosing file) got NPE.

Code for open dialog: FileKit.pickFile( mode = PickerMode.Single, title = "title", initialDirectory = null )

Exception on close dialog:

Exception in thread "ShowDialog" java.lang.NullPointerException at java.base/java.io.File.<init>(File.java:278) at java.desktop/sun.awt.X11.GtkFileDialogPeer.filenameFilterCallback(GtkFileDialogPeer.java:107) at java.desktop/sun.awt.X11.GtkFileDialogPeer.run(Native Method) at java.desktop/sun.awt.X11.GtkFileDialogPeer.showNativeDialog(GtkFileDialogPeer.java:195) at java.desktop/sun.awt.X11.GtkFileDialogPeer.lambda$setVisible$0(GtkFileDialogPeer.java:118) at java.base/java.lang.Thread.run(Thread.java:1583)

santiwanti commented 2 weeks ago

I can't reproduce this issue. What Linux distro are you using? Can you reproduce the issue by downloading the project and running the sample code?

hondogo commented 1 week ago

Sample code is also reproducing this exception. I noticed that first time launch dialog it is ok. Others got NPE. I'm using Linux Gentoo, kernel 5.15.1, xfce4

hondogo commented 1 week ago

Exception happens only if initialDirectory parameter is null in FileKit::pickFile

hondogo commented 1 week ago

May be the problem is with 'Recent files' directory (default when initialDirectory=null) that can be virtual and has some non standard path or something like this.

Snd-R commented 1 week ago

It's most likely a issue with jdk implementation, not much you can do about it. It fails on this line GtkFileDialogPeer.java#L107 Which tries to get parent of the current directory or selected file? and that returns null File.java#L474

I'm not sure how xfce handles recent directory, is it a gvfs recent:// path? if that's the case the getParent will return null and fail with NPE You can try running in debug mode and set a breakpoint on GtkFileDialogPeer.java#L107 to see what path is passed there

Alternatively, instead of using jdk implementation of GtkFileDialog you can try installing xdg-desktop-portal which this library supports and for which xfce should have a default config https://gitlab.xfce.org/xfce/xfce4-session/-/issues/181 https://gitlab.xfce.org/xfce/xfce4-session/-/blob/master/xfce4-session/xfce-portals.conf?ref_type=heads

For gentoo I think either of these packages should work https://packages.gentoo.org/packages/sys-apps/xdg-desktop-portal-gtk https://packages.gentoo.org/packages/sys-apps/xdg-desktop-portal-xapp

Snd-R commented 1 week ago

It also opens recent directory by default for me on KDE Plasma and works without issues, The code that fails for you with NPE tries to resolve parent path for files in recent directory. On my system it properly resolves to absolute path in home directory Here's a minimal code to open the GtkFileDialog that is used if xdg-desktop-portal is not available

import java.awt.FileDialog
import java.awt.Frame
import java.io.File
import java.io.FilenameFilter

fun main() {
    var results = emptyList<File>()
    val dialog = object : FileDialog(null as Frame?, "", LOAD) {
        override fun setVisible(value: Boolean) {
            super.setVisible(value)
            if (value) results = files.toList()
        }
    }

    dialog.isMultipleMode = false
    dialog.filenameFilter = FilenameFilter { _, _ -> true }
    dialog.directory = null
    dialog.isVisible = true
    dialog.dispose()
    println(results.map { it })
}