@vasakgroup/plugin-vicons
v2.1.2
Published
Icon API for Tauri plugins (Created for VasakOS)
Maintainers
Readme
Tauri Plugin vicons
Obtiene íconos nativos del sistema Linux (GTK) como base64, listos para usar en cualquier elemento <img>. Soporta temas de iconos del sistema, cacheo automático, y detección de cambios de tema en vivo.
Requisitos
- Rust 1.80.0+
- Tauri v2
- Linux con GTK 3 (entornos GNOME, KDE, Xfce, etc.)
Instalación
1. Agregar el crate Rust
[dependencies]
tauri-plugin-vicons = { git = "https://github.com/Vasak-OS/tauri-plugin-vicons", branch = "v2" }2. Registrar el plugin en lib.rs
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_vicons::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}3. Agregar el paquete JS (opcional)
bun add @vasakgroup/plugin-vicons4. Configurar permisos
En src-tauri/capabilities/default.json:
{
"permissions": [
"vicons:default"
]
}API
Comandos Rust
| Comando | Descripción | Retorno |
|-------------|------------------------------------------------|--------------------------|
| get_icon | Obtiene un icono regular por nombre o ruta | String (base64) |
| get_symbol| Obtiene un icono simbólico por nombre o ruta | String (base64) |
Ambos aceptan un solo argumento name: &str. Si es una ruta de archivo válida, leen el archivo directamente. Si es un nombre de icono GTK, lo buscan en el tema de iconos del sistema.
Eventos emitidos
| Evento | Cuándo se emite | Payload |
|---------------------------|------------------------------------------|---------|
| vicons:theme-changed | El tema de iconos del sistema cambió | null |
Escucharlo desde el frontend:
import { listen } from "@tauri-apps/api/event";
await listen("vicons:theme-changed", () => {
// recargar íconos, refrescar UI, etc.
});Funciones JS (guest-js)
| Función | Descripción | Retorno |
|-------------------|-----------------------------------------------------------------|------------------------|
| getIconSource | Obtiene un data URI completo listo para <img src> | string |
| getSymbolSource | Igual que getIconSource pero con iconos simbólicos | string |
| getIcon | Obtiene solo el base64 de un icono regular (sin data URI) | Promise<string> |
| getSymbol | Obtiene solo el base64 de un icono simbólico (sin data URI) | Promise<string> |
getIconSource y getSymbolSource detectan automáticamente el tipo MIME del icono (PNG, JPEG, GIF, WebP, BMP, SVG) mediante magic bytes.
Uso
Básico
import { getIconSource } from '@vasakgroup/plugin-vicons';
const icon = await getIconSource('folder');
// → "data:image/svg+xml;base64,PHN2ZyB4bWxucz0..."Con Vue
<script setup lang="ts">
import { getIconSource } from '@vasakgroup/plugin-vicons';
import { ref, onMounted } from 'vue';
const icon = ref('');
onMounted(async () => {
icon.value = await getIconSource('folder');
});
</script>
<template>
<img :src="icon" alt="folder" />
</template>Con React
import { getIconSource } from '@vasakgroup/plugin-vicons';
import { useEffect, useState } from 'react';
function FolderIcon() {
const [src, setSrc] = useState('');
useEffect(() => {
getIconSource('folder').then(setSrc);
}, []);
return <img src={src} alt="folder" />;
}Ruta de archivo directa
Si pasás una ruta de archivo existente, se lee directamente sin pasar por el tema GTK:
const icon = await getIconSource('/usr/share/icons/hicolor/48x48/apps/firefox.png');Escuchar cambios de tema
El plugin detecta automáticamente cambios en el tema de iconos del sistema (a través de la señal changed de GTK) y emite un evento:
import { listen } from "@tauri-apps/api/event";
import { getIconSource } from '@vasakgroup/plugin-vicons';
listen("vicons:theme-changed", async () => {
console.log("Theme changed, refreshing icons...");
const icon = await getIconSource('folder');
// actualizar UI con el nuevo icono
});Arquitectura
flowchart TB
subgraph Frontend
A[getIconSource / getSymbolSource] --> B[getIconType<br/>magic bytes PNG/JPEG/GIF/WebP/BMP/SVG]
C[listen 'vicons:theme-changed']
end
subgraph Backend
D[get_icon_impl / get_symbol_impl] --> E{¿ruta válida?}
E -->|sí| F[leer archivo]
E -->|no| G[buscar en GTK IconTheme]
G --> H{¿cache hit?}
H -->|sí + vigente| I[devolver cache]
H -->|no o expirado| J[GTK lookup → base64 → guardar cache]
end
subgraph ThemeMonitor
K[init_theme_monitor] --> L[connect_changed GTK signal]
L --> M[clear_cache_internal]
M --> N[emit 'vicons:theme-changed']
end
A --> D
N -.->|Tauri event| CCache
- Dos cachés separadas:
ICON_CACHEySYMBOL_CACHE(HashMap<String, CacheEntry>). - Cada entrada expira después de 30 minutos.
- Al cambiar el tema de iconos del sistema, ambos cachés se limpian por completo.
- La caché usa
std::sync::LazyLockystd::sync::Mutex(sin dependencias externas).
Detección de cambios de tema
GTK monitorea internamente los cambios de tema mediante:
- GSettings (
org.gnome.desktop.interface icon-theme) - inotify sobre
~/.config/gtk-3.0/settings.ini - XDG Desktop Portal
Cuando detecta un cambio, dispara la señal changed del IconTheme. El plugin la captura, limpia la caché, y emite vicons:theme-changed al frontend.
Logging
El plugin escribe logs en {app_data_dir}/logs/icons.log con niveles INFO, WARN y ERROR. Sin dependencias externas de logging — usa std::io::LineWriter directo a archivo.
Errores
| Error | Causa |
|---------------------|---------------------------------------------|
| IconNotFound | El nombre solicitado no existe en el tema |
| ThemeMonitorError | No se pudo inicializar el monitor de tema |
| Io | Error de lectura de archivo |
Dependencias
Solo 5 crates además de Tauri:
| Crate | Propósito |
|------------|-------------------------------|
| serde | Serialización |
| thiserror| Errores tipados |
| gtk | Acceso al theme de iconos GTK |
| glib | Bindings de GLib (con GTK) |
| base64 | Codificación base64 |
Licencia
GPLv3 — Vasak Group
