diff options
Diffstat (limited to 'src/platform/wayland/clipboard.c')
| -rw-r--r-- | src/platform/wayland/clipboard.c | 51 |
1 files changed, 21 insertions, 30 deletions
diff --git a/src/platform/wayland/clipboard.c b/src/platform/wayland/clipboard.c index a6922c4..24dee97 100644 --- a/src/platform/wayland/clipboard.c +++ b/src/platform/wayland/clipboard.c @@ -71,11 +71,6 @@ static void drag_event(struct clipboard *c, enum yasl_drag_event ev, c->drag_ud); } -static bool offer_droppable(const struct offer *o) -{ - return o && !o->tab && (o->uri_list || o->mime); -} - static void drop_event(struct clipboard *c, enum yasl_drop_event ev) { if (c->drop && c->drag_surface) @@ -103,27 +98,22 @@ static void transfer_end(struct transfer *t, bool complete) free(t); } -static void transfer_destroy(struct transfer *t) -{ - transfer_end(t, false); -} - static int transfer_io(int fd, short events, void *ud) { struct transfer *t = ud; - if (events & (POLLERR | POLLNVAL)) { transfer_destroy(t); return 0; } + if (events & (POLLERR | POLLNVAL)) { transfer_end(t, false); return 0; } if (t->sending) { ssize_t n = write(fd, t->text + t->offset, t->len - t->offset); if (n > 0) t->offset += (size_t)n; if (t->offset == t->len || n == 0 || - (n < 0 && errno != EAGAIN && errno != EINTR)) transfer_destroy(t); + (n < 0 && errno != EAGAIN && errno != EINTR)) transfer_end(t, false); } else { if (t->capacity - t->len < 4096) { size_t capacity = t->capacity ? t->capacity * 2 : 8192; if (capacity > CLIPBOARD_TEXT_MAX) capacity = CLIPBOARD_TEXT_MAX; - if (capacity <= t->len) { transfer_destroy(t); return 0; } + if (capacity <= t->len) { transfer_end(t, false); return 0; } char *text = realloc(t->text, capacity); - if (!text) { transfer_destroy(t); return 0; } + if (!text) { transfer_end(t, false); return 0; } t->text = text; t->capacity = capacity; } @@ -136,7 +126,7 @@ static int transfer_io(int fd, short events, void *ud) t->owner->receive(t->text ? t->text : "", t->len, t->uri_list, t->drop_surface, t->owner->ud); transfer_end(t, valid); - } else if (errno != EAGAIN && errno != EINTR) transfer_destroy(t); + } else if (errno != EAGAIN && errno != EINTR) transfer_end(t, false); } return 0; } @@ -160,11 +150,6 @@ static struct transfer *start_transfer_text(struct clipboard *c, int fd, bool se return t; } -static struct transfer *start_transfer(struct clipboard *c, int fd, bool sending, bool uri_list) -{ - return start_transfer_text(c, fd, sending, uri_list, c->text); -} - static const char *match_text_mime(const char *mime) { if (unlikely(!mime)) return NULL; @@ -274,7 +259,7 @@ static void drag_offer_enter(void *ud, struct wl_data_device *device, uint32_t s c->drag_surface = surface; if (o && o->tab) drag_event(c, YASL_DRAG_OVER, x, y); - else if (offer_droppable(o)) + else if (o && !o->tab && (o->uri_list || o->mime)) drop_event(c, YASL_DROP_OVER); } } @@ -284,7 +269,8 @@ static void drag_offer_clear(void *ud, struct wl_data_device *device) struct clipboard *c = ud; if (c->drag_offer && c->drag_offer->tab) drag_event(c, YASL_DRAG_LEAVE, c->drag_x, c->drag_y); - else if (offer_droppable(c->drag_offer)) + else if (c->drag_offer && !c->drag_offer->tab && + (c->drag_offer->uri_list || c->drag_offer->mime)) drop_event(c, YASL_DROP_LEAVE); free_offer(c->drag_offer); c->drag_offer = NULL; @@ -298,7 +284,8 @@ static void drag_motion(void *ud, struct wl_data_device *device, uint32_t time, c->drag_y = y; if (c->drag_offer && c->drag_offer->tab) drag_event(c, YASL_DRAG_OVER, x, y); - else if (offer_droppable(c->drag_offer)) + else if (c->drag_offer && !c->drag_offer->tab && + (c->drag_offer->uri_list || c->drag_offer->mime)) drop_event(c, YASL_DROP_OVER); } static void drag_drop(void *ud, struct wl_data_device *device) @@ -313,13 +300,13 @@ static void drag_drop(void *ud, struct wl_data_device *device) drag_event(c, YASL_DRAG_DROP, c->drag_x, c->drag_y); if (v3) wl_data_offer_finish(o->proxy); - } else if (offer_droppable(o)) { + } else if (o && !o->tab && (o->uri_list || o->mime)) { drop_event(c, YASL_DROP_LEAVE); int fds[2]; if (pipe2(fds, O_CLOEXEC) == 0) { wl_data_offer_receive(o->proxy, o->uri_list ? "text/uri-list" : o->mime, fds[1]); close(fds[1]); - struct transfer *t = start_transfer(c, fds[0], false, o->uri_list); + struct transfer *t = start_transfer_text(c, fds[0], false, o->uri_list, c->text); if (t) { t->drop = o; t->drop_surface = c->drag_surface; @@ -337,7 +324,11 @@ static const struct wl_data_device_listener device_listener = { }; static void source_target(void *ud, struct wl_data_source *s, const char *mime) { (void)ud; (void)s; (void)mime; } static void source_send(void *ud, struct wl_data_source *s, const char *mime, int32_t fd) -{ (void)s; (void)mime; start_transfer(ud, fd, true, false); } +{ + struct clipboard *c = ud; + (void)s; (void)mime; + start_transfer_text(c, fd, true, false, c->text); +} static void source_cancelled(void *ud, struct wl_data_source *s) { struct clipboard *c = ud; @@ -560,7 +551,7 @@ void clipboard_paste(struct clipboard *c, struct wl_surface *target) if (pipe2(fds, O_CLOEXEC) < 0) return; wl_data_offer_receive(c->selection->proxy, c->selection->mime, fds[1]); close(fds[1]); - struct transfer *t = start_transfer(c, fds[0], false, false); + struct transfer *t = start_transfer_text(c, fds[0], false, false, c->text); if (t) t->drop_surface = target; wl_display_flush(c->display); } @@ -593,7 +584,7 @@ void clipboard_paste_primary(struct clipboard *c, struct wl_surface *target) zwp_primary_selection_offer_v1_receive(c->primary_selection->proxy, c->primary_selection->mime, fds[1]); close(fds[1]); - struct transfer *t = start_transfer(c, fds[0], false, false); + struct transfer *t = start_transfer_text(c, fds[0], false, false, c->text); if (t) t->drop_surface = target; wl_display_flush(c->display); return; @@ -605,7 +596,7 @@ 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 (t->drop_surface == surface) transfer_end(t, false); } if (c->drag_surface == surface) c->drag_surface = NULL; } @@ -614,7 +605,7 @@ void clipboard_destroy(struct clipboard *c) { if (!c) return; while (c->transfers) - transfer_destroy(c->transfers); + transfer_end(c->transfers, false); free_offer(c->selection); clear_pending_offers(c); free_offer(c->drag_offer); |
