DPF

DISTRHO Plugin Framework
Log | Files | Refs | Submodules | README | LICENSE

commit 9ab4ff814516cd8e818ae81acd3d3ff5d04a1ba5
parent 29e9fe9a9f449a92a5426066d8ac00a698050ee7
Author: falkTX <falktx@falktx.com>
Date:   Mon, 11 Jul 2022 23:17:48 +0100

Try to make X11 copy&paste more robust

Signed-off-by: falkTX <falktx@falktx.com>

Diffstat:
Mdgl/src/WindowPrivateData.cpp | 62+++++++++++++++++++++++++++++++++++++++++++-------------------
Mdgl/src/WindowPrivateData.hpp | 3++-
Mdgl/src/pugl.cpp | 22++++++++++++++++++++++
Mdgl/src/pugl.hpp | 9+++++++++
4 files changed, 76 insertions(+), 20 deletions(-)

diff --git a/dgl/src/WindowPrivateData.cpp b/dgl/src/WindowPrivateData.cpp @@ -109,7 +109,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s) minHeight(0), keepAspectRatio(false), ignoreIdleCallbacks(false), - waitingForClipboard(false), + waitingForClipboardData(false), + waitingForClipboardEvents(false), clipboardTypeId(0), filenameToRenderInto(nullptr), #ifndef DGL_FILE_BROWSER_DISABLED @@ -137,7 +138,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c minHeight(0), keepAspectRatio(false), ignoreIdleCallbacks(false), - waitingForClipboard(false), + waitingForClipboardData(false), + waitingForClipboardEvents(false), clipboardTypeId(0), filenameToRenderInto(nullptr), #ifndef DGL_FILE_BROWSER_DISABLED @@ -167,7 +169,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, minHeight(0), keepAspectRatio(false), ignoreIdleCallbacks(false), - waitingForClipboard(false), + waitingForClipboardData(false), + waitingForClipboardEvents(false), clipboardTypeId(0), filenameToRenderInto(nullptr), #ifndef DGL_FILE_BROWSER_DISABLED @@ -198,7 +201,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, minHeight(0), keepAspectRatio(false), ignoreIdleCallbacks(false), - waitingForClipboard(false), + waitingForClipboardData(false), + waitingForClipboardEvents(false), clipboardTypeId(0), filenameToRenderInto(nullptr), #ifndef DGL_FILE_BROWSER_DISABLED @@ -610,7 +614,7 @@ void Window::PrivateData::onPuglConfigure(const double width, const double heigh void Window::PrivateData::onPuglExpose() { - DGL_DBGp("PUGL: onPuglExpose\n"); + DGL_DBG("PUGL: onPuglExpose\n"); puglOnDisplayPrepare(view); @@ -769,36 +773,48 @@ void Window::PrivateData::onPuglScroll(const Widget::ScrollEvent& ev) const void* Window::PrivateData::getClipboard(size_t& dataSize) { clipboardTypeId = 0; - waitingForClipboard = true; + waitingForClipboardData = true, + waitingForClipboardEvents = true; + // begin clipboard dance here if (puglPaste(view) != PUGL_SUCCESS) { dataSize = 0; - waitingForClipboard = false; + waitingForClipboardEvents = false; return nullptr; } - // wait for type request - while (waitingForClipboard && clipboardTypeId == 0) - puglUpdate(appData->world, 0.03); + // wait for type request, clipboardTypeId must be != 0 to be valid + while (clipboardTypeId == 0 && waitingForClipboardData) + { + #ifdef DGL_USING_X11 + puglX11UpdateWithoutExposures(appData->world); + #endif + } if (clipboardTypeId == 0) { dataSize = 0; - waitingForClipboard = false; + waitingForClipboardEvents = false; return nullptr; } - // wait for actual data - while (waitingForClipboard) - puglUpdate(appData->world, 0.03); + // wait for actual data (assumes offer was accepted) + while (waitingForClipboardData) + { + #ifdef DGL_USING_X11 + puglX11UpdateWithoutExposures(appData->world); + #endif + } if (clipboardTypeId == 0) { dataSize = 0; + waitingForClipboardEvents = false; return nullptr; } + waitingForClipboardEvents = false; return puglGetClipboard(view, clipboardTypeId - 1, &dataSize); } @@ -809,7 +825,8 @@ uint32_t Window::PrivateData::onClipboardDataOffer() if ((clipboardTypeId = self->onClipboardDataOffer()) != 0) return clipboardTypeId; - waitingForClipboard = false; + // stop waiting for data, it was rejected + waitingForClipboardData = false; return 0; } @@ -818,7 +835,7 @@ void Window::PrivateData::onClipboardData(const uint32_t typeId) if (clipboardTypeId != typeId) clipboardTypeId = 0; - waitingForClipboard = false; + waitingForClipboardData = false; } #if defined(DEBUG) && defined(DGL_DEBUG_EVENTS) @@ -834,7 +851,7 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu } #endif - if (pData->waitingForClipboard) + if (pData->waitingForClipboardEvents) { switch (event->type) { @@ -851,8 +868,15 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu case PUGL_BUTTON_RELEASE: case PUGL_MOTION: case PUGL_SCROLL: + case PUGL_TIMER: + case PUGL_LOOP_ENTER: + case PUGL_LOOP_LEAVE: return PUGL_SUCCESS; + case PUGL_DATA_OFFER: + case PUGL_DATA: + break; default: + d_stdout("Got event %d while waitingForClipboardEvents", event->type); break; } } @@ -865,10 +889,10 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu ///< View created, a #PuglEventCreate case PUGL_CREATE: -#if defined(HAVE_X11) && !defined(DISTRHO_OS_MAC) && !defined(DISTRHO_OS_WINDOWS) + #ifdef DGL_USING_X11 if (! pData->isEmbed) puglX11SetWindowTypeAndPID(view, pData->appData->isStandalone); -#endif + #endif break; ///< View destroyed, a #PuglEventDestroy diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp @@ -78,7 +78,8 @@ struct Window::PrivateData : IdleCallback { bool ignoreIdleCallbacks; /** Whether we are waiting to receive clipboard data, ignoring some events in the process. */ - bool waitingForClipboard; + bool waitingForClipboardData; + bool waitingForClipboardEvents; /** The type id returned by the last onClipboardDataOffer call. */ uint32_t clipboardTypeId; diff --git a/dgl/src/pugl.cpp b/dgl/src/pugl.cpp @@ -226,6 +226,8 @@ void puglRaiseWindow(PuglView* const view) if (NSWindow* const window = view->impl->window ? view->impl->window : [view->impl->wrapperView window]) [window orderFrontRegardless]; +#elif defined(DISTRHO_OS_WASM) + // nothing #elif defined(DISTRHO_OS_WINDOWS) SetForegroundWindow(view->impl->hwnd); SetActiveWindow(view->impl->hwnd); @@ -290,6 +292,8 @@ PuglStatus puglSetGeometryConstraints(PuglView* const view, const uint width, co if (aspect && (status = updateSizeHint(view, PUGL_FIXED_ASPECT)) != PUGL_SUCCESS) return status; } +#elif defined(DISTRHO_OS_WASM) + // nothing #elif defined(DISTRHO_OS_WINDOWS) // nothing #elif defined(HAVE_X11) @@ -317,6 +321,8 @@ void puglSetResizable(PuglView* const view, const bool resizable) [window setStyleMask:style]; } // FIXME use [view setAutoresizingMask:NSViewNotSizable] ? +#elif defined(DISTRHO_OS_WASM) + // nothing #elif defined(DISTRHO_OS_WINDOWS) if (const HWND hwnd = view->impl->hwnd) { @@ -433,6 +439,8 @@ void puglFallbackOnResize(PuglView* const view) #endif } +// -------------------------------------------------------------------------------------------------------------------- + #if defined(DISTRHO_OS_MAC) // -------------------------------------------------------------------------------------------------------------------- @@ -570,8 +578,22 @@ void puglWin32ShowCentered(PuglView* const view) // -------------------------------------------------------------------------------------------------------------------- +#elif defined(DISTRHO_OS_WASM) + +// nothing here yet + +// -------------------------------------------------------------------------------------------------------------------- + #elif defined(HAVE_X11) +PuglStatus puglX11UpdateWithoutExposures(PuglWorld* const world) +{ + world->impl->dispatchingEvents = true; + const PuglStatus st = dispatchX11Events(world); + world->impl->dispatchingEvents = false; + return st; +} + // -------------------------------------------------------------------------------------------------------------------- // X11 specific, set dialog window type and pid hints diff --git a/dgl/src/pugl.hpp b/dgl/src/pugl.hpp @@ -84,6 +84,10 @@ PuglStatus puglMacOSRemoveChildWindow(PuglView* view, PuglView* child); // macOS specific, center view based on parent coordinates (if there is one) void puglMacOSShowCentered(PuglView* view); +#elif defined(DISTRHO_OS_WASM) + +// nothing here yet + #elif defined(DISTRHO_OS_WINDOWS) // win32 specific, call ShowWindow with SW_RESTORE @@ -94,6 +98,11 @@ void puglWin32ShowCentered(PuglView* view); #elif defined(HAVE_X11) +#define DGL_USING_X11 + +// X11 specific, update world without triggering exposure evente +PuglStatus puglX11UpdateWithoutExposures(PuglWorld* world); + // X11 specific, set dialog window type and pid hints void puglX11SetWindowTypeAndPID(const PuglView* view, bool isStandalone);