[geary] Fix messages being selected after move/etc and autoselect is disabled.
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary] Fix messages being selected after move/etc and autoselect is disabled.
- Date: Thu, 20 Oct 2016 05:32:55 +0000 (UTC)
commit 310daa8ad03878fd70353d9806b7dd66fd7cce33
Author: Michael James Gratton <mike vee net>
Date: Thu Oct 20 16:27:43 2016 +1100
Fix messages being selected after move/etc and autoselect is disabled.
Bug 773054
* src/client/conversation-list/conversation-list-view.vala: Disable all
selection when the user is causing the selection will change. This
prevents the GtkTreeView impl from selecting the next row after rows
are removed as a result of user action, but not for some other reason,
i.e. the server removing a message.
* src/client/application/geary-controller.vala: Call new
ConversationListView::set_changing_selection as needed when moving
messages.
* src/client/conversation-list/conversation-list-store,
src/engine/app/app-conversation-monitor.vala: Rename
conversation_removed signal to conversations_removed and change its
param to be a collection of conversations, so we can re-enable
ConversationListView selection only after all conversations have been
removed. Update call sites.
src/client/application/geary-controller.vala | 25 +++++++++---
.../conversation-list/conversation-list-store.vala | 13 ++++--
.../conversation-list/conversation-list-view.vala | 40 ++++++++++++++++----
src/engine/app/app-conversation-monitor.vala | 21 +++++-----
4 files changed, 68 insertions(+), 31 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index 15cb7eb..a7a6468 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -1442,7 +1442,7 @@ public class GearyController : Geary.BaseObject {
current_conversations.seed_completed.connect(on_conversation_count_changed);
current_conversations.scan_completed.connect(on_conversation_count_changed);
current_conversations.conversations_added.connect(on_conversation_count_changed);
- current_conversations.conversation_removed.connect(on_conversation_count_changed);
+ current_conversations.conversations_removed.connect(on_conversation_count_changed);
if (!current_conversations.is_monitoring)
yield current_conversations.start_monitoring_async(conversation_cancellable);
@@ -1960,12 +1960,19 @@ public class GearyController : Geary.BaseObject {
Gee.List<Geary.EmailIdentifier> ids = get_selected_email_ids(false);
if (ids.size == 0)
return;
-
+
+ this.main_window.conversation_list_view.set_changing_selection(true);
+
Geary.FolderSupport.Move? supports_move = current_folder as Geary.FolderSupport.Move;
if (supports_move != null)
- move_conversation_async.begin(supports_move, ids, destination.path, cancellable_folder);
+ move_conversation_async.begin(
+ supports_move, ids, destination.path, cancellable_folder,
+ (obj, ret) => {
+ move_conversation_async.end(ret);
+ this.main_window.conversation_list_view.set_changing_selection(false);
+ });
}
-
+
private async void move_conversation_async(Geary.FolderSupport.Move source_folder,
Gee.List<Geary.EmailIdentifier> ids, Geary.FolderPath destination, Cancellable? cancellable) {
try {
@@ -2572,9 +2579,12 @@ public class GearyController : Geary.BaseObject {
last_deleted_conversation = selected_conversations.size > 0
? Geary.traverse<Geary.App.Conversation>(selected_conversations).first() : null;
- // Return focus to the conversation list from the clicked toolbar button.
- main_window.conversation_list_view.grab_focus();
-
+ // Return focus to the conversation list from the clicked
+ // toolbar button.
+ this.main_window.conversation_list_view.grab_focus();
+
+ this.main_window.conversation_list_view.set_changing_selection(true);
+
Gee.List<Geary.EmailIdentifier> ids = get_selected_email_ids(false);
if (archive) {
debug("Archiving selected messages");
@@ -2629,6 +2639,7 @@ public class GearyController : Geary.BaseObject {
} catch (Error e) {
debug("Unable to archive/trash/delete messages: %s", e.message);
}
+ this.main_window.conversation_list_view.set_changing_selection(false);
}
private void save_revokable(Geary.Revokable? new_revokable, string? description) {
diff --git a/src/client/conversation-list/conversation-list-store.vala
b/src/client/conversation-list/conversation-list-store.vala
index 6a8fd2a..7c3bc69 100644
--- a/src/client/conversation-list/conversation-list-store.vala
+++ b/src/client/conversation-list/conversation-list-store.vala
@@ -92,8 +92,8 @@ public class ConversationListStore : Gtk.ListStore {
private uint update_id = 0;
public signal void conversations_added_began();
-
public signal void conversations_added_finished();
+ public signal void conversations_removed(bool start);
public ConversationListStore(Geary.App.ConversationMonitor conversations) {
set_column_types(Column.get_types());
@@ -112,7 +112,7 @@ public class ConversationListStore : Gtk.ListStore {
conversations.scan_completed.connect(on_scan_completed);
conversations.conversations_added.connect(on_conversations_added);
- conversations.conversation_removed.connect(on_conversation_removed);
+ conversations.conversations_removed.connect(on_conversations_removed);
conversations.conversation_appended.connect(on_conversation_appended);
conversations.conversation_trimmed.connect(on_conversation_trimmed);
conversations.email_flags_changed.connect(on_email_flags_changed);
@@ -428,10 +428,13 @@ public class ConversationListStore : Gtk.ListStore {
conversations_added_finished();
}
- private void on_conversation_removed(Geary.App.Conversation conversation) {
- remove_conversation(conversation);
+ private void on_conversations_removed(Gee.Collection<Geary.App.Conversation> conversations) {
+ conversations_removed(true);
+ foreach (Geary.App.Conversation removed in conversations)
+ remove_conversation(removed);
+ conversations_removed(false);
}
-
+
private void on_conversation_appended(Geary.App.Conversation conversation) {
if (has_conversation(conversation)) {
refresh_conversation(conversation);
diff --git a/src/client/conversation-list/conversation-list-view.vala
b/src/client/conversation-list/conversation-list-view.vala
index 355681e..20366ea 100644
--- a/src/client/conversation-list/conversation-list-view.vala
+++ b/src/client/conversation-list/conversation-list-view.vala
@@ -19,6 +19,7 @@ public class ConversationListView : Gtk.TreeView {
private Gtk.Menu? context_menu = null;
private Gee.Set<Geary.App.Conversation> selected = new Gee.HashSet<Geary.App.Conversation>();
private uint selection_changed_id = 0;
+ private bool suppress_selection = false;
public signal void conversations_selected(Gee.Set<Geary.App.Conversation> selected);
@@ -83,6 +84,7 @@ public class ConversationListView : Gtk.TreeView {
old_store.conversations_added_began.disconnect(
on_conversations_added_began
);
+ old_store.conversations_removed.disconnect(on_conversations_removed);
old_store.row_inserted.disconnect(on_rows_changed);
old_store.rows_reordered.disconnect(on_rows_changed);
old_store.row_changed.disconnect(on_rows_changed);
@@ -102,6 +104,7 @@ public class ConversationListView : Gtk.TreeView {
new_store.conversations_added_finished.connect(
on_conversations_added_finished
);
+ new_store.conversations_removed.connect(on_conversations_removed);
}
// Disconnect the selection handler since we don't want to
@@ -113,12 +116,27 @@ public class ConversationListView : Gtk.TreeView {
selection.changed.connect(on_selection_changed);
}
+ /**
+ * Specifies an action is currently changing the view's selection.
+ */
+ public void set_changing_selection(bool is_changing) {
+ // Make sure that when not autoselecting, and if the user is
+ // causing selected rows to be removed, the next row is not
+ // automatically selected by GtkTreeView
+ if (is_changing) {
+ this.suppress_selection =
+ !GearyApplication.instance.config.autoselect;
+ } else {
+ // If no longer changing, always re-enable selection
+ get_selection().set_mode(Gtk.SelectionMode.MULTIPLE);
+ }
+ }
+
private void on_conversation_monitor_changed() {
if (conversation_monitor != null) {
conversation_monitor.scan_started.disconnect(on_scan_started);
conversation_monitor.scan_completed.disconnect(on_scan_completed);
conversation_monitor.seed_completed.disconnect(on_seed_completed);
- conversation_monitor.conversation_removed.disconnect(on_conversation_removed);
}
conversation_monitor = GearyApplication.instance.controller.current_conversations;
@@ -127,7 +145,6 @@ public class ConversationListView : Gtk.TreeView {
conversation_monitor.scan_started.connect(on_scan_started);
conversation_monitor.scan_completed.connect(on_scan_completed);
conversation_monitor.seed_completed.connect(on_seed_completed);
- conversation_monitor.conversation_removed.connect(on_conversation_removed);
}
}
@@ -157,11 +174,6 @@ public class ConversationListView : Gtk.TreeView {
}
}
- private void on_conversation_removed(Geary.App.Conversation conversation) {
- if (!GearyApplication.instance.config.autoselect)
- get_selection().unselect_all();
- }
-
private void on_conversations_added_began() {
Gtk.Adjustment? adjustment = get_adjustment();
// If we were at the top, we want to stay there after conversations are added.
@@ -184,7 +196,19 @@ public class ConversationListView : Gtk.TreeView {
adjustment.set_value(0);
}
-
+
+ private void on_conversations_removed(bool start) {
+ if (!GearyApplication.instance.config.autoselect) {
+ Gtk.SelectionMode mode = start
+ // Stop GtkTreeView from automatically selecting the
+ // next row after the removed rows
+ ? Gtk.SelectionMode.NONE
+ // Allow the user to make selections again
+ : Gtk.SelectionMode.MULTIPLE;
+ get_selection().set_mode(mode);
+ }
+ }
+
private Gtk.Adjustment? get_adjustment() {
Gtk.ScrolledWindow? parent = get_parent() as Gtk.ScrolledWindow;
if (parent == null) {
diff --git a/src/engine/app/app-conversation-monitor.vala b/src/engine/app/app-conversation-monitor.vala
index b906155..c974a99 100644
--- a/src/engine/app/app-conversation-monitor.vala
+++ b/src/engine/app/app-conversation-monitor.vala
@@ -112,15 +112,15 @@ public class Geary.App.ConversationMonitor : BaseObject {
/**
* "conversations-removed" is fired when all the email in a Conversation has been removed.
* It's possible this will be called without a signal alerting that it's emails have been
- * removed, i.e. a "conversation-removed" signal may fire with no accompanying
+ * removed, i.e. a "conversations-removed" signal may fire with no accompanying
* "conversation-trimmed".
*
* Note that this can only occur when monitoring is enabled. There is (currently) no
* user call to manually remove email from Conversations.
*/
- public virtual signal void conversation_removed(Conversation conversation) {
- Logging.debug(Logging.Flag.CONVERSATIONS, "[%s] ConversationMonitor::conversation_removed",
- folder.to_string());
+ public virtual signal void conversations_removed(Gee.Collection<Conversation> conversations) {
+ Logging.debug(Logging.Flag.CONVERSATIONS, "[%s] ConversationMonitor::conversations_removed %d",
+ folder.to_string(), conversations.size);
}
/**
@@ -216,8 +216,8 @@ public class Geary.App.ConversationMonitor : BaseObject {
conversations_added(conversations);
}
- protected virtual void notify_conversation_removed(Conversation conversation) {
- conversation_removed(conversation);
+ protected virtual void notify_conversations_removed(Gee.Collection<Conversation> conversations) {
+ conversations_removed(conversations);
}
protected virtual void notify_conversation_appended(Conversation conversation,
@@ -583,9 +583,8 @@ public class Geary.App.ConversationMonitor : BaseObject {
// fall-through
}
- if (removed_due_to_merge != null) {
- foreach (Conversation conversation in removed_due_to_merge)
- notify_conversation_removed(conversation);
+ if (removed_due_to_merge != null && removed_due_to_merge.size > 0) {
+ notify_conversations_removed(removed_due_to_merge);
}
if (added != null && added.size > 0)
@@ -637,8 +636,8 @@ public class Geary.App.ConversationMonitor : BaseObject {
foreach (Conversation conversation in trimmed.get_keys())
notify_conversation_trimmed(conversation, trimmed.get(conversation));
- foreach (Conversation conversation in removed)
- notify_conversation_removed(conversation);
+ if (removed.size > 0)
+ notify_conversations_removed(removed);
// For any still-existing conversations that we've trimmed messages
// from, do a search for any messages that should still be there due to
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]