[gnome-contacts/wip/exalm/papercuts: 5/6] Fix unselecting sidebar item




commit 9094c98fc3f85da0ad03aeec52f511c584ca2401
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Fri Aug 12 17:19:11 2022 +0400

    Fix unselecting sidebar item
    
    Multiple things here.
    
    - The selection model state was mever synced back to the list
    - The selected == null codepath didn't work
    - unselect_all() does nothing with GtkSingleSelection
    - gtk_list_box_unselect_all() does nothing with BROWSE selection mode
    
    Fixes https://gitlab.gnome.org/GNOME/gnome-contacts/-/issues/262

 src/contacts-contact-list.vala | 13 +++++++++++--
 src/contacts-contact-pane.vala |  4 ++--
 src/contacts-main-window.vala  | 19 +++++++++----------
 src/contacts-store.vala        |  1 +
 4 files changed, 23 insertions(+), 14 deletions(-)
---
diff --git a/src/contacts-contact-list.vala b/src/contacts-contact-list.vala
index 45129980..744ef5c8 100644
--- a/src/contacts-contact-list.vala
+++ b/src/contacts-contact-list.vala
@@ -45,7 +45,7 @@ public class Contacts.ContactList : Adw.Bin {
     var list_box = new Gtk.ListBox ();
     this.listbox = list_box;
     this.listbox.bind_model (this.store.filter_model, create_row_for_item);
-    this.listbox.selection_mode = Gtk.SelectionMode.BROWSE;
+    this.listbox.selection_mode = Gtk.SelectionMode.SINGLE;
     this.listbox.set_header_func (update_header);
     this.listbox.add_css_class ("navigation-sidebar");
 
@@ -72,6 +72,15 @@ public class Contacts.ContactList : Adw.Bin {
     viewport.scroll_to_focus = true;
     viewport.set_child (this.listbox);
     sw.set_child (viewport);
+
+    this.store.selection.selection_changed.connect (() => {
+      uint selected = this.store.selection.get_selected ();
+
+      if (selected == Gtk.INVALID_LIST_POSITION)
+        this.listbox.unselect_all ();
+      else
+        this.listbox.select_row (this.listbox.get_row_at_index ((int) selected));
+    });
   }
 
   public ContactList (Store store, Gtk.MultiSelection marked_contacts) {
@@ -139,7 +148,7 @@ public class Contacts.ContactList : Adw.Bin {
   private void on_row_selected (Gtk.ListBox listbox, Gtk.ListBoxRow? row) {
     if (this.state != UiState.SELECTING) {
       if (row == null) {
-        this.store.selection.unselect_all ();
+        this.store.selection.unselect_item (this.store.selection.get_selected ());
       } else {
         this.store.selection.select_item (row.get_index (), true);
       }
diff --git a/src/contacts-contact-pane.vala b/src/contacts-contact-pane.vala
index 5cbbc845..b375a9cb 100644
--- a/src/contacts-contact-pane.vala
+++ b/src/contacts-contact-pane.vala
@@ -238,7 +238,7 @@ public class Contacts.ContactPane : Adw.Bin {
       persona = yield primary_store.add_persona_from_details (details);
     } catch (Error e) {
       show_message_dialog (_("Unable to create new contacts: %s").printf (e.message));
-      this.store.selection.unselect_all ();
+      this.store.selection.unselect_item (this.store.selection.get_selected ());
       return;
     }
 
@@ -253,7 +253,7 @@ public class Contacts.ContactPane : Adw.Bin {
 
     // If we got here, we couldn't find the individual
     show_message_dialog (_("Unable to find newly created contact"));
-    this.store.selection.unselect_all ();
+    this.store.selection.unselect_item (this.store.selection.get_selected ());
   }
 
   private void show_message_dialog (string message) {
diff --git a/src/contacts-main-window.vala b/src/contacts-main-window.vala
index 42d20739..fdffed71 100644
--- a/src/contacts-main-window.vala
+++ b/src/contacts-main-window.vala
@@ -276,7 +276,7 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
     unowned Individual? selected = this.store.get_selected_contact ();
     return_if_fail (selected != null);
 
-    this.store.selection.unselect_all ();
+    this.store.selection.unselect_item (this.store.selection.get_selected ());
     this.state = UiState.NORMAL;
 
     var operation = new UnlinkOperation (this.store, selected);
@@ -351,7 +351,7 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
     if (this.state == UiState.UPDATING || this.state == UiState.CREATING)
       return;
 
-    this.store.selection.unselect_all ();
+    this.store.selection.unselect_item (this.store.selection.get_selected ());
 
     this.state = UiState.CREATING;
 
@@ -375,7 +375,7 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
   private void on_child_transition_running () {
     if (!this.content_box.child_transition_running &&
          this.content_box.visible_child == this.list_pane_page)
-      this.store.selection.unselect_all ();
+      this.store.selection.unselect_item (this.store.selection.get_selected ());
   }
 
   private void update_header () {
@@ -428,7 +428,7 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
 
     // Update related actions
     unowned var unlink_action = lookup_action ("unlink-contact");
-    ((SimpleAction) unlink_action).set_enabled (selected.personas.size > 1);
+    ((SimpleAction) unlink_action).set_enabled (selected != null && selected.personas.size > 1);
 
     // We really want to treat selection mode specially
     if (this.state != UiState.SELECTING) {
@@ -437,7 +437,8 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
         activate_action ("stop-editing-contact", new Variant.boolean (false));
 
       this.contact_pane.show_contact (selected);
-      show_contact_pane ();
+      if (selected != null)
+        show_contact_pane ();
 
       // clearing right_header
       this.right_header.title_widget = new Adw.WindowTitle ("", "");
@@ -451,8 +452,6 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
           this.favorite_button.tooltip_text = _("Mark as favorite");
       }
       this.state = UiState.SHOWING;
-      if (selected == null)
-        show_contact_pane ();
     }
   }
 
@@ -462,7 +461,7 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
 
     // Go back to normal state as much as possible, and hide the contacts that
     // will be linked together
-    this.store.selection.unselect_all ();
+    this.store.selection.unselect_item (this.store.selection.get_selected ());
     this.marked_contacts.unselect_all ();
     this.contacts_list.set_contacts_visible (selection, false);
     this.contact_pane.show_contact (null);
@@ -494,7 +493,7 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
   private void delete_contacts (Gtk.Bitset selection) {
     // Go back to normal state as much as possible, and hide the contacts that
     // will be deleted
-    this.store.selection.unselect_all ();
+    this.store.selection.unselect_item (this.store.selection.get_selected ());
     this.marked_contacts.unselect_all ();
     this.contacts_list.set_contacts_visible (selection, false);
     this.contact_pane.show_contact (null);
@@ -552,7 +551,7 @@ public class Contacts.MainWindow : Adw.ApplicationWindow {
     var selection = this.marked_contacts.get_selection ().copy ();
 
     // Go back to normal state as much as possible
-    this.store.selection.unselect_all ();
+    this.store.selection.unselect_item (this.store.selection.get_selected ());
     this.marked_contacts.unselect_all ();
     this.state = UiState.NORMAL;
 
diff --git a/src/contacts-store.vala b/src/contacts-store.vala
index 739d23d2..faa4ee5a 100644
--- a/src/contacts-store.vala
+++ b/src/contacts-store.vala
@@ -176,6 +176,7 @@ public class Contacts.Store : GLib.Object {
     this.filter_model = new Gtk.FilterListModel (this.sort_model, this.filter);
 
     this.selection = new Gtk.SingleSelection (this.filter_model);
+    this.selection.can_unselect = true;
     this.selection.autoselect = false;
   }
 


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