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 99346a2..a30c862 100644 --- a/src/solarfm/core/mixins/signals/file_action_signals_mixin.py +++ b/src/solarfm/core/mixins/signals/file_action_signals_mixin.py @@ -30,58 +30,46 @@ class FileActionSignalsMixin: wid = tab.get_wid() tid = tab.get_id() - dir_watcher.connect("changed", self.dir_watch_updates, (f"{wid}|{tid}",)) + dir_watcher.connect("changed", self.dir_watch_updates, *(f"{wid}|{tid}",)) tab.set_dir_watcher(dir_watcher) - # NOTE: Too lazy to impliment a proper update handler and so just regen store and update tab. - # Use a lock system to prevent too many update calls for certain instances but user can manually refresh if they have urgency - def dir_watch_updates(self, file_monitor, file, other_file = None, eve_type = None, data = None): + 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, Gio.FileMonitorEvent.RENAMED, Gio.FileMonitorEvent.MOVED_IN, Gio.FileMonitorEvent.MOVED_OUT]: - if eve_type in [Gio.FileMonitorEvent.MOVED_IN, Gio.FileMonitorEvent.MOVED_OUT]: - self.update_on_soft_lock_end(data[0]) - elif data[0] in self.soft_update_lock.keys(): - self.soft_update_lock[data[0]]["last_update_time"] = time.time() - else: - self.soft_lock_countdown(data[0]) + self.soft_lock_countdown(tab_widget_id) - @daemon_threaded - def soft_lock_countdown(self, tab_widget): - self.soft_update_lock[tab_widget] = { "last_update_time": time.time()} + def soft_lock_countdown(self, tab_widget_id): + if tab_widget_id in self.soft_update_lock: + timeout_id = self.soft_update_lock[tab_widget_id]["timeout_id"] + GLib.source_remove(timeout_id) - lock = True - while lock: - time.sleep(0.6) - last_update_time = self.soft_update_lock[tab_widget]["last_update_time"] - current_time = time.time() - if (current_time - last_update_time) > 0.6: - lock = False + timeout_id = GLib.timeout_add(0, self.update_on_soft_lock_end, 600, *(tab_widget_id,)) + self.soft_update_lock[tab_widget_id] = { "timeout_id": timeout_id } - self.soft_update_lock.pop(tab_widget, None) - GLib.idle_add(self.update_on_soft_lock_end, *(tab_widget,)) - def update_on_soft_lock_end(self, tab_widget): - wid, tid = tab_widget.split("|") + def update_on_soft_lock_end(self, timout_ms, tab_widget_id): + self.soft_update_lock.pop(tab_widget_id, None) + + wid, tid = tab_widget_id.split("|") notebook = self.builder.get_object(f"window_{wid}") tab = self.get_fm_window(wid).get_tab_by_id(tid) icon_grid = self.builder.get_object(f"{wid}|{tid}|icon_grid", use_gtk = False) store = icon_grid.get_model() - _store, tab_widget_label = self.get_store_and_label_from_notebook(notebook, f"{wid}|{tid}") + _store, tab_widget_id_label = self.get_store_and_label_from_notebook(notebook, f"{wid}|{tid}") tab.load_directory() icon_grid.clear_and_set_new_store() self.load_store(tab, icon_grid.get_store()) - tab_widget_label.set_label(tab.get_end_of_path()) + tab_widget_id_label.set_label(tab.get_end_of_path()) state = self.get_current_state() if [wid, tid] in [state.wid, state.tid]: self.set_bottom_labels(tab) return False - def do_file_search(self, widget, eve = None): if not self.ctrl_down and not self.shift_down and not self.alt_down: target = widget.get_name() diff --git a/src/solarfm/core/mixins/ui/grid_mixin.py b/src/solarfm/core/mixins/ui/grid_mixin.py index 2cbcbdc..0a36c09 100644 --- a/src/solarfm/core/mixins/ui/grid_mixin.py +++ b/src/solarfm/core/mixins/ui/grid_mixin.py @@ -34,7 +34,6 @@ class GridMixin: dir = tab.get_current_directory() files = tab.get_files() - store.clear() for file in files: store.append([None, file[0]]) @@ -48,33 +47,51 @@ class GridMixin: self.fm_controller.save_state() - @daemon_threaded def generate_icons(self, tab, store, dir, files): - try: - loop = asyncio.get_running_loop() - except RuntimeError: - loop = None + for i, file in enumerate(files): + # GLib.Thread(f"{i}", self.make_and_load_icon, i, store, tab, dir, file[0]) + self.make_and_load_icon( i, store, tab, dir, file[0]) - if loop and loop.is_running(): - 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)] - await asyncio.gather(*tasks) - - GLib.idle_add(self.do_ui_update) - - async def update_store(self, i, store, icon): + 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): + @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) + + def get_icon(self, tab, dir, file): return 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) + + def insert_store(self, store, itr, icon): store.set_value(itr, 0, icon) diff --git a/src/solarfm/core/widgets/context_menu_widget.py b/src/solarfm/core/widgets/context_menu_widget.py index 5774c5c..bbab184 100644 --- a/src/solarfm/core/widgets/context_menu_widget.py +++ b/src/solarfm/core/widgets/context_menu_widget.py @@ -40,16 +40,15 @@ class ContextMenuWidget(Gtk.Menu): def _emit(self, menu_item, type): event_system.emit("do_action_from_menu_controls", type) - - def make_submenu(self, name, data, keys): + def make_submenu(self, name, data): menu = Gtk.Menu() menu_item = Gtk.MenuItem(name) - for key in keys: + for key, value in data.items(): if isinstance(data, dict): - entry = self.make_menu_item(key, data[key]) + entry = self.make_menu_item(key, value) elif isinstance(data, list): - entry = self.make_menu_item(key, data) + entry = self.make_menu_item(key, value) else: continue @@ -58,11 +57,11 @@ class ContextMenuWidget(Gtk.Menu): menu_item.set_submenu(menu) return menu_item - def make_menu_item(self, name, data) -> Gtk.MenuItem: + def make_menu_item(self, label, data) -> Gtk.MenuItem: if isinstance(data, dict): - return self.make_submenu(name, data, data.keys()) + return self.make_submenu(label, data) elif isinstance(data, list): - entry = Gtk.ImageMenuItem(name) + entry = Gtk.ImageMenuItem(label) icon = getattr(Gtk, f"{data[0]}") entry.set_image( Gtk.Image(stock=icon) ) entry.set_always_show_image(True) @@ -71,18 +70,18 @@ class ContextMenuWidget(Gtk.Menu): def build_context_menu(self) -> None: data = self._context_menu_data - dkeys = data.keys() plugins_entry = None - for dkey in dkeys: - entry = self.make_menu_item(dkey, data[dkey]) + for key, value in data.items(): + entry = self.make_menu_item(key, value) self.append(entry) - if dkey == "Plugins": + if key == "Plugins": plugins_entry = entry self.attach_to_widget(self._window, None) - self.show_all() self.builder.expose_object("context_menu", self) + self.show_all() + if plugins_entry: self.builder.expose_object("context_menu_plugins", plugins_entry.get_submenu()) diff --git a/src/solarfm/core/widgets/files_view/grid_mixin.py b/src/solarfm/core/widgets/files_view/grid_mixin.py index 2071fac..a6b9ee6 100644 --- a/src/solarfm/core/widgets/files_view/grid_mixin.py +++ b/src/solarfm/core/widgets/files_view/grid_mixin.py @@ -55,6 +55,7 @@ class GridMixin: 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) ) @@ -63,9 +64,7 @@ class GridMixin: 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)] - await asyncio.gather(*tasks) - - GLib.idle_add(self.do_ui_update) + asyncio.gather(*tasks) async def update_store(self, i, store, icon): itr = store.get_iter(i) diff --git a/src/solarfm/core/window.py b/src/solarfm/core/window.py index 75fe20f..d9b8807 100644 --- a/src/solarfm/core/window.py +++ b/src/solarfm/core/window.py @@ -10,6 +10,7 @@ gi.require_version('Gdk', '3.0') from gi.repository import Gtk from gi.repository import Gdk from gi.repository import GLib +from gi.repository import GObject # Application imports from core.controller import Controller @@ -24,6 +25,8 @@ class Window(Gtk.ApplicationWindow): """docstring for Window.""" def __init__(self, args, unknownargs): + GObject.threads_init() + super(Window, self).__init__() settings_manager.set_main_window(self) @@ -85,7 +88,7 @@ class Window(Gtk.ApplicationWindow): if visual != None and screen.is_composited(): self.set_visual(visual) self.set_app_paintable(True) - self.connect("draw", self._area_draw) + # self.connect("draw", self._area_draw) # bind css file cssProvider = Gtk.CssProvider() diff --git a/src/solarfm/plugins/manifest.py b/src/solarfm/plugins/manifest.py index 392fc2a..f7dc613 100644 --- a/src/solarfm/plugins/manifest.py +++ b/src/solarfm/plugins/manifest.py @@ -53,9 +53,8 @@ class ManifestProcessor: def get_loading_data(self): loading_data = {} requests = self._plugin.requests - keys = requests.keys() - if "ui_target" in keys: + if "ui_target" in requests: if requests["ui_target"] in [ "none", "other", "main_Window", "main_menu_bar", "main_menu_bttn_box_bar", "path_menu_bar", "plugin_control_list", @@ -63,7 +62,7 @@ class ManifestProcessor: "window_2", "window_3", "window_4" ]: if requests["ui_target"] == "other": - if "ui_target_id" in keys: + if "ui_target_id" in requests: loading_data["ui_target"] = self._builder.get_object(requests["ui_target_id"]) if loading_data["ui_target"] == None: raise ManifestProcessorException('Invalid "ui_target_id" given in requests. Must have one if setting "ui_target" to "other"...') @@ -74,11 +73,11 @@ class ManifestProcessor: else: raise ManifestProcessorException('Unknown "ui_target" given in requests.') - if "pass_fm_events" in keys: + if "pass_fm_events" in requests: if requests["pass_fm_events"] in ["true"]: loading_data["pass_fm_events"] = True - if "pass_ui_objects" in keys: + if "pass_ui_objects" in requests: if len(requests["pass_ui_objects"]) > 0: loading_data["pass_ui_objects"] = [] for ui_id in requests["pass_ui_objects"]: @@ -87,7 +86,7 @@ class ManifestProcessor: except ManifestProcessorException as e: logger.error(repr(e)) - if "bind_keys" in keys: + if "bind_keys" in requests: if isinstance(requests["bind_keys"], list): loading_data["bind_keys"] = requests["bind_keys"] diff --git a/src/solarfm/plugins/plugins_controller.py b/src/solarfm/plugins/plugins_controller.py index 43a108e..f37cffc 100644 --- a/src/solarfm/plugins/plugins_controller.py +++ b/src/solarfm/plugins/plugins_controller.py @@ -100,20 +100,19 @@ class PluginsController: def execute_plugin(self, module: type, plugin: PluginInfo, loading_data: []): plugin.reference = module.Plugin() - keys = loading_data.keys() - if "ui_target" in keys: + if "ui_target" in loading_data: loading_data["ui_target"].add( plugin.reference.generate_reference_ui_element() ) loading_data["ui_target"].show_all() - if "pass_ui_objects" in keys: + if "pass_ui_objects" in loading_data: plugin.reference.set_ui_object_collection( loading_data["pass_ui_objects"] ) - if "pass_fm_events" in keys: + if "pass_fm_events" in loading_data: plugin.reference.set_fm_event_system(event_system) plugin.reference.subscribe_to_events() - if "bind_keys" in keys: + if "bind_keys" in loading_data: keybindings.append_bindings( loading_data["bind_keys"] ) plugin.reference.run() diff --git a/src/solarfm/utils/debugging.py b/src/solarfm/utils/debugging.py index 70cdf82..5eaa286 100644 --- a/src/solarfm/utils/debugging.py +++ b/src/solarfm/utils/debugging.py @@ -37,6 +37,14 @@ def debug_signal_handler(signal, frame): except Exception as ex: ... + try: + import ipdb + logger.debug("\n\nStarting IPDB debugger...\n\n") + ipdb.set_trace() + return + except Exception as ex: + ... + try: import pdb logger.debug("\n\nStarting embedded PDB debugger...\n\n")