diff --git a/src/interface/dialogs/contextmenu.py b/src/interface/dialogs/contextmenu.py index 6e4c603..67bb51d 100644 --- a/src/interface/dialogs/contextmenu.py +++ b/src/interface/dialogs/contextmenu.py @@ -1,7 +1,7 @@ +from PySide6.QtCore import Qt, QPoint, QObject, Signal, QRunnable, QThreadPool from utils.logging.logs import consoleLog, remove_download_log from utils.network.download import download_selected from utils.data.tracker import get_magnet_link -from PySide6.QtCore import Qt, QPoint, QTimer, QObject, Signal from utils.general.wrappers import run_thread from PySide6.QtWidgets import QMessageBox from utils.data.state import state @@ -14,13 +14,21 @@ import platform import time import os -class Worker(QObject): + +class WorkerSignals(QObject): finished = Signal(str) - def run(self, url): - magnet = get_magnet_link(url) + +class Worker(QRunnable): + def __init__(self, url): + super().__init__() + self.url = url + self.signals = WorkerSignals() + + def run(self): + magnet = get_magnet_link(self.url) if magnet: - self.finished.emit(magnet) + self.signals.finished.emit(magnet) class ContextMenu_Downloads: def __init__(self, main_window): @@ -220,6 +228,8 @@ class ContextMenu_TrackerTable: def copyMagnetURIAction(self): if not hasattr(self, '_context_menu_row'): return + if not hasattr(self, "_workers"): + self._workers = [] row = self._context_menu_row if row < 0 or row >= len(state.trackers): return @@ -243,10 +253,18 @@ class ContextMenu_TrackerTable: clipboard.setText(magnet) consoleLog("Magnet URI copied to clipboard!", True) - self._magnet_worker = Worker() - self._magnet_worker.finished.connect(copy_to_clipboard) + + def start_worker(url): + worker = Worker(url) + worker.signals.finished.connect(copy_to_clipboard) - run_thread(threading.Thread(target=self._magnet_worker.run, args=(url,))) + self._workers.append(worker) + + worker.signals.finished.connect(lambda _: self._workers.remove(worker)) + + QThreadPool.globalInstance().start(worker) + + start_worker(url) def openInBrowserAction(self): if not hasattr(self, '_context_menu_row'): diff --git a/src/main.py b/src/main.py index 1ab77ad..3cd40ff 100644 --- a/src/main.py +++ b/src/main.py @@ -1,6 +1,7 @@ from network.libtorrent_misc import send_notification, update_log, check_deleted_files from utils.logging.loghandler import split_data, check_completed, check_downloads from network.interface import list_interfaces, init_interfaces +from PySide6.QtNetwork import QLocalServer, QLocalSocket from utils.logging.logs import get_download_logs from utils.logging.logs import set_main_window from network.libtorrent_int import check_space @@ -10,12 +11,12 @@ from interface.assets.base64_icons import logo_base64 from PySide6.QtWidgets import QSystemTrayIcon, QMenu from utils.general.shutdown import force_exit from utils.config.config import read_config +from PySide6.QtGui import QAction, QPixmap from utils.logging.logs import consoleLog from interface.gui import MainWindow +from PySide6.QtCore import Qt, QObject from utils.data.state import state -from PySide6.QtGui import QAction, QPixmap from PySide6 import QtWidgets -from PySide6.QtCore import Qt import qdarktheme import threading import platform @@ -24,6 +25,40 @@ import signal import time import sys +SERVER_NAME = "SoftwareManager_python" + +class SingleInstance(QObject): + def __init__(self): + super().__init__() + self.server = QLocalServer() + + socket = QLocalSocket() + socket.connectToServer(SERVER_NAME) + + if socket.waitForConnected(100): + socket.write(b"raise") + socket.flush() + socket.waitForBytesWritten(100) + self.is_running = True + else: + QLocalServer.removeServer(SERVER_NAME) + self.server.listen(SERVER_NAME) + self.server.newConnection.connect(self.handle_connection) + self.is_running = False + self.is_running = False + + def handle_connection(self): + socket = self.server.nextPendingConnection() + socket.readyRead.connect(lambda: self.read_socket(socket)) + + def read_socket(self, socket): + msg = socket.readAll().data() + if msg == b"raise": + self.on_raise() + + def on_raise(self): + pass + def run_gui(app): custom_colors = {} if state.accent_color: @@ -58,6 +93,20 @@ def run_gui(app): tray.activated.connect(lambda reason: widget.show() if reason == QSystemTrayIcon.ActivationReason.Trigger else None) tray.setContextMenu(menu) + def show_from_tray(): + widget.show() + widget.raise_() + widget.activateWindow() + + single = SingleInstance() + if single.is_running: + consoleLog("Another instance is already running. Exiting this instance.") + closehelper() + force_exit() + + app._single_instance = single + single.on_raise = show_from_tray + set_main_window(widget) widget.show() signal.signal(signal.SIGINT, signal.SIG_DFL)