aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bindings/cpp/include/pugl/pugl.hpp16
-rw-r--r--doc/c/clipboards.rst2
-rw-r--r--examples/pugl_clipboard_demo.c2
-rw-r--r--include/pugl/pugl.h18
-rw-r--r--src/mac.m20
-rw-r--r--src/win.c1
-rw-r--r--src/x11.c3
-rw-r--r--src/x11.h1
-rw-r--r--test/test_local_copy_paste.c3
-rw-r--r--test/test_remote_copy_paste.c3
10 files changed, 61 insertions, 8 deletions
diff --git a/bindings/cpp/include/pugl/pugl.hpp b/bindings/cpp/include/pugl/pugl.hpp
index 18dd015..d691123 100644
--- a/bindings/cpp/include/pugl/pugl.hpp
+++ b/bindings/cpp/include/pugl/pugl.hpp
@@ -141,6 +141,9 @@ using ViewStyleFlags = PuglViewStyleFlags;
/// @copydoc PuglClipboard
using Clipboard = PuglClipboard;
+/// @copydoc PuglAction
+using Action = PuglAction;
+
/// @copydoc PuglRealizeEvent
using RealizeEvent = Event<PUGL_REALIZE, PuglRealizeEvent>;
@@ -665,15 +668,22 @@ public:
the `typeIndex` argument to the call of puglGetClipboardType() that
returned the accepted type.
- @param region The region of the view that will accept the data. This may
- be used by the system to avoid sending redundant events.
+ @param action The action that will be performed when the data is dropped.
+ This may be used to provide visual feedback to the user, for example by
+ having the drag source change the cursor.
+
+ @param region The region of the view that will accept this drop. This may
+ be used by the system to avoid sending redundant events when the item is
+ dragged within the region. This is only an optimization, an all-zero
+ region can safely be passed.
*/
Status acceptOffer(const DataOfferEvent& offer,
const uint32_t typeIndex,
+ const Action action,
const Rect& region)
{
return static_cast<Status>(
- puglAcceptOffer(cobj(), &offer, typeIndex, region));
+ puglAcceptOffer(cobj(), &offer, typeIndex, action, region));
}
/// @copydoc puglSetViewStyle
diff --git a/doc/c/clipboards.rst b/doc/c/clipboards.rst
index c7b6ef4..ca8b4ad 100644
--- a/doc/c/clipboards.rst
+++ b/doc/c/clipboards.rst
@@ -90,7 +90,7 @@ it can accept the offer with :func:`puglAcceptOffer`:
}
}
-A view region must be given,
+An :enum:`action <PuglAction>` and view region must be given,
which the window system may use to optimize the process and/or provide user feedback.
When an offer is accepted,
diff --git a/examples/pugl_clipboard_demo.c b/examples/pugl_clipboard_demo.c
index ba691cf..08227d1 100644
--- a/examples/pugl_clipboard_demo.c
+++ b/examples/pugl_clipboard_demo.c
@@ -94,7 +94,7 @@ onDataOffer(PuglView* view, const PuglDataOfferEvent* event)
for (uint32_t t = 0; t < numTypes; ++t) {
const char* type = puglGetClipboardType(view, clipboard, t);
if (!strncmp(type, "text/", 5)) {
- puglAcceptOffer(view, event, t, puglGetFrame(view));
+ puglAcceptOffer(view, event, t, PUGL_ACTION_LINK, puglGetFrame(view));
return;
}
}
diff --git a/include/pugl/pugl.h b/include/pugl/pugl.h
index 852003f..e57f6aa 100644
--- a/include/pugl/pugl.h
+++ b/include/pugl/pugl.h
@@ -158,6 +158,19 @@ typedef enum {
PUGL_CLIPBOARD_GENERAL, ///< General clipboard for copy/pasted data
} PuglClipboard;
+/**
+ An action that can be performed on data from a clipboard.
+
+ This is given when accepting a data offer, so the system can provide user
+ feedback, for example by changing the cursor or showing an animation.
+*/
+typedef enum {
+ PUGL_ACTION_COPY, ///< Data will be copied
+ PUGL_ACTION_LINK, ///< Data will be linked to
+ PUGL_ACTION_MOVE, ///< Data will be moved
+ PUGL_ACTION_PRIVATE, ///< Unspecified private action
+} PuglAction;
+
/// Common header for all event structs
typedef struct {
PuglEventType type; ///< Event type
@@ -1540,6 +1553,10 @@ puglGetClipboardType(const PuglView* view,
the `typeIndex` argument to the call of puglGetClipboardType() that returned
the accepted type.
+ @param action The action that will be performed on the data. This may be
+ used to provide visual feedback to the user, for example by changing the
+ cursor.
+
@param region The region of the view that will accept the data. This may be
used by the system to avoid sending redundant events.
*/
@@ -1548,6 +1565,7 @@ PuglStatus
puglAcceptOffer(PuglView* view,
const PuglDataOfferEvent* offer,
uint32_t typeIndex,
+ PuglAction action,
PuglRect region);
/**
diff --git a/src/mac.m b/src/mac.m
index 6da3cf7..107cadb 100644
--- a/src/mac.m
+++ b/src/mac.m
@@ -1926,10 +1926,28 @@ puglGetClipboardType(const PuglView* const view,
return mimeType ? [mimeType UTF8String] : [uti UTF8String];
}
+static NSDragOperation
+getDragOperation(const PuglAction action)
+{
+ switch (action) {
+ case PUGL_ACTION_COPY:
+ return NSDragOperationCopy;
+ case PUGL_ACTION_LINK:
+ return NSDragOperationLink;
+ case PUGL_ACTION_MOVE:
+ return NSDragOperationMove;
+ case PUGL_ACTION_PRIVATE:
+ break;
+ }
+
+ return NSDragOperationPrivate;
+}
+
PuglStatus
puglAcceptOffer(PuglView* const view,
const PuglDataOfferEvent* const offer,
const uint32_t typeIndex,
+ const PuglAction action,
const PuglRect region)
{
PuglWrapperView* const wrapper = view->impl->wrapperView;
@@ -1943,7 +1961,7 @@ puglAcceptOffer(PuglView* const view,
return PUGL_BAD_PARAMETER;
}
- wrapper->dragOperation = NSDragOperationCopy;
+ wrapper->dragOperation = getDragOperation(action);
wrapper->dragTypeIndex = typeIndex;
const PuglDataEvent data = {PUGL_DATA,
diff --git a/src/win.c b/src/win.c
index d118b36..0b850ef 100644
--- a/src/win.c
+++ b/src/win.c
@@ -1372,6 +1372,7 @@ PuglStatus
puglAcceptOffer(PuglView* const view,
const PuglDataOfferEvent* const PUGL_UNUSED(offer),
const uint32_t typeIndex,
+ PuglAction PUGL_UNUSED(action),
const PuglRect region)
{
if (typeIndex != 0) {
diff --git a/src/x11.c b/src/x11.c
index 5bdbbed..a66ac30 100644
--- a/src/x11.c
+++ b/src/x11.c
@@ -508,6 +508,7 @@ clearX11Clipboard(PuglX11Clipboard* const board)
board->source = None;
board->numFormats = 0;
+ board->acceptedAction = PUGL_ACTION_PRIVATE;
board->acceptedFormatIndex = UINT32_MAX;
board->acceptedFormat = None;
board->data.len = 0;
@@ -2116,6 +2117,7 @@ PuglStatus
puglAcceptOffer(PuglView* const view,
const PuglDataOfferEvent* const offer,
const uint32_t typeIndex,
+ PuglAction action,
const PuglRect region)
{
(void)region;
@@ -2124,6 +2126,7 @@ puglAcceptOffer(PuglView* const view,
Display* const display = view->world->impl->display;
PuglX11Clipboard* const board = getX11Clipboard(view, offer->clipboard);
+ board->acceptedAction = action;
board->acceptedFormatIndex = typeIndex;
board->acceptedFormat = board->formats[typeIndex];
diff --git a/src/x11.h b/src/x11.h
index 58073e5..2e14ae2 100644
--- a/src/x11.h
+++ b/src/x11.h
@@ -61,6 +61,7 @@ typedef struct {
Atom* formats;
char** formatStrings;
unsigned long numFormats;
+ PuglAction acceptedAction;
uint32_t acceptedFormatIndex;
Atom acceptedFormat;
PuglBlob data;
diff --git a/test/test_local_copy_paste.c b/test/test_local_copy_paste.c
index 9aa4cba..20332d1 100644
--- a/test/test_local_copy_paste.c
+++ b/test/test_local_copy_paste.c
@@ -98,7 +98,8 @@ onEvent(PuglView* view, const PuglEvent* event)
if (test->state == PASTED) {
test->state = RECEIVED_OFFER;
- assert(!puglAcceptOffer(view, &event->offer, 0, puglGetFrame(view)));
+ assert(!puglAcceptOffer(
+ view, &event->offer, 0, PUGL_ACTION_COPY, puglGetFrame(view)));
}
break;
diff --git a/test/test_remote_copy_paste.c b/test/test_remote_copy_paste.c
index de5a61b..e6464d8 100644
--- a/test/test_remote_copy_paste.c
+++ b/test/test_remote_copy_paste.c
@@ -108,7 +108,8 @@ onPasterEvent(PuglView* const view, const PuglEvent* const event)
if (test->state == PASTED) {
test->state = RECEIVED_OFFER;
- assert(!puglAcceptOffer(view, &event->offer, 0, puglGetFrame(view)));
+ assert(!puglAcceptOffer(
+ view, &event->offer, 0, PUGL_ACTION_COPY, puglGetFrame(view)));
}
break;