[geary/mjog/mutiple-main-windows] Improve UX when automating folder/conversation selection
- From: Michael Gratton <mjog src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [geary/mjog/mutiple-main-windows] Improve UX when automating folder/conversation selection
- Date: Mon, 18 Nov 2019 10:46:07 +0000 (UTC)
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]