Skip to main content

Module Context & Headers

This page is the orientation map for the SDK's public surface: the umbrella headers, the IModule interface, and the IModuleContext your module is handed.

Umbrella headers

Include the umbrella that covers what you need; each pulls in the relevant individual headers.

HeaderProvides
<framelift/core.h>Module lifecycle (IModule, ModuleBase), the entry macros, IModuleContext, settings/keybind helpers, events, hotkeys, Log. The one most plugins include.
<framelift/services.h>Cross-plugin + host services: IHistory, ISettingsStore, ISettingsRegistry, IPluginCatalog, IAppPaths, the log buffer, and JSON helpers.
<framelift/platform.h>Platform service families: media (IMediaPlayback, IMediaProperties, IVideoOutput, IAudioControl, ISubtitleControl), the window (IAppWindow, IEventPump), and IFileDialog.

UI is authored as embedded Qt Quick (QML) driven by a QObject view-model — see Rendering UI. There is no UI umbrella header.

Author-side convenience wrappers (lambdas over the POD ABI) live in <framelift/ContextHelpers.h> and <framelift/HotkeyHelpers.h>.

IModule

The interface the host knows your module by. Most authors derive from ModuleBase rather than implementing this directly — see Plugin Lifecycle.

class IModule
{
public:
static constexpr const char* InterfaceId = "framelift.IModule";
virtual ~IModule() = default;

virtual void Install(IModuleContext& ctx) noexcept {}
virtual void Uninstall() noexcept {}
virtual void* QueryInterface(const char* interfaceId) noexcept { return nullptr; }
};

A module opts into the host's other dispatch surfaces by implementing small secondary interfaces — IHotkeyProvider, IEventHandler, IMediaEventHandler, IShutdownHandler. A module that also draws UI is a QObject view-model with an embedded QML root — see Rendering UI. ModuleBase implements all the dispatch interfaces for you.

IModuleContext

Passed into Install(); ModuleBase stores it as ctx_. It is deliberately tiny — a frozen bootstrap that carries only the service registry and the pub/sub bus. Every other host capability (settings, the plugin catalogue, media, the window) is reached by discovering a service through it. All virtual methods use a C-compatible ABI — no STL types cross the boundary. Prefer the non-virtual template helpers below over the raw *Raw virtuals.

Services

template <typename T> T* GetService() const noexcept;            // nullptr if absent
template <typename T, typename... Us> void RegisterService(T*); // register under 1+ interfaces

Keyed by T::InterfaceId. See Cross-Plugin Communication.

Pub/sub

template <typename TEvent> void Publish(const TEvent& event) noexcept;
// framelift::Subscribe<TEvent>(ctx, lambda) — free helper in ContextHelpers.h

Keyed by TEvent::EventId. See Events.

Where the old context methods went

In earlier versions the context carried settings getters and settings-page registration directly. Those are now services you discover with GetService<T>(), which is what keeps IModuleContext frozen:

You want to…DiscoverThen call
Read/commit host settingsISettingsStoreGetSettingBool/Int/Float/String, CommitSetting*, SaveSettings
Get your per-plugin INI sectionISettingsStoreGetModuleSettings("section")IModuleSettings
Register a settings page / keybind rowISettingsRegistryRegisterSettingsPage, RegisterKeybindEntry
Get the user config dirIAppPathsGetPrefPath(buf, cap) (or framelift::GetPrefPath(ctx))

framelift::RegisterKeybindEntry(), framelift::GetSettingString(), and framelift::GetPrefPath() wrap these so you rarely touch the raw services. See Settings.

AppEvent

Platform input delivered to HandleKeyDownEvent (and the lower-level OnEvent/HandleEvent). type (an AppEventType) selects the active union member; accessors are AsKey(), AsFile(), AsCustom().

AppEventTypePayload
KeyDown / KeyUpAsKey(){ Key key; Mod mods; }
DropFileAsFile(){ const char* filePath; } (valid only during the call)
CustomAsCustom(){ uint32_t eventType; void* userData1; }
Quit, WindowExposed, RenderUpdate, PlayerWakeup, MouseButtonDown, MouseMotion, MouseWheelnone

Key is an integer keycode (uint32_t) with named constants in the Keys:: namespace (Keys::Space, Keys::F1, Keys::Left, …). Mod is an OR-able bitfield (Mod::Ctrl | Mod::Shift); test it with ModSet(state, Mod::Ctrl). All in <framelift/AppEvent.h>.