Git Product home page Git Product logo

nativefiledialog-extended's Introduction

Native File Dialog Extended

GitHub Actions

A small C library with 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
  • Supports 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)
  • 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
  • Multiple file selection support (for file open dialog)
  • Support for Vista's modern IFileDialog on Windows
  • No third party dependencies
  • Modern CMake build system
  • Works alongside SDL2 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
  • 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)
  • 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();

    nfdchar_t *outPath;
    nfdfilteritem_t filterItem[2] = { { "Source code", "c,cpp,cc" }, { "Headers", "h,hpp" } };
    nfdresult_t result = NFD_OpenDialog(&outPath, filterItem, 2, NULL);
    if (result == NFD_OKAY)
    {
        puts("Success!");
        puts(outPath);
        NFD_FreePath(outPath);
    }
    else if (result == NFD_CANCEL)
    {
        puts("User pressed cancel.");
    }
    else 
    {
        printf("Error: %s\n", NFD_GetError());
    }

    NFD_Quit();
    return 0;
}

See NFD.h for more options.

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

Screenshots

Windows 10 Windows 10 MacOS 10.13 MacOS 10.13 GTK3 on Ubuntu 20.04 GTK3 on Ubuntu 20.04

Building

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

See NFD.h for API calls. See the test directory for example code (both C and C++).

If you turned on the option to build the test directory (-DNFD_BUILD_TESTS=ON), then build/bin will contain the compiled test programs.

File Filter Syntax

Files can be filtered by file extension groups:

nfdfilteritem_t filterItem[2] = { { "Source code", "c,cpp,cc" }, { "Headers", "h,hpp" } };

A file filter is a pair of strings comprising the friendly name and the specification (multiple file extensions are comma-separated).

A list of file filters can be passed as an argument when invoking the library.

A wildcard filter is always added to every dialog.

Note: On MacOS, the file dialogs do not have friendly names and there is no way to switch between filters, so the filter specifications are combined (e.g. "c,cpp,cc,h,hpp"). The filter specification is also never explicitly shown to the user. This is usual MacOS behaviour and users expect it.

Note 2: You must ensure that the specification string is non-empty and that every file extension has at least one character. Otherwise, bad things might ensue (i.e. undefined behaviour).

Note 3: On Linux, the file extension is appended (if missing) when the user presses down the "Save" button. The appended file extension will remain visible to the user, even if an overwrite prompt is shown and the user then presses "Cancel".

Note 4: On Windows, the default folder parameter is only used if there is no recently used folder available. Otherwise, the default folder will be the folder that was last used. Internally, the Windows implementation calls IFileDialog::SetDefaultFolder(IShellItem). This is usual Windows behaviour and users expect it.

Iterating Over PathSets

A file open dialog that supports multiple selection produces a PathSet, which is a thin abstraction over the platform-specific collection. There are two ways to iterate over a PathSet:

Accessing by index

This method does array-like access on the PathSet, and is the easiest to use. However, on certain platforms (Linux, and possibly Windows), it takes O(N2) time in total to iterate the entire PathSet, because the underlying platform-specific implementation uses a linked list.

See test_opendialogmultiple.c.

Using an enumerator (experimental)

This method uses an enumerator object to iterate the paths in the PathSet. It is guaranteed to take O(N) time in total to iterate the entire PathSet.

See test_opendialogmultiple_enum.c.

This API is experimental, and subject to change.

Customization Macros

You can define the following macros before including nfd.h/nfd.hpp:

  • NFD_NATIVE: Define this before including nfd.h to make non-suffixed function names and typedefs (e.g. NFD_OpenDialog) aliases for the native functions (e.g. NFD_OpenDialogN) instead of aliases for the UTF-8 functions (e.g. NFD_OpenDialogU8). This macro does not affect the C++ wrapper nfd.hpp.
  • NFD_THROWS_EXCEPTIONS: (C++ only) Define this before including nfd.hpp to make NFD::Guard construction throw std::runtime_error if NFD_Init fails. Otherwise, there is no way to detect failure in NFD::Guard construction.

Macros that might be defined by nfd.h:

  • NFD_DIFFERENT_NATIVE_FUNCTIONS: Defined if the native and UTF-8 versions of functions are different (i.e. compiling for Windows); not defined otherwise. If NFD_DIFFERENT_NATIVE_FUNCTIONS is not defined, then the UTF-8 versions of functions are aliases for the native versions. This might be useful if you are writing a function that wants to provide overloads depending on whether the native functions and UTF-8 functions are the same. (Native is UTF-16 (wchar_t) for Windows and UTF-8 (char) for Mac/Linux.)

Usage with a Platform Abstraction Framework

NFDe is known to work with SDL2 and GLFW, and should also work with other platform abstraction framworks. However, you should initialize NFDe after initializing the framework, and probably should deinitialize NFDe before deinitializing the framework. This is because some frameworks expect to be initialized on a "clean slate", and they may configure the system in a different way from NFDe. NFD_Init is generally very careful not to disrupt the existing configuration unless necessary, and NFD_Quit restores the configuration back exactly to what it was before initialization.

An example with SDL2:

// Initialize SDL2 first
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) != 0) {
    // display some error here
}

// Then initialize NFDe
if (NFD_Init() != NFD_OKAY) {
    // display some error here
}

/*
Your main program goes here
*/

NFD_Quit(); // deinitialize NFDe first

SDL_Quit(); // Then deinitialize SDL2

Using xdg-desktop-portal on Linux

On Linux, you can use the portal implementation instead of GTK, which will open the "native" file chooser selected by the OS or customized by the user. The user must have xdg-desktop-portal and a suitable backend installed (this comes pre-installed with most common desktop distros), otherwise NFD_ERROR will be returned.

To use the portal implementation, add -DNFD_PORTAL=ON to the build command.

Note: Setting a default path is not supported by the portal implementation, and any default path passed to NFDe will be ignored. This is a limitation of the portal API, so there is no way NFDe can work around it. If this feature is something you desire, please show your interest on flatpak/xdg-desktop-portal#874.

*Note 2: The folder picker is only supported on org.freedesktop.portal.FileChooser interface version >= 3, which corresponds to xdg-desktop-portal version >= 1.7.1. NFD_PickFolder() will query the interface version at runtime, and return NFD_ERROR if the version is too low.

What is a portal?

Unlike Windows and MacOS, Linux does not have a file chooser baked into the operating system. Linux applications that want a file chooser usually link with a library that provides one (such as GTK, as in the Linux screenshot above). This is a mostly acceptable solution that many applications use, but may make the file chooser look foreign on non-GTK distros.

Flatpak was introduced in 2015, and with it came a standardized interface to open a file chooser. Applications using this interface did not need to come with a file chooser, and could use the one provided by Flatpak. This interface became known as the desktop portal, and its use expanded to non-Flatpak applications. Now, most major desktop Linux distros come with the desktop portal installed, with file choosers that fit the theme of the distro. Users can also install a different portal backend if desired. There are currently two known backends: GTK and KDE. (XFCE does not currently seem to have a portal backend.)

Platform-specific Quirks

MacOS

  • If the MacOS deployment target is โ‰ฅ 11.0, the allowedContentTypes property of NSSavePanel is used instead of the deprecated allowedFileTypes property for file filters. Thus, if you are filtering by a custom file extension specific to your application, you will need to define the data type in your Info.plist file as per the Apple documentation. (It is possible to force NFDe to use allowedFileTypes by adding -DNFD_USE_ALLOWEDCONTENTTYPES_IF_AVAILABLE=OFF to your CMake build command, but this is not recommended. If you need to support older MacOS versions, you should be setting the correct deployment target instead.)

Known Limitations

  • No support for Windows XP's legacy dialogs such as GetOpenFileName. (There are no plans to support this; you shouldn't be still using Windows XP anyway.)
  • No Emscripten (WebAssembly) bindings. (This might get implemented if I decide to port Circuit Sandbox for the web, but I don't think there is any way to implement a web-based folder picker.)
  • GTK dialogs don't set the existing window as parent, so if users click the existing window while the dialog is open then the dialog will go behind it. GTK writes a warning to stdout or stderr about this.
  • Portal dialogs (the alternative to GTK on Linux) don't support a default path. Any default path you supply will be ignored.
  • This library is not compatible with the original Native File Dialog library. Things might break if you use both in the same project. (There are no plans to support this; you have to use one or the other.)
  • This library does not explicitly dispatch calls to the UI thread. This may lead to crashes if you call functions from other threads when the platform does not support it (e.g. MacOS). Users are generally expected to call NFDe from an appropriate UI thread (i.e. the thread performing the UI event loop).

Reporting Bugs

Please use the GitHub issue tracker to report bugs or to contribute to this repository. Feel free to submit bug reports of any kind.

Credit

Bernard Teo (me) and other contributors for everything that wasn't from Michael Labbe's Native File Dialog.

Michael Labbe for his awesome Native File Dialog library, and the other contributors to that library.

Much of this README has also been copied from the README of original Native File Dialog repository.

License

Everything in this repository is distributed under the ZLib license, as is the original Native File Dialog library.

Support

I don't provide any paid support. Michael Labbe appears to provide paid support for his library at the time of writing.

nativefiledialog-extended's People

Contributors

achep avatar api-beast avatar ashkitten avatar btzy avatar dabbertorres avatar ds5678 avatar encounter avatar erikprantare avatar frostkiwi avatar itrooz avatar jgranick avatar jonathanspw avatar ltjax avatar mlabbe avatar monwarez avatar mrsapps avatar noah1510 avatar tamaskenez avatar tcantenot avatar therustmonk avatar tomix1024 avatar topolarity avatar werwolv avatar wheybags 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  avatar  avatar  avatar

nativefiledialog-extended's Issues

Crash on Linux when NFD is initialized before GLFW window is created

This isn't so much a bug to be fixed, but due to the restructuring of code from NFD requiring explicit initialization, there's now a potential for causing problems for the Linux platform.

The issue is that, for applications using GLFW, if you initialize NFD before you initialize GLFW and create a window, you'll get a mysterious crash deep in GTK code whenever you try to open a native dialog on Linux. This may be true of other X11-based apps besides GLFW, but I can't confirm this.

This is definitely something you should make note of in your documentation. I'm just thankful I found the cause, since I appreciate the enhancements you made in this NFD fork. I was planning to fix the same things you did in the original NFD library before I found your version. Thanks for the work you've done in enhancing the library!

IEEE_INVALID_FLAG message after calling NFD from gfortran

I am calling NFD from gfortran for a file dialog to get a path to a file. Everything works but I get an IEEE error at exit (from fortran).
I use a short C interface (largely taken from the test_getfiledialog.c example) as the "glue" to gfortran. The main only consists of a call to the getfiledialog interface and a print of the path to check it. This output follows after the gfortran code exit:

"Note: The following floating-point exceptions are signalling: IEEE_INVALID_FLAG"

This message does NOT appear if I call the same interface from a C main() rather than from gfortran.

These IEEE messages appear for OSX and for Ubuntu using gfortran (from macports or brew on OSX) but no similar message appears when the same code is compiled and run on Win10/11 compiling with MSYS2/mingw64.

I am mystified why an IEEE floating point exception is being triggered for NFD... and not for mingw64.

can help me create a wrapper version for c#?

I am working with AvaloniaUI, sorry, Avalonia OpenFileDialog is not suitable for NativeAOT compiler. Can you help me create the wrapper version for .net of this library?
Thanks very much

Open an asynchronous File Dialog

Opening the file dialog (or folder picker) in main thread blocks the main thread.
Currently my application's rendering, and input (handled by glfw) is done on the main thread, and it gets blocked if a file dialog is opened

Now on Windows and Linux, I'm able to open the file dialog asynchronously using std::async (I have to call the NFD init and quit functions from the new thread only)

ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย resultย =ย std::async(std::launch::async, 
 ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย [](NFD::UniquePath&ย outpath) 
 ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย { 
 ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย //ย Initย andย Uninitย inย theย sameย threadย asย Dialogย creation 
 ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย NFD::Init(); 
 ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย autoย retย =ย NFD::PickFolder(outpath,ย nullptr,ย "Openย Project"); 
 ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย NFD::Quit(); 
 ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย returnย ret; 
 ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย }, 
 ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย std::reference_wrapper(outpath));

However, this does not work for AppKit.

Is there any way add an async API to open dialogs?

More C++y API

The C++ wrapper atm is still (understandabley) pretty C-y.
Some things that could be improved would be to use std::basic_string instead of unique_ptr,
and to use std::filesystem::path to represent paths.

I understand that this could possibly mean API breaks, so I'm wondering how backwards compatible this project tries to be?
We could also use [[deprecated(reason)]] to faze out old functions if that would help.

One issue could possibly be the need to maintain two separate APIs for C and C++, as they'd diverge more.

I'm thinking about forking this and just do away with all the C, but I'd rather contribute to an already existing repo if it's possible :^)

PickFolder returns a file path on Ubuntu 20.04

Hello and thanks for the great library!

I have an issue when calling PickFolder with the portal implementation, it shows up on Ubuntu 20.04, nfde 1.0.2, running the included test.

Build config: cmake -DCMAKE_BUILD_TYPE=Release -DNFD_PORTAL=ON .., this is the result:

~/nativefiledialog-extended/build$ ./test/test_pickfolder_c
Success!
/home/tom/xpano/tests/data/image00.jpg

The picker is correctly titled "Select Folder", but the individual files are not greyed out and the returned value is the full path to the first file. I haven't figured out a way to select just the directory path.

20

latest available libdbus version is installed:

libdbus-1-dev/focal-updates,focal-security,now 1.12.16-2ubuntu2.3 amd64 [installed]

With the GTK implementation the files are greyed out as expected and a directory path is returned:

image

~/nativefiledialog-extended/build$ ./test/test_pickfolder_c
Success!
/home/tom/xpano/tests/data

Also with Ubuntu 22.04 the library works as expected both in portal and GTK implementations.

WebAssembly (emscripten) support

Hi, I'm not committing to anything, but I'd like to add support for WebAssembly/emscripten to this library. (WerWolv/ImHex#1299)

(The implementation would use the browser's methods to let the user pick a file/folder in their filesystem)

Is that something you'd be interested in ?

MinGW support is unknown

The README suggests that MinGW is supported, but it hasn't been tested since being forked from the upstream NFD repository. There is no GitHub Action for MinGW, so we can't be sure that it still works.

How does this project work?

I'd be interested in learning more about how this project works. Some questions:

  • What's the .m file? Beginner here. I googled and "An M file is a class implementation file used by programs written in Objective-C"
  • Is this project written in .c or .cpp?
  • What's the high-level overview of what this project does? Is it basically a wrapper with #ifdef WINDOWS cascades for each platform?
  • What's gtk?

Why I'm curious: I'm interested in making a JavaScript wrapper around this API using https://napi.rs/ and https://github.com/btzy/nfde-rs and I was curious about some of the design decisions behind that Rust wrapper and that lead me to be curious about the design of the original library.

Consider comparison of other native file dialog libraries?

in my cursory google searching, i was able to to find the interesting https://sourceforge.net/projects/tinyfiledialogs/ project that seems to be similarish to this project. i'd be interested in seeing a comparison paragraph similar to how the current readme describes some differences between it and the original nativefiledialog library.

why not leave such comparisons as an exercise to the reader? because a reader may not be as "in-tune" with the strengths and weaknesses of your library. you wrote it; โค๏ธ tell me how cool it is! ๐Ÿ˜Š

other cool file dialog libraries i found

https://github.com/samhocevar/portable-file-dialogs

  • c++11
  • header only
  • sync or async

https://github.com/PolyMeilex/rfd

  • rust
  • wasm support with html-based <input> popup
  • sync or async

C++ PickFolder, pass UniquePath by reference

In the C++ version, the PickFolder functions do not pass UniquePathN and UniquePathU8 by reference as the other functions do. This results in a compiler error:

error C2280: 'std::unique_ptr<nfdchar_t,NFD::PathDeleter<nfdchar_t>>::unique_ptr(const std::unique_ptr<nfdchar_t,NFD::PathDeleter<nfdchar_t>> &)': attempting to reference a deleted function

inline nfdresult_t PickFolder(UniquePathN outPath, const nfdnchar_t* defaultPath = nullptr) noexcept {

inline nfdresult_t PickFolder(UniquePathU8 outPath, const nfdu8char_t* defaultPath = nullptr) noexcept {

Changing these to references resolved the issue for me.

New API to set each property of the dialog separately

EDIT: A versioned struct will be used instead of this, implemented in #128.

The current API looks like:

nfdresult_t res = NFD_OpenDialogN(outPath, filterList, filterCount, "/path/to/default/folder");

This interface is inextensible. It is impossible to add new parameters without breaking API and ABI, so it is not possible to provide some improvements in a non-breaking manner. They include:

  • Setting a custom title on a dialog (#63) (this feature is also required by Linux applications wishing to provide non-English translations of the text "Open File" etc, since unlikely Windows and MacOS, GTK does not provide a default title).
  • Setting a parent window handle (HWND on Windows, parent_window string on Portal, etc) (required to properly fix #90).

Adding a new API that sets each property separately will allow support for additional parameters, and also make it more future-proof, like the following:

NFD_OpenFileDialog* dialog = NFD_OpenFileDialog_Create();
NFD_OpenFileDialog_SetFilterList(dialog, filterList, filterCount);
NFD_OpenFileDialog_SetDefaultFolder(dialog, "/path/to/default/folder");
nfdresult_t res = NFD_OpenFileDialog_Show(dialog, outPath);

I'm not decided on this and am not sure that this is the best way yet - feel free to leave comments.

The current API will be retained, and it will call the new API under the hood.

Try to use portals, and fall back on GTK

Hey !

Portals can be quite difficult to setup for users, which make it difficult for us to use it, but the native feeling is great for those who want it

Would it be possible to add a "build option" (or idk) to compile both portals and GTK implementations, and first try to use portals, and fallback on GTK popups ?

I'd be ready to help with that
Thanks !

CI bug?

I've been working on generating automated builds for use in NuGet packages, and I noticed something in your build script:

autoappend: {flag: ON, name: NoAppendExtn}

This appears to be a bug because it doesn't match the other ones in the file.

autoappend: {flag: ON, name: AutoAppendExtn}

autoappend: [ {flag: OFF, name: NoAppendExtn} ] # By default the NFD_PORTAL mode does not append extensions, because it breaks some features of the portal

GTK4 Support

GTK4 has been released, we should eventually support it.

Most of the work has been done in #38 , but the major blocking issue is this. In summary, it is not possible to hide non-local files in the GTK4 file chooser (non-local files are those that do not have filepaths, such as resources on the Internet). We either have to filter the response and show an error message if non-local files are selected, or implement a shim to download those non-local files (not sure if this might be out of scope for NFD?).

Opinions on this issue are welcome.

xdg-desktop-portal backend on Linux returns URI encoded paths

Hi

I recently switched from the GTK backend to the Portals backend on Linux to allow file dialogs to work properly in Flatpaks and AppImages. Switching over was easy, however the xdg-desktop-portal backend returns all paths in URI encoding.

For example:
/home/werwolv/Hello World.txt becomes /home/werwolv/Hello%20World.txt

That behaviour is different from all the other backend which directly returns the normal path.

Is this an oversight in the library?
If it's the expected behaviour, what is the intended way to deal with these paths?

[Windows] Selecting *.* causes save dialog to append entire list of last selected file formats

Steps to reproduce:

  1. Run test_savedialog.c.
  2. Change the filter dropdown to *.*.
  3. Type a file name without extension (e.g. "test"), and click "Save" / press Enter.
  4. Observe that the returned file name is "C:\path\to\file\test.c,cpp,cc".

Expected behaviour:

It should return "C:\path\to\file\test.c" (i.e. just the first extension) instead. Note that normal Windows behaviour seems to append the ".c" extension even if the filter dropdown is *.*, so we should stick to that.

Reference: mlabbe/nativefiledialog#101

Problems with linking using a simple Makefile.

gcc editor.c SDL_FontCache.c -g -lSDL2 -lSDL2_image -lSDL2_ttf submodules/nativefiledialog-extended/build/src/libnfd.a -o editor
gives me:
/bin/ld: submodules/nativefiledialog-extended/build/src/libnfd.a(nfd_gtk.cpp.o): undefined reference to symbol 'g_free' /bin/ld: /lib/x86_64-linux-gnu/libglib-2.0.so.0: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status make: *** [Makefile:19: all] Error 1

I have little to no experience with cmake. How do I go about solving this issue?

Consider documentation website?

It doesn't have to be big! I want to make that very clear. Even a tiny landing page would be sufficient.

Why this might be a good idea:

  • Google SEO. GitHub project readmes have okish SEO. GitHub wikis have almost zero. They don't seem to be indexed very well
    image
  • Putting more detailed docs outside the readme. This is more of an organizational thing to keep the readme sort of like an "index page" that outsources to the developer-focused "how does this work" (GitHub wiki) and "how do I contribute" (CONTRIBUTING.md) and the user-focused "how do I use this" (docs website) places.
  • Encourage more examples! Having a place to put examples that makes them look nice and pretty with prose explainer text and/or images too next to them is good!
  • Document the API a little more effectively. JavaScript + TypeScript (where I come from) notoriously has terrific IDE intellisense! This combined with JSDoc comments means that you can do this:

    the C/C++ ecosystem doesn't quite have the same level. There's some in-code intellisense, but out-of-code documentation really helps.
  • Preview what the library does! Having even an auto-generated website like this: https://mesqueeb.github.io/is-what/ is vastly better than having to download the thing to your PC when you are browsing on your phone.
  • Legitimacy. Basically the same as SEO, but more for answering the "should I use this library or the original?" question by showing (not telling)

The website itself doesn't have to be very complicated. Here's an example of what the files might look like if you use Vitepress https://vitepress.dev/ (Markdown-based static site generator):
image
(there's a stackblitz demo in there too that's used as an embed <iframe>; ignore that)
https://github.com/jcbhmr/tsx/tree/add-docs-site/docs

Compilation issue with macOS SDK 12.3

Hi there. When trying to build Tracy (wolfpld/tracy#368) on a recently upgraded macOS, I encountered the following compilation issue with NFD:

cd /Users/jedumas/external/git/nativefiledialog-extended/build/src && /Applications/Xcode12.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc  -I/Users/jedumas/external/git/nativefiledialog-extended/src/include -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk -nostdlib -fno-exceptions -fno-rtti -MD -MT src/CMakeFiles/nfd.dir/nfd_cocoa.m.o -MF CMakeFiles/nfd.dir/nfd_cocoa.m.o.d -o CMakeFiles/nfd.dir/nfd_cocoa.m.o -c /Users/jedumas/external/git/nativefiledialog-extended/src/nfd_cocoa.m
In file included from /Users/jedumas/external/git/nativefiledialog-extended/src/nfd_cocoa.m:8:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/System/Library/Frameworks/AppKit.framework/Headers/AppKit.h:10:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:12:
/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSBundle.h:91:143: error: function does not return NSString
- (NSAttributedString *)localizedAttributedStringForKey:(NSString *)key value:(nullable NSString *)value table:(nullable NSString *)tableName NS_FORMAT_ARGUMENT(1) NS_REFINED_FOR_SWIFT API_AVAILABLE(macos...
                                                         ~~~~~~~~~~~~~~                                                                       ^                  ~
/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSObjCRuntime.h:103:48: note: expanded from macro 'NS_FORMAT_ARGUMENT'
        #define NS_FORMAT_ARGUMENT(A) __attribute__ ((format_arg(A)))
                                                      ^          ~
In file included from /Users/jedumas/external/git/nativefiledialog-extended/src/nfd_cocoa.m:8:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/System/Library/Frameworks/AppKit.framework/Headers/AppKit.h:10:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/Foundation.h:130:
/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSURLSession.h:500:168: error: expected ')'
- (void)readDataOfMinLength:(NSUInteger)minBytes maxLength:(NSUInteger)maxBytes timeout:(NSTimeInterval)timeout completionHandler:(void (^) (NSData * _Nullable_result data, BOOL atEOF, NSError * _Nullabl...
                                                                                                                                                                       ^
/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSURLSession.h:500:141: note: to match this '('
- (void)readDataOfMinLength:(NSUInteger)minBytes maxLength:(NSUInteger)maxBytes timeout:(NSTimeInterval)timeout completionHandler:(void (^) (NSData * _Nullable_result data, BOOL atEOF, NSError * _Nullabl...
                                                                                                                                            ^
/Users/jedumas/external/git/nativefiledialog-extended/src/nfd_cocoa.m:78:13: warning: 'setAllowedFileTypes:' is deprecated: first deprecated in macOS 12.0 - Use -allowedContentTypes instead
      [-Wdeprecated-declarations]
    [dialog setAllowedFileTypes:allowedFileTypes];
            ^
/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/System/Library/Frameworks/AppKit.framework/Headers/NSSavePanel.h:215:49: note: property 'allowedFileTypes' is declared deprecated here
@property (nullable, copy) NSArray<NSString *> *allowedFileTypes API_DEPRECATED("Use -allowedContentTypes instead", macos(10.3,12.0));
                                                ^
/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/System/Library/Frameworks/AppKit.framework/Headers/NSSavePanel.h:215:49: note: 'setAllowedFileTypes:' has been explicitly marked deprecated here
1 warning and 2 errors generated.
make[2]: *** [src/CMakeFiles/nfd.dir/nfd_cocoa.m.o] Error 1
make[1]: *** [src/CMakeFiles/nfd.dir/all] Error 2
make: *** [all] Error 2

To reproduce, specify the OSX_SYSROOT folder when calling CMake:

cmake -DCMAKE_OSX_SYSROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX12.3.sdk/ ..

Use GitHub Actions to let contributors open PRs for wiki pages

Something like https://github.com/Andrew-Chen-Wang/github-wiki-action or https://github.com/spenserblack/actions-wiki

name: Publish wiki
on:
  push:
    branches: [main]
    paths:
      - wiki/**
      - .github/workflows/publish-wiki.yml
concurrency:
  group: publish-wiki
  cancel-in-progress: true
permissions:
  contents: write
jobs:
  publish-wiki:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: Andrew-Chen-Wang/github-wiki-action@v4
If you really want to, you can also sync in reverse (wiki to repo)
name: Pull wiki
on:
  gollum:
  push:
    branches: main
    paths: .github/workflows/pull-wiki.yml
  schedule:
    - cron: "0 0 * * *"
  workflow_dispatch:
concurrency:
  group: ${{ github.workflow }}
  cancel-in-progress: true
jobs:
  pull-wiki:
    permissions:
      contents: write
      id-token: write
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - run: |
          export GIT_DIR=$(mktemp -d)
          trap 'rm -rf "$GIT_DIR"' SIGINT SIGTERM ERR EXIT
          export GIT_WORK_TREE=wiki
          git clone https://github.com/jcbhmr/.github.wiki.git "$GIT_DIR" --bare
          git config --unset core.bare
          git reset --hard
      - uses: EndBug/add-and-commit@v9
        with:
          message: '[skip actions] Pull wiki'

Confusing build instructions

I though the build instructions were a bit confusing,
seeing as all I needed to do to use it was to do add_subdirectory(path-to-nfde).
I could take a whack at restructuring the README a bit.
Is the idea that a user can choose between

  • adding a subdirectory with cmake
  • build a standalone library
    ?

[OSX] Dialog does not capture focus

  • OS: OSX 19.6.0

I have opened a similar issue in the original nfd repo, but I had no luck finding help there, but this fork looks a lot more maintained so I decided to ask here, so...

My file dialogs on MacOs do not catch the focus no matter how hard I try, which also means that the keyboard does not work and only some mouse inputs reach the dialog.

The described problem is present in nativefiledialog, nativefiledialog-extended, and in osdialog, but it does not occur when using osascript

GIF:

Top one is nfd dialog, bottom one is osascript dialog for comparasion
GIF

Workaround that I found that can potentially help to narrow down the problem:

  • Open some sort of window/prompt/dialog (I used NSAlert)
  • After the NSAlert is closed open NSOpenPanel (closing is not necessary)
  • Done, now file dialog will work as expected

Another Workaround that I found

  • I have to click on the very edge of dialog, and then it catches focus and works as expected:
    GIF

Universal Bindings

We are running into some issues while generating cross platform bindings for .NET. It mostly arises from the use of macros to define the utf8 functions on Mac and Linux. On Windows, both native and utf8 functions get exported, but on Mac and Linux, only native functions get exported.

I see two potential solutions:

  • On Mac and Linux, change the utf8 macros to function definitions, so that all 3 platforms have both sets of function exports.
  • On Mac and Linux, change utf8 to be the default and native to be the macro.

File dialogs do not block application UI

I am compiling and testing nfd-ext on Win 10/11 platforms. When a file dialog is shown, users can still interface with the background application, which is not expected. How can I fix it?

Arm64 Support

What would be involved in setting up continuous integration for Arm64 binaries?

Consider merging OpenDialog, OpenDialogMultiple, and PickFolder into a single API

On all four backends, these three APIs actually call a single platform native API. NFDe is essentially calling the same code, but setting a flag to determine whether to select files or folders, and whether to select single vs multiple items. Since all backends only actually use a single API with options, NFDe should probably do the same too. As a bonus, we will also support the ability to select multiple folders.

Note that on MacOS, the native API seems to be even more flexible - you can choose to allow the selection of both files and folders.

Or maybe it shouldn't be merged for single vs multiple due to the differing return type, but at least we can merge the files vs folders part.

Windows: shell32.lib necessary, but not documented in Readme?

When trying to get the demo (1.0 release) working using windows, msvc, bazel (using rules_foreign_cc as wrapper), i observed the following error:

ERROR: D:/code/cbs_gui/playground/BUILD:10:10: Linking playground/file_dialog.exe failed: (Exit 1120): link.exe failed: error executing command C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\HostX64\x64\link.exe @bazel-out/x64_windows-dbg/bin/playground/file_dialog.exe-2.params
nfd.lib(nfd_win.cpp.obj) : error LNK2019: unresolved external symbol __imp_SHCreateItemFromParsingName referenced in function "enum nfdresult_t __cdecl `anonymous namespace'::SetDefaultPath(struct IFileDialog *,wchar_t const *)" (?SetDefaultPath@?A0xc5579a01@@YA?AW4nfdresult_t@@PEAUIFileDialog@@PEB_W@Z)
bazel-out\x64_windows-dbg\bin\playground\file_dialog.exe : fatal error LNK1120: 1 unresolved externals

This was fixed by linking also against shell32.lib:

load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake")

cmake(
    name = "nativefiledialog",
    lib_source = "@nativefiledialog//:all_srcs",
    lib_name = 'nfd',
    visibility = ["//visibility:public"],
    linkopts = [
      "-DEFAULTLIB:ole32.lib",
      "-DEFAULTLIB:uuid.lib",
# FIX
      "-DEFAULTLIB:shell32.lib"
    ]
)

Maybe the Readme is missing to declare this dependency?

Update README for CMake support

I've never used premake and from what I can tell it lets me compile for whatever platform I like. However, my project would ideally have one source which compiles to many different platforms. I am using CMake for my build system.

How would I make a cross platform CMake file of this project?

Setting up Xcode search path for nfd.hpp

Hi there

I'm trying to add this library to my project in xcode, but I seem to be stuck on including the header files.

I've compile the static library, and linked to it. The examples are all working well too.

However, from the nfd.h header is included as <nfd.h> from nfd.hpp which suggests that it's a system wide header, right? I get this in nfd.hpp:

image

Have I missed a step in installing it in the right location?

Many thanks

Crash on Linux

When using this on Linux and calling OpenDialog the application instantly terminates

Gtk:ERROR:../../../../gtk/gtkpathbar.c:1754:gtk_path_bar_get_info_callback: assertion failed: (cancellable == file_info->path_bar->priv->get_info_cancellable)
Bail out! Gtk:ERROR:../../../../gtk/gtkpathbar.c:1754:gtk_path_bar_get_info_callback: assertion failed: (cancellable == file_info->path_bar->priv->get_info_cancellable)

when not using gtk but dbus instead there is simply a segmentation fault.

Add versioning/tags

Can you add versioning/tags so this can be included in OS repositories? I'm planning to package it for Fedora/EPEL as a dependency of something else.

All files wildcard filter description cannot be localized

I cannot find a way to change the default All files wildcard filter description to match my locale.

It looks like it was hard coded in all platform specific code. I can add my own wildcard filter and it functions properly, but it does not override the default:
sample

undefined reference to *gtk something*

Can't build the project. Getting undefined reference.

Tried to fix it by half haphazardly throwing the following cmake code I found online but it didn't work:
FIND_PACKAGE ( PkgConfig REQUIRED )
PKG_CHECK_MODULES( GTK REQUIRED gtk+-3.0 )
INCLUDE_DIRECTORIES ( ${GTK_INCLUDE_DIRS} )
include_directories(${GTK3_INCLUDE_DIRS})
link_directories(${GTK3_LIBRARY_DIRS})
add_definitions(${GTK3_CFLAGS_OTHER})
...
target_link_libraries(app PUBLIC ${GTK3_LIBRARIES})

libgtk-3-dev is installed an up to date.

[PR for wiki] Add overview comments & move bindings to readme

jcbhmr.patch

diff --git a/Bindings-in-other-languages.md b/Bindings-in-other-languages.md
deleted file mode 100644
index 6d6e579..0000000
--- a/Bindings-in-other-languages.md
+++ /dev/null
@@ -1,7 +0,0 @@
-This page lists known bindings in other programming languages.  Please report issues with these bindings on their respective repositories.
-
-| Language  | Repository  |
-| --- | --- |
-| Rust  | [nfde-rs](https://github.com/btzy/nfde-rs)  |
-| Java/Kotlin  | [Native File Dialog Java](https://github.com/WonderzGmbH/nativefiledialog-java)  |
-| Java  | [LWJGL - Lightweight Java Game Library 3](https://github.com/LWJGL/lwjgl3)  |
\ No newline at end of file
diff --git a/Home.md b/Home.md
index 280bfec..b146619 100644
--- a/Home.md
+++ b/Home.md
@@ -1,4 +1,23 @@
-Welcome to the nativefiledialog-extended wiki!
+Hello! ๐Ÿ‘‹ This is the Native File Dialog (Extended) wiki page. You might be
+looking for the [README page] of the main repository instead. Check out the
+sidebar for more wiki pages!
 
-- [[Bindings in other languages]]
-- [[Native File Dialog Extended in the wild]]
\ No newline at end of file
+**This project has a C interface.** This interface is `nfd.h`. This means that
+after compiling this project into a static or shared library, you can use it
+with anything that knows how to call C code. C is the lingua franca of desktop
+programming, so almost any general-purpose programming language (including C++,
+Rust, Python, and JavaScript (NodeJS)) will have a way of calling C interfaces.
+For interpreted and garbage-collected languages like Python and JavaScript, this
+usually involves writing some boilerplate code (or autogenerating them using
+some tools) to marshal objects across languages.
+
+**This project is implemented in C++ (for Windows and Linux) and Objective-C
+(for MacOS).** This means that to compile this project from source, you need to
+use a C++ or Objective-C compiler, depending that platform you are compiling
+for. (The nfd_cocoa.m file is the implementation for MacOS.) The required
+compilers are the standard compilers for each of the three operating systems,
+and can be downloaded easily for free from their official websites (or for
+Linux, it should come pre-installed). Once compiled into a static or shared
+library, however, its interface looks and behaves like a C library.
+
+[README]: https://github.com/btzy/nativefiledialog-extended#readme
diff --git a/Native-File-Dialog-Extended-in-the-wild.md b/Native-File-Dialog-Extended-in-the-wild.md
index d1c8d33..c13f892 100644
--- a/Native-File-Dialog-Extended-in-the-wild.md
+++ b/Native-File-Dialog-Extended-in-the-wild.md
@@ -1,19 +1,20 @@
-This page lists known popular projects that depend on NFDe, which might give an indication as to how battle-tested the backends are.
+This page lists known popular projects that depend on NFDe, which might give an
+indication as to how battle-tested the backends are.
 
-| Project  | Windows  | MacOS  | Linux (GTK)  | Linux (Portal)  | Frameworks  | Description  |
-| --- | :-: | :-: | :-: | :-: | --- | --- |
-| [Amalgam Engine](https://github.com/Net5F/AmalgamEngine)  | โœ”๏ธ | โœ”๏ธ | โœ”๏ธ | | SDL2  | Engine for creating virtual worlds  |
-| [dgb-n64](https://github.com/Dillonb/n64)  | โœ”๏ธ | | | โœ”๏ธ | ImGui  | Nintendo 64 low-level emulator  |
-| [glscopeclient](https://github.com/glscopeclient/scopehal-apps)  | โœ”๏ธ | โœ”๏ธ | โœ”๏ธ | | ImGui, GLFW  | Signal analysis tool for oscilloscopes and logic analyzers  |
-| [ImHex](https://github.com/WerWolv/ImHex)  | โœ”๏ธ | โœ”๏ธ | | โœ”๏ธ | ImGui, GLFW  | Featureful hex editor  |
-| [ImPlay](https://github.com/tsl0922/ImPlay)  | โœ”๏ธ | โœ”๏ธ | โœ”๏ธ | | ImGui, GLFW  | Desktop media player  |
-| [mahi-gui](https://github.com/mahilab/mahi-gui)  | โœ”๏ธ | โœ”๏ธ | โœ”๏ธ | | GLFW  | GUI framework  |
-| [Metaforce](https://github.com/AxioDL/metaforce)  | โœ”๏ธ | โœ”๏ธ | | โœ”๏ธ | ImGui, SDL2  | Native reimplementation of Metroid Prime  |
-| [Nodable](https://github.com/berdal84/Nodable)  | โœ”๏ธ | โœ”๏ธ | | โœ”๏ธ | ImGui  | Hybrid textual and nodal source code editor  |
-| [OpenJKDF2](https://github.com/shinyquagsire23/OpenJKDF2)  | โœ”๏ธ | โœ”๏ธ | โœ”๏ธ | | SDL2  | Open-source reimplementation of Dead Frontier 2  |
-| [OpenSiv3D](https://github.com/Siv3D/OpenSiv3D)  | | | โœ”๏ธ | | GLFW  | Creative coding framework  |
-| [Soundux](https://github.com/Soundux/Soundux)  | โœ”๏ธ | | โœ”๏ธ | | | Soundboard  |
-| [SPlisHSPlasH](https://github.com/InteractiveComputerGraphics/SPlisHSPlasH)  | โœ”๏ธ | | | โœ”๏ธ | ImGui, GLFW  | Fluid simulation library  |
-| [TinyUSDZ](https://github.com/syoyo/tinyusdz)  | โœ”๏ธ | โœ”๏ธ | โœ”๏ธ | | SDL2  | Universal Scene Description (USD) library  |
-| [Tracy Profiler](https://github.com/wolfpld/tracy)  | โœ”๏ธ | โœ”๏ธ | | โœ”๏ธ | ImGui, GLFW  | Code profiler  |
-| [Vita3K](https://github.com/Vita3K/Vita3K)  | โœ”๏ธ | โœ”๏ธ | | โœ”๏ธ | ImGui, SDL2  | PlayStation Vita emulator  |
+| Project                                                                     | Windows | MacOS | Linux (GTK) | Linux (Portal) | Frameworks  | Description                                                |
+| --------------------------------------------------------------------------- | :-----: | :---: | :---------: | :------------: | ----------- | ---------------------------------------------------------- |
+| [Amalgam Engine](https://github.com/Net5F/AmalgamEngine)                    |   โœ”๏ธ    |  โœ”๏ธ   |     โœ”๏ธ      |                | SDL2        | Engine for creating virtual worlds                         |
+| [dgb-n64](https://github.com/Dillonb/n64)                                   |   โœ”๏ธ    |       |             |       โœ”๏ธ       | ImGui       | Nintendo 64 low-level emulator                             |
+| [glscopeclient](https://github.com/glscopeclient/scopehal-apps)             |   โœ”๏ธ    |  โœ”๏ธ   |     โœ”๏ธ      |                | ImGui, GLFW | Signal analysis tool for oscilloscopes and logic analyzers |
+| [ImHex](https://github.com/WerWolv/ImHex)                                   |   โœ”๏ธ    |  โœ”๏ธ   |             |       โœ”๏ธ       | ImGui, GLFW | Featureful hex editor                                      |
+| [ImPlay](https://github.com/tsl0922/ImPlay)                                 |   โœ”๏ธ    |  โœ”๏ธ   |     โœ”๏ธ      |                | ImGui, GLFW | Desktop media player                                       |
+| [mahi-gui](https://github.com/mahilab/mahi-gui)                             |   โœ”๏ธ    |  โœ”๏ธ   |     โœ”๏ธ      |                | GLFW        | GUI framework                                              |
+| [Metaforce](https://github.com/AxioDL/metaforce)                            |   โœ”๏ธ    |  โœ”๏ธ   |             |       โœ”๏ธ       | ImGui, SDL2 | Native reimplementation of Metroid Prime                   |
+| [Nodable](https://github.com/berdal84/Nodable)                              |   โœ”๏ธ    |  โœ”๏ธ   |             |       โœ”๏ธ       | ImGui       | Hybrid textual and nodal source code editor                |
+| [OpenJKDF2](https://github.com/shinyquagsire23/OpenJKDF2)                   |   โœ”๏ธ    |  โœ”๏ธ   |     โœ”๏ธ      |                | SDL2        | Open-source reimplementation of Dead Frontier 2            |
+| [OpenSiv3D](https://github.com/Siv3D/OpenSiv3D)                             |         |       |     โœ”๏ธ      |                | GLFW        | Creative coding framework                                  |
+| [Soundux](https://github.com/Soundux/Soundux)                               |   โœ”๏ธ    |       |     โœ”๏ธ      |                |             | Soundboard                                                 |
+| [SPlisHSPlasH](https://github.com/InteractiveComputerGraphics/SPlisHSPlasH) |   โœ”๏ธ    |       |             |       โœ”๏ธ       | ImGui, GLFW | Fluid simulation library                                   |
+| [TinyUSDZ](https://github.com/syoyo/tinyusdz)                               |   โœ”๏ธ    |  โœ”๏ธ   |     โœ”๏ธ      |                | SDL2        | Universal Scene Description (USD) library                  |
+| [Tracy Profiler](https://github.com/wolfpld/tracy)                          |   โœ”๏ธ    |  โœ”๏ธ   |             |       โœ”๏ธ       | ImGui, GLFW | Code profiler                                              |
+| [Vita3K](https://github.com/Vita3K/Vita3K)                                  |   โœ”๏ธ    |  โœ”๏ธ   |             |       โœ”๏ธ       | ImGui, SDL2 | PlayStation Vita emulator                                  |

This PR would...

  • Remove the bindings for other languages page from the wiki
  • Add overview comments from #103 to the homepage
  • Use https://prettier.io/ (Markdown formatter) on all content (especially tables!)

Formatting with .clang-format

It would be nice to use clang-format to format the code base.

One issue brought up would be the raised barrier of entry to contribute.
I found an action that automatically checks(but doesn't format): https://github.com/marketplace/actions/clang-format-lint.
Could be useful for people without clang-format mayhaps?

Also, I vouch for trying 80 columns.
It's the most common width to use, and it's always possible to relax this limit in the future as it's all automatically formatted.
Imo it makes it easier to read from top to bottom :)

Doxygen

After #118 is merged, I want to convert the existing comments to Doxygen syntax. That will enable other parsers (such as CppSharp) to pick up the documentation and use it in their own code generation. Is that ok with you?

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.