Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
# Main window for MacroPad Server (PySide6)
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
import sys
|
|
|
|
|
import threading
|
|
|
|
|
from typing import Optional
|
|
|
|
|
|
2026-01-05 19:33:07 -08:00
|
|
|
# Windows startup management
|
|
|
|
|
if sys.platform == 'win32':
|
|
|
|
|
import winreg
|
|
|
|
|
|
2026-01-03 17:12:39 -08:00
|
|
|
|
|
|
|
|
def get_resource_path(relative_path):
|
|
|
|
|
"""Get the path to a bundled resource file."""
|
|
|
|
|
if getattr(sys, 'frozen', False):
|
|
|
|
|
base_path = sys._MEIPASS
|
|
|
|
|
else:
|
|
|
|
|
base_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
|
return os.path.join(base_path, relative_path)
|
|
|
|
|
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
from PySide6.QtWidgets import (
|
|
|
|
|
QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
|
|
|
|
|
QLabel, QPushButton, QTabWidget, QGridLayout,
|
|
|
|
|
QScrollArea, QFrame, QMenu, QMenuBar, QStatusBar,
|
2026-01-03 17:07:49 -08:00
|
|
|
QMessageBox, QApplication, QSystemTrayIcon, QStyle
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
)
|
2026-01-05 19:33:07 -08:00
|
|
|
from PySide6.QtCore import Qt, Signal, QTimer, QSize, QEvent
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
from PySide6.QtGui import QIcon, QPixmap, QAction, QFont
|
|
|
|
|
|
2026-01-05 19:33:07 -08:00
|
|
|
from config import VERSION, THEME, DEFAULT_PORT, SETTINGS_FILE
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
from macro_manager import MacroManager
|
|
|
|
|
from web_server import WebServer
|
2026-01-05 19:33:07 -08:00
|
|
|
from .settings_manager import SettingsManager
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class MacroButton(QPushButton):
|
|
|
|
|
"""Custom button widget for displaying a macro."""
|
|
|
|
|
|
2026-01-03 17:37:43 -08:00
|
|
|
# Signals for context menu actions
|
|
|
|
|
edit_requested = Signal(str)
|
|
|
|
|
delete_requested = Signal(str)
|
|
|
|
|
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
def __init__(self, macro_id: str, macro: dict, parent=None):
|
|
|
|
|
super().__init__(parent)
|
|
|
|
|
self.macro_id = macro_id
|
|
|
|
|
self.macro = macro
|
|
|
|
|
|
|
|
|
|
self.setFixedSize(120, 100)
|
|
|
|
|
self.setCursor(Qt.PointingHandCursor)
|
|
|
|
|
self.setStyleSheet(f"""
|
|
|
|
|
QPushButton {{
|
|
|
|
|
background-color: {THEME['button_bg']};
|
|
|
|
|
color: {THEME['fg_color']};
|
|
|
|
|
border: none;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
padding: 8px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}}
|
|
|
|
|
QPushButton:hover {{
|
|
|
|
|
background-color: {THEME['highlight_color']};
|
|
|
|
|
}}
|
|
|
|
|
QPushButton:pressed {{
|
|
|
|
|
background-color: {THEME['accent_color']};
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
# Layout
|
|
|
|
|
layout = QVBoxLayout(self)
|
|
|
|
|
layout.setSpacing(4)
|
|
|
|
|
layout.setContentsMargins(4, 4, 4, 4)
|
|
|
|
|
|
|
|
|
|
# Image or placeholder
|
|
|
|
|
image_label = QLabel()
|
|
|
|
|
image_label.setFixedSize(48, 48)
|
|
|
|
|
image_label.setAlignment(Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
if macro.get("image_path"):
|
|
|
|
|
pixmap = QPixmap(macro["image_path"])
|
|
|
|
|
if not pixmap.isNull():
|
|
|
|
|
pixmap = pixmap.scaled(48, 48, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
|
|
|
|
image_label.setPixmap(pixmap)
|
|
|
|
|
else:
|
|
|
|
|
self._set_placeholder(image_label, macro["name"])
|
|
|
|
|
else:
|
|
|
|
|
self._set_placeholder(image_label, macro["name"])
|
|
|
|
|
|
|
|
|
|
layout.addWidget(image_label, alignment=Qt.AlignCenter)
|
|
|
|
|
|
|
|
|
|
# Name label
|
|
|
|
|
name_label = QLabel(macro["name"])
|
|
|
|
|
name_label.setAlignment(Qt.AlignCenter)
|
|
|
|
|
name_label.setWordWrap(True)
|
|
|
|
|
name_label.setStyleSheet(f"color: {THEME['fg_color']}; font-size: 11px;")
|
|
|
|
|
layout.addWidget(name_label)
|
|
|
|
|
|
|
|
|
|
def _set_placeholder(self, label: QLabel, name: str):
|
|
|
|
|
"""Set a placeholder with the first letter of the name."""
|
|
|
|
|
label.setStyleSheet(f"""
|
|
|
|
|
background-color: {THEME['highlight_color']};
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
font-size: 20px;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
color: {THEME['fg_color']};
|
|
|
|
|
""")
|
|
|
|
|
label.setText(name[0].upper() if name else "?")
|
|
|
|
|
|
|
|
|
|
def contextMenuEvent(self, event):
|
|
|
|
|
"""Show context menu on right-click."""
|
|
|
|
|
menu = QMenu(self)
|
|
|
|
|
edit_action = menu.addAction("Edit")
|
|
|
|
|
delete_action = menu.addAction("Delete")
|
|
|
|
|
|
|
|
|
|
action = menu.exec_(event.globalPos())
|
|
|
|
|
if action == edit_action:
|
2026-01-03 17:37:43 -08:00
|
|
|
self.edit_requested.emit(self.macro_id)
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
elif action == delete_action:
|
2026-01-03 17:37:43 -08:00
|
|
|
self.delete_requested.emit(self.macro_id)
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class MainWindow(QMainWindow):
|
|
|
|
|
"""Main application window."""
|
|
|
|
|
|
|
|
|
|
macros_changed = Signal()
|
|
|
|
|
|
|
|
|
|
def __init__(self, app_dir: str):
|
|
|
|
|
super().__init__()
|
|
|
|
|
self.app_dir = app_dir
|
|
|
|
|
self.current_tab = "All"
|
|
|
|
|
self.sort_by = "name"
|
|
|
|
|
|
2026-01-05 19:33:07 -08:00
|
|
|
# Initialize settings manager
|
|
|
|
|
settings_file = os.path.join(app_dir, SETTINGS_FILE)
|
|
|
|
|
self.settings_manager = SettingsManager(settings_file)
|
|
|
|
|
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
# Initialize macro manager
|
|
|
|
|
data_file = os.path.join(app_dir, "macros.json")
|
|
|
|
|
images_dir = os.path.join(app_dir, "macro_images")
|
|
|
|
|
os.makedirs(images_dir, exist_ok=True)
|
|
|
|
|
|
|
|
|
|
self.macro_manager = MacroManager(data_file, images_dir, app_dir)
|
|
|
|
|
|
|
|
|
|
# Initialize web server
|
|
|
|
|
self.web_server = WebServer(self.macro_manager, app_dir, DEFAULT_PORT)
|
|
|
|
|
self.server_thread = None
|
|
|
|
|
|
2026-01-05 19:33:07 -08:00
|
|
|
# Relay client (initialized later if enabled)
|
|
|
|
|
self.relay_client = None
|
|
|
|
|
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
# Setup UI
|
|
|
|
|
self.setup_ui()
|
|
|
|
|
self.setup_menu()
|
|
|
|
|
self.setup_tray()
|
|
|
|
|
|
|
|
|
|
# Start web server
|
|
|
|
|
self.start_server()
|
|
|
|
|
|
2026-01-05 19:33:07 -08:00
|
|
|
# Start relay client if enabled
|
|
|
|
|
if self.settings_manager.get_relay_enabled():
|
|
|
|
|
self.start_relay_client()
|
|
|
|
|
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
# Connect signals
|
|
|
|
|
self.macros_changed.connect(self.refresh_macros)
|
|
|
|
|
|
|
|
|
|
# Load initial data
|
|
|
|
|
self.refresh_tabs()
|
|
|
|
|
self.refresh_macros()
|
|
|
|
|
|
|
|
|
|
def setup_ui(self):
|
|
|
|
|
"""Setup the main UI components."""
|
|
|
|
|
self.setWindowTitle(f"MacroPad Server v{VERSION}")
|
|
|
|
|
self.setMinimumSize(600, 400)
|
|
|
|
|
self.setStyleSheet(f"background-color: {THEME['bg_color']};")
|
|
|
|
|
|
|
|
|
|
# Central widget
|
|
|
|
|
central = QWidget()
|
|
|
|
|
self.setCentralWidget(central)
|
|
|
|
|
layout = QVBoxLayout(central)
|
|
|
|
|
layout.setSpacing(0)
|
|
|
|
|
layout.setContentsMargins(0, 0, 0, 0)
|
|
|
|
|
|
|
|
|
|
# Toolbar
|
|
|
|
|
toolbar = QWidget()
|
|
|
|
|
toolbar.setStyleSheet(f"background-color: {THEME['highlight_color']};")
|
|
|
|
|
toolbar_layout = QHBoxLayout(toolbar)
|
|
|
|
|
toolbar_layout.setContentsMargins(10, 10, 10, 10)
|
|
|
|
|
|
|
|
|
|
add_btn = QPushButton("+ Add Macro")
|
|
|
|
|
add_btn.setStyleSheet(f"""
|
|
|
|
|
QPushButton {{
|
|
|
|
|
background-color: {THEME['accent_color']};
|
|
|
|
|
color: white;
|
|
|
|
|
border: none;
|
|
|
|
|
padding: 8px 16px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}}
|
|
|
|
|
QPushButton:hover {{
|
|
|
|
|
background-color: #0096ff;
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
add_btn.clicked.connect(self.add_macro)
|
|
|
|
|
toolbar_layout.addWidget(add_btn)
|
|
|
|
|
|
|
|
|
|
toolbar_layout.addStretch()
|
|
|
|
|
|
|
|
|
|
# IP address label
|
|
|
|
|
self.ip_label = QLabel()
|
|
|
|
|
self.ip_label.setStyleSheet(f"color: {THEME['fg_color']};")
|
|
|
|
|
self.update_ip_label()
|
|
|
|
|
toolbar_layout.addWidget(self.ip_label)
|
|
|
|
|
|
|
|
|
|
qr_btn = QPushButton("QR Code")
|
|
|
|
|
qr_btn.setStyleSheet(f"""
|
|
|
|
|
QPushButton {{
|
|
|
|
|
background-color: {THEME['button_bg']};
|
|
|
|
|
color: white;
|
|
|
|
|
border: none;
|
|
|
|
|
padding: 8px 16px;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
}}
|
|
|
|
|
QPushButton:hover {{
|
|
|
|
|
background-color: {THEME['highlight_color']};
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
qr_btn.clicked.connect(self.show_qr_code)
|
|
|
|
|
toolbar_layout.addWidget(qr_btn)
|
|
|
|
|
|
|
|
|
|
layout.addWidget(toolbar)
|
|
|
|
|
|
|
|
|
|
# Tab widget
|
|
|
|
|
self.tab_widget = QTabWidget()
|
|
|
|
|
self.tab_widget.setStyleSheet(f"""
|
|
|
|
|
QTabWidget::pane {{
|
|
|
|
|
border: none;
|
|
|
|
|
background: {THEME['bg_color']};
|
|
|
|
|
}}
|
|
|
|
|
QTabBar::tab {{
|
|
|
|
|
background: {THEME['tab_bg']};
|
|
|
|
|
color: {THEME['fg_color']};
|
|
|
|
|
padding: 8px 16px;
|
|
|
|
|
margin-right: 2px;
|
|
|
|
|
border-top-left-radius: 4px;
|
|
|
|
|
border-top-right-radius: 4px;
|
|
|
|
|
}}
|
|
|
|
|
QTabBar::tab:selected {{
|
|
|
|
|
background: {THEME['tab_selected']};
|
|
|
|
|
}}
|
|
|
|
|
QTabBar::tab:hover {{
|
|
|
|
|
background: {THEME['highlight_color']};
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
self.tab_widget.currentChanged.connect(self.on_tab_changed)
|
|
|
|
|
layout.addWidget(self.tab_widget)
|
|
|
|
|
|
|
|
|
|
# Status bar
|
|
|
|
|
self.status_bar = QStatusBar()
|
|
|
|
|
self.status_bar.setStyleSheet(f"""
|
|
|
|
|
background-color: {THEME['highlight_color']};
|
|
|
|
|
color: {THEME['fg_color']};
|
|
|
|
|
""")
|
|
|
|
|
self.setStatusBar(self.status_bar)
|
|
|
|
|
self.status_bar.showMessage("Ready")
|
|
|
|
|
|
|
|
|
|
def setup_menu(self):
|
|
|
|
|
"""Setup the menu bar."""
|
|
|
|
|
menubar = self.menuBar()
|
|
|
|
|
menubar.setStyleSheet(f"""
|
|
|
|
|
QMenuBar {{
|
|
|
|
|
background-color: {THEME['highlight_color']};
|
|
|
|
|
color: {THEME['fg_color']};
|
|
|
|
|
}}
|
|
|
|
|
QMenuBar::item:selected {{
|
|
|
|
|
background-color: {THEME['accent_color']};
|
|
|
|
|
}}
|
|
|
|
|
QMenu {{
|
|
|
|
|
background-color: {THEME['highlight_color']};
|
|
|
|
|
color: {THEME['fg_color']};
|
|
|
|
|
}}
|
|
|
|
|
QMenu::item:selected {{
|
|
|
|
|
background-color: {THEME['accent_color']};
|
|
|
|
|
}}
|
|
|
|
|
""")
|
|
|
|
|
|
|
|
|
|
# File menu
|
|
|
|
|
file_menu = menubar.addMenu("File")
|
|
|
|
|
|
|
|
|
|
add_action = QAction("Add Macro", self)
|
|
|
|
|
add_action.setShortcut("Ctrl+N")
|
|
|
|
|
add_action.triggered.connect(self.add_macro)
|
|
|
|
|
file_menu.addAction(add_action)
|
|
|
|
|
|
|
|
|
|
file_menu.addSeparator()
|
|
|
|
|
|
2026-01-05 19:33:07 -08:00
|
|
|
# Windows startup option (only on Windows)
|
|
|
|
|
if sys.platform == 'win32':
|
|
|
|
|
self.startup_action = QAction("Start on Windows Startup", self)
|
|
|
|
|
self.startup_action.setCheckable(True)
|
|
|
|
|
self.startup_action.setChecked(self.get_startup_enabled())
|
|
|
|
|
self.startup_action.triggered.connect(self.toggle_startup)
|
|
|
|
|
file_menu.addAction(self.startup_action)
|
|
|
|
|
file_menu.addSeparator()
|
|
|
|
|
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
quit_action = QAction("Quit", self)
|
|
|
|
|
quit_action.setShortcut("Ctrl+Q")
|
|
|
|
|
quit_action.triggered.connect(self.close)
|
|
|
|
|
file_menu.addAction(quit_action)
|
|
|
|
|
|
2026-01-05 19:33:07 -08:00
|
|
|
# Edit menu
|
|
|
|
|
edit_menu = menubar.addMenu("Edit")
|
|
|
|
|
|
|
|
|
|
settings_action = QAction("Settings...", self)
|
|
|
|
|
settings_action.setShortcut("Ctrl+,")
|
|
|
|
|
settings_action.triggered.connect(self.show_settings)
|
|
|
|
|
edit_menu.addAction(settings_action)
|
|
|
|
|
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
# View menu
|
|
|
|
|
view_menu = menubar.addMenu("View")
|
|
|
|
|
|
|
|
|
|
refresh_action = QAction("Refresh", self)
|
|
|
|
|
refresh_action.setShortcut("F5")
|
|
|
|
|
refresh_action.triggered.connect(self.refresh_all)
|
|
|
|
|
view_menu.addAction(refresh_action)
|
|
|
|
|
|
|
|
|
|
# Sort submenu
|
|
|
|
|
sort_menu = view_menu.addMenu("Sort By")
|
|
|
|
|
for sort_option in [("Name", "name"), ("Type", "type"), ("Recent", "recent")]:
|
|
|
|
|
action = QAction(sort_option[0], self)
|
|
|
|
|
action.triggered.connect(lambda checked, s=sort_option[1]: self.set_sort(s))
|
|
|
|
|
sort_menu.addAction(action)
|
|
|
|
|
|
|
|
|
|
# Help menu
|
|
|
|
|
help_menu = menubar.addMenu("Help")
|
|
|
|
|
|
|
|
|
|
about_action = QAction("About", self)
|
|
|
|
|
about_action.triggered.connect(self.show_about)
|
|
|
|
|
help_menu.addAction(about_action)
|
|
|
|
|
|
|
|
|
|
def setup_tray(self):
|
|
|
|
|
"""Setup system tray icon."""
|
|
|
|
|
self.tray_icon = QSystemTrayIcon(self)
|
|
|
|
|
|
2026-01-03 17:12:39 -08:00
|
|
|
# Load icon from bundled resources
|
|
|
|
|
icon_path = get_resource_path("Macro Pad.png")
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
if os.path.exists(icon_path):
|
2026-01-03 17:12:39 -08:00
|
|
|
icon = QIcon(icon_path)
|
|
|
|
|
self.tray_icon.setIcon(icon)
|
|
|
|
|
self.setWindowIcon(icon)
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
else:
|
2026-01-03 17:07:49 -08:00
|
|
|
self.tray_icon.setIcon(self.style().standardIcon(QStyle.StandardPixmap.SP_ComputerIcon))
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
|
|
|
|
|
# Tray menu
|
|
|
|
|
tray_menu = QMenu()
|
|
|
|
|
show_action = tray_menu.addAction("Show")
|
|
|
|
|
show_action.triggered.connect(self.show)
|
|
|
|
|
quit_action = tray_menu.addAction("Quit")
|
|
|
|
|
quit_action.triggered.connect(self.close)
|
|
|
|
|
|
|
|
|
|
self.tray_icon.setContextMenu(tray_menu)
|
|
|
|
|
self.tray_icon.activated.connect(self.on_tray_activated)
|
|
|
|
|
self.tray_icon.show()
|
|
|
|
|
|
|
|
|
|
def on_tray_activated(self, reason):
|
|
|
|
|
"""Handle tray icon activation."""
|
2026-01-03 17:07:49 -08:00
|
|
|
if reason == QSystemTrayIcon.ActivationReason.DoubleClick:
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
self.show()
|
|
|
|
|
self.activateWindow()
|
|
|
|
|
|
|
|
|
|
def start_server(self):
|
|
|
|
|
"""Start the web server in a background thread."""
|
2026-01-03 17:15:38 -08:00
|
|
|
self.server_error = None
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
|
|
|
|
|
def run():
|
2026-01-03 17:15:38 -08:00
|
|
|
try:
|
|
|
|
|
self.web_server.create_app()
|
|
|
|
|
self.web_server.run()
|
|
|
|
|
except Exception as e:
|
|
|
|
|
self.server_error = str(e)
|
|
|
|
|
# Emit signal to show error on main thread
|
|
|
|
|
QTimer.singleShot(0, self.show_server_error)
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
|
|
|
|
|
self.server_thread = threading.Thread(target=run, daemon=True)
|
|
|
|
|
self.server_thread.start()
|
2026-01-03 17:15:38 -08:00
|
|
|
|
|
|
|
|
# Give the server a moment to start, then check for errors
|
|
|
|
|
QTimer.singleShot(1000, self.check_server_started)
|
|
|
|
|
|
|
|
|
|
def check_server_started(self):
|
|
|
|
|
"""Check if server started successfully."""
|
|
|
|
|
if self.server_error:
|
|
|
|
|
self.show_server_error()
|
|
|
|
|
else:
|
|
|
|
|
self.status_bar.showMessage(f"Server running on port {DEFAULT_PORT}")
|
|
|
|
|
|
|
|
|
|
def show_server_error(self):
|
|
|
|
|
"""Show server error dialog."""
|
|
|
|
|
error_msg = self.server_error or "Unknown error"
|
|
|
|
|
self.status_bar.showMessage(f"Server failed to start")
|
|
|
|
|
QMessageBox.warning(
|
|
|
|
|
self,
|
|
|
|
|
"Web Server Error",
|
|
|
|
|
f"Failed to start web server on port {DEFAULT_PORT}.\n\n"
|
|
|
|
|
f"Error: {error_msg}\n\n"
|
|
|
|
|
"The web interface will not be available.\n"
|
|
|
|
|
"Check if another application is using the port."
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def stop_server(self):
|
|
|
|
|
"""Stop the web server."""
|
|
|
|
|
if self.web_server:
|
|
|
|
|
self.web_server.stop()
|
|
|
|
|
self.status_bar.showMessage("Server stopped")
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
|
|
|
|
|
def update_ip_label(self):
|
|
|
|
|
"""Update the IP address label."""
|
2026-01-05 19:33:07 -08:00
|
|
|
# Check if relay is connected and has a session ID
|
|
|
|
|
if self.relay_client and self.relay_client.is_connected():
|
|
|
|
|
session_id = self.settings_manager.get_relay_session_id()
|
|
|
|
|
if session_id:
|
|
|
|
|
relay_url = self.settings_manager.get_relay_url()
|
|
|
|
|
# Convert wss:// to https:// for display
|
|
|
|
|
base_url = relay_url.replace('wss://', 'https://').replace('ws://', 'http://')
|
|
|
|
|
base_url = base_url.replace('/desktop', '').rstrip('/')
|
|
|
|
|
self.ip_label.setText(f"{base_url}/{session_id}")
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# Fall back to local IP
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
try:
|
|
|
|
|
import netifaces
|
|
|
|
|
for iface in netifaces.interfaces():
|
|
|
|
|
addrs = netifaces.ifaddresses(iface)
|
|
|
|
|
if netifaces.AF_INET in addrs:
|
|
|
|
|
for addr in addrs[netifaces.AF_INET]:
|
|
|
|
|
ip = addr.get('addr', '')
|
|
|
|
|
if ip and not ip.startswith('127.'):
|
|
|
|
|
self.ip_label.setText(f"http://{ip}:{DEFAULT_PORT}")
|
|
|
|
|
return
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
self.ip_label.setText(f"http://localhost:{DEFAULT_PORT}")
|
|
|
|
|
|
|
|
|
|
def refresh_tabs(self):
|
|
|
|
|
"""Refresh the tab widget."""
|
|
|
|
|
self.tab_widget.blockSignals(True)
|
|
|
|
|
self.tab_widget.clear()
|
|
|
|
|
|
|
|
|
|
tabs = self.macro_manager.get_unique_tabs()
|
|
|
|
|
for tab_name in tabs:
|
|
|
|
|
scroll = QScrollArea()
|
|
|
|
|
scroll.setWidgetResizable(True)
|
|
|
|
|
scroll.setStyleSheet(f"background-color: {THEME['bg_color']}; border: none;")
|
|
|
|
|
|
|
|
|
|
container = QWidget()
|
|
|
|
|
container.setStyleSheet(f"background-color: {THEME['bg_color']};")
|
|
|
|
|
scroll.setWidget(container)
|
|
|
|
|
|
|
|
|
|
self.tab_widget.addTab(scroll, tab_name)
|
|
|
|
|
|
|
|
|
|
self.tab_widget.blockSignals(False)
|
|
|
|
|
|
|
|
|
|
def refresh_macros(self):
|
|
|
|
|
"""Refresh the macro grid."""
|
|
|
|
|
current_index = self.tab_widget.currentIndex()
|
|
|
|
|
if current_index < 0:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
scroll = self.tab_widget.widget(current_index)
|
|
|
|
|
container = scroll.widget()
|
|
|
|
|
|
|
|
|
|
# Clear existing layout
|
|
|
|
|
if container.layout():
|
|
|
|
|
while container.layout().count():
|
|
|
|
|
item = container.layout().takeAt(0)
|
|
|
|
|
if item.widget():
|
|
|
|
|
item.widget().deleteLater()
|
|
|
|
|
else:
|
|
|
|
|
container.setLayout(QGridLayout())
|
|
|
|
|
|
|
|
|
|
layout = container.layout()
|
|
|
|
|
layout.setSpacing(10)
|
|
|
|
|
layout.setContentsMargins(10, 10, 10, 10)
|
|
|
|
|
layout.setAlignment(Qt.AlignTop | Qt.AlignLeft)
|
|
|
|
|
|
|
|
|
|
# Get macros for current tab
|
|
|
|
|
tab_name = self.tab_widget.tabText(current_index)
|
|
|
|
|
macro_list = self.macro_manager.get_sorted_macros(self.sort_by)
|
|
|
|
|
filtered = self.macro_manager.filter_macros_by_tab(macro_list, tab_name)
|
|
|
|
|
|
|
|
|
|
# Add macro buttons
|
|
|
|
|
cols = max(1, (self.width() - 40) // 130)
|
|
|
|
|
for i, (macro_id, macro) in enumerate(filtered):
|
|
|
|
|
btn = MacroButton(macro_id, macro)
|
|
|
|
|
btn.clicked.connect(lambda checked, mid=macro_id: self.execute_macro(mid))
|
2026-01-03 17:37:43 -08:00
|
|
|
btn.edit_requested.connect(self.edit_macro)
|
|
|
|
|
btn.delete_requested.connect(self.delete_macro)
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
layout.addWidget(btn, i // cols, i % cols)
|
|
|
|
|
|
|
|
|
|
def on_tab_changed(self, index):
|
|
|
|
|
"""Handle tab change."""
|
|
|
|
|
self.refresh_macros()
|
|
|
|
|
|
|
|
|
|
def execute_macro(self, macro_id: str):
|
|
|
|
|
"""Execute a macro."""
|
|
|
|
|
success = self.macro_manager.execute_macro(macro_id)
|
|
|
|
|
if success:
|
|
|
|
|
self.status_bar.showMessage("Macro executed", 2000)
|
|
|
|
|
else:
|
|
|
|
|
self.status_bar.showMessage("Macro execution failed", 2000)
|
|
|
|
|
|
|
|
|
|
def add_macro(self):
|
|
|
|
|
"""Open dialog to add a new macro."""
|
|
|
|
|
from .macro_editor import MacroEditorDialog
|
|
|
|
|
dialog = MacroEditorDialog(self.macro_manager, parent=self)
|
|
|
|
|
if dialog.exec_():
|
|
|
|
|
self.refresh_tabs()
|
|
|
|
|
self.refresh_macros()
|
|
|
|
|
|
|
|
|
|
def edit_macro(self, macro_id: str):
|
|
|
|
|
"""Open dialog to edit a macro."""
|
|
|
|
|
from .macro_editor import MacroEditorDialog
|
|
|
|
|
dialog = MacroEditorDialog(self.macro_manager, macro_id=macro_id, parent=self)
|
|
|
|
|
if dialog.exec_():
|
|
|
|
|
self.refresh_tabs()
|
|
|
|
|
self.refresh_macros()
|
|
|
|
|
|
|
|
|
|
def delete_macro(self, macro_id: str):
|
|
|
|
|
"""Delete a macro with confirmation."""
|
|
|
|
|
reply = QMessageBox.question(
|
|
|
|
|
self, "Delete Macro",
|
|
|
|
|
"Are you sure you want to delete this macro?",
|
|
|
|
|
QMessageBox.Yes | QMessageBox.No
|
|
|
|
|
)
|
|
|
|
|
if reply == QMessageBox.Yes:
|
|
|
|
|
self.macro_manager.delete_macro(macro_id)
|
|
|
|
|
self.refresh_tabs()
|
|
|
|
|
self.refresh_macros()
|
|
|
|
|
|
|
|
|
|
def set_sort(self, sort_by: str):
|
|
|
|
|
"""Set the sort order."""
|
|
|
|
|
self.sort_by = sort_by
|
|
|
|
|
self.refresh_macros()
|
|
|
|
|
|
|
|
|
|
def refresh_all(self):
|
|
|
|
|
"""Refresh tabs and macros."""
|
|
|
|
|
self.refresh_tabs()
|
|
|
|
|
self.refresh_macros()
|
|
|
|
|
|
|
|
|
|
def show_qr_code(self):
|
|
|
|
|
"""Show QR code dialog."""
|
|
|
|
|
try:
|
|
|
|
|
import qrcode
|
|
|
|
|
from PySide6.QtWidgets import QDialog, QVBoxLayout
|
|
|
|
|
from io import BytesIO
|
|
|
|
|
|
|
|
|
|
url = self.ip_label.text()
|
|
|
|
|
qr = qrcode.QRCode(version=1, box_size=10, border=4)
|
|
|
|
|
qr.add_data(url)
|
|
|
|
|
qr.make(fit=True)
|
|
|
|
|
img = qr.make_image(fill_color="black", back_color="white")
|
|
|
|
|
|
|
|
|
|
# Convert to QPixmap
|
|
|
|
|
buffer = BytesIO()
|
|
|
|
|
img.save(buffer, format="PNG")
|
|
|
|
|
buffer.seek(0)
|
|
|
|
|
|
|
|
|
|
pixmap = QPixmap()
|
|
|
|
|
pixmap.loadFromData(buffer.read())
|
|
|
|
|
|
|
|
|
|
# Show dialog
|
|
|
|
|
dialog = QDialog(self)
|
|
|
|
|
dialog.setWindowTitle("QR Code")
|
|
|
|
|
layout = QVBoxLayout(dialog)
|
|
|
|
|
|
|
|
|
|
label = QLabel()
|
|
|
|
|
label.setPixmap(pixmap.scaled(300, 300, Qt.KeepAspectRatio, Qt.SmoothTransformation))
|
|
|
|
|
layout.addWidget(label)
|
|
|
|
|
|
|
|
|
|
url_label = QLabel(url)
|
|
|
|
|
url_label.setStyleSheet(f"color: {THEME['fg_color']};")
|
|
|
|
|
url_label.setAlignment(Qt.AlignCenter)
|
|
|
|
|
layout.addWidget(url_label)
|
|
|
|
|
|
|
|
|
|
dialog.exec_()
|
|
|
|
|
except ImportError:
|
|
|
|
|
QMessageBox.warning(self, "Error", "QR code library not available")
|
|
|
|
|
|
|
|
|
|
def show_about(self):
|
|
|
|
|
"""Show about dialog."""
|
2026-01-03 18:59:57 -08:00
|
|
|
about_box = QMessageBox(self)
|
|
|
|
|
about_box.setWindowTitle("About MacroPad Server")
|
|
|
|
|
about_box.setTextFormat(Qt.RichText)
|
|
|
|
|
about_box.setTextInteractionFlags(Qt.TextBrowserInteraction)
|
|
|
|
|
about_box.setText(
|
|
|
|
|
f"<h2>MacroPad Server v{VERSION}</h2>"
|
|
|
|
|
"<p>A cross-platform macro management application<br>"
|
|
|
|
|
"with desktop and web interfaces.</p>"
|
2026-01-03 19:00:32 -08:00
|
|
|
"<p><b>Author:</b> <a href='https://shadowdao.com'>ShadowDao</a></p>"
|
2026-01-03 18:59:57 -08:00
|
|
|
"<p><b>Updates:</b> <a href='https://shadowdao.com'>shadowdao.com</a></p>"
|
|
|
|
|
"<p><b>Donate:</b> <a href='https://liberapay.com/GoTakeAKnapp/'>Liberapay</a></p>"
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
)
|
2026-01-03 18:59:57 -08:00
|
|
|
about_box.setStandardButtons(QMessageBox.Ok)
|
|
|
|
|
about_box.exec()
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
|
2026-01-05 19:33:07 -08:00
|
|
|
def show_settings(self):
|
|
|
|
|
"""Show settings dialog."""
|
|
|
|
|
from .settings_dialog import SettingsDialog
|
|
|
|
|
dialog = SettingsDialog(self.settings_manager, parent=self)
|
|
|
|
|
dialog.relay_settings_changed.connect(self.on_relay_settings_changed)
|
|
|
|
|
dialog.exec_()
|
|
|
|
|
|
|
|
|
|
def on_relay_settings_changed(self):
|
|
|
|
|
"""Handle relay settings changes."""
|
|
|
|
|
# Stop existing relay client if running
|
|
|
|
|
self.stop_relay_client()
|
|
|
|
|
|
|
|
|
|
# Start new relay client if enabled
|
|
|
|
|
if self.settings_manager.get_relay_enabled():
|
|
|
|
|
self.start_relay_client()
|
|
|
|
|
|
|
|
|
|
# Update IP label to show relay URL if connected
|
|
|
|
|
self.update_ip_label()
|
|
|
|
|
|
|
|
|
|
def start_relay_client(self):
|
|
|
|
|
"""Start the relay client in a background thread."""
|
|
|
|
|
try:
|
|
|
|
|
from relay_client import RelayClient
|
|
|
|
|
except ImportError:
|
|
|
|
|
self.status_bar.showMessage("Relay client not available", 3000)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
url = self.settings_manager.get_relay_url()
|
|
|
|
|
password = self.settings_manager.get_relay_password()
|
|
|
|
|
session_id = self.settings_manager.get_relay_session_id()
|
|
|
|
|
|
|
|
|
|
if not url or not password:
|
|
|
|
|
self.status_bar.showMessage("Relay not configured", 3000)
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
self.relay_client = RelayClient(
|
|
|
|
|
relay_url=url,
|
|
|
|
|
password=password,
|
|
|
|
|
session_id=session_id,
|
|
|
|
|
local_port=DEFAULT_PORT,
|
|
|
|
|
on_connected=self.on_relay_connected,
|
|
|
|
|
on_disconnected=self.on_relay_disconnected,
|
|
|
|
|
on_session_id=self.on_relay_session_id
|
|
|
|
|
)
|
|
|
|
|
self.relay_client.start()
|
|
|
|
|
self.status_bar.showMessage("Connecting to relay server...")
|
|
|
|
|
|
|
|
|
|
def stop_relay_client(self):
|
|
|
|
|
"""Stop the relay client."""
|
|
|
|
|
if self.relay_client:
|
|
|
|
|
self.relay_client.stop()
|
|
|
|
|
self.relay_client = None
|
|
|
|
|
self.status_bar.showMessage("Relay disconnected", 2000)
|
|
|
|
|
|
|
|
|
|
def on_relay_connected(self):
|
|
|
|
|
"""Handle relay connection established."""
|
|
|
|
|
QTimer.singleShot(0, lambda: self._update_relay_status(True))
|
|
|
|
|
|
|
|
|
|
def on_relay_disconnected(self):
|
|
|
|
|
"""Handle relay disconnection."""
|
|
|
|
|
QTimer.singleShot(0, lambda: self._update_relay_status(False))
|
|
|
|
|
|
|
|
|
|
def on_relay_session_id(self, session_id: str):
|
|
|
|
|
"""Handle receiving session ID from relay."""
|
|
|
|
|
self.settings_manager.set_relay_session_id(session_id)
|
|
|
|
|
QTimer.singleShot(0, self.update_ip_label)
|
|
|
|
|
|
|
|
|
|
def _update_relay_status(self, connected: bool):
|
|
|
|
|
"""Update UI for relay status (called on main thread)."""
|
|
|
|
|
if connected:
|
|
|
|
|
self.status_bar.showMessage("Connected to relay server")
|
|
|
|
|
else:
|
|
|
|
|
self.status_bar.showMessage("Relay disconnected - reconnecting...")
|
|
|
|
|
self.update_ip_label()
|
|
|
|
|
|
|
|
|
|
# Windows startup management
|
|
|
|
|
def get_startup_enabled(self) -> bool:
|
|
|
|
|
"""Check if app is set to start on Windows startup."""
|
|
|
|
|
if sys.platform != 'win32':
|
|
|
|
|
return False
|
|
|
|
|
try:
|
|
|
|
|
key = winreg.OpenKey(
|
|
|
|
|
winreg.HKEY_CURRENT_USER,
|
|
|
|
|
r"Software\Microsoft\Windows\CurrentVersion\Run",
|
|
|
|
|
0, winreg.KEY_READ
|
|
|
|
|
)
|
|
|
|
|
try:
|
|
|
|
|
winreg.QueryValueEx(key, "MacroPad Server")
|
|
|
|
|
return True
|
|
|
|
|
except FileNotFoundError:
|
|
|
|
|
return False
|
|
|
|
|
finally:
|
|
|
|
|
winreg.CloseKey(key)
|
|
|
|
|
except Exception:
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def set_startup_enabled(self, enabled: bool):
|
|
|
|
|
"""Enable or disable starting on Windows startup."""
|
|
|
|
|
if sys.platform != 'win32':
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
key = winreg.OpenKey(
|
|
|
|
|
winreg.HKEY_CURRENT_USER,
|
|
|
|
|
r"Software\Microsoft\Windows\CurrentVersion\Run",
|
|
|
|
|
0, winreg.KEY_SET_VALUE
|
|
|
|
|
)
|
|
|
|
|
try:
|
|
|
|
|
if enabled:
|
|
|
|
|
# Get the executable path
|
|
|
|
|
if getattr(sys, 'frozen', False):
|
|
|
|
|
# Running as compiled executable
|
|
|
|
|
exe_path = sys.executable
|
|
|
|
|
else:
|
|
|
|
|
# Running as script - use pythonw to avoid console
|
|
|
|
|
exe_path = f'"{sys.executable}" "{os.path.abspath(sys.argv[0])}"'
|
|
|
|
|
|
|
|
|
|
winreg.SetValueEx(key, "MacroPad Server", 0, winreg.REG_SZ, exe_path)
|
|
|
|
|
self.status_bar.showMessage("Added to Windows startup", 3000)
|
|
|
|
|
else:
|
|
|
|
|
try:
|
|
|
|
|
winreg.DeleteValue(key, "MacroPad Server")
|
|
|
|
|
self.status_bar.showMessage("Removed from Windows startup", 3000)
|
|
|
|
|
except FileNotFoundError:
|
|
|
|
|
pass
|
|
|
|
|
finally:
|
|
|
|
|
winreg.CloseKey(key)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
QMessageBox.warning(self, "Error", f"Failed to update startup settings: {e}")
|
|
|
|
|
|
|
|
|
|
def toggle_startup(self):
|
|
|
|
|
"""Toggle the startup setting."""
|
|
|
|
|
current = self.get_startup_enabled()
|
|
|
|
|
self.set_startup_enabled(not current)
|
|
|
|
|
# Update menu checkmark
|
|
|
|
|
if hasattr(self, 'startup_action'):
|
|
|
|
|
self.startup_action.setChecked(not current)
|
|
|
|
|
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
def closeEvent(self, event):
|
|
|
|
|
"""Handle window close."""
|
2026-01-05 19:33:07 -08:00
|
|
|
# Stop the relay client
|
|
|
|
|
self.stop_relay_client()
|
|
|
|
|
|
2026-01-03 17:15:38 -08:00
|
|
|
# Stop the web server
|
|
|
|
|
self.stop_server()
|
|
|
|
|
|
|
|
|
|
# Hide tray icon
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
self.tray_icon.hide()
|
2026-01-03 17:15:38 -08:00
|
|
|
|
Modernize application to v0.9.0 with PySide6, FastAPI, and PWA support
## Major Changes
### Build System
- Replace requirements.txt with pyproject.toml for modern dependency management
- Support for uv package manager alongside pip
- Update PyInstaller spec files for new dependencies and structure
### Desktop GUI (Tkinter → PySide6)
- Complete rewrite of UI using PySide6/Qt6
- New modular structure in gui/ directory:
- main_window.py: Main application window
- macro_editor.py: Macro creation/editing dialog
- command_builder.py: Visual command sequence builder
- Modern dark theme with consistent styling
- System tray integration
### Web Server (Flask → FastAPI)
- Migrate from Flask/Waitress to FastAPI/Uvicorn
- Add WebSocket support for real-time updates
- Full CRUD API for macro management
- Image upload endpoint
### Web Interface → PWA
- New web/ directory with standalone static files
- PWA manifest and service worker for installability
- Offline caching support
- Full macro editing from web interface
- Responsive mobile-first design
- Command builder UI matching desktop functionality
### Macro System Enhancement
- New command sequence model replacing simple text/app types
- Command types: text, key, hotkey, wait, app
- Support for delays between commands (wait in ms)
- Support for key presses between commands (enter, tab, etc.)
- Automatic migration of existing macros to new format
- Backward compatibility maintained
### Files Added
- pyproject.toml
- gui/__init__.py, main_window.py, macro_editor.py, command_builder.py
- gui/widgets/__init__.py
- web/index.html, manifest.json, service-worker.js
- web/css/styles.css, web/js/app.js
- web/icons/icon-192.png, icon-512.png
### Files Removed
- requirements.txt (replaced by pyproject.toml)
- ui_components.py (replaced by gui/ modules)
- web_templates.py (replaced by web/ static files)
- main.spec (consolidated into platform-specific specs)
### Files Modified
- main.py: Simplified entry point for PySide6
- macro_manager.py: Command sequence model and migration
- web_server.py: FastAPI implementation
- config.py: Version bump to 0.9.0
- All .spec files: Updated for PySide6 and new structure
- README.md: Complete rewrite for v0.9.0
- .gitea/workflows/release.yml: Disabled pending build testing
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 16:57:14 -08:00
|
|
|
event.accept()
|
|
|
|
|
|
|
|
|
|
def resizeEvent(self, event):
|
|
|
|
|
"""Handle window resize."""
|
|
|
|
|
super().resizeEvent(event)
|
|
|
|
|
self.refresh_macros()
|
2026-01-05 19:33:07 -08:00
|
|
|
|
|
|
|
|
def changeEvent(self, event):
|
|
|
|
|
"""Handle window state changes - minimize to tray."""
|
|
|
|
|
if event.type() == QEvent.Type.WindowStateChange:
|
|
|
|
|
if self.windowState() & Qt.WindowMinimized:
|
|
|
|
|
# Hide instead of minimize (goes to tray)
|
|
|
|
|
event.ignore()
|
|
|
|
|
self.hide()
|
|
|
|
|
self.tray_icon.showMessage(
|
|
|
|
|
"MacroPad Server",
|
|
|
|
|
"Running in system tray. Double-click to restore.",
|
|
|
|
|
QSystemTrayIcon.Information,
|
|
|
|
|
2000
|
|
|
|
|
)
|
|
|
|
|
return
|
|
|
|
|
super().changeEvent(event)
|