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