SkillAgentSearch skills...

Nativefiledialog Extended

Cross platform (Windows, Mac, Linux) native file dialog library with C and C++ bindings, based on mlabbe/nativefiledialog.

Install / Use

npx skills add btzy/nativefiledialog-extended

Installs into whichever agent you are using.

About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Native File Dialog Extended

build

A small C library that portably invokes native file open, folder select and file save dialogs. Write dialog code once and have it pop up native dialogs on all supported platforms. Avoid linking large dependencies like wxWidgets and Qt.

This library is based on Michael Labbe's Native File Dialog (mlabbe/nativefiledialog).

Features:

  • Lean C API, static library — no C++/ObjC runtime needed
  • Support for Windows (MSVC, MinGW, Clang), macOS (Clang), and Linux (GTK, portal) (GCC, Clang)
  • Zlib licensed
  • Friendly names for filters (e.g. C/C++ Source files (*.c;*.cpp) instead of (*.c;*.cpp)) on platforms that support it
  • Automatically append file extension on platforms where users expect it
  • Support for setting a default folder path
  • Support for setting a default file name (e.g. Untitled.c)
  • Support for setting a parent window handle so that the dialog stays on top
  • Consistent UTF-8 support on all platforms
  • Native character set (UTF-16 wchar_t) support on Windows
  • Initialization and de-initialization of platform library (e.g. COM (Windows) / GTK (Linux GTK) / D-Bus (Linux portal)) decoupled from dialog functions, so applications can choose when to initialize/de-initialize
  • Support for multiple selection (for file open and folder select dialogs)
  • Support for Vista's modern IFileDialog on Windows
  • No third party dependencies
  • Modern CMake build system
  • Works alongside SDL, GLFW, and ImGui on all platforms
  • Optional C++ wrapper with unique_ptr auto-freeing semantics and optional parameters, for those using this library from C++

Comparison with original Native File Dialog:

The friendly names feature is the primary reason for breaking API compatibility with Michael Labbe's library (and hence this library probably will never be merged with it). There are also a number of tweaks that cause observable differences in this library.

Features added in Native File Dialog Extended:

  • Friendly names for filters
  • Automatically appending file extensions
  • Support for setting a default file name
  • Support for setting a parent window handle so that the dialog stays on top
  • Native character set (UTF-16 wchar_t) support on Windows
  • xdg-desktop-portal support on Linux that opens the "native" file chooser (see "Usage" section below)
  • Multiple folder selection support
  • Initialization and de-initialization of platform library decoupled from file dialog functions
  • Modern CMake build system
  • Optional C++ wrapper with unique_ptr auto-freeing semantics and optional parameters

There is also significant code refractoring, especially for the Windows implementation.

The wiki keeps track of known language bindings and known popular projects that depend on this library.

Basic Usage

#include <nfd.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    
    NFD_Init();

    nfdu8char_t *outPath;
    nfdu8filteritem_t filters[2] = { { "Source code", "c,cpp,cc" }, { "Headers", "h,hpp" } };
    nfdopendialogu8args_t args = {0};
    args.filterList = filters;
    args.filterCount = 2;
    nfdresult_t result = NFD_OpenDialogU8_With(&outPath, &args);
    if (result == NFD_OKAY)
    {
        puts("Success!");
        puts(outPath);
        NFD_FreePathU8(outPath);
    }
    else if (result == NFD_CANCEL)
    {
        puts("User pressed cancel.");
    }
    else 
    {
        printf("Error: %s\n", NFD_GetError());
    }

    NFD_Quit();
    return 0;
}

The U8/u8 in NFDe refer to the API for UTF-8 characters (char), which most consumers probably want. An N/n version is also available, which uses the native character type (wchar_t on Windows and char on other platforms).

For the full list of arguments that you can set on the args struct, see the "All Options" section below.

If you are using a platform abstraction framework such as SDL or GLFW, also see the "Usage with a Platform Abstraction Framework" section below.

Screenshots

Windows 10 Windows 10 macOS 10.13 macOS 10.13 GTK3 on Ubuntu 20.04 GTK3 on Ubuntu 20.04

Building

On Linux, if building with Wayland support (the default), this project depends on Wayland protocols as a git submodule, so it needs to be checked out:

git submodule update --init

CMake Projects

If your project uses CMake, simply add the following lines to your CMakeLists.txt:

add_subdirectory(path/to/nativefiledialog-extended)
target_link_libraries(MyProgram PRIVATE nfd)

Make sure that you also have the needed dependencies.

When included as a subproject, sample programs are not built and the install target is disabled by default. Add -DNFD_BUILD_TESTS=ON to build sample programs and -DNFD_INSTALL=ON to enable the install target.

Standalone Library

If you want to build the standalone static library, execute the following commands (starting from the project root directory):

For GCC and Clang:

mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build .

For MSVC:

mkdir build
cd build
cmake ..
cmake --build . --config Release

The above commands will make a build directory, and build the project (in release mode) there. If you are developing NFDe, you may want to do -DCMAKE_BUILD_TYPE=Debug/--config Debug to build a debug version of the library instead.

When building as a standalone library, sample programs are built and the install target is enabled by default. Add -DNFD_BUILD_TESTS=OFF to disable building sample programs and -DNFD_INSTALL=OFF to disable the install target.

On Linux, if you want to use the Flatpak desktop portal instead of GTK, add -DNFD_PORTAL=ON. (Otherwise, GTK will be used.) See the "Usage" section below for more information.

See the CI build file for some example build commands.

Visual Studio on Windows

Recent versions of Visual Studio have CMake support built into the IDE. You should be able to "Open Folder" in the project root directory, and Visual Studio will recognize and configure the project appropriately. From there, you will be able to set configurations for Debug vs Release, and for x86 vs x64. For more information, see the Microsoft Docs page. This has been tested to work on Visual Studio 2019, and it probably works on Visual Studio 2017 too.

Compiling Your Programs

  1. Add src/include to your include search path.
  2. Add nfd.lib or nfd_d.lib to the list of static libraries to link against (for release or debug, respectively).
  3. Add build/<debug|release>/<arch> to the library search path.

Dependencies

Linux

GTK (default)

Make sure libgtk-3-dev is installed on your system.

Portal

Make sure libdbus-1-dev is installed on your system.

macOS

On macOS, add AppKit and UniformTypeIdentifiers to the list of frameworks.

Windows

On Windows (both MSVC and MinGW), ensure you are building against ole32.lib, uuid.lib, and shell32.lib.

Usage

All Options

To open a dialog, you set options on a struct and then pass that struct to an NFDe function, e.g.:

nfdopendialogu8args_t args = {0};
args.filterList = filters;
args.filterCount = 2;
nfdresult_t result = NFD_OpenDialogU8_With(&outPath, &args);

All options are optional and may be set individually (zero initialization sets all options to reasonable defaults), except for filterList and filterCount which must be either both set or both left unset.

Future versions of NFDe may add additional options to the end of the arguments struct without bumping the major version number, so to ensure backward API compatibility, you should not assume that the struct has a specific length or number of fields. You may assume that zero-initialization of the struct will continue to set all options to reasonable defaults, so assigning {0} to the struct is acceptable. For those building shared libraries of NFDe, backward ABI compatibility is ensured by an internal version index (NFD_INTERFACE_VERSION), which is expected to be transparent to consumers.

OpenDialog/OpenDialogMultiple:

typedef struct {
    const nfdu8filteritem_t* filterList;
    nfdfiltersize_t filterCount;
    const nfdu8char_t* defaultPath;
    nfdwindowhandle_t parentWindow;
    const nfdu8char_t* title;
    const nfdu8char_t* acceptLabel;
    const nfdu8char_t* cancelLabel;
} nfdopendialogu8args_t;

SaveDialog:

typedef struct {
    const nfdu8filteritem_t* filterList;
    nfdfiltersize_t filterCount;
    const nfdu8char_t* defaultPath;
    const nfdu8char_t* defaultName;
    nfdwindowhandle_t parentWindow;
    const nfdu8char_t* title;
    const nfdu8char_t* acceptLabel;
    const nfdu8char_t* cancelLabel;
} nfdsavedialogu8args_t;

PickFolder/PickFolderMultiple:

typedef struct {
    const nfdu8char_t* defaultPath;
    nfdwindowhandle_t parentWindow;
    const nfdu8char_t* title;
    const nfdu8char_t* acceptLabel;
    const nfdu8char_t* cancelLabel;
} nfdpickfolderu8args_t;

Related Skills

View on GitHub
GitHub Stars1.0k
CategoryDevelopment
Updated1d ago
Forks137

Languages

C++

Security Score

100/100

Audited on Aug 6, 2026

No findings