commit a1fc530dd0fe2ece95e6f046690b0c82d5ccf170
parent 9b228b0c5b741917aaf60989d46d5ffcaa5fce73
Author: falkTX <falktx@falktx.com>
Date: Sat, 28 May 2022 00:51:05 +0100
Make new clipboard things work on X11
Signed-off-by: falkTX <falktx@falktx.com>
Diffstat:
3 files changed, 94 insertions(+), 17 deletions(-)
diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp
@@ -321,18 +321,12 @@ void Window::setIgnoringKeyRepeat(const bool ignore) noexcept
const void* Window::getClipboard(size_t& dataSize)
{
- if (pData->clipboardTypeIndex == 0)
- {
- dataSize = 0;
- return nullptr;
- }
-
- return puglGetClipboard(pData->view, pData->clipboardTypeIndex, &dataSize);
+ return pData->getClipboard(dataSize);
}
bool Window::setClipboard(const char* const mimeType, const void* const data, const size_t dataSize)
{
- return puglSetClipboard(pData->view, mimeType, data, dataSize) == PUGL_SUCCESS;
+ return puglSetClipboard(pData->view, mimeType != nullptr ? mimeType : "text/plain", data, dataSize) == PUGL_SUCCESS;
}
bool Window::setCursor(const MouseCursor cursor)
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),
- clipboardTypeIndex(0),
+ waitingForClipboard(false),
+ clipboardTypeId(0),
filenameToRenderInto(nullptr),
#ifndef DGL_FILE_BROWSER_DISABLED
fileBrowserHandle(nullptr),
@@ -136,7 +137,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s, PrivateData* c
minHeight(0),
keepAspectRatio(false),
ignoreIdleCallbacks(false),
- clipboardTypeIndex(0),
+ waitingForClipboard(false),
+ clipboardTypeId(0),
filenameToRenderInto(nullptr),
#ifndef DGL_FILE_BROWSER_DISABLED
fileBrowserHandle(nullptr),
@@ -165,7 +167,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
minHeight(0),
keepAspectRatio(false),
ignoreIdleCallbacks(false),
- clipboardTypeIndex(0),
+ waitingForClipboard(false),
+ clipboardTypeId(0),
filenameToRenderInto(nullptr),
#ifndef DGL_FILE_BROWSER_DISABLED
fileBrowserHandle(nullptr),
@@ -195,7 +198,8 @@ Window::PrivateData::PrivateData(Application& a, Window* const s,
minHeight(0),
keepAspectRatio(false),
ignoreIdleCallbacks(false),
- clipboardTypeIndex(0),
+ waitingForClipboard(false),
+ clipboardTypeId(0),
filenameToRenderInto(nullptr),
#ifndef DGL_FILE_BROWSER_DISABLED
fileBrowserHandle(nullptr),
@@ -757,11 +761,59 @@ void Window::PrivateData::onPuglScroll(const Widget::ScrollEvent& ev)
#endif
}
+const void* Window::PrivateData::getClipboard(size_t& dataSize)
+{
+ clipboardTypeId = 0;
+ waitingForClipboard = true;
+
+ if (puglPaste(view) != PUGL_SUCCESS)
+ {
+ dataSize = 0;
+ waitingForClipboard = false;
+ return nullptr;
+ }
+
+ // wait for type request
+ while (waitingForClipboard && clipboardTypeId == 0)
+ puglUpdate(appData->world, 0.03);
+
+ if (clipboardTypeId == 0)
+ {
+ dataSize = 0;
+ waitingForClipboard = false;
+ return nullptr;
+ }
+
+ // wait for actual data
+ while (waitingForClipboard)
+ puglUpdate(appData->world, 0.03);
+
+ if (clipboardTypeId == 0)
+ {
+ dataSize = 0;
+ return nullptr;
+ }
+
+ return puglGetClipboard(view, clipboardTypeId - 1, &dataSize);
+}
+
uint32_t Window::PrivateData::onClipboardDataOffer()
{
DGL_DBG("onClipboardDataOffer\n");
- return clipboardTypeIndex = self->onClipboardDataOffer();
+ if ((clipboardTypeId = self->onClipboardDataOffer()) != 0)
+ return clipboardTypeId;
+
+ waitingForClipboard = false;
+ return 0;
+}
+
+void Window::PrivateData::onClipboardData(const uint32_t typeId)
+{
+ if (clipboardTypeId != typeId)
+ clipboardTypeId = 0;
+
+ waitingForClipboard = false;
}
#if defined(DEBUG) && defined(DGL_DEBUG_EVENTS)
@@ -777,6 +829,29 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu
}
#endif
+ if (pData->waitingForClipboard)
+ {
+ switch (event->type)
+ {
+ case PUGL_UPDATE:
+ case PUGL_EXPOSE:
+ case PUGL_FOCUS_IN:
+ case PUGL_FOCUS_OUT:
+ case PUGL_KEY_PRESS:
+ case PUGL_KEY_RELEASE:
+ case PUGL_TEXT:
+ case PUGL_POINTER_IN:
+ case PUGL_POINTER_OUT:
+ case PUGL_BUTTON_PRESS:
+ case PUGL_BUTTON_RELEASE:
+ case PUGL_MOTION:
+ case PUGL_SCROLL:
+ return PUGL_SUCCESS;
+ default:
+ break;
+ }
+ }
+
switch (event->type)
{
///< No event
@@ -944,12 +1019,13 @@ PuglStatus Window::PrivateData::puglEventCallback(PuglView* const view, const Pu
///< Data offered from clipboard, a #PuglDataOfferEvent
case PUGL_DATA_OFFER:
- if (const uint32_t offerId = pData->onClipboardDataOffer())
- puglAcceptOffer(view, &event->offer, offerId - 1);
+ if (const uint32_t offerTypeId = pData->onClipboardDataOffer())
+ puglAcceptOffer(view, &event->offer, offerTypeId - 1);
break;
///< Data available from clipboard, a #PuglDataEvent
case PUGL_DATA:
+ pData->onClipboardData(event->data.typeIndex + 1);
break;
}
diff --git a/dgl/src/WindowPrivateData.hpp b/dgl/src/WindowPrivateData.hpp
@@ -80,8 +80,11 @@ struct Window::PrivateData : IdleCallback {
/** Whether to ignore idle callback requests, useful for temporary windows. */
bool ignoreIdleCallbacks;
- /** The type index returned by the last onClipboardDataOffer call. */
- uint32_t clipboardTypeIndex;
+ /** Whether we are waiting to receive clipboard data, ignoring some events in the process. */
+ bool waitingForClipboard;
+
+ /** The type id returned by the last onClipboardDataOffer call. */
+ uint32_t clipboardTypeId;
/** Render to a picture file when non-null, automatically free+unset after saving. */
char* filenameToRenderInto;
@@ -185,7 +188,11 @@ struct Window::PrivateData : IdleCallback {
void onPuglMouse(const Widget::MouseEvent& ev);
void onPuglMotion(const Widget::MotionEvent& ev);
void onPuglScroll(const Widget::ScrollEvent& ev);
+
+ // clipboard related handling
+ const void* getClipboard(size_t& dataSize);
uint32_t onClipboardDataOffer();
+ void onClipboardData(uint32_t typeId);
// Pugl event handling entry point
static PuglStatus puglEventCallback(PuglView* view, const PuglEvent* event);