Fix favicon icons by converting to RGBA PNG refine README
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
<h1 align="center">deskify</h1>
|
||||
|
||||
<p align="center">
|
||||
<b>A blazing fast, lightweight Nativefier alternative written in Rust & Tauri.</b><br>
|
||||
Instantly turn any website or web app into a native, standalone Linux desktop application.
|
||||
<b>Turn websites into first-class Linux desktop applications with Rust, Tauri, and the system WebView.</b><br>
|
||||
Build native-feeling, standalone web app wrappers with CLI-first Linux integration.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
@@ -35,7 +35,7 @@ The comparison below is intentionally rough and practical (not benchmark marketi
|
||||
| Electron / Nativefier | Bundled Chromium per app | Good | Low to medium | Per-app process, app-bundled runtime | Easy to medium | Depends on the site |
|
||||
| PWA | Browser runtime | Limited / browser-dependent | Low | Shared browser context | Very easy | Depends on browser + site |
|
||||
| Flatpak web app models | Sandbox-oriented runtime model | Good | Limited | Strong sandbox model | Medium | Depends on runtime + site |
|
||||
| **Deskify** | System WebView | Native (`.desktop`, icons, WMClass) | **High (CLI-first)** | Medium (system webview model) | Medium (Tauri prerequisites) | Depends on the site |
|
||||
| **Deskify** | System WebView | Native (`.desktop`, icons, WMClass) | **High (CLI-first)** | Medium (shared system WebView security model) | Medium (Tauri prerequisites) | Depends on the site |
|
||||
|
||||
### Deskify Focus (Today)
|
||||
|
||||
@@ -119,7 +119,7 @@ The table above covers the technical tradeoffs in more detail. In practice, `des
|
||||
- a system-WebView-based runtime model instead of shipping a bundled browser per app
|
||||
|
||||
### Key Features
|
||||
- **Extremely Lightweight:** Generated binaries are tiny (~4-6 MB) and RAM consumption is minimal.
|
||||
- **System-WebView Runtime Model:** Generated wrappers stay small because Deskify relies on the system WebView instead of bundling a browser runtime per app.
|
||||
- **Automatic Icon Fetching:** Scrapes high-quality 128x128 favicons automatically using the Google Favicon API.
|
||||
- **XDG-Compliant System Integration:** Safely creates `.desktop` entries in `~/.local/share/applications` and manages application icons in `~/.local/share/icons/hicolor/`.
|
||||
- **Wayland/X11 Ready:** Perfectly binds `StartupWMClass` to ensure your DE groups the app exactly to its custom icon (no generic gear icons in GNOME/KDE taskbars).
|
||||
|
||||
22
src/main.rs
22
src/main.rs
@@ -1,6 +1,7 @@
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use clap::{Parser, Subcommand};
|
||||
use directories::BaseDirs;
|
||||
use image::{DynamicImage, ImageFormat};
|
||||
use regex::Regex;
|
||||
use serde_json::{Map, Value, json};
|
||||
use std::fs;
|
||||
@@ -92,6 +93,16 @@ fn is_deskify_desktop_entry(content: &str) -> bool {
|
||||
&& (content.contains(".local/bin/") || content.contains("deskify")))
|
||||
}
|
||||
|
||||
fn write_rgba_png(img: DynamicImage, output_path: &Path) -> Result<()> {
|
||||
// Tauri expects PNG icons in RGBA format; many favicons are palette/LA/ICO etc.
|
||||
let rgba = img.to_rgba8();
|
||||
let rgba_img = DynamicImage::ImageRgba8(rgba);
|
||||
rgba_img
|
||||
.save_with_format(output_path, ImageFormat::Png)
|
||||
.with_context(|| format!("Failed to write RGBA PNG icon to {}", output_path.display()))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fetch_or_create_icon(
|
||||
website_url: &str,
|
||||
custom_icon: Option<&String>,
|
||||
@@ -99,8 +110,9 @@ fn fetch_or_create_icon(
|
||||
) -> Result<()> {
|
||||
if let Some(icon_path) = custom_icon {
|
||||
if Path::new(icon_path).exists() {
|
||||
fs::copy(icon_path, output_path)
|
||||
.with_context(|| format!("Failed to copy custom icon from {}", icon_path))?;
|
||||
let img = image::open(icon_path)
|
||||
.with_context(|| format!("Failed to read custom icon image from {}", icon_path))?;
|
||||
write_rgba_png(img, output_path)?;
|
||||
return Ok(());
|
||||
} else {
|
||||
eprintln!(
|
||||
@@ -118,8 +130,12 @@ fn fetch_or_create_icon(
|
||||
if let Ok(response) = ureq::get(&api_url).call() {
|
||||
let mut bytes = Vec::new();
|
||||
if response.into_reader().read_to_end(&mut bytes).is_ok() && !bytes.is_empty() {
|
||||
fs::write(output_path, bytes).context("Failed to write downloaded icon to disk")?;
|
||||
if let Ok(img) = image::load_from_memory(&bytes) {
|
||||
write_rgba_png(img, output_path)?;
|
||||
return Ok(());
|
||||
} else {
|
||||
eprintln!("Warning: Downloaded favicon could not be decoded as an image, falling back to dummy icon.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user