From 13228ca1f7114471aec1c0655220087a5873968b Mon Sep 17 00:00:00 2001 From: N0tACyb0rg Date: Sat, 11 May 2024 12:45:52 -0700 Subject: [PATCH] Added config toggle for the system tray, made PyQt6 optional (system tray is disabled if not installed), and behavior fixes with the system tray. --- src/variamain.py | 79 ++++++++++++++++++++++++++------------- src/window/preferences.py | 28 ++++++++++++++ src/window/tray.py | 3 ++ 3 files changed, 83 insertions(+), 27 deletions(-) diff --git a/src/variamain.py b/src/variamain.py index b2373cd..452d565 100644 --- a/src/variamain.py +++ b/src/variamain.py @@ -23,22 +23,35 @@ from download.listen import listen_to_aria2 from download.scheduler import schedule_downloads -from window.tray import SystemTray +import importlib.util class MainWindow(Adw.ApplicationWindow): def __init__(self, variaapp, appdir, appconf, aria2c_subprocess, aria2cexec, *args, **kwargs): super().__init__(*args, **kwargs) self.set_hide_on_close(True) - self.connect('close-request', self.exitProgram, variaapp, True) self.variaapp = variaapp - + self.appconf = appconf self.scheduler_currently_downloading = False self.appdir = appdir - self.appconf = appconf self.aria2c_subprocess = aria2c_subprocess self.bindir = aria2cexec[:-6] + # Check for PyQt6 as it is an optional dependency: + qt_gui = importlib.util.find_spec("PyQt6.QtGui") + qt_widgets = importlib.util.find_spec("PyQt6.QtWidgets") + self.hasqt = qt_gui is not None and qt_widgets is not None + + # Fix config if PyQt6 does not exist and the tray is enabled in the config: + if not self.hasqt and self.appconf["use_tray"] == "tray": + self.appconf["use_tray"] = "none" + self.save_appconf() + + if appconf["use_tray"] == "tray": + self.connect('close-request', self.exitProgram, variaapp, True) + else: + self.connect('close-request', self.exitProgram, variaapp, False) + # Set up variables and all: aria2_connection_successful = initiate(self, variaVersion) @@ -91,9 +104,13 @@ def __init__(self, variaapp, appdir, appconf, aria2c_subprocess, aria2cexec, *ar thread = threading.Thread(target=schedule_downloads(self, True)) thread.start() - self.tray = SystemTray(window=self) - thread = threading.Thread(target=self.tray.run()) - thread.start() + # Start the system tray thread: + if appconf["use_tray"] == "tray": + from window.tray import SystemTray + + self.tray = SystemTray(window=self) + thread = threading.Thread(target=self.tray.run()) + thread.start() # Load incomplete downloads: default_state = {"url": None, "filename": None} @@ -301,6 +318,10 @@ def trayExit(self): def exitProgram(self, app, variaapp, background): if (background == True): self.hide() + try: + self.tray.set_state(False) + except AttributeError: + pass notification = Gio.Notification.new(_("Background Mode")) notification.set_body(_("Continuing the downloads in the background.")) notification.set_title(_("Background Mode")), @@ -316,29 +337,29 @@ def exitProgram(self, app, variaapp, background): self.pause_all("no") self.api.client.shutdown() - if (self.is_visible() == True): - self.hide() - exiting_dialog = Adw.MessageDialog() - exiting_dialog_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=25) - exiting_dialog.set_child(exiting_dialog_box) - exiting_dialog_box.set_margin_top(30) - exiting_dialog_box.set_margin_bottom(30) - exiting_dialog_spinner = Gtk.Spinner() - exiting_dialog_spinner.set_size_request(30, 30) - exiting_dialog_spinner.start() - exiting_dialog_box.append(exiting_dialog_spinner) - exiting_dialog_label = Gtk.Label(label=_("Exiting Varia...")) - exiting_dialog_label.get_style_context().add_class("title-1") - exiting_dialog_box.append(exiting_dialog_label) - exiting_dialog.set_transient_for(self) - GLib.idle_add(exiting_dialog.show) - else: - exiting_dialog = None + self.hide() + exiting_dialog = Adw.MessageDialog() + exiting_dialog_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=25) + exiting_dialog.set_child(exiting_dialog_box) + exiting_dialog_box.set_margin_top(30) + exiting_dialog_box.set_margin_bottom(30) + exiting_dialog_spinner = Gtk.Spinner() + exiting_dialog_spinner.set_size_request(30, 30) + exiting_dialog_spinner.start() + exiting_dialog_box.append(exiting_dialog_spinner) + exiting_dialog_label = Gtk.Label(label=_("Exiting Varia...")) + exiting_dialog_label.get_style_context().add_class("title-1") + exiting_dialog_box.append(exiting_dialog_label) + exiting_dialog.set_transient_for(self) + GLib.idle_add(exiting_dialog.show) GLib.timeout_add(3000, self.aria2c_exiting_check, app, 0, variaapp, exiting_dialog) else: - self.tray.exit() + try: + self.tray.exit() + except AttributeError: + pass self.destroy() variaapp.quit() @@ -353,7 +374,10 @@ def aria2c_exiting_check(self, app, counter, variaapp, exiting_dialog): if (exiting_dialog is not None): exiting_dialog.destroy() self.destroy() - self.tray.exit() + try: + self.tray.exit() + except AttributeError: + pass variaapp.quit() for thread in threading.enumerate(): print(thread.name) @@ -416,6 +440,7 @@ def main(version, aria2cexec): 'remote_location': '', 'schedule_enabled': '0', 'default_mode': 'visible', + 'use_tray': 'tray', 'schedule_mode': 'inclusive', 'schedule': [], 'remote_time': '0', diff --git a/src/window/preferences.py b/src/window/preferences.py index 00b6d85..531d56f 100644 --- a/src/window/preferences.py +++ b/src/window/preferences.py @@ -166,6 +166,21 @@ def show_preferences(button, self, app): if (self.appconf["default_mode"] == "background"): start_in_background.set_active("active") + # Tray: + + tray = Adw.SwitchRow() + tray.set_title(_("Use System Tray")) + tray.connect("notify::active", on_use_system_tray, self, preferences) + + if self.hasqt: + tray.set_sensitive(True) + else: + tray.set_sensitive(False) + tray.set_subtitle(_("Please install PyQt6 to use the system tray")) + + if self.appconf["use_tray"] == "tray": + tray.set_active("active") + # Construct Group 1: group_1.add(download_directory_actionrow) @@ -173,6 +188,7 @@ def show_preferences(button, self, app): group_1.add(scheduler_actionrow) group_1.add(simultaneous_download_amount_unit_names_box) group_1.add(start_in_background) + group_1.add(tray) # Remote aria2: @@ -421,6 +437,18 @@ def on_start_in_background(switch, state, self): self.save_appconf() +def on_use_system_tray(switch, state, self, preferencesWindow): + state = switch.get_active() + if state: + if self.appconf["use_tray"] == "none": + restart_varia_dialog(preferencesWindow) + self.appconf["use_tray"] = "tray" + else: + self.appconf["use_tray"] = "none" + restart_varia_dialog(preferencesWindow) + + self.save_appconf() + def on_remote_time(switch, state, self): state = switch.get_active() if state: diff --git a/src/window/tray.py b/src/window/tray.py index 1d0e321..27a7adc 100644 --- a/src/window/tray.py +++ b/src/window/tray.py @@ -32,6 +32,9 @@ def run(self): self.window.show() self.app.exec() + def set_state(self, state): + self.shown = state + def exit(self): self.app.quit()