From 8f48c5ede7e1da18f85daae9bda5a4b68272498b Mon Sep 17 00:00:00 2001
From: Florent Le Coz <louiz@louiz.org>
Date: Mon, 7 Mar 2011 21:41:13 +0100
Subject: Inputs are garbage collected, making MucListTab collectable. Memory
 improvement issues.

---
 src/core.py    |  9 ++++++---
 src/tabs.py    | 16 +++++-----------
 src/windows.py | 23 +++++++++++++++++++++++
 3 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/src/core.py b/src/core.py
index d113fe25..99ae27d1 100644
--- a/src/core.py
+++ b/src/core.py
@@ -1200,12 +1200,15 @@ class Core(object):
         if isinstance(tab, tabs.RosterInfoTab) or\
                 isinstance(tab, tabs.InfoTab):
             return              # The tab 0 should NEVER be closed
+        del tab.key_func      # Remove self references
+        del tab.commands      # and make the object collectable
         tab.on_close()
         self.tabs.remove(tab)
-        self.rotate_rooms_left()
-        del tab.key_func        # Remove self references
-        del tab.commands        # and make the object collectable
+        import gc
+        gc.collect()
+        log.debug('___ Referrers of closing tab:\n%s\n______' % gc.get_referrers(tab))
         del tab
+        self.refresh_window()
 
     def move_separator(self):
         """
diff --git a/src/tabs.py b/src/tabs.py
index 6788a49d..cd13273a 100644
--- a/src/tabs.py
+++ b/src/tabs.py
@@ -61,6 +61,7 @@ class Tab(object):
     number = 0
     tab_core = None
     def __init__(self):
+        self.input = None
         self._color_state = theme.COLOR_TAB_NORMAL
         self.need_resize = False
         self.nb = Tab.number
@@ -226,10 +227,10 @@ class Tab(object):
         """
         Called when the tab is to be closed
         """
-        pass
+        self.input.on_delete()
 
     def __del__(self):
-        log.debug('Closing tab %s' % self.__class__.__name__)
+        log.debug('------ Closing tab %s' % self.__class__.__name__)
 
 class ChatTab(Tab):
     """
@@ -384,9 +385,6 @@ class InfoTab(ChatTab, TabWithInfoWin):
     def just_before_refresh(self):
         return
 
-    def on_close(self):
-        return
-
 class MucTab(ChatTab, TabWithInfoWin):
     """
     The tab containing a multi-user-chat room.
@@ -726,9 +724,6 @@ class MucTab(ChatTab, TabWithInfoWin):
     def just_before_refresh(self):
         return
 
-    def on_close(self):
-        return
-
     def handle_presence(self, presence):
         from_nick = presence['from'].resource
         from_room = presence['from'].bare
@@ -1036,9 +1031,6 @@ class PrivateTab(ChatTab, TabWithInfoWin):
     def just_before_refresh(self):
         return
 
-    def on_close(self):
-        return
-
     def rename_user(self, old_nick, new_nick):
         """
         The user changed her nick in the corresponding muc: update the tab’s name and
@@ -1474,6 +1466,7 @@ class ConversationTab(ChatTab, TabWithInfoWin):
         return
 
     def on_close(self):
+        Tab.on_close(self)
         if config.get('send_chat_states', 'true') == 'true':
             self.send_chat_state('gone')
 
@@ -1541,6 +1534,7 @@ class MucListTab(Tab):
         self.input.do_command("/") # we add the slash
 
     def close(self, arg=None):
+        self.input.on_delete()
         self.core.close_tab(self)
 
     def join_selected_no_focus(self):
diff --git a/src/windows.py b/src/windows.py
index a949ca99..e6ca9800 100644
--- a/src/windows.py
+++ b/src/windows.py
@@ -734,6 +734,13 @@ class Input(Win):
         self.on_input = None    # callback called on any key pressed
         self.color = None       # use this color on addstr
 
+    def on_delete(self):
+        """
+        Remove all references kept to a tab, so that the tab
+        can be garbage collected
+        """
+        del self.key_func
+
     def set_color(self, color):
         self.color = color
         self.rewrite_text()
@@ -1171,6 +1178,22 @@ class CommandInput(Input):
             self.addstr(0, cursor_pos, '') # WTF, this works but .move() doesn't…
             self._refresh()
 
+    def on_delete(self):
+        """
+        SERIOUSLY BIG WTF.
+
+        I can do
+        self.key_func.clear()
+
+        but not
+        del self.key_func
+        because that would raise an AttributeError exception. WTF.
+        """
+        self.on_abort = None
+        self.on_success = None
+        self.on_input = None
+        self.key_func.clear()
+
 class VerticalSeparator(Win):
     """
     Just a one-column window, with just a line in it, that is
-- 
cgit v1.2.3