Main Entry Point and Menu System
Relevant source files
The following files were used as context for generating this wiki page:
This page documents the Rust backend's application entry point (main.rs) and its menu system. It covers application initialization, Tauri command registration, menu construction with keyboard shortcuts, and the mechanism for forwarding menu actions to the frontend. For information about the frontend orchestration and how menu actions are handled in Vue, see Main Application Component. For details on the individual command handlers that are registered here, see Command Handlers.
Purpose and Scope
The main.rs file serves as the entry point for the Tauri desktop application. It is responsible for:
- Initializing the Tauri runtime and window system
- Constructing the native application menu with keyboard shortcuts
- Registering all Tauri command handlers for frontend-backend IPC
- Managing workspace watcher state
- Forwarding menu events to the frontend via the event system
This 192-line file src-tauri/src/main.rs:1-192 acts as the "glue" that connects Tauri's native platform capabilities with the application's custom backend logic and frontend UI.
Sources: src-tauri/src/main.rs:1-192
Application Initialization Flow
The application bootstrap process follows a specific sequence to ensure all components are properly initialized before the application becomes interactive.
Initialization Sequence Diagram
Sources: src-tauri/src/main.rs:19-52
Main Function Structure
The main() function src-tauri/src/main.rs:19-52 uses Tauri's builder pattern to configure the application:
| Step | Purpose | Code Location |
|---|---|---|
| State Management | Initialize shared WorkspaceWatcherState for file watching | src-tauri/src/main.rs:21 |
| Dialog Plugin | Enable native file/folder picker dialogs | src-tauri/src/main.rs:22 |
| Setup Hook | Construct and set application menu | src-tauri/src/main.rs:23-26 |
| Menu Handler | Register callback for menu click events | src-tauri/src/main.rs:27-31 |
| Command Registration | Register 15 IPC command handlers | src-tauri/src/main.rs:32-49 |
| Run | Start the Tauri application event loop | src-tauri/src/main.rs:50-51 |
Sources: src-tauri/src/main.rs:19-52
Menu System Architecture
The menu system consists of three interconnected components: menu construction, event routing, and action emission. Menu items are assigned string identifiers that are mapped to action strings and forwarded to the frontend.
Menu Event Flow Diagram
Sources: src-tauri/src/main.rs:27-31, src-tauri/src/main.rs:161-191
Menu Action Mapping
The map_menu_action() function src-tauri/src/main.rs:161-180 converts menu item IDs to action strings. This indirection allows the menu ID to differ from the action name if needed, though currently they are identical:
| Menu Item ID | Action String | Keyboard Shortcut |
|---|---|---|
open-folder | open-folder | Cmd/Ctrl+O |
close-folder | close-folder | Cmd/Ctrl+W |
undo-action | undo-action | Cmd/Ctrl+Z |
redo-action | redo-action | Cmd/Ctrl+Shift+Z |
new-card | new-card | Cmd/Ctrl+N |
new-board | new-board | Cmd/Ctrl+Shift+N |
attach-existing-board | attach-existing-board | (none) |
new-column | new-column | (none) |
rename-selected-column | rename-selected-column | (none) |
delete-selected-column | delete-selected-column | (none) |
toggle-archive-column | toggle-archive-column | Cmd/Ctrl+Shift+A |
toggle-sub-boards | toggle-sub-boards | (none) |
delete-current-board | delete-current-board | (none) |
archive-selected-cards | archive-selected-cards | Delete |
delete-selected-cards | delete-selected-cards | Shift+Delete |
The mapping function returns Option<&'static str>, allowing unrecognized menu IDs to be ignored src-tauri/src/main.rs:178.
Sources: src-tauri/src/main.rs:161-180, src-tauri/src/main.rs:68-112
Menu Construction
The build_menu() function src-tauri/src/main.rs:54-159 constructs the native application menu using Tauri's menu builder API. The menu structure varies by platform, with macOS receiving a dedicated application menu.
Menu Structure Diagram
Sources: src-tauri/src/main.rs:54-159
Menu Item Construction
Menu items are created using MenuItemBuilder src-tauri/src/main.rs:68-112, which provides a fluent API for configuring each item:
MenuItemBuilder::with_id(id, label)
.accelerator(shortcut) // Optional
.build(app)?For example, the "New Card" menu item src-tauri/src/main.rs:102-104:
MenuItemBuilder::with_id("new-card", "New Card")
.accelerator("CmdOrCtrl+N")
.build(app)?The CmdOrCtrl prefix ensures cross-platform compatibility: Cmd on macOS, Ctrl on Windows/Linux.
Sources: src-tauri/src/main.rs:68-112
Platform-Specific Menu Construction
The menu construction logic uses conditional compilation to handle platform differences:
macOS-specific elements src-tauri/src/main.rs:56-67, src-tauri/src/main.rs:114-117:
PredefinedMenuItem::about()creates a standard "About" menu itemAboutMetadataBuilderpopulates it with app name, version, and icon- The app menu is added to the menu bar src-tauri/src/main.rs:149-150
All platforms src-tauri/src/main.rs:118-158:
- File, Edit, Board, Column, and Card menus are created using
SubmenuBuilder - Separators divide related menu items using
.separator() - Final menu is assembled using
MenuBuilderchain
Sources: src-tauri/src/main.rs:54-159
Menu Event Handling
When a user clicks a menu item or presses a keyboard shortcut, Tauri invokes the callback registered via on_menu_event() src-tauri/src/main.rs:27-31. This callback orchestrates the flow from native menu event to frontend notification.
Menu Event Handler Flow
Sources: src-tauri/src/main.rs:27-31
Event Emission
The emit_menu_action() function src-tauri/src/main.rs:182-191 uses Tauri's event system to notify the frontend:
- Constructs a
MenuActionPayloadwith the action string src-tauri/src/main.rs:186-188 - Calls
app_handle.emit()with event nameMENU_ACTION_EVENTsrc-tauri/src/main.rs:184-189 - Returns
Result<(), String>to handle potential emission errors
The event name MENU_ACTION_EVENT is defined in backend/models.rs (imported at src-tauri/src/main.rs:17) and used by the frontend to listen for menu actions.
Sources: src-tauri/src/main.rs:182-191, src-tauri/src/main.rs:16-17
Command Handler Registration
The invoke_handler macro src-tauri/src/main.rs:32-49 registers 15 Tauri command handlers that the frontend can invoke via IPC. These commands provide the backend API for all workspace, board, and card operations.
Registered Commands by Category
| Category | Commands | Module |
|---|---|---|
| Workspace | load_workspacesave_workspace_boardsapply_workspace_snapshotsync_known_board_tree | workspace.rs |
| Card | save_card_filecreate_card_in_boardrename_carddelete_card_file | card.rs |
| Board | save_board_filecreate_boardrename_boarddelete_board | board.rs |
| Watcher | watch_workspaceunwatch_workspace | watcher.rs |
| Config | load_app_configsave_app_config | workspace.rs |
All command functions are imported from backend::commands module src-tauri/src/main.rs:10-15.
Sources: src-tauri/src/main.rs:10-15, src-tauri/src/main.rs:32-49
Command Invocation Pattern
Commands are invoked from the frontend using Tauri's invoke() API:
// Frontend code example
const result = await invoke('load_workspace', { workspacePath });The tauri::generate_handler! macro src-tauri/src/main.rs:32 generates the routing code that:
- Deserializes command arguments from the frontend
- Calls the appropriate Rust function
- Serializes the return value back to the frontend
- Handles errors and converts them to frontend-compatible formats
Sources: src-tauri/src/main.rs:32-49
State Management
The application manages a single piece of shared state: WorkspaceWatcherState src-tauri/src/main.rs:21. This state is initialized using Tauri's manage() method, which makes it available to all command handlers.
WorkspaceWatcherState Usage
The WorkspaceWatcherState type is defined in backend/models.rs src-tauri/src/main.rs:16 and provides thread-safe access to the file system watcher. For details on how the watcher operates, see File System Watching.
Sources: src-tauri/src/main.rs:21, src-tauri/src/main.rs:16
Configuration Files
The Tauri configuration file src-tauri/tauri.conf.json:1-36 defines application metadata and window properties:
| Setting | Value | Purpose |
|---|---|---|
productName | "KanStack" | Application display name |
version | "0.6.0" | Current version number |
identifier | "com.kanstack.app" | Bundle identifier |
window.width | 1440 | Initial window width |
window.height | 920 | Initial window height |
window.maximized | true | Start maximized |
window.title | "" | Empty title (set dynamically) |
beforeDevCommand | "npm run dev" | Dev server startup command |
beforeBuildCommand | "npm run build" | Production build command |
devUrl | "http://localhost:1420" | Dev server URL |
frontendDist | "../dist" | Production build output directory |
The window title is left empty src-tauri/tauri.conf.json:16 because it is set dynamically by the frontend based on the current workspace and board.
Sources: src-tauri/tauri.conf.json:1-36
Bootstrap Summary
The complete application bootstrap process can be summarized as:
- State Initialization: Create
WorkspaceWatcherStatefor file watching - Plugin Setup: Initialize dialog plugin for native file pickers
- Menu Construction: Build platform-appropriate menu with shortcuts
- Menu Routing: Register event handler to forward menu actions to frontend
- Command Registration: Register 15 IPC command handlers
- Event Loop: Start Tauri runtime and display window
This architecture separates concerns cleanly: the menu system handles user actions in native UI, the command system handles programmatic operations from the frontend, and the event system bridges the two layers bidirectionally.
Sources: src-tauri/src/main.rs:1-192, src-tauri/tauri.conf.json:1-36
