Philipp Hörist pushed to branch master at gajim / gajim
Commits: e205b303 by Philipp Hörist at 2023-05-14T11:38:57+00:00 imprv: ChatList: Improve sorting
The sort of the chat list is inhibited when the mouse is over the chat list. This makes sure the sorting is invalidated once the mouse exits the chat list.
- - - - -
2 changed files:
- gajim/gtk/chat_list.py - gajim/gtk/chat_list_row.py
Changes:
===================================== gajim/gtk/chat_list.py ===================================== @@ -71,7 +71,9 @@ def __init__(self, workspace_id: str) -> None: self.set_sort_func(self._sort_func) self._set_placeholder()
- self._mouseover: bool = False + self._rows_need_sort = False + self._context_menu_visible = False + self._mouseover = False self._pinned_order_change = False self.connect('enter-notify-event', self._on_mouse_focus_changed) self.connect('leave-notify-event', self._on_mouse_focus_changed) @@ -206,6 +208,8 @@ def add_chat(self,
row.connect('drag-begin', self._on_row_drag_begin) row.connect('unread-changed', self._on_row_unread_changed) + row.connect('context-menu-state-changed', + self._on_context_menu_state_changed)
self.add(row)
@@ -371,6 +375,14 @@ def _on_row_drag_begin(self, def _on_row_unread_changed(self, row: ChatListRow) -> None: self._emit_unread_changed()
+ def _on_context_menu_state_changed(self, + row: ChatListRow, + menu_is_visible: bool + ) -> None: + + self._context_menu_visible = menu_is_visible + self._schedule_check_sort_inhibit() + def _on_drag_data_received(self, _widget: Gtk.Widget, _drag_context: Gdk.DragContext, @@ -478,8 +490,9 @@ def _header_func(row: ChatListRow, before: ChatListRow | None) -> None: row.set_header_type(None)
def _sort_func(self, row1: ChatListRow, row2: ChatListRow) -> int: - if self._mouseover and not self._pinned_order_change: - log.debug('Mouseover active, don’t sort rows') + if self._is_sort_inhibited(): + self._rows_need_sort = True + log.debug('Sort inhibited') return 0
# Sort pinned rows according to stored order @@ -497,6 +510,33 @@ def _sort_func(self, row1: ChatListRow, row2: ChatListRow) -> int: # Sort by timestamp return -1 if row1.timestamp > row2.timestamp else 1
+ def invalidate_sort(self) -> None: + if self._is_sort_inhibited(): + return + + self._rows_need_sort = False + log.debug('Sort Chatlist') + Gtk.ListBox.invalidate_sort(self) + + def _is_sort_inhibited(self) -> bool: + if self._pinned_order_change: + return False + return self._mouseover or self._context_menu_visible + + def _schedule_check_sort_inhibit(self) -> None: + if self._is_sort_inhibited(): + return + GLib.timeout_add(100, self._check_sort_inhibit) + + def _check_sort_inhibit(self) -> None: + if self._is_sort_inhibited(): + return + + if not self._rows_need_sort: + return + + self.invalidate_sort() + def _on_mouse_focus_changed(self, _widget: Gtk.ListBox, event: Gdk.EventCrossing @@ -510,6 +550,8 @@ def _on_mouse_focus_changed(self, # Not hovering a Gtk.ListBoxRow (row is INFERIOR) self._mouseover = False
+ self._schedule_check_sort_inhibit() + @staticmethod def _on_start_chat_clicked(_button: Gtk.Button) -> None: app.app.activate_action('start-chat', GLib.Variant('as', ['', '']))
===================================== gajim/gtk/chat_list_row.py ===================================== @@ -63,6 +63,10 @@ class ChatListRow(Gtk.ListBoxRow): GObject.SignalFlags.RUN_LAST, None, ()), + 'context-menu-state-changed': ( + GObject.SignalFlags.RUN_LAST, + None, + (bool,)), }
def __init__(self, @@ -437,14 +441,14 @@ def _on_row_button_press_event(self, ) -> None:
if event.button == Gdk.BUTTON_SECONDARY: - self._popup_menu(event) + self._raise_context_popover(event)
elif event.button == Gdk.BUTTON_MIDDLE: app.window.activate_action( 'remove-chat', GLib.Variant('as', [self.account, str(self.jid)]))
- def _popup_menu(self, event: Gdk.EventButton): + def _raise_context_popover(self, event: Gdk.EventButton): menu = get_chat_list_row_menu( self.workspace_id, self.account, self.jid, self._pinned)
@@ -460,8 +464,13 @@ def _popup_menu(self, event: Gdk.EventButton):
popover = GajimPopover(menu, relative_to=self) popover.set_pointing_to_coord(x=x, y=event.y) + popover.connect('closed', self._on_context_popover_closed) + self.emit('context-menu-state-changed', True) popover.popup()
+ def _on_context_popover_closed(self, _popover: Gtk.Popover) -> None: + self.emit('context-menu-state-changed', False) + def _on_drag_begin(self, row: ChatListRow, drag_context: Gdk.DragContext
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/commit/e205b303e1f25da1a5d90072d5c61376d...