This guide will show you how to add a minimal bar widget, register it so it shows up in the Bar tab “Widgets Positioning” selector, and make it editable right from the UI.
Note At this point, we recommend contributing plugins rather than core widgets. Plugins are easier to distribute, maintain independently, and don’t require changes to the main codebase. See the Plugins Overview for details on creating and sharing plugins.
Overview
Adding a new widget is straightforward once you know the flow. You’ll go through these steps:
- Create the widget file
- Register the widget in the registry
- Verify it shows up in the BarTab selector
- Test the Widget from the Settings Panel
- Add a settings UI
- Add more settings later (optional)
Let’s break it down step by step.
Step 1: Create the Widget File
Create a new file at Modules/Bar/Widgets/HelloWorld.qml:
Rectangle {
id: root
// Provided by Bar.qml via NWidgetLoader
property var screen
property real scaling: 1.0
property string widgetId: ""
property string section: ""
property int sectionWidgetIndex: -1
property int sectionWidgetsCount: 0
// Access your metadata and per-instance settings
property var widgetMetadata: BarWidgetRegistry.widgetMetadata[widgetId]
property var widgetSettings: {
if (section && sectionWidgetIndex >= 0) {
var widgets = Settings.data.bar.widgets[section]
if (widgets && sectionWidgetIndex < widgets.length) {
return widgets[sectionWidgetIndex]
}
}
return {}
}
implicitHeight: Math.round(Style.capsuleHeight * scaling)
implicitWidth: Math.round(120 * scaling)
radius: Math.round(Style.radiusS * scaling)
color: Color.mSurfaceVariant
border.width: Math.max(1, Style.borderS * scaling)
border.color: Color.mOutline
RowLayout {
id: layout
anchors.fill: parent
anchors.margins: Style.marginXS * scaling
spacing: Style.marginXS * scaling
NText {
text: widgetSettings.text !== undefined ? widgetSettings.text : (widgetMetadata?.text || "Hello")
pointSize: Style.fontSizeXS * scaling
font.weight: Style.fontWeightBold
color: Color.mPrimary
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
}
}
}
Step 2: Register the Widget in the Registry
Open Services/UI/BarWidgetRegistry.qml and make three small edits:
- Add the widget to the
widgetsmap:
"HelloWorld": helloWorldComponent,
- Provide defaults in
widgetMetadata(this seeds per-instance settings when adding from the UI):
"HelloWorld": {
"text": "Hello"
},
- Add a
Componententry so the registry can instantiate it:
property Component helloWorldComponent: Component {
HelloWorld {}
}
Example The
textfield is just an example of a simple per-widget setting copied to the user’s settings when they add it.
Step 3: Verify It Shows Up in the BarTab Selector
The Bar settings UI (Modules/Panels/Settings/Tabs/BarTab.qml) reads available widgets from BarWidgetRegistry.getAvailableWidgets() and builds the selector automatically. Once registered, HelloWorld appears in the add-widget menu for Left/Center/Right sections.
Step 4: Test the Widget from the Settings Panel
- Open Settings → Bar → Widgets Positioning.
- In the desired section (Left/Center/Right), click “Add” and select
HelloWorld. - Drag to reorder if needed.
Step 5: Add a Settings UI
To let users change the widget text via the Bar settings dialog, create a settings component and map it.
1) Create Modules/Panels/Settings/Bar/WidgetSettings/HelloWorldSettings.qml:
ColumnLayout {
// Provided by the dialog loader
property var widgetData
property var widgetMetadata
// Local state – initialize from widgetData with metadata fallback
property string textValue: widgetData?.text !== undefined ? widgetData.text : (widgetMetadata?.text || "Hello")
NText {
text: "HelloWorld Text"
pointSize: Style.fontSizeM * scaling
font.weight: Style.fontWeightBold
color: Color.mOnSurface
}
NTextInput {
Layout.fillWidth: true
placeholderText: "Enter text to display..."
text: textValue
onTextChanged: textValue = text
}
// Called by the dialog's Apply button
function saveSettings() {
// Return a new settings object; preserve other keys
var updated = Object.assign({}, widgetData)
updated.text = textValue
return updated
}
}
2) Map the settings component in Modules/Panels/Settings/Bar/BarWidgetSettingsDialog.qml:
// Inside loadWidgetSettings() widgetSettingsMap
"HelloWorld": "WidgetSettings/HelloWorldSettings.qml",
Now the gear icon on the widget chip opens a dialog with an input field to edit the text.
Tip The
saveSettings()function ensures your changes are written back into the JSON safely.
Step 6 (Optional): Add More Settings Later
- Add keys under
widgetMetadata["HelloWorld"]for new defaults (e.g.,icon,color, etc.). - They’ll be copied into a widget instance the first time the user adds it.
- To adjust existing instances, the user can edit in the UI if supported, or modify their settings JSON.
This inserts the widget with default settings for first-run configurations. Existing users won’t be affected unless they reset or remove their settings file.
That’s it! You’ve now built a simple, editable widget for the Bar and exposed it cleanly in the settings UI.