| ... |
... |
@@ -71,7 +71,9 @@ def __init__(self, workspace_id: str) -> None: |
|
71
|
71
|
self.set_sort_func(self._sort_func)
|
|
72
|
72
|
self._set_placeholder()
|
|
73
|
73
|
|
|
74
|
|
- self._mouseover: bool = False
|
|
|
74
|
+ self._rows_need_sort = False
|
|
|
75
|
+ self._context_menu_visible = False
|
|
|
76
|
+ self._mouseover = False
|
|
75
|
77
|
self._pinned_order_change = False
|
|
76
|
78
|
self.connect('enter-notify-event', self._on_mouse_focus_changed)
|
|
77
|
79
|
self.connect('leave-notify-event', self._on_mouse_focus_changed)
|
| ... |
... |
@@ -206,6 +208,8 @@ def add_chat(self, |
|
206
|
208
|
|
|
207
|
209
|
row.connect('drag-begin', self._on_row_drag_begin)
|
|
208
|
210
|
row.connect('unread-changed', self._on_row_unread_changed)
|
|
|
211
|
+ row.connect('context-menu-state-changed',
|
|
|
212
|
+ self._on_context_menu_state_changed)
|
|
209
|
213
|
|
|
210
|
214
|
self.add(row)
|
|
211
|
215
|
|
| ... |
... |
@@ -371,6 +375,14 @@ def _on_row_drag_begin(self, |
|
371
|
375
|
def _on_row_unread_changed(self, row: ChatListRow) -> None:
|
|
372
|
376
|
self._emit_unread_changed()
|
|
373
|
377
|
|
|
|
378
|
+ def _on_context_menu_state_changed(self,
|
|
|
379
|
+ row: ChatListRow,
|
|
|
380
|
+ menu_is_visible: bool
|
|
|
381
|
+ ) -> None:
|
|
|
382
|
+
|
|
|
383
|
+ self._context_menu_visible = menu_is_visible
|
|
|
384
|
+ self._schedule_check_sort_inhibit()
|
|
|
385
|
+
|
|
374
|
386
|
def _on_drag_data_received(self,
|
|
375
|
387
|
_widget: Gtk.Widget,
|
|
376
|
388
|
_drag_context: Gdk.DragContext,
|
| ... |
... |
@@ -478,8 +490,9 @@ def _header_func(row: ChatListRow, before: ChatListRow | None) -> None: |
|
478
|
490
|
row.set_header_type(None)
|
|
479
|
491
|
|
|
480
|
492
|
def _sort_func(self, row1: ChatListRow, row2: ChatListRow) -> int:
|
|
481
|
|
- if self._mouseover and not self._pinned_order_change:
|
|
482
|
|
- log.debug('Mouseover active, don’t sort rows')
|
|
|
493
|
+ if self._is_sort_inhibited():
|
|
|
494
|
+ self._rows_need_sort = True
|
|
|
495
|
+ log.debug('Sort inhibited')
|
|
483
|
496
|
return 0
|
|
484
|
497
|
|
|
485
|
498
|
# Sort pinned rows according to stored order
|
| ... |
... |
@@ -497,6 +510,33 @@ def _sort_func(self, row1: ChatListRow, row2: ChatListRow) -> int: |
|
497
|
510
|
# Sort by timestamp
|
|
498
|
511
|
return -1 if row1.timestamp > row2.timestamp else 1
|
|
499
|
512
|
|
|
|
513
|
+ def invalidate_sort(self) -> None:
|
|
|
514
|
+ if self._is_sort_inhibited():
|
|
|
515
|
+ return
|
|
|
516
|
+
|
|
|
517
|
+ self._rows_need_sort = False
|
|
|
518
|
+ log.debug('Sort Chatlist')
|
|
|
519
|
+ Gtk.ListBox.invalidate_sort(self)
|
|
|
520
|
+
|
|
|
521
|
+ def _is_sort_inhibited(self) -> bool:
|
|
|
522
|
+ if self._pinned_order_change:
|
|
|
523
|
+ return False
|
|
|
524
|
+ return self._mouseover or self._context_menu_visible
|
|
|
525
|
+
|
|
|
526
|
+ def _schedule_check_sort_inhibit(self) -> None:
|
|
|
527
|
+ if self._is_sort_inhibited():
|
|
|
528
|
+ return
|
|
|
529
|
+ GLib.timeout_add(100, self._check_sort_inhibit)
|
|
|
530
|
+
|
|
|
531
|
+ def _check_sort_inhibit(self) -> None:
|
|
|
532
|
+ if self._is_sort_inhibited():
|
|
|
533
|
+ return
|
|
|
534
|
+
|
|
|
535
|
+ if not self._rows_need_sort:
|
|
|
536
|
+ return
|
|
|
537
|
+
|
|
|
538
|
+ self.invalidate_sort()
|
|
|
539
|
+
|
|
500
|
540
|
def _on_mouse_focus_changed(self,
|
|
501
|
541
|
_widget: Gtk.ListBox,
|
|
502
|
542
|
event: Gdk.EventCrossing
|
| ... |
... |
@@ -510,6 +550,8 @@ def _on_mouse_focus_changed(self, |
|
510
|
550
|
# Not hovering a Gtk.ListBoxRow (row is INFERIOR)
|
|
511
|
551
|
self._mouseover = False
|
|
512
|
552
|
|
|
|
553
|
+ self._schedule_check_sort_inhibit()
|
|
|
554
|
+
|
|
513
|
555
|
@staticmethod
|
|
514
|
556
|
def _on_start_chat_clicked(_button: Gtk.Button) -> None:
|
|
515
|
557
|
app.app.activate_action('start-chat', GLib.Variant('as', ['', '']))
|