Attempting to prompt for gc; About page updates; small non crit errors fixed

This commit is contained in:
itdominator 2024-07-04 17:24:31 -05:00
parent ce00970171
commit 9d3a5b9f3b
20 changed files with 349 additions and 118 deletions

View File

@ -122,7 +122,6 @@ class Plugin(PluginBase):
uri = state.uris[0] uri = state.uris[0]
path = state.tab.get_current_directory() path = state.tab.get_current_directory()
properties = self._set_ui_data(uri, path) properties = self._set_ui_data(uri, path)
response = self._properties_dialog.run() response = self._properties_dialog.run()
if response in [Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT]: if response in [Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT]:
@ -168,13 +167,13 @@ class Plugin(PluginBase):
def _set_ui_data(self, uri, path): def _set_ui_data(self, uri, path):
properties = Properties() properties = Properties()
file_info = Gio.File.new_for_path(uri).query_info(attributes="standard::*,owner::*,time::access,time::changed", file_info = Gio.File.new_for_path(uri).query_info(attributes = "standard::*,owner::*,time::access,time::changed",
flags=Gio.FileQueryInfoFlags.NONE, flags = Gio.FileQueryInfoFlags.NONE,
cancellable=None) cancellable = None)
is_symlink = file_info.get_attribute_as_string("standard::is-symlink") is_symlink = file_info.get_attribute_as_string("standard::is-symlink")
properties.file_uri = uri properties.file_uri = uri
properties.file_target = file_info.get_attribute_as_string("standard::symlink-target") if is_symlink else "" properties.file_target = file_info.get_attribute_as_string("standard::symlink-target") if is_symlink in [True, "TRUE"] else ""
properties.file_name = file_info.get_display_name() properties.file_name = file_info.get_display_name()
properties.file_location = path properties.file_location = path
properties.mime_type = file_info.get_content_type() properties.mime_type = file_info.get_content_type()
@ -186,7 +185,7 @@ class Plugin(PluginBase):
# NOTE: Read = 4, Write = 2, Exec = 1 # NOTE: Read = 4, Write = 2, Exec = 1
command = ["stat", "-c", "%a", uri] command = ["stat", "-c", "%a", uri]
with subprocess.Popen(command, stdout=subprocess.PIPE) as proc: with subprocess.Popen(command, stdout = subprocess.PIPE) as proc:
properties.chmod_stat = list(proc.stdout.read().decode("UTF-8").strip()) properties.chmod_stat = list(proc.stdout.read().decode("UTF-8").strip())
owner = self._chmod_map[f"{properties.chmod_stat[0]}"] owner = self._chmod_map[f"{properties.chmod_stat[0]}"]
group = self._chmod_map[f"{properties.chmod_stat[1]}"] group = self._chmod_map[f"{properties.chmod_stat[1]}"]

View File

@ -51,4 +51,4 @@ if __name__ == "__main__":
main(args, unknownargs) main(args, unknownargs)
except Exception as e: except Exception as e:
traceback.print_exc() traceback.print_exc()
quit() quit()

View File

@ -135,46 +135,48 @@ class Controller(UIMixin, SignalsMixins, Controller_Data):
event_system.emit("hide_rename_file_menu") event_system.emit("hide_rename_file_menu")
if action == "open": if action == "open":
event_system.emit("open_files") event_system.emit_and_await("open_files")
if action == "open_with": if action == "open_with":
event_system.emit("show_appchooser_menu") event_system.emit_and_await("show_appchooser_menu")
if action == "open_2_new_tab": if action == "open_2_new_tab":
event_system.emit("open_2_new_tab") event_system.emit_and_await("open_2_new_tab")
if action == "execute": if action == "execute":
event_system.emit("execute_files") event_system.emit_and_await("execute_files")
if action == "execute_in_terminal": if action == "execute_in_terminal":
event_system.emit("execute_files", (True,)) event_system.emit_and_await("execute_files", (True,))
if action == "rename": if action == "rename":
event_system.emit("rename_files") event_system.emit_and_await("rename_files")
if action == "cut": if action == "cut":
event_system.emit("cut_files") event_system.emit_and_await("cut_files")
if action == "copy": if action == "copy":
event_system.emit("copy_files") event_system.emit_and_await("copy_files")
if action == "copy_path": if action == "copy_path":
event_system.emit("copy_path") event_system.emit_and_await("copy_path")
if action == "copy_name": if action == "copy_name":
event_system.emit("copy_name") event_system.emit_and_await("copy_name")
if action == "copy_path_name": if action == "copy_path_name":
event_system.emit("copy_path_name") event_system.emit_and_await("copy_path_name")
if action == "paste": if action == "paste":
event_system.emit("paste_files") event_system.emit_and_await("paste_files")
if action == "create": if action == "create":
event_system.emit("create_files") event_system.emit_and_await("create_files")
if action in ["save_session", "save_session_as", "load_session"]: if action in ["save_session", "save_session_as", "load_session"]:
event_system.emit("save_load_session", (action)) event_system.emit_and_await("save_load_session", (action))
if action == "about_page": if action == "about_page":
event_system.emit("show_about_page") event_system.emit_and_await("show_about_page")
if action == "io_popup": if action == "io_popup":
event_system.emit("show_io_popup") event_system.emit_and_await("show_io_popup")
if action == "plugins_popup": if action == "plugins_popup":
event_system.emit("show_plugins_popup") event_system.emit_and_await("show_plugins_popup")
if action == "messages_popup": if action == "messages_popup":
event_system.emit("show_messages_popup") event_system.emit_and_await("show_messages_popup")
if action == "ui_debug": if action == "ui_debug":
event_system.emit("load_interactive_debug") event_system.emit_and_await("load_interactive_debug")
if action == "tear_down": if action == "tear_down":
event_system.emit("tear_down") event_system.emit_and_await("tear_down")
action = None
def go_home(self, widget=None, eve=None): def go_home(self, widget=None, eve=None):
@ -192,11 +194,14 @@ class Controller(UIMixin, SignalsMixins, Controller_Data):
def tggl_top_main_menubar(self, widget=None, eve=None): def tggl_top_main_menubar(self, widget=None, eve=None):
top_main_menubar = self.builder.get_object("top_main_menubar") top_main_menubar = self.builder.get_object("top_main_menubar")
top_main_menubar.hide() if top_main_menubar.is_visible() else top_main_menubar.show() top_main_menubar.hide() if top_main_menubar.is_visible() else top_main_menubar.show()
top_main_menubar = None
def open_terminal(self, widget=None, eve=None): def open_terminal(self, widget=None, eve=None):
wid, tid = self.fm_controller.get_active_wid_and_tid() wid, tid = self.fm_controller.get_active_wid_and_tid()
tab = self.get_fm_window(wid).get_tab_by_id(tid) tab = self.get_fm_window(wid).get_tab_by_id(tid)
tab.execute([f"{tab.terminal_app}"], start_dir=tab.get_current_directory()) tab.execute([f"{tab.terminal_app}"], start_dir=tab.get_current_directory())
wid, tid, tab = None, None, None
def go_to_path(self, path: str): def go_to_path(self, path: str):
self.builder.get_object("path_entry").set_text(path) self.builder.get_object("path_entry").set_text(path)

View File

@ -114,6 +114,9 @@ class Controller_Data:
uris.append(fpath) uris.append(fpath)
tab = None
dir = None
return uris return uris

View File

@ -68,6 +68,14 @@ class FileActionSignalsMixin:
if [wid, tid] in [state.wid, state.tid]: if [wid, tid] in [state.wid, state.tid]:
self.set_bottom_labels(tab) 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 return False
def do_file_search(self, widget, eve = None): def do_file_search(self, widget, eve = None):
@ -90,4 +98,4 @@ class FileActionSignalsMixin:
items = icon_grid.get_selected_items() items = icon_grid.get_selected_items()
if len(items) > 0: if len(items) > 0:
icon_grid.scroll_to_path(items[0], False, 0.5, 0.5) icon_grid.scroll_to_path(items[0], False, 0.5, 0.5)

View File

@ -45,7 +45,10 @@ class GridMixin:
if save_state and not trace_debug: if save_state and not trace_debug:
self.fm_controller.save_state() self.fm_controller.save_state()
dir = None
files = None
@daemon_threaded
def generate_icons(self, tab, store, dir, files): def generate_icons(self, tab, store, dir, files):
for i, file in enumerate(files): for i, file in enumerate(files):
# GLib.Thread(f"{i}", self.make_and_load_icon, i, store, tab, dir, file[0]) # GLib.Thread(f"{i}", self.make_and_load_icon, i, store, tab, dir, file[0])
@ -54,14 +57,16 @@ class GridMixin:
def update_store(self, i, store, icon): def update_store(self, i, store, icon):
itr = store.get_iter(i) itr = store.get_iter(i)
GLib.idle_add(self.insert_store, store, itr, icon) GLib.idle_add(self.insert_store, store, itr, icon)
itr = None
@daemon_threaded @daemon_threaded
def make_and_load_icon(self, i, store, tab, dir, file): def make_and_load_icon(self, i, store, tab, dir, file):
icon = tab.create_icon(dir, file) icon = tab.create_icon(dir, file)
self.update_store(i, store, icon) self.update_store(i, store, icon)
icon = None
def get_icon(self, tab, dir, file): def get_icon(self, tab, dir, file):
return tab.create_icon(dir, file) tab.create_icon(dir, file)
# @daemon_threaded # @daemon_threaded
@ -159,6 +164,7 @@ class GridMixin:
store = icon_grid.get_model() store = icon_grid.get_model()
tab_label = notebook.get_tab_label(obj).get_children()[0] tab_label = notebook.get_tab_label(obj).get_children()[0]
icon_grid = None
return store, tab_label return store, tab_label
def get_icon_grid_from_notebook(self, notebook, _name): def get_icon_grid_from_notebook(self, notebook, _name):

View File

@ -41,16 +41,26 @@ class TabMixin(GridMixin):
notebook.set_tab_reorderable(scroll, True) notebook.set_tab_reorderable(scroll, True)
self.fm_controller.set_wid_and_tid(wid, tab.get_id()) self.fm_controller.set_wid_and_tid(wid, tab.get_id())
path_entry.set_text(tab.get_current_directory()) # path_entry.set_text(tab.get_current_directory())
event_system.emit("go_to_path", (tab.get_current_directory(),)) # NOTE: Not efficent if I understand how
notebook.show_all() notebook.show_all()
notebook.set_current_page(index) notebook.set_current_page(index)
ctx = notebook.get_style_context() ctx = notebook.get_style_context()
ctx.add_class("notebook-unselected-focus") ctx.add_class("notebook-unselected-focus")
self.load_store(tab, store) self.load_store(tab, store)
self.set_window_title() event_system.emit("set_window_title", (tab.get_current_directory(),))
self.set_file_watcher(tab) self.set_file_watcher(tab)
tab_widget = None
scroll, store = None, None
index = None
notebook = None
path_entry = None
tab = None
ctx = None
def get_tab_widget(self, tab): def get_tab_widget(self, tab):
tab_widget = self.create_tab_widget() tab_widget = self.create_tab_widget()
tab_widget.tab = tab tab_widget.tab = tab
@ -63,6 +73,7 @@ class TabMixin(GridMixin):
def close_tab(self, button, eve = None): def close_tab(self, button, eve = None):
notebook = button.get_parent().get_parent() notebook = button.get_parent().get_parent()
if notebook.get_n_pages() == 1: if notebook.get_n_pages() == 1:
notebook = None
return return
tab_box = button.get_parent() tab_box = button.get_parent()
@ -79,25 +90,35 @@ class TabMixin(GridMixin):
self.builder.dereference_object(f"{wid}|{tid}|icon_grid") self.builder.dereference_object(f"{wid}|{tid}|icon_grid")
self.builder.dereference_object(f"{wid}|{tid}") self.builder.dereference_object(f"{wid}|{tid}")
icon_grid.set_model(None)
iter = store.get_iter_first()
while iter:
next_iter = store.iter_next(iter)
store.unref_node(iter)
iter = next_iter
store.clear()
store.run_dispose() store.run_dispose()
icon_grid.set_model(None)
icon_grid.run_dispose() icon_grid.run_dispose()
scroll.run_dispose() scroll.run_dispose()
tab_box.run_dispose() tab_box.run_dispose()
del store iter = None
del icon_grid wid, tid = None, None
del scroll store = None
del tab_box icon_grid = None
del watcher scroll = None
del tab tab_box = None
watcher = None
tab = None
notebook = None
if not settings_manager.is_trace_debug(): if not settings_manager.is_trace_debug():
self.fm_controller.save_state() self.fm_controller.save_state()
self.set_window_title() self.set_window_title()
gc.collect() gc.collect()
# NOTE: Not actually getting called even tho set in the glade file... # NOTE: Not actually getting called even tho set in the glade file...
@ -121,6 +142,11 @@ class TabMixin(GridMixin):
if not settings_manager.is_trace_debug(): if not settings_manager.is_trace_debug():
self.fm_controller.save_state() self.fm_controller.save_state()
wid, tid = None, None
window = None
tab = None
def on_tab_switch_update(self, notebook, content = None, index = None): def on_tab_switch_update(self, notebook, content = None, index = None):
self.selected_files.clear() self.selected_files.clear()
wid, tid = content.get_children()[0].get_name().split("|") wid, tid = content.get_children()[0].get_name().split("|")
@ -129,6 +155,8 @@ class TabMixin(GridMixin):
self.set_path_text(wid, tid) self.set_path_text(wid, tid)
self.set_window_title() self.set_window_title()
wid, tid = None, None
def get_id_from_tab_box(self, tab_box): def get_id_from_tab_box(self, tab_box):
return tab_box.tab.get_id() return tab_box.tab.get_id()
@ -146,6 +174,8 @@ class TabMixin(GridMixin):
state.tab.load_directory() state.tab.load_directory()
self.load_store(state.tab, state.store) self.load_store(state.tab, state.store)
state = None
def update_tab(self, tab_label, tab, store, wid, tid): def update_tab(self, tab_label, tab, store, wid, tid):
self.load_store(tab, store) self.load_store(tab, store)
self.set_path_text(wid, tid) self.set_path_text(wid, tid)
@ -186,16 +216,38 @@ class TabMixin(GridMixin):
if isinstance(focused_obj, Gtk.Entry): if isinstance(focused_obj, Gtk.Entry):
self.process_path_menu(widget, tab, dir) self.process_path_menu(widget, tab, dir)
action = None
store = None
if path.endswith(".") or path == dir: if path.endswith(".") or path == dir:
tab_label = None
notebook = None
wid, tid = None, None
path = None
tab = None
return return
if not tab.set_path(path): if not tab.set_path(path):
tab_label = None
notebook = None
wid, tid = None, None
path = None
tab = None
return return
icon_grid = self.get_icon_grid_from_notebook(notebook, f"{wid}|{tid}") icon_grid = self.get_icon_grid_from_notebook(notebook, f"{wid}|{tid}")
icon_grid.clear_and_set_new_store() icon_grid.clear_and_set_new_store()
self.update_tab(tab_label, tab, icon_grid.get_store(), wid, tid) self.update_tab(tab_label, tab, icon_grid.get_store(), wid, tid)
action = None
wid, tid = None, None
notebook = None
store, tab_label = None, None
path = None
tab = None
icon_grid = None
def process_path_menu(self, gtk_entry, tab, dir): def process_path_menu(self, gtk_entry, tab, dir):
path_menu_buttons = self.builder.get_object("path_menu_buttons") path_menu_buttons = self.builder.get_object("path_menu_buttons")
query = gtk_entry.get_text().replace(dir, "") query = gtk_entry.get_text().replace(dir, "")
@ -212,6 +264,10 @@ class TabMixin(GridMixin):
path_menu_buttons.add(button) path_menu_buttons.add(button)
show_path_menu = True show_path_menu = True
path_menu_buttons = None
query = None
files = None
if not show_path_menu: if not show_path_menu:
event_system.emit("hide_path_menu") event_system.emit("hide_path_menu")
else: else:
@ -242,10 +298,17 @@ class TabMixin(GridMixin):
path_entry.set_position(-1) path_entry.set_position(-1)
event_system.emit("hide_path_menu") event_system.emit("hide_path_menu")
state = None
path = None
path_entry = None
def show_hide_hidden_files(self): def show_hide_hidden_files(self):
wid, tid = self.fm_controller.get_active_wid_and_tid() wid, tid = self.fm_controller.get_active_wid_and_tid()
tab = self.get_fm_window(wid).get_tab_by_id(tid) tab = self.get_fm_window(wid).get_tab_by_id(tid)
tab.set_hiding_hidden(not tab.is_hiding_hidden()) tab.set_hiding_hidden(not tab.is_hiding_hidden())
tab.load_directory() tab.load_directory()
self.builder.get_object("refresh_tab").released() self.builder.get_object("refresh_tab").released()
wid, tid = None, None
tab = None

View File

@ -46,11 +46,19 @@ class WindowMixin(TabMixin):
self.window.set_title(f"{app_name} ~ {dir}") self.window.set_title(f"{app_name} ~ {dir}")
self.set_bottom_labels(tab) self.set_bottom_labels(tab)
wid, tid = None, None
notebook = None
tab = None
dir = None
def set_path_text(self, wid, tid): def set_path_text(self, wid, tid):
path_entry = self.builder.get_object("path_entry") path_entry = self.builder.get_object("path_entry")
tab = self.get_fm_window(wid).get_tab_by_id(tid) tab = self.get_fm_window(wid).get_tab_by_id(tid)
path_entry.set_text(tab.get_current_directory()) path_entry.set_text(tab.get_current_directory())
path_entry = None
tab = None
def grid_set_selected_items(self, icons_grid): def grid_set_selected_items(self, icons_grid):
new_items = icons_grid.get_selected_items() new_items = icons_grid.get_selected_items()
items_size = len(new_items) items_size = len(new_items)
@ -164,6 +172,12 @@ class WindowMixin(TabMixin):
if target not in current: if target not in current:
self.fm_controller.set_wid_and_tid(wid, tid) self.fm_controller.set_wid_and_tid(wid, tid)
current = None
target = None
wid, tid = None, None
store = None
path_at_loc = None
def grid_on_drag_data_received(self, widget, drag_context, x, y, data, info, time): def grid_on_drag_data_received(self, widget, drag_context, x, y, data, info, time):
if info == 80: if info == 80:
@ -183,4 +197,4 @@ class WindowMixin(TabMixin):
Gtk.drag_finish(drag_context, False, False, time) Gtk.drag_finish(drag_context, False, False, time)
def create_new_tab_notebook(self, widget=None, wid=None, path=None): def create_new_tab_notebook(self, widget=None, wid=None, path=None):
self.create_tab(wid, None, path) self.create_tab(wid, None, path)

View File

@ -35,7 +35,7 @@ class UIMixin(PaneMixin, WindowMixin):
nickname = session["window"]["Nickname"] nickname = session["window"]["Nickname"]
tabs = session["window"]["tabs"] tabs = session["window"]["tabs"]
isHidden = True if session["window"]["isHidden"] == "True" else False isHidden = True if session["window"]["isHidden"] == "True" else False
event_system.emit("load_files_view_state", (nickname, tabs, isHidden)) event_system.emit_and_await("load_files_view_state", (nickname, tabs, isHidden))
def _focus_last_visible_notebook(self, icon_grid): def _focus_last_visible_notebook(self, icon_grid):
@ -47,6 +47,8 @@ class UIMixin(PaneMixin, WindowMixin):
icon_grid.event(Gdk.Event().new(type = Gdk.EventType.BUTTON_RELEASE)) icon_grid.event(Gdk.Event().new(type = Gdk.EventType.BUTTON_RELEASE))
window = None
def _current_loading_process(self, session_json = None): def _current_loading_process(self, session_json = None):
if session_json: if session_json:
for j, value in enumerate(session_json): for j, value in enumerate(session_json):

View File

@ -16,10 +16,7 @@ class ContextMenuWidget(Gtk.Menu):
def __init__(self): def __init__(self):
super(ContextMenuWidget, self).__init__() super(ContextMenuWidget, self).__init__()
self.builder = settings_manager.get_builder() self._builder = Gtk.Builder()
self._builder = Gtk.Builder()
self._context_menu_data = settings_manager.get_context_menu_data()
self._window = settings_manager.get_main_window()
self._setup_styling() self._setup_styling()
self._setup_signals() self._setup_signals()
@ -32,14 +29,48 @@ class ContextMenuWidget(Gtk.Menu):
def _setup_signals(self): def _setup_signals(self):
event_system.subscribe("show_context_menu", self.show_context_menu) event_system.subscribe("show_context_menu", self.show_context_menu)
event_system.subscribe("hide_context_menu", self.hide_context_menu) event_system.subscribe("hide_context_menu", self.hide_context_menu)
settings_manager.register_signals_to_builder([self,], self._builder) settings_manager.register_signals_to_builder(self, self._builder)
def _load_widgets(self): def _load_widgets(self):
self.builder = settings_manager.get_builder()
self._window = settings_manager.get_main_window()
self._context_menu_data = settings_manager.get_context_menu_data()
self.builder.expose_object("context_menu", self)
self.build_context_menu() self.build_context_menu()
def _emit(self, menu_item, type): def _emit(self, menu_item, type):
event_system.emit("do_action_from_menu_controls", type) event_system.emit("do_action_from_menu_controls", type)
def build_context_menu(self) -> None:
data = self._context_menu_data
plugins_entry = None
for key, value in data.items():
entry = self.make_menu_item(key, value)
self.append(entry)
if key == "Plugins":
plugins_entry = entry
self.attach_to_widget(self._window, None)
self.show_all()
if plugins_entry:
self.builder.expose_object("context_menu_plugins", plugins_entry.get_submenu())
def make_menu_item(self, label, data) -> Gtk.MenuItem:
if isinstance(data, dict):
return self.make_submenu(label, data)
elif isinstance(data, list):
entry = Gtk.ImageMenuItem(label)
icon = getattr(Gtk, f"{data[0]}")
entry.set_image( Gtk.Image(stock=icon) )
entry.set_always_show_image(True)
entry.connect("activate", self._emit, (data[1]))
return entry
def make_submenu(self, name, data): def make_submenu(self, name, data):
menu = Gtk.Menu() menu = Gtk.Menu()
menu_item = Gtk.MenuItem(name) menu_item = Gtk.MenuItem(name)
@ -57,36 +88,9 @@ class ContextMenuWidget(Gtk.Menu):
menu_item.set_submenu(menu) menu_item.set_submenu(menu)
return menu_item return menu_item
def make_menu_item(self, label, data) -> Gtk.MenuItem:
if isinstance(data, dict):
return self.make_submenu(label, data)
elif isinstance(data, list):
entry = Gtk.ImageMenuItem(label)
icon = getattr(Gtk, f"{data[0]}")
entry.set_image( Gtk.Image(stock=icon) )
entry.set_always_show_image(True)
entry.connect("activate", self._emit, (data[1]))
return entry
def build_context_menu(self) -> None: def show_context_menu(self, widget = None, eve = None):
data = self._context_menu_data
plugins_entry = None
for key, value in data.items():
entry = self.make_menu_item(key, value)
self.append(entry)
if key == "Plugins":
plugins_entry = entry
self.attach_to_widget(self._window, None)
self.builder.expose_object("context_menu", self)
self.show_all()
if plugins_entry:
self.builder.expose_object("context_menu_plugins", plugins_entry.get_submenu())
def show_context_menu(self, widget=None, eve=None):
self.builder.get_object("context_menu").popup_at_pointer(None) self.builder.get_object("context_menu").popup_at_pointer(None)
def hide_context_menu(self, widget=None, eve=None): def hide_context_menu(self, widget = None, eve = None):
self.builder.get_object("context_menu").popdown() self.builder.get_object("context_menu").popdown()

View File

@ -39,11 +39,10 @@ class AboutWidget:
self.about_page = self._builder.get_object("about_page") self.about_page = self._builder.get_object("about_page")
builder.expose_object(f"about_page", self.about_page) builder.expose_object(f"about_page", self.about_page)
def show_about_page(self, widget = None, eve = None):
def show_about_page(self, widget=None, eve=None):
response = self.about_page.run() response = self.about_page.run()
if response in [Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT]: if response in [Gtk.ResponseType.CANCEL, Gtk.ResponseType.DELETE_EVENT]:
self.hide_about_page() self.hide_about_page()
def hide_about_page(self, widget=None, eve=None): def hide_about_page(self, widget = None, eve = None):
self.about_page.hide() self.about_page.hide()

View File

@ -31,7 +31,6 @@ class GridMixin:
# return # return
dir = tab.get_current_directory() dir = tab.get_current_directory()
files = tab.get_files() files = tab.get_files()
@ -46,32 +45,56 @@ class GridMixin:
if save_state and not trace_debug: if save_state and not trace_debug:
self.fm_controller.save_state() self.fm_controller.save_state()
dir = None
files = None
@daemon_threaded @daemon_threaded
def generate_icons(self, tab, store, dir, files): def generate_icons(self, tab, store, dir, files):
try: for i, file in enumerate(files):
loop = asyncio.get_running_loop() # GLib.Thread(f"{i}", self.make_and_load_icon, i, store, tab, dir, file[0])
except RuntimeError: self.make_and_load_icon( i, store, tab, dir, file[0])
loop = None
if loop and loop.is_running(): def update_store(self, i, store, icon):
loop = asyncio.get_event_loop()
loop.create_task( self.create_icons(tab, store, dir, files) )
else:
asyncio.run( self.create_icons(tab, store, dir, files) )
async def create_icons(self, tab, store, dir, files):
icons = [self.get_icon(tab, dir, file[0]) for file in files]
data = await asyncio.gather(*icons)
tasks = [self.update_store(i, store, icon) for i, icon in enumerate(data)]
asyncio.gather(*tasks)
async def update_store(self, i, store, icon):
itr = store.get_iter(i) itr = store.get_iter(i)
GLib.idle_add(self.insert_store, store, itr, icon) GLib.idle_add(self.insert_store, store, itr, icon)
itr = None
@daemon_threaded
def make_and_load_icon(self, i, store, tab, dir, file):
icon = tab.create_icon(dir, file)
self.update_store(i, store, icon)
icon = None
def get_icon(self, tab, dir, file):
tab.create_icon(dir, file)
# @daemon_threaded
# def generate_icons(self, tab, store, dir, files):
# try:
# loop = asyncio.get_running_loop()
# except RuntimeError:
# loop = None
# if loop and loop.is_running():
# loop = asyncio.get_event_loop()
# loop.create_task( self.create_icons(tab, store, dir, files) )
# else:
# asyncio.run( self.create_icons(tab, store, dir, files) )
# async def create_icons(self, tab, store, dir, files):
# icons = [self.get_icon(tab, dir, file[0]) for file in files]
# data = await asyncio.gather(*icons)
# tasks = [self.update_store(i, store, icon) for i, icon in enumerate(data)]
# asyncio.gather(*tasks)
# async def update_store(self, i, store, icon):
# itr = store.get_iter(i)
# GLib.idle_add(self.insert_store, store, itr, icon)
# async def get_icon(self, tab, dir, file):
# return tab.create_icon(dir, file)
async def get_icon(self, tab, dir, file):
return tab.create_icon(dir, file)
def insert_store(self, store, itr, icon): def insert_store(self, store, itr, icon):
store.set_value(itr, 0, icon) store.set_value(itr, 0, icon)
@ -141,4 +164,11 @@ class GridMixin:
store = icon_grid.get_model() store = icon_grid.get_model()
tab_label = notebook.get_tab_label(obj).get_children()[0] tab_label = notebook.get_tab_label(obj).get_children()[0]
return store, tab_label return store, tab_label
def get_icon_grid_from_notebook(self, notebook, _name):
for obj in notebook.get_children():
icon_grid = obj.get_children()[0]
name = icon_grid.get_name()
if name == _name:
return icon_grid

View File

@ -41,18 +41,26 @@ class TabMixin(GridMixin):
notebook.set_tab_reorderable(scroll, True) notebook.set_tab_reorderable(scroll, True)
self.fm_controller.set_wid_and_tid(wid, tab.get_id()) self.fm_controller.set_wid_and_tid(wid, tab.get_id())
event_system.emit("go_to_path", (tab.get_current_directory(),)) # NOTE: Not efficent if I understand how
# path_entry.set_text(tab.get_current_directory()) # path_entry.set_text(tab.get_current_directory())
event_system.emit("go_to_path", (tab.get_current_directory(),)) # NOTE: Not efficent if I understand how
notebook.show_all() notebook.show_all()
notebook.set_current_page(index) notebook.set_current_page(index)
ctx = notebook.get_style_context() ctx = notebook.get_style_context()
ctx.add_class("notebook-unselected-focus") ctx.add_class("notebook-unselected-focus")
self.load_store(tab, store) self.load_store(tab, store)
# self.set_window_title()
event_system.emit("set_window_title", (tab.get_current_directory(),)) event_system.emit("set_window_title", (tab.get_current_directory(),))
self.set_file_watcher(tab) self.set_file_watcher(tab)
tab_widget = None
scroll, store = None, None
index = None
notebook = None
# path_entry = None
tab = None
ctx = None
def get_tab_widget(self, tab): def get_tab_widget(self, tab):
tab_widget = self.create_tab_widget() tab_widget = self.create_tab_widget()
tab_widget.tab_id = tab.get_id() tab_widget.tab_id = tab.get_id()
@ -65,6 +73,7 @@ class TabMixin(GridMixin):
def close_tab(self, button, eve = None): def close_tab(self, button, eve = None):
notebook = button.get_parent().get_parent() notebook = button.get_parent().get_parent()
if notebook.get_n_pages() == 1: if notebook.get_n_pages() == 1:
notebook = None
return return
tab_box = button.get_parent() tab_box = button.get_parent()
@ -81,19 +90,30 @@ class TabMixin(GridMixin):
self.builder.dereference_object(f"{wid}|{tid}|icon_grid") self.builder.dereference_object(f"{wid}|{tid}|icon_grid")
self.builder.dereference_object(f"{wid}|{tid}") self.builder.dereference_object(f"{wid}|{tid}")
icon_grid.set_model(None)
iter = store.get_iter_first()
while iter:
next_iter = store.iter_next(iter)
store.unref_node(iter)
iter = next_iter
store.clear()
store.run_dispose() store.run_dispose()
icon_grid.set_model(None)
icon_grid.run_dispose() icon_grid.run_dispose()
scroll.run_dispose() scroll.run_dispose()
tab_box.run_dispose() tab_box.run_dispose()
del store iter = None
del icon_grid wid, tid = None, None
del scroll store = None
del tab_box icon_grid = None
del watcher scroll = None
del tab tab_box = None
watcher = None
tab = None
notebook = None
if not settings_manager.is_trace_debug(): if not settings_manager.is_trace_debug():
self.fm_controller.save_state() self.fm_controller.save_state()
@ -123,6 +143,11 @@ class TabMixin(GridMixin):
if not settings_manager.is_trace_debug(): if not settings_manager.is_trace_debug():
self.fm_controller.save_state() self.fm_controller.save_state()
wid, tid = None, None
window = None
tab = None
def on_tab_switch_update(self, notebook, content = None, index = None): def on_tab_switch_update(self, notebook, content = None, index = None):
self.selected_files.clear() self.selected_files.clear()
wid, tid = content.get_children()[0].tab.get_name().split("|") wid, tid = content.get_children()[0].tab.get_name().split("|")
@ -130,6 +155,8 @@ class TabMixin(GridMixin):
self.set_path_text(wid, tid) self.set_path_text(wid, tid)
self.set_window_title() self.set_window_title()
wid, tid = None, None
def get_id_from_tab_box(self, tab_box): def get_id_from_tab_box(self, tab_box):
return tab_box.tab.get_id() return tab_box.tab.get_id()
@ -147,6 +174,8 @@ class TabMixin(GridMixin):
state.tab.load_directory() state.tab.load_directory()
self.load_store(state.tab, state.store) self.load_store(state.tab, state.store)
state = None
def update_tab(self, tab_label, tab, store, wid, tid): def update_tab(self, tab_label, tab, store, wid, tid):
self.load_store(tab, store) self.load_store(tab, store)
self.set_path_text(wid, tid) self.set_path_text(wid, tid)
@ -187,16 +216,38 @@ class TabMixin(GridMixin):
if isinstance(focused_obj, Gtk.Entry): if isinstance(focused_obj, Gtk.Entry):
self.process_path_menu(widget, tab, dir) self.process_path_menu(widget, tab, dir)
action = None
store = None
if path.endswith(".") or path == dir: if path.endswith(".") or path == dir:
tab_label = None
notebook = None
wid, tid = None, None
path = None
tab = None
return return
if not tab.set_path(path): if not tab.set_path(path):
tab_label = None
notebook = None
wid, tid = None, None
path = None
tab = None
return return
icon_grid = self.get_icon_grid_from_notebook(notebook, f"{wid}|{tid}") icon_grid = self.get_icon_grid_from_notebook(notebook, f"{wid}|{tid}")
icon_grid.clear_and_set_new_store() icon_grid.clear_and_set_new_store()
self.update_tab(tab_label, tab, store, wid, tid) self.update_tab(tab_label, tab, store, wid, tid)
action = None
wid, tid = None, None
notebook = None
store, tab_label = None, None
path = None
tab = None
icon_grid = None
def process_path_menu(self, gtk_entry, tab, dir): def process_path_menu(self, gtk_entry, tab, dir):
path_menu_buttons = self.builder.get_object("path_menu_buttons") path_menu_buttons = self.builder.get_object("path_menu_buttons")
query = gtk_entry.get_text().replace(dir, "") query = gtk_entry.get_text().replace(dir, "")
@ -213,6 +264,10 @@ class TabMixin(GridMixin):
path_menu_buttons.add(button) path_menu_buttons.add(button)
show_path_menu = True show_path_menu = True
path_menu_buttons = None
query = None
files = None
if not show_path_menu: if not show_path_menu:
event_system.emit("hide_path_menu") event_system.emit("hide_path_menu")
else: else:
@ -244,9 +299,16 @@ class TabMixin(GridMixin):
path_entry.set_position(-1) path_entry.set_position(-1)
event_system.emit("hide_path_menu") event_system.emit("hide_path_menu")
state = None
path = None
path_entry = None
def show_hide_hidden_files(self): def show_hide_hidden_files(self):
wid, tid = self.fm_controller.get_active_wid_and_tid() wid, tid = self.fm_controller.get_active_wid_and_tid()
tab = self.get_fm_window(wid).get_tab_by_id(tid) tab = self.get_fm_window(wid).get_tab_by_id(tid)
tab.set_hiding_hidden(not tab.is_hiding_hidden()) tab.set_hiding_hidden(not tab.is_hiding_hidden())
tab.load_directory() tab.load_directory()
self.builder.get_object("refresh_tab").released() self.builder.get_object("refresh_tab").released()
wid, tid = None, None
tab = None

View File

@ -42,10 +42,17 @@ class WindowMixin(TabMixin):
event_system.emit("set_window_title", (dir,)) event_system.emit("set_window_title", (dir,))
self.set_bottom_labels(tab) self.set_bottom_labels(tab)
wid, tid = None, None
notebook = None
tab = None
dir = None
def set_path_text(self, wid, tid): def set_path_text(self, wid, tid):
tab = self.get_fm_window(wid).get_tab_by_id(tid) tab = self.get_fm_window(wid).get_tab_by_id(tid)
event_system.emit("go_to_path", (tab.get_current_directory(),)) event_system.emit("go_to_path", (tab.get_current_directory(),))
tab = None
def grid_set_selected_items(self, icons_grid): def grid_set_selected_items(self, icons_grid):
new_items = icons_grid.get_selected_items() new_items = icons_grid.get_selected_items()
items_size = len(new_items) items_size = len(new_items)
@ -160,6 +167,12 @@ class WindowMixin(TabMixin):
if target not in current: if target not in current:
self.fm_controller.set_wid_and_tid(wid, tid) self.fm_controller.set_wid_and_tid(wid, tid)
current = None
target = None
wid, tid = None, None
store = None
path_at_loc = None
def grid_on_drag_data_received(self, widget, drag_context, x, y, data, info, time): def grid_on_drag_data_received(self, widget, drag_context, x, y, data, info, time):
if info == 80: if info == 80:
@ -179,4 +192,4 @@ class WindowMixin(TabMixin):
Gtk.drag_finish(drag_context, False, False, time) Gtk.drag_finish(drag_context, False, False, time)
def create_new_tab_notebook(self, widget=None, wid=None, path=None): def create_new_tab_notebook(self, widget=None, wid=None, path=None):
self.create_tab(wid, None, path) self.create_tab(wid, None, path)

View File

@ -77,9 +77,18 @@ class IconGridWidget(Gtk.IconView):
def clear_and_set_new_store(self): def clear_and_set_new_store(self):
store = self.get_model() store = self.get_model()
if store: if store:
iter = store.get_iter_first()
while iter:
next_iter = store.iter_next(iter)
store.unref_node(iter)
iter = next_iter
store.clear()
store.run_dispose() store.run_dispose()
store = None
self.set_model(None) self.set_model(None)
store = Gtk.ListStore(GdkPixbuf.Pixbuf or GdkPixbuf.PixbufAnimation or None, str or None) store = Gtk.ListStore(GdkPixbuf.Pixbuf or GdkPixbuf.PixbufAnimation or None, str or None)
# store = Gtk.ListStore(Gtk.DirectoryList) # store = Gtk.ListStore(Gtk.DirectoryList)
self.set_model(store) self.set_model(store)
store = None

View File

@ -61,7 +61,6 @@ class MessagePopupWidget(Gtk.Popover):
scroll_window.set_hexpand(True) scroll_window.set_hexpand(True)
vbox.set_orientation(Gtk.Orientation.VERTICAL) vbox.set_orientation(Gtk.Orientation.VERTICAL)
self.builder.expose_object(f"message_popup_widget", self)
self.builder.expose_object(f"message_text_view", message_text_view) self.builder.expose_object(f"message_text_view", message_text_view)
scroll_window.add(message_text_view) scroll_window.add(message_text_view)
@ -126,4 +125,4 @@ class MessagePopupWidget(Gtk.Popover):
with open(target, "w") as f: with open(target, "w") as f:
f.write(text) f.write(text)
save_location_prompt.destroy() save_location_prompt.destroy()

View File

@ -60,7 +60,11 @@ class IPCServer(Singleton):
try: try:
conn = listener.accept() conn = listener.accept()
start_time = time.perf_counter() start_time = time.perf_counter()
GLib.idle_add(self._handle_ipc_message, *(conn, start_time,)) GLib.idle_add(self._handle_ipc_message, *(conn, start_time,))
conn = None
start_time = None
except Exception as e: except Exception as e:
logger.debug( repr(e) ) logger.debug( repr(e) )
@ -74,19 +78,24 @@ class IPCServer(Singleton):
if "FILE|" in msg: if "FILE|" in msg:
file = msg.split("FILE|")[1].strip() file = msg.split("FILE|")[1].strip()
if file: if file:
event_system.emit("handle_file_from_ipc", file) event_system.emit_and_await("handle_file_from_ipc", file)
msg = None
file = None
conn.close() conn.close()
break break
if msg in ['close connection', 'close server']: if msg in ['close connection', 'close server']:
msg = None
conn.close() conn.close()
break break
# NOTE: Not perfect but insures we don't lock up the connection for too long. # NOTE: Not perfect but insures we don't lock up the connection for too long.
end_time = time.perf_counter() end_time = time.perf_counter()
if (end_time - start_time) > self._ipc_timeout: if (end_time - start_time) > self._ipc_timeout:
msg = None
end_time = None
conn.close() conn.close()
break break
@ -126,4 +135,4 @@ class IPCServer(Singleton):
logger.error("IPC Socket no longer valid.... Removing.") logger.error("IPC Socket no longer valid.... Removing.")
os.unlink(self._ipc_address) os.unlink(self._ipc_address)
except Exception as e: except Exception as e:
logger.error( repr(e) ) logger.error( repr(e) )

View File

@ -171,4 +171,4 @@ class SettingsManager(StartCheckMixin, Singleton):
def save_settings(self): def save_settings(self):
with open(self._CONFIG_FILE, 'w') as outfile: with open(self._CONFIG_FILE, 'w') as outfile:
json.dump(self.settings.as_dict(), outfile, separators=(',', ':'), indent=4) json.dump(self.settings.as_dict(), outfile, separators=(',', ':'), indent=4)

View File

@ -20,6 +20,9 @@ function main() {
files[$size]="${target}" files[$size]="${target}"
done done
G_SLICE=always-malloc
G_DEBUG=gc-friendly
GOBJECT_DEBUG=instance-count
python /opt/solarfm.zip "${files[@]}" python /opt/solarfm.zip "${files[@]}"
} }
main "$@"; main "$@";

View File

@ -8,7 +8,7 @@
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="border-width">5</property> <property name="border-width">5</property>
<property name="window-position">center-on-parent</property> <property name="window-position">center-on-parent</property>
<property name="icon">../icons/solarfm.png</property> <property name="icon">../icons/solarfm-64x64.png</property>
<property name="type-hint">dialog</property> <property name="type-hint">dialog</property>
<property name="skip-taskbar-hint">True</property> <property name="skip-taskbar-hint">True</property>
<property name="skip-pager-hint">True</property> <property name="skip-pager-hint">True</property>
@ -19,6 +19,7 @@
<property name="copyright" translatable="yes">Copyright (C) 2021 GPL2</property> <property name="copyright" translatable="yes">Copyright (C) 2021 GPL2</property>
<property name="comments" translatable="yes">by ITDominator</property> <property name="comments" translatable="yes">by ITDominator</property>
<property name="website">https://code.itdominator.com/itdominator/SolarFM</property> <property name="website">https://code.itdominator.com/itdominator/SolarFM</property>
<property name="website-label" translatable="yes">ITDominator</property>
<property name="license" translatable="yes">SolarFM - Copyright (C) 2021 ITDominator GPL2 <property name="license" translatable="yes">SolarFM - Copyright (C) 2021 ITDominator GPL2
@ -367,7 +368,9 @@ Public License instead of this License.
SolarFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspection.</property> SolarFM is developed on Atom, git, and using Python 3+ with Gtk GObject introspection.</property>
<property name="translator-credits" translatable="yes" comments="Please replace this line with your own names, one name per line. ">translator-credits</property> <property name="documenters">...</property>
<property name="translator-credits" translatable="yes" comments="Please replace this line with your own names, one name per line. ">...</property>
<property name="artists">...</property>
<property name="logo">../icons/solarfm-64x64.png</property> <property name="logo">../icons/solarfm-64x64.png</property>
<property name="wrap-license">True</property> <property name="wrap-license">True</property>
<property name="license-type">custom</property> <property name="license-type">custom</property>