From 0b743ab0d396cbbaad5aebaebed235ecd0f1a564 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Tue, 6 Oct 2020 13:34:30 +0200 Subject: [PATCH 059/124] conversation-list: use shift+activate to open conversation in new window Open on shift+double click and shift+space/enter the selected conversation in a new window. --- .../application/application-main-window.vala | 14 ++--- .../conversation-list-view.vala | 61 ++++++++++++++++--- 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/src/client/application/application-main-window.vala b/src/client/application/application-main-window.vala index c2b0954b..01b7b9c6 100644 --- a/src/client/application/application-main-window.vala +++ b/src/client/application/application-main-window.vala @@ -2143,17 +2143,16 @@ public class Application.MainWindow : focus_next_pane(); } - private void on_conversation_activated(Geary.App.Conversation activated) { - if (main_leaflet.folded) { - focus_next_pane(); - } - /* TODO: find correct UX for opening the conversation in a new window - if (this.selected_folder != null) { + private void on_conversation_activated(Geary.App.Conversation activated, bool single) { + if (single) { + if (main_leaflet.folded) + focus_next_pane(); + } else if (this.selected_folder != null) { if (this.selected_folder.used_as != DRAFTS) { this.application.new_window.begin( this.selected_folder, this.conversation_list_view.copy_selected() - ); + ); } else { // TODO: Determine how to map between conversations // and drafts correctly. @@ -2166,7 +2165,6 @@ public class Application.MainWindow : ); } } - */ } private void on_find_in_conversation_action() { diff --git a/src/client/conversation-list/conversation-list-view.vala b/src/client/conversation-list/conversation-list-view.vala index dcced90d..0baa66b4 100644 --- a/src/client/conversation-list/conversation-list-view.vala +++ b/src/client/conversation-list/conversation-list-view.vala @@ -17,6 +17,7 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface { private Geary.Scheduler.Scheduled? scheduled_update_visible_conversations = null; private Gee.Set selected = new Gee.HashSet(); private Geary.IdleManager selection_update; + private Gtk.GestureMultiPress gesture; // Determines if the next folder scan should avoid selecting a // conversation when autoselect is enabled @@ -26,7 +27,7 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface { public signal void conversations_selected(Gee.Set selected); // Signal for when a conversation has been double-clicked, or selected and enter is pressed. - public signal void conversation_activated(Geary.App.Conversation activated); + public signal void conversation_activated(Geary.App.Conversation activated, bool single = false); public virtual signal void load_more() { enable_load_more = false; @@ -42,7 +43,6 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface { base_ref(); set_show_expanders(false); set_headers_visible(false); - set_activate_on_single_click(true); this.config = config; @@ -53,11 +53,13 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface { Gtk.TreeSelection selection = get_selection(); selection.set_mode(Gtk.SelectionMode.MULTIPLE); style_updated.connect(on_style_changed); - row_activated.connect(on_row_activated); notify["vadjustment"].connect(on_vadjustment_changed); + key_press_event.connect(on_key_press); button_press_event.connect(on_button_press); + gesture = new Gtk.GestureMultiPress(this); + gesture.pressed.connect(on_gesture_pressed); // Set up drag and drop. Gtk.drag_source_set(this, Gdk.ModifierType.BUTTON1_MASK, FolderList.Tree.TARGET_ENTRY_LIST, @@ -270,6 +272,53 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface { return parent.get_vadjustment(); } + private void on_gesture_pressed(int n_press, double x, double y) { + if (gesture.get_current_button() != Gdk.BUTTON_PRIMARY) + return; + + Gtk.TreePath? path; + get_path_at_pos((int) x, (int) y, out path, null, null, null); + + // If the user clicked in an empty area, do nothing. + if (path == null) + return; + + Geary.App.Conversation? c = get_model().get_conversation_at_path(path); + if (c == null) + return; + + Gdk.Event event = gesture.get_last_event(gesture.get_current_sequence()); + Gdk.ModifierType modifiers = Gtk.accelerator_get_default_mod_mask(); + + Gdk.ModifierType state_mask; + event.get_state(out state_mask); + + if ((state_mask & modifiers) == 0 && n_press == 1) { + conversation_activated(c, true); + } else if ((state_mask & modifiers) == Gdk.ModifierType.SHIFT_MASK && n_press == 2) { + conversation_activated(c); + } + } + + private bool on_key_press(Gdk.EventKey event) { + if (this.selected.size != 1) + return false; + + Geary.App.Conversation? c = this.selected.to_array()[0]; + if (c == null) + return false; + + Gdk.ModifierType modifiers = Gtk.accelerator_get_default_mod_mask(); + + if (event.keyval == Gdk.Key.Return || + event.keyval == Gdk.Key.ISO_Enter || + event.keyval == Gdk.Key.KP_Enter || + event.keyval == Gdk.Key.space || + event.keyval == Gdk.Key.KP_Space) + conversation_activated(c, !((event.state & modifiers) == Gdk.ModifierType.SHIFT_MASK)); + return false; + } + private bool on_button_press(Gdk.EventButton event) { // Get the coordinates on the cell as well as the clicked path. int cell_x; @@ -576,12 +625,6 @@ public class ConversationListView : Gtk.TreeView, Geary.BaseInterface { return false; } - private void on_row_activated(Gtk.TreePath path) { - Geary.App.Conversation? c = get_model().get_conversation_at_path(path); - if (c != null) - conversation_activated(c); - } - // Enable/disable hover effect on all selected cells. private void set_hover_selected(bool hover) { ConversationListCellRenderer.set_hover_selected(hover); -- 2.29.2