Promote shell to its own top-level directory

This commit is contained in:
David Heinemeier Hansson committed 2026-05-18 14:56:59 +02:00
1 parent d782705878
commit 0fe985b45d
83 files changed
+50 -28

No files matched your search

+3 -3
View File
@@ -107,7 +107,7 @@ When testing layer-shell UI, capture the reference and candidate states as separ
# Omarchy shell
The Quickshell desktop runs as a single long-running process out of
`default/quickshell/omarchy-shell/`. The `omarchy-shell.service` user unit
`shell/`. The `omarchy-shell.service` user unit
keeps it running for the graphical session; do not start additional
standalone `quickshell -p` instances for individual components.
@@ -116,7 +116,7 @@ Run `omarchy-restart-shell` after making changes to QML files.
Plugin contract:
- Each plugin lives in its own directory under
`default/quickshell/omarchy-shell/plugins/<id>/` (first-party) or
`shell/plugins/<id>/` (first-party) or
`~/.config/omarchy/plugins/<id>/` (third-party).
- Every plugin ships a `manifest.json` declaring `id`, `kinds`,
`activation`, and `entryPoints`. The full schema is in
@@ -137,7 +137,7 @@ IPC:
plugins can register additional IPC targets (the bar registers `bar`,
the background switcher registers `image-selector`).
Widget files in `plugins/bar/widgets/` contain Nerd Font glyphs as raw
Widget files in `shell/plugins/bar/widgets/` contain Nerd Font glyphs as raw
unicode characters. The `Write` and `Edit` tools strip multi-byte
codepoints in some positions — do **not** rewrite widget files wholesale
through those tools. For glyph fixes, use the targeted `Edit` tool with
+1 -1
View File
@@ -30,7 +30,7 @@ if [[ -z ${OMARCHY_PATH:-} ]]; then
exit 1
fi
SHELL_QML="$OMARCHY_PATH/default/quickshell/omarchy-shell/shell.qml"
SHELL_QML="$OMARCHY_PATH/shell/shell.qml"
perl -MCwd=abs_path -MEncode=encode,decode -MSocket -MIO::Handle \
-e '
+1 -1
View File
@@ -7,7 +7,7 @@
set -e
CONFIG_FILE="$HOME/.config/omarchy/shell.json"
DEFAULTS_FILE="$OMARCHY_PATH/default/quickshell/omarchy-shell/shell-defaults.json"
DEFAULTS_FILE="$OMARCHY_PATH/shell/shell-defaults.json"
position=$1
if [[ ! $position =~ ^(top|bottom|left|right)$ ]]; then
+1 -1
View File
@@ -8,7 +8,7 @@ StartLimitBurst=5
[Service]
Type=exec
Environment=OMARCHY_PATH=%h/.local/share/omarchy
ExecStart=/usr/bin/quickshell -p %h/.local/share/omarchy/default/quickshell/omarchy-shell
ExecStart=/usr/bin/quickshell -p %h/.local/share/omarchy/shell
Restart=always
RestartSec=2
Slice=session-graphical.slice
+4 -3
View File
@@ -51,13 +51,14 @@ This directory contains Omarchy's source files managed by git. Any changes will
├── config/ # Default config templates
├── themes/ # Stock themes
├── default/ # System defaults
├── shell/ # Omarchy shell source and defaults
├── migrations/ # Update migrations
└── install/ # Installation scripts
```
**Reading `~/.local/share/omarchy/` is SAFE and useful** - do it freely to:
- Understand how omarchy commands work: `omarchy theme set --help` or `cat $(which omarchy-theme-set)`
- See default configs before customizing: `cat ~/.local/share/omarchy/default/quickshell/omarchy-shell/shell-defaults.json`
- See default configs before customizing: `cat ~/.local/share/omarchy/shell/shell-defaults.json`
- Check stock theme files to copy for customization
- Reference default hyprland settings: `cat ~/.local/share/omarchy/default/hypr/*`
@@ -154,7 +155,7 @@ inside a single long-running Quickshell process (`omarchy-shell`).
```
~/.config/omarchy/shell.json # User overrides: bar.position, bar.layout, plugins[]
~/.local/share/omarchy/default/quickshell/omarchy-shell/shell-defaults.json # Canonical defaults
~/.local/share/omarchy/shell/shell-defaults.json # Canonical defaults
```
The shell hot-reloads `shell.json` on save — no restart needed for layout
@@ -375,7 +376,7 @@ omarchy reminder clear
## Out of Scope
This skill intentionally does not cover Omarchy source development. Do not use this skill for:
- Editing files in `~/.local/share/omarchy/` (`bin/`, `config/`, `default/`, `themes/`, `migrations/`, etc.)
- Editing files in `~/.local/share/omarchy/` (`bin/`, `config/`, `default/`, `shell/`, `themes/`, `migrations/`, etc.)
- Creating or editing migrations
- Running `omarchy dev ...` commands
+1 -1
View File
@@ -36,7 +36,7 @@ first call.
(loaded by `shell summon`, unloaded by `shell hide`). On-demand
plugins can set `keepLoaded: true` to survive between summons.
Full schema: `services/PluginRegistry.qml`.
Full schema: [`shell/services/PluginRegistry.qml`](../shell/services/PluginRegistry.qml).
## Installing a third-party plugin
+2 -1
View File
@@ -10,7 +10,8 @@ for file in ~/.config/hypr/bindings.lua ~/.config/hypr/bindings/*.lua; do
done
if ! systemctl --user is-active --quiet omarchy-shell.service && omarchy-cmd-present quickshell; then
quickshell kill -p "$OMARCHY_PATH/default/quickshell/omarchy-shell" >/dev/null 2>&1 || true
quickshell kill -p "$OMARCHY_PATH/shell" >/dev/null 2>&1 || true
quickshell kill -p "$OMARCHY_PATH/default/quickshell"/omarchy-shell >/dev/null 2>&1 || true
fi
systemctl --user enable --now omarchy-shell.service || true
+13
View File
@@ -0,0 +1,13 @@
echo "Move omarchy-shell to the top-level shell directory"
mkdir -p ~/.config/systemd/user
cp "$OMARCHY_PATH/config/systemd/user/omarchy-shell.service" ~/.config/systemd/user/omarchy-shell.service
systemctl --user daemon-reload
if omarchy-cmd-present quickshell; then
quickshell kill -p "$OMARCHY_PATH/default/quickshell"/omarchy-shell >/dev/null 2>&1 || true
fi
if systemctl --user is-enabled --quiet omarchy-shell.service || systemctl --user is-active --quiet omarchy-shell.service; then
systemctl --user restart omarchy-shell.service || true
fi
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -14,10 +14,10 @@ Hosting everything inside one shell means:
- third-party plugins can be loaded from disk without changing any source
code in Omarchy itself
The runtime layout in this branch:
The runtime layout:
```
default/quickshell/omarchy-shell/
shell/
shell.qml entry point (ShellRoot)
shell-defaults.json canonical out-of-the-box config
services/
@@ -94,7 +94,7 @@ The full schema lives in `services/PluginRegistry.qml`.
3. Enable the plugin with `omarchy-shell shell setPluginEnabled <id> true`.
4. If it's a `bar-widget`, add it to a layout section from the bar editor.
First-party plugins under `default/quickshell/omarchy-shell/plugins/`
First-party plugins under `shell/plugins/`
are discovered the same way and cannot be disabled.
## IPC contract
@@ -118,14 +118,14 @@ running a separate Quickshell instance.
Direct invocation:
```
quickshell ipc -p $OMARCHY_PATH/default/quickshell/omarchy-shell call shell ping
quickshell ipc -p $OMARCHY_PATH/shell call shell ping
```
The `omarchy-shell.service` user unit starts the shell for the graphical
session and restarts it if it exits. Use `omarchy-restart-shell` to reload
the long-running shell process.
A convenience wrapper, [`omarchy-shell`](../../../bin/omarchy-shell),
A convenience wrapper, [`omarchy-shell`](../bin/omarchy-shell),
forwards IPC calls to the running service. It does not start the shell; the
systemd unit owns the shell lifecycle.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -577,7 +577,7 @@ Item {
Process {
id: screenRecordingProc
command: ["bash", "-lc", root.commandWithOmarchyPath(root.shellQuote(root.omarchyPath + "/default/quickshell/omarchy-shell/scripts/indicators/screen-recording.sh"))]
command: ["bash", "-lc", root.commandWithOmarchyPath(root.shellQuote(root.omarchyPath + "/shell/scripts/indicators/screen-recording.sh"))]
stdout: StdioCollector {
waitForEnd: true
onStreamFinished: root.updateIndicator("screenRecording", text)
@@ -586,7 +586,7 @@ Item {
Process {
id: notificationSilencingProc
command: ["bash", "-lc", root.commandWithOmarchyPath(root.shellQuote(root.omarchyPath + "/default/quickshell/omarchy-shell/scripts/indicators/notification-silencing.sh"))]
command: ["bash", "-lc", root.commandWithOmarchyPath(root.shellQuote(root.omarchyPath + "/shell/scripts/indicators/notification-silencing.sh"))]
stdout: StdioCollector {
waitForEnd: true
onStreamFinished: root.updateIndicator("notifications", text)
@@ -548,7 +548,7 @@ Item {
// Poll the weather pill text/class every minute. Local to this widget.
Process {
id: weatherProc
command: ["bash", "-lc", root.bar ? root.bar.commandWithOmarchyPath(root.bar.shellQuote(root.bar.omarchyPath + "/default/quickshell/omarchy-shell/scripts/weather.sh")) : ""]
command: ["bash", "-lc", root.bar ? root.bar.commandWithOmarchyPath(root.bar.shellQuote(root.bar.omarchyPath + "/shell/scripts/weather.sh")) : ""]
stdout: StdioCollector {
waitForEnd: true
onStreamFinished: root.updateWeather(text)
@@ -152,7 +152,7 @@ Item {
}
FileView {
path: root.omarchyPath + "/default/quickshell/omarchy-shell/plugins/emoji-picker/emojis.json"
path: root.omarchyPath + "/shell/plugins/emoji-picker/emojis.json"
onLoaded: root.loadEmojis(text())
}
PanelWindow {
@@ -61,7 +61,7 @@ Item {
function scriptPath(name) {
var base = omarchyPath || Quickshell.env("OMARCHY_PATH") || (Quickshell.env("HOME") + "/.local/share/omarchy")
return base + "/default/quickshell/omarchy-shell/scripts/" + name
return base + "/shell/scripts/" + name
}
function focusPicker() {
@@ -37,13 +37,16 @@ Item {
var env = Quickshell.env("OMARCHY_PATH")
if (env) return env
var dir = String(Quickshell.shellDir || "")
if (dir.indexOf("/default/quickshell/omarchy-shell") !== -1)
return dir.substring(0, dir.indexOf("/default/quickshell/omarchy-shell"))
while (dir.length > 1 && dir.charAt(dir.length - 1) === "/")
dir = dir.substring(0, dir.length - 1)
var suffix = "/shell"
if (dir.length > suffix.length && dir.substring(dir.length - suffix.length) === suffix)
return dir.substring(0, dir.length - suffix.length)
return Quickshell.env("HOME") + "/.local/share/omarchy"
}
readonly property string home: Quickshell.env("HOME")
readonly property string userConfigPath: home + "/.config/omarchy/shell.json"
readonly property string defaultsPath: omarchyPath + "/default/quickshell/omarchy-shell/shell-defaults.json"
readonly property string defaultsPath: omarchyPath + "/shell/shell-defaults.json"
// ---------------- theme --------------------------------------------------
// Bar settings deliberately isn't a themable surface in shell.toml — it
File renamed without changes.
@@ -26,13 +26,17 @@ ShellRoot {
var env = Quickshell.env("OMARCHY_PATH")
if (env) return env
var dir = String(Quickshell.shellDir || "")
if (dir.indexOf("/default/quickshell/omarchy-shell") !== -1)
return dir.substring(0, dir.indexOf("/default/quickshell/omarchy-shell"))
while (dir.length > 1 && dir.charAt(dir.length - 1) === "/")
dir = dir.substring(0, dir.length - 1)
var suffix = "/shell"
if (dir.length > suffix.length && dir.substring(dir.length - suffix.length) === suffix)
return dir.substring(0, dir.length - suffix.length)
return home + "/.local/share/omarchy"
}
property string omarchyPath: deriveOmarchyPath()
readonly property string firstPartyPluginsDir: omarchyPath + "/default/quickshell/omarchy-shell/plugins"
readonly property string defaultsPath: omarchyPath + "/default/quickshell/omarchy-shell/shell-defaults.json"
readonly property string shellPath: omarchyPath + "/shell"
readonly property string firstPartyPluginsDir: shellPath + "/plugins"
readonly property string defaultsPath: shellPath + "/shell-defaults.json"
readonly property string userConfigPath: home + "/.config/omarchy/shell.json"
// Bundled fallback so the shell can start even when shell-defaults.json is