updated dir watch; removed keys call where senseable; added additional. debug hook; added threading and async code for testing
This commit is contained in:
parent
a362039e73
commit
2f954f4c79
|
@ -30,58 +30,46 @@ class FileActionSignalsMixin:
|
||||||
|
|
||||||
wid = tab.get_wid()
|
wid = tab.get_wid()
|
||||||
tid = tab.get_id()
|
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)
|
tab.set_dir_watcher(dir_watcher)
|
||||||
|
|
||||||
# NOTE: Too lazy to impliment a proper update handler and so just regen store and update tab.
|
def dir_watch_updates(self, file_monitor, file, other_file = None, eve_type = None, tab_widget_id = None):
|
||||||
# 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):
|
|
||||||
if eve_type in [Gio.FileMonitorEvent.CREATED, Gio.FileMonitorEvent.DELETED,
|
if eve_type in [Gio.FileMonitorEvent.CREATED, Gio.FileMonitorEvent.DELETED,
|
||||||
Gio.FileMonitorEvent.RENAMED, Gio.FileMonitorEvent.MOVED_IN,
|
Gio.FileMonitorEvent.RENAMED, Gio.FileMonitorEvent.MOVED_IN,
|
||||||
Gio.FileMonitorEvent.MOVED_OUT]:
|
Gio.FileMonitorEvent.MOVED_OUT]:
|
||||||
|
|
||||||
if eve_type in [Gio.FileMonitorEvent.MOVED_IN, Gio.FileMonitorEvent.MOVED_OUT]:
|
self.soft_lock_countdown(tab_widget_id)
|
||||||
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])
|
|
||||||
|
|
||||||
@daemon_threaded
|
def soft_lock_countdown(self, tab_widget_id):
|
||||||
def soft_lock_countdown(self, tab_widget):
|
if tab_widget_id in self.soft_update_lock:
|
||||||
self.soft_update_lock[tab_widget] = { "last_update_time": time.time()}
|
timeout_id = self.soft_update_lock[tab_widget_id]["timeout_id"]
|
||||||
|
GLib.source_remove(timeout_id)
|
||||||
|
|
||||||
lock = True
|
timeout_id = GLib.timeout_add(0, self.update_on_soft_lock_end, 600, *(tab_widget_id,))
|
||||||
while lock:
|
self.soft_update_lock[tab_widget_id] = { "timeout_id": timeout_id }
|
||||||
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
|
|
||||||
|
|
||||||
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):
|
def update_on_soft_lock_end(self, timout_ms, tab_widget_id):
|
||||||
wid, tid = tab_widget.split("|")
|
self.soft_update_lock.pop(tab_widget_id, None)
|
||||||
|
|
||||||
|
wid, tid = tab_widget_id.split("|")
|
||||||
notebook = self.builder.get_object(f"window_{wid}")
|
notebook = self.builder.get_object(f"window_{wid}")
|
||||||
tab = self.get_fm_window(wid).get_tab_by_id(tid)
|
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)
|
icon_grid = self.builder.get_object(f"{wid}|{tid}|icon_grid", use_gtk = False)
|
||||||
store = icon_grid.get_model()
|
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()
|
tab.load_directory()
|
||||||
icon_grid.clear_and_set_new_store()
|
icon_grid.clear_and_set_new_store()
|
||||||
self.load_store(tab, icon_grid.get_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()
|
state = self.get_current_state()
|
||||||
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)
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def do_file_search(self, widget, eve = None):
|
def do_file_search(self, widget, eve = None):
|
||||||
if not self.ctrl_down and not self.shift_down and not self.alt_down:
|
if not self.ctrl_down and not self.shift_down and not self.alt_down:
|
||||||
target = widget.get_name()
|
target = widget.get_name()
|
||||||
|
|
|
@ -34,7 +34,6 @@ class GridMixin:
|
||||||
|
|
||||||
dir = tab.get_current_directory()
|
dir = tab.get_current_directory()
|
||||||
files = tab.get_files()
|
files = tab.get_files()
|
||||||
store.clear()
|
|
||||||
|
|
||||||
for file in files:
|
for file in files:
|
||||||
store.append([None, file[0]])
|
store.append([None, file[0]])
|
||||||
|
@ -48,33 +47,51 @@ class GridMixin:
|
||||||
self.fm_controller.save_state()
|
self.fm_controller.save_state()
|
||||||
|
|
||||||
|
|
||||||
@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.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):
|
|
||||||
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)
|
||||||
|
|
||||||
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)
|
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):
|
def insert_store(self, store, itr, icon):
|
||||||
store.set_value(itr, 0, icon)
|
store.set_value(itr, 0, icon)
|
||||||
|
|
||||||
|
|
|
@ -40,16 +40,15 @@ class ContextMenuWidget(Gtk.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 make_submenu(self, name, data):
|
||||||
def make_submenu(self, name, data, keys):
|
|
||||||
menu = Gtk.Menu()
|
menu = Gtk.Menu()
|
||||||
menu_item = Gtk.MenuItem(name)
|
menu_item = Gtk.MenuItem(name)
|
||||||
|
|
||||||
for key in keys:
|
for key, value in data.items():
|
||||||
if isinstance(data, dict):
|
if isinstance(data, dict):
|
||||||
entry = self.make_menu_item(key, data[key])
|
entry = self.make_menu_item(key, value)
|
||||||
elif isinstance(data, list):
|
elif isinstance(data, list):
|
||||||
entry = self.make_menu_item(key, data)
|
entry = self.make_menu_item(key, value)
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
@ -58,11 +57,11 @@ 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, name, data) -> Gtk.MenuItem:
|
def make_menu_item(self, label, data) -> Gtk.MenuItem:
|
||||||
if isinstance(data, dict):
|
if isinstance(data, dict):
|
||||||
return self.make_submenu(name, data, data.keys())
|
return self.make_submenu(label, data)
|
||||||
elif isinstance(data, list):
|
elif isinstance(data, list):
|
||||||
entry = Gtk.ImageMenuItem(name)
|
entry = Gtk.ImageMenuItem(label)
|
||||||
icon = getattr(Gtk, f"{data[0]}")
|
icon = getattr(Gtk, f"{data[0]}")
|
||||||
entry.set_image( Gtk.Image(stock=icon) )
|
entry.set_image( Gtk.Image(stock=icon) )
|
||||||
entry.set_always_show_image(True)
|
entry.set_always_show_image(True)
|
||||||
|
@ -71,18 +70,18 @@ class ContextMenuWidget(Gtk.Menu):
|
||||||
|
|
||||||
def build_context_menu(self) -> None:
|
def build_context_menu(self) -> None:
|
||||||
data = self._context_menu_data
|
data = self._context_menu_data
|
||||||
dkeys = data.keys()
|
|
||||||
plugins_entry = None
|
plugins_entry = None
|
||||||
|
|
||||||
for dkey in dkeys:
|
for key, value in data.items():
|
||||||
entry = self.make_menu_item(dkey, data[dkey])
|
entry = self.make_menu_item(key, value)
|
||||||
self.append(entry)
|
self.append(entry)
|
||||||
if dkey == "Plugins":
|
if key == "Plugins":
|
||||||
plugins_entry = entry
|
plugins_entry = entry
|
||||||
|
|
||||||
self.attach_to_widget(self._window, None)
|
self.attach_to_widget(self._window, None)
|
||||||
self.show_all()
|
|
||||||
self.builder.expose_object("context_menu", self)
|
self.builder.expose_object("context_menu", self)
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
if plugins_entry:
|
if plugins_entry:
|
||||||
self.builder.expose_object("context_menu_plugins", plugins_entry.get_submenu())
|
self.builder.expose_object("context_menu_plugins", plugins_entry.get_submenu())
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ class GridMixin:
|
||||||
loop = None
|
loop = None
|
||||||
|
|
||||||
if loop and loop.is_running():
|
if loop and loop.is_running():
|
||||||
|
loop = asyncio.get_event_loop()
|
||||||
loop.create_task( self.create_icons(tab, store, dir, files) )
|
loop.create_task( self.create_icons(tab, store, dir, files) )
|
||||||
else:
|
else:
|
||||||
asyncio.run( self.create_icons(tab, store, dir, files) )
|
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]
|
icons = [self.get_icon(tab, dir, file[0]) for file in files]
|
||||||
data = await asyncio.gather(*icons)
|
data = await asyncio.gather(*icons)
|
||||||
tasks = [self.update_store(i, store, icon) for i, icon in enumerate(data)]
|
tasks = [self.update_store(i, store, icon) for i, icon in enumerate(data)]
|
||||||
await asyncio.gather(*tasks)
|
asyncio.gather(*tasks)
|
||||||
|
|
||||||
GLib.idle_add(self.do_ui_update)
|
|
||||||
|
|
||||||
async def update_store(self, i, store, icon):
|
async def update_store(self, i, store, icon):
|
||||||
itr = store.get_iter(i)
|
itr = store.get_iter(i)
|
||||||
|
|
|
@ -10,6 +10,7 @@ gi.require_version('Gdk', '3.0')
|
||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
from gi.repository import Gdk
|
from gi.repository import Gdk
|
||||||
from gi.repository import GLib
|
from gi.repository import GLib
|
||||||
|
from gi.repository import GObject
|
||||||
|
|
||||||
# Application imports
|
# Application imports
|
||||||
from core.controller import Controller
|
from core.controller import Controller
|
||||||
|
@ -24,6 +25,8 @@ class Window(Gtk.ApplicationWindow):
|
||||||
"""docstring for Window."""
|
"""docstring for Window."""
|
||||||
|
|
||||||
def __init__(self, args, unknownargs):
|
def __init__(self, args, unknownargs):
|
||||||
|
GObject.threads_init()
|
||||||
|
|
||||||
super(Window, self).__init__()
|
super(Window, self).__init__()
|
||||||
settings_manager.set_main_window(self)
|
settings_manager.set_main_window(self)
|
||||||
|
|
||||||
|
@ -85,7 +88,7 @@ class Window(Gtk.ApplicationWindow):
|
||||||
if visual != None and screen.is_composited():
|
if visual != None and screen.is_composited():
|
||||||
self.set_visual(visual)
|
self.set_visual(visual)
|
||||||
self.set_app_paintable(True)
|
self.set_app_paintable(True)
|
||||||
self.connect("draw", self._area_draw)
|
# self.connect("draw", self._area_draw)
|
||||||
|
|
||||||
# bind css file
|
# bind css file
|
||||||
cssProvider = Gtk.CssProvider()
|
cssProvider = Gtk.CssProvider()
|
||||||
|
|
|
@ -53,9 +53,8 @@ class ManifestProcessor:
|
||||||
def get_loading_data(self):
|
def get_loading_data(self):
|
||||||
loading_data = {}
|
loading_data = {}
|
||||||
requests = self._plugin.requests
|
requests = self._plugin.requests
|
||||||
keys = requests.keys()
|
|
||||||
|
|
||||||
if "ui_target" in keys:
|
if "ui_target" in requests:
|
||||||
if requests["ui_target"] in [
|
if requests["ui_target"] in [
|
||||||
"none", "other", "main_Window", "main_menu_bar",
|
"none", "other", "main_Window", "main_menu_bar",
|
||||||
"main_menu_bttn_box_bar", "path_menu_bar", "plugin_control_list",
|
"main_menu_bttn_box_bar", "path_menu_bar", "plugin_control_list",
|
||||||
|
@ -63,7 +62,7 @@ class ManifestProcessor:
|
||||||
"window_2", "window_3", "window_4"
|
"window_2", "window_3", "window_4"
|
||||||
]:
|
]:
|
||||||
if requests["ui_target"] == "other":
|
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"])
|
loading_data["ui_target"] = self._builder.get_object(requests["ui_target_id"])
|
||||||
if loading_data["ui_target"] == None:
|
if loading_data["ui_target"] == None:
|
||||||
raise ManifestProcessorException('Invalid "ui_target_id" given in requests. Must have one if setting "ui_target" to "other"...')
|
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:
|
else:
|
||||||
raise ManifestProcessorException('Unknown "ui_target" given in requests.')
|
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"]:
|
if requests["pass_fm_events"] in ["true"]:
|
||||||
loading_data["pass_fm_events"] = 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:
|
if len(requests["pass_ui_objects"]) > 0:
|
||||||
loading_data["pass_ui_objects"] = []
|
loading_data["pass_ui_objects"] = []
|
||||||
for ui_id in requests["pass_ui_objects"]:
|
for ui_id in requests["pass_ui_objects"]:
|
||||||
|
@ -87,7 +86,7 @@ class ManifestProcessor:
|
||||||
except ManifestProcessorException as e:
|
except ManifestProcessorException as e:
|
||||||
logger.error(repr(e))
|
logger.error(repr(e))
|
||||||
|
|
||||||
if "bind_keys" in keys:
|
if "bind_keys" in requests:
|
||||||
if isinstance(requests["bind_keys"], list):
|
if isinstance(requests["bind_keys"], list):
|
||||||
loading_data["bind_keys"] = requests["bind_keys"]
|
loading_data["bind_keys"] = requests["bind_keys"]
|
||||||
|
|
||||||
|
|
|
@ -100,20 +100,19 @@ class PluginsController:
|
||||||
|
|
||||||
def execute_plugin(self, module: type, plugin: PluginInfo, loading_data: []):
|
def execute_plugin(self, module: type, plugin: PluginInfo, loading_data: []):
|
||||||
plugin.reference = module.Plugin()
|
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"].add( plugin.reference.generate_reference_ui_element() )
|
||||||
loading_data["ui_target"].show_all()
|
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"] )
|
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.set_fm_event_system(event_system)
|
||||||
plugin.reference.subscribe_to_events()
|
plugin.reference.subscribe_to_events()
|
||||||
|
|
||||||
if "bind_keys" in keys:
|
if "bind_keys" in loading_data:
|
||||||
keybindings.append_bindings( loading_data["bind_keys"] )
|
keybindings.append_bindings( loading_data["bind_keys"] )
|
||||||
|
|
||||||
plugin.reference.run()
|
plugin.reference.run()
|
||||||
|
|
|
@ -37,6 +37,14 @@ def debug_signal_handler(signal, frame):
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
...
|
...
|
||||||
|
|
||||||
|
try:
|
||||||
|
import ipdb
|
||||||
|
logger.debug("\n\nStarting IPDB debugger...\n\n")
|
||||||
|
ipdb.set_trace()
|
||||||
|
return
|
||||||
|
except Exception as ex:
|
||||||
|
...
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import pdb
|
import pdb
|
||||||
logger.debug("\n\nStarting embedded PDB debugger...\n\n")
|
logger.debug("\n\nStarting embedded PDB debugger...\n\n")
|
||||||
|
|
Loading…
Reference in New Issue