diff --git a/osc.c b/osc.c index 4dc47172..82793fb5 100644 --- a/osc.c +++ b/osc.c @@ -261,12 +261,12 @@ osc_from_clipboard(struct terminal *term, const char *source) if (from_clipboard) { text_from_clipboard( - seat, term, &from_clipboard_cb, &from_clipboard_done, ctx); + seat, term, true, &from_clipboard_cb, &from_clipboard_done, ctx); } if (from_primary) { text_from_primary( - seat, term, &from_clipboard_cb, &from_clipboard_done, ctx); + seat, term, true, &from_clipboard_cb, &from_clipboard_done, ctx); } } diff --git a/search.c b/search.c index 5228bf61..5386ffd3 100644 --- a/search.c +++ b/search.c @@ -1375,13 +1375,13 @@ execute_binding(struct seat *seat, struct terminal *term, case BIND_ACTION_SEARCH_CLIPBOARD_PASTE: text_from_clipboard( - seat, term, &from_clipboard_cb, &from_clipboard_done, term); + seat, term, false, &from_clipboard_cb, &from_clipboard_done, term); *update_search_result = *redraw = true; return true; case BIND_ACTION_SEARCH_PRIMARY_PASTE: text_from_primary( - seat, term, &from_clipboard_cb, &from_clipboard_done, term); + seat, term, false, &from_clipboard_cb, &from_clipboard_done, term); *update_search_result = *redraw = true; return true; diff --git a/selection.c b/selection.c index f07396a5..0a479ee8 100644 --- a/selection.c +++ b/selection.c @@ -2006,6 +2006,7 @@ struct clipboard_receive { int timeout_fd; struct itimerspec timeout; bool bracketed; + bool no_strip; bool quote_paths; void (*decoder)(struct clipboard_receive *ctx, char *data, size_t size); @@ -2153,6 +2154,8 @@ static bool fdm_receive(struct fdm *fdm, int fd, int events, void *data) { struct clipboard_receive *ctx = data; + const bool no_strip = ctx->no_strip; + const bool bracketed = ctx->bracketed; if ((events & EPOLLHUP) && !(events & EPOLLIN)) goto done; @@ -2204,13 +2207,14 @@ fdm_receive(struct fdm *fdm, int fd, int events, void *data) break; case '\n': - if (!ctx->bracketed) + if (!no_strip && !bracketed) { p[i] = '\r'; + } break; case '\r': /* Convert \r\n -> \r */ - if (!ctx->bracketed && i + 1 < left && p[i + 1] == '\n') { + if (!no_strip && !bracketed && i + 1 < left && p[i + 1] == '\n') { i++; skip_one(); goto again; @@ -2223,8 +2227,11 @@ fdm_receive(struct fdm *fdm, int fd, int events, void *data) case '\x11': case '\x12': case '\x13': case '\x14': case '\x15': case '\x16': case '\x17': case '\x18': case '\x19': case '\x1a': case '\x1b': case '\x1c': case '\x1d': case '\x1e': case '\x1f': - skip_one(); - goto again; + if (!no_strip) { + skip_one(); + goto again; + } + break; /* * In addition to stripping non-formatting C0 controls, @@ -2242,7 +2249,7 @@ fdm_receive(struct fdm *fdm, int fd, int events, void *data) * handled above. */ case '\b': case '\x7f': case '\x00': - if (!ctx->bracketed) { + if (!no_strip && !bracketed) { skip_one(); goto again; } @@ -2263,8 +2270,8 @@ done: } static void -begin_receive_clipboard(struct terminal *term, int read_fd, - enum data_offer_mime_type mime_type, +begin_receive_clipboard(struct terminal *term, bool no_strip, + int read_fd, enum data_offer_mime_type mime_type, void (*cb)(char *data, size_t size, void *user), void (*done)(void *user), void *user) { @@ -2297,6 +2304,7 @@ begin_receive_clipboard(struct terminal *term, int read_fd, .timeout_fd = timeout_fd, .timeout = timeout, .bracketed = term->bracketed_paste, + .no_strip = no_strip, .quote_paths = term->grid == &term->normal, .decoder = (mime_type == DATA_OFFER_MIME_URI_LIST ? &fdm_receive_decoder_uri @@ -2326,6 +2334,7 @@ err: void text_from_clipboard(struct seat *seat, struct terminal *term, + bool no_strip, void (*cb)(char *data, size_t size, void *user), void (*done)(void *user), void *user) { @@ -2358,7 +2367,8 @@ text_from_clipboard(struct seat *seat, struct terminal *term, /* Don't keep our copy of the write-end open (or we'll never get EOF) */ close(write_fd); - begin_receive_clipboard(term, read_fd, clipboard->mime_type, cb, done, user); + begin_receive_clipboard( + term, no_strip, read_fd, clipboard->mime_type, cb, done, user); } static void @@ -2401,7 +2411,8 @@ selection_from_clipboard(struct seat *seat, struct terminal *term, uint32_t seri if (term->bracketed_paste) term_paste_data_to_slave(term, "\033[200~", 6); - text_from_clipboard(seat, term, &receive_offer, &receive_offer_done, term); + text_from_clipboard( + seat, term, false, &receive_offer, &receive_offer_done, term); } bool @@ -2470,7 +2481,7 @@ selection_to_primary(struct seat *seat, struct terminal *term, uint32_t serial) void text_from_primary( - struct seat *seat, struct terminal *term, + struct seat *seat, struct terminal *term, bool no_strip, void (*cb)(char *data, size_t size, void *user), void (*done)(void *user), void *user) { @@ -2508,7 +2519,8 @@ text_from_primary( /* Don't keep our copy of the write-end open (or we'll never get EOF) */ close(write_fd); - begin_receive_clipboard(term, read_fd, primary->mime_type, cb, done, user); + begin_receive_clipboard( + term, no_strip, read_fd, primary->mime_type, cb, done, user); } void @@ -2530,7 +2542,8 @@ selection_from_primary(struct seat *seat, struct terminal *term) if (term->bracketed_paste) term_paste_data_to_slave(term, "\033[200~", 6); - text_from_primary(seat, term, &receive_offer, &receive_offer_done, term); + text_from_primary( + seat, term, false, &receive_offer, &receive_offer_done, term); } static void @@ -2819,7 +2832,7 @@ drop(void *data, struct wl_data_device *wl_data_device) term_paste_data_to_slave(term, "\033[200~", 6); begin_receive_clipboard( - term, read_fd, clipboard->mime_type, + term, false, read_fd, clipboard->mime_type, &receive_dnd, &receive_dnd_done, ctx); /* data offer is now "owned" by the receive context */ diff --git a/selection.h b/selection.h index 26298457..b6ad099a 100644 --- a/selection.h +++ b/selection.h @@ -63,12 +63,12 @@ bool text_to_primary( * point). */ void text_from_clipboard( - struct seat *seat, struct terminal *term, + struct seat *seat, struct terminal *term, bool no_strip, void (*cb)(char *data, size_t size, void *user), void (*done)(void *user), void *user); void text_from_primary( - struct seat *seat, struct terminal *term, + struct seat *seat, struct terminal *term, bool no_strip, void (*cb)(char *data, size_t size, void *user), void (*dont)(void *user), void *user);