Ir al contenido

Control de estados del icono en la Menu Bar de macOS

¿Alguna vez has sentido que el icono de tu aplicación en la Menu Bar está muerto? Es frustrante cuando una aplicación trabaja en segundo plano pero no ofrece ninguna señal visual de lo que está pasando. Una interfaz estática hace que el usuario se pregunte si el proceso se detuvo o si realmente está escuchando.

Dar feedback visual inmediato mejora la experiencia y evita que el usuario pierda el hilo de lo que la aplicación está haciendo en cada momento.

  • Acceso al código de la aplicación macOS en apps/macos.
  • Clase AppState para la gestión de estados.
  • AppStateStore para el control de tareas en ejecución.
  • CritterIconRenderer para el renderizado de los componentes del icono.

El icono base se dibuja mediante CritterIconRenderer.makeIcon(blink:legWiggle:earWiggle:earScale:earHoles:). Para gestionar los estados visuales, debes interactuar con las señales internas de la aplicación.

Cuando el detector de voz detecta la palabra de activación, el icono debe reaccionar visualmente. Las orejas escalan a 1.9x y muestran huecos circulares para mejorar la legibilidad.

// Llama a esto cuando se detecte la wake word
AppState.triggerVoiceEars(ttl: nil)
// Detén la animación tras 1 segundo de silencio
// Esto coincide con la ventana de captura de audio
AppState.stopVoiceEars()

Cuando el agente está procesando una tarea (como un WebChat agent), activa el movimiento de “scurry”. Te recomiendo usar un bloque defer para evitar que la animación se quede atascada si el proceso falla.

// Activa el movimiento rápido de patas
AppStateStore.shared.setWorking(true)
defer {
// Asegura que el icono vuelva a la normalidad al terminar
AppStateStore.shared.setWorking(false)
}
// Ejecuta aquí la tarea pesada o el llamado al agente
  • Idle: El icono realiza animaciones normales como parpadeos o sacudidas ocasionales.
  • Paused: El status item utiliza appearsDisabled y se detiene todo movimiento.
  • Scurry: Es un movimiento aditivo. Usa un leg wiggle de hasta 1.0 y un pequeño desplazamiento horizontal mientras el trabajo está en curso.
  • Dimensiones: La imagen template es de 18×18 pt, renderizada en un backing store de Retina de 36×36 px.
  • El icono se queda animando indefinidamente: Esto ocurre si no se resetea el estado tras una tarea. Usa siempre bloques defer para llamar a setWorking(false) y mantén los TTL (Time To Live) por debajo de los 10 segundos.
  • Las orejas no cambian de tamaño: Verifica que no estés intentando activar este estado mediante un CLI externo. El sistema está diseñado para responder únicamente a señales internas de la aplicación para evitar parpadeos accidentales.

Si tienes dudas sobre cómo integrar estos estados en tu flujo de trabajo, consulta al AI Setup Assistant.

  • Documentación de CritterIconRenderer
  • Integración de WebChat agent
OpenClaw

OpenClaw Expert

Sigues atascado?

Si esta pagina no resolvio tu caso, pregunta a OpenClaw Expert para pasos concretos.