diff --git a/src/solarfm/__builtins__.py b/src/solarfm/__builtins__.py index 6ead649..9c7cce9 100644 --- a/src/solarfm/__builtins__.py +++ b/src/solarfm/__builtins__.py @@ -16,13 +16,17 @@ from utils.settings_manager.manager import SettingsManager # NOTE: Threads WILL NOT die with parent's destruction. def threaded_wrapper(fn): def wrapper(*args, **kwargs): - threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=False).start() + thread = threading.Thread(target = fn, args = args, kwargs = kwargs, daemon = False) + thread.start() + return thread return wrapper # NOTE: Threads WILL die with parent's destruction. def daemon_threaded_wrapper(fn): def wrapper(*args, **kwargs): - threading.Thread(target=fn, args=args, kwargs=kwargs, daemon=True).start() + thread = threading.Thread(target = fn, args = args, kwargs = kwargs, daemon = True) + thread.start() + return thread return wrapper def sizeof_fmt_def(num, suffix="B"): @@ -61,4 +65,4 @@ def custom_except_hook(exc_type, exc_value, exc_traceback): logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback)) -sys.excepthook = custom_except_hook +sys.excepthook = custom_except_hook \ No newline at end of file diff --git a/src/solarfm/core/controller.py b/src/solarfm/core/controller.py index ce10937..e818db6 100644 --- a/src/solarfm/core/controller.py +++ b/src/solarfm/core/controller.py @@ -78,6 +78,7 @@ class Controller(UIMixin, SignalsMixins, Controller_Data): event_system.subscribe("do_action_from_menu_controls", self.do_action_from_menu_controls) event_system.subscribe("set_clipboard_data", self.set_clipboard_data) + def _load_glade_file(self): self.builder.add_from_file( settings_manager.get_glade_file() ) self.builder.expose_object("main_window", self.window) @@ -113,6 +114,7 @@ class Controller(UIMixin, SignalsMixins, Controller_Data): if not settings_manager.is_trace_debug(): self.fm_controller.save_state() + def reload_plugins(self, widget=None, eve=None): self.plugins.reload_plugins() diff --git a/src/solarfm/core/controller_data.py b/src/solarfm/core/controller_data.py index 89961ac..7a1514d 100644 --- a/src/solarfm/core/controller_data.py +++ b/src/solarfm/core/controller_data.py @@ -70,23 +70,16 @@ class Controller_Data: Returns: state (obj): State ''' - # state = State() + state = self._state state.fm_controller = self.fm_controller state.notebooks = self.notebooks state.wid, state.tid = self.fm_controller.get_active_wid_and_tid() state.tab = self.get_fm_window(state.wid).get_tab_by_id(state.tid) state.icon_grid = self.builder.get_object(f"{state.wid}|{state.tid}|icon_grid", use_gtk = False) - # state.icon_grid = event_system.emit_and_await("get_files_view_icon_grid", (state.wid, state.tid)) state.store = state.icon_grid.get_model() - - # NOTE: Need to watch this as I thought we had issues with just using single reference upon closing it. - # But, I found that not doing it this way caused objects to generate upon every click... (Because we're getting state info, duh) - # Yet interactive debug view shows them just pilling on and never clearing... state.message_dialog = self.message_dialog state.user_pass_dialog = self.user_pass_dialog - # state.message_dialog = MessageWidget() - # state.user_pass_dialog = UserPassWidget() selected_files = state.icon_grid.get_selected_items() if selected_files: @@ -186,4 +179,4 @@ class Controller_Data: proc = subprocess.Popen(['xclip','-selection','clipboard'], stdin=subprocess.PIPE) proc.stdin.write(data.encode("utf-8")) proc.stdin.close() - retcode = proc.wait() + retcode = proc.wait() \ No newline at end of file diff --git a/src/solarfm/core/mixins/signals/keyboard_signals_mixin.py b/src/solarfm/core/mixins/signals/keyboard_signals_mixin.py index 9e02fe1..ac1dbf2 100644 --- a/src/solarfm/core/mixins/signals/keyboard_signals_mixin.py +++ b/src/solarfm/core/mixins/signals/keyboard_signals_mixin.py @@ -25,6 +25,14 @@ class KeyboardSignalsMixin: self.shift_down = False self.alt_down = False + def unmap_special_key(self, keyname): + if "control" in keyname: + self.ctrl_down = False + if "shift" in keyname: + self.shift_down = False + if "alt" in keyname: + self.alt_down = False + def on_global_key_press_controller(self, eve, user_data): keyname = Gdk.keyval_name(user_data.keyval).lower() if keyname.replace("_l", "").replace("_r", "") in ["control", "alt", "shift"]: @@ -35,32 +43,19 @@ class KeyboardSignalsMixin: if "alt" in keyname: self.alt_down = True + def on_global_key_release_controller(self, widget, event): """Handler for keyboard events""" keyname = Gdk.keyval_name(event.keyval).lower() if keyname.replace("_l", "").replace("_r", "") in ["control", "alt", "shift"]: - if "control" in keyname: - self.ctrl_down = False - if "shift" in keyname: - self.shift_down = False - if "alt" in keyname: - self.alt_down = False + self.unmap_special_key(keyname) mapping = keybindings.lookup(event) if mapping: - # See if in filemanager scope try: - getattr(self, mapping)() - return True + self.handle_as_controller_scope(mapping) except Exception: - # Must be plugins scope, event call, OR we forgot to add method to file manager scope - if "||" in mapping: - sender, eve_type = mapping.split("||") - else: - sender = "" - eve_type = mapping - - self.handle_plugin_key_event(sender, eve_type) + self.handle_as_plugin_scope(mapping) else: logger.debug(f"on_global_key_release_controller > key > {keyname}") @@ -68,7 +63,19 @@ class KeyboardSignalsMixin: if keyname in ["1", "kp_1", "2", "kp_2", "3", "kp_3", "4", "kp_4"]: self.builder.get_object(f"tggl_notebook_{keyname.strip('kp_')}").released() - def handle_plugin_key_event(self, sender, eve_type): + def handle_as_controller_scope(self, mapping): + getattr(self, mapping)() + + def handle_as_plugin_scope(self, mapping): + if "||" in mapping: + sender, eve_type = mapping.split("||") + else: + sender = "" + eve_type = mapping + + self.handle_as_key_event_system(sender, eve_type) + + def handle_as_key_event_system(self, sender, eve_type): event_system.emit(eve_type) def keyboard_close_tab(self): @@ -82,6 +89,6 @@ class KeyboardSignalsMixin: self.get_fm_window(wid).delete_tab_by_id(tid) notebook.remove_page(page) - if not trace_debug: + if not settings_manager.is_trace_debug(): self.fm_controller.save_state() - self.set_window_title() + self.set_window_title() \ No newline at end of file diff --git a/src/solarfm/core/mixins/ui/grid_mixin.py b/src/solarfm/core/mixins/ui/grid_mixin.py index 937802c..a769103 100644 --- a/src/solarfm/core/mixins/ui/grid_mixin.py +++ b/src/solarfm/core/mixins/ui/grid_mixin.py @@ -26,7 +26,7 @@ class GridMixin: store.append([None, file[0]]) Gtk.main_iteration() - self.generate_icons(tab, store, dir, files) + thread = 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: @@ -48,13 +48,10 @@ class GridMixin: tasks = [self.update_store(i, store, dir, tab, file[0]) for i, file in enumerate(files)] await asyncio.gather(*tasks) - async def load_icon(self, i, store, icon): - GLib.idle_add(self.update_store, i, store, icon ) - async def update_store(self, i, store, dir, tab, file): icon = tab.create_icon(dir, file) itr = store.get_iter(i) - store.set_value(itr, 0, icon) + GLib.idle_add(store.set_value, itr, 0, icon) def create_tab_widget(self, tab): return TabHeaderWidget(tab, self.close_tab) diff --git a/src/solarfm/core/ui_mixin.py b/src/solarfm/core/ui_mixin.py index 406f1fa..b596497 100644 --- a/src/solarfm/core/ui_mixin.py +++ b/src/solarfm/core/ui_mixin.py @@ -34,7 +34,9 @@ class UIMixin(PaneMixin, WindowMixin): nickname = session["window"]["Nickname"] tabs = session["window"]["tabs"] isHidden = True if session["window"]["isHidden"] == "True" else False - event_system.emit("load_files_view_state", (nickname, tabs)) + event_system.emit("load_files_view_state", (nickname, tabs, isHidden)) + + @daemon_threaded def _focus_last_visible_notebook(self, icon_grid): diff --git a/src/solarfm/core/widgets/files_view/files_widget.py b/src/solarfm/core/widgets/files_view/files_widget.py index cca26d6..de10fa7 100644 --- a/src/solarfm/core/widgets/files_view/files_widget.py +++ b/src/solarfm/core/widgets/files_view/files_widget.py @@ -1,11 +1,9 @@ # Python imports # Lib imports -import gi -gi.require_version('Gtk', '3.0') -from gi.repository import Gtk # Application imports +from ...sfm_builder import SFMBuilder from ...mixins.signals.file_action_signals_mixin import FileActionSignalsMixin from .window_mixin import WindowMixin @@ -27,7 +25,8 @@ class FilesWidget(FileActionSignalsMixin, WindowMixin): self.INDEX = self.ccount self.NAME = f"window_{self.INDEX}" - self.builder = Gtk.Builder() + self.builder = SFMBuilder() + self.files_view = None self.fm_controller = None @@ -41,20 +40,21 @@ class FilesWidget(FileActionSignalsMixin, WindowMixin): ... def _setup_signals(self): - settings_manager.register_signals_to_builder([self,], self.builder) + settings_manager.register_signals_to_builder([self], self.builder) def _subscribe_to_events(self): event_system.subscribe("load_files_view_state", self._load_files_view_state) event_system.subscribe("get_files_view_icon_grid", self._get_files_view_icon_grid) def _load_widgets(self): - _builder = settings_manager.get_builder() + _builder = settings_manager.get_builder() self.files_view = _builder.get_object(f"{self.NAME}") self.files_view.set_group_name("files_widget") + self.builder.expose_object(f"{self.NAME}", self.files_view) - def _load_files_view_state(self, win_name = None, tabs = None): + def _load_files_view_state(self, win_name = None, tabs = None, isHidden = False): if win_name == self.NAME: if tabs: for tab in tabs: @@ -62,10 +62,13 @@ class FilesWidget(FileActionSignalsMixin, WindowMixin): else: self.create_new_tab_notebook(None, self.INDEX, None) + if isHidden: + self.files_view.hide() + def _get_files_view_icon_grid(self, win_index = None, tid = None): if win_index == str(self.INDEX): return self.builder.get_object(f"{self.INDEX}|{tid}|icon_grid", use_gtk = False) def set_fm_controller(self, _fm_controller): - self.fm_controller = _fm_controller + self.fm_controller = _fm_controller \ No newline at end of file diff --git a/src/solarfm/core/widgets/files_view/grid_mixin.py b/src/solarfm/core/widgets/files_view/grid_mixin.py index 11ca4f6..258b320 100644 --- a/src/solarfm/core/widgets/files_view/grid_mixin.py +++ b/src/solarfm/core/widgets/files_view/grid_mixin.py @@ -26,7 +26,7 @@ class GridMixin: store.append([None, file[0]]) Gtk.main_iteration() - self.generate_icons(tab, store, dir, files) + thread = 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: @@ -48,13 +48,10 @@ class GridMixin: tasks = [self.update_store(i, store, dir, tab, file[0]) for i, file in enumerate(files)] await asyncio.gather(*tasks) - async def load_icon(self, i, store, icon): - GLib.idle_add(self.update_store, i, store, icon ) - async def update_store(self, i, store, dir, tab, file): icon = tab.create_icon(dir, file) itr = store.get_iter(i) - store.set_value(itr, 0, icon) + GLib.idle_add(store.set_value, itr, 0, icon) def create_tab_widget(self, tab): return TabHeaderWidget(tab, self.close_tab)