Improved keybinding clarity; trying to fix thread and async issues
This commit is contained in:
parent
e6739c3087
commit
d936b17429
|
@ -16,13 +16,17 @@ from utils.settings_manager.manager import SettingsManager
|
||||||
# NOTE: Threads WILL NOT die with parent's destruction.
|
# NOTE: Threads WILL NOT die with parent's destruction.
|
||||||
def threaded_wrapper(fn):
|
def threaded_wrapper(fn):
|
||||||
def wrapper(*args, **kwargs):
|
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
|
return wrapper
|
||||||
|
|
||||||
# NOTE: Threads WILL die with parent's destruction.
|
# NOTE: Threads WILL die with parent's destruction.
|
||||||
def daemon_threaded_wrapper(fn):
|
def daemon_threaded_wrapper(fn):
|
||||||
def wrapper(*args, **kwargs):
|
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
|
return wrapper
|
||||||
|
|
||||||
def sizeof_fmt_def(num, suffix="B"):
|
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))
|
logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))
|
||||||
|
|
||||||
sys.excepthook = custom_except_hook
|
sys.excepthook = custom_except_hook
|
|
@ -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("do_action_from_menu_controls", self.do_action_from_menu_controls)
|
||||||
event_system.subscribe("set_clipboard_data", self.set_clipboard_data)
|
event_system.subscribe("set_clipboard_data", self.set_clipboard_data)
|
||||||
|
|
||||||
|
|
||||||
def _load_glade_file(self):
|
def _load_glade_file(self):
|
||||||
self.builder.add_from_file( settings_manager.get_glade_file() )
|
self.builder.add_from_file( settings_manager.get_glade_file() )
|
||||||
self.builder.expose_object("main_window", self.window)
|
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():
|
if not settings_manager.is_trace_debug():
|
||||||
self.fm_controller.save_state()
|
self.fm_controller.save_state()
|
||||||
|
|
||||||
|
|
||||||
def reload_plugins(self, widget=None, eve=None):
|
def reload_plugins(self, widget=None, eve=None):
|
||||||
self.plugins.reload_plugins()
|
self.plugins.reload_plugins()
|
||||||
|
|
||||||
|
|
|
@ -70,23 +70,16 @@ class Controller_Data:
|
||||||
Returns:
|
Returns:
|
||||||
state (obj): State
|
state (obj): State
|
||||||
'''
|
'''
|
||||||
# state = State()
|
|
||||||
state = self._state
|
state = self._state
|
||||||
state.fm_controller = self.fm_controller
|
state.fm_controller = self.fm_controller
|
||||||
state.notebooks = self.notebooks
|
state.notebooks = self.notebooks
|
||||||
state.wid, state.tid = self.fm_controller.get_active_wid_and_tid()
|
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.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 = 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()
|
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.message_dialog = self.message_dialog
|
||||||
state.user_pass_dialog = self.user_pass_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()
|
selected_files = state.icon_grid.get_selected_items()
|
||||||
if selected_files:
|
if selected_files:
|
||||||
|
@ -186,4 +179,4 @@ class Controller_Data:
|
||||||
proc = subprocess.Popen(['xclip','-selection','clipboard'], stdin=subprocess.PIPE)
|
proc = subprocess.Popen(['xclip','-selection','clipboard'], stdin=subprocess.PIPE)
|
||||||
proc.stdin.write(data.encode("utf-8"))
|
proc.stdin.write(data.encode("utf-8"))
|
||||||
proc.stdin.close()
|
proc.stdin.close()
|
||||||
retcode = proc.wait()
|
retcode = proc.wait()
|
|
@ -25,6 +25,14 @@ class KeyboardSignalsMixin:
|
||||||
self.shift_down = False
|
self.shift_down = False
|
||||||
self.alt_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):
|
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()
|
||||||
if keyname.replace("_l", "").replace("_r", "") in ["control", "alt", "shift"]:
|
if keyname.replace("_l", "").replace("_r", "") in ["control", "alt", "shift"]:
|
||||||
|
@ -35,32 +43,19 @@ class KeyboardSignalsMixin:
|
||||||
if "alt" in keyname:
|
if "alt" in keyname:
|
||||||
self.alt_down = True
|
self.alt_down = True
|
||||||
|
|
||||||
|
|
||||||
def on_global_key_release_controller(self, widget, event):
|
def on_global_key_release_controller(self, widget, event):
|
||||||
"""Handler for keyboard events"""
|
"""Handler for keyboard events"""
|
||||||
keyname = Gdk.keyval_name(event.keyval).lower()
|
keyname = Gdk.keyval_name(event.keyval).lower()
|
||||||
if keyname.replace("_l", "").replace("_r", "") in ["control", "alt", "shift"]:
|
if keyname.replace("_l", "").replace("_r", "") in ["control", "alt", "shift"]:
|
||||||
if "control" in keyname:
|
self.unmap_special_key(keyname)
|
||||||
self.ctrl_down = False
|
|
||||||
if "shift" in keyname:
|
|
||||||
self.shift_down = False
|
|
||||||
if "alt" in keyname:
|
|
||||||
self.alt_down = False
|
|
||||||
|
|
||||||
mapping = keybindings.lookup(event)
|
mapping = keybindings.lookup(event)
|
||||||
if mapping:
|
if mapping:
|
||||||
# See if in filemanager scope
|
|
||||||
try:
|
try:
|
||||||
getattr(self, mapping)()
|
self.handle_as_controller_scope(mapping)
|
||||||
return True
|
|
||||||
except Exception:
|
except Exception:
|
||||||
# Must be plugins scope, event call, OR we forgot to add method to file manager scope
|
self.handle_as_plugin_scope(mapping)
|
||||||
if "||" in mapping:
|
|
||||||
sender, eve_type = mapping.split("||")
|
|
||||||
else:
|
|
||||||
sender = ""
|
|
||||||
eve_type = mapping
|
|
||||||
|
|
||||||
self.handle_plugin_key_event(sender, eve_type)
|
|
||||||
else:
|
else:
|
||||||
logger.debug(f"on_global_key_release_controller > key > {keyname}")
|
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"]:
|
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()
|
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)
|
event_system.emit(eve_type)
|
||||||
|
|
||||||
def keyboard_close_tab(self):
|
def keyboard_close_tab(self):
|
||||||
|
@ -82,6 +89,6 @@ class KeyboardSignalsMixin:
|
||||||
|
|
||||||
self.get_fm_window(wid).delete_tab_by_id(tid)
|
self.get_fm_window(wid).delete_tab_by_id(tid)
|
||||||
notebook.remove_page(page)
|
notebook.remove_page(page)
|
||||||
if not 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()
|
|
@ -26,7 +26,7 @@ class GridMixin:
|
||||||
store.append([None, file[0]])
|
store.append([None, file[0]])
|
||||||
|
|
||||||
Gtk.main_iteration()
|
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
|
# NOTE: Not likely called often from here but it could be useful
|
||||||
if save_state and not trace_debug:
|
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)]
|
tasks = [self.update_store(i, store, dir, tab, file[0]) for i, file in enumerate(files)]
|
||||||
await asyncio.gather(*tasks)
|
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):
|
async def update_store(self, i, store, dir, tab, file):
|
||||||
icon = tab.create_icon(dir, file)
|
icon = tab.create_icon(dir, file)
|
||||||
itr = store.get_iter(i)
|
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):
|
def create_tab_widget(self, tab):
|
||||||
return TabHeaderWidget(tab, self.close_tab)
|
return TabHeaderWidget(tab, self.close_tab)
|
||||||
|
|
|
@ -34,7 +34,9 @@ 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))
|
event_system.emit("load_files_view_state", (nickname, tabs, isHidden))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@daemon_threaded
|
@daemon_threaded
|
||||||
def _focus_last_visible_notebook(self, icon_grid):
|
def _focus_last_visible_notebook(self, icon_grid):
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
# Python imports
|
# Python imports
|
||||||
|
|
||||||
# Lib imports
|
# Lib imports
|
||||||
import gi
|
|
||||||
gi.require_version('Gtk', '3.0')
|
|
||||||
from gi.repository import Gtk
|
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
|
from ...sfm_builder import SFMBuilder
|
||||||
from ...mixins.signals.file_action_signals_mixin import FileActionSignalsMixin
|
from ...mixins.signals.file_action_signals_mixin import FileActionSignalsMixin
|
||||||
from .window_mixin import WindowMixin
|
from .window_mixin import WindowMixin
|
||||||
|
|
||||||
|
@ -27,7 +25,8 @@ class FilesWidget(FileActionSignalsMixin, WindowMixin):
|
||||||
|
|
||||||
self.INDEX = self.ccount
|
self.INDEX = self.ccount
|
||||||
self.NAME = f"window_{self.INDEX}"
|
self.NAME = f"window_{self.INDEX}"
|
||||||
self.builder = Gtk.Builder()
|
self.builder = SFMBuilder()
|
||||||
|
|
||||||
self.files_view = None
|
self.files_view = None
|
||||||
self.fm_controller = None
|
self.fm_controller = None
|
||||||
|
|
||||||
|
@ -41,20 +40,21 @@ class FilesWidget(FileActionSignalsMixin, WindowMixin):
|
||||||
...
|
...
|
||||||
|
|
||||||
def _setup_signals(self):
|
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):
|
def _subscribe_to_events(self):
|
||||||
event_system.subscribe("load_files_view_state", self._load_files_view_state)
|
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)
|
event_system.subscribe("get_files_view_icon_grid", self._get_files_view_icon_grid)
|
||||||
|
|
||||||
def _load_widgets(self):
|
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 = _builder.get_object(f"{self.NAME}")
|
||||||
|
|
||||||
self.files_view.set_group_name("files_widget")
|
self.files_view.set_group_name("files_widget")
|
||||||
|
|
||||||
self.builder.expose_object(f"{self.NAME}", self.files_view)
|
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 win_name == self.NAME:
|
||||||
if tabs:
|
if tabs:
|
||||||
for tab in tabs:
|
for tab in tabs:
|
||||||
|
@ -62,10 +62,13 @@ class FilesWidget(FileActionSignalsMixin, WindowMixin):
|
||||||
else:
|
else:
|
||||||
self.create_new_tab_notebook(None, self.INDEX, None)
|
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):
|
def _get_files_view_icon_grid(self, win_index = None, tid = None):
|
||||||
if win_index == str(self.INDEX):
|
if win_index == str(self.INDEX):
|
||||||
return self.builder.get_object(f"{self.INDEX}|{tid}|icon_grid", use_gtk = False)
|
return self.builder.get_object(f"{self.INDEX}|{tid}|icon_grid", use_gtk = False)
|
||||||
|
|
||||||
|
|
||||||
def set_fm_controller(self, _fm_controller):
|
def set_fm_controller(self, _fm_controller):
|
||||||
self.fm_controller = _fm_controller
|
self.fm_controller = _fm_controller
|
|
@ -26,7 +26,7 @@ class GridMixin:
|
||||||
store.append([None, file[0]])
|
store.append([None, file[0]])
|
||||||
|
|
||||||
Gtk.main_iteration()
|
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
|
# NOTE: Not likely called often from here but it could be useful
|
||||||
if save_state and not trace_debug:
|
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)]
|
tasks = [self.update_store(i, store, dir, tab, file[0]) for i, file in enumerate(files)]
|
||||||
await asyncio.gather(*tasks)
|
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):
|
async def update_store(self, i, store, dir, tab, file):
|
||||||
icon = tab.create_icon(dir, file)
|
icon = tab.create_icon(dir, file)
|
||||||
itr = store.get_iter(i)
|
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):
|
def create_tab_widget(self, tab):
|
||||||
return TabHeaderWidget(tab, self.close_tab)
|
return TabHeaderWidget(tab, self.close_tab)
|
||||||
|
|
Loading…
Reference in New Issue