La ventana que hizo la llamada
Recibir la ventana origen en vez de su etiqueta: qué se puede hacer con ella, cómo se usa para dirigir una respuesta, y por qué en una aplicación con varias ventanas es la diferencia entre un comando correcto y uno que se puede engañar.
Recibirla
#[tauri::command]async fn cerrar_y_avisar(window: tauri::WebviewWindow) -> Result<(), ErrorPayload> { // La etiqueta la sabe el framework, no el frontend let quien = window.label().to_string(); println!("cerrando {quien}"); Ok(window.close()?)}window.label() es lo que hace útil el argumento: la identidad de quien llamó, en un dato en el que se puede confiar. Todo lo demás —cerrar, enfocar, redimensionar, emitir— es la API del nivel 11.1 aplicada a esa ventana concreta.
Dirigir un evento a quien preguntó
Es el uso que resuelve un problema real. Imagina un comando largo que informa de su progreso:
#[tauri::command]async fn indexar(window: tauri::WebviewWindow) -> Result<(), ErrorPayload> { let w = window.clone(); tauri::async_runtime::spawn(async move { for (hechos, total) in indexar_todo().await { // solo a quien lo pidió, no a todas las ventanas let _ = w.emit("indexado-progreso", (hechos, total)); } }); Ok(())}Si emitieras a todas —lo que hace el manejador de la aplicación— la ventana de ajustes recibiría el progreso de un indexado que no pidió, y tendría que filtrarlo. Emitir a la ventana origen resuelve el reparto sin que nadie tenga que filtrar nada.
Y el caso simétrico del nivel 15.5: cuando el cambio sí le importa a todas, se emite a todas menos a la que llamó, porque esa ya tiene la respuesta y repintaría dos veces. La etiqueta de la ventana origen es lo que permite hacer esa exclusión:
#[tauri::command]async fn marcar_resuelto( app: tauri::AppHandle, window: tauri::WebviewWindow, id: ProblemaId,) -> Result<ProblemaResumen, ErrorPayload> { let p = logica::marcar(id).await?; let resumen = ProblemaResumen::de(p); // a todas menos a la que llamó: esa recibe el valor de retorno for (etiqueta, w) in app.webview_windows() { if etiqueta != window.label() { let _ = w.emit("problema-cambiado", &resumen); } } Ok(resumen)}Usar la etiqueta para decidir
Como la etiqueta es de confianza, se puede usar para que un comando se comporte distinto según desde dónde se llame:
#[tauri::command]async fn guardar_ajustes(window: tauri::WebviewWindow, a: Ajustes) -> Result<(), ErrorPayload> { // solo la ventana de ajustes puede escribir ajustes if window.label() != "settings" { return Err(ErrorPayload::prohibido("este comando no es de esta ventana")); } logica::guardar_ajustes(a).await?; Ok(())}Es una comprobación defensiva y merece una precisión honesta: no es el mecanismo principal para eso. La forma correcta de limitar qué ventana puede invocar qué es la capability, que apunta a ventanas por su etiqueta y se comprueba en el tramo 4 del recorrido, antes de que tu código exista. La comprobación en el comando es un cinturón adicional, útil cuando la lógica depende del origen de forma más fina que un permiso.