Compare commits

..

10 Commits

Author SHA1 Message Date
Vxrtrauter de1c8577d6 test new workflow 2026-02-02 02:26:41 +01:00
Vxrtrauter c835b8375c test new workflow 2026-02-02 02:23:52 +01:00
Vxrtrauter e7291e8e99 revert workflow changes 2026-02-02 02:23:22 +01:00
Vxrtrauter a4efe9185a update workflows 2026-02-02 02:18:33 +01:00
Vxrtrauter 86b4f023ac update QApplication instance handling (switch to pyqtdarktheme-fork) 2026-02-02 00:50:32 +01:00
KeksNino 006da55aa0 fix: pause/resume button showing up twice 2026-02-01 20:28:24 +01:00
KeksNino 214a389ad3 fix: if statement to disable windows transparency 2026-02-01 20:14:49 +01:00
KeksNino d4005d7e86 fix: disable transparency on windows as it is broken 2026-01-31 19:17:30 +01:00
KeksNino 08a45cb422 feat: add qt window transparency 2026-01-31 18:46:40 +01:00
Vxrtrauter c49726fe42 feat: improve cursor styles for buttons and combo box in GUI 2026-01-31 07:51:00 +01:00
7 changed files with 79 additions and 40 deletions
+17 -11
View File
@@ -28,8 +28,8 @@ jobs:
artifact_name: SoftwareManager-dev-${{ github.sha }}-linux artifact_name: SoftwareManager-dev-${{ github.sha }}-linux
asset_name: SoftwareManager-dev-${{ github.sha }}-linux asset_name: SoftwareManager-dev-${{ github.sha }}-linux
- os: windows-latest - os: windows-latest
artifact_name: SoftwareManager-dev-${{ github.sha }}-windows.exe artifact_name: SoftwareManager-dev-${{ github.sha }}-windows.zip
asset_name: SoftwareManager-dev-${{ github.sha }}-windows.exe asset_name: SoftwareManager-dev-${{ github.sha }}-windows.zip
- os: macos-latest - os: macos-latest
artifact_name: SoftwareManager-dev-${{ github.sha }}-macos artifact_name: SoftwareManager-dev-${{ github.sha }}-macos
asset_name: SoftwareManager-dev-${{ github.sha }}-macos asset_name: SoftwareManager-dev-${{ github.sha }}-macos
@@ -86,7 +86,7 @@ jobs:
if: runner.os == 'Windows' if: runner.os == 'Windows'
shell: bash shell: bash
run: | run: |
pyinstaller --onefile --windowed \ pyinstaller --onedir --windowed \
--add-data "build_info.json;." \ --add-data "build_info.json;." \
--add-data "build_info.json;core" \ --add-data "build_info.json;core" \
--add-data "build_info.json;core/interface" \ --add-data "build_info.json;core/interface" \
@@ -122,15 +122,21 @@ jobs:
--name ${{ env.APP_NAME }} \ --name ${{ env.APP_NAME }} \
main.py main.py
- name: Make executable (Unix) - name: Package and rename artifact (Windows)
if: runner.os != 'Windows' if: runner.os == 'Windows'
run: chmod +x dist/${{ env.APP_NAME }} shell: powershell
run: |
cd dist
Compress-Archive -Path '${{ env.APP_NAME }}' -DestinationPath '${{ matrix.artifact_name }}'
Get-ChildItem
- name: Rename artifact - name: Rename artifact (Unix)
if: runner.os != 'Windows'
shell: bash shell: bash
run: | run: |
cd dist cd dist
mv ${{ env.APP_NAME }}${{ runner.os == 'Windows' && '.exe' || '' }} ${{ matrix.artifact_name }} chmod +x ${{ env.APP_NAME }}
mv ${{ env.APP_NAME }} ${{ matrix.artifact_name }}
ls -la ls -la
- name: Upload build artifact - name: Upload build artifact
@@ -157,7 +163,7 @@ jobs:
mkdir -p release mkdir -p release
SHORT_SHA="${{ needs.build.outputs.short_sha }}" SHORT_SHA="${{ needs.build.outputs.short_sha }}"
cp artifacts/ubuntu-22.04-build/SoftwareManager-dev-*-linux release/SoftwareManager-dev-${SHORT_SHA}-linux cp artifacts/ubuntu-22.04-build/SoftwareManager-dev-*-linux release/SoftwareManager-dev-${SHORT_SHA}-linux
cp artifacts/windows-latest-build/SoftwareManager-dev-*-windows.exe release/SoftwareManager-dev-${SHORT_SHA}-windows.exe cp artifacts/windows-latest-build/SoftwareManager-dev-*-windows.zip release/SoftwareManager-dev-${SHORT_SHA}-windows.zip
cp artifacts/macos-latest-build/SoftwareManager-dev-*-macos release/SoftwareManager-dev-${SHORT_SHA}-macos cp artifacts/macos-latest-build/SoftwareManager-dev-*-macos release/SoftwareManager-dev-${SHORT_SHA}-macos
chmod +x release/SoftwareManager-dev-*-linux release/SoftwareManager-dev-*-macos chmod +x release/SoftwareManager-dev-*-linux release/SoftwareManager-dev-*-macos
ls -la release/ ls -la release/
@@ -175,7 +181,7 @@ jobs:
### Downloads ### Downloads
- Linux: \`SoftwareManager-dev-${SHORT_SHA}-linux\` - Linux: \`SoftwareManager-dev-${SHORT_SHA}-linux\`
- Windows: \`SoftwareManager-dev-${SHORT_SHA}-windows.exe\` - Windows: \`SoftwareManager-dev-${SHORT_SHA}-windows.zip\`
- macOS: \`SoftwareManager-dev-${SHORT_SHA}-macos\` - macOS: \`SoftwareManager-dev-${SHORT_SHA}-macos\`
EOF EOF
cat release_notes.md cat release_notes.md
@@ -188,7 +194,7 @@ jobs:
body_path: release_notes.md body_path: release_notes.md
files: | files: |
release/SoftwareManager-dev-${{ needs.build.outputs.short_sha }}-linux release/SoftwareManager-dev-${{ needs.build.outputs.short_sha }}-linux
release/SoftwareManager-dev-${{ needs.build.outputs.short_sha }}-windows.exe release/SoftwareManager-dev-${{ needs.build.outputs.short_sha }}-windows.zip
release/SoftwareManager-dev-${{ needs.build.outputs.short_sha }}-macos release/SoftwareManager-dev-${{ needs.build.outputs.short_sha }}-macos
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+15
View File
@@ -60,6 +60,21 @@ def settings_dialog(self):
autoresume_layout.addWidget(autoresume_checkbox) autoresume_layout.addWidget(autoresume_checkbox)
dialog.layout().addWidget(autoresume_container) dialog.layout().addWidget(autoresume_container)
# transparent window checkbox
transparent_window_container = QWidget()
transparent_window_layout = QHBoxLayout()
transparent_window_checkbox = QCheckBox()
transparent_window_container.setLayout(transparent_window_layout)
transparent_window_layout.addWidget(QLabel("Window Transparency (requires restart) (Linux/MacOS only): "))
transparent_window_layout.addStretch()
transparent_window_checkbox.setChecked(state.window_transparency)
transparent_window_checkbox.toggled.connect(lambda checked: setattr(state, 'window_transparency', checked))
transparent_window_layout.addWidget(transparent_window_checkbox)
dialog.layout().addWidget(transparent_window_container)
################## ##################
# SERVER SETTING # # SERVER SETTING #
################## ##################
+11 -7
View File
@@ -6,7 +6,6 @@ from PySide6.QtWidgets import (
QWidget, QWidget,
QVBoxLayout, QVBoxLayout,
QListWidget, QListWidget,
QToolBar,
QLabel, QLabel,
QHBoxLayout, QHBoxLayout,
QComboBox, QComboBox,
@@ -16,13 +15,10 @@ from PySide6.QtWidgets import (
QMessageBox, QMessageBox,
QTableWidget, QTableWidget,
QTextEdit, QTextEdit,
QStyle,
QStyleOptionButton,
QStyledItemDelegate, QStyledItemDelegate,
QApplication,
) )
from PySide6.QtGui import QIcon, QAction, QCloseEvent, QImage, QPixmap from PySide6.QtGui import QIcon, QCloseEvent, QImage, QPixmap
import darkdetect import darkdetect
import threading import threading
import platform import platform
@@ -138,6 +134,7 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
self.searchbar.returnPressed.connect(lambda: run_thread(threading.Thread(target=return_pressed, args=(self,)))) # Triggers data function thread on enter self.searchbar.returnPressed.connect(lambda: run_thread(threading.Thread(target=return_pressed, args=(self,)))) # Triggers data function thread on enter
self.dlbutton = QtWidgets.QPushButton("Download") self.dlbutton = QtWidgets.QPushButton("Download")
self.dlbutton.setCursor(Qt.PointingHandCursor)
self.libraryList = QListWidget() self.libraryList = QListWidget()
self.emptyResults = QLabel("No Results") self.emptyResults = QLabel("No Results")
@@ -209,8 +206,7 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
status = magnetdl.status() status = magnetdl.status()
if col == 0: if col == 0:
is_paused = magnetdl.status().paused pass
return "▶︎" if is_paused else "⏸︎"
elif col == 1: elif col == 1:
return status.name if status.has_metadata else "Fetching metadata..." return status.name if status.has_metadata else "Fetching metadata..."
elif col == 2: elif col == 2:
@@ -364,13 +360,18 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
# Tabs # Tabs
self.tabs = QTabWidget() self.tabs = QTabWidget()
self.tabs = QTabWidget()
self.tabs.setStyleSheet(""" self.tabs.setStyleSheet("""
QTabBar::tab { QTabBar::tab {
font-size: 11px; font-size: 11px;
padding: 2px 8px; padding: 2px 8px;
height: 25px; height: 25px;
} }
QTabWidget::pane {
margin-top: -20px;
}
""") """)
self.horizontal_layout = QHBoxLayout() self.horizontal_layout = QHBoxLayout()
self.horizontal_layout.addWidget(self.emptyResults, stretch=3) self.horizontal_layout.addWidget(self.emptyResults, stretch=3)
self.horizontal_layout.addWidget(self.qtablewidget) self.horizontal_layout.addWidget(self.qtablewidget)
@@ -404,6 +405,7 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
self.tracker_list = QComboBox() self.tracker_list = QComboBox()
self.tracker_list.addItems(["rutracker", "uztracker", "m0nkrus"]) self.tracker_list.addItems(["rutracker", "uztracker", "m0nkrus"])
self.tracker_list.setCursor(Qt.PointingHandCursor)
self.tracker_list.activated.connect(self.set_tracker) self.tracker_list.activated.connect(self.set_tracker)
self.corner_layout.addWidget(self.tracker_list) self.corner_layout.addWidget(self.tracker_list)
@@ -415,6 +417,7 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
else: else:
self.settings_btn.setIcon(QIcon(get_asset_path("settings_black.png"))) self.settings_btn.setIcon(QIcon(get_asset_path("settings_black.png")))
self.settings_btn.setToolTip("Settings") self.settings_btn.setToolTip("Settings")
self.settings_btn.setCursor(Qt.PointingHandCursor)
self.settings_btn.clicked.connect(lambda: settings_dialog(self)) self.settings_btn.clicked.connect(lambda: settings_dialog(self))
@@ -429,6 +432,7 @@ class MainWindow(QtWidgets.QMainWindow, QWidget):
self.tab_layout.setContentsMargins(0, 0, 0, 0) self.tab_layout.setContentsMargins(0, 0, 0, 0)
self.tab_layout.setSpacing(0) self.tab_layout.setSpacing(0)
self.tab_bar_layout = QHBoxLayout() self.tab_bar_layout = QHBoxLayout()
self.tab_bar_layout.setContentsMargins(0, 0, 0, 0) self.tab_bar_layout.setContentsMargins(0, 0, 0, 0)
self.tab_bar_layout.setSpacing(0) self.tab_bar_layout.setSpacing(0)
+14 -2
View File
@@ -6,8 +6,19 @@ from core.utils.data.state import state
def create_config(): def create_config():
config = configparser.ConfigParser() config = configparser.ConfigParser()
config["General"] = {"debug": True, "api_url": f"{state.api_url}", "download_path": f"{state.download_path}", f"download_speed_limit": f"{state.down_speed_limit}", f"upload_speed_limit": f"{state.up_speed_limit}", config["General"] = {
"ignore_updates": f"{state.ignore_updates}", "image_path": f"{state.image_path}", "autoresume": f"{state.autoresume}", "max_connections": f"{state.max_connections}", "max_downloads": f"{state.max_downloads}"} "debug": True,
"api_url": f"{state.api_url}",
"download_path": f"{state.download_path}",
"download_speed_limit": f"{state.down_speed_limit}",
"upload_speed_limit": f"{state.up_speed_limit}",
"ignore_updates": f"{state.ignore_updates}",
"image_path": f"{state.image_path}",
"autoresume": f"{state.autoresume}",
"max_connections": f"{state.max_connections}",
"max_downloads": f"{state.max_downloads}",
"window_transparency": f"{state.window_transparency}",
}
if platform.system() == "Windows": if platform.system() == "Windows":
config_dir = os.environ.get("APPDATA", os.path.expanduser("~\\AppData\\Roaming")) config_dir = os.environ.get("APPDATA", os.path.expanduser("~\\AppData\\Roaming"))
@@ -48,5 +59,6 @@ def read_config():
state.autoresume = config.getboolean("General", "autoresume", fallback=state.autoresume) state.autoresume = config.getboolean("General", "autoresume", fallback=state.autoresume)
state.max_connections = config.getint("General", "max_connections", fallback=state.max_connections) state.max_connections = config.getint("General", "max_connections", fallback=state.max_connections)
state.max_downloads = config.getint("General", "max_downloads", fallback=state.max_downloads) state.max_downloads = config.getint("General", "max_downloads", fallback=state.max_downloads)
state.window_transparency = config.getboolean("General", "window_transparency", fallback=state.window_transparency)
create_config() create_config()
+1
View File
@@ -26,6 +26,7 @@ class AppState(QObject):
self.settings_path: str = None self.settings_path: str = None
self.dl_session: Any = None self.dl_session: Any = None
self.active_downloads: List[str] = {} self.active_downloads: List[str] = {}
self.window_transparency: bool = False
@property @property
def image_path(self) -> str: def image_path(self) -> str:
+8 -7
View File
@@ -8,9 +8,10 @@ from core.utils.general.wrappers import run_thread
from core.utils.general.loghandler import split_data, check_completed from core.utils.general.loghandler import split_data, check_completed
from core.utils.config.config import read_config from core.utils.config.config import read_config
from PySide6 import QtWidgets from PySide6 import QtWidgets
from PySide6.QtCore import Qt
import qdarktheme import qdarktheme
import darkdetect
import threading import threading
import platform
import signal import signal
import argparse import argparse
import sys import sys
@@ -21,16 +22,16 @@ parser.add_argument("--debug", action="store_true")
args = parser.parse_args() args = parser.parse_args()
def run_gui(): def run_gui():
app = QtWidgets.QApplication([]) app = QtWidgets.QApplication.instance() or QtWidgets.QApplication(sys.argv)
if darkdetect.isDark: qdarktheme.setup_theme("auto")
app.setStyleSheet(qdarktheme.load_stylesheet("dark"))
else:
app.setStyleSheet(qdarktheme.load_stylesheet("light"))
widget = MainWindow() widget = MainWindow()
if state.window_transparency and platform.system() != "Windows":
widget.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
widget.setStyleSheet("MainWindow { background: transparent; }")
from core.utils.general.logs import set_main_window from core.utils.general.logs import set_main_window
set_main_window(widget) set_main_window(widget)
widget.show() widget.show()
sys.exit(app.exec()) sys.exit(app.exec())
+2 -2
View File
@@ -1,9 +1,9 @@
requests==2.32.2 requests==2.32.2
PySide6==6.10.1 PySide6==6.10.1
beautifulsoup4==4.13.5 beautifulsoup4==4.13.5
darkdetect==0.8.0 darkdetect==0.7.1
pyinstaller==6.15.0 pyinstaller==6.15.0
pyqtdarktheme==0.1.7 PyQtDarkTheme-fork==2.3.4
aiohttp==3.13.0 aiohttp==3.13.0
plyer==2.1.0 plyer==2.1.0
psutil==7.1.0 psutil==7.1.0