diff --git a/dgl/src/ApplicationPrivateData.cpp b/dgl/src/ApplicationPrivateData.cpp index be8490b2..00787d14 100644 --- a/dgl/src/ApplicationPrivateData.cpp +++ b/dgl/src/ApplicationPrivateData.cpp @@ -61,9 +61,6 @@ Application::PrivateData::PrivateData(const bool standalone) puglSetWorldHandle(world, this); puglSetClassName(world, DISTRHO_MACRO_AS_STRING(DGL_NAMESPACE)); -#ifdef HAVE_X11 - sofdFileDialogSetup(world); -#endif #ifdef DISTRHO_OS_MAC if (standalone) diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp index 73807933..d0d42b38 100644 --- a/dgl/src/WindowPrivateData.cpp +++ b/dgl/src/WindowPrivateData.cpp @@ -190,7 +190,7 @@ Window::PrivateData::~PrivateData() if (isEmbed) { #ifdef HAVE_X11 - sofdFileDialogClose(view); + sofdFileDialogClose(); #endif puglHide(view); appData->oneWindowClosed(); @@ -349,7 +349,7 @@ void Window::PrivateData::hide() stopModal(); #ifdef HAVE_X11 - sofdFileDialogClose(view); + sofdFileDialogClose(); #endif puglHide(view); @@ -400,12 +400,8 @@ void Window::PrivateData::idleCallback() } # endif # ifdef HAVE_X11 - char* path; - if (sofdFileDialogGetPath(&path)) - { - self->onFileSelected(path); - sofdFileDialogFree(path); - } + if (sofdFileDialogIdle(view)) + self->onFileSelected(sofdFileDialogGetPath()); # endif #endif } diff --git a/dgl/src/pugl.cpp b/dgl/src/pugl.cpp index 28e3f97b..e74af3e9 100644 --- a/dgl/src/pugl.cpp +++ b/dgl/src/pugl.cpp @@ -529,34 +529,11 @@ PuglStatus puglX11GrabFocus(PuglView* const view) } // -------------------------------------------------------------------------------------------------------------------- -// X11 specific, setup event loop filter for sofd file dialog +// X11 specific stuff for sofd -static bool sofd_has_action; +static Display* sofd_display; static char* sofd_filename; -static bool sofd_event_filter(Display* const display, XEvent* const xevent) -{ - if (x_fib_handle_events(display, xevent) == 0) - return false; - - if (sofd_filename != nullptr) - std::free(sofd_filename); - - if (x_fib_status() > 0) - sofd_filename = x_fib_filename(); - else - sofd_filename = nullptr; - - x_fib_close(display); - sofd_has_action = true; - return true; -} - -void sofdFileDialogSetup(PuglWorld* const world) -{ - puglX11SetEventFilter(world, sofd_event_filter); -} - // -------------------------------------------------------------------------------------------------------------------- // X11 specific, show file dialog via sofd @@ -564,6 +541,12 @@ bool sofdFileDialogShow(PuglView* const view, const char* const startDir, const char* const title, const uint flags, const uint width, const uint height) { + // only one possible at a time + DISTRHO_SAFE_ASSERT_RETURN(sofd_display == nullptr, false); + + sofd_display = XOpenDisplay(nullptr); + DISTRHO_SAFE_ASSERT_RETURN(sofd_display != nullptr, false); + DISTRHO_SAFE_ASSERT_RETURN(x_fib_configure(0, startDir) == 0, false); DISTRHO_SAFE_ASSERT_RETURN(x_fib_configure(1, title) == 0, false); @@ -573,44 +556,68 @@ bool sofdFileDialogShow(PuglView* const view, x_fib_cfg_buttons(2, options.buttons.showPlaces-1); */ - PuglInternals* const impl = view->impl; - return (x_fib_show(impl->display, impl->win, width, height) == 0); + return (x_fib_show(sofd_display, view->impl->win, width, height) == 0); } // -------------------------------------------------------------------------------------------------------------------- -// X11 specific, close sofd file dialog +// X11 specific, idle sofd file dialog, returns true if dialog was closed (with or without a file selection) -void sofdFileDialogClose(PuglView* const view) +bool sofdFileDialogIdle(PuglView* const view) { - PuglInternals* const impl = view->impl; - x_fib_close(impl->display); -} + if (sofd_display == nullptr) + return false; -// -------------------------------------------------------------------------------------------------------------------- -// X11 specific, get path chosen via sofd file dialog + XEvent event; + while (XPending(sofd_display) > 0) + { + XNextEvent(sofd_display, &event); -bool sofdFileDialogGetPath(char** path) -{ - if (! sofd_has_action) - return false; + if (x_fib_handle_events(sofd_display, &event) == 0) + continue; - sofd_has_action = false; - *path = sofd_filename; - return true; + if (sofd_filename != nullptr) + std::free(sofd_filename); + + if (x_fib_status() > 0) + sofd_filename = x_fib_filename(); + else + sofd_filename = nullptr; + + x_fib_close(sofd_display); + XCloseDisplay(sofd_display); + sofd_display = nullptr; + return true; + } + + return false; } // -------------------------------------------------------------------------------------------------------------------- -// X11 specific, free path of sofd file dialog, no longer needed +// X11 specific, close sofd file dialog -void sofdFileDialogFree(char* const path) +void sofdFileDialogClose() { - DISTRHO_SAFE_ASSERT_RETURN(path == nullptr || path == sofd_filename,); + if (sofd_display != nullptr) + { + x_fib_close(sofd_display); + XCloseDisplay(sofd_display); + sofd_display = nullptr; + } - std::free(sofd_filename); - sofd_filename = nullptr; + if (sofd_filename != nullptr) + { + std::free(sofd_filename); + sofd_filename = nullptr; + } } // -------------------------------------------------------------------------------------------------------------------- +// X11 specific, get path chosen via sofd file dialog + +const char* sofdFileDialogGetPath() +{ + return sofd_filename; +} #endif // -------------------------------------------------------------------------------------------------------------------- diff --git a/dgl/src/pugl.hpp b/dgl/src/pugl.hpp index 9be12209..5067d054 100644 --- a/dgl/src/pugl.hpp +++ b/dgl/src/pugl.hpp @@ -124,25 +124,21 @@ puglWin32SetWindowResizable(PuglView* view, bool resizable); PUGL_API PuglStatus puglX11GrabFocus(PuglView* view); -// X11 specific, setup event loop filter for sofd file dialog -PUGL_API void -sofdFileDialogSetup(PuglWorld* world); - // X11 specific, show file dialog via sofd PUGL_API bool sofdFileDialogShow(PuglView* view, const char* startDir, const char* title, uint flags, uint width, uint height); +// X11 specific, idle sofd file dialog, returns true if dialog was closed (with or without a file selection) +PUGL_API bool +sofdFileDialogIdle(PuglView* const view); + // X11 specific, close sofd file dialog PUGL_API void -sofdFileDialogClose(PuglView* view); +sofdFileDialogClose(); // X11 specific, get path chosen via sofd file dialog -PUGL_API bool -sofdFileDialogGetPath(char** path); - -// X11 specific, free path of sofd file dialog, no longer needed -PUGL_API void -sofdFileDialogFree(char* path); +PUGL_API const char* +sofdFileDialogGetPath(); #endif PUGL_END_DECLS