[geary/mjog/mutiple-main-windows] Improve UX when automating folder/conversation selection



commit a760e26560368c3c2e88fed82351e850d051db5e
Author: Michael Gratton <mike vee net>
Date:   Mon Nov 18 20:27:08 2019 +1100

    Improve UX when automating folder/conversation selection
    
    Don't select the inbox of the first account by default in MainWindow,
    and provide a means of inhibiting conversation autoselect when changing
    folder. This allows selecting a conversation in a different folder and
    opening new folders with a specific conversation selected without
    jumping to the first conversation first when the autoselect pref is
    enabled.

 src/client/application/application-client.vala     | 30 +++++++++++++---
 src/client/application/application-controller.vala |  1 +
 .../application/application-main-window.vala       | 42 ++++++++++------------
 .../conversation-list/conversation-list-view.vala  | 12 +++++++
 4 files changed, 58 insertions(+), 27 deletions(-)
---
diff --git a/src/client/application/application-client.vala b/src/client/application/application-client.vala
index f5ef4e9e..bb64b290 100644
--- a/src/client/application/application-client.vala
+++ b/src/client/application/application-client.vala
@@ -516,7 +516,7 @@ public class Application.Client : Gtk.Application {
      */
     public MainWindow get_active_main_window() {
         if (this.last_active_main_window == null) {
-            this.last_active_main_window = new_main_window();
+            this.last_active_main_window = new_main_window(true);
         }
         return last_active_main_window;
     }
@@ -619,10 +619,16 @@ public class Application.Client : Gtk.Application {
                                  Gee.Collection<Geary.App.Conversation>? select_conversations) {
         yield create_controller();
 
-        MainWindow main = new_main_window();
+        bool do_select = (
+            select_folder != null &&
+            select_conversations != null &&
+            !select_conversations.is_empty
+        );
+
+        MainWindow main = new_main_window(!do_select);
         main.present();
 
-        if (select_folder != null) {
+        if (do_select) {
             if (select_conversations == null || select_conversations.is_empty) {
                 main.select_folder.begin(select_folder, true);
             } else {
@@ -789,10 +795,26 @@ public class Application.Client : Gtk.Application {
         return main;
     }
 
-    private MainWindow new_main_window() {
+    private MainWindow new_main_window(bool select_first_inbox) {
         MainWindow window = new MainWindow(this);
         this.controller.register_window(window);
         window.focus_in_event.connect(on_main_window_focus_in);
+        if (select_first_inbox) {
+            try {
+                var config = this.controller.get_first_account();
+                if (config != null) {
+                    var first = this.engine.get_account_instance(config);
+                    if (first != null) {
+                        Geary.Folder? inbox = first.get_special_folder(INBOX);
+                        if (inbox != null) {
+                            window.select_folder.begin(inbox, true);
+                        }
+                    }
+                }
+            } catch (GLib.Error error) {
+                debug("Error getting Inbox for first account");
+            }
+        }
         return window;
     }
 
diff --git a/src/client/application/application-controller.vala 
b/src/client/application/application-controller.vala
index b8f09e93..9473943d 100644
--- a/src/client/application/application-controller.vala
+++ b/src/client/application/application-controller.vala
@@ -310,6 +310,7 @@ internal class Application.Controller : Geary.BaseObject {
             window.select_folder.begin(
                 null,
                 false,
+                true,
                 (obj, res) => {
                     window.select_folder.end(res);
                     window.close();
diff --git a/src/client/application/application-main-window.vala 
b/src/client/application/application-main-window.vala
index 7c2e2c90..62b2d3b4 100644
--- a/src/client/application/application-main-window.vala
+++ b/src/client/application/application-main-window.vala
@@ -215,8 +215,8 @@ public class Application.MainWindow :
 
     private GLib.SimpleActionGroup edit_actions = new GLib.SimpleActionGroup();
 
-    // Determines if the conversation viewer should autoselect on next
-    // load
+    // Determines if the conversation viewer should auto-mark messages
+    // on next load
     private bool previous_selection_was_interactive = false;
 
     // Caches the last non-search folder so it can be re-selected on
@@ -424,7 +424,8 @@ public class Application.MainWindow :
      * the folder list), as opposed to some side effect.
      */
     public async void select_folder(Geary.Folder? to_select,
-                                    bool is_interactive) {
+                                    bool is_interactive,
+                                    bool inhibit_autoselect = false) {
         if (this.selected_folder != to_select) {
             // Cancel any existing folder loading
             this.folder_open.cancel();
@@ -461,15 +462,21 @@ public class Application.MainWindow :
 
             select_account(to_select != null ? to_select.account : null);
             this.selected_folder = to_select;
+
             // Ensure that the folder is selected in the UI if
             // this was called by something other than the
             // selection changed callback. That will check to
             // ensure that we're not setting it again.
             if (to_select != null) {
-                this.folder_list.select_folder(to_select);
+                // Prefer the inboxes branch if it exists
+                if (to_select.special_folder_type != INBOX ||
+                    !this.folder_list.select_inbox(to_select.account)) {
+                    this.folder_list.select_folder(to_select);
+                }
             } else {
                 this.folder_list.deselect_folder();
             }
+
             if (!(to_select is Geary.SearchFolder)) {
                 this.previous_non_search_folder = to_select;
             }
@@ -508,6 +515,9 @@ public class Application.MainWindow :
 
                 );
                 this.progress_monitor.add(conversations_model.preview_monitor);
+                if (inhibit_autoselect) {
+                    this.conversation_list_view.inhibit_next_autoselect();
+                }
                 this.conversation_list_view.set_model(conversations_model);
 
                 // disable copy/move to the new folder
@@ -534,7 +544,8 @@ public class Application.MainWindow :
     public async void show_conversations(Geary.Folder location,
                                          Gee.Collection<Geary.App.Conversation> to_show,
                                          bool is_interactive) {
-        yield select_folder(location, is_interactive);
+        bool inhibit_autoselect = (location != this.selected_folder);
+        yield select_folder(location, is_interactive, inhibit_autoselect);
         // The folder may have changed again by the type the async
         // call returns, so only continue if still current
         if (this.selected_folder == location) {
@@ -565,7 +576,8 @@ public class Application.MainWindow :
     public async void show_email(Geary.Folder location,
                                  Gee.Collection<Geary.EmailIdentifier> to_show,
                                  bool is_interactive) {
-        yield select_folder(location, is_interactive);
+        bool inhibit_autoselect = (location != this.selected_folder);
+        yield select_folder(location, is_interactive, inhibit_autoselect);
         // The folder may have changed again by the type the async
         // call returns, so only continue if still current
         if (this.selected_folder == location) {
@@ -1284,23 +1296,6 @@ public class Application.MainWindow :
         foreach (Geary.Folder folder in available) {
             if (Controller.should_add_folder(available, folder)) {
                 add_folder(folder);
-
-                if (folder.special_folder_type == INBOX) {
-                    // Select this inbox if there isn't an existing
-                    // folder selected and it is the inbox for the
-                    // first account
-                    Geary.AccountInformation? first_account =
-                        this.application.controller.get_first_account();
-                    if (!this.folder_list.is_any_selected() &&
-                        folder.account.information == first_account) {
-                        // First we try to select the Inboxes branch
-                        // inbox if it's there, falling back to the
-                        // main folder list.
-                        if (!this.folder_list.select_inbox(folder.account)) {
-                            this.folder_list.select_folder(folder);
-                        }
-                    }
-                }
             }
         }
     }
@@ -1670,6 +1665,7 @@ public class Application.MainWindow :
             this.select_folder.begin(
                 null,
                 false,
+                true,
                 (obj, res) => {
                     this.select_folder.end(res);
                     destroy();
diff --git a/src/client/conversation-list/conversation-list-view.vala 
b/src/client/conversation-list/conversation-list-view.vala
index 2697554e..ab1c5e57 100644
--- a/src/client/conversation-list/conversation-list-view.vala
+++ b/src/client/conversation-list/conversation-list-view.vala
@@ -18,6 +18,11 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface {
     private Gee.Set<Geary.App.Conversation> selected = new Gee.HashSet<Geary.App.Conversation>();
     private Geary.IdleManager selection_update;
 
+    // Determines if the next folder scan should avoid selecting a
+    // conversation when autoselect is enabled
+    private bool should_inhibit_autoselect = false;
+
+
     public signal void conversations_selected(Gee.Set<Geary.App.Conversation> selected);
 
     // Signal for when a conversation has been double-clicked, or selected and enter is pressed.
@@ -131,6 +136,10 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface {
         return this.selected.read_only_view;
     }
 
+    public void inhibit_next_autoselect() {
+        this.should_inhibit_autoselect = true;
+    }
+
     public void scroll(Gtk.ScrollType where) {
         Gtk.TreeSelection selection = get_selection();
         weak Gtk.TreeModel model;
@@ -197,12 +206,15 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface {
         // nothing has been selected yet and we're not showing a
         // composer.
         if (this.config.autoselect &&
+            !this.should_inhibit_autoselect &&
             get_selection().count_selected_rows() == 0) {
             var parent = get_toplevel() as Application.MainWindow;
             if (parent != null && !parent.has_composer) {
                 set_cursor(new Gtk.TreePath.from_indices(0, -1), null, false);
             }
         }
+
+        this.should_inhibit_autoselect = false;
     }
 
     private void on_conversations_added(bool start) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]