diff --git a/0001-I-966-Composer-Correct-caret-placement-around-signat.patch b/0001-I-966-Composer-Correct-caret-placement-around-signat.patch new file mode 100644 index 0000000..fef2437 --- /dev/null +++ b/0001-I-966-Composer-Correct-caret-placement-around-signat.patch @@ -0,0 +1,471 @@ +From 63102bd4672b4182e824963608ce73e0bcc417d2 Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Thu, 4 Jun 2020 17:49:22 +0200 +Subject: [PATCH 1/5] I#966 - Composer: Correct caret placement around + signature wrapper + +Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/966 +--- + data/webkit/e-editor.js | 96 +++++++++++++-------- + src/composer/e-composer-private.c | 54 ++++++++++-- + src/composer/e-composer-private.h | 2 + + src/e-util/e-content-editor.c | 2 + + src/e-util/e-content-editor.h | 2 + + src/e-util/e-mail-signature-combo-box.c | 6 ++ + src/e-util/test-html-editor-units-bugs.c | 1 + + src/modules/webkit-editor/e-webkit-editor.c | 14 ++- + 8 files changed, 121 insertions(+), 56 deletions(-) + +diff --git a/data/webkit/e-editor.js b/data/webkit/e-editor.js +index 0451093a54..61dba68c94 100644 +--- a/data/webkit/e-editor.js ++++ b/data/webkit/e-editor.js +@@ -79,7 +79,6 @@ var EvoEditor = { + UNICODE_SMILEYS : false, + WRAP_QUOTED_TEXT_IN_REPLIES : true, + START_BOTTOM : false, +- TOP_SIGNATURE : false, + + FORCE_NO : 0, + FORCE_YES : 1, +@@ -4719,6 +4718,31 @@ EvoEditor.GetCurrentSignatureUid = function() + return ""; + } + ++EvoEditor.insertEmptyParagraphBefore = function(beforeNode) ++{ ++ var node = document.createElement("DIV"); ++ ++ node.appendChild(document.createElement("BR")); ++ document.body.insertBefore(node, beforeNode); ++ EvoEditor.maybeUpdateParagraphWidth(node); ++ ++ return node; ++} ++ ++EvoEditor.scrollIntoSelection = function() ++{ ++ var node = document.getSelection().focusNode; ++ ++ if (node) { ++ if (node.nodeType != node.ELEMENT_NODE) ++ node = node.parentElement; ++ ++ if (node && node.scrollIntoView != undefined) { ++ node.scrollIntoView(); ++ } ++ } ++} ++ + EvoEditor.removeUnwantedTags = function(parent) + { + if (!parent) +@@ -4735,12 +4759,9 @@ EvoEditor.removeUnwantedTags = function(parent) + } + } + +-EvoEditor.InsertSignature = function(content, isHTML, uid, fromMessage, checkChanged, ignoreNextChange, startBottom, topSignature, addDelimiter) ++EvoEditor.InsertSignature = function(content, isHTML, canRepositionCaret, uid, fromMessage, checkChanged, ignoreNextChange, startBottom, topSignature, addDelimiter) + { +- var sigSpan, node, scrollX, scrollY; +- +- scrollX = window.scrollX; +- scrollY = window.scrollY; ++ var sigSpan, node; + + sigSpan = document.createElement("SPAN"); + sigSpan.className = "-x-evo-signature"; +@@ -4819,8 +4840,9 @@ EvoEditor.InsertSignature = function(content, isHTML, uid, fromMessage, checkCha + if (checkChanged) { + /* Normalize the signature that we want to insert as the one in the + * message already is normalized. */ +- webkit_dom_node_normalize (WEBKIT_DOM_NODE (signature_to_insert)); +- if (!webkit_dom_node_is_equal_node (WEBKIT_DOM_NODE (signature_to_insert), signature)) { ++ signature.normalize(); ++ ++ if (signature.firstElementChild && !signature.firstElementChild.isEqualNode(sigSpan)) { + /* Signature in the body is different than the one with the + * same id, so set the active signature to None and leave + * the signature that is in the body. */ +@@ -4835,7 +4857,7 @@ EvoEditor.InsertSignature = function(content, isHTML, uid, fromMessage, checkCha + if (signature.hasAttribute("name")) { + id = signature.getAttribute("name"); + signature.id = id; +- signature.removeAttribute(name); ++ signature.removeAttribute("name"); + } else { + id = signature.id; + } +@@ -4902,7 +4924,9 @@ EvoEditor.InsertSignature = function(content, isHTML, uid, fromMessage, checkCha + + EvoUndoRedo.StartRecord(EvoUndoRedo.RECORD_KIND_CUSTOM, "InsertSignature::new-changes", document.body, document.body, EvoEditor.CLAIM_CONTENT_FLAG_SAVE_HTML); + try { +- if (topSignature) { ++ var emptyDocument = !document.body.firstElementChild || !document.body.firstElementChild.nextElementSibling; ++ ++ if (topSignature && !emptyDocument) { + document.body.insertBefore(useWrapper, document.body.firstChild); + + node = document.createElement("DIV"); +@@ -4910,7 +4934,15 @@ EvoEditor.InsertSignature = function(content, isHTML, uid, fromMessage, checkCha + node.className = "-x-evo-top-signature-spacer"; + + document.body.insertBefore(node, useWrapper.nextSibling); ++ ++ // Insert empty paragraph before the signature ++ EvoEditor.insertEmptyParagraphBefore(document.body.firstChild); + } else { ++ if (!startBottom && !emptyDocument) { ++ // Insert empty paragraph before the signature ++ EvoEditor.insertEmptyParagraphBefore(null); ++ } ++ + document.body.appendChild(useWrapper); + } + } finally { +@@ -4920,36 +4952,27 @@ EvoEditor.InsertSignature = function(content, isHTML, uid, fromMessage, checkCha + + fromMessage = false; + +- // Position the caret and scroll to it +- if (startBottom) { +- if (topSignature) { +- document.getSelection().setPosition(document.body.lastChild, 0); +- } else if (useWrapper.previousSibling) { +- document.getSelection().setPosition(useWrapper.previousSibling, 0); ++ if (canRepositionCaret) { ++ // Position the caret and scroll to it ++ if (startBottom) { ++ if (topSignature) { ++ document.getSelection().setPosition(document.body.lastChild, 0); ++ } else if (useWrapper.previousSibling) { ++ document.getSelection().setPosition(useWrapper.previousSibling, 0); ++ } else { ++ document.getSelection().setPosition(useWrapper, 0); ++ } + } else { +- document.getSelection().setPosition(useWrapper, 0); ++ document.getSelection().setPosition(document.body.firstChild, 0); + } +- } else { +- document.getSelection().setPosition(document.body.firstChild, 0); +- } +- +- node = document.getSelection().anchorNode; + +- if (node) { +- if (node.nodeType != node.ELEMENT_NODE) +- node = node.parentElement; +- +- if (node && node.scrollIntoViewIfNeeded != undefined) +- node.scrollIntoViewIfNeeded(); ++ EvoEditor.scrollIntoSelection(); + } + } + } finally { + EvoUndoRedo.StopRecord(EvoUndoRedo.RECORD_KIND_GROUP, "InsertSignature"); + } + +- // the above changes can cause change of the scroll offset, thus restore it +- window.scrollTo(scrollX, scrollY); +- + var res = []; + + res["fromMessage"] = fromMessage; +@@ -5716,15 +5739,12 @@ EvoEditor.processLoadedContent = function() + node.scrollIntoView(); + } + +- if (EvoEditor.START_BOTTOM) { +- var node = document.createElement("DIV"); +- +- node.appendChild(document.createElement("BR")); +- document.body.appendChild(node); +- EvoEditor.maybeUpdateParagraphWidth(node); +- ++ if (EvoEditor.START_BOTTOM && document.body.firstElementChild && document.body.firstElementChild.nextElementSibling) { ++ node = EvoEditor.insertEmptyParagraphBefore(null); + document.getSelection().setPosition(node, 0); + node.scrollIntoView(); ++ } else { ++ EvoEditor.scrollIntoSelection(); + } + } + +diff --git a/src/composer/e-composer-private.c b/src/composer/e-composer-private.c +index e4a1c17924..77d1ca7918 100644 +--- a/src/composer/e-composer-private.c ++++ b/src/composer/e-composer-private.c +@@ -548,6 +548,8 @@ e_composer_private_finalize (EMsgComposer *composer) + g_ptr_array_foreach (array, (GFunc) g_free, NULL); + g_ptr_array_free (array, TRUE); + ++ g_clear_object (&composer->priv->load_signature_cancellable); ++ + g_free (composer->priv->charset); + g_free (composer->priv->mime_type); + g_free (composer->priv->mime_body); +@@ -769,11 +771,29 @@ e_composer_selection_is_image_uris (EMsgComposer *composer, + return all_image_uris; + } + ++typedef struct _UpdateSignatureData { ++ EMsgComposer *composer; ++ gboolean can_reposition_caret; ++} UpdateSignatureData; ++ ++static void ++update_signature_data_free (gpointer ptr) ++{ ++ UpdateSignatureData *usd = ptr; ++ ++ if (usd) { ++ g_clear_object (&usd->composer); ++ g_slice_free (UpdateSignatureData, usd); ++ } ++} ++ + static void + composer_load_signature_cb (EMailSignatureComboBox *combo_box, +- GAsyncResult *result, +- EMsgComposer *composer) ++ GAsyncResult *result, ++ gpointer user_data) + { ++ UpdateSignatureData *usd = user_data; ++ EMsgComposer *composer = usd->composer; + gchar *contents = NULL, *new_signature_id; + gsize length = 0; + gboolean is_html; +@@ -786,15 +806,18 @@ composer_load_signature_cb (EMailSignatureComboBox *combo_box, + + /* FIXME Use an EAlert here. */ + if (error != NULL) { +- g_warning ("%s: %s", G_STRFUNC, error->message); ++ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) ++ g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); +- g_object_unref (composer); ++ update_signature_data_free (usd); + return; + } + ++ g_clear_object (&composer->priv->load_signature_cancellable); ++ + if (composer->priv->ignore_next_signature_change) { + composer->priv->ignore_next_signature_change = FALSE; +- g_object_unref (composer); ++ update_signature_data_free (usd); + return; + } + +@@ -805,6 +828,7 @@ composer_load_signature_cb (EMailSignatureComboBox *combo_box, + cnt_editor, + contents, + is_html, ++ usd->can_reposition_caret, + gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box)), + &composer->priv->set_signature_from_message, + &composer->priv->check_if_signature_is_changed, +@@ -833,7 +857,7 @@ composer_load_signature_cb (EMailSignatureComboBox *combo_box, + + g_free (new_signature_id); + g_free (contents); +- g_object_unref (composer); ++ update_signature_data_free (usd); + } + + static void +@@ -853,9 +877,15 @@ e_composer_update_signature (EMsgComposer *composer) + EMailSignatureComboBox *combo_box; + EHTMLEditor *editor; + EContentEditor *cnt_editor; ++ UpdateSignatureData *usd; + + g_return_if_fail (E_IS_MSG_COMPOSER (composer)); + ++ if (composer->priv->load_signature_cancellable) { ++ g_cancellable_cancel (composer->priv->load_signature_cancellable); ++ g_clear_object (&composer->priv->load_signature_cancellable); ++ } ++ + /* Do nothing if we're redirecting a message or we disabled + * the signature on purpose */ + if (composer->priv->redirect || composer->priv->disable_signature) +@@ -874,13 +904,19 @@ e_composer_update_signature (EMsgComposer *composer) + return; + } + ++ composer->priv->load_signature_cancellable = g_cancellable_new (); ++ ++ usd = g_slice_new (UpdateSignatureData); ++ usd->composer = g_object_ref (composer); ++ usd->can_reposition_caret = e_msg_composer_get_is_reply_or_forward (composer) && ++ !gtk_widget_get_realized (GTK_WIDGET (composer)); ++ + /* XXX Signature files should be local and therefore load quickly, + * so while we do load them asynchronously we don't allow for + * user cancellation and we keep the composer alive until the + * asynchronous loading is complete. */ + e_mail_signature_combo_box_load_selected ( +- combo_box, G_PRIORITY_DEFAULT, NULL, ++ combo_box, G_PRIORITY_DEFAULT, composer->priv->load_signature_cancellable, + (GAsyncReadyCallback) composer_load_signature_cb, +- g_object_ref (composer)); ++ usd); + } +- +diff --git a/src/composer/e-composer-private.h b/src/composer/e-composer-private.h +index c415974cbc..19c1aefb64 100644 +--- a/src/composer/e-composer-private.h ++++ b/src/composer/e-composer-private.h +@@ -124,6 +124,8 @@ struct _EMsgComposerPrivate { + + guint content_hash_ref_count; /* when reaches 0, the content_hash is freed; to be able to reuse it */ + EContentEditorContentHash *content_hash; ++ ++ GCancellable *load_signature_cancellable; + }; + + void e_composer_private_constructed (EMsgComposer *composer); +diff --git a/src/e-util/e-content-editor.c b/src/e-util/e-content-editor.c +index 9f69638c39..ed07be45b2 100644 +--- a/src/e-util/e-content-editor.c ++++ b/src/e-util/e-content-editor.c +@@ -2400,6 +2400,7 @@ gchar * + e_content_editor_insert_signature (EContentEditor *editor, + const gchar *content, + gboolean is_html, ++ gboolean can_reposition_caret, + const gchar *signature_id, + gboolean *set_signature_from_message, + gboolean *check_if_signature_is_changed, +@@ -2417,6 +2418,7 @@ e_content_editor_insert_signature (EContentEditor *editor, + editor, + content, + is_html, ++ can_reposition_caret, + signature_id, + set_signature_from_message, + check_if_signature_is_changed, +diff --git a/src/e-util/e-content-editor.h b/src/e-util/e-content-editor.h +index ae00b147f4..eaa7aab44d 100644 +--- a/src/e-util/e-content-editor.h ++++ b/src/e-util/e-content-editor.h +@@ -145,6 +145,7 @@ struct _EContentEditorInterface { + gchar * (*insert_signature) (EContentEditor *editor, + const gchar *content, + gboolean is_html, ++ gboolean can_reposition_caret, + const gchar *signature_id, + gboolean *set_signature_from_message, + gboolean *check_if_signature_is_changed, +@@ -644,6 +645,7 @@ gchar * e_content_editor_insert_signature + (EContentEditor *editor, + const gchar *content, + gboolean is_html, ++ gboolean can_reposition_caret, + const gchar *signature_id, + gboolean *set_signature_from_message, + gboolean *check_if_signature_is_changed, +diff --git a/src/e-util/e-mail-signature-combo-box.c b/src/e-util/e-mail-signature-combo-box.c +index 8ba4428135..7dac48bc1e 100644 +--- a/src/e-util/e-mail-signature-combo-box.c ++++ b/src/e-util/e-mail-signature-combo-box.c +@@ -615,6 +615,7 @@ e_mail_signature_combo_box_set_identity (EMailSignatureComboBox *combo_box, + typedef struct _LoadContext LoadContext; + + struct _LoadContext { ++ GCancellable *cancellable; + gchar *contents; + gsize length; + gboolean is_html; +@@ -623,6 +624,7 @@ struct _LoadContext { + static void + load_context_free (LoadContext *context) + { ++ g_clear_object (&context->cancellable); + g_free (context->contents); + g_slice_free (LoadContext, context); + } +@@ -761,6 +763,7 @@ e_mail_signature_combo_box_load_selected (EMailSignatureComboBox *combo_box, + g_return_if_fail (E_IS_MAIL_SIGNATURE_COMBO_BOX (combo_box)); + + context = g_slice_new0 (LoadContext); ++ context->cancellable = cancellable ? g_object_ref (cancellable) : NULL; + + simple = g_simple_async_result_new ( + G_OBJECT (combo_box), callback, user_data, +@@ -824,6 +827,9 @@ e_mail_signature_combo_box_load_selected_finish (EMailSignatureComboBox *combo_b + if (g_simple_async_result_propagate_error (simple, error)) + return FALSE; + ++ if (g_cancellable_set_error_if_cancelled (context->cancellable, error)) ++ return FALSE; ++ + if (contents != NULL) { + *contents = context->contents; + context->contents = NULL; +diff --git a/src/e-util/test-html-editor-units-bugs.c b/src/e-util/test-html-editor-units-bugs.c +index a67b8a478d..8ca3e532d5 100644 +--- a/src/e-util/test-html-editor-units-bugs.c ++++ b/src/e-util/test-html-editor-units-bugs.c +@@ -712,6 +712,7 @@ test_bug_772513 (TestFixture *fixture) + cnt_editor, + "", + FALSE, ++ FALSE, + "none", + &set_signature_from_message, + &check_if_signature_is_changed, +diff --git a/src/modules/webkit-editor/e-webkit-editor.c b/src/modules/webkit-editor/e-webkit-editor.c +index a300f3b980..304781d626 100644 +--- a/src/modules/webkit-editor/e-webkit-editor.c ++++ b/src/modules/webkit-editor/e-webkit-editor.c +@@ -2470,10 +2470,6 @@ webkit_editor_set_top_signature (EWebKitEditor *wk_editor, + + wk_editor->priv->top_signature = value; + +- e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable, +- "EvoEditor.TOP_SIGNATURE = %x;", +- e_webkit_editor_three_state_to_bool (value, "composer-top-signature")); +- + g_object_notify (G_OBJECT (wk_editor), "top-signature"); + } + +@@ -2579,6 +2575,7 @@ static gchar * + webkit_editor_insert_signature (EContentEditor *editor, + const gchar *content, + gboolean is_html, ++ gboolean can_reposition_caret, + const gchar *signature_id, + gboolean *set_signature_from_message, + gboolean *check_if_signature_is_changed, +@@ -2597,9 +2594,10 @@ webkit_editor_insert_signature (EContentEditor *editor, + } + + jsc_value = webkit_editor_call_jsc_sync (E_WEBKIT_EDITOR (editor), +- "EvoEditor.InsertSignature(%s, %x, %s, %x, %x, %x, %x, %x, %x);", ++ "EvoEditor.InsertSignature(%s, %x, %x, %s, %x, %x, %x, %x, %x, %x);", + content ? content : "", + is_html, ++ can_reposition_caret, + signature_id, + *set_signature_from_message, + *check_if_signature_is_changed, +@@ -4798,10 +4796,8 @@ webkit_editor_load_changed_cb (EWebKitEditor *wk_editor, + return; + + e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable, +- "EvoEditor.START_BOTTOM = %x;\n" +- "EvoEditor.TOP_SIGNATURE = %x;", +- e_webkit_editor_three_state_to_bool (wk_editor->priv->start_bottom, "composer-reply-start-bottom"), +- e_webkit_editor_three_state_to_bool (wk_editor->priv->top_signature, "composer-top-signature")); ++ "EvoEditor.START_BOTTOM = %x;", ++ e_webkit_editor_three_state_to_bool (wk_editor->priv->start_bottom, "composer-reply-start-bottom")); + + /* Dispatch queued operations - as we are using this just for load + * operations load just the latest request and throw away the rest. */ +-- +2.27.0 + diff --git a/0002-I-969-Workaround-freeze-on-drag-of-message-over-comp.patch b/0002-I-969-Workaround-freeze-on-drag-of-message-over-comp.patch new file mode 100644 index 0000000..e938e4b --- /dev/null +++ b/0002-I-969-Workaround-freeze-on-drag-of-message-over-comp.patch @@ -0,0 +1,58 @@ +From edfd6aa9b513c7347e930d44012c53123cf88a74 Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Fri, 5 Jun 2020 13:40:41 +0200 +Subject: [PATCH 2/5] I#969 - Workaround freeze on drag of message over + composer body + +Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/969 +--- + src/modules/webkit-editor/e-webkit-editor.c | 26 +++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/src/modules/webkit-editor/e-webkit-editor.c b/src/modules/webkit-editor/e-webkit-editor.c +index 304781d626..2a91782e41 100644 +--- a/src/modules/webkit-editor/e-webkit-editor.c ++++ b/src/modules/webkit-editor/e-webkit-editor.c +@@ -5101,6 +5101,28 @@ webkit_editor_drag_leave_cb (EWebKitEditor *wk_editor, + g_signal_stop_emission_by_name (GTK_WIDGET (wk_editor), "drag-leave"); + } + ++static gboolean ++webkit_editor_drag_motion_cb (GtkWidget *widget, ++ GdkDragContext *context, ++ gint x, ++ gint y, ++ guint time, ++ gpointer user_data) ++{ ++ GdkAtom chosen; ++ ++ chosen = gtk_drag_dest_find_target (widget, context, NULL); ++ ++ /* This is when dragging message from the message list, which can eventually freeze ++ Evolution, if PDF file format is set, when processes by WebKitGTK itself. */ ++ if (chosen != GDK_NONE && chosen == gdk_atom_intern ("x-uid-list", TRUE)) { ++ gdk_drag_status (context, GDK_ACTION_COPY, time); ++ return TRUE; ++ } ++ ++ return FALSE; ++} ++ + static gboolean + webkit_editor_drag_drop_cb (EWebKitEditor *wk_editor, + GdkDragContext *context, +@@ -5533,6 +5555,10 @@ e_webkit_editor_init (EWebKitEditor *wk_editor) + wk_editor, "drag-drop", + G_CALLBACK (webkit_editor_drag_drop_cb), NULL); + ++ g_signal_connect ( ++ wk_editor, "drag-motion", ++ G_CALLBACK (webkit_editor_drag_motion_cb), NULL); ++ + g_signal_connect ( + wk_editor, "web-process-crashed", + G_CALLBACK (webkit_editor_web_process_crashed_cb), NULL); +-- +2.27.0 + diff --git a/0003-I-975-Composer-Some-user-options-not-propagated-to-t.patch b/0003-I-975-Composer-Some-user-options-not-propagated-to-t.patch new file mode 100644 index 0000000..9f587e3 --- /dev/null +++ b/0003-I-975-Composer-Some-user-options-not-propagated-to-t.patch @@ -0,0 +1,39 @@ +From b8acc612b838e7354c05efa8348954841566b26b Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Mon, 8 Jun 2020 09:17:32 +0200 +Subject: [PATCH 3/5] I#975 - Composer: Some user options not propagated to the + WebProcess + +Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/975 +--- + src/modules/webkit-editor/e-webkit-editor.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/src/modules/webkit-editor/e-webkit-editor.c b/src/modules/webkit-editor/e-webkit-editor.c +index 2a91782e41..ca8bf6e65d 100644 +--- a/src/modules/webkit-editor/e-webkit-editor.c ++++ b/src/modules/webkit-editor/e-webkit-editor.c +@@ -4796,8 +4796,18 @@ webkit_editor_load_changed_cb (EWebKitEditor *wk_editor, + return; + + e_web_view_jsc_run_script (WEBKIT_WEB_VIEW (wk_editor), wk_editor->priv->cancellable, +- "EvoEditor.START_BOTTOM = %x;", +- e_webkit_editor_three_state_to_bool (wk_editor->priv->start_bottom, "composer-reply-start-bottom")); ++ "EvoEditor.NORMAL_PARAGRAPH_WIDTH = %d;" ++ "EvoEditor.START_BOTTOM = %x;" ++ "EvoEditor.MAGIC_LINKS = %x;" ++ "EvoEditor.MAGIC_SMILEYS = %x;" ++ "EvoEditor.UNICODE_SMILEYS = %x;" ++ "EvoEditor.WRAP_QUOTED_TEXT_IN_REPLIES = %x;", ++ wk_editor->priv->normal_paragraph_width, ++ e_webkit_editor_three_state_to_bool (wk_editor->priv->start_bottom, "composer-reply-start-bottom"), ++ wk_editor->priv->magic_links, ++ wk_editor->priv->magic_smileys, ++ wk_editor->priv->unicode_smileys, ++ wk_editor->priv->wrap_quoted_text_in_replies); + + /* Dispatch queued operations - as we are using this just for load + * operations load just the latest request and throw away the rest. */ +-- +2.27.0 + diff --git a/0004-I-982-Message-contains-search-broken-in-3.36.3.patch b/0004-I-982-Message-contains-search-broken-in-3.36.3.patch new file mode 100644 index 0000000..722551a --- /dev/null +++ b/0004-I-982-Message-contains-search-broken-in-3.36.3.patch @@ -0,0 +1,235 @@ +From fb5dfe31f4985cf3b42eba899fd71f3cf2d256bf Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Thu, 11 Jun 2020 19:06:29 +0200 +Subject: [PATCH 4/5] I#982 - 'Message contains'-search broken in 3.36.3 + +Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/982 +--- + src/e-util/e-filter-rule.c | 111 +++++++++++++++++++++++---- + src/mail/message-list.c | 18 ++--- + src/mail/searchtypes.xml.in | 8 +- + src/modules/mail/e-mail-shell-view.c | 2 +- + 4 files changed, 107 insertions(+), 32 deletions(-) + +diff --git a/src/e-util/e-filter-rule.c b/src/e-util/e-filter-rule.c +index 2ec1d8dfc1..72bfc6af5e 100644 +--- a/src/e-util/e-filter-rule.c ++++ b/src/e-util/e-filter-rule.c +@@ -811,9 +811,16 @@ filter_rule_xml_decode (EFilterRule *rule, + } + + static void +-filter_rule_build_code (EFilterRule *rule, +- GString *out) ++filter_rule_build_code_for_parts (EFilterRule *rule, ++ GList *parts, ++ gboolean without_match_all, ++ gboolean force_match_all, ++ GString *out) + { ++ g_return_if_fail (rule != NULL); ++ g_return_if_fail (parts != NULL); ++ g_return_if_fail (out != NULL); ++ + switch (rule->threading) { + case E_FILTER_THREAD_NONE: + break; +@@ -831,25 +838,97 @@ filter_rule_build_code (EFilterRule *rule, + break; + } + +- if (rule->threading != E_FILTER_THREAD_NONE) ++ if ((rule->threading != E_FILTER_THREAD_NONE && !without_match_all) || force_match_all) + g_string_append (out, "(match-all "); + +- switch (rule->grouping) { +- case E_FILTER_GROUP_ALL: +- g_string_append (out, " (and\n "); +- break; +- case E_FILTER_GROUP_ANY: +- g_string_append (out, " (or\n "); +- break; +- default: +- g_warning ("Invalid grouping"); ++ if (parts->next) { ++ switch (rule->grouping) { ++ case E_FILTER_GROUP_ALL: ++ g_string_append (out, " (and\n "); ++ break; ++ case E_FILTER_GROUP_ANY: ++ g_string_append (out, " (or\n "); ++ break; ++ default: ++ g_warning ("Invalid grouping"); ++ } ++ } ++ ++ e_filter_part_build_code_list (parts, out); ++ ++ if (parts->next) ++ g_string_append (out, ")\n"); ++ ++ if (rule->threading != E_FILTER_THREAD_NONE) { ++ if (without_match_all && !force_match_all) ++ g_string_append (out, ")\n"); ++ else ++ g_string_append (out, "))\n"); ++ } else if (force_match_all) { ++ g_string_append (out, ")\n"); ++ } ++} ++ ++static void ++filter_rule_build_code (EFilterRule *rule, ++ GString *out) ++{ ++ GList *link; ++ gboolean has_body_search = FALSE; ++ ++ if (!rule->parts) ++ return; ++ ++ for (link = rule->parts; link && !has_body_search; link = g_list_next (link)) { ++ EFilterPart *part = link->data; ++ ++ has_body_search = g_strcmp0 (part->name, "body") == 0; + } + +- e_filter_part_build_code_list (rule->parts, out); +- g_string_append (out, ")\n"); ++ if (has_body_search) { ++ GList *body_searches = NULL, *other_searches = NULL; + +- if (rule->threading != E_FILTER_THREAD_NONE) +- g_string_append (out, "))\n"); ++ for (link = rule->parts; link; link = g_list_next (link)) { ++ EFilterPart *part = link->data; ++ ++ if (g_strcmp0 (part->name, "body") == 0) { ++ body_searches = g_list_prepend (body_searches, part); ++ } else { ++ other_searches = g_list_prepend (other_searches, part); ++ } ++ } ++ ++ if (other_searches && body_searches) { ++ switch (rule->grouping) { ++ case E_FILTER_GROUP_ALL: ++ g_string_append (out, "(and "); ++ break; ++ case E_FILTER_GROUP_ANY: ++ g_string_append (out, "(or "); ++ break; ++ default: ++ g_warning ("Invalid grouping"); ++ } ++ ++ body_searches = g_list_reverse (body_searches); ++ other_searches = g_list_reverse (other_searches); ++ ++ filter_rule_build_code_for_parts (rule, other_searches, FALSE, TRUE, out); ++ ++ g_string_append_c (out, ' '); ++ ++ filter_rule_build_code_for_parts (rule, body_searches, TRUE, FALSE, out); ++ ++ g_string_append_c (out, ')'); ++ } else { ++ filter_rule_build_code_for_parts (rule, rule->parts, FALSE, FALSE, out); ++ } ++ ++ g_list_free (body_searches); ++ g_list_free (other_searches); ++ } else { ++ filter_rule_build_code_for_parts (rule, rule->parts, FALSE, FALSE, out); ++ } + } + + static void +diff --git a/src/mail/message-list.c b/src/mail/message-list.c +index 01b7528850..2c5741a139 100644 +--- a/src/mail/message-list.c ++++ b/src/mail/message-list.c +@@ -6176,7 +6176,7 @@ message_list_regen_thread (GSimpleAsyncResult *simple, + /* The 'expr' should be enclosed in "(match-all ...)", thus the search traverses + folder content, but also try to not repeat it, to avoid unnecessary performance hits. */ + if (regen_data->search != NULL) { +- gboolean is_match_all = g_str_has_prefix (regen_data->search, "(match-all "); ++ gboolean is_match_all = g_str_has_prefix (regen_data->search, "(match-all ") && !strstr (regen_data->search, "(body-contains "); + gboolean is_match_threads = strstr (regen_data->search, "(match-threads ") != NULL; + + if (expr->len == 0) { +@@ -6186,25 +6186,21 @@ message_list_regen_thread (GSimpleAsyncResult *simple, + g_string_prepend (expr, "(match-all "); + g_string_append_c (expr, ')'); + } +- } else if (is_match_threads) { ++ } else if (is_match_threads || !is_match_all) { + /* The "match-threads" cannot be below "match-all". */ + g_string_prepend (expr, "(and (match-all "); + g_string_append (expr, ") "); + g_string_append (expr, regen_data->search); + g_string_append_c (expr, ')'); + } else { ++ const gchar *stripped_search = regen_data->search + 11; /* strlen ("(match-all ") */ ++ gint len = strlen (stripped_search); ++ + g_string_prepend (expr, "(match-all (and "); + g_string_append_c (expr, ' '); + +- if (is_match_all) { +- const gchar *stripped_search = regen_data->search + 11; /* strlen ("(match-all ") */ +- gint len = strlen (stripped_search); +- +- if (len > 0 && stripped_search[len - 1] == ')') { +- g_string_append_len (expr, stripped_search, len - 1); +- } else { +- g_string_append (expr, regen_data->search); +- } ++ if (len > 0 && stripped_search[len - 1] == ')') { ++ g_string_append_len (expr, stripped_search, len - 1); + } else { + g_string_append (expr, regen_data->search); + } +diff --git a/src/mail/searchtypes.xml.in b/src/mail/searchtypes.xml.in +index e03e28e60f..d0362d59dd 100644 +--- a/src/mail/searchtypes.xml.in ++++ b/src/mail/searchtypes.xml.in +@@ -728,10 +728,6 @@ + + + +- +- +- +- + + + +@@ -740,6 +736,10 @@ + + + ++ ++ ++ ++ + + + +diff --git a/src/modules/mail/e-mail-shell-view.c b/src/modules/mail/e-mail-shell-view.c +index 8dcca65eca..be72de3441 100644 +--- a/src/modules/mail/e-mail-shell-view.c ++++ b/src/modules/mail/e-mail-shell-view.c +@@ -752,7 +752,7 @@ filter: + + /* Apply selected filter. */ + +- if (query && *query && !g_str_has_prefix (query, "(match-all ") && !strstr (query, "(match-threads ")) { ++ if (query && *query && !strstr (query, "(match-all ") && !strstr (query, "(match-threads ")) { + /* Make sure the query is enclosed in "(match-all ...)", to traverse the folders' content */ + temp = g_strconcat ("(match-all ", query, ")", NULL); + g_free (query); +-- +2.27.0 + diff --git a/0005-I-979-Undeletable-empty-item-in-folder-list.patch b/0005-I-979-Undeletable-empty-item-in-folder-list.patch new file mode 100644 index 0000000..4932196 --- /dev/null +++ b/0005-I-979-Undeletable-empty-item-in-folder-list.patch @@ -0,0 +1,137 @@ +From c72c70e1b3eb9142e98b73ac06a38fedda7fb7d2 Mon Sep 17 00:00:00 2001 +From: Milan Crha +Date: Thu, 18 Jun 2020 09:54:55 +0200 +Subject: [PATCH 5/5] I#979 - Undeletable empty item in folder list + +Closes https://gitlab.gnome.org/GNOME/evolution/-/issues/979 +--- + src/mail/em-folder-tree-model.c | 34 ++++++++++++++++++--------------- + src/mail/em-folder-tree-model.h | 2 +- + src/mail/em-folder-tree.c | 5 ++--- + 3 files changed, 22 insertions(+), 19 deletions(-) + +diff --git a/src/mail/em-folder-tree-model.c b/src/mail/em-folder-tree-model.c +index d43fb1e1c4..0d3e50fedc 100644 +--- a/src/mail/em-folder-tree-model.c ++++ b/src/mail/em-folder-tree-model.c +@@ -1385,7 +1385,7 @@ em_folder_tree_model_set_session (EMFolderTreeModel *model, + g_object_notify (G_OBJECT (model), "session"); + } + +-void ++gboolean + em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, + GtkTreeIter *iter, + CamelStore *store, +@@ -1414,18 +1414,18 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, + gboolean folder_is_outbox = FALSE; + gchar *uri; + +- g_return_if_fail (EM_IS_FOLDER_TREE_MODEL (model)); +- g_return_if_fail (iter != NULL); +- g_return_if_fail (CAMEL_IS_STORE (store)); +- g_return_if_fail (fi != NULL); ++ g_return_val_if_fail (EM_IS_FOLDER_TREE_MODEL (model), FALSE); ++ g_return_val_if_fail (iter != NULL, FALSE); ++ g_return_val_if_fail (CAMEL_IS_STORE (store), FALSE); ++ g_return_val_if_fail (fi != NULL, FALSE); + + si = folder_tree_model_store_index_lookup (model, store); +- g_return_if_fail (si != NULL); ++ g_return_val_if_fail (si != NULL, FALSE); + + /* Make sure we don't already know about it. */ + if (g_hash_table_lookup (si->full_hash, fi->full_name)) { + store_info_unref (si); +- return; ++ return FALSE; + } + + if (!si->loaded) +@@ -1568,7 +1568,7 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, + g_signal_emit (model, signals[LOADED_ROW], 0, path, iter); + g_signal_emit (model, signals[LOADING_ROW], 0, path, iter); + gtk_tree_path_free (path); +- return; ++ return TRUE; + } + + if (fi->child) { +@@ -1587,8 +1587,9 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, + emitted = TRUE; + } + +- em_folder_tree_model_set_folder_info ( +- model, &sub, store, fi, fully_loaded); ++ if (!em_folder_tree_model_set_folder_info (model, &sub, store, fi, fully_loaded)) ++ gtk_tree_store_remove (tree_store, &sub); ++ + fi = fi->next; + } while (fi); + } +@@ -1598,6 +1599,8 @@ em_folder_tree_model_set_folder_info (EMFolderTreeModel *model, + g_signal_emit (model, signals[LOADED_ROW], 0, path, iter); + gtk_tree_path_free (path); + } ++ ++ return TRUE; + } + + static void +@@ -1676,8 +1679,9 @@ folder_tree_model_folder_renamed_cb (CamelStore *store, + gtk_tree_path_free (path); + + gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &root); +- em_folder_tree_model_set_folder_info ( +- EM_FOLDER_TREE_MODEL (model), &iter, store, info, TRUE); ++ ++ if (!em_folder_tree_model_set_folder_info (EM_FOLDER_TREE_MODEL (model), &iter, store, info, TRUE)) ++ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); + } + + static void +@@ -1741,9 +1745,9 @@ folder_tree_model_folder_subscribed_cb (CamelStore *store, + + gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent); + +- em_folder_tree_model_set_folder_info ( +- EM_FOLDER_TREE_MODEL (model), &iter, store, fi, +- (fi->flags & (CAMEL_FOLDER_NOINFERIORS | CAMEL_FOLDER_NOCHILDREN)) != 0); ++ if (!em_folder_tree_model_set_folder_info (EM_FOLDER_TREE_MODEL (model), &iter, store, fi, ++ (fi->flags & (CAMEL_FOLDER_NOINFERIORS | CAMEL_FOLDER_NOCHILDREN)) != 0)) ++ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); + } + + static void +diff --git a/src/mail/em-folder-tree-model.h b/src/mail/em-folder-tree-model.h +index 1402144e4c..45784278be 100644 +--- a/src/mail/em-folder-tree-model.h ++++ b/src/mail/em-folder-tree-model.h +@@ -123,7 +123,7 @@ EMailSession * em_folder_tree_model_get_session + void em_folder_tree_model_set_session + (EMFolderTreeModel *model, + EMailSession *session); +-void em_folder_tree_model_set_folder_info ++gboolean em_folder_tree_model_set_folder_info + (EMFolderTreeModel *model, + GtkTreeIter *iter, + CamelStore *store, +diff --git a/src/mail/em-folder-tree.c b/src/mail/em-folder-tree.c +index 39871c6f1f..b4eab4f9f8 100644 +--- a/src/mail/em-folder-tree.c ++++ b/src/mail/em-folder-tree.c +@@ -363,9 +363,8 @@ folder_tree_get_folder_info_cb (CamelStore *store, + GTK_TREE_STORE (model), + &iter, &root); + +- em_folder_tree_model_set_folder_info ( +- EM_FOLDER_TREE_MODEL (model), +- &iter, store, child_info, TRUE); ++ if (!em_folder_tree_model_set_folder_info (EM_FOLDER_TREE_MODEL (model), &iter, store, child_info, TRUE)) ++ gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); + } + + child_info = child_info->next; +-- +2.27.0 + diff --git a/evolution.spec b/evolution.spec index 2e99ee6..40a3ab2 100644 --- a/evolution.spec +++ b/evolution.spec @@ -41,7 +41,7 @@ Name: evolution Version: 3.37.2 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Mail and calendar client for GNOME License: GPLv2+ and GFDL URL: https://wiki.gnome.org/Apps/Evolution @@ -49,6 +49,14 @@ Source: http://download.gnome.org/sources/%{name}/3.37/%{name}-%{version}.tar.xz Source1: flatpak-evolution-fix-service-names.sh Source2: flatpak-evolution-wrapper.sh.in +# Various bugfix backports from upstream mainline +Patch0001: 0001-I-966-Composer-Correct-caret-placement-around-signat.patch +Patch0002: 0002-I-969-Workaround-freeze-on-drag-of-message-over-comp.patch +Patch0003: 0003-I-975-Composer-Some-user-options-not-propagated-to-t.patch +Patch0004: 0004-I-982-Message-contains-search-broken-in-3.36.3.patch +Patch0005: 0005-I-979-Undeletable-empty-item-in-folder-list.patch + + Obsoletes: anjal <= %{last_anjal_version} Obsoletes: libgal2 <= %{last_libgal2_version} Obsoletes: evolution-NetworkManager < %{last_evo_nm_version} @@ -234,7 +242,7 @@ the functionality of the installed %{name} package. %endif %prep -%setup -q -n %{name}-%{version} +%autosetup -p1 -n %{name}-%{version} # Remove the welcome email from Novell for inbox in src/mail/default/*/Inbox; do @@ -561,6 +569,9 @@ grep -v "%{_datadir}/locale" evolution.lang > help.lang %endif %changelog +* Tue Jun 23 2020 Adam Williamson - 3.37.2-2 +- Backport several fixes for annoying bugs from mainline + * Fri May 29 2020 Milan Crha - 3.37.2-1 - Update to 3.37.2