Build your first widget
This guide builds hello-clock, a bar widget that shows the local time and an optional date. You need OmniWM running, omniwmctl on your PATH, and a text editor. Enable Settings > Workspace Bar to see the result. Basic programming knowledge is enough; no Luau experience is required.
1. Create the widget
Section titled “1. Create the widget”Run:
omniwmctl shell init hello-clockThe command creates ~/.config/omniwm/shell/widgets/hello-clock/init.luau. Open that file in your editor. If the name already exists, use your existing tutorial folder or choose another name; the command does not replace it.
OmniShell calls the global render(ctx) function to get a UI tree. The starter also includes a popout(ctx) function; this clock does not need a popout, so replace the starter with the file in the next step.
2. Render and style the time
Section titled “2. Render and style the time”Save this complete file as ~/.config/omniwm/shell/widgets/hello-clock/init.luau:
Download widgets/hello-clock/init.luau
interval = 60
function render(ctx) local content = { key = "clock", gap = 8, pad = 6, radius = 8, fill = "surface" } content[#content + 1] = ui.symbol{ name = "clock", color = "accent", size = 14 } content[#content + 1] = ui.text{ text = ctx.data.clock, style = "bold", reserve = "00:00 PM" } if ctx.select("settings", "date") ~= false then content[#content + 1] = ui.text{ text = ctx.data.date, color = "secondaryForeground", size = 11 } end return ui.row(content)endui.row{ ... } is Luau’s shorthand for passing a table to ui.row. Named entries such as gap style the row; numbered entries are its children. content[#content + 1] appends a child, and .. concatenates strings.
The widget reads localized ctx.data.clock and ctx.data.date. interval = 60 requests minute updates for timed data. The reserve string keeps the time label’s width stable as its characters change. surface, accent, and secondaryForeground are palette colors, so the widget follows the selected style’s palette.
ctx.select("settings", "date") reads one option. The ~= false check means “show the date unless explicitly disabled,” matching the option default below. See context and data and layout and styling for other choices.
3. Declare the option
Section titled “3. Declare the option”Save this file beside init.luau, at ~/.config/omniwm/shell/widgets/hello-clock/settings.toml:
Download widgets/hello-clock/settings.toml
[options.date]type = "boolean"title = "Show date"default = trueThis declaration adds Show date to the widget’s native options editor. The actual value is saved for the active profile and delivered as ctx.data.settings; the declaration describes the control and its default. Components and configuration explains the supported option types.
Your final folder contains:
~/.config/omniwm/shell/widgets/hello-clock/├── init.luau└── settings.toml4. Put it on the bar
Section titled “4. Put it on the bar”- Open Settings > Workspace Bar > Layout > Bar Widgets.
- Select Add Widget…, choose hello-clock, and add it to the Center group.
- Select the new widget and open Options….
- Turn Show date off, then on.
You should see a clock symbol, the local time, and the date. Turning the option off removes only the date. The existing bar layout stays in place; you can remove the bundled clock separately if you prefer one time display.
Widgets in the top-level widgets/ folder are available to every profile. Their placement and option values belong to the active profile. See profiles and palettes.
5. Check edits and diagnostics
Section titled “5. Check edits and diagnostics”Change gap = 8 to gap = 12 and save. OmniShell watches widget files and reloads the widget; the spacing should change without restarting OmniWM. Restore the original value when finished.
omniwmctl query shell-widgetsFind hello-clock in the result and check its state and error. For editor completion, use ~/.config/omniwm/shell/omniwm.d.luau; browse the same definitions in the Luau reference.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Check |
|---|---|
| The widget is missing | Enable the Workspace Bar, add hello-clock to a lane, and check its exact folder name and init.luau filename. |
| No options appear | Put settings.toml beside the effective init.luau, then check shell-widgets for metadata errors. |
| An edit fails to render | Read the reported error and fix that line; keep the global render(ctx) function. |
| The date stays hidden | Open this widget’s Options… in the active profile and turn Show date on. |
Next, build a menu with clickable rows and a popout.