summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorexquo <62397152+exquo@users.noreply.github.com>2023-03-29 09:03:31 +0000
committerGitHub <noreply@github.com>2023-03-29 11:03:31 +0200
commitab23c8bea814cbbc17bf5ace66abd62ab4c34243 (patch)
treeacef7d88b5c3b121e23947d359738eea87255f9f
parent9e7ec1c69d33c7b365b081ca72074e6c6979c85f (diff)
downloadurwid-ab23c8bea814cbbc17bf5ace66abd62ab4c34243.tar.gz
Reconnect the 'modified' signal after setting a new ListBox.body (#474)
Ensure that the cached canvas is marked invalidated when a newly set ListBox.body is modified at runtime. Fixes #428
-rw-r--r--urwid/listbox.py21
-rw-r--r--urwid/tests/test_listbox.py11
2 files changed, 24 insertions, 8 deletions
diff --git a/urwid/listbox.py b/urwid/listbox.py
index fd4b117..e49edaa 100644
--- a/urwid/listbox.py
+++ b/urwid/listbox.py
@@ -27,7 +27,7 @@ from urwid.canvas import SolidCanvas, CanvasCombine
from urwid.widget import Widget, nocache_widget_render_instance, BOX, GIVEN
from urwid.decoration import calculate_top_bottom_filler, normalize_valign
from urwid import signals
-from urwid.signals import connect_signal
+from urwid.signals import connect_signal, disconnect_signal
from urwid.monitored_list import MonitoredList, MonitoredFocusList
from urwid.container import WidgetContainerMixin
from urwid.command_map import (CURSOR_UP, CURSOR_DOWN,
@@ -250,13 +250,6 @@ class ListBox(Widget, WidgetContainerMixin):
:type body: ListWalker
"""
self._set_body(body)
- try:
- connect_signal(self._body, "modified", self._invalidate)
- except NameError:
- # our list walker has no modified signal so we must not
- # cache our canvases because we don't know when our
- # content has changed
- self.render = nocache_widget_render_instance(self)
# offset_rows is the number of rows between the top of the view
# and the top of the focused item
@@ -281,10 +274,22 @@ class ListBox(Widget, WidgetContainerMixin):
return self._body
def _set_body(self, body):
+ try:
+ disconnect_signal(self._body, "modified", self._invalidate)
+ except AttributeError:
+ # _body is not yet assigned
+ pass
if getattr(body, 'get_focus', None):
self._body = body
else:
self._body = SimpleListWalker(body)
+ try:
+ connect_signal(self._body, "modified", self._invalidate)
+ except NameError:
+ # our list walker has no modified signal so we must not
+ # cache our canvases because we don't know when our
+ # content has changed
+ self.render = nocache_widget_render_instance(self)
self._invalidate()
body = property(_get_body, _set_body, doc="""
diff --git a/urwid/tests/test_listbox.py b/urwid/tests/test_listbox.py
index adeb8d5..9d2eddb 100644
--- a/urwid/tests/test_listbox.py
+++ b/urwid/tests/test_listbox.py
@@ -802,3 +802,14 @@ class ZeroHeightContentsTest(unittest.TestCase):
lb.keypress((40,10), 'up')
self.assertEqual(lb.get_focus()[1], 1)
+
+class ListBoxSetBodyTest(unittest.TestCase):
+ def test_signal_connected(self):
+ lb = urwid.ListBox([])
+ lb.body = urwid.SimpleListWalker([])
+ self.assertEqual(
+ lb.body._urwid_signals['modified'][0][1],
+ lb._invalidate,
+ "outdated canvas cache reuse "
+ "after ListWalker's contents modified"
+ )