Commit Graph
5 Commits
Author SHA1 Message Date
Ryan Hughes e9806b093b Reset to defaults: bundle builtin defaults as a guaranteed fallback
Reset previously could zero the bar out when defaultConfig was empty —
either because bar-defaults.json hadn't finished loading or because the
resolved path was wrong. The shell now carries an inline builtinBarConfig
that mirrors bar-defaults.json, and Reset uses it whenever the on-disk
defaults aren't yet populated.

Also: log the resolved omarchyPath / defaultsPath / userConfigPath at
startup, and route FileView load failures through console.warn so the
next time a user hits this they can see why.
2026-05-14 02:21:47 -04:00
Ryan Hughes 66155fff84 Persist full bar config instead of a diff against defaults
The diff serializer would write only the sections the user touched and
rely on the bar merging defaults back in at load time. After a Reset to
Defaults the user file became {}, so the next 'Add widget' diffed
against the section and wrote ONLY the user-added entry, dropping every
default widget the user could see in the GUI.

- Reset to Defaults now writes the merged defaults verbatim so the GUI
  and bar.json agree on the full widget list, and any subsequent edit
  operates on that explicit list.
- Save writes the full draft, not a diff. The user gets a predictable
  what-you-see-is-what-you-save customizer at the cost of Omarchy
  defaults changes not silently propagating after the first save.
2026-05-14 02:21:47 -04:00
Ryan Hughes 9862aeb661 Resolve first-party widgets relative to the shell.qml directory
Quickshell.shellDir points at the directory holding the loaded
shell.qml, so the bar can find its own widgets and bar-defaults.json
without depending on OMARCHY_PATH being set in the environment. The
old behaviour silently fell back to ~/.local/share/omarchy when the
env var was unset, which is fine for the installed shell but caused
'No such file or directory' for every first-party widget when running
quickshell -p straight from the repo.

- firstPartyWidgetSource now uses Qt.resolvedUrl("widgets/<name>.qml")
  so the resolution is anchored to shell.qml itself.
- deriveOmarchyPath() in both bar/shell.qml and bar-settings/shell.qml
  walks back from Quickshell.shellDir to find the omarchy root, with
  OMARCHY_PATH still allowed as an explicit override and the install
  default as a final fallback.
2026-05-14 02:21:47 -04:00
Ryan Hughes af5a71347b Address reviewer findings for bar settings GUI
CRITICAL:
- Re-inject working entry into the settings form every time the dialog
  opens. Previously the Loader's onLoaded only fires when the
  sourceComponent identity changes, so reopening the dialog on the same
  widget id (or on a second instance of the same id, e.g. two spacers)
  showed stale field values.
- 'Add widget' menu and the centerAnchor dropdown both read
  draft.layout[section] without depending on the section array
  identity. Mutating the array in place did not invalidate those
  bindings, so the menu would show a stale availability list and let
  non-spacer widgets be added twice. Layout mutations now replace the
  whole  object so any binding that reads it re-evaluates.

WARNINGS:
- Save now writes only the diff against the merged defaults so future
  bar-defaults changes are not silently shadowed by a stale snapshot.
- FileView onFileChanged handlers simplified to a single reload() —
  the explicit second loader call was duplicating loadConfig and
  bumping barConfigSerial twice per change (visible flicker).
- userFile onLoaded ignores reloads while the user has an unsaved
  working draft so external edits during editing do not clobber the
  in-progress state.
- SpinBox forms switched from onValueChanged to onValueModified so the
  initial-value bind no longer fires fieldChanged.
- Hyprland window-rule sizes aligned with the FloatingWindow
  implicitWidth/Height values (720 main, 380 dialog).
- omarchy-launch-bar-settings falls back to initialTitle when focusing,
  so a dialog that has not yet had its title applied still surfaces
  the existing instance.
2026-05-14 02:21:47 -04:00
Ryan Hughes a03f589258 Add visual bar customizer
Each layout entry is now an object — {id, ...inline settings} — instead
of a (name, separate modules map) pair. Multiple instances of the same
widget are trivially supported (spacer is the main beneficiary). Settings
travel with the entry, so reordering keeps them attached.

shell.qml:
- normalizeLayout converts string entries to {id} and drops invalid ones
- ModuleSlot binds to a full entry; moduleName and moduleSettings derive
  from it via entryId/entrySettings helpers
- centerAnchor lookup walks layoutEntries directly
- builtinBarConfig defaults use the object form
- README + bar-defaults.json updated to the new schema

bar-settings/ (new Quickshell config):
- Top toolbar with Reset / Save and Position / centerAnchor dropdowns
- Three section editors (left/center/right) with current widgets shown
  as cards: name + description + move up/down/settings/remove buttons
- '+ Add widget' menu per section, sorted alphabetically by display name
  (only spacer can repeat; everything else is one per bar)
- Per-widget settings dialog (FloatingWindow) loads an inline schema for
  widgets in the catalog. Initial schemas: spacer (size), calendar
  (formats), brightness (step)
- FileView { atomicWrites } writes to ~/.config/omarchy/bar.json on Save

omarchy-launch-bar-settings + hypr window rules pin the settings window
to a 760px floating square. controlCenter gains a 'Customize bar…' button
that launches it.
2026-05-14 02:21:47 -04:00