refactoring pid logic; addedd window state preservation; slight thread rework

This commit is contained in:
itdominator 2024-01-08 21:11:10 -06:00
parent 8e5ae4824c
commit be7be00f78
12 changed files with 122 additions and 58 deletions

View File

@ -16,35 +16,39 @@ class AppLaunchException(Exception):
class Application(IPCServer):
class Application:
""" docstring for Application. """
def __init__(self, args, unknownargs):
super(Application, self).__init__()
if not settings_manager.is_trace_debug():
self.socket_realization_check()
if not self.is_ipc_alive:
for arg in unknownargs + [args.new_tab,]:
if os.path.isdir(arg):
message = f"FILE|{arg}"
self.send_ipc_message(message)
raise AppLaunchException(f"{app_name} IPC Server Exists: Have sent path(s) to it and closing...")
self.load_ipc(args, unknownargs)
self.setup_debug_hook()
Window(args, unknownargs).main()
def socket_realization_check(self):
def load_ipc(self, args, unknownargs):
ipc_server = IPCServer()
self.ipc_realization_check(ipc_server)
if not ipc_server.is_ipc_alive:
for arg in unknownargs + [args.new_tab,]:
if os.path.isfile(arg):
message = f"FILE|{arg}"
ipc_server.send_ipc_message(message)
raise AppLaunchException(f"{app_name} IPC Server Exists: Have sent path(s) to it and closing...")
def ipc_realization_check(self, ipc_server):
try:
self.create_ipc_listener()
ipc_server.create_ipc_listener()
except Exception:
self.send_test_ipc_message()
ipc_server.send_test_ipc_message()
try:
self.create_ipc_listener()
ipc_server.create_ipc_listener()
except Exception as e:
...

View File

@ -41,15 +41,13 @@ class FileActionSignalsMixin:
Gio.FileMonitorEvent.MOVED_OUT]:
if eve_type in [Gio.FileMonitorEvent.MOVED_IN, Gio.FileMonitorEvent.MOVED_OUT]:
# self.update_on_soft_lock_end(data[0])
GLib.Thread("", self.soft_lock_countdown, data[0])
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])
GLib.Thread("", self.soft_lock_countdown, data[0])
self.soft_lock_countdown(data[0])
# @daemon_threaded
@daemon_threaded
def soft_lock_countdown(self, tab_widget):
self.soft_update_lock[tab_widget] = { "last_update_time": time.time()}
@ -63,9 +61,6 @@ class FileActionSignalsMixin:
self.soft_update_lock.pop(tab_widget, None)
GLib.idle_add(self.update_on_soft_lock_end, *(tab_widget,))
thread = GLib.Thread.self()
thread.unref()
def update_on_soft_lock_end(self, tab_widget):
wid, tid = tab_widget.split("|")

View File

@ -39,13 +39,15 @@ class GridMixin:
store.append([None, file[0]])
Gtk.main_iteration()
GLib.Thread("", self.generate_icons, tab, store, dir, files)
self.generate_icons(tab, store, dir, files)
# GLib.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:
self.fm_controller.save_state()
@daemon_threaded
def generate_icons(self, tab, store, dir, files):
try:
loop = asyncio.get_running_loop()
@ -57,9 +59,6 @@ class GridMixin:
else:
asyncio.run( self.create_icons(tab, store, dir, files) )
thread = GLib.Thread.self()
thread.unref()
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)
@ -77,6 +76,7 @@ class GridMixin:
def insert_store(self, store, itr, icon):
store.set_value(itr, 0, icon)
# Note: If the function returns GLib.SOURCE_REMOVE or False it is automatically removed from the list of event sources and will not be called again.
return False

View File

@ -177,6 +177,10 @@ class WindowMixin(TabMixin):
if from_uri != dest:
event_system.emit("move_files", (uris, dest))
Gtk.drag_finish(drag_context, True, False, time)
return
Gtk.drag_finish(drag_context, False, False, time)
def create_new_tab_notebook(self, widget=None, wid=None, path=None):
self.create_tab(wid, None, path)
self.create_tab(wid, None, path)

View File

@ -39,13 +39,15 @@ class GridMixin:
store.append([None, file[0]])
Gtk.main_iteration()
GLib.Thread("", self.generate_icons, tab, store, dir, files)
self.generate_icons(tab, store, dir, files)
# GLib.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:
self.fm_controller.save_state()
@daemon_threaded
def generate_icons(self, tab, store, dir, files):
try:
loop = asyncio.get_running_loop()
@ -57,9 +59,6 @@ class GridMixin:
else:
asyncio.run( self.create_icons(tab, store, dir, files) )
thread = GLib.Thread.self()
thread.unref()
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)
@ -77,6 +76,7 @@ class GridMixin:
def insert_store(self, store, itr, icon):
store.set_value(itr, 0, icon)
# Note: If the function returns GLib.SOURCE_REMOVE or False it is automatically removed from the list of event sources and will not be called again.
return False

View File

@ -173,6 +173,10 @@ class WindowMixin(TabMixin):
if from_uri != dest:
event_system.emit("move_files", (uris, dest))
Gtk.drag_finish(drag_context, True, False, time)
return
Gtk.drag_finish(drag_context, False, False, time)
def create_new_tab_notebook(self, widget=None, wid=None, path=None):
self.create_tab(wid, None, path)
self.create_tab(wid, None, path)

View File

@ -25,17 +25,17 @@ class Window(Gtk.ApplicationWindow):
def __init__(self, args, unknownargs):
super(Window, self).__init__()
self._controller = None
settings_manager.set_main_window(self)
self._set_window_data()
self._controller = None
self._setup_styling()
self._setup_signals()
self._subscribe_to_events()
self._load_widgets(args, unknownargs)
self._set_window_data()
self._set_size_constraints()
self.show()
@ -66,6 +66,18 @@ class Window(Gtk.ApplicationWindow):
self.add( self._controller.get_core_widget() )
def _set_size_constraints(self):
_window_x = settings.config.main_window_x
_window_y = settings.config.main_window_y
_min_width = settings.config.main_window_min_width
_min_height = settings.config.main_window_min_height
_width = settings.config.main_window_width
_height = settings.config.main_window_height
self.move(_window_x, _window_y - 28)
self.set_size_request(_min_width, _min_height)
self.set_default_size(_width, _height)
def _set_window_data(self) -> None:
screen = self.get_screen()
visual = screen.get_rgba_visual()
@ -91,8 +103,19 @@ class Window(Gtk.ApplicationWindow):
def _load_interactive_debug(self):
self.set_interactive_debugging(True)
def _tear_down(self, widget = None, eve = None):
event_system.emit("shutting_down")
size = self.get_size()
pos = self.get_position()
settings_manager.set_main_window_width(size.width)
settings_manager.set_main_window_height(size.height)
settings_manager.set_main_window_x(pos.root_x)
settings_manager.set_main_window_y(pos.root_y)
settings_manager.save_settings()
settings_manager.clear_pid()
Gtk.main_quit()

View File

@ -146,6 +146,13 @@ class SettingsManager(StartCheckMixin, Singleton):
def is_trace_debug(self) -> bool: return self._trace_debug
def is_debug(self) -> bool: return self._debug
def set_main_window_x(self, x = 0): self.settings.config.main_window_x = x
def set_main_window_y(self, y = 0): self.settings.config.main_window_y = y
def set_main_window_width(self, width = 800): self.settings.config.main_window_width = width
def set_main_window_height(self, height = 600): self.settings.config.main_window_height = height
def set_main_window_min_width(self, width = 720): self.settings.config.main_window_min_width = width
def set_main_window_min_height(self, height = 480): self.settings.config.main_window_min_height = height
def set_trace_debug(self, trace_debug: bool):
self._trace_debug = trace_debug

View File

@ -30,7 +30,14 @@ class Config:
sys_icon_wh: list = field(default_factory=lambda: [56, 56])
steam_cdn_url: str = "https://steamcdn-a.akamaihd.net/steam/apps/"
remux_folder_max_disk_usage: str = "8589934592"
make_transparent: int = 0
main_window_x: int = 721
main_window_y: int = 465
main_window_min_width: int = 720
main_window_min_height: int = 480
main_window_width: int = 800
main_window_height: int = 600
application_dirs: list = field(default_factory=lambda: [
"/usr/share/applications",
f"{settings_manager.get_home_path()}/.local/share/applications"
])
])

View File

@ -11,36 +11,48 @@ import inspect
class StartCheckMixin:
def is_dirty_start(self) -> bool: return self._dirty_start
def clear_pid(self): self._clean_pid()
def is_dirty_start(self) -> bool:
return self._dirty_start
def clear_pid(self):
if not self.is_trace_debug():
self._clean_pid()
def do_dirty_start_check(self):
if not os.path.exists(self._PID_FILE):
self._write_new_pid()
else:
with open(self._PID_FILE, "r") as _pid:
pid = _pid.readline().strip()
if self.is_trace_debug():
pid = os.getpid()
self._print_pid(pid)
return
if os.path.exists(self._PID_FILE):
with open(self._PID_FILE, "r") as f:
pid = f.readline().strip()
if pid not in ("", None):
self._check_alive_status(int(pid))
else:
self._write_new_pid()
if self.is_pid_alive( int(pid) ):
print("PID file exists and PID is alive... Letting downstream errors (sans debug args) handle app closure propigation.")
return
self._write_new_pid()
""" Check For the existence of a unix pid. """
def _check_alive_status(self, pid):
def is_pid_alive(self, pid):
print(f"PID Found: {pid}")
try:
os.kill(pid, 0)
except OSError:
print(f"{app_name} is starting dirty...")
print(f"{app_name} PID file exists but PID is irrelevant; starting dirty...")
self._dirty_start = True
self._write_new_pid()
return
return False
print("PID is alive... Let downstream errors (sans debug args) handle app closure propigation.")
return True
def _write_new_pid(self):
pid = os.getpid()
self._write_pid(pid)
self._print_pid(pid)
def _print_pid(self, pid):
print(f"{app_name} PID: {pid}")
def _clean_pid(self):
@ -48,4 +60,4 @@ class StartCheckMixin:
def _write_pid(self, pid):
with open(self._PID_FILE, "w") as _pid:
_pid.write(f"{pid}")
_pid.write(f"{pid}")

View File

@ -1,8 +1,9 @@
{
"Open Actions": {
"Open": ["STOCK_OPEN", "open"],
"Open With": ["STOCK_OPEN", "open_with"],
"Execute": ["STOCK_EXECUTE", "execute"],
"Open": ["STOCK_OPEN", "open"],
"Open With": ["STOCK_OPEN", "open_with"],
"Open 2 Tab": ["STOCK_OPEN", "open_2_new_tab"],
"Execute": ["STOCK_EXECUTE", "execute"],
"Execute in Terminal": ["STOCK_EXECUTE", "execute_in_terminal"]
},
"File Actions": {
@ -16,4 +17,4 @@
"Paste": ["STOCK_PASTE", "paste"]
},
"Plugins": {}
}
}

View File

@ -21,7 +21,14 @@
"sys_icon_wh": [56, 56],
"file_manager_app": "solarfm",
"steam_cdn_url": "https://steamcdn-a.akamaihd.net/steam/apps/",
"remux_folder_max_disk_usage": "8589934592"
"remux_folder_max_disk_usage": "8589934592",
"make_transparent":0,
"main_window_x":721,
"main_window_y":465,
"main_window_min_width":720,
"main_window_min_height":480,
"main_window_width":800,
"main_window_height":600,
},
"filters": {
"meshs": [".dae", ".fbx", ".gltf", ".obj", ".stl"],