On 2020/01/07 23:57, Benjamin Baier wrote: > > there was a commit that adressed the copy from Emacs issue > https://git.claws-mail.org/?p=claws.git;a=commit;h=b910146ff51f32e9501fb4ad5537a47ceb06f154 > > But even better 7 days ago they reverted the main culprit > https://git.claws-mail.org/?p=claws.git;a=commit;h=6759b5272b412a467098d7699c767b8611cde1fd > >revert pasting images as attachments 66fccde959a1b4addee971412b35d4b51d8272b1 > > > >it breaks too many basic and previously working paste actions > > I have backported that commit and lightly tested with my limited use cases. > Works for me and also masks the problem I had with copy&paste > https://marc.info/?l=openbsd-bugs&m=157842725819911&w=2
Makes sense to me, I would like if some other claws-mail users give it a spin before committing it though. I'll reinclude the diff here, mostly because yours was quoted-printable encoded which can be a pain to apply - hopefully this one will stay plaintext. I've also added a header to the patch explaining what it's for. Index: Makefile =================================================================== RCS file: /cvs/ports/mail/claws-mail/Makefile,v retrieving revision 1.124 diff -u -p -r1.124 Makefile --- Makefile 15 Dec 2019 18:36:18 -0000 1.124 +++ Makefile 7 Jan 2020 23:40:51 -0000 @@ -14,7 +14,7 @@ PKGNAME-spamassassin= claws-mail-spamass PKGNAME-pdfviewer= claws-mail-pdfviewer-${V} PKGNAME-gdata= claws-mail-gdata-${V} -REVISION-main= 1 +REVISION-main= 2 REVISION-pdfviewer= 0 REVISION-gdata= 0 Index: patches/patch-src_compose_c =================================================================== RCS file: patches/patch-src_compose_c diff -N patches/patch-src_compose_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_compose_c 7 Jan 2020 23:40:51 -0000 @@ -0,0 +1,281 @@ +$OpenBSD$ + +Adapted from + +From 6759b5272b412a467098d7699c767b8611cde1fd Mon Sep 17 00:00:00 2001 +From: Paul <p...@claws-mail.org> +Date: Tue, 31 Dec 2019 09:58:13 +0000 +Subject: [PATCH] revert pasting images as attachments 66fccde959a1b4addee971412b35d4b51d8272b1 + +Index: src/compose.c +--- src/compose.c.orig ++++ src/compose.c +@@ -10897,196 +10897,58 @@ static void entry_copy_clipboard(GtkWidget *entry) + gtk_clipboard_get(GDK_SELECTION_CLIPBOARD)); + } + +-static void paste_text(Compose *compose, GtkWidget *entry, +- gboolean wrap, GdkAtom clip, GtkTextIter *insert_place, +- const gchar *contents) +-{ +- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(entry)); +- GtkTextMark *mark_start = gtk_text_buffer_get_insert(buffer); +- GtkTextIter start_iter, end_iter; +- gint start, end; +- +- if (contents == NULL) +- return; +- +- /* we shouldn't delete the selection when middle-click-pasting, or we +- * can't mid-click-paste our own selection */ +- if (clip != GDK_SELECTION_PRIMARY) { +- undo_paste_clipboard(GTK_TEXT_VIEW(compose->text), compose->undostruct); +- gtk_text_buffer_delete_selection(buffer, FALSE, TRUE); +- } +- +- if (insert_place == NULL) { +- /* if insert_place isn't specified, insert at the cursor. +- * used for Ctrl-V pasting */ +- gtk_text_buffer_get_iter_at_mark(buffer, &start_iter, mark_start); +- start = gtk_text_iter_get_offset(&start_iter); +- gtk_text_buffer_insert(buffer, &start_iter, contents, strlen(contents)); +- } else { +- /* if insert_place is specified, paste here. +- * used for mid-click-pasting */ +- start = gtk_text_iter_get_offset(insert_place); +- gtk_text_buffer_insert(buffer, insert_place, contents, strlen(contents)); +- if (prefs_common.primary_paste_unselects) +- gtk_text_buffer_select_range(buffer, insert_place, insert_place); +- } +- +- if (!wrap) { +- /* paste unwrapped: mark the paste so it's not wrapped later */ +- end = start + strlen(contents); +- gtk_text_buffer_get_iter_at_offset(buffer, &start_iter, start); +- gtk_text_buffer_get_iter_at_offset(buffer, &end_iter, end); +- gtk_text_buffer_apply_tag_by_name(buffer, "no_wrap", &start_iter, &end_iter); +- } else if (wrap && clip == GDK_SELECTION_PRIMARY) { +- /* rewrap paragraph now (after a mid-click-paste) */ +- mark_start = gtk_text_buffer_get_insert(buffer); +- gtk_text_buffer_get_iter_at_mark(buffer, &start_iter, mark_start); +- gtk_text_iter_backward_char(&start_iter); +- compose_beautify_paragraph(compose, &start_iter, TRUE); +- } +- compose->modified = TRUE; +-} +- +-static void attach_uri_list(Compose *compose, GtkSelectionData *data) +-{ +- GList *list, *tmp; +- int att = 0; +- gchar *warn_files = NULL; +- +- list = uri_list_extract_filenames( +- (const gchar *)gtk_selection_data_get_data(data)); +- for (tmp = list; tmp != NULL; tmp = tmp->next) { +- gchar *utf8_filename = conv_filename_to_utf8((const gchar *)tmp->data); +- gchar *tmp_f = g_strdup_printf("%s%s\n", +- warn_files?warn_files:"", +- utf8_filename); +- g_free(warn_files); +- warn_files = tmp_f; +- att++; +- compose_attach_append +- (compose, (const gchar *)tmp->data, +- utf8_filename, NULL, NULL); +- g_free(utf8_filename); +- } +- if (list) { +- compose_changed_cb(NULL, compose); +- alertpanel_notice(ngettext( +- "The following file has been attached: \n%s", +- "The following files have been attached: \n%s", att), warn_files); +- g_free(warn_files); +- } +- list_free_strings_full(list); +-} +- +-int attach_image(Compose *compose, GtkSelectionData *data, const gchar *subtype) +-{ +- FILE *fp; +- const guchar *contents; +- gchar *file; +- gchar *type; +- size_t len; +- int r; +- +- cm_return_val_if_fail(data != NULL, -1); +- +- contents = gtk_selection_data_get_data(data); +- len = gtk_selection_data_get_length(data); +- +- file = g_strconcat(get_tmp_file(), "-image.", subtype, NULL); +- +- debug_print("writing image to %s\n", file); +- +- if ((fp = claws_fopen(file, "wb")) == NULL) { +- FILE_OP_ERROR(file, "claws_fopen"); +- return -1; +- } +- +- if (claws_fwrite(contents, 1, len, fp) != len) { +- FILE_OP_ERROR(file, "claws_fwrite"); +- claws_fclose(fp); +- claws_unlink(file); +- return -1; +- } +- +- r = claws_safe_fclose(fp); +- +- if (r == EOF) { +- FILE_OP_ERROR(file, "claws_fclose"); +- claws_unlink(file); +- return -1; +- } +- +- type = g_strconcat("image/", subtype, NULL); +- +- compose_attach_append(compose, (const gchar *)file, +- (const gchar *)file, type, NULL); +- +- alertpanel_notice(_("The pasted image has been attached as: \n%s"), file); +- +- g_free(file); +- g_free(type); +- +- return 0; +-} +- + static void entry_paste_clipboard(Compose *compose, GtkWidget *entry, +- gboolean wrap, GdkAtom clip, GtkTextIter *insert_place) ++ gboolean wrap, GdkAtom clip, GtkTextIter *insert_place) + { +- if (GTK_IS_TEXT_VIEW(entry)) { +- GdkAtom types = gdk_atom_intern ("TARGETS", FALSE); +- GdkAtom *targets = NULL; +- int n_targets = 0, i; +- gboolean paste_done = FALSE; +- GtkClipboard *clipboard = gtk_clipboard_get(clip); ++ if (GTK_IS_TEXT_VIEW(entry)) { ++ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(entry)); ++ GtkTextMark *mark_start = gtk_text_buffer_get_insert(buffer); ++ GtkTextIter start_iter, end_iter; ++ gint start, end; ++ gchar *contents = gtk_clipboard_wait_for_text(gtk_clipboard_get(clip)); + +- GtkSelectionData *contents = gtk_clipboard_wait_for_contents( +- clipboard, types); ++ if (contents == NULL) ++ return; + +- if (contents != NULL) { +- gtk_selection_data_get_targets(contents, &targets, &n_targets); +- gtk_selection_data_free(contents); ++ /* we shouldn't delete the selection when middle-click-pasting, or we ++ * can't mid-click-paste our own selection */ ++ if (clip != GDK_SELECTION_PRIMARY) { ++ undo_paste_clipboard(GTK_TEXT_VIEW(compose->text), compose->undostruct); ++ gtk_text_buffer_delete_selection(buffer, FALSE, TRUE); + } + +- for (i = 0; i < n_targets; i++) { +- GdkAtom atom = targets[i]; +- gchar *atom_type = gdk_atom_name(atom); +- +- if (atom_type != NULL) { +- GtkSelectionData *data = gtk_clipboard_wait_for_contents( +- clipboard, atom); +- debug_print("got contents of type %s\n", atom_type); +- if (!strcmp(atom_type, "text/plain")) { +- /* let the default text handler handle it */ +- break; +- } else if (!strcmp(atom_type, "text/uri-list")) { +- attach_uri_list(compose, data); +- +- paste_done = TRUE; +- break; +- } else if (!strncmp(atom_type, "image/", strlen("image/"))) { +- gchar *subtype = g_strdup((gchar *)(strstr(atom_type, "/")+1)); +- debug_print("image of type %s\n", subtype); +- +- attach_image(compose, data, subtype); +- g_free(subtype); +- +- paste_done = TRUE; +- break; +- } +- } +- } +- if (!paste_done) { +- gchar *def_text = gtk_clipboard_wait_for_text(clipboard); +- paste_text(compose, entry, wrap, clip, +- insert_place, def_text); +- g_free(def_text); +- } +- g_free(targets); +- +- } else if (GTK_IS_EDITABLE(entry)) { ++ if (insert_place == NULL) { ++ /* if insert_place isn't specified, insert at the cursor. ++ * used for Ctrl-V pasting */ ++ gtk_text_buffer_get_iter_at_mark(buffer, &start_iter, mark_start); ++ start = gtk_text_iter_get_offset(&start_iter); ++ gtk_text_buffer_insert(buffer, &start_iter, contents, strlen(contents)); ++ } else { ++ /* if insert_place is specified, paste here. ++ * used for mid-click-pasting */ ++ start = gtk_text_iter_get_offset(insert_place); ++ gtk_text_buffer_insert(buffer, insert_place, contents, strlen(contents)); ++ if (prefs_common.primary_paste_unselects) ++ gtk_text_buffer_select_range(buffer, insert_place, insert_place); ++ } ++ ++ if (!wrap) { ++ /* paste unwrapped: mark the paste so it's not wrapped later */ ++ end = start + strlen(contents); ++ gtk_text_buffer_get_iter_at_offset(buffer, &start_iter, start); ++ gtk_text_buffer_get_iter_at_offset(buffer, &end_iter, end); ++ gtk_text_buffer_apply_tag_by_name(buffer, "no_wrap", &start_iter, &end_iter); ++ } else if (wrap && clip == GDK_SELECTION_PRIMARY) { ++ /* rewrap paragraph now (after a mid-click-paste) */ ++ mark_start = gtk_text_buffer_get_insert(buffer); ++ gtk_text_buffer_get_iter_at_mark(buffer, &start_iter, mark_start); ++ gtk_text_iter_backward_char(&start_iter); ++ compose_beautify_paragraph(compose, &start_iter, TRUE); ++ } ++ } else if (GTK_IS_EDITABLE(entry)) + gtk_editable_paste_clipboard (GTK_EDITABLE(entry)); +- compose->modified = TRUE; +- } ++ ++ compose->modified = TRUE; + } + + static void entry_allsel(GtkWidget *entry) +@@ -11746,13 +11608,25 @@ static void compose_attach_drag_received_cb (GtkWidget + gpointer user_data) + { + Compose *compose = (Compose *)user_data; ++ GList *list, *tmp; + GdkAtom type; + + type = gtk_selection_data_get_data_type(data); + if ((gdk_atom_name(type) && !strcmp(gdk_atom_name(type), "text/uri-list")) + && gtk_drag_get_source_widget(context) != + summary_get_main_widget(mainwindow_get_mainwindow()->summaryview)) { +- attach_uri_list(compose, data); ++ list = uri_list_extract_filenames( ++ (const gchar *)gtk_selection_data_get_data(data)); ++ for (tmp = list; tmp != NULL; tmp = tmp->next) { ++ gchar *utf8_filename = conv_filename_to_utf8((const gchar *)tmp->data); ++ compose_attach_append ++ (compose, (const gchar *)tmp->data, ++ utf8_filename, NULL, NULL); ++ g_free(utf8_filename); ++ } ++ if (list) ++ compose_changed_cb(NULL, compose); ++ list_free_strings_full(list); + } else if (gtk_drag_get_source_widget(context) + == summary_get_main_widget(mainwindow_get_mainwindow()->summaryview)) { + /* comes from our summaryview */