commit
1574f2853d
11 changed files with 1662 additions and 0 deletions
@ -0,0 +1,280 @@ |
|||||||
|
# Byte-compiled / optimized / DLL files |
||||||
|
__pycache__/ |
||||||
|
*.py[cod] |
||||||
|
*$py.class |
||||||
|
|
||||||
|
# C extensions |
||||||
|
*.so |
||||||
|
|
||||||
|
# Distribution / packaging |
||||||
|
.Python |
||||||
|
build/ |
||||||
|
develop-eggs/ |
||||||
|
dist/ |
||||||
|
downloads/ |
||||||
|
eggs/ |
||||||
|
.eggs/ |
||||||
|
lib/ |
||||||
|
lib64/ |
||||||
|
parts/ |
||||||
|
sdist/ |
||||||
|
var/ |
||||||
|
wheels/ |
||||||
|
share/python-wheels/ |
||||||
|
*.egg-info/ |
||||||
|
.installed.cfg |
||||||
|
*.egg |
||||||
|
MANIFEST |
||||||
|
|
||||||
|
# PyInstaller |
||||||
|
# Usually these files are written by a python script from a template |
||||||
|
# before PyInstaller builds the exe, so as to inject date/other infos into it. |
||||||
|
*.manifest |
||||||
|
*.spec |
||||||
|
|
||||||
|
# Installer logs |
||||||
|
pip-log.txt |
||||||
|
pip-delete-this-directory.txt |
||||||
|
|
||||||
|
# Unit test / coverage reports |
||||||
|
htmlcov/ |
||||||
|
.tox/ |
||||||
|
.nox/ |
||||||
|
.coverage |
||||||
|
.coverage.* |
||||||
|
.cache |
||||||
|
nosetests.xml |
||||||
|
coverage.xml |
||||||
|
*.cover |
||||||
|
*.py,cover |
||||||
|
.hypothesis/ |
||||||
|
.pytest_cache/ |
||||||
|
cover/ |
||||||
|
|
||||||
|
# Translations |
||||||
|
*.mo |
||||||
|
*.pot |
||||||
|
|
||||||
|
# Django stuff: |
||||||
|
*.log |
||||||
|
local_settings.py |
||||||
|
db.sqlite3 |
||||||
|
db.sqlite3-journal |
||||||
|
|
||||||
|
# Flask stuff: |
||||||
|
instance/ |
||||||
|
.webassets-cache |
||||||
|
|
||||||
|
# Scrapy stuff: |
||||||
|
.scrapy |
||||||
|
|
||||||
|
# Sphinx documentation |
||||||
|
docs/_build/ |
||||||
|
|
||||||
|
# PyBuilder |
||||||
|
.pybuilder/ |
||||||
|
target/ |
||||||
|
|
||||||
|
# Jupyter Notebook |
||||||
|
.ipynb_checkpoints |
||||||
|
|
||||||
|
# IPython |
||||||
|
profile_default/ |
||||||
|
ipython_config.py |
||||||
|
|
||||||
|
# pyenv |
||||||
|
# For a library or package, you might want to ignore these files since the code is |
||||||
|
# intended to run in multiple environments; otherwise, check them in: |
||||||
|
# .python-version |
||||||
|
|
||||||
|
# pipenv |
||||||
|
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. |
||||||
|
# However, in case of collaboration, if having platform-specific dependencies or dependencies |
||||||
|
# having no cross-platform support, pipenv may install dependencies that don't work, or not |
||||||
|
# install all needed dependencies. |
||||||
|
#Pipfile.lock |
||||||
|
|
||||||
|
# poetry |
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. |
||||||
|
# This is especially recommended for binary packages to ensure reproducibility, and is more |
||||||
|
# commonly ignored for libraries. |
||||||
|
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control |
||||||
|
#poetry.lock |
||||||
|
|
||||||
|
# pdm |
||||||
|
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. |
||||||
|
#pdm.lock |
||||||
|
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it |
||||||
|
# in version control. |
||||||
|
# https://pdm.fming.dev/#use-with-ide |
||||||
|
.pdm.toml |
||||||
|
|
||||||
|
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm |
||||||
|
__pypackages__/ |
||||||
|
|
||||||
|
# Celery stuff |
||||||
|
celerybeat-schedule |
||||||
|
celerybeat.pid |
||||||
|
|
||||||
|
# SageMath parsed files |
||||||
|
*.sage.py |
||||||
|
|
||||||
|
# Environments |
||||||
|
.env |
||||||
|
.venv |
||||||
|
env/ |
||||||
|
venv/ |
||||||
|
ENV/ |
||||||
|
env.bak/ |
||||||
|
venv.bak/ |
||||||
|
|
||||||
|
# Spyder project settings |
||||||
|
.spyderproject |
||||||
|
.spyproject |
||||||
|
|
||||||
|
# Rope project settings |
||||||
|
.ropeproject |
||||||
|
|
||||||
|
# mkdocs documentation |
||||||
|
/site |
||||||
|
|
||||||
|
# mypy |
||||||
|
.mypy_cache/ |
||||||
|
.dmypy.json |
||||||
|
dmypy.json |
||||||
|
|
||||||
|
# Pyre type checker |
||||||
|
.pyre/ |
||||||
|
|
||||||
|
# pytype static type analyzer |
||||||
|
.pytype/ |
||||||
|
|
||||||
|
# Cython debug symbols |
||||||
|
cython_debug/ |
||||||
|
|
||||||
|
# PyCharm |
||||||
|
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can |
||||||
|
# be added to the global gitignore or merged into this project gitignore. |
||||||
|
# For PyCharm Community Edition, use 'PyCharm CE' instead of 'PyCharm'. |
||||||
|
.idea/ |
||||||
|
|
||||||
|
# VSCode |
||||||
|
.vscode/ |
||||||
|
*.code-workspace |
||||||
|
|
||||||
|
# Local History for Visual Studio Code |
||||||
|
.history/ |
||||||
|
|
||||||
|
# Built Visual Studio Code Extensions |
||||||
|
*.vsix |
||||||
|
|
||||||
|
# macOS |
||||||
|
.DS_Store |
||||||
|
.AppleDouble |
||||||
|
.LSOverride |
||||||
|
|
||||||
|
# Icon must end with two \r |
||||||
|
Icon |
||||||
|
|
||||||
|
# Thumbnails |
||||||
|
._* |
||||||
|
|
||||||
|
# Files that might appear in the root of a volume |
||||||
|
.DocumentRevisions-V100 |
||||||
|
.fseventsd |
||||||
|
.Spotlight-V100 |
||||||
|
.TemporaryItems |
||||||
|
.Trashes |
||||||
|
.VolumeIcon.icns |
||||||
|
.com.apple.timemachine.donotpresent |
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share |
||||||
|
.AppleDB |
||||||
|
.AppleDesktop |
||||||
|
Network Trash Folder |
||||||
|
Temporary Items |
||||||
|
.apdisk |
||||||
|
|
||||||
|
# Windows |
||||||
|
# Windows thumbnail cache files |
||||||
|
Thumbs.db |
||||||
|
Thumbs.db:encryptable |
||||||
|
ehthumbs.db |
||||||
|
ehthumbs_vista.db |
||||||
|
|
||||||
|
# Dump file |
||||||
|
*.stackdump |
||||||
|
|
||||||
|
# Folder config file |
||||||
|
[Dd]esktop.ini |
||||||
|
|
||||||
|
# Recycle Bin used on file shares |
||||||
|
$RECYCLE.BIN/ |
||||||
|
|
||||||
|
# Windows Installer files |
||||||
|
*.cab |
||||||
|
*.msi |
||||||
|
*.msix |
||||||
|
*.msm |
||||||
|
*.msp |
||||||
|
|
||||||
|
# Windows shortcuts |
||||||
|
*.lnk |
||||||
|
|
||||||
|
# Linux |
||||||
|
*~ |
||||||
|
|
||||||
|
# temporary files which can be created if a process still has a handle open of a deleted file |
||||||
|
.fuse_hidden* |
||||||
|
|
||||||
|
# KDE directory preferences |
||||||
|
.directory |
||||||
|
|
||||||
|
# Linux trash folder which might appear on any partition or disk |
||||||
|
.Trash-* |
||||||
|
|
||||||
|
# .nfs files are created when an open file is removed but is still being accessed |
||||||
|
.nfs* |
||||||
|
|
||||||
|
# Project specific |
||||||
|
# ComfyUI installations (if any get created locally) |
||||||
|
ComfyUI/ |
||||||
|
comfy/ |
||||||
|
|
||||||
|
# Logs |
||||||
|
*.log |
||||||
|
logs/ |
||||||
|
|
||||||
|
# Configuration files that might contain sensitive info |
||||||
|
config.json |
||||||
|
*.ini |
||||||
|
|
||||||
|
# Temporary files |
||||||
|
*.tmp |
||||||
|
*.temp |
||||||
|
temp/ |
||||||
|
tmp/ |
||||||
|
|
||||||
|
# Archive files (shouldn't be committed) |
||||||
|
*.zip |
||||||
|
*.tar.gz |
||||||
|
*.rar |
||||||
|
*.7z |
||||||
|
|
||||||
|
# Backup files |
||||||
|
*.bak |
||||||
|
*.backup |
||||||
|
*~ |
||||||
|
|
||||||
|
# Editor swap files |
||||||
|
*.swp |
||||||
|
*.swo |
||||||
|
*~ |
||||||
|
|
||||||
|
# GTK/GLib cache and temporary files |
||||||
|
.cache/ |
||||||
|
gschemas.compiled |
||||||
|
|
||||||
|
# Application specific temporary files |
||||||
|
comfyui_*.pid |
||||||
|
launcher_*.lock |
||||||
@ -0,0 +1,60 @@ |
|||||||
|
# Changelog |
||||||
|
|
||||||
|
All notable changes to ComfyUI Launcher will be documented in this file. |
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), |
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). |
||||||
|
|
||||||
|
## [1.0.0] - 2025-09-29 |
||||||
|
|
||||||
|
### Added |
||||||
|
- Initial release of ComfyUI Launcher |
||||||
|
- GTK4 based modern interface with libadwaita |
||||||
|
- Full conda environment detection and management |
||||||
|
- Automatic ComfyUI installation via comfy-cli |
||||||
|
- Real-time process monitoring (checks every 3 seconds) |
||||||
|
- Start/stop controls for ComfyUI |
||||||
|
- Real-time log viewing with timestamps |
||||||
|
- Status indicators with visual feedback |
||||||
|
- Cross-platform support (Linux distributions) |
||||||
|
- System dependency detection and installation guidance |
||||||
|
- Desktop integration file |
||||||
|
- Comprehensive documentation in English and Italian |
||||||
|
- Automated installation script for Fedora and Debian-based systems |
||||||
|
|
||||||
|
### Features |
||||||
|
- **Environment Management**: Automatic detection of conda environments |
||||||
|
- **Process Control**: Start, stop, and monitor ComfyUI processes |
||||||
|
- **Real-time Monitoring**: Continuous status checking via port 8188 and process detection |
||||||
|
- **Installation Assistant**: One-click installation of ComfyUI and dependencies |
||||||
|
- **Log Viewer**: Real-time output display with monospace font |
||||||
|
- **Modern UI**: GTK4 interface with proper dark/light theme support |
||||||
|
- **Cross-distribution Support**: Works on Fedora, Ubuntu, Debian, and other Linux distributions |
||||||
|
|
||||||
|
### System Requirements |
||||||
|
- Python 3.9 or higher |
||||||
|
- GTK4 and libadwaita |
||||||
|
- Conda or Miniconda |
||||||
|
- Cairo, GObject Introspection development libraries |
||||||
|
|
||||||
|
### Known Issues |
||||||
|
- Font fallback may not work properly on systems without monospace fonts |
||||||
|
- Some older GTK themes may not display correctly with libadwaita |
||||||
|
|
||||||
|
### Documentation |
||||||
|
- Complete installation guide for Debian and Fedora |
||||||
|
- Troubleshooting section for common issues |
||||||
|
- Development setup instructions |
||||||
|
- Contributing guidelines |
||||||
|
|
||||||
|
### Files Added |
||||||
|
- `main.py` - Main application code |
||||||
|
- `requirements.txt` - Python dependencies |
||||||
|
- `install.sh` - Automated installation script |
||||||
|
- `README_EN.md` - English documentation |
||||||
|
- `README.md` - Italian documentation |
||||||
|
- `style.css` - Custom GTK styles |
||||||
|
- `pyproject.toml` - Project configuration |
||||||
|
- `.gitignore` - Git ignore rules |
||||||
|
- `LICENSE` - MIT license |
||||||
|
- `CHANGELOG.md` - This changelog |
||||||
@ -0,0 +1,41 @@ |
|||||||
|
MIT License |
||||||
|
|
||||||
|
Copyright (c) 2025 ComfyUI Launcher Team |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
of this software and associated documentation files (the "Software"), to deal |
||||||
|
in the Software without restriction, including without limitation the rights |
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the Software is |
||||||
|
furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all |
||||||
|
copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
SOFTWARE. |
||||||
|
|
||||||
|
Copyright (c) 2025 [Il tuo nome] |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
of this software and associated documentation files (the "Software"), to deal |
||||||
|
in the Software without restriction, including without limitation the rights |
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
copies of the Software, and to permit persons to whom the Software is |
||||||
|
furnished to do so, subject to the following conditions: |
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all |
||||||
|
copies or substantial portions of the Software. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
SOFTWARE. |
||||||
@ -0,0 +1,124 @@ |
|||||||
|
# ComfyUI Launcher |
||||||
|
|
||||||
|
Un launcher GTK4 moderno per ComfyUI con supporto completo per ambienti conda. |
||||||
|
|
||||||
|
## Caratteristiche |
||||||
|
|
||||||
|
- 🚀 **Gestione Ambienti Conda**: Selezione facile degli ambienti conda disponibili |
||||||
|
- 🔧 **Installazione Automatica**: Installa ComfyUI e comfy-cli con un click |
||||||
|
- 📊 **Monitoraggio in Tempo Reale**: Controlla continuamente se ComfyUI è in esecuzione |
||||||
|
- 🎮 **Controlli Intuitivi**: Avvia e ferma ComfyUI facilmente |
||||||
|
- 📝 **Log in Tempo Reale**: Visualizza l'output di ComfyUI direttamente nel launcher |
||||||
|
- 🎨 **Interfaccia Moderna**: Basata su GTK4 e libadwaita |
||||||
|
|
||||||
|
## Prerequisiti |
||||||
|
|
||||||
|
- Python 3.9 o superiore |
||||||
|
- conda o miniconda installato |
||||||
|
- GTK4 e libadwaita |
||||||
|
- Librerie di sviluppo (cairo-devel, gobject-introspection-devel, ecc.) |
||||||
|
|
||||||
|
## Installazione Dipendenze Sistema |
||||||
|
|
||||||
|
### Fedora/RHEL: |
||||||
|
```bash |
||||||
|
sudo dnf install cairo-devel gobject-introspection-devel gtk3-devel pkg-config python3-devel |
||||||
|
``` |
||||||
|
|
||||||
|
### Ubuntu/Debian: |
||||||
|
```bash |
||||||
|
sudo apt install libcairo2-dev libgirepository1.0-dev libgtk-3-dev pkg-config python3-dev |
||||||
|
``` |
||||||
|
|
||||||
|
## Installazione |
||||||
|
|
||||||
|
1. Clona il repository: |
||||||
|
```bash |
||||||
|
git clone <repository-url> |
||||||
|
cd gtk-app |
||||||
|
``` |
||||||
|
|
||||||
|
2. Crea e attiva l'ambiente virtuale: |
||||||
|
```bash |
||||||
|
python3 -m venv .venv |
||||||
|
source .venv/bin/activate |
||||||
|
``` |
||||||
|
|
||||||
|
3. Installa le dipendenze Python: |
||||||
|
```bash |
||||||
|
pip install pygobject |
||||||
|
``` |
||||||
|
|
||||||
|
## Utilizzo |
||||||
|
|
||||||
|
1. Avvia il launcher: |
||||||
|
```bash |
||||||
|
python main.py |
||||||
|
``` |
||||||
|
|
||||||
|
2. Seleziona un ambiente conda dalla lista dropdown |
||||||
|
|
||||||
|
3. Se ComfyUI non è installato nell'ambiente, clicca "Installa ComfyUI" |
||||||
|
|
||||||
|
4. Una volta installato, usa "Avvia ComfyUI" per lanciare ComfyUI |
||||||
|
|
||||||
|
5. Il launcher monitorerà automaticamente lo stato di ComfyUI |
||||||
|
|
||||||
|
## Funzionalità Dettagliate |
||||||
|
|
||||||
|
### Gestione Ambienti Conda |
||||||
|
- Lista automatica di tutti gli ambienti conda disponibili |
||||||
|
- Supporto per l'ambiente base |
||||||
|
- Pulsante di aggiornamento per ricaricare la lista |
||||||
|
|
||||||
|
### Monitoraggio Stato |
||||||
|
- Controllo ogni 3 secondi se ComfyUI è in esecuzione |
||||||
|
- Indicatore visivo dello stato (icona e colore) |
||||||
|
- Rilevamento tramite porta 8188 e processi attivi |
||||||
|
|
||||||
|
### Controlli |
||||||
|
- **Avvia ComfyUI**: Lancia ComfyUI nell'ambiente selezionato |
||||||
|
- **Ferma ComfyUI**: Termina gracefully il processo ComfyUI |
||||||
|
- **Installa ComfyUI**: Installa comfy-cli e ComfyUI nell'ambiente |
||||||
|
|
||||||
|
### Log |
||||||
|
- Output in tempo reale di ComfyUI |
||||||
|
- Timestamp per ogni messaggio |
||||||
|
- Font monospace per miglior leggibilità |
||||||
|
|
||||||
|
## File di Configurazione |
||||||
|
|
||||||
|
- `main.py`: Applicazione principale |
||||||
|
- `style.css`: Stili personalizzati (opzionale) |
||||||
|
- `comfyui-launcher.desktop`: File desktop per integrazione sistema |
||||||
|
|
||||||
|
## Problemi Comuni |
||||||
|
|
||||||
|
### Conda non trovato |
||||||
|
Assicurati che conda sia nel PATH: |
||||||
|
```bash |
||||||
|
export PATH="$HOME/miniconda3/bin:$PATH" |
||||||
|
``` |
||||||
|
|
||||||
|
### Errori di permessi |
||||||
|
Su alcuni sistemi potrebbe essere necessario rendere eseguibile lo script: |
||||||
|
```bash |
||||||
|
chmod +x main.py |
||||||
|
``` |
||||||
|
|
||||||
|
### ComfyUI non si avvia |
||||||
|
- Verifica che l'ambiente conda abbia Python 3.9+ |
||||||
|
- Controlla che comfy-cli sia installato correttamente |
||||||
|
- Verifica i log per eventuali errori specifici |
||||||
|
|
||||||
|
## Contribuire |
||||||
|
|
||||||
|
Contributi sono benvenuti! Per favore: |
||||||
|
1. Fai un fork del repository |
||||||
|
2. Crea un branch per la tua feature |
||||||
|
3. Committa le modifiche |
||||||
|
4. Apri una Pull Request |
||||||
|
|
||||||
|
## Licenza |
||||||
|
|
||||||
|
MIT License - vedi il file LICENSE per dettagli. |
||||||
@ -0,0 +1,247 @@ |
|||||||
|
# ComfyUI Launcher |
||||||
|
|
||||||
|
A modern GTK4 launcher for ComfyUI with full conda environment support. |
||||||
|
|
||||||
|
 |
||||||
|
 |
||||||
|
 |
||||||
|
|
||||||
|
## Features |
||||||
|
|
||||||
|
- 🚀 **Conda Environment Management**: Easy selection of available conda environments |
||||||
|
- 🔧 **Automatic Installation**: Install ComfyUI and comfy-cli with one click |
||||||
|
- 📊 **Real-time Monitoring**: Continuously monitors if ComfyUI is running |
||||||
|
- 🎮 **Intuitive Controls**: Start and stop ComfyUI easily |
||||||
|
- 📝 **Real-time Logs**: View ComfyUI output directly in the launcher |
||||||
|
- 🎨 **Modern Interface**: Built with GTK4 and libadwaita |
||||||
|
|
||||||
|
## Prerequisites |
||||||
|
|
||||||
|
- Python 3.9 or higher |
||||||
|
- conda or miniconda installed |
||||||
|
- GTK4 and libadwaita |
||||||
|
- Development libraries (cairo-devel, gobject-introspection-devel, etc.) |
||||||
|
|
||||||
|
## System Dependencies Installation |
||||||
|
|
||||||
|
### Fedora/RHEL/CentOS/Rocky Linux |
||||||
|
|
||||||
|
```bash |
||||||
|
# Install system dependencies |
||||||
|
sudo dnf install cairo-devel gobject-introspection-devel gtk4-devel pkg-config python3-devel |
||||||
|
|
||||||
|
# Install conda if not already installed |
||||||
|
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh |
||||||
|
bash Miniconda3-latest-Linux-x86_64.sh |
||||||
|
``` |
||||||
|
|
||||||
|
### Debian/Ubuntu |
||||||
|
|
||||||
|
```bash |
||||||
|
# Update package list |
||||||
|
sudo apt update |
||||||
|
|
||||||
|
# Install system dependencies |
||||||
|
sudo apt install libcairo2-dev libgirepository1.0-dev libgtk-4-dev pkg-config python3-dev python3-venv |
||||||
|
|
||||||
|
# Install conda if not already installed |
||||||
|
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh |
||||||
|
bash Miniconda3-latest-Linux-x86_64.sh |
||||||
|
``` |
||||||
|
|
||||||
|
## Installation |
||||||
|
|
||||||
|
1. **Clone the repository:** |
||||||
|
```bash |
||||||
|
git clone <repository-url> |
||||||
|
cd gtk-app |
||||||
|
``` |
||||||
|
|
||||||
|
2. **Create and activate virtual environment:** |
||||||
|
```bash |
||||||
|
python3 -m venv .venv |
||||||
|
source .venv/bin/activate |
||||||
|
``` |
||||||
|
|
||||||
|
3. **Install Python dependencies:** |
||||||
|
```bash |
||||||
|
pip install -r requirements.txt |
||||||
|
``` |
||||||
|
|
||||||
|
## Usage |
||||||
|
|
||||||
|
### Quick Start |
||||||
|
|
||||||
|
1. **Launch the application:** |
||||||
|
```bash |
||||||
|
python main.py |
||||||
|
``` |
||||||
|
or use the provided script: |
||||||
|
```bash |
||||||
|
./run.sh |
||||||
|
``` |
||||||
|
|
||||||
|
2. **Select a conda environment** from the dropdown list |
||||||
|
|
||||||
|
3. **Install ComfyUI** (if not already installed) by clicking "Install ComfyUI" |
||||||
|
|
||||||
|
4. **Start ComfyUI** by clicking "Start ComfyUI" |
||||||
|
|
||||||
|
5. The launcher will **automatically monitor** ComfyUI status |
||||||
|
|
||||||
|
### Detailed Workflow |
||||||
|
|
||||||
|
1. **Environment Selection** |
||||||
|
- The launcher automatically detects all available conda environments |
||||||
|
- Select your preferred environment from the dropdown |
||||||
|
- Click "Refresh Environment List" to reload environments |
||||||
|
|
||||||
|
2. **ComfyUI Installation** |
||||||
|
- If ComfyUI is not installed in the selected environment, click "Install ComfyUI" |
||||||
|
- This will install both `comfy-cli` and ComfyUI automatically |
||||||
|
- Installation progress is shown in the log window |
||||||
|
|
||||||
|
3. **Running ComfyUI** |
||||||
|
- Click "Start ComfyUI" to launch ComfyUI in the selected environment |
||||||
|
- Real-time output appears in the log window |
||||||
|
- The status indicator shows when ComfyUI is running |
||||||
|
|
||||||
|
4. **Monitoring** |
||||||
|
- The launcher checks every 3 seconds if ComfyUI is running |
||||||
|
- Status is indicated by both text and visual indicators |
||||||
|
- Automatic detection works even if ComfyUI was started outside the launcher |
||||||
|
|
||||||
|
## Features Detail |
||||||
|
|
||||||
|
### Environment Management |
||||||
|
- Automatic detection of all conda environments |
||||||
|
- Support for conda base environment |
||||||
|
- Refresh button to reload environment list |
||||||
|
- Clear indication of selected environment |
||||||
|
|
||||||
|
### Status Monitoring |
||||||
|
- Checks every 3 seconds if ComfyUI is running |
||||||
|
- Visual status indicator (icon and color) |
||||||
|
- Detection via port 8188 and active processes |
||||||
|
- Works even with externally started ComfyUI instances |
||||||
|
|
||||||
|
### Controls |
||||||
|
- **Start ComfyUI**: Launch ComfyUI in selected environment |
||||||
|
- **Stop ComfyUI**: Gracefully terminate ComfyUI process |
||||||
|
- **Install ComfyUI**: Install comfy-cli and ComfyUI in environment |
||||||
|
- **Refresh Environments**: Reload conda environment list |
||||||
|
|
||||||
|
### Logging |
||||||
|
- Real-time output from ComfyUI |
||||||
|
- Timestamp for each message |
||||||
|
- Monospace font for better readability |
||||||
|
- Automatic scrolling to latest messages |
||||||
|
|
||||||
|
## File Structure |
||||||
|
|
||||||
|
``` |
||||||
|
gtk-app/ |
||||||
|
├── main.py # Main application |
||||||
|
├── requirements.txt # Python dependencies |
||||||
|
├── style.css # Custom styles (optional) |
||||||
|
├── comfyui-launcher.desktop # Desktop integration file |
||||||
|
├── run.sh # Launch script |
||||||
|
├── README.md # This file |
||||||
|
├── .gitignore # Git ignore rules |
||||||
|
└── .venv/ # Virtual environment (created after setup) |
||||||
|
``` |
||||||
|
|
||||||
|
## Troubleshooting |
||||||
|
|
||||||
|
### Conda not found |
||||||
|
Make sure conda is in your PATH: |
||||||
|
```bash |
||||||
|
export PATH="$HOME/miniconda3/bin:$PATH" |
||||||
|
# Add to ~/.bashrc or ~/.zshrc for persistence |
||||||
|
echo 'export PATH="$HOME/miniconda3/bin:$PATH"' >> ~/.bashrc |
||||||
|
``` |
||||||
|
|
||||||
|
### Permission errors |
||||||
|
Make the script executable: |
||||||
|
```bash |
||||||
|
chmod +x main.py |
||||||
|
chmod +x run.sh |
||||||
|
``` |
||||||
|
|
||||||
|
### ComfyUI won't start |
||||||
|
- Verify the conda environment has Python 3.9+ |
||||||
|
- Check that comfy-cli is properly installed |
||||||
|
- Review logs for specific error messages |
||||||
|
- Ensure sufficient disk space and memory |
||||||
|
|
||||||
|
### GTK/PyGObject errors |
||||||
|
Make sure all system dependencies are installed: |
||||||
|
```bash |
||||||
|
# Fedora/RHEL |
||||||
|
sudo dnf install gtk4-devel python3-gobject |
||||||
|
|
||||||
|
# Debian/Ubuntu |
||||||
|
sudo apt install libgtk-4-dev python3-gi |
||||||
|
``` |
||||||
|
|
||||||
|
### Missing fonts |
||||||
|
The launcher uses monospace fonts for logs. If fonts appear wrong: |
||||||
|
```bash |
||||||
|
# Install additional fonts (optional) |
||||||
|
sudo dnf install jetbrains-mono-fonts # Fedora |
||||||
|
sudo apt install fonts-jetbrains-mono # Ubuntu |
||||||
|
``` |
||||||
|
|
||||||
|
## Development |
||||||
|
|
||||||
|
### Setting up development environment |
||||||
|
|
||||||
|
1. Fork the repository |
||||||
|
2. Clone your fork |
||||||
|
3. Install development dependencies: |
||||||
|
```bash |
||||||
|
pip install -r requirements.txt |
||||||
|
``` |
||||||
|
4. Make your changes |
||||||
|
5. Test thoroughly |
||||||
|
6. Submit a pull request |
||||||
|
|
||||||
|
### Code Style |
||||||
|
- Follow PEP 8 for Python code |
||||||
|
- Use meaningful variable names |
||||||
|
- Add comments for complex logic |
||||||
|
- Keep functions focused and small |
||||||
|
|
||||||
|
## Contributing |
||||||
|
|
||||||
|
Contributions are welcome! Please: |
||||||
|
|
||||||
|
1. Fork the repository |
||||||
|
2. Create a feature branch |
||||||
|
3. Make your changes |
||||||
|
4. Add tests if applicable |
||||||
|
5. Update documentation |
||||||
|
6. Submit a pull request |
||||||
|
|
||||||
|
## License |
||||||
|
|
||||||
|
MIT License - see the LICENSE file for details. |
||||||
|
|
||||||
|
## Acknowledgments |
||||||
|
|
||||||
|
- [ComfyUI](https://github.com/comfyanonymous/ComfyUI) - The amazing stable diffusion GUI |
||||||
|
- [comfy-cli](https://github.com/Comfy-Org/comfy-cli) - Command line tool for ComfyUI |
||||||
|
- [GTK](https://gtk.org/) - The GUI toolkit |
||||||
|
- [PyGObject](https://pygobject.readthedocs.io/) - Python bindings for GTK |
||||||
|
|
||||||
|
## Support |
||||||
|
|
||||||
|
If you encounter issues: |
||||||
|
|
||||||
|
1. Check the troubleshooting section above |
||||||
|
2. Search existing GitHub issues |
||||||
|
3. Create a new issue with: |
||||||
|
- Your operating system and version |
||||||
|
- Python version |
||||||
|
- Complete error messages |
||||||
|
- Steps to reproduce the problem |
||||||
@ -0,0 +1,57 @@ |
|||||||
|
{ |
||||||
|
"_comment": "ComfyUI Launcher Configuration Template", |
||||||
|
"_instructions": "Copy this file to ~/.config/comfyui-launcher/config.json to customize settings", |
||||||
|
|
||||||
|
"launcher": { |
||||||
|
"window": { |
||||||
|
"width": 900, |
||||||
|
"height": 700, |
||||||
|
"remember_size": true, |
||||||
|
"remember_position": true |
||||||
|
}, |
||||||
|
"monitoring": { |
||||||
|
"check_interval_seconds": 3, |
||||||
|
"port_to_check": 8188, |
||||||
|
"process_patterns": [ |
||||||
|
"comfy.*launch", |
||||||
|
"python.*main.py.*comfyui" |
||||||
|
] |
||||||
|
}, |
||||||
|
"logging": { |
||||||
|
"max_log_lines": 1000, |
||||||
|
"auto_scroll": true, |
||||||
|
"timestamp_format": "%H:%M:%S", |
||||||
|
"font_family": "JetBrains Mono, Fira Code, Source Code Pro, monospace", |
||||||
|
"font_size": "10pt" |
||||||
|
}, |
||||||
|
"conda": { |
||||||
|
"auto_refresh_on_startup": true, |
||||||
|
"preferred_environments": [], |
||||||
|
"exclude_environments": [] |
||||||
|
}, |
||||||
|
"comfyui": { |
||||||
|
"default_args": [], |
||||||
|
"auto_start_browser": false, |
||||||
|
"startup_timeout_seconds": 60, |
||||||
|
"shutdown_timeout_seconds": 10 |
||||||
|
} |
||||||
|
}, |
||||||
|
"paths": { |
||||||
|
"conda_executable": "conda", |
||||||
|
"comfy_executable": "comfy", |
||||||
|
"default_comfyui_directory": "~/comfy/ComfyUI" |
||||||
|
}, |
||||||
|
"ui": { |
||||||
|
"theme": "auto", |
||||||
|
"use_dark_theme": null, |
||||||
|
"accent_color": "#3584e4", |
||||||
|
"show_tooltips": true, |
||||||
|
"animations_enabled": true |
||||||
|
}, |
||||||
|
"advanced": { |
||||||
|
"debug_mode": false, |
||||||
|
"verbose_logging": false, |
||||||
|
"check_for_updates": true, |
||||||
|
"telemetry_enabled": false |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,207 @@ |
|||||||
|
#!/bin/bash |
||||||
|
|
||||||
|
# ComfyUI Launcher Installation Script |
||||||
|
# This script automates the installation process for different Linux distributions |
||||||
|
|
||||||
|
set -e # Exit on any error |
||||||
|
|
||||||
|
# Colors for output |
||||||
|
RED='\033[0;31m' |
||||||
|
GREEN='\033[0;32m' |
||||||
|
YELLOW='\033[1;33m' |
||||||
|
BLUE='\033[0;34m' |
||||||
|
NC='\033[0m' # No Color |
||||||
|
|
||||||
|
# Function to print colored output |
||||||
|
print_status() { |
||||||
|
echo -e "${BLUE}[INFO]${NC} $1" |
||||||
|
} |
||||||
|
|
||||||
|
print_success() { |
||||||
|
echo -e "${GREEN}[SUCCESS]${NC} $1" |
||||||
|
} |
||||||
|
|
||||||
|
print_warning() { |
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1" |
||||||
|
} |
||||||
|
|
||||||
|
print_error() { |
||||||
|
echo -e "${RED}[ERROR]${NC} $1" |
||||||
|
} |
||||||
|
|
||||||
|
# Detect Linux distribution |
||||||
|
detect_distro() { |
||||||
|
if [ -f /etc/os-release ]; then |
||||||
|
. /etc/os-release |
||||||
|
DISTRO=$ID |
||||||
|
VERSION=$VERSION_ID |
||||||
|
else |
||||||
|
print_error "Cannot detect Linux distribution" |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
# Install system dependencies based on distribution |
||||||
|
install_system_deps() { |
||||||
|
print_status "Installing system dependencies for $DISTRO..." |
||||||
|
|
||||||
|
case $DISTRO in |
||||||
|
"fedora"|"rhel"|"centos"|"rocky") |
||||||
|
sudo dnf install -y cairo-devel gobject-introspection-devel gtk4-devel pkg-config python3-devel python3-pip |
||||||
|
;; |
||||||
|
"ubuntu"|"debian") |
||||||
|
sudo apt update |
||||||
|
sudo apt install -y libcairo2-dev libgirepository1.0-dev libgtk-4-dev pkg-config python3-dev python3-pip python3-venv |
||||||
|
;; |
||||||
|
"arch"|"manjaro") |
||||||
|
sudo pacman -S --needed cairo gobject-introspection gtk4 pkgconf python python-pip |
||||||
|
;; |
||||||
|
*) |
||||||
|
print_warning "Unsupported distribution: $DISTRO" |
||||||
|
print_warning "Please install the following packages manually:" |
||||||
|
print_warning "- Cairo development libraries" |
||||||
|
print_warning "- GObject Introspection development libraries" |
||||||
|
print_warning "- GTK4 development libraries" |
||||||
|
print_warning "- pkg-config" |
||||||
|
print_warning "- Python 3.9+ development headers" |
||||||
|
;; |
||||||
|
esac |
||||||
|
} |
||||||
|
|
||||||
|
# Check if conda is installed |
||||||
|
check_conda() { |
||||||
|
if command -v conda &> /dev/null; then |
||||||
|
print_success "Conda found: $(conda --version)" |
||||||
|
return 0 |
||||||
|
else |
||||||
|
print_warning "Conda not found" |
||||||
|
return 1 |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
# Install conda if not present |
||||||
|
install_conda() { |
||||||
|
print_status "Installing Miniconda..." |
||||||
|
|
||||||
|
# Detect architecture |
||||||
|
ARCH=$(uname -m) |
||||||
|
if [ "$ARCH" = "x86_64" ]; then |
||||||
|
CONDA_URL="https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh" |
||||||
|
elif [ "$ARCH" = "aarch64" ]; then |
||||||
|
CONDA_URL="https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh" |
||||||
|
else |
||||||
|
print_error "Unsupported architecture: $ARCH" |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
|
||||||
|
# Download and install conda |
||||||
|
wget "$CONDA_URL" -O miniconda.sh |
||||||
|
bash miniconda.sh -b -p "$HOME/miniconda3" |
||||||
|
rm miniconda.sh |
||||||
|
|
||||||
|
# Add conda to PATH |
||||||
|
echo 'export PATH="$HOME/miniconda3/bin:$PATH"' >> ~/.bashrc |
||||||
|
export PATH="$HOME/miniconda3/bin:$PATH" |
||||||
|
|
||||||
|
# Initialize conda |
||||||
|
conda init bash |
||||||
|
|
||||||
|
print_success "Miniconda installed successfully" |
||||||
|
print_warning "Please restart your terminal or run: source ~/.bashrc" |
||||||
|
} |
||||||
|
|
||||||
|
# Setup Python virtual environment |
||||||
|
setup_venv() { |
||||||
|
print_status "Setting up Python virtual environment..." |
||||||
|
|
||||||
|
if [ ! -d ".venv" ]; then |
||||||
|
python3 -m venv .venv |
||||||
|
print_success "Virtual environment created" |
||||||
|
else |
||||||
|
print_status "Virtual environment already exists" |
||||||
|
fi |
||||||
|
|
||||||
|
# Activate virtual environment |
||||||
|
source .venv/bin/activate |
||||||
|
|
||||||
|
# Upgrade pip |
||||||
|
pip install --upgrade pip |
||||||
|
|
||||||
|
# Install requirements |
||||||
|
if [ -f "requirements.txt" ]; then |
||||||
|
print_status "Installing Python dependencies..." |
||||||
|
pip install -r requirements.txt |
||||||
|
print_success "Python dependencies installed" |
||||||
|
else |
||||||
|
print_warning "requirements.txt not found, installing basic dependencies..." |
||||||
|
pip install PyGObject |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
# Make scripts executable |
||||||
|
make_executable() { |
||||||
|
print_status "Making scripts executable..." |
||||||
|
chmod +x main.py 2>/dev/null || true |
||||||
|
chmod +x run.sh 2>/dev/null || true |
||||||
|
print_success "Scripts are now executable" |
||||||
|
} |
||||||
|
|
||||||
|
# Create desktop entry (optional) |
||||||
|
create_desktop_entry() { |
||||||
|
if [ -f "comfyui-launcher.desktop" ]; then |
||||||
|
read -p "Install desktop entry? (y/N): " -n 1 -r |
||||||
|
echo |
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then |
||||||
|
DESKTOP_FILE="$HOME/.local/share/applications/comfyui-launcher.desktop" |
||||||
|
mkdir -p "$(dirname "$DESKTOP_FILE")" |
||||||
|
|
||||||
|
# Update paths in desktop file |
||||||
|
CURRENT_DIR=$(pwd) |
||||||
|
sed "s|/home/enne2/Development/gtk-app|$CURRENT_DIR|g" comfyui-launcher.desktop > "$DESKTOP_FILE" |
||||||
|
|
||||||
|
print_success "Desktop entry installed to $DESKTOP_FILE" |
||||||
|
fi |
||||||
|
fi |
||||||
|
} |
||||||
|
|
||||||
|
# Main installation function |
||||||
|
main() { |
||||||
|
print_status "ComfyUI Launcher Installation Script" |
||||||
|
print_status "======================================" |
||||||
|
|
||||||
|
# Detect distribution |
||||||
|
detect_distro |
||||||
|
print_status "Detected distribution: $DISTRO $VERSION" |
||||||
|
|
||||||
|
# Install system dependencies |
||||||
|
install_system_deps |
||||||
|
|
||||||
|
# Check for conda |
||||||
|
if ! check_conda; then |
||||||
|
read -p "Install Miniconda? (y/N): " -n 1 -r |
||||||
|
echo |
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then |
||||||
|
install_conda |
||||||
|
else |
||||||
|
print_warning "Conda not installed. You'll need to install it manually for full functionality." |
||||||
|
fi |
||||||
|
fi |
||||||
|
|
||||||
|
# Setup Python environment |
||||||
|
setup_venv |
||||||
|
|
||||||
|
# Make scripts executable |
||||||
|
make_executable |
||||||
|
|
||||||
|
# Optional desktop entry |
||||||
|
create_desktop_entry |
||||||
|
|
||||||
|
print_success "Installation completed!" |
||||||
|
print_status "To run the launcher:" |
||||||
|
print_status " ./run.sh" |
||||||
|
print_status "or:" |
||||||
|
print_status " source .venv/bin/activate && python main.py" |
||||||
|
} |
||||||
|
|
||||||
|
# Run main function |
||||||
|
main "$@" |
||||||
@ -0,0 +1,501 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
|
||||||
|
import gi |
||||||
|
gi.require_version('Gtk', '4.0') |
||||||
|
gi.require_version('Adw', '1') |
||||||
|
|
||||||
|
from gi.repository import Gtk, Adw, Gio, GLib |
||||||
|
import sys |
||||||
|
import subprocess |
||||||
|
import json |
||||||
|
import os |
||||||
|
import threading |
||||||
|
import time |
||||||
|
import re |
||||||
|
|
||||||
|
class ComfyUILauncher(Gtk.ApplicationWindow): |
||||||
|
def __init__(self, **kwargs): |
||||||
|
super().__init__(**kwargs) |
||||||
|
|
||||||
|
# Configurazione finestra principale |
||||||
|
self.set_title("ComfyUI Launcher") |
||||||
|
self.set_default_size(900, 700) |
||||||
|
|
||||||
|
# Variabili di stato |
||||||
|
self.comfyui_process = None |
||||||
|
self.is_running = False |
||||||
|
self.selected_conda_env = None |
||||||
|
self.conda_envs = [] |
||||||
|
self.status_check_timeout = None |
||||||
|
|
||||||
|
# Crea il layout principale |
||||||
|
self.setup_ui() |
||||||
|
|
||||||
|
# Inizializza il controllo degli ambienti conda |
||||||
|
self.load_conda_environments() |
||||||
|
|
||||||
|
# Avvia il monitoraggio dello stato |
||||||
|
self.start_status_monitoring() |
||||||
|
|
||||||
|
def setup_ui(self): |
||||||
|
# Header bar |
||||||
|
header = Gtk.HeaderBar() |
||||||
|
header.set_title_widget(Gtk.Label(label="ComfyUI Launcher")) |
||||||
|
self.set_titlebar(header) |
||||||
|
|
||||||
|
# Menu button |
||||||
|
menu_button = Gtk.MenuButton() |
||||||
|
menu_button.set_icon_name("open-menu-symbolic") |
||||||
|
header.pack_end(menu_button) |
||||||
|
|
||||||
|
# Main content area |
||||||
|
main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=12) |
||||||
|
main_box.set_margin_top(12) |
||||||
|
main_box.set_margin_bottom(12) |
||||||
|
main_box.set_margin_start(12) |
||||||
|
main_box.set_margin_end(12) |
||||||
|
|
||||||
|
# Title |
||||||
|
title_label = Gtk.Label() |
||||||
|
title_label.set_markup("<span size='x-large'><b>ComfyUI Launcher</b></span>") |
||||||
|
title_label.set_margin_bottom(12) |
||||||
|
main_box.append(title_label) |
||||||
|
|
||||||
|
# Status section |
||||||
|
status_frame = Gtk.Frame() |
||||||
|
status_frame.set_label("Stato ComfyUI") |
||||||
|
status_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12) |
||||||
|
status_box.set_margin_top(12) |
||||||
|
status_box.set_margin_bottom(12) |
||||||
|
status_box.set_margin_start(12) |
||||||
|
status_box.set_margin_end(12) |
||||||
|
|
||||||
|
self.status_indicator = Gtk.Image() |
||||||
|
self.status_indicator.set_from_icon_name("media-playback-stop-symbolic") |
||||||
|
self.status_indicator.set_icon_size(Gtk.IconSize.LARGE) |
||||||
|
status_box.append(self.status_indicator) |
||||||
|
|
||||||
|
self.status_label = Gtk.Label(label="ComfyUI non in esecuzione") |
||||||
|
self.status_label.set_hexpand(True) |
||||||
|
self.status_label.set_halign(Gtk.Align.START) |
||||||
|
status_box.append(self.status_label) |
||||||
|
|
||||||
|
status_frame.set_child(status_box) |
||||||
|
main_box.append(status_frame) |
||||||
|
|
||||||
|
# Environment selection |
||||||
|
env_frame = Gtk.Frame() |
||||||
|
env_frame.set_label("Selezione Ambiente Conda") |
||||||
|
env_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6) |
||||||
|
env_box.set_margin_top(12) |
||||||
|
env_box.set_margin_bottom(12) |
||||||
|
env_box.set_margin_start(12) |
||||||
|
env_box.set_margin_end(12) |
||||||
|
|
||||||
|
# Dropdown per ambienti conda |
||||||
|
self.env_dropdown = Gtk.DropDown() |
||||||
|
self.env_dropdown.set_enable_search(True) |
||||||
|
self.env_dropdown.connect("notify::selected-item", self.on_env_selected) |
||||||
|
env_box.append(self.env_dropdown) |
||||||
|
|
||||||
|
# Refresh button |
||||||
|
refresh_button = Gtk.Button(label="Aggiorna Lista Ambienti") |
||||||
|
refresh_button.connect("clicked", self.on_refresh_envs) |
||||||
|
env_box.append(refresh_button) |
||||||
|
|
||||||
|
env_frame.set_child(env_box) |
||||||
|
main_box.append(env_frame) |
||||||
|
|
||||||
|
# Control buttons |
||||||
|
control_frame = Gtk.Frame() |
||||||
|
control_frame.set_label("Controlli") |
||||||
|
control_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=12) |
||||||
|
control_box.set_margin_top(12) |
||||||
|
control_box.set_margin_bottom(12) |
||||||
|
control_box.set_margin_start(12) |
||||||
|
control_box.set_margin_end(12) |
||||||
|
control_box.set_homogeneous(True) |
||||||
|
|
||||||
|
self.start_button = Gtk.Button(label="Avvia ComfyUI") |
||||||
|
self.start_button.add_css_class("suggested-action") |
||||||
|
self.start_button.connect("clicked", self.on_start_comfyui) |
||||||
|
self.start_button.set_sensitive(False) |
||||||
|
control_box.append(self.start_button) |
||||||
|
|
||||||
|
self.stop_button = Gtk.Button(label="Ferma ComfyUI") |
||||||
|
self.stop_button.add_css_class("destructive-action") |
||||||
|
self.stop_button.connect("clicked", self.on_stop_comfyui) |
||||||
|
self.stop_button.set_sensitive(False) |
||||||
|
control_box.append(self.stop_button) |
||||||
|
|
||||||
|
self.install_button = Gtk.Button(label="Installa ComfyUI") |
||||||
|
self.install_button.connect("clicked", self.on_install_comfyui) |
||||||
|
control_box.append(self.install_button) |
||||||
|
|
||||||
|
control_frame.set_child(control_box) |
||||||
|
main_box.append(control_frame) |
||||||
|
|
||||||
|
# Log section |
||||||
|
log_frame = Gtk.Frame() |
||||||
|
log_frame.set_label("Log") |
||||||
|
log_frame.set_vexpand(True) |
||||||
|
|
||||||
|
scrolled = Gtk.ScrolledWindow() |
||||||
|
scrolled.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) |
||||||
|
scrolled.set_vexpand(True) |
||||||
|
|
||||||
|
self.log_view = Gtk.TextView() |
||||||
|
self.log_view.set_editable(False) |
||||||
|
self.log_view.set_monospace(True) |
||||||
|
self.log_buffer = self.log_view.get_buffer() |
||||||
|
scrolled.set_child(self.log_view) |
||||||
|
|
||||||
|
log_frame.set_child(scrolled) |
||||||
|
main_box.append(log_frame) |
||||||
|
|
||||||
|
self.set_child(main_box) |
||||||
|
|
||||||
|
# Setup menu |
||||||
|
self.setup_menu(menu_button) |
||||||
|
|
||||||
|
def setup_menu(self, menu_button): |
||||||
|
menu = Gio.Menu() |
||||||
|
menu.append("Apri Cartella ComfyUI", "app.open_folder") |
||||||
|
menu.append("About", "app.about") |
||||||
|
menu.append("Quit", "app.quit") |
||||||
|
menu_button.set_menu_model(menu) |
||||||
|
|
||||||
|
def log_message(self, message): |
||||||
|
"""Aggiunge un messaggio al log""" |
||||||
|
def update_log(): |
||||||
|
current_text = self.log_buffer.get_text( |
||||||
|
self.log_buffer.get_start_iter(), |
||||||
|
self.log_buffer.get_end_iter(), |
||||||
|
False |
||||||
|
) |
||||||
|
timestamp = time.strftime("%H:%M:%S") |
||||||
|
new_text = f"{current_text}[{timestamp}] {message}\n" if current_text else f"[{timestamp}] {message}\n" |
||||||
|
self.log_buffer.set_text(new_text) |
||||||
|
|
||||||
|
# Scorri alla fine |
||||||
|
mark = self.log_buffer.get_insert() |
||||||
|
self.log_view.scroll_mark_onscreen(mark) |
||||||
|
|
||||||
|
GLib.idle_add(update_log) |
||||||
|
|
||||||
|
def load_conda_environments(self): |
||||||
|
"""Carica la lista degli ambienti conda disponibili""" |
||||||
|
def load_envs(): |
||||||
|
try: |
||||||
|
# Prova a ottenere la lista degli ambienti conda |
||||||
|
result = subprocess.run(['conda', 'env', 'list', '--json'], |
||||||
|
capture_output=True, text=True, timeout=30) |
||||||
|
if result.returncode == 0: |
||||||
|
env_data = json.loads(result.stdout) |
||||||
|
envs = [] |
||||||
|
for env_path in env_data['envs']: |
||||||
|
env_name = os.path.basename(env_path) |
||||||
|
if env_name == env_path: # È il path base, usa 'base' |
||||||
|
env_name = 'base' |
||||||
|
envs.append((env_name, env_path)) |
||||||
|
|
||||||
|
def update_ui(): |
||||||
|
self.conda_envs = envs |
||||||
|
string_list = Gtk.StringList() |
||||||
|
for name, path in envs: |
||||||
|
string_list.append(f"{name} ({path})") |
||||||
|
self.env_dropdown.set_model(string_list) |
||||||
|
if envs: |
||||||
|
self.env_dropdown.set_selected(0) |
||||||
|
self.log_message(f"Trovati {len(envs)} ambienti conda") |
||||||
|
|
||||||
|
GLib.idle_add(update_ui) |
||||||
|
else: |
||||||
|
GLib.idle_add(lambda: self.log_message(f"Errore nel caricare ambienti conda: {result.stderr}")) |
||||||
|
except subprocess.TimeoutExpired: |
||||||
|
GLib.idle_add(lambda: self.log_message("Timeout nel caricamento ambienti conda")) |
||||||
|
except FileNotFoundError: |
||||||
|
GLib.idle_add(lambda: self.log_message("Conda non trovato. Assicurati che conda sia installato e nel PATH")) |
||||||
|
except Exception as e: |
||||||
|
GLib.idle_add(lambda: self.log_message(f"Errore imprevisto: {str(e)}")) |
||||||
|
|
||||||
|
# Esegui in un thread separato per non bloccare l'UI |
||||||
|
threading.Thread(target=load_envs, daemon=True).start() |
||||||
|
|
||||||
|
def on_env_selected(self, dropdown, param): |
||||||
|
"""Gestisce la selezione di un ambiente conda""" |
||||||
|
selected_idx = dropdown.get_selected() |
||||||
|
if selected_idx != Gtk.INVALID_LIST_POSITION and self.conda_envs: |
||||||
|
env_name, env_path = self.conda_envs[selected_idx] |
||||||
|
self.selected_conda_env = (env_name, env_path) |
||||||
|
self.log_message(f"Selezionato ambiente: {env_name}") |
||||||
|
self.update_button_states() |
||||||
|
|
||||||
|
def on_refresh_envs(self, button): |
||||||
|
"""Aggiorna la lista degli ambienti conda""" |
||||||
|
self.log_message("Aggiornamento lista ambienti...") |
||||||
|
self.load_conda_environments() |
||||||
|
|
||||||
|
def update_button_states(self): |
||||||
|
"""Aggiorna lo stato dei pulsanti in base allo stato corrente""" |
||||||
|
has_env = self.selected_conda_env is not None |
||||||
|
self.start_button.set_sensitive(has_env and not self.is_running) |
||||||
|
self.stop_button.set_sensitive(self.is_running) |
||||||
|
self.install_button.set_sensitive(has_env) |
||||||
|
|
||||||
|
def check_comfyui_running(self): |
||||||
|
"""Controlla se ComfyUI è in esecuzione""" |
||||||
|
try: |
||||||
|
# Controlla se il processo ComfyUI è ancora vivo |
||||||
|
if self.comfyui_process and self.comfyui_process.poll() is None: |
||||||
|
return True |
||||||
|
|
||||||
|
# Controlla se c'è un processo ComfyUI in esecuzione (porta 8188) |
||||||
|
try: |
||||||
|
result = subprocess.run(['ss', '-tulpn'], capture_output=True, text=True, timeout=5) |
||||||
|
if ':8188' in result.stdout: |
||||||
|
return True |
||||||
|
except: |
||||||
|
# Fallback con netstat se ss non è disponibile |
||||||
|
try: |
||||||
|
result = subprocess.run(['netstat', '-tulpn'], capture_output=True, text=True, timeout=5) |
||||||
|
if ':8188' in result.stdout: |
||||||
|
return True |
||||||
|
except: |
||||||
|
pass |
||||||
|
|
||||||
|
# Controlla processi con nome 'comfy' o 'python' che potrebbero essere ComfyUI |
||||||
|
try: |
||||||
|
result = subprocess.run(['pgrep', '-f', 'comfy.*launch'], capture_output=True, text=True, timeout=5) |
||||||
|
if result.returncode == 0 and result.stdout.strip(): |
||||||
|
return True |
||||||
|
except: |
||||||
|
pass |
||||||
|
|
||||||
|
return False |
||||||
|
except Exception as e: |
||||||
|
self.log_message(f"Errore nel controllo stato: {str(e)}") |
||||||
|
return False |
||||||
|
|
||||||
|
def update_status_ui(self): |
||||||
|
"""Aggiorna l'interfaccia utente con lo stato corrente""" |
||||||
|
if self.is_running: |
||||||
|
self.status_indicator.set_from_icon_name("media-playback-start-symbolic") |
||||||
|
self.status_indicator.add_css_class("success") |
||||||
|
self.status_label.set_text("ComfyUI in esecuzione") |
||||||
|
else: |
||||||
|
self.status_indicator.set_from_icon_name("media-playback-stop-symbolic") |
||||||
|
self.status_indicator.remove_css_class("success") |
||||||
|
self.status_label.set_text("ComfyUI non in esecuzione") |
||||||
|
|
||||||
|
self.update_button_states() |
||||||
|
|
||||||
|
def start_status_monitoring(self): |
||||||
|
"""Avvia il monitoraggio periodico dello stato""" |
||||||
|
def monitor(): |
||||||
|
was_running = self.is_running |
||||||
|
self.is_running = self.check_comfyui_running() |
||||||
|
|
||||||
|
if was_running != self.is_running: |
||||||
|
if self.is_running: |
||||||
|
self.log_message("ComfyUI rilevato in esecuzione") |
||||||
|
else: |
||||||
|
self.log_message("ComfyUI non più in esecuzione") |
||||||
|
GLib.idle_add(self.update_status_ui) |
||||||
|
|
||||||
|
return True # Continua il monitoring |
||||||
|
|
||||||
|
# Controlla ogni 3 secondi |
||||||
|
self.status_check_timeout = GLib.timeout_add(3000, monitor) |
||||||
|
|
||||||
|
def on_start_comfyui(self, button): |
||||||
|
"""Avvia ComfyUI""" |
||||||
|
if not self.selected_conda_env: |
||||||
|
self.log_message("Nessun ambiente conda selezionato") |
||||||
|
return |
||||||
|
|
||||||
|
env_name, env_path = self.selected_conda_env |
||||||
|
self.log_message(f"Avvio ComfyUI nell'ambiente {env_name}...") |
||||||
|
|
||||||
|
def start_comfy(): |
||||||
|
try: |
||||||
|
# Comando per attivare l'ambiente conda e avviare comfyui |
||||||
|
if env_name == 'base': |
||||||
|
cmd = ['conda', 'run', '-n', 'base', 'comfy', 'launch'] |
||||||
|
else: |
||||||
|
cmd = ['conda', 'run', '-n', env_name, 'comfy', 'launch'] |
||||||
|
|
||||||
|
self.comfyui_process = subprocess.Popen( |
||||||
|
cmd, |
||||||
|
stdout=subprocess.PIPE, |
||||||
|
stderr=subprocess.STDOUT, |
||||||
|
text=True, |
||||||
|
bufsize=1, |
||||||
|
universal_newlines=True |
||||||
|
) |
||||||
|
|
||||||
|
GLib.idle_add(lambda: self.log_message("Processo ComfyUI avviato")) |
||||||
|
|
||||||
|
# Leggi l'output in tempo reale |
||||||
|
for line in iter(self.comfyui_process.stdout.readline, ''): |
||||||
|
if line: |
||||||
|
GLib.idle_add(lambda l=line.strip(): self.log_message(f"ComfyUI: {l}")) |
||||||
|
|
||||||
|
except Exception as e: |
||||||
|
GLib.idle_add(lambda: self.log_message(f"Errore nell'avvio: {str(e)}")) |
||||||
|
|
||||||
|
threading.Thread(target=start_comfy, daemon=True).start() |
||||||
|
|
||||||
|
def on_stop_comfyui(self, button): |
||||||
|
"""Ferma ComfyUI""" |
||||||
|
self.log_message("Fermando ComfyUI...") |
||||||
|
|
||||||
|
if self.comfyui_process: |
||||||
|
try: |
||||||
|
self.comfyui_process.terminate() |
||||||
|
# Aspetta un po' per la terminazione graceful |
||||||
|
try: |
||||||
|
self.comfyui_process.wait(timeout=5) |
||||||
|
except subprocess.TimeoutExpired: |
||||||
|
# Forza la terminazione |
||||||
|
self.comfyui_process.kill() |
||||||
|
self.comfyui_process = None |
||||||
|
self.log_message("Processo ComfyUI terminato") |
||||||
|
except Exception as e: |
||||||
|
self.log_message(f"Errore nella terminazione: {str(e)}") |
||||||
|
else: |
||||||
|
# Prova a killare qualsiasi processo sulla porta 8188 |
||||||
|
try: |
||||||
|
subprocess.run(['pkill', '-f', 'comfy'], timeout=5) |
||||||
|
self.log_message("Terminati processi ComfyUI") |
||||||
|
except: |
||||||
|
self.log_message("Nessun processo ComfyUI trovato da terminare") |
||||||
|
|
||||||
|
def on_install_comfyui(self, button): |
||||||
|
"""Installa ComfyUI nell'ambiente selezionato""" |
||||||
|
if not self.selected_conda_env: |
||||||
|
self.log_message("Nessun ambiente conda selezionato") |
||||||
|
return |
||||||
|
|
||||||
|
env_name, env_path = self.selected_conda_env |
||||||
|
self.log_message(f"Installazione ComfyUI nell'ambiente {env_name}...") |
||||||
|
|
||||||
|
def install_comfy(): |
||||||
|
try: |
||||||
|
# Prima installa comfy-cli |
||||||
|
cmd1 = ['conda', 'run', '-n', env_name, 'pip', 'install', 'comfy-cli'] |
||||||
|
result1 = subprocess.run(cmd1, capture_output=True, text=True, timeout=300) |
||||||
|
|
||||||
|
if result1.returncode == 0: |
||||||
|
GLib.idle_add(lambda: self.log_message("comfy-cli installato con successo")) |
||||||
|
|
||||||
|
# Poi installa ComfyUI |
||||||
|
cmd2 = ['conda', 'run', '-n', env_name, 'comfy', 'install'] |
||||||
|
result2 = subprocess.run(cmd2, capture_output=True, text=True, timeout=600) |
||||||
|
|
||||||
|
if result2.returncode == 0: |
||||||
|
GLib.idle_add(lambda: self.log_message("ComfyUI installato con successo!")) |
||||||
|
else: |
||||||
|
GLib.idle_add(lambda: self.log_message(f"Errore installazione ComfyUI: {result2.stderr}")) |
||||||
|
else: |
||||||
|
GLib.idle_add(lambda: self.log_message(f"Errore installazione comfy-cli: {result1.stderr}")) |
||||||
|
|
||||||
|
except subprocess.TimeoutExpired: |
||||||
|
GLib.idle_add(lambda: self.log_message("Timeout durante l'installazione")) |
||||||
|
except Exception as e: |
||||||
|
GLib.idle_add(lambda: self.log_message(f"Errore durante l'installazione: {str(e)}")) |
||||||
|
|
||||||
|
threading.Thread(target=install_comfy, daemon=True).start() |
||||||
|
|
||||||
|
class ComfyUIApp(Adw.Application): |
||||||
|
def __init__(self, **kwargs): |
||||||
|
super().__init__(**kwargs) |
||||||
|
self.connect('activate', self.on_activate) |
||||||
|
|
||||||
|
# Configura il style manager per gestire correttamente i temi |
||||||
|
self.setup_style_manager() |
||||||
|
|
||||||
|
# Aggiungi azioni per il menu |
||||||
|
self.setup_actions() |
||||||
|
|
||||||
|
def setup_style_manager(self): |
||||||
|
"""Configura il gestore dello stile per evitare warning""" |
||||||
|
style_manager = Adw.StyleManager.get_default() |
||||||
|
style_manager.set_color_scheme(Adw.ColorScheme.DEFAULT) |
||||||
|
|
||||||
|
def setup_actions(self): |
||||||
|
# Azione About |
||||||
|
about_action = Gio.SimpleAction.new("about", None) |
||||||
|
about_action.connect("activate", self.on_about_action) |
||||||
|
self.add_action(about_action) |
||||||
|
|
||||||
|
# Azione Quit |
||||||
|
quit_action = Gio.SimpleAction.new("quit", None) |
||||||
|
quit_action.connect("activate", self.on_quit_action) |
||||||
|
self.add_action(quit_action) |
||||||
|
|
||||||
|
# Azione Open Folder |
||||||
|
open_folder_action = Gio.SimpleAction.new("open_folder", None) |
||||||
|
open_folder_action.connect("activate", self.on_open_folder_action) |
||||||
|
self.add_action(open_folder_action) |
||||||
|
|
||||||
|
# Shortcut per quit |
||||||
|
self.set_accels_for_action("app.quit", ["<primary>q"]) |
||||||
|
|
||||||
|
def on_activate(self, app): |
||||||
|
print("Avvio ComfyUI Launcher...") |
||||||
|
# Crea la finestra principale |
||||||
|
self.win = ComfyUILauncher(application=app) |
||||||
|
print("Finestra launcher creata") |
||||||
|
self.win.present() |
||||||
|
print("Launcher presentato") |
||||||
|
|
||||||
|
def on_about_action(self, action, param): |
||||||
|
# Mostra dialog About |
||||||
|
about = Adw.AboutWindow( |
||||||
|
transient_for=self.win, |
||||||
|
application_name="ComfyUI Launcher", |
||||||
|
application_icon="application-x-executable", |
||||||
|
developer_name="ComfyUI Launcher", |
||||||
|
version="1.0.0", |
||||||
|
developers=["ComfyUI Launcher Team"], |
||||||
|
copyright="© 2025 ComfyUI Launcher", |
||||||
|
comments="Un launcher GTK per ComfyUI con supporto conda" |
||||||
|
) |
||||||
|
about.present() |
||||||
|
|
||||||
|
def on_open_folder_action(self, action, param): |
||||||
|
"""Apre la cartella ComfyUI""" |
||||||
|
try: |
||||||
|
# Prova ad aprire la cartella di default di ComfyUI |
||||||
|
home_dir = os.path.expanduser("~") |
||||||
|
comfy_dir = os.path.join(home_dir, "comfy", "ComfyUI") |
||||||
|
if os.path.exists(comfy_dir): |
||||||
|
subprocess.run(['xdg-open', comfy_dir]) |
||||||
|
else: |
||||||
|
self.win.log_message("Cartella ComfyUI non trovata") |
||||||
|
except Exception as e: |
||||||
|
self.win.log_message(f"Errore nell'apertura cartella: {str(e)}") |
||||||
|
|
||||||
|
def on_quit_action(self, action, param): |
||||||
|
# Ferma ComfyUI se in esecuzione prima di chiudere |
||||||
|
if hasattr(self, 'win') and self.win.comfyui_process: |
||||||
|
self.win.on_stop_comfyui(None) |
||||||
|
self.quit() |
||||||
|
|
||||||
|
def main(): |
||||||
|
print("Avvio del ComfyUI Launcher...") |
||||||
|
try: |
||||||
|
app = ComfyUIApp(application_id="com.example.ComfyUILauncher") |
||||||
|
print("Applicazione launcher creata, avvio in corso...") |
||||||
|
exit_code = app.run(sys.argv) |
||||||
|
print(f"Launcher terminato con codice: {exit_code}") |
||||||
|
return exit_code |
||||||
|
except Exception as e: |
||||||
|
print(f"Errore durante l'esecuzione del launcher: {e}") |
||||||
|
import traceback |
||||||
|
traceback.print_exc() |
||||||
|
return 1 |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
main() |
||||||
@ -0,0 +1,84 @@ |
|||||||
|
[build-system] |
||||||
|
requires = ["setuptools>=61.0", "wheel"] |
||||||
|
build-backend = "setuptools.build_meta" |
||||||
|
|
||||||
|
[project] |
||||||
|
name = "comfyui-launcher" |
||||||
|
version = "1.0.0" |
||||||
|
description = "A modern GTK4 launcher for ComfyUI with conda environment support" |
||||||
|
readme = "README_EN.md" |
||||||
|
license = {text = "MIT"} |
||||||
|
authors = [ |
||||||
|
{name = "ComfyUI Launcher Team"}, |
||||||
|
] |
||||||
|
maintainers = [ |
||||||
|
{name = "ComfyUI Launcher Team"}, |
||||||
|
] |
||||||
|
keywords = ["comfyui", "launcher", "gtk4", "conda", "ai", "stable-diffusion"] |
||||||
|
classifiers = [ |
||||||
|
"Development Status :: 4 - Beta", |
||||||
|
"Intended Audience :: End Users/Desktop", |
||||||
|
"License :: OSI Approved :: MIT License", |
||||||
|
"Operating System :: POSIX :: Linux", |
||||||
|
"Programming Language :: Python :: 3", |
||||||
|
"Programming Language :: Python :: 3.9", |
||||||
|
"Programming Language :: Python :: 3.10", |
||||||
|
"Programming Language :: Python :: 3.11", |
||||||
|
"Programming Language :: Python :: 3.12", |
||||||
|
"Topic :: Multimedia :: Graphics", |
||||||
|
"Topic :: Scientific/Engineering :: Artificial Intelligence", |
||||||
|
"Environment :: X11 Applications :: GTK", |
||||||
|
] |
||||||
|
requires-python = ">=3.9" |
||||||
|
dependencies = [ |
||||||
|
"PyGObject>=3.42.0", |
||||||
|
] |
||||||
|
|
||||||
|
[project.optional-dependencies] |
||||||
|
monitoring = ["psutil>=5.9.0"] |
||||||
|
dev = [ |
||||||
|
"black", |
||||||
|
"flake8", |
||||||
|
"mypy", |
||||||
|
"pytest", |
||||||
|
] |
||||||
|
|
||||||
|
[project.urls] |
||||||
|
Homepage = "https://github.com/your-username/comfyui-launcher" |
||||||
|
Repository = "https://github.com/your-username/comfyui-launcher" |
||||||
|
Issues = "https://github.com/your-username/comfyui-launcher/issues" |
||||||
|
Documentation = "https://github.com/your-username/comfyui-launcher/blob/main/README_EN.md" |
||||||
|
|
||||||
|
[project.scripts] |
||||||
|
comfyui-launcher = "main:main" |
||||||
|
|
||||||
|
[tool.setuptools] |
||||||
|
py-modules = ["main"] |
||||||
|
|
||||||
|
[tool.black] |
||||||
|
line-length = 88 |
||||||
|
target-version = ['py39'] |
||||||
|
include = '\.pyi?$' |
||||||
|
extend-exclude = ''' |
||||||
|
/( |
||||||
|
# directories |
||||||
|
\.eggs |
||||||
|
| \.git |
||||||
|
| \.hg |
||||||
|
| \.mypy_cache |
||||||
|
| \.tox |
||||||
|
| \.venv |
||||||
|
| build |
||||||
|
| dist |
||||||
|
)/ |
||||||
|
''' |
||||||
|
|
||||||
|
[tool.flake8] |
||||||
|
max-line-length = 88 |
||||||
|
extend-ignore = ["E203", "W503"] |
||||||
|
|
||||||
|
[tool.mypy] |
||||||
|
python_version = "3.9" |
||||||
|
warn_return_any = true |
||||||
|
warn_unused_configs = true |
||||||
|
disallow_untyped_defs = true |
||||||
@ -0,0 +1,26 @@ |
|||||||
|
# ComfyUI Launcher Requirements |
||||||
|
# Python dependencies for the GTK4 ComfyUI launcher |
||||||
|
|
||||||
|
# Core GTK bindings |
||||||
|
PyGObject>=3.42.0 |
||||||
|
|
||||||
|
# System monitoring (optional, fallback to system commands if not available) |
||||||
|
psutil>=5.9.0 |
||||||
|
|
||||||
|
# Note: Additional system dependencies required: |
||||||
|
# - GTK4 development libraries |
||||||
|
# - Cairo development libraries |
||||||
|
# - GObject Introspection development libraries |
||||||
|
# - pkg-config |
||||||
|
# - Python development headers |
||||||
|
# |
||||||
|
# Install system dependencies first: |
||||||
|
# |
||||||
|
# Fedora/RHEL/CentOS: |
||||||
|
# sudo dnf install cairo-devel gobject-introspection-devel gtk4-devel pkg-config python3-devel |
||||||
|
# |
||||||
|
# Debian/Ubuntu: |
||||||
|
# sudo apt install libcairo2-dev libgirepository1.0-dev libgtk-4-dev pkg-config python3-dev |
||||||
|
# |
||||||
|
# Arch Linux: |
||||||
|
# sudo pacman -S cairo gobject-introspection gtk4 pkgconf python |
||||||
@ -0,0 +1,35 @@ |
|||||||
|
/* Stili per il ComfyUI Launcher */ |
||||||
|
|
||||||
|
.status-running { |
||||||
|
color: #26a269; |
||||||
|
} |
||||||
|
|
||||||
|
.status-stopped { |
||||||
|
color: #c01c28; |
||||||
|
} |
||||||
|
|
||||||
|
.log-view { |
||||||
|
font-family: "JetBrains Mono", "Fira Code", "Source Code Pro", monospace; |
||||||
|
font-size: 10pt; |
||||||
|
background-color: #1e1e1e; |
||||||
|
color: #d4d4d4; |
||||||
|
} |
||||||
|
|
||||||
|
.environment-frame { |
||||||
|
border: 1px solid #3584e4; |
||||||
|
border-radius: 6px; |
||||||
|
} |
||||||
|
|
||||||
|
.control-button { |
||||||
|
margin: 6px; |
||||||
|
padding: 12px 24px; |
||||||
|
font-weight: bold; |
||||||
|
} |
||||||
|
|
||||||
|
.install-button { |
||||||
|
background: linear-gradient(to bottom, #62a0ea, #3584e4); |
||||||
|
} |
||||||
|
|
||||||
|
.install-button:hover { |
||||||
|
background: linear-gradient(to bottom, #74b0fa, #4894f4); |
||||||
|
} |
||||||
Loading…
Reference in new issue