You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
7
7
@@ -298,6 +298,32 @@ Macros that might be defined by `nfd.h`:
298
298
299
299
NFDe is known to work with SDL2 and GLFW, and should also work with other platform abstraction framworks. This section explains how to use NFDe properly with such frameworks.
300
300
301
+
### Initialization order
302
+
303
+
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.
304
+
305
+
An example with SDL2:
306
+
307
+
```
308
+
// Initialize SDL2 first
309
+
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) != 0) {
310
+
// display some error here
311
+
}
312
+
313
+
// Then initialize NFDe
314
+
if (NFD_Init() != NFD_OKAY) {
315
+
// display some error here
316
+
}
317
+
318
+
/*
319
+
Your main program goes here
320
+
*/
321
+
322
+
NFD_Quit(); // deinitialize NFDe first
323
+
324
+
SDL_Quit(); // Then deinitialize SDL2
325
+
```
326
+
301
327
### Parent window handle
302
328
303
329
The `parentWindow` argument allows the user to give the dialog a parent.
@@ -308,7 +334,7 @@ Win32 (Windows), Cocoa (macOS), X11 (Linux), and Wayland (Linux) windows are sup
308
334
309
335
If using SDL2, include `<nfd_sdl2.h>` and do the following:
310
336
311
-
Call the following function once, after you create your first SDL2 window (usually with `SDL_CreateWindow()`) but before opening any file dialogs, to tell NFDe the `wl_display` your application is using (this is a no-op if your application isn't using Wayland):
337
+
Call the following function once, after you create your first SDL2 window (usually with `SDL_CreateWindow()`) but before opening any file dialogs, to tell NFDe the `wl_display` your application is using (this function does nothing if your application isn't using Wayland):
@@ -322,16 +348,27 @@ See `test_sdl.c` for an example.
322
348
323
349
#### GLFW3
324
350
325
-
If using GLFW3, define the appropriate `GLFW_EXPOSE_NATIVE_*` macros described on the [GLFW native access page](https://www.glfw.org/docs/latest/group__native.html), and then include `<nfd_glfw3.h>` and call the following function to set the parent window handle:
351
+
If using GLFW3, define the appropriate `GLFW_EXPOSE_NATIVE_*` macros as described on the [GLFW native access page](https://www.glfw.org/docs/latest/group__native.html), and then include `<nfd_glfw3.h>` and do the following:
352
+
353
+
Call the following function once, after `glfwInit()` and `NFD_Init()` but before opening any file dialogs, to tell NFDe the `wl_display` your application is using (this function does nothing if your application isn't using Wayland):
354
+
```C
355
+
NFD_SetDisplayPropertiesFromGLFW();
356
+
```
357
+
358
+
Each time you want to show a dialog, call the following function to retrieve the parent window handle and set the corresponding argument:
*Note: GLFW version < 3.4 does not support dynamically selecting a display server at runtime, meaning that it will support either X11 or Wayland, but not both. Make sure the `GLFW_EXPOSE_NATIVE_*` macros you define are indeed available on your GLFW library.*
366
+
330
367
#### Others
331
368
332
-
If you are using another platform abstraction framework, or not using any such framework, you can do the following:
369
+
If using another platform abstraction framework or not using any such framework, do the following:
333
370
334
-
If you are using Wayland, call the following function once, after connecting to the Wayland compositor (thereby obtaining a `wl_display*`) but before opening any file dialogs:
371
+
Figure out if you are using Wayland in your application code, and if so, call the following function to tell NFDe the `wl_display` you are using:
335
372
```C
336
373
NFD_SetWaylandDisplay(display /* wl_display* */);
337
374
```
@@ -344,41 +381,15 @@ To make a window (in this case the file dialog) stay above another window, we ne
344
381
345
382
#### Why is Wayland special?
346
383
347
-
Linux has two differences when compared with Windows and macOS: Linux applications open a connection with a display server (X11 or Wayland) to show their windows, and windows are owned by this connection. It is possible to open multiple connections at the same time (including multiple connections to the same display server), and windows are not shared between those connections. GTK needs to use a connection opened by itself, and so it opens a new connection if it hasn't previously opened a connection (which will be the case if your application doesn't create its own GTK windows). Using portals essentially causes the file dialog to be shown by a separate helper process, which also opens its own connection. In either case, the window handle needs to be passed to a different connection. On X11, window handles are global identifiers that can be used as-is by another connection, but on Wayland, the handles need to be _exported_ to a string and then _imported_ by the receiving connection, and performing the export operation requires the owner's Wayland display handle.
348
-
349
-
### Initialization order
350
-
351
-
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.
352
-
353
-
An example with SDL2:
354
-
355
-
```
356
-
// Initialize SDL2 first
357
-
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) != 0) {
358
-
// display some error here
359
-
}
360
-
361
-
// Then initialize NFDe
362
-
if (NFD_Init() != NFD_OKAY) {
363
-
// display some error here
364
-
}
365
-
366
-
/*
367
-
Your main program goes here
368
-
*/
369
-
370
-
NFD_Quit(); // deinitialize NFDe first
371
-
372
-
SDL_Quit(); // Then deinitialize SDL2
373
-
```
384
+
Linux has two differences when compared with Windows and macOS: (1) Linux applications open a connection with a display server (X11 or Wayland) to show their windows, and (2) windows are owned by this connection. It is possible to open multiple connections at the same time (including multiple connections to the same display server), and windows are not shared between those connections. GTK needs to use a connection opened by itself, and so it opens a new connection if it hasn't previously opened a connection (which will be the case if your application doesn't use GTK on its own). Portals work by opening the file dialog in a separate helper process, which also opens its own connection. In either case, the window handle needs to be passed to a different connection. On X11, window handles are global identifiers that can be used as-is by another connection, but on Wayland, the handles need to be _exported_ to a string and then _imported_ by the receiving connection, and performing the export operation requires the owner's Wayland display handle.
374
385
375
386
## Using xdg-desktop-portal on Linux
376
387
377
388
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.
378
389
379
390
To use the portal implementation, add `-DNFD_PORTAL=ON` to the build command.
380
391
381
-
*Note: 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.
392
+
*Note: 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.*
0 commit comments