From e946120dc9d0a69b424aff82673d69bbe3f16776 Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Sun, 17 May 2026 02:02:27 +0200 Subject: [PATCH] Fixed urwid race/crash in conversations by neutral --- nomadnet/ui/textui/Conversations.py | 45 +++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/nomadnet/ui/textui/Conversations.py b/nomadnet/ui/textui/Conversations.py index 4adefff..57521e3 100644 --- a/nomadnet/ui/textui/Conversations.py +++ b/nomadnet/ui/textui/Conversations.py @@ -1,4 +1,5 @@ import RNS +import collections import os import shutil import time @@ -133,7 +134,40 @@ class ConversationsDisplay(): self.shortcuts_display = self.list_shortcuts self.widget = self.columns_widget - nomadnet.Conversation.created_callback = self.update_conversation_list + + self._pending_actions = collections.deque() + self._wake_fd = None + try: + self._wake_fd = self.app.ui.loop.watch_pipe(self._process_pending) + except Exception: + pass + + nomadnet.Conversation.created_callback = lambda: self._wake(self.update_conversation_list) + + def _process_pending(self, data): + while True: + try: + action = self._pending_actions.popleft() + except IndexError: + break + try: + action() + except Exception as e: + RNS.log("Conversations UI action failed: "+str(e), RNS.LOG_ERROR) + return True + + def _wake(self, action): + self._pending_actions.append(action) + if self._wake_fd is not None: + try: + os.write(self._wake_fd, b".") + return + except Exception: + pass + try: + self.app.ui.loop.set_alarm_in(0.0, lambda l, d: self._process_pending(None)) + except Exception: + pass def focus_change_event(self): if not self.dialog_open: @@ -1024,7 +1058,7 @@ class ConversationWidget(urwid.WidgetWrap): self.update_message_widgets() - self.conversation.register_changed_callback(self.conversation_changed) + self.conversation.register_changed_callback(self._on_conversation_changed_from_callback) #title_editor = MessageEdit(caption="\u270E", edit_text="", multiline=False) title_editor = MessageEdit(caption="", edit_text="", multiline=False) @@ -1243,6 +1277,13 @@ class ConversationWidget(urwid.WidgetWrap): else: return super(ConversationWidget, self).keypress(size, key) + def _on_conversation_changed_from_callback(self, conversation): + delegate = getattr(self, "delegate", None) + if delegate is not None and hasattr(delegate, "_wake"): + delegate._wake(lambda: self.conversation_changed(conversation)) + else: + self.conversation_changed(conversation) + def conversation_changed(self, conversation): if hasattr(self, "peer_info_widget"): self._update_peer_info()