Skip to main content
Glama
list_windows.rs5.1 kB
//! Window listing and discovery. use serde::Serialize; use serde_json::Value; use tauri::{command, AppHandle, Manager, Runtime}; /// Information about a webview window. #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] pub struct WindowInfo { /// The unique label/identifier for this window pub label: String, /// The window title (if available) pub title: Option<String>, /// The current URL loaded in the webview (if available) pub url: Option<String>, /// Whether this window currently has focus pub focused: bool, /// Whether this window is visible pub visible: bool, /// Whether this is the main window (label == "main") pub is_main: bool, } /// Lists all open webview windows in the application. /// /// Returns detailed information about each window including its label, title, /// URL, focus state, and visibility. /// /// # Arguments /// /// * `app` - The Tauri application handle /// /// # Returns /// /// * `Ok(Value)` - JSON array of WindowInfo objects /// * `Err(String)` - Error message if retrieval fails /// /// # Examples /// /// ```typescript /// import { invoke } from '@tauri-apps/api/core'; /// /// const windows = await invoke('plugin:mcp-bridge|list_windows'); /// console.log(`Found ${windows.length} windows`); /// ``` #[command] pub async fn list_windows<R: Runtime>(app: AppHandle<R>) -> Result<Value, String> { let windows = app.webview_windows(); let mut window_list: Vec<WindowInfo> = Vec::new(); for (label, window) in windows.iter() { let title = window.title().ok(); let url = window.url().ok().map(|u| u.to_string()); let focused = window.is_focused().unwrap_or(false); let visible = window.is_visible().unwrap_or(false); let is_main = label == "main"; window_list.push(WindowInfo { label: label.clone(), title, url, focused, visible, is_main, }); } // Sort by label for consistent ordering, with "main" first window_list.sort_by(|a, b| { if a.is_main { std::cmp::Ordering::Less } else if b.is_main { std::cmp::Ordering::Greater } else { a.label.cmp(&b.label) } }); serde_json::to_value(&window_list).map_err(|e| format!("Failed to serialize windows: {e}")) } /// Context about which window was used for an operation. #[derive(Debug, Clone, Serialize)] #[serde(rename_all = "camelCase")] pub struct WindowContext { /// The label of the window that was used pub window_label: String, /// Total number of windows available pub total_windows: usize, /// Warning message if multiple windows exist but none was specified pub warning: Option<String>, } /// Result of resolving a window, including context information. pub struct ResolvedWindow<R: Runtime> { pub window: tauri::WebviewWindow<R>, pub context: WindowContext, } /// Resolves a window by label, defaulting to "main" if not specified. /// Returns both the window and context about the resolution. /// /// # Arguments /// /// * `app` - The Tauri application handle /// * `label` - Optional window label (defaults to "main") /// /// # Returns /// /// * `Ok(ResolvedWindow)` - The resolved window with context /// * `Err(String)` - Error if window not found pub fn resolve_window_with_context<R: Runtime>( app: &AppHandle<R>, label: Option<String>, ) -> Result<ResolvedWindow<R>, String> { let windows = app.webview_windows(); let total_windows = windows.len(); let explicit_label = label.is_some(); let target_label = label.unwrap_or_else(|| "main".to_string()); let window = app .get_webview_window(&target_label) .ok_or_else(|| format!("Window '{target_label}' not found"))?; let warning = if !explicit_label && total_windows > 1 { Some(format!( "Multiple windows detected ({total_windows} total). Defaulting to 'main' window. \ Use windowId parameter to target a specific window. \ Available windows: {}", windows.keys().cloned().collect::<Vec<_>>().join(", ") )) } else { None }; Ok(ResolvedWindow { window, context: WindowContext { window_label: target_label, total_windows, warning, }, }) } /// Resolves a window by label, defaulting to "main" if not specified. /// Simple version without context (for backward compatibility). /// /// # Arguments /// /// * `app` - The Tauri application handle /// * `label` - Optional window label (defaults to "main") /// /// # Returns /// /// * `Ok(WebviewWindow)` - The resolved window /// * `Err(String)` - Error if window not found pub fn resolve_window<R: Runtime>( app: &AppHandle<R>, label: Option<String>, ) -> Result<tauri::WebviewWindow<R>, String> { let label = label.unwrap_or_else(|| "main".to_string()); app.get_webview_window(&label) .ok_or_else(|| format!("Window '{label}' not found")) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/hypothesi/mcp-server-tauri'

If you have feedback or need assistance with the MCP directory API, please join our Discord server