Atajos, y una sola definición de cada acción
El mismo comando en el menú, en un botón y en un atajo, definido una vez. Los atajos que cada sistema reserva, y por qué las teclas no son las mismas en todas partes.
Una definición por acción
pub enum Accion { NuevoProyecto, Guardar, Buscar, Borrar, Preferencias }impl Accion { fn titulo(&self) -> &str { /* … */ } fn atajo(&self) -> Option<&str> { /* … */ } fn disponible(&self, estado: &Estado) -> bool { /* … */ } async fn ejecutar(&self, app: &AppHandle) -> Result<(), Error> { /* … */ }}Con eso:
- El menú se construye recorriendo el enumerado, tomando título, atajo y disponibilidad de la propia acción.
- El menú contextual también.
- Los botones del frontend llaman a un comando que recibe la acción, y le preguntan al core si está disponible para pintarse activos o no.
- Y añadir una acción nueva es una variante más: aparece en los tres sitios sin tocarlos.
La cuarta propiedad es la que evita la divergencia: disponible se define una vez y la respetan el menú, el botón y el atajo.
Los atajos que no se pueden usar
Y la regla que resume la tabla: no reutilices un atajo conocido para otra cosa. Un usuario que pulsa el de guardar espera guardar; si en tu aplicación hace otra cosa, la primera vez pierde trabajo.
Escribirlos para las tres plataformas
Tauri acepta un modificador especial que se traduce solo: la tecla de comando en macOS y control en el resto. Usarlo evita definir dos veces cada atajo y evita el fallo más común — poner control en macOS, donde no es lo que la gente pulsa.
// una definición, dos comportamientos correctos.accelerator("CmdOrCtrl+S")Y comprobar en las dos plataformas de todos modos, porque hay combinaciones que en una funcionan y en otra las intercepta el sistema.
Dónde se ejecuta la acción
Una decisión con dos respuestas válidas:
Lo que no vale es partir una acción entre los dos: que el menú haga la mitad en el core y emita un evento para la otra mitad produce comportamientos distintos según desde dónde se invoque.
Y los atajos que el frontend captura
Un detalle que produce fallos raros: si tu frontend escucha teclas y el menú también tiene el atajo, los dos pueden reaccionar.
La regla: si un atajo está en el menú, el frontend no debe capturarlo. El menú tiene prioridad y es el que el usuario ve documentado. Y al revés: si el frontend captura algo, que no esté en el menú, o ponlo en el menú y quítalo del frontend.