feat(sdk): menu and action system #355

Closed
opened 2026-02-27 19:30:47 +00:00 by forbes · 1 comment
Owner

Goal

Addons can register menu items and keyboard-shortcut actions.

New files

  • src/Gui/SDK/IMenuProvider.h — Abstract interface: id(), menu_path(), items(), on_triggered(item_id)
  • src/Gui/SDK/IActionProvider.h — Abstract interface: id(), command_name(), shortcut(), on_triggered()

Modified files

  • src/Gui/SDK/SDKRegistry.h/.cpp — Menu/action registration
  • src/Gui/SDK/bindings/kcsdk_py.cpp — Bind both interfaces with trampolines

Depends on #350. Part of the KCSDK epic (#346). Phase 6 of 8.

## Goal Addons can register menu items and keyboard-shortcut actions. ## New files - `src/Gui/SDK/IMenuProvider.h` — Abstract interface: `id()`, `menu_path()`, `items()`, `on_triggered(item_id)` - `src/Gui/SDK/IActionProvider.h` — Abstract interface: `id()`, `command_name()`, `shortcut()`, `on_triggered()` ## Modified files - `src/Gui/SDK/SDKRegistry.h/.cpp` — Menu/action registration - `src/Gui/SDK/bindings/kcsdk_py.cpp` — Bind both interfaces with trampolines Depends on #350. Part of the KCSDK epic (#346). Phase 6 of 8.
forbes added the enhancement label 2026-02-27 19:30:47 +00:00
Author
Owner

Scope revision

After reviewing the SDK's goals (stable API contract, GIL safety, lifecycle management) against FreeCAD's existing command and menu systems, we're re-scoping this issue:

Kept: IMenuProvider (full C++ interface)

Declarative menu placement with optional context awareness via context_ids(). Real value over raw WorkbenchManipulator: eliminates boilerplate, ties menus into the editing context system (same pattern as IToolbarProvider), and gives the SDK lifecycle oversight.

Changed: IActionProvider → kindred_sdk.register_command() (Python wrapper only)

FreeCAD's addCommand() is already stable, well-documented, and widely understood. Wrapping it in a C++ interface adds indirection without solving a real problem. Instead, a thin Python wrapper standardizes the calling convention within the SDK contract without a C++ abstraction layer.

Rationale

The C++ interface layer adds value when it provides GIL safety, type checking, or lifecycle management that Python alone can't easily achieve (e.g., IPanelProvider's QWidget bridging, IToolbarProvider's context auto-injection, IMenuProvider's WorkbenchManipulator management). Command registration has none of these concerns — it's a one-shot Python call with no ongoing lifecycle.

## Scope revision After reviewing the SDK's goals (stable API contract, GIL safety, lifecycle management) against FreeCAD's existing command and menu systems, we're re-scoping this issue: ### Kept: IMenuProvider (full C++ interface) Declarative menu placement with optional context awareness via context_ids(). Real value over raw WorkbenchManipulator: eliminates boilerplate, ties menus into the editing context system (same pattern as IToolbarProvider), and gives the SDK lifecycle oversight. ### Changed: IActionProvider → kindred_sdk.register_command() (Python wrapper only) FreeCAD's addCommand() is already stable, well-documented, and widely understood. Wrapping it in a C++ interface adds indirection without solving a real problem. Instead, a thin Python wrapper standardizes the calling convention within the SDK contract without a C++ abstraction layer. ### Rationale The C++ interface layer adds value when it provides GIL safety, type checking, or lifecycle management that Python alone can't easily achieve (e.g., IPanelProvider's QWidget bridging, IToolbarProvider's context auto-injection, IMenuProvider's WorkbenchManipulator management). Command registration has none of these concerns — it's a one-shot Python call with no ongoing lifecycle.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kindred/create#355