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.
This commit is contained in:
parent
68aaec3245
commit
a760e26560
4 changed files with 58 additions and 27 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue