-
Notifications
You must be signed in to change notification settings - Fork 0
Fix Windows system tray and add macOS ICNS icon support #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
94aa8bd
5836f4f
f11a457
6ffb231
8a5cc30
32769d3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -3,6 +3,11 @@ | |||||
|
|
||||||
| from PIL import Image, ImageEnhance | ||||||
| from pathlib import Path | ||||||
| try: | ||||||
| from icnsutil import IcnsFile | ||||||
| ICNS_AVAILABLE = True | ||||||
| except ImportError: | ||||||
| ICNS_AVAILABLE = False | ||||||
|
|
||||||
|
|
||||||
| def make_transparent(image, *, background=(255, 255, 255), alpha_power=1.0, alpha_floor=6): | ||||||
|
|
@@ -88,17 +93,19 @@ def main(): | |||||
| print(f" ✓ Saved {original_processed_path}") | ||||||
|
|
||||||
| # Generate icons at different sizes | ||||||
| sizes = { | ||||||
| "icon.png": 256, | ||||||
| "icon_256.png": 256, | ||||||
| "icon_128.png": 128, | ||||||
| "icon_64.png": 64, | ||||||
| "icon_48.png": 48, | ||||||
| "icon_32.png": 32, | ||||||
| "icon_16.png": 16, | ||||||
| } | ||||||
| sizes = [ | ||||||
| ("icon.png", 256), | ||||||
| ("icon_256.png", 256), | ||||||
| ("icon_128.png", 128), | ||||||
| ("icon_64.png", 64), | ||||||
| ("icon_48.png", 48), | ||||||
| ("icon_32.png", 32), | ||||||
| ("icon_16.png", 16), | ||||||
| ] | ||||||
|
|
||||||
| for filename, size in sizes.items(): | ||||||
| # Process all icon sizes and save as PNG files | ||||||
| icon_sizes_for_ico = {} | ||||||
|
||||||
| for filename, size in sizes: | ||||||
| output_path = icons_dir / filename | ||||||
| print(f"Generating {filename} ({size}x{size})...") | ||||||
|
|
||||||
|
|
@@ -108,6 +115,76 @@ def main(): | |||||
| # Save as PNG with transparency | ||||||
| resized.save(output_path, "PNG", optimize=True) | ||||||
| print(f" ✓ Saved {output_path}") | ||||||
|
|
||||||
| # Collect images for ICO file (avoid duplicates) | ||||||
|
||||||
| # Collect images for ICO file (avoid duplicates) | |
| # Track unique icon sizes for the ICO file (skip duplicate sizes in the sizes list) |
Copilot
AI
Dec 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The temporary PNG files created for ICNS generation are immediately deleted after being added to the ICNS file. However, if an exception occurs between saving the temp file and unlinking it (e.g., in the icns.add_media() call), the temp file will not be cleaned up. Consider using a try-finally block or context manager to ensure cleanup, or use a temporary directory that's automatically cleaned up.
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -49,7 +49,8 @@ def __init__(self, on_show: Optional[Callable] = None, | |||||||
|
|
||||||||
| async def setup(self): | ||||||||
| """Setup the tray icon using Windows Shell NotifyIcon.""" | ||||||||
| icon_path = ICON_DIR / "icon.png" | ||||||||
| # Use ICO file for Windows (supports multiple resolutions) | ||||||||
|
||||||||
| # Use ICO file for Windows (supports multiple resolutions) | |
| # Use ICO file for Windows: LoadImage cannot load PNG files as ICOs, | |
| # and this limitation previously caused a bug when using a PNG icon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The build script has a complex ternary expression that's difficult to read and maintain. Consider breaking this into multiple lines or using if-elif-else logic for better readability. For example:
Then use
icon_argin the list.