SDDM: port upstream Omarchy login theme with Hyprland greeter
swadhinbiswas committed 2 months ago
211249e
1 parent f9ebd67
commit 211249e
17 files changed
+220 -4
Showing 17 changed files+220-4
README.mdbin/omarchy-refresh-sddmdefault/sddm/hyprland.luadefault/sddm/omarchy/Main.qmldefault/sddm/omarchy/bullet.pngdefault/sddm/omarchy/entry-failed.pngdefault/sddm/omarchy/entry.pngdefault/sddm/omarchy/lock-failed.pngdefault/sddm/omarchy/lock.pngdefault/sddm/omarchy/logo.pngdefault/sddm/omarchy/metadata.desktopdefault/sddm/omarchy/theme.confdocs/FORK-NOTES.mdinstall.shscripts/backup.shscripts/verify.shuninstall.sh
▼README.md
+4-3
| @@ -32,7 +32,7 @@ | ||
32 | 32 | |
33 | 33 | --- |
34 | 34 | |
35 | -de-omarchy takes the [Omarchy](https://github.com/basecamp/omarchy) experience — the bar, launcher, theming, notifications, lock screen, screensaver — and installs it as a **self-contained desktop layer** on top of your existing system. No ISO, no bootloader, no display manager, no mirrors touched. Everything it adds is additive, marked, and reversible. | |
35 | +de-omarchy takes the [Omarchy](https://github.com/basecamp/omarchy) experience — the bar, launcher, theming, notifications, lock screen, screensaver — and installs it as a **self-contained desktop layer** on top of your existing system. No ISO, no bootloader, no new display manager, no mirrors touched. Everything it adds is additive, marked, and reversible. | |
36 | 36 | |
37 | 37 | Your system stays yours. Your bindings win. Uninstalling puts everything back exactly as it was. |
38 | 38 | |
| @@ -48,6 +48,7 @@ Your system stays yours. Your bindings win. Uninstalling puts everything back ex | ||
48 | 48 | | **Plugin marketplace** | Browse and install community plugins (<kbd>SUPER</kbd>+<kbd>SHIFT</kbd>+<kbd>I</kbd>) | |
49 | 49 | | **Monitor Manager** | Visual multi-monitor arrangement, <kbd>SUPER</kbd>+<kbd>CTRL</kbd>+<kbd>M</kbd> | |
50 | 50 | | **Animated screensaver** | Terminal-text-effects at 120 fps — the real upstream behavior | |
51 | +| **Omarchy login screen** | SDDM greeter themed like upstream, running on a bare Hyprland session | | |
51 | 52 | | **~440 CLI commands** | One `omarchy` entry point; every command self-documents for humans *and* AI agents | |
52 | 53 | |
53 | 54 | ## Installation |
| @@ -78,9 +79,9 @@ Idempotent. Safe to re-run any time. | ||
78 | 79 | > [!IMPORTANT] |
79 | 80 | > **The safety contract** |
80 | 81 | > |
81 | -> **Never touched:** `pacman.conf`, mirrors, repos, kernel, bootloader, display manager, monitors layout, `.zshrc`, `.zshenv`, `starship.toml`, `kitty.conf`, SSH keys. Nothing in `$HOME` is deleted or overwritten. | |
82 | +> **Never touched:** `pacman.conf`, mirrors, repos, kernel, bootloader, display-manager binaries and PAM stack, monitors layout, `.zshrc`, `.zshenv`, `starship.toml`, `kitty.conf`, SSH keys. Nothing in `$HOME` is deleted or overwritten. | |
82 | 83 | > |
83 | -> **Added:** the runtime dir, the four symlinks, the marked Hyprland block, `/etc/environment.d/10-de-omarchy.conf`, a PAM stanza for the lock screen, and `/usr/bin` symlinks for a dozen commands. | |
84 | +> **Added:** the runtime dir, the four symlinks, the marked Hyprland block, `/etc/environment.d/10-de-omarchy.conf`, a PAM stanza for the lock screen, `/usr/bin` symlinks for a dozen commands — and, when SDDM is already installed, an Omarchy login theme plus its own drop-in config (remove it to fall back to your previous login screen). | |
84 | 85 | |
85 | 86 | To undo completely: |
86 | 87 | |
87 | 88 | |
▼bin/omarchy-refresh-sddm
+14-1
| @@ -1,7 +1,20 @@ | ||
1 | 1 | #!/bin/bash |
2 | 2 | |
3 | -# omarchy:summary=Refresh the SDDM theme from default | |
3 | +# omarchy:summary=Refresh the SDDM login theme from the runtime copy | |
4 | +# omarchy:group=sddm | |
4 | 5 | # omarchy:requires-sudo=true |
6 | +# omarchy:examples=omarchy-refresh-sddm | |
7 | +set -euo pipefail | |
8 | + | |
9 | +OMARCHY_PATH="${OMARCHY_PATH:-/usr/share/de-omarchy}" | |
10 | + | |
11 | +if [[ ! -d /usr/share/sddm/themes ]]; then | |
12 | + echo "SDDM is not installed — nothing to refresh." >&2 | |
13 | + exit 1 | |
14 | +fi | |
5 | 15 | |
6 | 16 | sudo rm -rf /usr/share/sddm/themes/omarchy |
7 | 17 | sudo cp -r "$OMARCHY_PATH/default/sddm/omarchy" /usr/share/sddm/themes/omarchy |
18 | +sudo cp "$OMARCHY_PATH/default/sddm/hyprland.lua" /usr/share/sddm/hyprland.lua | |
19 | + | |
20 | +echo "SDDM theme refreshed — applies the next time the login screen appears." | |
8 | 21 | |
▼default/sddm/hyprland.lua
+13-0
| @@ -0,0 +1,13 @@ | ||
1 | +-- Minimal Hyprland config for the SDDM Wayland greeter. | |
2 | +-- SDDM starts the greeter itself after the compositor is ready. | |
3 | +hl.config({ | |
4 | + misc = { | |
5 | + disable_hyprland_logo = true, | |
6 | + disable_splash_rendering = true, | |
7 | + force_default_wallpaper = 0, | |
8 | + }, | |
9 | + | |
10 | + animations = { | |
11 | + enabled = false, | |
12 | + }, | |
13 | +}) | |
0 | 14 | |
▼default/sddm/omarchy/Main.qml
+117-0
| @@ -0,0 +1,117 @@ | ||
1 | +import QtQuick 2.0 | |
2 | +import SddmComponents 2.0 | |
3 | + | |
4 | +Rectangle { | |
5 | + id: root | |
6 | + width: 640 | |
7 | + height: 480 | |
8 | + color: "#1a1b26" | |
9 | + | |
10 | + property string currentUser: userModel.lastUser | |
11 | + property bool loginFailed: false | |
12 | + property int sessionIndex: { | |
13 | + for (var i = 0; i < sessionModel.rowCount(); i++) { | |
14 | + var name = (sessionModel.data(sessionModel.index(i, 0), Qt.DisplayRole) || "").toString() | |
15 | + if (name.indexOf("uwsm") !== -1) | |
16 | + return i | |
17 | + } | |
18 | + return sessionModel.lastIndex | |
19 | + } | |
20 | + | |
21 | + Connections { | |
22 | + target: sddm | |
23 | + function onLoginFailed() { | |
24 | + root.loginFailed = true | |
25 | + password.text = "" | |
26 | + password.focus = true | |
27 | + } | |
28 | + function onLoginSucceeded() { | |
29 | + root.loginFailed = false | |
30 | + } | |
31 | + } | |
32 | + | |
33 | + Column { | |
34 | + anchors.centerIn: parent | |
35 | + spacing: 40 | |
36 | + | |
37 | + Image { | |
38 | + id: logo | |
39 | + source: "logo.png" | |
40 | + width: Math.min(sourceSize.width, root.width * 0.8) | |
41 | + height: sourceSize.width > 0 ? Math.round(width * sourceSize.height / sourceSize.width) : 0 | |
42 | + fillMode: Image.PreserveAspectFit | |
43 | + anchors.horizontalCenter: parent.horizontalCenter | |
44 | + } | |
45 | + | |
46 | + Row { | |
47 | + anchors.horizontalCenter: parent.horizontalCenter | |
48 | + spacing: 15 | |
49 | + | |
50 | + Image { | |
51 | + source: root.loginFailed ? "lock-failed.png" : "lock.png" | |
52 | + width: 34 | |
53 | + height: 38 | |
54 | + fillMode: Image.PreserveAspectFit | |
55 | + anchors.verticalCenter: parent.verticalCenter | |
56 | + } | |
57 | + | |
58 | + Item { | |
59 | + width: entry.width | |
60 | + height: entry.height | |
61 | + | |
62 | + Image { | |
63 | + id: entry | |
64 | + source: root.loginFailed ? "entry-failed.png" : "entry.png" | |
65 | + anchors.centerIn: parent | |
66 | + } | |
67 | + | |
68 | + Row { | |
69 | + anchors.left: parent.left | |
70 | + anchors.leftMargin: 20 | |
71 | + anchors.verticalCenter: parent.verticalCenter | |
72 | + spacing: 5 | |
73 | + | |
74 | + Repeater { | |
75 | + model: Math.min(password.text.length, 21) | |
76 | + | |
77 | + Image { | |
78 | + source: "bullet.png" | |
79 | + width: 7 | |
80 | + height: 7 | |
81 | + } | |
82 | + } | |
83 | + } | |
84 | + | |
85 | + TextInput { | |
86 | + id: password | |
87 | + anchors.fill: parent | |
88 | + anchors.leftMargin: 20 | |
89 | + anchors.rightMargin: 20 | |
90 | + verticalAlignment: TextInput.AlignVCenter | |
91 | + echoMode: TextInput.Password | |
92 | + font.family: "JetBrainsMono Nerd Font" | |
93 | + font.pixelSize: 24 | |
94 | + font.letterSpacing: 5 | |
95 | + passwordCharacter: "\u2022" | |
96 | + color: "transparent" | |
97 | + selectionColor: "transparent" | |
98 | + selectedTextColor: "transparent" | |
99 | + cursorDelegate: Item {} | |
100 | + focus: true | |
101 | + | |
102 | + onTextChanged: root.loginFailed = false | |
103 | + | |
104 | + Keys.onPressed: { | |
105 | + if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { | |
106 | + sddm.login(root.currentUser, password.text, root.sessionIndex) | |
107 | + event.accepted = true | |
108 | + } | |
109 | + } | |
110 | + } | |
111 | + } | |
112 | + } | |
113 | + | |
114 | + } | |
115 | + | |
116 | + Component.onCompleted: password.forceActiveFocus() | |
117 | +} | |
0 | 118 | |
▼default/sddm/omarchy/bullet.png
+0-0
Binary file not shown.
▼default/sddm/omarchy/entry-failed.png
+0-0
Binary file not shown.
▼default/sddm/omarchy/entry.png
+0-0
Binary file not shown.
▼default/sddm/omarchy/lock-failed.png
+0-0
Binary file not shown.
▼default/sddm/omarchy/lock.png
+0-0
Binary file not shown.
▼default/sddm/omarchy/logo.png
+0-0
Binary file not shown.
▼default/sddm/omarchy/metadata.desktop
+7-0
| @@ -0,0 +1,7 @@ | ||
1 | +[SddmGreeterTheme] | |
2 | +Name=Omarchy | |
3 | +Description=Minimal terminal-style login theme matching the Limine bootloader aesthetic | |
4 | +Author=Omarchy | |
5 | +Type=sddm-theme | |
6 | +Version=1.0 | |
7 | +QtVersion=6 | |
0 | 8 | |
▼default/sddm/omarchy/theme.conf
+1-0
| @@ -0,0 +1 @@ | ||
1 | +[General] | |
0 | 2 | |
▼docs/FORK-NOTES.md
+7-0
| @@ -40,6 +40,13 @@ direct `pacman -Syu` is not blocked. | ||
40 | 40 | - Install model: `install.sh` layers onto an EXISTING Arch/CachyOS system |
41 | 41 | additively (backs up first, appends one marked block to hyprland.lua, |
42 | 42 | never overwrites user files) instead of owning the machine |
43 | +- SDDM login screen: theme + greeter config vendored verbatim from upstream | |
44 | + (`default/sddm/`), deployed only when SDDM is already installed, via a new | |
45 | + `/etc/sddm.conf.d/50-de-omarchy.conf` drop-in (sorts after existing confs so | |
46 | + Current=omarchy wins without editing them). Upstream's PAM edits are | |
47 | + deliberately NOT ported: removing pam_gnome_keyring from /etc/pam.d/sddm is | |
48 | + ISO-specific and would break password keyrings on existing systems; same for | |
49 | + the sddm-autologin faillock tweak. | |
43 | 50 | |
44 | 51 | ## Diverged shared files |
45 | 52 | |
46 | 53 | |
▼install.sh
+26-0
| @@ -281,6 +281,32 @@ if [[ ! -f /etc/pam.d/omarchy-lock-password ]]; then | ||
281 | 281 | sudo chmod 644 /etc/pam.d/omarchy-lock-password |
282 | 282 | fi |
283 | 283 | |
284 | +# ---------------------------------------------------------------------------- | |
285 | +# 6b. SDDM login screen — upstream's Omarchy greeter (only if SDDM installed) | |
286 | +# | |
287 | +# Additive by design: the theme lands in its own dir under themes/, and the | |
288 | +# settings arrive as a NEW drop-in file named to sort AFTER any existing | |
289 | +# /etc/sddm.conf.d/*.conf, so Current=omarchy wins without editing anything. | |
290 | +# Deleting our drop-in (or running uninstall.sh) restores the previous theme | |
291 | +# untouched. Requires no display-manager binaries or PAM changes. | |
292 | +# ---------------------------------------------------------------------------- | |
293 | +if [[ -d /usr/share/sddm/themes && -f /etc/pam.d/sddm ]]; then | |
294 | + log "Installing SDDM login theme (Omarchy greeter on Hyprland)" | |
295 | + sudo rm -rf /usr/share/sddm/themes/omarchy | |
296 | + sudo cp -r "$RUNTIME/default/sddm/omarchy" /usr/share/sddm/themes/omarchy | |
297 | + sudo install -m 644 "$RUNTIME/default/sddm/hyprland.lua" /usr/share/sddm/hyprland.lua | |
298 | + printf '%s\n' \ | |
299 | + '[Theme]' 'Current=omarchy' \ | |
300 | + '' \ | |
301 | + '[General]' 'DisplayServer=wayland' \ | |
302 | + '' \ | |
303 | + '[Wayland]' \ | |
304 | + 'CompositorCommand=start-hyprland -- --config /usr/share/sddm/hyprland.lua' \ | |
305 | + | sudo tee /etc/sddm.conf.d/50-de-omarchy.conf >/dev/null | |
306 | +else | |
307 | + log "SDDM not detected — skipping login theme" | |
308 | +fi | |
309 | + | |
284 | 310 | # ---------------------------------------------------------------------------- |
285 | 311 | # 7. Clean up stale host config (additive: comments out dead code) |
286 | 312 | # ---------------------------------------------------------------------------- |
287 | 313 | |
▼scripts/backup.sh
+4-0
| @@ -21,6 +21,10 @@ for f in starship.toml; do | ||
21 | 21 | done |
22 | 22 | log "DONE targeted config" |
23 | 23 | |
24 | +# --- 1b. System configs the installer can touch (SDDM drop-in) -------------- | |
25 | +[[ -d /etc/sddm.conf.d ]] && { mkdir -p "$BACKUP_ROOT/sddm.conf.d"; rsync -a /etc/sddm.conf.d/ "$BACKUP_ROOT/sddm.conf.d/"; } | |
26 | +log "DONE sddm.conf.d" | |
27 | + | |
24 | 28 | # --- 2. Shell & identity dotfiles ------------------------------------------- |
25 | 29 | for f in .zshrc .zshenv .zprofile .zlogin .zlogout .bashrc .bash_profile \ |
26 | 30 | .p10k.zsh .gitconfig .profile; do |
27 | 31 | |
▼scripts/verify.sh
+13-0
| @@ -67,6 +67,19 @@ for widget_dir in sysmon notification-center; do | ||
67 | 67 | && ok "runtime plugin present: $widget_dir" |
68 | 68 | done |
69 | 69 | |
70 | +# SDDM login theme (only meaningful when SDDM is installed) | |
71 | +if [[ -d /usr/share/sddm/themes ]]; then | |
72 | + [[ -f /usr/share/sddm/themes/omarchy/Main.qml ]] \ | |
73 | + && ok "SDDM theme deployed" || bad "SDDM installed but omarchy theme missing (rerun install.sh)" | |
74 | + ACTIVE=$(grep -h '^Current=' /etc/sddm.conf.d/*.conf /etc/sddm.conf 2>/dev/null | tail -1 | cut -d= -f2) | |
75 | + if [[ -f /etc/sddm.conf.d/50-de-omarchy.conf ]]; then | |
76 | + [[ $ACTIVE == omarchy ]] && ok "SDDM active theme: omarchy" \ | |
77 | + || bad "SDDM Current=$ACTIVE but drop-in says omarchy" | |
78 | + else | |
79 | + echo " [warn] SDDM present but no de-omarchy drop-in — login screen not themed yet" | |
80 | + fi | |
81 | +fi | |
82 | + | |
70 | 83 | # monitors sanity: live monitors match display/monitors.lua outputs |
71 | 84 | if command -v hyprctl >/dev/null 2>&1 && [[ -f $(dirname "${BASH_SOURCE[0]}")/../display/monitors.lua ]]; then |
72 | 85 | LIVE=$(hyprctl monitors all 2>/dev/null | grep -oP '^Monitor \K[^ ]+' | sort) |
73 | 86 | |
▼uninstall.sh
+14-0
| @@ -50,5 +50,19 @@ fi | ||
50 | 50 | && sudo rm /etc/environment.d/10-de-omarchy.conf \ |
51 | 51 | && log "removed /etc/environment.d/10-de-omarchy.conf" |
52 | 52 | |
53 | +# 3b. Remove SDDM theme + drop-in (previous theme in earlier conf.d files | |
54 | +# becomes active again automatically — we never edited those). | |
55 | +if [[ -d /usr/share/sddm/themes ]]; then | |
56 | + [[ -d /usr/share/sddm/themes/omarchy ]] \ | |
57 | + && sudo rm -rf /usr/share/sddm/themes/omarchy \ | |
58 | + && log "removed /usr/share/sddm/themes/omarchy" | |
59 | + [[ -f /usr/share/sddm/hyprland.lua ]] \ | |
60 | + && sudo rm /usr/share/sddm/hyprland.lua \ | |
61 | + && log "removed /usr/share/sddm/hyprland.lua" | |
62 | +fi | |
63 | +[[ -f /etc/sddm.conf.d/50-de-omarchy.conf ]] \ | |
64 | + && sudo rm /etc/sddm.conf.d/50-de-omarchy.conf \ | |
65 | + && log "removed /etc/sddm.conf.d/50-de-omarchy.conf (previous SDDM theme resumes)" | |
66 | + | |
53 | 67 | log "Done. Your desktop is back to the pre-de-omarchy state after 'hyprctl reload'." |
54 | 68 | log "Full snapshot backups remain in: $BACKUP_ROOT" |
55 | 69 | |