Philipp Hörist pushed to branch mainwindow at gajim / gajim
Commits: abc60184 by lovetox at 2021-02-05T16:40:23+01:00 Reset unread counter
- - - - -
6 changed files:
- gajim/common/modules/chatstates.py - gajim/groupchat_control.py - gajim/gtk/chat_list.py - gajim/gtk/chat_list_stack.py - gajim/gtk/main.py - gajim/gtk/util.py
Changes:
===================================== gajim/common/modules/chatstates.py ===================================== @@ -135,6 +135,7 @@ def _presence_received(self, app.nec.push_outgoing_event( NetworkEvent('chatstate-received', account=self._account, + jid=contact.jid, contact=contact))
def _process_chatstate(self, _con, _stanza, properties): @@ -163,6 +164,7 @@ def _process_chatstate(self, _con, _stanza, properties): app.nec.push_outgoing_event( NetworkEvent('chatstate-received', account=self._account, + jid=contact.jid, contact=contact))
@ensure_enabled
===================================== gajim/groupchat_control.py ===================================== @@ -963,7 +963,7 @@ def check_focus_out_line(self): - remove previous line first """
- if app.window.is_chat_focused(self.account, self.room_jid): + if app.window.is_chat_active(self.account, self.room_jid): return
self.conv_textview.show_focus_out_line()
===================================== gajim/gtk/chat_list.py ===================================== @@ -37,6 +37,9 @@ def __init__(self, workspace_id):
self.show_all()
+ def is_visible(self): + return self.get_parent().get_property('child-widget') == self + def _on_destroy(self): GLib.source_remove(self._timer_id)
@@ -101,12 +104,11 @@ def remove_chat(self, account, jid): self.remove(row) row.destroy()
- def get_active_chat(self): + def get_selected_chat(self): row = self.get_selected_row() if row is None: return None - - return (row.account, row.jid) + return row
def contains_chat(self, account, jid): return self._chats.get((account, jid)) is not None @@ -132,9 +134,7 @@ def _on_message_received(self, event): return
row = self._chats.get((event.account, event.jid)) - if not (row.is_selected() and - self.get_toplevel().get_property('has-toplevel-focus')): - row.add_unread() + row.add_unread() row.set_last_message_text('Me', event.msgtxt)
@@ -218,6 +218,11 @@ def __init__(self, workspace_id, account, jid, type_):
self.show_all()
+ @property + def is_active(self): + return (self.is_selected() and + self.get_toplevel().get_property('is-active')) + def _on_state_flags_changed(self, _listboxrow, *args): state = self.get_state_flags() if (state & Gtk.StateFlags.PRELIGHT) != 0: @@ -233,10 +238,20 @@ def update_time(self): self._ui.timestamp_label.set_text( get_uf_relative_time(self._timestamp))
+ def _update_unread(self): + print('Update unread', self.account, self.jid, self._unread_count) + self._ui.unread_label.set_text(str(self._unread_count)) + self._ui.unread_label.set_visible(bool(self._unread_count)) + def add_unread(self): + if self.is_active: + return self._unread_count += 1 - self._ui.unread_label.set_text(str(self._unread_count)) - self._ui.unread_label.show() + self._update_unread() + + def reset_unread(self): + self._unread_count = 0 + self._update_unread()
def set_last_message_text(self, nickname, text): self._ui.message_label.set_text(text)
===================================== gajim/gtk/chat_list_stack.py ===================================== @@ -12,7 +12,7 @@
class ChatListStack(Gtk.Stack): - def __init__(self, ui, chat_stack): + def __init__(self, main_window, ui, chat_stack): Gtk.Stack.__init__(self) self.set_hexpand(True) self.set_vexpand(True) @@ -28,19 +28,30 @@ def __init__(self, ui, chat_stack): self._ui.search_entry.connect( 'search-changed', self._on_search_changed)
- def get_active_chat(self): + main_window.connect('notify::is-active', self._on_window_active) + + def _on_window_active(self, window, _param): + is_active = window.get_property('is-active') + if is_active: + chat = self.get_selected_chat() + if chat is not None: + chat.reset_unread() + + def get_selected_chat(self): workspace_id = self.get_visible_child_name() if workspace_id == 'empty': return None
chat_list = self._chat_lists[workspace_id] - return chat_list.get_active_chat() + return chat_list.get_selected_chat()
def is_chat_active(self, account, jid): - active = self.get_active_chat() - if active is None: + chat = self.get_selected_chat() + if chat is None: return False - return active == (account, jid) + if chat.account != account or chat.jid != jid: + return False + return chat.is_active
def _on_search_changed(self, search_entry): chat_list = self.get_visible_child() @@ -67,7 +78,10 @@ def _on_row_selected(self, _chat_list, row): if row is None: self._chat_stack.clear() return + self._chat_stack.show_chat(row.account, row.jid) + if row.is_active: + row.reset_unread()
def show_chat_list(self, workspace_id): current_workspace_id = self.get_visible_child_name()
===================================== gajim/gtk/main.py ===================================== @@ -45,7 +45,7 @@ def __init__(self): self.add(self._ui.main_grid)
self._chat_stack = ChatStack() - self._chat_list_stack = ChatListStack(self._ui, self._chat_stack) + self._chat_list_stack = ChatListStack(self, self._ui, self._chat_stack) self._ui.chat_list_scrolled.add(self._chat_list_stack)
self._account_side_bar = AccountSideBar() @@ -158,10 +158,7 @@ def get_workspace_bar(self): def get_active_workspace(self): return self._workspace_side_bar.get_active_workspace()
- def get_active_chat(self): - return self._chat_list_stack.get_active_chat() - - def is_chat_focused(self, account, jid): + def is_chat_active(self, account, jid): if not self.get_property('has-toplevel-focus'): return False return self._chat_list_stack.is_chat_active(account, jid)
===================================== gajim/gtk/util.py ===================================== @@ -856,3 +856,36 @@ def _destroy(*args):
def check_finalize(obj, name): weakref.finalize(obj, print, f'{name} has been finalized') + + +def _connect_destroy(sender, func, detailed_signal, handler, *args, **kwargs): + """Connect a bound method to a foreign object signal and disconnect + if the object the method is bound to emits destroy (Gtk.Widget subclass). + Also works if the handler is a nested function in a method and + references the method's bound object. + This solves the problem that the sender holds a strong reference + to the bound method and the bound to object doesn't get GCed. + """ + + if hasattr(handler, "__self__"): + obj = handler.__self__ + else: + # XXX: get the "self" var of the enclosing scope. + # Used for nested functions which ref the object but aren't methods. + # In case they don't ref "self" normal connect() should be used anyway. + index = handler.__code__.co_freevars.index("self") + obj = handler.__closure__[index].cell_contents + + assert obj is not sender + + handler_id = func(detailed_signal, handler, *args, **kwargs) + + def disconnect_cb(*args): + sender.disconnect(handler_id) + + obj.connect('destroy', disconnect_cb) + return handler_id + + +def connect_destroy(sender, *args, **kwargs): + return _connect_destroy(sender, sender.connect, *args, **kwargs)
View it on GitLab: https://dev.gajim.org/gajim/gajim/-/commit/abc6018484ac131058f52b1fdfb1960d5...