Skip to content

Commit ce1a059

Browse files
committed
Linux/Wayland: Support parent windows
1 parent a1a4010 commit ce1a059

File tree

9 files changed

+276
-25
lines changed

9 files changed

+276
-25
lines changed

.github/workflows/cmake.yml

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,15 @@ jobs:
3737

3838
build-ubuntu:
3939

40-
name: Ubuntu ${{ matrix.os.name }} - ${{ matrix.compiler.name }}, ${{ matrix.portal.name }}, ${{ matrix.autoappend.name }}, ${{ matrix.casesensitive.name }}, ${{ matrix.shared_lib.name }}, C++${{ matrix.cppstd }}
40+
name: Ubuntu ${{ matrix.os.name }} - ${{ matrix.compiler.name }}, ${{ matrix.portal.name }}, ${{ matrix.wayland.name }}, ${{ matrix.autoappend.name }}, ${{ matrix.casesensitive.name }}, ${{ matrix.shared_lib.name }}, C++${{ matrix.cppstd }}
4141
runs-on: ${{ matrix.os.label }}
4242

4343
strategy:
4444
matrix:
4545
os: [ {label: ubuntu-latest, name: latest}, {label: ubuntu-22.04, name: 22.04} ]
4646
portal: [ {flag: OFF, dep: libgtk-3-dev, name: GTK}, {flag: ON, dep: libdbus-1-dev, name: Portal} ] # The NFD_PORTAL setting defaults to OFF (i.e. uses GTK)
4747
autoappend: [ {flag: OFF, name: NoAppendExtn} ] # By default the NFD_PORTAL mode does not append extensions, because it breaks some features of the portal
48+
wayland: [ {flag: OFF, dep: , name: NoWayland} ]
4849
casesensitive: [ {flag: OFF, name: CaseInsensitive} ] # Case insensitive or case sensitive file filtering
4950
compiler: [ {c: gcc, cpp: g++, name: GCC}, {c: clang, cpp: clang++, name: Clang} ] # The default compiler is gcc/g++
5051
cppstd: [20, 11]
@@ -53,34 +54,47 @@ jobs:
5354
- os: {label: ubuntu-latest, name: latest}
5455
portal: {flag: ON, dep: libdbus-1-dev, name: Portal}
5556
autoappend: {flag: ON, name: AutoAppendExtn}
57+
wayland: {flag: OFF, dep: , name: NoWayland}
5658
casesensitive: {flag: OFF, name: CaseInsensitive}
5759
compiler: {c: gcc, cpp: g++, name: GCC}
5860
cppstd: 11
5961
shared_lib: {flag: OFF, name: Static}
6062
- os: {label: ubuntu-latest, name: latest}
6163
portal: {flag: ON, dep: libdbus-1-dev, name: Portal}
6264
autoappend: {flag: ON, name: AutoAppendExtn}
65+
wayland: {flag: OFF, dep: , name: NoWayland}
6366
casesensitive: {flag: OFF, name: CaseInsensitive}
6467
compiler: {c: clang, cpp: clang++, name: Clang}
6568
cppstd: 11
6669
shared_lib: {flag: OFF, name: Static}
6770
- os: {label: ubuntu-latest, name: latest}
6871
portal: {flag: ON, dep: libdbus-1-dev, name: Portal}
6972
autoappend: {flag: OFF, name: NoAppendExtn}
73+
wayland: {flag: OFF, dep: , name: NoWayland}
7074
casesensitive: {flag: OFF, name: CaseInsensitive}
7175
compiler: {c: gcc, cpp: g++, name: GCC}
7276
cppstd: 11
7377
shared_lib: {flag: ON, name: Shared}
78+
- os: {label: ubuntu-latest, name: latest}
79+
portal: {flag: ON, dep: libdbus-1-dev, name: Portal}
80+
autoappend: {flag: OFF, name: NoAppendExtn}
81+
wayland: {flag: ON, dep: libwayland-dev libwayland-bin, name: Wayland}
82+
casesensitive: {flag: OFF, name: CaseInsensitive}
83+
compiler: {c: gcc, cpp: g++, name: GCC}
84+
cppstd: 11
85+
shared_lib: {flag: ON, name: Static}
7486
- os: {label: ubuntu-latest, name: latest}
7587
portal: {flag: OFF, dep: libgtk-3-dev, name: GTK}
7688
autoappend: {flag: OFF, name: NoAppendExtn}
89+
wayland: {flag: OFF, dep: , name: NoWayland}
7790
casesensitive: {flag: ON, name: CaseSensitive}
7891
compiler: {c: gcc, cpp: g++, name: GCC}
7992
cppstd: 11
8093
shared_lib: {flag: OFF, name: Static}
8194
- os: {label: ubuntu-latest, name: latest}
8295
portal: {flag: ON, dep: libdbus-1-dev, name: Portal}
8396
autoappend: {flag: OFF, name: NoAppendExtn}
97+
wayland: {flag: OFF, dep: , name: NoWayland}
8498
casesensitive: {flag: ON, name: CaseSensitive}
8599
compiler: {c: gcc, cpp: g++, name: GCC}
86100
cppstd: 11
@@ -89,16 +103,18 @@ jobs:
89103
steps:
90104
- name: Checkout
91105
uses: actions/checkout@v4
106+
with:
107+
submodules: true
92108
- name: Install Dependencies
93-
run: sudo apt-get update && sudo apt-get install ${{ matrix.portal.dep }}
109+
run: sudo apt-get update && sudo apt-get install ${{ matrix.portal.dep }} ${{ matrix.wayland.dep }}
94110
- name: Configure
95-
run: mkdir build && mkdir install && cd build && cmake -DCMAKE_INSTALL_PREFIX="../install" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=${{ matrix.compiler.c }} -DCMAKE_CXX_COMPILER=${{ matrix.compiler.cpp }} -DCMAKE_CXX_STANDARD=${{ matrix.cppstd }} -DCMAKE_C_FLAGS="-Wall -Wextra -Wshadow -Werror -pedantic" -DCMAKE_CXX_FLAGS="-Wall -Wextra -Wshadow -Werror -pedantic" -DNFD_PORTAL=${{ matrix.portal.flag }} -DNFD_APPEND_EXTENSION=${{ matrix.autoappend.flag }} -DNFD_CASE_SENSITIVE_FILTER=${{ matrix.casesensitive.flag }} -DBUILD_SHARED_LIBS=${{ matrix.shared_lib.flag }} -DNFD_BUILD_TESTS=ON ..
111+
run: mkdir build && mkdir install && cd build && cmake -DCMAKE_INSTALL_PREFIX="../install" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=${{ matrix.compiler.c }} -DCMAKE_CXX_COMPILER=${{ matrix.compiler.cpp }} -DCMAKE_CXX_STANDARD=${{ matrix.cppstd }} -DCMAKE_C_FLAGS="-Wall -Wextra -Wshadow -Werror -pedantic" -DCMAKE_CXX_FLAGS="-Wall -Wextra -Wshadow -Werror -pedantic" -DNFD_PORTAL=${{ matrix.portal.flag }} -DNFD_WAYLAND=${{ matrix.wayland.flag }} -DNFD_APPEND_EXTENSION=${{ matrix.autoappend.flag }} -DNFD_CASE_SENSITIVE_FILTER=${{ matrix.casesensitive.flag }} -DBUILD_SHARED_LIBS=${{ matrix.shared_lib.flag }} -DNFD_BUILD_TESTS=ON ..
96112
- name: Build
97113
run: cmake --build build --target install
98114
- name: Upload test binaries
99115
uses: actions/upload-artifact@v4
100116
with:
101-
name: Ubuntu ${{ matrix.os.name }} - ${{ matrix.compiler.name }}, ${{ matrix.portal.name }}, ${{ matrix.autoappend.name }}, ${{ matrix.casesensitive.name }}, ${{ matrix.shared_lib.name }}, C++${{ matrix.cppstd }}
117+
name: Ubuntu ${{ matrix.os.name }} - ${{ matrix.compiler.name }}, ${{ matrix.portal.name }}, ${{ matrix.wayland.name }}, ${{ matrix.autoappend.name }}, ${{ matrix.casesensitive.name }}, ${{ matrix.shared_lib.name }}, C++${{ matrix.cppstd }}
102118
path: |
103119
build/src/*
104120
build/test/*
@@ -208,26 +224,29 @@ jobs:
208224
209225
build-ubuntu-sdl2:
210226

211-
name: Ubuntu latest - GCC, ${{ matrix.portal.name }}, Static, SDL2
227+
name: Ubuntu latest - GCC, ${{ matrix.portal.name }}, ${{ matrix.wayland.name }}, Static, SDL2
212228
runs-on: ubuntu-latest
213229

214230
strategy:
215231
matrix:
216232
portal: [ {flag: OFF, dep: libgtk-3-dev, name: GTK}, {flag: ON, dep: libdbus-1-dev, name: Portal} ] # The NFD_PORTAL setting defaults to OFF (i.e. uses GTK)
233+
wayland: [ {flag: OFF, dep: , name: NoWayland}, {flag: ON, dep: libwayland-dev libwayland-bin, name: Wayland} ]
217234

218235
steps:
219236
- name: Checkout
220237
uses: actions/checkout@v4
238+
with:
239+
submodules: true
221240
- name: Install Dependencies
222-
run: sudo apt-get update && sudo apt-get install ${{ matrix.portal.dep }} libsdl2-dev libsdl2-ttf-dev
241+
run: sudo apt-get update && sudo apt-get install ${{ matrix.portal.dep }} ${{ matrix.wayland.dep }} libsdl2-dev libsdl2-ttf-dev
223242
- name: Configure
224-
run: mkdir build && mkdir install && cd build && cmake -DCMAKE_INSTALL_PREFIX="../install" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Wall -Wextra -Wshadow -Werror -pedantic" -DCMAKE_CXX_FLAGS="-Wall -Wextra -Wshadow -Werror -pedantic" -DNFD_PORTAL=${{ matrix.portal.flag }} -DNFD_APPEND_EXTENSION=OFF -DNFD_BUILD_TESTS=OFF -DNFD_BUILD_SDL2_TESTS=ON ..
243+
run: mkdir build && mkdir install && cd build && cmake -DCMAKE_INSTALL_PREFIX="../install" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-Wall -Wextra -Wshadow -Werror -pedantic" -DCMAKE_CXX_FLAGS="-Wall -Wextra -Wshadow -Werror -pedantic" -DNFD_PORTAL=${{ matrix.portal.flag }} -DNFD_WAYLAND=${{ matrix.wayland.flag }} -DNFD_APPEND_EXTENSION=OFF -DNFD_BUILD_TESTS=OFF -DNFD_BUILD_SDL2_TESTS=ON ..
225244
- name: Build
226245
run: cmake --build build --target install
227246
- name: Upload test binaries
228247
uses: actions/upload-artifact@v4
229248
with:
230-
name: Ubuntu latest - GCC, ${{ matrix.portal.name }}, Static, SDL2
249+
name: Ubuntu latest - GCC, ${{ matrix.portal.name }}, ${{ matrix.wayland.name }}, Static, SDL2
231250
path: |
232251
build/src/*
233252
build/test/*

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "3ps/wayland-protocols"]
2+
path = 3ps/wayland-protocols
3+
url = https://gitlab.freedesktop.org/wayland/wayland-protocols.git

3ps/wayland-protocols

Submodule wayland-protocols added at 122a47a

src/CMakeLists.txt

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,33 @@ if(nfd_PLATFORM STREQUAL PLATFORM_LINUX)
1818
option(NFD_PORTAL "Use xdg-desktop-portal instead of GTK" OFF)
1919
if(NOT NFD_PORTAL)
2020
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
21-
message("Using GTK version: ${GTK3_VERSION}")
21+
message(STATUS "Using GTK version: ${GTK3_VERSION}")
2222
list(APPEND SOURCE_FILES nfd_gtk.cpp)
2323
else()
2424
pkg_check_modules(DBUS REQUIRED dbus-1)
25-
message("Using DBUS version: ${DBUS_VERSION}")
25+
message(STATUS "Using D-Bus version: ${DBUS_VERSION}")
2626
list(APPEND SOURCE_FILES nfd_portal.cpp)
2727
endif()
28+
29+
# for Linux, we support X11, Wayland, or both
30+
option(NFD_X11 "Support X11 on Linux" ON)
31+
option(NFD_WAYLAND "Support Wayland on Linux" ON)
32+
if(NFD_WAYLAND)
33+
pkg_check_modules(WAYLAND REQUIRED wayland-client)
34+
message(STATUS "Using Wayland version: ${WAYLAND_VERSION}")
35+
set(NFD_WAYLAND_PROTOCOL_XDG_FOREIGN ${CMAKE_CURRENT_SOURCE_DIR}/../3ps/wayland-protocols/unstable/xdg-foreign/xdg-foreign-unstable-v1.xml)
36+
add_custom_command(
37+
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xdg-foreign-unstable-v1.h
38+
COMMAND wayland-scanner client-header < ${NFD_WAYLAND_PROTOCOL_XDG_FOREIGN} > ${CMAKE_CURRENT_BINARY_DIR}/xdg-foreign-unstable-v1.h
39+
MAIN_DEPENDENCY ${NFD_WAYLAND_PROTOCOL_XDG_FOREIGN}
40+
)
41+
add_custom_command(
42+
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xdg-foreign-unstable-v1.c
43+
COMMAND wayland-scanner private-code < ${NFD_WAYLAND_PROTOCOL_XDG_FOREIGN} > ${CMAKE_CURRENT_BINARY_DIR}/xdg-foreign-unstable-v1.c
44+
MAIN_DEPENDENCY ${NFD_WAYLAND_PROTOCOL_XDG_FOREIGN}
45+
)
46+
list(APPEND SOURCE_FILES ${CMAKE_CURRENT_BINARY_DIR}/xdg-foreign-unstable-v1.h ${CMAKE_CURRENT_BINARY_DIR}/xdg-foreign-unstable-v1.c)
47+
endif()
2848
endif()
2949

3050
if(nfd_PLATFORM STREQUAL PLATFORM_MACOS)
@@ -94,10 +114,21 @@ if(nfd_PLATFORM STREQUAL PLATFORM_LINUX)
94114
if(NFD_APPEND_EXTENSION)
95115
target_compile_definitions(${TARGET_NAME} PRIVATE NFD_APPEND_EXTENSION)
96116
endif()
117+
97118
option(NFD_CASE_SENSITIVE_FILTER "Make filters case sensitive" OFF)
98119
if(NFD_CASE_SENSITIVE_FILTER)
99120
target_compile_definitions(${TARGET_NAME} PRIVATE NFD_CASE_SENSITIVE_FILTER)
100121
endif()
122+
123+
if(NFD_X11)
124+
target_compile_definitions(${TARGET_NAME} PRIVATE NFD_X11)
125+
endif()
126+
if(NFD_WAYLAND)
127+
target_include_directories(${TARGET_NAME} PRIVATE ${WAYLAND_INCLUDE_DIRS})
128+
target_link_libraries(${TARGET_NAME} PRIVATE ${WAYLAND_LINK_LIBRARIES})
129+
target_compile_definitions(${TARGET_NAME} PRIVATE NFD_WAYLAND)
130+
target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
131+
endif()
101132
endif()
102133

103134
if(nfd_PLATFORM STREQUAL PLATFORM_MACOS)
@@ -122,7 +153,7 @@ if(nfd_COMPILER STREQUAL COMPILER_CLANGCL)
122153
endif()
123154

124155
if(nfd_COMPILER STREQUAL COMPILER_GNU)
125-
target_compile_options(${TARGET_NAME} PRIVATE -nostdlib -fno-exceptions -fno-rtti)
156+
target_compile_options(${TARGET_NAME} PRIVATE -nostdlib -fno-exceptions $<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>)
126157
endif()
127158

128159
set_target_properties(${TARGET_NAME} PROPERTIES

src/include/nfd.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ enum {
105105
NFD_WINDOW_HANDLE_TYPE_COCOA = 2,
106106
// X11: handle is Window
107107
NFD_WINDOW_HANDLE_TYPE_X11 = 3,
108-
// Wayland support will be implemented separately in the future
108+
// Wayland: handle is wl_surface*
109+
NFD_WINDOW_HANDLE_TYPE_WAYLAND = 4,
109110
};
110111
// The native window handle. If using a platform abstraction framework (e.g. SDL2), this should be
111112
// obtained using the corresponding NFD glue header (e.g. nfd_sdl2.h).
@@ -190,6 +191,11 @@ NFD_API nfdresult_t NFD_Init(void);
190191
/** Call this to de-initialize NFD, if NFD_Init returned NFD_OKAY. */
191192
NFD_API void NFD_Quit(void);
192193

194+
struct wl_display;
195+
/** Sets or updates the Wayland display used by your application. Use NULL to remove an existing
196+
* display. Only defined on Linux. */
197+
NFD_API nfdresult_t NFD_SetWaylandDisplay(struct wl_display*);
198+
193199
/** Single file open dialog
194200
*
195201
* It's the caller's responsibility to free `outPath` via NFD_FreePathN() if this function returns

src/include/nfd_sdl2.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@ extern "C" {
2626
#define NFD_INLINE static inline
2727
#endif // __cplusplus
2828

29+
NFD_INLINE bool NFD_SetDisplayPropertiesFromSDLWindow(SDL_Window* sdlWindow) {
30+
#if defined(SDL_VIDEO_DRIVER_WAYLAND)
31+
SDL_SysWMinfo info;
32+
SDL_VERSION(&info.version);
33+
if (!SDL_GetWindowWMInfo(sdlWindow, &info) || info.subsystem != SDL_SYSWM_WAYLAND) {
34+
return false;
35+
}
36+
return NFD_SetWaylandDisplay(info.info.wl.display) == NFD_OKAY;
37+
#else
38+
(void)sdlWindow;
39+
return true;
40+
#endif
41+
}
42+
2943
/**
3044
* Converts an SDL window handle to a native window handle that can be passed to NFDe.
3145
* @param sdlWindow The SDL window handle.
@@ -59,6 +73,12 @@ NFD_INLINE bool NFD_GetNativeWindowFromSDLWindow(SDL_Window* sdlWindow,
5973
nativeWindow->type = NFD_WINDOW_HANDLE_TYPE_X11;
6074
nativeWindow->handle = (void*)info.info.x11.window;
6175
return true;
76+
#endif
77+
#if defined(SDL_VIDEO_DRIVER_WAYLAND)
78+
case SDL_SYSWM_WAYLAND:
79+
nativeWindow->type = NFD_WINDOW_HANDLE_TYPE_WAYLAND;
80+
nativeWindow->handle = (void*)info.info.wl.surface;
81+
return true;
6282
#endif
6383
default:
6484
// Silence the warning in case we are not using a supported backend.

src/nfd_gtk.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,12 @@ nfdresult_t NFD_Init(void) {
549549
}
550550
return NFD_OKAY;
551551
}
552+
553+
nfdresult_t NFD_SetWaylandDisplay(wl_display*) {
554+
// TODO do something with the display
555+
return NFD_OKAY;
556+
}
557+
552558
void NFD_Quit(void) {
553559
// do nothing, GTK cannot be de-initialized
554560
}

0 commit comments

Comments
 (0)