summaryrefslogtreecommitdiff
path: root/src/wayland/clipboard.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/wayland/clipboard.c')
-rw-r--r--src/wayland/clipboard.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/src/wayland/clipboard.c b/src/wayland/clipboard.c
index 0e6ce33..7df1a70 100644
--- a/src/wayland/clipboard.c
+++ b/src/wayland/clipboard.c
@@ -134,10 +134,8 @@ static int transfer_io(int fd, short events, void *ud)
memcpy(t->text + t->len, buf, (size_t)n);
t->len += n;
} else if (n == 0) {
- if (t->len) {
- t->owner->receive(t->text, t->len, t->uri_list,
- t->drop_surface, t->owner->ud);
- }
+ t->owner->receive(t->text ? t->text : "", t->len, t->uri_list,
+ t->drop_surface, t->owner->ud);
transfer_end(t, true);
} else if (errno != EAGAIN && errno != EINTR) transfer_destroy(t);
}
@@ -556,24 +554,22 @@ void clipboard_copy(struct clipboard *c, const char *text, uint32_t serial)
wl_data_device_set_selection(c->device, c->source, serial);
}
-void clipboard_paste(struct clipboard *c)
+void clipboard_paste(struct clipboard *c, struct wl_surface *target)
{
if (!c || !c->device || !c->selection || !c->selection->mime) return;
int fds[2];
if (pipe2(fds, O_CLOEXEC) < 0) return;
wl_data_offer_receive(c->selection->proxy, c->selection->mime, fds[1]);
close(fds[1]);
- start_transfer(c, fds[0], false, false);
+ struct transfer *t = start_transfer(c, fds[0], false, false);
+ if (t) t->drop_surface = target;
wl_display_flush(c->display);
}
void clipboard_copy_primary(struct clipboard *c, const char *text, uint32_t serial)
{
if (!c || !text || !serial) return;
- if (!c->primary_device || !c->primary_manager) {
- clipboard_copy(c, text, serial);
- return;
- }
+ if (!c->primary_device || !c->primary_manager) return;
char *copy = strdup(text);
if (!copy) return;
if (c->primary_source) zwp_primary_selection_source_v1_destroy(c->primary_source);
@@ -589,7 +585,7 @@ void clipboard_copy_primary(struct clipboard *c, const char *text, uint32_t seri
zwp_primary_selection_device_v1_set_selection(c->primary_device, c->primary_source, serial);
}
-void clipboard_paste_primary(struct clipboard *c)
+void clipboard_paste_primary(struct clipboard *c, struct wl_surface *target)
{
if (!c) return;
if (c->primary_device && c->primary_selection && c->primary_selection->mime) {
@@ -598,11 +594,21 @@ void clipboard_paste_primary(struct clipboard *c)
zwp_primary_selection_offer_v1_receive(c->primary_selection->proxy,
c->primary_selection->mime, fds[1]);
close(fds[1]);
- start_transfer(c, fds[0], false, false);
+ struct transfer *t = start_transfer(c, fds[0], false, false);
+ if (t) t->drop_surface = target;
wl_display_flush(c->display);
return;
}
- clipboard_paste(c);
+}
+
+void clipboard_forget_surface(struct clipboard *c, struct wl_surface *surface)
+{
+ if (!c || !surface) return;
+ for (struct transfer *t = c->transfers, *next; t; t = next) {
+ next = t->next;
+ if (t->drop_surface == surface) transfer_destroy(t);
+ }
+ if (c->drag_surface == surface) c->drag_surface = NULL;
}
void clipboard_destroy(struct clipboard *c)