Arquitectura General | vasak-desktop

Visión general de la arquitectura de Vasak Desktop y cómo se estructuran los componentes.

¿Qué es Vasak Desktop?

Vasak Desktop NO es un entorno de escritorio completo (como GNOME o KDE). Es una interfaz de escritorio ligera que no cuenta con un WM propio pero que proporciona:

  • Panel Superior - Barra de tareas con applets de sistema
  • Vista de Escritorio - Fondo con widgets opcionales
  • Control Center - Acceso rápido a configuración
  • Menú de Aplicaciones - Búsqueda y lanzamiento de apps
  • File Manager - Herramienta para revisar archivos
  • Search Launcher - Herramienta de busqueda rapida
  • Config Manager - Herramienta de configuracion del sistema operativo

Se ejecuta como varias ventanas de Tauri independientes que se comunican vía IPC.

El resto de herramientas de VasakOS que no comparten el Backend con el desktop comparten una arquitectura similar y pueden integrarse de la misma manera con las configuraciones del desktop

Arquitectura de Alto Nivel

graph TD User["👤 USUARIO FINAL"] Panel["🪟 Ventana PANEL
(Top Bar)"] Desktop["🖥️ Ventana DESKTOP
(Background)"] Frontend["🎨 Frontend Vue.js
(TypeScript + CSS)"] IPC["🔗 IPC Tauri Bridge
(Frontend ↔ Backend)"] Backend["⚙️ Backend Rust
- Comandos de sistema
- Integración D-Bus
- Gestión de ventanas"] DBus["🔌 D-Bus
(IPC)"] GTK["🎭 GTK
(Theme)"] System["📁 System
(FS/IO)"] Services["🔧 Servicios del Sistema
(PulseAudio, NetworkManager,
BlueZ, MPRIS, gsettings...)"] User --> Panel User --> Desktop Panel --> Frontend Desktop --> Frontend Frontend --> IPC IPC --> Backend Backend --> DBus Backend --> GTK Backend --> System DBus --> Services style User fill:#e1f5ff style Panel fill:#fff3e0 style Desktop fill:#fff3e0 style Frontend fill:#f3e5f5 style IPC fill:#ffe0b2 style Backend fill:#c8e6c9 style DBus fill:#ffccbc style GTK fill:#ffccbc style System fill:#ffccbc style Services fill:#b3e5fc

Ventanas de la Aplicación

Vasak Desktop se compone de 2 ventanas independientes:

Ventana 1: Panel (Top Bar)

1
2
3
4
5
6
7
8
9
{
  "label": "panel",
  "title": "Vasak Panel",
  "width": [ancho de pantalla],
  "height": 40,
  "y": 0,
  "decorations": false,
  "alwaysOnTop": true
}

Muestra:

  • Menú de aplicaciones
  • Widgets (reloj, música)
  • Applets de sistema (audio, red, bluetooth, batería)
  • Control center

Ventana 2: Desktop (Background)

1
2
3
4
5
6
7
8
{
  "label": "desktop",
  "title": "Vasak Desktop",
  "fullscreen": true,
  "decorations": false,
  "alwaysOnBottom": true,
  "skipTaskbar": true
}

Muestra:

  • Fondo de escritorio
  • Widgets opcionales (clima, reloj)

Capas de la Aplicación

1. Capa de Presentación (Frontend)

Tecnología: Vue.js 3.5.18, TypeScript, Tailwind CSS 4.1

graph LR Frontend["🎨 Frontend Vue.js
src/"] Frontend --> App["📄 App.vue
Componente raíz"] Frontend --> Main["📄 main.ts
Entry point"] Frontend --> Style["📄 style.css
Estilos globales"] Frontend --> Views["📁 views/
Páginas principales"] Frontend --> Components["📁 components/
Componentes reutilizables"] Frontend --> Routes["📁 routes/
Configuración de rutas"] Frontend --> Tools["📁 tools/
Controllers"] Views --> ViewPanel["📄 PanelView.vue
Ventana panel superior"] Views --> ViewDesktop["📄 DesktopView.vue
Ventana fondo escritorio"] Views --> ViewMenu["📄 MenuView.vue
Vista del menú de apps"] Views --> ViewCC["📄 ControlCenterView.vue
Centro de control"] Components --> CompBtns["📁 buttons/
Botones de interfaz"] Components --> CompCards["📁 cards/
Tarjetas de información"] Components --> CompCtrl["📁 controls/
Controles interactivos"] Components --> CompAreas["📁 areas/
Áreas completas"] CompAreas --> AreaPanel["📁 panel/"] CompAreas --> AreaCC["📁 control-center/"] CompAreas --> AreaMenu["📁 menu/"] Tools --> ToolBat["📄 battery.controller.ts"] Tools --> ToolNet["📄 network.controller.ts"] Tools --> ToolBT["📄 bluetooth.controller.ts"] Tools --> ToolTray["📄 tray.controller.ts"] Routes --> RouteIdx["📄 index.ts"] style Frontend fill:#667eea,stroke:#764ba2,color:#fff style App fill:#f3e5f5,stroke:#ce93d8,color:#000 style Views fill:#4facfe,stroke:#00f2fe,color:#fff style Components fill:#43e97b,stroke:#38f9d7,color:#fff style Routes fill:#feca57,stroke:#ff9a56,color:#fff style Tools fill:#fa709a,stroke:#f5576c,color:#fff style ViewPanel fill:#f3e5f5,stroke:#ce93d8,color:#000 style ViewDesktop fill:#f3e5f5,stroke:#ce93d8,color:#000 style ViewMenu fill:#f3e5f5,stroke:#ce93d8,color:#000 style ViewCC fill:#f3e5f5,stroke:#ce93d8,color:#000

Flujo de Datos:

  • Componentes → invoke('command') → Backend
  • Backend → emit('event') → Componentes actualizan

2. Capa de Comunicación (IPC)

Tecnología: Tauri IPC Bridge

sequenceDiagram participant VueComp as Vue
Component participant Invoke as invoke() participant IPCBridge as IPC Bridge participant BackendCmd as Backend
Command participant DBusService as D-Bus /
System Call participant Result as Resultado VueComp->>Invoke: invoke('get_audio_volume') activate Invoke Invoke->>IPCBridge: envía comando serializado deactivate Invoke activate IPCBridge IPCBridge->>BackendCmd: #64 (Backend Handler) deactivate IPCBridge activate BackendCmd BackendCmd->>DBusService: consulta D-Bus / llamada sistema deactivate BackendCmd activate DBusService DBusService->>Result: obtiene valor (ej: 50%) deactivate DBusService activate Result Result->>IPCBridge: retorna respuesta deactivate Result activate IPCBridge IPCBridge->>VueComp: resolve Promise con resultado deactivate IPCBridge activate VueComp VueComp->>VueComp: actualiza estado local deactivate VueComp Note over VueComp,Result: Solo comandos explícitamente registrados pueden ser invocados

Seguridad: Solo comandos explícitamente registrados pueden ser invocados.

3. Capa de Lógica (Backend)

Tecnología: Rust 1.70+, Tauri 2.x

graph LR Backend["⚙️ Backend Rust
src-tauri/src/"] Backend --> Main["📄 main.rs
Punto de entrada
setup de ventanas
"] Backend --> Lib["📄 lib.rs
Registro de comandos
y módulos
"] Backend --> Structs["📄 structs.rs
Estructuras compartidas"] Backend --> Commands["📁 commands/
Manejadores IPC"] Backend --> WindowMgr["📁 window_manager/
Gestión de ventanas"] Backend --> MonitorMgr["📄 monitor_manager.rs
Gestión de monitores"] Backend --> DBusService["📄 dbus_service.rs
Integración D-Bus"] Backend --> Tray["📁 tray/
Bandeja del sistema"] Backend --> Utils["📁 utils/
Funciones de utilidad"] Commands --> AudioCmd["📄 audio.rs
Control de audio"] Commands --> BluetoothCmd["📄 bluetooth.rs
Control bluetooth"] Commands --> NetworkCmd["📄 network.rs
Control de red"] Commands --> BrightnessCmd["📄 brightness.rs
Control de brillo"] Commands --> NotificationsCmd["📄 notifications.rs
Sistema de notificaciones"] Commands --> ShortcutsCmd["📄 shortcuts.rs
Gestión de atajos"] Commands --> SearchCmd["📄 search.rs
Búsqueda de apps"] Commands --> SystemConfigCmd["📄 system_config.rs
Configuración del SO"] Commands --> ThemeCmd["📄 theme.rs
Temas GTK, iconos"] Commands --> SessionCmd["📄 session.rs
Logout, shutdown, suspend"] WindowMgr --> WinMod["📄 window_controller.rs"] Utils --> UtilShortcuts["📁 shortcuts/"] Utils --> UtilSearch["📁 search/"] style Backend fill:#667eea,stroke:#764ba2,color:#fff style Main fill:#4facfe,stroke:#00f2fe,color:#fff style Lib fill:#4facfe,stroke:#00f2fe,color:#fff style Structs fill:#4facfe,stroke:#00f2fe,color:#fff style Commands fill:#feca57,stroke:#ff9a56,color:#fff style WindowMgr fill:#43e97b,stroke:#38f9d7,color:#fff style MonitorMgr fill:#43e97b,stroke:#38f9d7,color:#fff style DBusService fill:#f093fb,stroke:#f5576c,color:#fff style Tray fill:#fa709a,stroke:#f5576c,color:#fff style Utils fill:#4facfe,stroke:#00f2fe,color:#fff style AudioCmd fill:#43e97b,stroke:#38f9d7,color:#fff style BluetoothCmd fill:#f093fb,stroke:#f5576c,color:#fff style NetworkCmd fill:#fa709a,stroke:#f5576c,color:#fff style BrightnessCmd fill:#feca57,stroke:#ff9a56,color:#fff style NotificationsCmd fill:#43e97b,stroke:#38f9d7,color:#fff style ShortcutsCmd fill:#feca57,stroke:#ff9a56,color:#fff style SearchCmd fill:#feca57,stroke:#ff9a56,color:#fff style SystemConfigCmd fill:#4facfe,stroke:#00f2fe,color:#fff style ThemeCmd fill:#feca57,stroke:#ff9a56,color:#fff style SessionCmd fill:#f093fb,stroke:#f5576c,color:#fff

Responsabilidades del Backend:

  • Ejecutar comandos del sistema vía shell o APIs nativas
  • Comunicar con servicios del sistema vía D-Bus
  • Gestionar eventos de hardware y notificaciones
  • Aplicar configuración del sistema (gsettings, archivos de config)
  • Manejar las ventanas de Tauri

4. Capa de Integración del Sistema (D-Bus)

Tecnología: Zbus (Rust) + D-Bus

Interfaz estándar de Linux para:

  • Control de audio (PulseAudio/PipeWire)
  • Bluetooth (BlueZ)
  • Red (NetworkManager)
  • Notificaciones (Freedesktop)
  • Energía (UPower)

Ver D-Bus para más detalles.

5. Capa de Hardware/SO

Componentes del Sistema:

  • PulseAudio / PipeWire (Audio)
  • BlueZ (Bluetooth)
  • NetworkManager (Red)
  • X11 / Wayland (Ventanas)
  • Compositor (Efectos visuales)

El soporte actual sobre Wayland es EXPERIMENTAL

Flujo de Datos Típico

Ejemplo: Cambiar Volumen

sequenceDiagram participant Usuario participant VueComponent as Vue Component participant PiniaStore as Pinia Store participant BackendHandler as Backend Handler participant IPCBridge as IPC Bridge participant BackendRust as Backend Rust participant SystemOS as Sistema OS participant DBusEvent as D-Bus Event Usuario->>VueComponent: Mueve slider de volumen activate VueComponent VueComponent->>PiniaStore: emit('volume-changed', newValue) activate PiniaStore PiniaStore->>PiniaStore: actualiza estado local deactivate PiniaStore VueComponent->>BackendHandler: invoke('set_audio_volume', {level: 50}) deactivate VueComponent activate BackendHandler BackendHandler->>IPCBridge: envía comando deactivate BackendHandler activate IPCBridge IPCBridge->>BackendRust: ejecuta set_audio_volume deactivate IPCBridge activate BackendRust BackendRust->>SystemOS: pactl set-sink-volume @DEFAULT_SINK@ 50% activate SystemOS SystemOS->>SystemOS: Cambia volumen real deactivate SystemOS SystemOS->>DBusEvent: Emite evento de cambio activate DBusEvent DBusEvent->>BackendRust: Recibe confirmación deactivate DBusEvent deactivate BackendRust BackendRust->>VueComponent: event('audio_volume_changed', newValue) activate VueComponent VueComponent->>Usuario: Refleja el cambio visual deactivate VueComponent

Estructura de Directorios

Frontend (src/)

graph LR Src["📁 src/
Frontend Vue.js"] Src --> AppVue["📄 App.vue
Componente raíz"] Src --> MainTs["📄 main.ts
Entry point"] Src --> StyleCss["📄 style.css
Estilos globales"] Src --> VieDts["📄 vite-env.d.ts
Tipos Vite"] Src --> Assets["📁 assets/
Recursos estáticos"] Src --> Components["📁 components/
Reutilizables"] Src --> Interfaces["📁 interfaces/
Tipos TypeScript"] Src --> Layouts["📁 layouts/
Plantillas"] Src --> Routes["📁 routes/
Enrutamiento"] Src --> Tools["📁 tools/
Controladores"] Src --> Types["📁 types/
Definiciones"] Src --> Views["📁 views/
Páginas principales"] Assets --> AssetsImg["📁 img/"] Assets --> AssetsVec["📁 vectors/"] Components --> CompMenu["📄 SearchMenuComponent.vue"] Components --> CompAreas["📁 areas/"] Components --> CompBtns["📁 buttons/"] Components --> CompCards["📁 cards/"] Components --> CompCtrl["📁 controls/"] Components --> CompIcon["📁 icon/"] Components --> CompWdg["📁 widgets/"] CompAreas --> AreaPanel["📁 panel/"] CompAreas --> AreaCC["📁 control-center/"] CompAreas --> AreaMenu["📁 menu/"] Interfaces --> IfBat["📄 battery.ts"] Interfaces --> IfNot["📄 notifications.ts"] Interfaces --> IfTray["📄 tray.ts"] Layouts --> LayConfig["📄 ConfigAppLayout.vue"] Routes --> RouteIdx["📄 index.ts"] Tools --> ToolBat["📄 battery.controller.ts"] Tools --> ToolBT["📄 bluetooth.controller.ts"] Tools --> ToolNet["📄 network.controller.ts"] Tools --> ToolTray["📄 tray.controller.ts"] Types --> TypeVue["📄 vue-libvasak.d.ts"] Views --> ViewCC["📄 ControlCenterView.vue"] Views --> ViewDsk["📄 DesktopView.vue"] Views --> ViewMnu["📄 MenuView.vue"] Views --> ViewPnl["📄 PanelView.vue"] Views --> ViewApp["📁 applets/"] Views --> ViewApps["📁 apps/"] style Src fill:#667eea,stroke:#764ba2,color:#fff style Components fill:#4facfe,stroke:#00f2fe,color:#fff style Assets fill:#4facfe,stroke:#00f2fe,color:#fff style Interfaces fill:#43e97b,stroke:#38f9d7,color:#fff style Layouts fill:#43e97b,stroke:#38f9d7,color:#fff style Routes fill:#43e97b,stroke:#38f9d7,color:#fff style Tools fill:#feca57,stroke:#ff9a56,color:#fff style Types fill:#fa709a,stroke:#f5576c,color:#fff style Views fill:#f093fb,stroke:#f5576c,color:#fff

Backend (src-tauri/src/)

graph LR SrcTauri["📁 src-tauri/src/
Backend Rust"] SrcTauri --> LibRs["📄 lib.rs
Módulos principales"] SrcTauri --> MainRs["📄 main.rs
Entry point"] SrcTauri --> ErrorRs["📄 error.rs
Manejo de errores"] SrcTauri --> StructRs["📄 structs.rs
Estructuras compartidas"] SrcTauri --> ConstRs["📄 constants.rs
Constantes"] SrcTauri --> Commands["📁 commands/
Comandos IPC"] SrcTauri --> WinMgr["📁 window_manager/
Gestión de ventanas"] SrcTauri --> AudioRs["📄 audio.rs
Control de audio"] SrcTauri --> BrightRs["📄 brightness.rs
Control de brillo"] SrcTauri --> BTRs["📄 bluetooth.rs
Bluetooth control"] SrcTauri --> NetRs["📄 network.rs
Network control"] SrcTauri --> NotifRs["📄 notifications.rs
Sistema notificaciones"] SrcTauri --> DBusRs["📄 dbus_service.rs
D-Bus integration"] SrcTauri --> EventsRs["📄 eventloops.rs
Bucles de eventos"] SrcTauri --> ShortcutsRs["📄 platform_shortcuts.rs
Atajos de teclado"] SrcTauri --> MenuRs["📄 menu_manager.rs
Gestión de menús"] SrcTauri --> Tray["📁 tray/
Bandeja del sistema"] SrcTauri --> Applets["📁 applets/
Mini-aplicaciones"] SrcTauri --> Utils["📁 utils/
Funciones de utilidad"] SrcTauri --> WinApps["📁 windows_apps/
Manejo de aplicaciones"] Commands --> AudioCmd["📄 audio_commands.rs"] Commands --> BTCmd["📄 bluetooth_commands.rs"] Commands --> NetCmd["📄 network_commands.rs"] WinMgr --> ModWin["📄 mod.rs"] WinMgr --> WinCtrl["📄 window_controller.rs"] WinMgr --> MonMgr["📄 monitor_handler.rs"] Tray --> ModTray["📄 mod.rs"] Tray --> TrayIcon["📄 tray_icon.rs"] style SrcTauri fill:#667eea,stroke:#764ba2,color:#fff style Commands fill:#4facfe,stroke:#00f2fe,color:#fff style WinMgr fill:#4facfe,stroke:#00f2fe,color:#fff style Tray fill:#4facfe,stroke:#00f2fe,color:#fff style Utils fill:#4facfe,stroke:#00f2fe,color:#fff style Applets fill:#4facfe,stroke:#00f2fe,color:#fff style WinApps fill:#4facfe,stroke:#00f2fe,color:#fff style AudioRs fill:#43e97b,stroke:#38f9d7,color:#fff style BrightRs fill:#feca57,stroke:#ff9a56,color:#fff style BTRs fill:#f093fb,stroke:#f5576c,color:#fff style NetRs fill:#fa709a,stroke:#f5576c,color:#fff style NotifRs fill:#43e97b,stroke:#38f9d7,color:#fff style DBusRs fill:#f093fb,stroke:#f5576c,color:#fff

Patrones de Diseño

1. MVC (Model-View-Controller)

Frontend:

  • Model: Pinia stores
  • View: Vue components
  • Controller: Métodos en componentes

Backend:

  • Model: Estructuras en structs.rs
  • Controller: Funciones en commands/
  • Business Logic: Módulos especializados

2. Pub-Sub (Publicar-Suscribirse)

Para eventos del sistema:

1
2
// Backend: Emitir evento
window.emit("audio_volume_changed", {level: 50})?;
1
2
3
4
5
6
// Frontend: Escuchar evento
onMounted(() => {
  listen('audio_volume_changed', (event) => {
    state.volume = event.payload.level;
  });
});

3. Service Layer

Cada funcionalidad tiene su capa de servicio:

  • audio.rs - Servicio de audio
  • network.rs - Servicio de red
  • bluetooth.rs - Servicio de Bluetooth

Flujos de Información

Comando (Frontend → Backend)

1
2
3
4
5
6
// Frontend
import { invoke } from '@tauri-apps/api/tauri';

const result = await invoke('set_brightness', { 
  level: 75 
});
1
2
3
4
5
6
// Backend
#[tauri::command]
pub fn set_brightness(level: u32) -> Result<(), String> {
    brightness::set_level(level)?;
    Ok(())
}

Evento (Backend → Frontend)

1
2
3
4
// Backend
window.emit("brightness_changed", json!({
    "level": 75
}))?;
1
2
3
4
5
6
// Frontend
import { listen } from '@tauri-apps/api/event';

listen('brightness_changed', (event) => {
  console.log('Brillo:', event.payload.level);
});

Configuración y Manifiestos

tauri.conf.json

Define permisos y configuración de Tauri:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
  "build": {
    "beforeDevCommand": "bun run dev",
    "devUrl": "http://localhost:5173"
  },
  "app": {
    "windows": [
      {
        "title": "Vasak Desktop",
        "label": "main",
        "width": 1024,
        "height": 768
      }
    ]
  }
}

Cargo.toml

Dependencias y configuración de Rust.

tsconfig.json

Configuración de TypeScript.

vite.config.ts

Configuración de build del frontend.

Vasak group © Todos los derechos reservados