From d237afea94c1c9f0b29ea755e5003b6fb9ea4352 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Sun, 12 Oct 2025 20:24:04 -0500 Subject: [PATCH] more attempts at leak fixes; thumbnailer plugin updates and corrections --- src/solarfm/core/controller_data.py | 1 + .../signals/file_action_signals_mixin.py | 13 +++----- .../mixins/signals/keyboard_signals_mixin.py | 2 +- src/solarfm/core/mixins/ui/grid_mixin.py | 28 +++++++++-------- src/solarfm/core/mixins/ui/tab_mixin.py | 23 ++++++++------ src/solarfm/core/widgets/icon_grid_widget.py | 31 +++++++++++++++++-- src/solarfm/core/widgets/tab_header_widget.py | 2 +- 7 files changed, 64 insertions(+), 36 deletions(-) diff --git a/src/solarfm/core/controller_data.py b/src/solarfm/core/controller_data.py index 35e2618..6a13dcb 100644 --- a/src/solarfm/core/controller_data.py +++ b/src/solarfm/core/controller_data.py @@ -54,6 +54,7 @@ class Controller_Data: self.ctrl_down = False self.shift_down = False self.alt_down = False + self.was_midified_key = None self._state = State() self.message_dialog = MessageWidget() diff --git a/src/solarfm/core/mixins/signals/file_action_signals_mixin.py b/src/solarfm/core/mixins/signals/file_action_signals_mixin.py index 9acce62..5910e43 100644 --- a/src/solarfm/core/mixins/signals/file_action_signals_mixin.py +++ b/src/solarfm/core/mixins/signals/file_action_signals_mixin.py @@ -20,6 +20,8 @@ class FileActionSignalsMixin: if tab.get_dir_watcher(): watcher = tab.get_dir_watcher() watcher.cancel() + watcher.disconnect(watcher.watch_id) + watcher.run_dispose() if settings_manager.is_debug(): logger.debug(f"Watcher Is Cancelled: {watcher.is_cancelled()}") @@ -30,8 +32,9 @@ class FileActionSignalsMixin: wid = tab.get_wid() tid = tab.get_id() - dir_watcher.connect("changed", self.dir_watch_updates, *(f"{wid}|{tid}",)) + watch_id = dir_watcher.connect("changed", self.dir_watch_updates, *(f"{wid}|{tid}",)) tab.set_dir_watcher(dir_watcher) + dir_watcher.watch_id = watch_id def dir_watch_updates(self, file_monitor, file, other_file = None, eve_type = None, tab_widget_id = None): if eve_type in [Gio.FileMonitorEvent.CREATED, Gio.FileMonitorEvent.DELETED, @@ -68,14 +71,6 @@ class FileActionSignalsMixin: if [wid, tid] in [state.wid, state.tid]: self.set_bottom_labels(tab) - wid, tid = None, None - notebook = None - tab = None - icon_grid = None - store = None - _store, tab_widget_id_label = None, None - state = None - return False def do_file_search(self, widget, eve = None): diff --git a/src/solarfm/core/mixins/signals/keyboard_signals_mixin.py b/src/solarfm/core/mixins/signals/keyboard_signals_mixin.py index 03446d0..eed30c5 100644 --- a/src/solarfm/core/mixins/signals/keyboard_signals_mixin.py +++ b/src/solarfm/core/mixins/signals/keyboard_signals_mixin.py @@ -34,7 +34,7 @@ class KeyboardSignalsMixin: self.alt_down = False def on_global_key_press_controller(self, eve, user_data): - keyname = Gdk.keyval_name(user_data.keyval).lower() + keyname = Gdk.keyval_name(user_data.keyval).lower() modifiers = Gdk.ModifierType(user_data.get_state() & ~Gdk.ModifierType.LOCK_MASK) self.was_midified_key = True if modifiers != 0 else False diff --git a/src/solarfm/core/mixins/ui/grid_mixin.py b/src/solarfm/core/mixins/ui/grid_mixin.py index 497c6ac..8500c77 100644 --- a/src/solarfm/core/mixins/ui/grid_mixin.py +++ b/src/solarfm/core/mixins/ui/grid_mixin.py @@ -26,30 +26,32 @@ class GridMixin: for file in files: store.append([None, file[0]]) - Gtk.main_iteration() self.generate_icons(tab, store, dir, files) # NOTE: Not likely called often from here but it could be useful if save_state and not trace_debug: self.fm_controller.save_state() - dir = None - files = None - + @daemon_threaded def generate_icons(self, tab, store, dir, files): for i, file in enumerate(files): - self.make_and_load_icon( i, store, tab, dir, file[0]) + self.make_and_load_icon(i, store, tab, dir, file[0]) - def update_store(self, i, store, icon): - itr = store.get_iter(i) - GLib.idle_add(self.insert_store, store, itr, icon.copy()) - itr = None - del icon - - @daemon_threaded def make_and_load_icon(self, i, store, tab, dir, file): icon = tab.create_icon(dir, file) - GLib.idle_add(self.update_store, i, store, icon) + # self.update_store(i, store, icon) + GLib.idle_add(self.update_store, i, store, icon.copy()) + icon.run_dispose() + + def update_store(self, i, store, icon): + try: + itr = store.get_iter(i) + except Exception: + return + + self.insert_store(store, itr, icon) + # GLib.idle_add(self.insert_store, store, itr, icon.copy()) + # icon.run_dispose() icon = None def get_icon(self, tab, dir, file): diff --git a/src/solarfm/core/mixins/ui/tab_mixin.py b/src/solarfm/core/mixins/ui/tab_mixin.py index 6ba6fdf..92e9c11 100644 --- a/src/solarfm/core/mixins/ui/tab_mixin.py +++ b/src/solarfm/core/mixins/ui/tab_mixin.py @@ -74,17 +74,25 @@ class TabMixin(GridMixin): watcher = tab.get_dir_watcher() watcher.cancel() + watcher.disconnect(watcher.watch_id) + watcher.run_dispose() self.get_fm_window(wid).delete_tab_by_id(tid) - tab_box.unload_signals() - icon_grid.unload_signals() - icon_grid.set_model(None) + tab_box.clear_signals_and_data() + icon_grid.clear_signals_and_data() self.builder.dereference_object(f"{wid}|{tid}|icon_grid") self.builder.dereference_object(f"{wid}|{tid}") notebook.remove_page( notebook.page_num(scroll) ) + tab_box.run_dispose() + icon_grid.run_dispose() + scroll.run_dispose() + tab_box.unparent() + icon_grid.unparent() + scroll.unparent() + if not settings_manager.is_trace_debug(): self.fm_controller.save_state() @@ -103,6 +111,8 @@ class TabMixin(GridMixin): _tab = window.get_tab_by_id(tid) watcher = _tab.get_dir_watcher() watcher.cancel() + watcher.disconnect(watcher.watch_id) + watcher.run_dispose() window.get_all_tabs().insert(new_index, window.get_all_tabs().pop(i)) tab = window.get_tab_by_id(tid) @@ -110,11 +120,6 @@ class TabMixin(GridMixin): if not settings_manager.is_trace_debug(): self.fm_controller.save_state() - wid, tid = None, None - window = None - tab = None - - def on_tab_switch_update(self, notebook, content = None, index = None): self.selected_files.clear() wid, tid = content.get_children()[0].get_name().split("|") @@ -123,8 +128,6 @@ class TabMixin(GridMixin): self.set_path_text(wid, tid) self.set_window_title() - wid, tid = None, None - def get_id_from_tab_box(self, tab_box): return tab_box.tab.get_id() diff --git a/src/solarfm/core/widgets/icon_grid_widget.py b/src/solarfm/core/widgets/icon_grid_widget.py index bc487a0..fe80006 100644 --- a/src/solarfm/core/widgets/icon_grid_widget.py +++ b/src/solarfm/core/widgets/icon_grid_widget.py @@ -1,4 +1,5 @@ # Python imports +import gc # Lib imports import gi @@ -77,14 +78,14 @@ class IconGridWidget(Gtk.IconView): return self.get_model() def clear_and_set_new_store(self): - self.set_model(None) + self._clear_store() self.set_model( Gtk.ListStore( GdkPixbuf.Pixbuf or GdkPixbuf.PixbufAnimation or None, str or None ) ) - def unload_signals(self): + def clear_signals_and_data(self): self.unset_model_drag_dest() self.unset_model_drag_source() @@ -92,3 +93,29 @@ class IconGridWidget(Gtk.IconView): self.disconnect(handle_id) self._handler_ids.clear() + self._clear_store() + + def _clear_store(self): + store = self.get_model() + + if store: + iter = store.get_iter_first() + while iter: + next_iter = store.iter_next(iter) + item = store.get_value(iter, 0) + + if item: + item.run_dispose() + item = None + + store.set_value(iter, 0, None) + store.set_value(iter, 1, None) + store.unref_node(iter) + iter = next_iter + + store.clear() + store.run_dispose() + del store + gc.collect() + + self.set_model(None) diff --git a/src/solarfm/core/widgets/tab_header_widget.py b/src/solarfm/core/widgets/tab_header_widget.py index 7f3f1c8..e7a7888 100644 --- a/src/solarfm/core/widgets/tab_header_widget.py +++ b/src/solarfm/core/widgets/tab_header_widget.py @@ -47,7 +47,7 @@ class TabHeaderWidget(Gtk.Box): self.show_all() - def unload_signals(self): + def clear_signals_and_data(self): self.close_btn.disconnect(self._handler_id) self._close_tab = None self._handler_id = None \ No newline at end of file