Skip to content

Commit c3590fd

Browse files
author
Rye
authored
Merge pull request #2918 from RyeMutt/rye/nfde
Introduce NativeFileDialog-Extended filepickers for Linux
2 parents 6aa18dc + 058711f commit c3590fd

File tree

17 files changed

+690
-551
lines changed

17 files changed

+690
-551
lines changed

.github/workflows/build.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ jobs:
137137
libgl1-mesa-dev libglu1-mesa-dev libxinerama-dev \
138138
libxcursor-dev libxfixes-dev libgstreamer1.0-dev \
139139
libgstreamer-plugins-base1.0-dev ninja-build libxft-dev \
140-
llvm mold libpipewire-0.3-dev
140+
llvm mold libpipewire-0.3-dev libdbus-1-dev
141141
142142
- name: Install windows dependencies
143143
if: runner.os == 'Windows'

autobuild.xml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,6 +1914,68 @@
19141914
<key>description</key>
19151915
<string>NanoSVG is a simple single-header-file SVG parser and rasterizer</string>
19161916
</map>
1917+
<key>nfde</key>
1918+
<map>
1919+
<key>platforms</key>
1920+
<map>
1921+
<key>linux64</key>
1922+
<map>
1923+
<key>archive</key>
1924+
<map>
1925+
<key>hash</key>
1926+
<string>4d23e53790c8e82c737a3f5df8cddc40b864257d</string>
1927+
<key>hash_algorithm</key>
1928+
<string>sha1</string>
1929+
<key>url</key>
1930+
<string>https://github.com/secondlife/3p-nfde/releases/download/v1.2.1-r1/nfde-1.2.1-r1-linux64-11465721541.tar.zst</string>
1931+
</map>
1932+
<key>name</key>
1933+
<string>linux64</string>
1934+
</map>
1935+
<key>darwin64</key>
1936+
<map>
1937+
<key>archive</key>
1938+
<map>
1939+
<key>hash</key>
1940+
<string>9ec692bdc93c4f2aa1f2951b71ee4a5737e43bc9</string>
1941+
<key>hash_algorithm</key>
1942+
<string>sha1</string>
1943+
<key>url</key>
1944+
<string>https://github.com/secondlife/3p-nfde/releases/download/v1.2.1-r1/nfde-1.2.1-r1-darwin64-11465721541.tar.zst</string>
1945+
</map>
1946+
<key>name</key>
1947+
<string>darwin64</string>
1948+
</map>
1949+
<key>windows64</key>
1950+
<map>
1951+
<key>archive</key>
1952+
<map>
1953+
<key>hash</key>
1954+
<string>65c88f9e849a4a460f0b051f884f9df0608dd389</string>
1955+
<key>hash_algorithm</key>
1956+
<string>sha1</string>
1957+
<key>url</key>
1958+
<string>https://github.com/secondlife/3p-nfde/releases/download/v1.2.1-r1/nfde-1.2.1-r1-windows64-11465721541.tar.zst</string>
1959+
</map>
1960+
<key>name</key>
1961+
<string>windows64</string>
1962+
</map>
1963+
</map>
1964+
<key>license</key>
1965+
<string>zlib</string>
1966+
<key>license_file</key>
1967+
<string>LICENSES/nfde.txt</string>
1968+
<key>copyright</key>
1969+
<string>Copyright (C) The nativefiledialog-extended authors</string>
1970+
<key>version</key>
1971+
<string>1.2.1-r1</string>
1972+
<key>name</key>
1973+
<string>nfde</string>
1974+
<key>canonical_repo</key>
1975+
<string>https://github.com/secondlife/3p-nfde</string>
1976+
<key>description</key>
1977+
<string>Cross platform (Windows, Mac, Linux) native file dialog library with C and C++ bindings, based on mlabbe/nativefiledialog.</string>
1978+
</map>
19171979
<key>nghttp2</key>
19181980
<map>
19191981
<key>platforms</key>

indra/cmake/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ set(cmake_SOURCE_FILES
4343
Lualibs.cmake
4444
Meshoptimizer.cmake
4545
NDOF.cmake
46+
NFDE.cmake
4647
OPENAL.cmake
4748
OpenGL.cmake
4849
OpenJPEG.cmake

indra/cmake/LLWindow.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ include_guard()
99

1010
if (LINUX)
1111
# linux uses SDL2 for window and keyboard
12-
target_compile_definitions( ll::SDL2 INTERFACE LL_USE_SDL_KEYBOARD=1 )
12+
target_compile_definitions( ll::SDL2 INTERFACE LL_USE_SDL_WINDOW=1 LL_USE_SDL_KEYBOARD=1 )
1313
endif (LINUX)

indra/cmake/NFDE.cmake

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# -*- cmake -*-
2+
if(LINUX)
3+
set(USE_NFDE ON CACHE BOOL "Use Native File Dialog wrapper library")
4+
set(USE_NFDE_PORTAL ON CACHE BOOL "Use NFDE XDG Portals")
5+
endif()
6+
7+
include_guard()
8+
9+
add_library(ll::nfde INTERFACE IMPORTED)
10+
if(USE_NFDE)
11+
include(Prebuilt)
12+
use_prebuilt_binary(nfde)
13+
14+
target_compile_definitions( ll::nfde INTERFACE LL_NFD=1)
15+
16+
if (WINDOWS)
17+
target_link_libraries( ll::nfde INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/nfd.lib)
18+
elseif (DARWIN)
19+
target_link_libraries( ll::nfde INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libnfd.a)
20+
elseif (LINUX)
21+
if(USE_NFDE_PORTAL)
22+
target_link_libraries( ll::nfde INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libnfd_portal.a)
23+
else()
24+
target_link_libraries( ll::nfde INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libnfd_gtk.a)
25+
endif()
26+
endif ()
27+
28+
if (LINUX)
29+
find_package(PkgConfig REQUIRED)
30+
if(NOT USE_NFDE_PORTAL)
31+
pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
32+
target_link_libraries(ll::nfde INTERFACE ${GTK3_LINK_LIBRARIES})
33+
else()
34+
pkg_check_modules(DBUS REQUIRED dbus-1)
35+
target_link_libraries(ll::nfde INTERFACE ${DBUS_LINK_LIBRARIES})
36+
endif()
37+
endif()
38+
39+
target_include_directories( ll::nfde SYSTEM INTERFACE
40+
${LIBS_PREBUILT_DIR}/include/nfde
41+
)
42+
endif()

indra/cmake/SDL2.cmake

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@ use_prebuilt_binary( SDL2 )
1212

1313
find_library( SDL2_LIBRARY
1414
NAMES SDL2
15-
PATHS "${LIBS_PREBUILT_DIR}/lib/release")
16-
if ( "${SDL2_LIBRARY}" STREQUAL "SDL2_LIBRARY-NOTFOUND" )
17-
message( FATAL_ERROR "unable to find SDL2_LIBRARY" )
18-
endif()
15+
PATHS "${LIBS_PREBUILT_DIR}/lib/release" REQUIRED)
1916

2017
target_link_libraries( ll::SDL2 INTERFACE "${SDL2_LIBRARY}" )
21-
target_include_directories( ll::SDL2 SYSTEM INTERFACE "${LIBS_PREBUILT_DIR}/include" )
18+
target_include_directories( ll::SDL2 SYSTEM INTERFACE "${LIBS_PREBUILT_DIR}/include/SDL2" )
2219

indra/integration_tests/llimage_libtest/CMakeLists.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,6 @@ target_link_libraries(llimage_libtest
3333
llfilesystem
3434
llmath
3535
llimage
36-
llkdu
37-
llimagej2coj
3836
)
3937

4038
# Ensure people working on the viewer don't break this library

indra/llwindow/llsdl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ void init_sdl()
5656
std::initializer_list<std::tuple< char const*, char const * > > hintList =
5757
{
5858
{SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR,"0"},
59-
{SDL_HINT_VIDEODRIVER,"wayland,x11"},
6059
{SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH,"1"},
6160
{SDL_HINT_IME_INTERNAL_EDITING,"1"}
6261
};

indra/llwindow/llwindowsdl.cpp

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -114,18 +114,6 @@ Display* LLWindowSDL::get_SDL_Display(void)
114114
#include <wayland-client-protocol.h>
115115
#include <dlfcn.h>
116116

117-
bool LLWindowSDL::isWaylandWindowNotDrawing() const
118-
{
119-
if( Wayland != mServerProtocol || mWaylandData.mLastFrameEvent == 0 )
120-
return false;
121-
122-
auto currentTime = LLTimer::getTotalTime();
123-
if( (currentTime - mWaylandData.mLastFrameEvent) > 250000 )
124-
return true;
125-
126-
return false;
127-
}
128-
129117
uint32_t (*ll_wl_proxy_get_version)(struct wl_proxy *proxy);
130118
void (*ll_wl_proxy_destroy)(struct wl_proxy *proxy);
131119
int (*ll_wl_proxy_add_listener)(struct wl_proxy *proxy, void (**implementation)(void), void *data);
@@ -210,8 +198,22 @@ void LLWindowSDL::waylandFrameDoneCB(void *data, struct wl_callback *cb, uint32_
210198
pThis->setupWaylandFrameCallback(); // ask for a new frame
211199
}
212200

201+
bool LLWindowSDL::isWaylandWindowNotDrawing() const
202+
{
203+
if(!mWaylandLoaded || Wayland != mServerProtocol || mWaylandData.mLastFrameEvent == 0)
204+
return false;
205+
206+
auto currentTime = LLTimer::getTotalTime();
207+
if( (currentTime - mWaylandData.mLastFrameEvent) > 250000 )
208+
return true;
209+
210+
return false;
211+
}
212+
213213
void LLWindowSDL::setupWaylandFrameCallback()
214214
{
215+
if(!mWaylandLoaded) return;
216+
215217
static wl_callback_listener frame_listener { nullptr };
216218
frame_listener.done = &LLWindowSDL::waylandFrameDoneCB;
217219

@@ -403,12 +405,14 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b
403405
if(!mContext)
404406
{
405407
LL_WARNS() << "Cannot create GL context " << SDL_GetError() << LL_ENDL;
408+
close();
406409
setupFailure("GL Context creation error", "Error", OSMB_OK);
407410
}
408411

409412
if (SDL_GL_MakeCurrent(mWindow, mContext) != 0)
410413
{
411414
LL_WARNS() << "Failed to make context current. SDL: " << SDL_GetError() << LL_ENDL;
415+
close();
412416
setupFailure("GL Context failed to set current failure", "Error", OSMB_OK);
413417
}
414418

@@ -443,14 +447,6 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b
443447
setupFailure( error, "Error", OSMB_OK );
444448
}
445449
}
446-
else
447-
{
448-
if (!mWindow)
449-
{
450-
LL_WARNS() << "createContext: window creation failure. SDL: " << SDL_GetError() << LL_ENDL;
451-
setupFailure("Window creation error", "Error", OSMB_OK);
452-
}
453-
}
454450

455451
SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &redBits);
456452
SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &greenBits);
@@ -468,9 +464,6 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b
468464
LL_INFOS() << " Stencil Bits " << S32(stencilBits) << LL_ENDL;
469465

470466
GLint colorBits = redBits + greenBits + blueBits + alphaBits;
471-
// fixme: actually, it's REALLY important for picking that we get at
472-
// least 8 bits each of red,green,blue. Alpha we can be a bit more
473-
// relaxed about if we have to.
474467
if (colorBits < 32)
475468
{
476469
close();
@@ -504,42 +497,38 @@ bool LLWindowSDL::createContext(int x, int y, int width, int height, int bits, b
504497
if ( SDL_GetWindowWMInfo(mWindow, &info) )
505498
{
506499
/* Save the information for later use */
507-
if ( info.subsystem == SDL_SYSWM_X11 )
500+
if (info.subsystem == SDL_SYSWM_X11)
508501
{
509-
SDL_SetHint(SDL_HINT_VIDEODRIVER, "x11");
510502
mX11Data.mDisplay = info.info.x11.display;
511503
mX11Data.mXWindowID = info.info.x11.window;
512504
mServerProtocol = X11;
513505
LL_INFOS() << "Running under X11" << LL_ENDL;
514506
}
515-
else if ( info.subsystem == SDL_SYSWM_WAYLAND )
507+
else if (info.subsystem == SDL_SYSWM_WAYLAND)
516508
{
517509
#ifdef LL_WAYLAND
518-
if( !loadWaylandClient() ) {
519-
SDL_SetHint(SDL_HINT_VIDEODRIVER, "x11");
520-
LL_ERRS() << "Failed to load wayland-client.so or grab required functions" << LL_ENDL;
521-
} else {
522-
SDL_SetHint(SDL_HINT_VIDEODRIVER, "wayland");
510+
mWaylandLoaded = loadWaylandClient();
511+
if(!mWaylandLoaded)
512+
{
513+
LL_WARNS() << "Failed to load wayland-client.so or grab required functions" << LL_ENDL;
523514
}
515+
#endif
524516

525517
mWaylandData.mSurface = info.info.wl.surface;
526518
mServerProtocol = Wayland;
519+
527520
setupWaylandFrameCallback();
528521

529522
// If set (XWayland) remove DISPLAY, this will prompt dullahan to also use Wayland
530523
if( getenv("DISPLAY") )
531524
unsetenv("DISPLAY");
532525

533526
LL_INFOS() << "Running under Wayland" << LL_ENDL;
534-
LL_WARNS() << "Be aware that with at least SDL2 the window will not receive minimizing events, thus minimized state can only be estimated."
535-
"also setting the application icon via SDL_SetWindowIcon does not work." << LL_ENDL;
536-
#else
537-
setupFailure("Viewer is running under Wayland, but was not compiled with full wayland support!\nYou can compile the viewer with wayland prelimiary support using COMPILE_WAYLAND_SUPPORT", "Error", OSMB_OK);
538-
#endif
527+
LL_WARNS() << "Be aware that with at least SDL2 the window will not receive minimizing events, thus minimized state can only be estimated." << LL_ENDL;
539528
}
540529
else
541530
{
542-
LL_WARNS() << "We're not running under X11 or Wayland? Wild." << LL_ENDL;
531+
LL_WARNS() << "Unsupported windowing system" << LL_ENDL;
543532
}
544533
}
545534
else
@@ -1268,6 +1257,7 @@ U32 LLWindowSDL::SDLCheckGrabbyKeys(U32 keysym, bool gain)
12681257

12691258
void check_vm_bloat()
12701259
{
1260+
#if LL_LINUX
12711261
// watch our own VM and RSS sizes, warn if we bloated rapidly
12721262
static const std::string STATS_FILE = "/proc/self/stat";
12731263
FILE *fp = fopen(STATS_FILE.c_str(), "r");
@@ -1351,6 +1341,7 @@ void check_vm_bloat()
13511341
free(ptr);
13521342
fclose(fp);
13531343
}
1344+
#endif
13541345
}
13551346

13561347

@@ -1949,9 +1940,9 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async)
19491940
LL_INFOS() << "spawn_web_browser returning." << LL_ENDL;
19501941
}
19511942

1952-
void *LLWindowSDL::getPlatformWindow()
1943+
void* LLWindowSDL::getPlatformWindow()
19531944
{
1954-
return nullptr;
1945+
return (void*)mWindow;
19551946
}
19561947

19571948
void LLWindowSDL::bringToFront()
@@ -1968,6 +1959,8 @@ void LLWindowSDL::bringToFront()
19681959
//static
19691960
std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()
19701961
{
1962+
std::vector<std::string> rtns;
1963+
#if LL_LINUX
19711964
// Use libfontconfig to find us a nice ordered list of fallback fonts
19721965
// specific to this system.
19731966
std::string final_fallback("/usr/share/fonts/truetype/kochi/kochi-gothic.ttf");
@@ -1984,7 +1977,7 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()
19841977
// renderable range if for some reason our FreeType actually fails
19851978
// to use some of the fonts we want it to.
19861979
const bool elide_unicode_coverage = true;
1987-
std::vector<std::string> rtns;
1980+
19881981
FcFontSet *fs = nullptr;
19891982
FcPattern *sortpat = nullptr;
19901983

@@ -2058,6 +2051,7 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList()
20582051
LL_INFOS() << "Using " << rtns.size() << "/" << found_font_count << " system fonts." << LL_ENDL;
20592052

20602053
rtns.push_back(final_fallback);
2054+
#endif
20612055
return rtns;
20622056
}
20632057

indra/llwindow/llwindowsdl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ class LLWindowSDL : public LLWindow {
254254
uint64_t mLastFrameEvent = 0;
255255
} mWaylandData;
256256

257+
bool mWaylandLoaded = false;
258+
257259
bool isWaylandWindowNotDrawing() const;
258260

259261
void setupWaylandFrameCallback();

0 commit comments

Comments
 (0)