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()
|
||||
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()
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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"]
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue