ContextMenu
A right-click context menu anchored to the pointer, with keyboard shortcuts, checkable items, and nested submenus.
import { ContextMenu } from "@glint/components/context-menu.slint";import { Tokens } from "@glint/theme/tokens.slint";import { IconSet } from "@lucide";
export component Demo inherits Window { width: 560px; height: 320px; background: Tokens.color-background;
in-out property <string> last-action: "None";
VerticalLayout { alignment: center; padding: 24px; spacing: 12px;
HorizontalLayout { alignment: center;
menu := ContextMenu { items: [ { label: "Back", icon: IconSet.ArrowLeft, shortcut: "Alt+Left" }, { label: "Forward", icon: IconSet.ArrowRight, shortcut: "Alt+Right" }, { label: "Reload", icon: IconSet.RotateCw, shortcut: "Ctrl+R" }, { label: "View", separator-before: true, children: [ { label: "Source", shortcut: "Ctrl+U" }, { label: "Inspect", shortcut: "Ctrl+Shift+I" } ] } ]; selected(row, child) => { if (child >= 0) { root.last-action = "Submenu item " + child + " in row " + row; } else { root.last-action = "Row " + row; } }
Rectangle { width: 380px; height: 180px; background: Tokens.color-surface-1; border-width: 1px; border-color: Tokens.color-border-hairline; border-radius: Tokens.radius-lg;
VerticalLayout { alignment: center; spacing: 8px;
Text { text: "Right-click anywhere in this area"; color: Tokens.color-foreground; font-size: Tokens.typography-body-size; horizontal-alignment: center; } Text { text: "Opens context menu at the pointer position"; color: Tokens.color-muted-foreground; font-size: Tokens.typography-body-sm-size; horizontal-alignment: center; } } } } }
Text { text: "Last action: " + root.last-action; color: Tokens.color-muted-foreground; font-size: Tokens.typography-body-sm-size; horizontal-alignment: center; } }}Usage
import { ContextMenu } from "@glint/components/context-menu.slint";
export component AppWindow inherits Window { VerticalLayout { alignment: center;
menu := ContextMenu { items: [ { label: "Cut" }, { label: "Copy" }, { label: "Paste" }, ]; selected(row, child) => { // handle choice }
Rectangle { width: 300px; height: 150px; // your right-clickable canvas or content } } }}ContextMenu wraps an interactive region in its @children slot. Right-clicking anywhere within that area captures the pointer coordinate and opens the menu popup powered by MenuPanel anchored to the cursor location.
The menu dismisses on click-outside or when Escape is pressed. Calling show() programmatically opens the menu at the last known pointer position or the area’s top-left corner.
Examples
Submenu alignment and positioning
Submenus open beside the parent row. Use submenu-side (PanelSide.right, PanelSide.left) and submenu-align (PanelAlign.start, PanelAlign.center, PanelAlign.end) to configure placement.
import { ContextMenu } from "@glint/components/context-menu.slint";import { PanelSide, PanelAlign } from "@glint/components/panel.slint";import { Tokens } from "@glint/theme/tokens.slint";import { IconSet } from "@lucide";
export component Demo inherits Window { width: 560px; height: 320px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center;
menu := ContextMenu { submenu-side: PanelSide.right; submenu-align: PanelAlign.start; items: [ { label: "Inspect Element", icon: IconSet.Search }, { label: "Developer Tools", separator-before: true, children: [ { label: "Console" }, { label: "Network" }, { label: "Performance" } ] } ];
Rectangle { width: 360px; height: 160px; background: Tokens.color-surface-1; border-width: 1px; border-color: Tokens.color-border-hairline; border-radius: Tokens.radius-lg;
VerticalLayout { alignment: center;
Text { text: "Right-click to inspect submenus"; color: Tokens.color-foreground; horizontal-alignment: center; } } } } } }}Checkable options and radio groups
Items can act as toggleable checkboxes or mutually exclusive radio choices. Group headers and separators follow the unified grouped rows model. Activating a checkbox toggles its state, while choosing a radio option clears other options sharing the same radio-group.
import { ContextMenu } from "@glint/components/context-menu.slint";import { MenuEntry } from "@glint/components/menu-entry.slint";import { Tokens } from "@glint/theme/tokens.slint";
export component Demo inherits Window { width: 560px; height: 320px; background: Tokens.color-background;
in-out property <[MenuEntry]> editor-items: [ { label: "Word Wrap", checkable: true, checked: true }, { label: "Show Line Numbers", checkable: true, checked: true }, { label: "Tabs", separator-before: true, heading-before: "Indentation", checkable: true, checked: false, radio-group: "indent" }, { label: "Spaces (2)", checkable: true, checked: true, radio-group: "indent" }, { label: "Spaces (4)", checkable: true, checked: false, radio-group: "indent" }, ];
VerticalLayout { alignment: center; padding: 24px;
HorizontalLayout { alignment: center;
menu := ContextMenu { items <=> root.editor-items;
Rectangle { width: 360px; height: 160px; background: Tokens.color-surface-1; border-width: 1px; border-color: Tokens.color-border-hairline; border-radius: Tokens.radius-lg;
VerticalLayout { alignment: center;
Text { text: "Right-click for editor settings"; color: Tokens.color-foreground; horizontal-alignment: center; } } } } } }}Programmatic keyboard opening
Calling show() opens the context menu for keyboard users. You can bind show() to application keyboard shortcuts or dedicated context menu keys.
import { Button } from "@glint/components/button.slint";import { ContextMenu } from "@glint/components/context-menu.slint";import { Tokens } from "@glint/theme/tokens.slint";import { IconSet } from "@lucide";
export component Demo inherits Window { width: 560px; height: 320px; background: Tokens.color-background;
VerticalLayout { alignment: center; padding: 24px; spacing: 12px;
HorizontalLayout { alignment: center;
menu := ContextMenu { items: [ { label: "Copy", icon: IconSet.Copy, shortcut: "Ctrl+C" }, { label: "Paste", icon: IconSet.Clipboard, shortcut: "Ctrl+V" }, { label: "Select All", shortcut: "Ctrl+A" } ];
Rectangle { width: 340px; height: 140px; background: Tokens.color-surface-1; border-width: 1px; border-color: Tokens.color-border-hairline; border-radius: Tokens.radius-lg;
VerticalLayout { alignment: center;
Text { text: "Right-click area or use button below"; color: Tokens.color-foreground; horizontal-alignment: center; } } } } }
HorizontalLayout { alignment: center;
Button { text: "Open via show()"; clicked => { menu.show(); } } } }}API Reference
Properties
| Property | Type | Default | Description |
|---|---|---|---|
items | in-out [MenuEntry] | no default | Menu rows shown on right-click. in-out because activating a checkbox or radio row writes its new checked back here. |
min-content-width | in length | 200px | The floor under the popup panel's width; the panel grows past it to fit its widest row, icon and shortcut hint included. |
submenu-side | in PanelSide | PanelSide.right | Where a row's submenu panel opens: which side of the menu, and how it lines up against the row it hangs off. A submenu opens beside its row, so top and bottom read as right. |
submenu-align | in PanelAlign | PanelAlign.start | |
highlighted-index | in-out int | 0 | Row highlighted by ↑/↓ inside the open menu; consumers rarely set this. |
is-open | out bool | no default | True while the menu is on screen; mirrors PopupWindow.is-open. |
menu-x | in-out length | no default | Internal — where the menu opens horizontally (set on right-click). |
menu-y | in-out length | no default | Internal — where the menu opens vertically (set on right-click). |
Callbacks
| Callback | Description |
|---|---|
selected(int , int) | Fired with the chosen row's index, and with the index of the submenu leaf that was taken or -1 when the row itself was; the menu auto-closes. |
Functions
| Function | Description |
|---|---|
show() | Opens the menu with the highlight back at the top. Mirrors PopupWindow.show() — the keyboard path into a menu that otherwise only the right mouse button reaches. |
close() | Closes the menu. Mirrors PopupWindow.close(). |
Enums
| Enum | Values |
|---|---|
PanelSide | top, right, bottom, left |
PanelAlign | start, center, end |
Accessibility
- Pointer location. The context menu positions its floating surface at the right-click pointer coordinates while remaining clamped within window bounds.
- Accessible list. The menu is reported as an accessible list structure containing individual list items with index information.
- Keyboard operation. When opened via keyboard
show(), focus lands on the first item. ↑/↓ navigate, → enters submenus, ← returns to the parent menu, and Escape closes the menu. - State indicators. Checked states on toggleable and radio options are announced directly to assistive technologies.