Command and Menu Handling
Relevant source files
The following files were used as context for generating this wiki page:Command and menu handling is the system responsible for processing user-initiated actions within the Ghostbird extension, primarily through keyboard shortcuts and context menus. These actions, defined in the extension's manifest, are the primary way users control the GhostText session, such as starting a connection, stopping it, or opening the options page. The background script listens for these events and orchestrates the appropriate response.
This system is crucial for providing a seamless user experience, allowing for quick control over the editing session without leaving the keyboard. The architecture separates the definition of commands (in the manifest) from their implementation (in the background script), allowing for a clean and maintainable codebase.
Manifest Configuration
The foundation of command and menu handling is the manifest_template.json file. It declares the available commands, their default keyboard shortcuts, and the user-facing UI elements like the compose_action button.
Sources: manifest_template.json, tools/generate_manifest.ts
Commands
Commands are registered in the commands object of the manifest. Each command has a description and may have a suggested key binding. These commands are then handled by the background script.
The following diagram illustrates how the manifest template is processed to generate the final manifest.json.
This diagram shows the generate_manifest.ts script taking the template and version information to produce the final manifest file for the extension package.
Sources: tools/generate_manifest.ts:10-25, doc/building.md
The following commands are defined:
| Command ID | Description (from message key) | Suggested Key |
|---|---|---|
start_ghostbird | Start Ghostbird | Ctrl+Shift+H |
stop_ghostbird | Stop Ghostbird | (none) |
toggle_ghostbird | Toggle Ghostbird | (none) |
open_options | Open the options page | (none) |
Sources: manifest_template.json:42-59
{
"commands": {
"start_ghostbird": {
"description": "__MSG_manifest_commands_start_ghostbird_description__",
"suggested_key": {
"default": "Ctrl+Shift+H"
}
},
"stop_ghostbird": {
"description": "__MSG_manifest_commands_stop_ghostbird_description__"
},
"toggle_ghostbird": {
"description": "__MSG_manifest_commands_toggle_ghostbird_description__"
},
"open_options": {
"description": "__MSG_manifest_commands_open_options_description__"
}
}
}
Sources: manifest_template.json:42-59
Compose Action Button
The compose_action entry defines the toolbar button that appears in Thunderbird's compose window. This button serves as a visual indicator of the connection status and a primary trigger for starting the Ghostbird session.
"compose_action": {
"default_title": "Ghostbird",
"default_label": "",
"default_icon": "gray.svg"
}
Sources: manifest_template.json:64-68
Clicking this button triggers the main action, which is handled by the background script to initiate a connection to the GhostText server.
Sources: doc/design.md:37-41
Architectural Overview
The command and menu handling logic resides primarily in the background script (background.js). It listens for events from the commands and menus APIs and routes them to the appropriate handlers.
Sources: doc/design.md:12-23, src/app-background/api.ts
Command and Menu APIs
The src/app-background/api.ts file defines the core interfaces and types for interacting with commands and menus.
CommandId Type
The CommandId type is a union of all possible command strings defined in the manifest. This ensures type safety when handling command events.
export type CommandId = "start_ghostbird" | "stop_ghostbird" | "toggle_ghostbird" | "open_options"
Sources: src/app-background/api.ts:6-6
Command Execution Flow
When a user triggers a command (e.g., by pressing Ctrl+Shift+H), the following sequence occurs:
This diagram shows the flow from a user keypress to the background script initiating a connection.
Sources: doc/design.md:37-41, README.md:65-71
The BackgroundEventRouter class, mentioned in the design documentation, is responsible for receiving these events and delegating them to specific handlers.
Sources: doc/design.md:14-14, src/test/util/dependency_reporter.ts:14-17
Context Menu Handling
Ghostbird provides a context menu on the compose_action (toolbar) button. This menu offers additional actions, such as disconnecting a session.
Sources: README.md:104-104
Menu Interfaces
The IButtonMenu interface, defined in src/app-background/api.ts, outlines the contract for managing the context menu.
/** Controls the context menu on the toolbar button */
export interface IButtonMenu {
/** @returns whether the menu has been initialized */
isInitialized(): boolean
/**
* Creates a context menu shown when the toolbar button is right clicked.
* @param menuItems Items to show in the menu
* @param currentShown Information about the menu currently shown
*/
initItems(menuItems: ReadonlyArray<MenuItem>, currentShown: MenuShownInfo | undefined): Promise<void>
}
Sources: src/app-background/api.ts:43-55
The menu items themselves are described by the MenuItem type:
| Property | Type | Description |
|---|---|---|
label | MessageId | ID of the localized text to be displayed. |
id | CommandId | The command to execute when the item is clicked. |
icon | string | Path to the icon to display. |
| Sources: src/app-background/api.ts:62-68 |
Menu Initialization Flow
The context menu is initialized dynamically by the background script.
This flowchart depicts the logic for creating the context menu items upon extension startup or as needed.
Sources: src/app-background/api.ts:43-55
Summary
The command and menu handling system in Ghostbird provides a robust and user-friendly way to interact with the extension. By defining commands and UI entry points in the manifest.json and handling the logic within the background script, the system maintains a clear separation of concerns. The use of specific interfaces and types like CommandId and IButtonMenu ensures that the implementation is type-safe and consistent with the features declared in the manifest. This architecture allows users to efficiently control Ghostbird sessions via keyboard shortcuts and the toolbar button's context menu.