A tiny, neat C library that portably invokes native file open and save dialogs.

Overview

Native File Dialog

A tiny, neat C library that portably invokes native file open, folder select and 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.

Features:

  • Lean C API, static library -- no ObjC, no C++, no STL.
  • Zlib licensed.
  • Consistent UTF-8 support on all platforms.
  • Simple universal file filter syntax.
  • Paid support available.
  • Multiple file selection support.
  • 64-bit and 32-bit friendly.
  • GCC, Clang, Xcode, Mingw and Visual Studio supported.
  • No third party dependencies for building or linking.
  • Support for Vista's modern IFileDialog on Windows.
  • Support for non-deprecated Cocoa APIs on OS X.
  • GTK3 dialog on Linux.
  • Optional Zenity support on Linux to avoid linking GTK.
  • Tested, works alongside http://www.libsdl.org on all platforms, for the game developers out there.

Example Usage

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

int main( void )
{
    nfdchar_t *outPath = NULL;
    nfdresult_t result = NFD_OpenDialog( NULL, NULL, &outPath );
        
    if ( result == NFD_OKAY ) {
        puts("Success!");
        puts(outPath);
        free(outPath);
    }
    else if ( result == NFD_CANCEL ) {
        puts("User pressed cancel.");
    }
    else {
        printf("Error: %s\n", NFD_GetError() );
    }

    return 0;
}

See self-documenting API NFD.h for more options.

Screenshots

Windows rendering a dialog GTK3 on Linux rendering a dialog Cocoa on MacOS rendering a dialog

Changelog

  • Major version increments denote API or ABI departure.
  • Minor version increments denote build or trivial departures.
  • Micro version increments just recompile and drop-in.
release what's new date
1.0.0 initial oct 2014
1.1.0 premake5; scons deprecated aug 2016
1.1.1 mingw support, build fixes aug 2016
1.1.2 test_pickfolder() added aug 2016
1.1.3 zenity linux backend added nov 2017
fix char type in decls nov 2017
1.1.4 fix win32 memleaks dec 2018
improve win32 errorhandling dec 2018
macos fix focus bug dec 2018
1.1.5 win32 fix com reinitialize aug 2019
1.1.6 fix osx filter bug aug 2019
remove deprecated scons aug 2019
fix mingw compilation aug 2019
-Wextra warning cleanup aug 2019

Building

NFD uses Premake5 generated Makefiles and IDE project files. The generated project files are checked in under build/ so you don't have to download and use Premake in most cases.

If you need to run Premake5 directly, further build documentation is available.

Previously, NFD used SCons to build. As of 1.1.6, SCons support has been removed entirely.

nfd.a will be built for release builds, and nfd_d.a will be built for debug builds.

Makefiles

The makefile offers up to four options, with release_x64 as the default.

make config=release_x86
make config=release_x64
make config=debug_x86
make config=debug_x64

Compiling Your Programs

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

Linux GTK

apt-get libgtk-3-dev installs the gtk dependency for library compilation.

On Linux, you have the option of compiling and linking against GTK. If you use it, the recommended way to compile is to include the arguments of pkg-config --cflags --libs gtk+-3.0.

Linux Zenity

Alternatively, you can use the Zenity backend by running the Makefile in build/gmake_linux_zenity. Zenity runs the dialog in its own address space, but requires the user to have Zenity correctly installed and configured on their system.

MacOS

On Mac OS, add AppKit to the list of frameworks.

Windows

On Windows, ensure you are linking against comctl32.lib.

Usage

See NFD.h for API calls. See tests/*.c for example code.

After compiling, build/bin contains compiled test programs. The appropriate subdirectory under build/lib contains the built library.

File Filter Syntax

There is a form of file filtering in every file dialog API, but no consistent means of supporting it. NFD provides support for filtering files by groups of extensions, providing its own descriptions (where applicable) for the extensions.

A wildcard filter is always added to every dialog.

Separators

  • ; Begin a new filter.
  • , Add a separate type to the filter.

Examples

txt The default filter is for text files. There is a wildcard option in a dropdown.

png,jpg;psd The default filter is for png and jpg files. A second filter is available for psd files. There is a wildcard option in a dropdown.

NULL Wildcard only.

Iterating Over PathSets

See test_opendialogmultiple.c.

Known Limitations

I accept quality code patches, or will resolve these and other matters through support. See contributing for details.

  • No support for Windows XP's legacy dialogs such as GetOpenFileName.
  • No support for file filter names -- ex: "Image Files" (*.png, *.jpg). Nameless filters are supported, however.
  • GTK Zenity implementation's process exec error handling does not gracefully handle numerous error cases, choosing to abort rather than cleanup and return.
  • GTK 3 spams one warning per dialog created.

Copyright and Credit

Copyright © 2014-2019 Frogtoss Games, Inc. File LICENSE covers all files in this repo.

Native File Dialog by Michael Labbe [email protected]

Tomasz Konojacki for microutf8

Denis Kolodin for mingw support.

Tom Mason for Zenity support.

Support

Directed support for this work is available from the original author under a paid agreement.

Contact Frogtoss Games.

Issues
  • Add mingw/msys support

    Add mingw/msys support

    This PR makes similar what #10 does, but with premakes and offered to devel branch.

    I've implemented MinGW/MSYS support. It builds:

    $ cd build/gmake_windows
    $ make
    ==== Building nfd (release_x64) ====
    Creating ../lib/Release/x64
    Creating ../obj/x64/Release/nfd
    nfd_common.c
    nfd_win.cpp
    Linking nfd
    ==== Building test_opendialog (release_x64) ====
    Creating ../bin
    Creating ../obj/x64/Release/test_opendialog
    test_opendialog.c
    Linking test_opendialog
    ==== Building test_opendialogmultiple (release_x64) ====
    Creating ../obj/x64/Release/test_opendialogmultiple
    test_opendialogmultiple.c
    Linking test_opendialogmultiple
    ==== Building test_savedialog (release_x64) ====
    Creating ../obj/x64/Release/test_savedialog
    test_savedialog.c
    Linking test_savedialog
    

    I've checked all tests, It works!

    P.S. I made changes with linux, but checked it with windows+msys.

    opened by DenisKolodin 18
  • GTK+3: Dialog does not disappear

    GTK+3: Dialog does not disappear

    When using NFD from SDL, I noticed that the dialog never disappears after clicking Cancel or OK. It freezes and control is returned to the application as expected, but still remains in the foreground of the application. I can then call the window to the background and continue work. On the next call, the window appears as expected, but predictably shows the same behavior.

    I would expect that the dialog disappears and focus is returned to the previous window.

    opened by paniq 12
  • Support for compiling with MSYS

    Support for compiling with MSYS

    This pull request includes support for compiling NFD using the MSYS/MinGW environment.

    opened by rafalcieslak 11
  • Screen does no longer update after dismissing the open dialog on OSX using SDL

    Screen does no longer update after dismissing the open dialog on OSX using SDL

    I seem to have a bit of trouble with NFD_OpenDialog on OSX that calls NSOpenPanel which changes the glContext. The same problem occurs with NFD_SaveDialog if you browse more files and then dismiss the dialog.

    I've tried various workarounds like this: http://stackoverflow.com/questions/13987148/nsopenpanel-breaks-my-sdl-opengl-app but I can't get anything to work. Am I missing something? Using SDL version 2.0.3.

    / Harry

    opened by lundstroem 10
  • add zenity backend

    add zenity backend

    Hey, I'd like to use this and don't want to pull in all of gtk as a dependency, so I added a zenity backend, as you suggested in your readme.

    opened by wheybags 10
  • Select Directory Support

    Select Directory Support

    Hi,

    I wonder if there are any plans on supporting the ability to select a directory?

    opened by emoon 9
  • Focus for Mac Window

    Focus for Mac Window

    Hi,

    first of all thanks for the great work on the Native File Requester. We use it on www.visualgraphics.tv for multi os file requesters for the Desktops.

    We have one issue which may not be yours. Under Mac / Cocoa we never succeed in setting the focus back to the SDL2 OpenGL Window after a Dialog was open. Resulting that the user has to select the main window once before being able to continue work.

    Did you see this behavior too ?

    Thanks again,

    Markus

    opened by markusmoenig 8
  • About Adding In ARM64 Support

    About Adding In ARM64 Support

    Hello,

    I noticed that nativefiledialog does not have support for ARM64. I added in the changes needed to build nativefiledialog on ARM64 Linux (and Windows in theory, but I haven't test building on Windows).

    But before I make a PR, I want to ask a question about one of your bullet points:

    Do not submit anything I can't verify or maintain.

    Do you have the ability to verify ARM64 builds? I'm worried that you might reject my PR if you don't have any ARM64 hardware to test the ARM64 builds.

    linux feature macos 
    opened by CuriousTommy 7
  • Fix MinGW requiring fpermissive to compile

    Fix MinGW requiring fpermissive to compile

    This is the error I get otherwise:

    ../../src/nfd_win.cpp: In function 'nfdresult_t NFD_OpenDialog(const nfdchar_t*, const nfdchar_t*, nfdchar_t**)':
    ../../src/nfd_win.cpp:448:1: error: jump to label 'end' [-fpermissive]
     end:
     ^~~
    ../../src/nfd_win.cpp:379:14: note:   from here
             goto end;
                  ^~~
    ../../src/nfd_win.cpp:383:13: note:   crosses initialization of 'HRESULT result'
         HRESULT result = ::CoCreateInstance(::CLSID_FileOpenDialog, NULL,
                 ^~~~~~
    
    opened by ncruces 6
  • [OSX] File Extensions filters < 3 chars not working

    [OSX] File Extensions filters < 3 chars not working

    I originally wanted to add a file extension for 7-zip files (7z) but it would not work.. After some experimenting, I found that "e7" also did not work but "e7e" did work... I also could not get "7z " or " 7z" to work..

    I could not find any NFD code that alluded to constraining the file extension to 3-chars, making me wonder if this is a different issue outside of NFD.. here are the relevant functions regarding the filter list:

    NFD_OpenDialogMultiple AddFilterListToDialog BuildAllowedFileTypes

    I am not skilled with OBJC so I'm not sure how to fix the problem.

    opened by bazz1tv 6
  • GTK+ dialogs always crash

    GTK+ dialogs always crash

    Compilation Environment

    • OS (eg: OSX 10.14, Ubuntu 18.04): #1 SMP Debian 5.10.70-1 (2021-09-30)
    • Compiler (eg: GCC, Clang): gcc
    • Compiler Version (eg: MSVC 2017): gcc version 10.2.1 20210110 (Debian 10.2.1-6)
    • Build directory used (eg: build/gmake_linux: included sources
    • Have I attempted to reproduce the problem on the devel branch? No, devel does not compile

    Describe the bug

    GTK+ always crashes on any file dialog operation:

    libpng warning: Image width exceeds user limit in IHDR
    libpng warning: Image height exceeds user limit in IHDR
    libpng error: Invalid IHDR data
    Segmentation fault
    

    Additional context

    Note, the app that uses NFD is using SDL2 only and might be that GTK+ is not initialised. Devel branch does not compile with errors like

    ftg_core.h:13771:12: error: stray ‘\342’ in program
    13771 |     You can’t perform that action at this time.
    

    User Description

    Open source / Individual.

    opened by slajerek 0
  • feature request: set dialog title

    feature request: set dialog title

    Currently, your API does not allow the title of the file dialog to be specified.

    It seems straightforward to support this, because all of the underlying platform APIs provide an option to set the title:

    • IFileDialog::SetTitle on Windows
    • title property of NSSavePanel on MacOS
    • on Gtk and Zenity you are already setting the title to "Open File": https://github.com/mlabbe/nativefiledialog/blob/67345b80ebb429ecc2aeda94c478b3bcc5f7888e/src/nfd_gtk.c#L181 and https://github.com/mlabbe/nativefiledialog/blob/67345b80ebb429ecc2aeda94c478b3bcc5f7888e/src/nfd_zenity.c#L190

    PS. Just got a Julia wrapper for this library (https://github.com/Suavesito-Olimpiada/NativeFileDialog.jl) along with precompiled binaries for many platforms (https://github.com/JuliaBinaryWrappers/NativeFileDialog_jll.jl), thanks to @Suavesito-Olimpiada.

    opened by stevengj 0
  • NFD_MAX_STRLEN is 256, but MAX_PATH on Linux often is 4096, as well as unsafe strdup() use

    NFD_MAX_STRLEN is 256, but MAX_PATH on Linux often is 4096, as well as unsafe strdup() use

    I've checked the source code and found that NFD_MAX_STRLEN is 256 and maybe used for paths. However, on Linux MAX_PATH is often 4096. But with a 4096 buffer, it is probably risky to just put it multiple times onto the stack as done here since that might exceed the stack space on some systems with less stack by default (Alpine with musl-libc comes to mind). So that might need some more fundamental refactoring.

    While checking this file, I have also found strdup() is used without null pointer checking, meaning the code would crash on allocation failure rather than allowing the calling application to recover in some way which would be preferable. I've seen a similar potential issue with NFDi_Malloc use. (I know this recovery isn't safely possible with glib/GTK+, but it should be with most/all(?) other targets.)

    opened by ell1e 1
  • Suggestion/feature request: use dlopen() for GTK+

    Suggestion/feature request: use dlopen() for GTK+

    The README suggests using GTK+ dialogs requires to link GTK+, which automatically makes a build unusable on Linux systems where it is installed. For greater versatility of the resulting binaries, wouldn't it be possible to require GTK+3 only at build time by using dlopen() and function pointers instead (and otherwise only its headers but no link) to access it? I think that'd be a great addition to allow more universal binaries. It would also allow the library to report some sort of recoverable error if neither GTK+ nor zenity are available, such that the calling program could possibly fall back to other alternatives if desired.

    opened by ell1e 0
  • Selecting *.* on windows causes it to use the last file format instead

    Selecting *.* on windows causes it to use the last file format instead

    Compilation Environment

    • OS: Windows 10
    • Compiler: MSVC 2019
    • Build directory used: cmake
    • Have I attempted to reproduce the problem on the devel branch? Yes

    Describe the bug

    nfdchar_t* path = nullptr;
    auto result = NFD_SaveDialog("mp4;mkv;webm", nullptr, &path);
    if (result == NFD_OKAY) {
        std::cout << "Selected path is: " << path << std::endl;
        free(path);
    }
    

    This will create a file dialog with 4 options, *.mp4, *.mkv, *.webm and *.* The first three work fine, however, picking *.* will append .webm to the path instead of not appending anything

    opened by matcool 1
  • support Windows XP

    support Windows XP

    I would eventually like for this to be used as a fallback at runtime when the Vista API is not available (as discussed on #12), but I'm comfortable doing a separate build for now.

    opened by z64me 0
  • Added a CMakeLists file

    Added a CMakeLists file

    Added a CMakeLists file for anyone using cmake like me.

    opened by AlvaroBarua 0
  • Zenity: add --confirm-overwrite for save dialog

    Zenity: add --confirm-overwrite for save dialog

    Zenity: The save dialog now prompts the user for confirmation if the selected path already exists.

    opened by jorio 0
  • Memory leak in AddFiltersToDialog on Windows (nfd_win.cpp)

    Memory leak in AddFiltersToDialog on Windows (nfd_win.cpp)

    Compilation Environment

    • OS: Windows
    • Compiler: MSVC
    • Compiler Version: MSVC 1928
    • Build directory used: vs2010
    • Have I attempted to reproduce the problem on the devel branch? Yes

    Memory leak in AddFiltersToDialog when deallocating COMDLG_FILTERSPEC

    Before the function returns in AddFiltersToDialog, the code frees the allocated memory for specList and its members, but it only does it for the pszSpec but not the pszName. In the for loop there should also be a line for NFDi_Free( (void*)specList[i].pszName );.

    opened by KaiH0717 0
  • Zenity does not append extensions from filterlist onto return value

    Zenity does not append extensions from filterlist onto return value

    As of c0e491055bba7b6e0326e2d94566b65e6aebc014, the GTK build adds an extension to the returned value. This is done to match the behaviour of the other platforms. This affects the dialogs that return filenames.

    The extension is derived from the first filter in the selected list. For example, if the user passes in png,jpg;pdf, then the three extensions that will be presented are:

    • png, jpg
    • pdf
    • *.*

    If the user enters some_file with the first filter selected, then some_file.png is returned. If the user enters some_file with the second filter selected, then some_file.pdf is returned. With the third filter selected, some_file is returned.

    It appears to not be possible to query which filter was selected when Zenity returns, so this functionality cannot be added to Native File Dialog. As a result, it always returns some_file. If anyone knows a way to get the selected filter from Zenity or a way to provide parity, please update this bug.

    opened by mlabbe 1
Releases(release_116)
Owner
Michael Labbe
I program.
Michael Labbe
Tiny library for handling rust strings in windows.

tinywinstr Tiny library for handling rust strings in windows.

Ed Way 1 Oct 25, 2021
Simple and portable (but not inflexible) GUI library in C that uses the native GUI technologies of each platform it supports.

libui: a portable GUI library for C This README is being written. Status It has come to my attention that I have not been particularly clear about how

Pietro Gagliardi 10.1k Nov 21, 2021
Cross-platform native Rust menu library

A cross-platform Rust library for managing the native operating system menus.

Mads Marquart 6 Nov 22, 2021
A data-first Rust-native UI design toolkit.

Druid A data-first Rust-native UI toolkit. Druid is an experimental Rust-native UI toolkit. Its main goal is to offer a polished user experience. Ther

null 4.8k Nov 23, 2021
Rust bindings to the minimalist, native, cross-platform UI toolkit `libui`

Improved User Interface A cross-platform UI toolkit for Rust based on libui iui: ui-sys: iui is a simple (about 4 kLOC of Rust), small (about 800kb, i

Rust Native UI Group 797 Nov 17, 2021
Truly cross platform, truly native. multiple backend GUI for rust

WIP: Sauron-native a rust UI library that conquers all platforms ranging from desktop to mobile devices. An attempt to create a truly native, truly cr

Jovansonlee Cesar 617 Nov 19, 2021
File system enumerator and monitor for Android.

File system enumerator and file monitor for Android. Built to be compatible with other command line utilties! This tool was created to somewhat automa

Kyle Benac 12 Sep 25, 2021
A cross-platform GUI library for Rust focused on simplicity and type-safety

A cross-platform GUI library for Rust, inspired by Elm

Héctor Ramón 12k Nov 29, 2021
A react-inspired UI library for building multimedia desktop apps with rust and vulkan.

narui A react-inspired UI library for building multimedia desktop apps with rust and vulkan. declarative UI with Ergonomics similar to React with hook

apertus° - open source cinema 13 Nov 23, 2021
An idiomatic GUI library inspired by Elm and based on gtk4-rs

An idiomatic GUI library inspired by Elm and based on gtk4-rs. Relm4 is a new version of relm that's built from scratch and is compatible with GTK4 an

Aaron Erhardt 181 Nov 22, 2021
An easy-to-use, 2D GUI library written entirely in Rust.

Conrod An easy-to-use, 2D GUI library written entirely in Rust. Guide What is Conrod? A Brief Summary Screenshots and Videos Feature Overview Availabl

PistonDevelopers 3.2k Nov 28, 2021
Rust bindings for the FLTK GUI library.

fltk-rs Rust bindings for the FLTK Graphical User Interface library. The FLTK crate is a crossplatform lightweight gui library which can be statically

Mohammed Alyousef 550 Nov 22, 2021
Idiomatic, GTK+-based, GUI library, inspired by Elm, written in Rust

Relm Asynchronous, GTK+-based, GUI library, inspired by Elm, written in Rust. This library is in beta stage: it has not been thoroughly tested and its

null 2.1k Nov 29, 2021
Clear Coat is a Rust wrapper for the IUP GUI library.

Clear Coat Clear Coat is a Rust wrapper for the IUP GUI library. IUP uses native controls and has Windows and GTK backends. A macOS backend has been o

Jordan Miner 18 Feb 13, 2021
A single-header ANSI C immediate mode cross-platform GUI library

Nuklear This is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed a

Immediate Mode UIs, Nuklear, etc. 5k Nov 22, 2021
The bindings to the Nuklear 2D immediate GUI library.

nuklear-rust The bindings to the Nuklear 2D immediate GUI library. Currently beta. Drawing backends: gfx-pre-ll for GFX 3D drawing engine (examples: O

Serhii Plyhun 324 Nov 17, 2021
A cross-platform GUI library for Rust, inspired by Elm

Iced A cross-platform GUI library for Rust focused on simplicity and type-safety. Inspired by Elm. Features Simple, easy-to-use, batteries-included AP

Héctor Ramón 12k Nov 24, 2021
SwiftUI Inspired UI Library written in rust

Mule (Definitely a Work in Progress) The night I started this project I was on the couch drinking a Moscow Mule.

null 37 Aug 22, 2021
Termbox is a library that provides minimalistic API which allows the programmer to write text-based user interfaces.

Termbox is a library that provides minimalistic API which allows the programmer to write text-based user interfaces.

null 1.8k Nov 24, 2021