feat: sync with upstream — v1.2.0, in-app updates, Projects, modules

Brings the public tree back in line with the development repo after several
weeks of drift caused by a stale publish include list.

New:
- In-app update path: GET /update/check compares the checkout against
  origin/main and POST /update/apply runs `ncp upgrade` detached (pull,
  rebuild, restart). The sidebar shows the version, checks on click, and
  offers an "update available" pill.
- Projects: a project workspace groups chats and RAG documents, with
  per-project instructions and document retrieval scoped to the active
  project. Replaces the standalone Documents page.
- modules/: auto-discovered feature plugins (mail, network) with their
  frontend counterparts and tests.
- Memory curation runs in-process (synapse/memory/curator.py) on the chat
  model when a conversation goes idle. The separate memory service on :8001
  is gone, along with the launcher lines that started it.

Also: the KDE theme, panel and Promethean terminal assets, the full test
suite, and VERSION 1.2.0.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
This commit is contained in:
janvanwan
2026-08-25 09:13:55 -05:00
parent fe5d18afa7
commit 42eaed647a
88 changed files with 4280 additions and 1888 deletions
@@ -7,7 +7,7 @@ X-KDE-ServiceTypes=org.kde.kwin.decoration
[KWin]
Type=Aurorae
X-KDE-PluginInfo-Author=Jon
X-KDE-PluginInfo-Author=NexusOS
X-KDE-PluginInfo-Email=
X-KDE-PluginInfo-Name=NexusOS
X-KDE-PluginInfo-Version=1.0
+167 -8
View File
@@ -12,8 +12,10 @@ KDE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO="$(cd "$KDE/../../.." && pwd)"
NO_SDDM=0
FORCE_PANEL=0
for arg in "$@"; do
[[ "$arg" == "--no-sddm" ]] && NO_SDDM=1
[[ "$arg" == "--panel" ]] && FORCE_PANEL=1
done
echo "NexusOS KDE installer — repo: $REPO"
@@ -24,13 +26,11 @@ mkdir -p \
~/.local/share/plasma/desktoptheme \
~/.local/share/color-schemes \
~/.local/share/konsole \
~/.local/share/kscreenlocker/themes \
~/.config/Kvantum
# ── 2. Symlink theme directories (update automatically on git pull) ──────
ln -sfn "$KDE/aurorae/NexusOS" ~/.local/share/aurorae/themes/NexusOS
ln -sfn "$KDE/plasma/NexusOS" ~/.local/share/plasma/desktoptheme/NexusOS
ln -sfn "$KDE/kscreenlocker/NexusOS" ~/.local/share/kscreenlocker/themes/NexusOS
ln -sfn "$KDE/kvantum/NexusOS" ~/.config/Kvantum/NexusOS
echo " [ok] theme symlinks"
@@ -80,10 +80,25 @@ else
echo " [skip] plasma-apply-desktoptheme not found — apply desktop theme manually"
fi
# ── 8. kscreenlocker ─────────────────────────────────────────────────────
# ── 8. Lock screen ───────────────────────────────────────────────────────
# Plasma 5.27 draws the lock screen from a look-and-feel package's
# contents/lockscreen, and [Greeter]Theme names that PACKAGE. The old value here
# ("NexusOS") was not a look-and-feel id, so it silently fell back to Breeze.
# The standalone kscreenlocker theme that value referred to targeted an earlier
# kscreenlocker API that 5.27 no longer loads, and has been deleted.
#
# Breeze's lock UI is deliberately kept rather than replaced: a lock screen that
# fails to load is one you cannot get back through. Only the wallpaper is ours,
# which is what carries the brushed-metal look.
if command -v kwriteconfig5 &>/dev/null; then
kwriteconfig5 --file kscreenlockerrc --group Greeter --key Theme NexusOS
echo " [ok] kscreenlocker theme: NexusOS"
kwriteconfig5 --file kscreenlockerrc --group Greeter --key Theme org.kde.breeze.desktop
LOCK_BG="$KDE/sddm/NexusOS-QML/assets/background.png"
if [[ -f "$LOCK_BG" ]]; then
kwriteconfig5 --file kscreenlockerrc \
--group Greeter --group Wallpaper --group org.kde.image --group General \
--key Image "$LOCK_BG"
echo " [ok] lock screen wallpaper: NexusOS brushed metal"
fi
fi
# ── 9. GTK apps under Plasma ─────────────────────────────────────────────
@@ -106,7 +121,7 @@ if [[ $NO_SDDM -eq 0 ]]; then
sudo cp -r "$KDE/sddm/NexusOS-QML" /usr/share/sddm/themes/
sudo cp "$REPO/management/sessions/nexusos-kde.desktop" /usr/share/xsessions/
if command -v kwriteconfig5 &>/dev/null; then
sudo kwriteconfig5 --file /etc/sddm.conf --group Theme --key Current NexusOS-QML
sudo kwriteconfig5 --file /etc/sddm.conf.d/nexusos.conf --group Theme --key Current NexusOS-QML
else
# Fallback: write the INI directly
sudo bash -c 'printf "[Theme]\nCurrent=NexusOS-QML\n" > /etc/sddm.conf.d/nexusos.conf'
@@ -125,14 +140,158 @@ if [[ -f "$DESKTOP_SRC" ]]; then
echo " [ok] Promethean Terminal launcher updated"
fi
# ── 11b. Global Theme + wallpaper ────────────────────────────────────────
# Copied, NOT symlinked, unlike the theme dirs above: KPackage silently skips a
# symlinked package directory, so a symlinked look-and-feel never appears in
# `lookandfeeltool -l` or System Settings at all. Aurorae/desktoptheme/Kvantum
# read their directories directly and are fine as symlinks.
LNF_SRC="$KDE/look-and-feel/com.nexusos.desktop"
WALL_SRC="$KDE/wallpaper/NexusOS"
if [[ -d "$LNF_SRC" ]]; then
mkdir -p ~/.local/share/plasma/look-and-feel ~/.local/share/wallpapers
rm -rf ~/.local/share/plasma/look-and-feel/com.nexusos.desktop
cp -rL "$LNF_SRC" ~/.local/share/plasma/look-and-feel/
rm -rf ~/.local/share/wallpapers/NexusOS
cp -rL "$WALL_SRC" ~/.local/share/wallpapers/
echo " [ok] Global Theme + wallpaper packages installed"
if command -v lookandfeeltool &>/dev/null; then
# Verify registration before applying. KPackage reports nothing when it
# rejects a package, so without this check a botched install is silent and
# you only find out by opening System Settings.
if lookandfeeltool -l 2>/dev/null | grep -qx "com.nexusos.desktop"; then
lookandfeeltool -a com.nexusos.desktop 2>/dev/null \
&& echo " [ok] Global Theme applied (splash, colors, decoration)"
else
echo " [WARN] com.nexusos.desktop did not register with KPackage."
echo " Most likely it was symlinked instead of copied -- KPackage"
echo " skips symlinked package directories silently."
fi
fi
if command -v plasma-apply-wallpaperimage &>/dev/null; then
plasma-apply-wallpaperimage ~/.local/share/wallpapers/NexusOS &>/dev/null \
&& echo " [ok] wallpaper applied"
fi
fi
# ── 11c. Panel layout + dock ─────────────────────────────────────────────
# The XFCE panel rebuilt with native Plasma widgets, plus Plank for the dock
# (its config and NexusOS theme already exist under assets/themes/restore-snapshot).
#
# Applied ONCE, guarded by a marker file. This rewrites the panel from scratch,
# so re-running it on every restore would wipe any widget you added since. Pass
# --panel to force it, e.g. after a fresh install or to undo panel experiments.
PANEL_MARKER="$HOME/.config/nexusos-panel-applied"
PANEL_JS="$KDE/panel-layout.js"
if [[ -f "$PANEL_JS" ]] && { [[ ! -f "$PANEL_MARKER" ]] || [[ $FORCE_PANEL -eq 1 ]]; }; then
if qdbus org.kde.plasmashell /PlasmaShell evaluateScript \
"$(sed "s|__NEXUS_ROOT__|$REPO|g" "$PANEL_JS")" &>/dev/null; then
touch "$PANEL_MARKER"
echo " [ok] panel layout applied (top, 36px, Nexus launcher)"
else
echo " [skip] panel layout — plasmashell not running"
fi
elif [[ -f "$PANEL_MARKER" ]]; then
echo " [ok] panel layout already applied (--panel to redo)"
fi
# Plank autostart. Plank is a GTK X11 app and runs fine under Plasma; this is
# the same dock, config and theme the XFCE session used.
if command -v plank &>/dev/null; then
mkdir -p ~/.config/autostart
# Symlink, matching bin/panel/install.sh. cp fails outright when the target is
# already a symlink back to this same file ("are the same file"), which made
# the step look like it had silently done nothing.
ln -sfn "$REPO/management/autostart/plank.desktop" ~/.config/autostart/plank.desktop \
&& echo " [ok] Plank autostart installed"
pgrep -x plank &>/dev/null || { setsid plank </dev/null &>/dev/null & disown; }
fi
# ── 11d. Custom shortcut: region screenshot to clipboard ─────────────────
# Meta+Shift+S -> `xfce4-screenshooter -rc`, the equivalent of the XFCE binding.
# Spectacle is not installed by kde-plasma-desktop, and xfce4-screenshooter
# works fine under Plasma, so this keeps the tool that is already here.
#
# Written as ONE atomic replace rather than a series of kwriteconfig5 calls,
# because khotkeys watches khotkeysrc and rewrites it from its own model on
# every change.
#
# The UUID below is FIXED, not generated. kglobalaccel records the key binding
# in kglobalshortcutsrc against the action's UUID, so a fresh UUID on each run
# cannot take a key that the previous run's UUID already holds: the entry gets
# registered with no shortcut at all, and every re-run leaves another dead
# registration behind. A stable UUID means a re-run re-claims its own binding.
if ! grep -q "^Key=Meta+Shift+S$" ~/.config/khotkeysrc 2>/dev/null; then
python3 - <<'PYEOF'
import pathlib, re
# Fixed so re-runs reclaim the same kglobalaccel registration.
SHORTCUT_UUID = "87a4ba1e-4f01-4a79-9cd1-b73c17d459ea"
p = pathlib.Path.home() / ".config" / "khotkeysrc"
s = p.read_text() if p.exists() else "[Data]\nDataCount=0\n"
# Drop any half-written entry from an earlier failed attempt.
for m in re.findall(r"\[Data_(\d+)\]\n(?:[^\[]*)", s):
blk = re.search(r"\[Data_%s\]\n((?:[^\[]*))" % m, s)
if blk and "Screenshot region to clipboard" in blk.group(1):
s = re.sub(r"\n\[Data_%s[^\]]*\]\n(?:[^\[]*)" % m, "\n", s)
count = int(re.search(r"\[Data\]\nDataCount=(\d+)", s).group(1))
n = count + 1
s = re.sub(r"(\[Data\]\nDataCount=)\d+", r"\g<1>%d" % n, s, count=1)
s = s.rstrip("\n") + """
[Data_%d]
Comment=Select a region and copy it straight to the clipboard
Enabled=true
Name=Screenshot region to clipboard
Type=SIMPLE_ACTION_DATA
[Data_%dActions]
ActionsCount=1
[Data_%dActions0]
CommandURL=xfce4-screenshooter -rc
Type=COMMAND_URL
[Data_%dConditions]
Comment=
ConditionsCount=0
[Data_%dTriggers]
Comment=Simple_action
TriggersCount=1
[Data_%dTriggers0]
Key=Meta+Shift+S
Type=SHORTCUT
Uuid={%s}
""" % (n, n, n, n, n, n, SHORTCUT_UUID)
tmp = p.with_suffix(".nexustmp")
tmp.write_text(s)
tmp.replace(p)
PYEOF
qdbus org.kde.kded5 /modules/khotkeys reread_configuration &>/dev/null \
&& echo " [ok] Meta+Shift+S -> region screenshot to clipboard"
else
echo " [ok] screenshot shortcut already bound"
fi
# ── 12. Apply live changes (if Plasma is running) ────────────────────────
if qdbus org.kde.KWin /KWin reconfigure 2>/dev/null; then
echo " [ok] KWin reconfigured"
# Restart plasmashell to pick up new shell theme
# Restart plasmashell to pick up new shell theme.
# setsid + closed stdio is load-bearing, not tidiness: the restarted shell
# outlives this script, and if it inherits our stdout it holds the write end
# of the caller's pipe open forever. `ncp restore` captures output, so a
# plain `kstart5 plasmashell &` hangs the entire restore after the theme is
# already applied -- which looks like a failure and isn't one.
if command -v kquitapp5 &>/dev/null && command -v kstart5 &>/dev/null; then
kquitapp5 plasmashell 2>/dev/null
sleep 1
kstart5 plasmashell &
setsid kstart5 plasmashell </dev/null >/dev/null 2>&1 &
disown 2>/dev/null || true
echo " [ok] plasmashell restarted"
fi
fi
@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1920 1200" width="1920" height="1200">
<defs>
<linearGradient id="metalBase" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#1a1a2e;stop-opacity:1"/>
<stop offset="35%" style="stop-color:#16213e;stop-opacity:1"/>
<stop offset="65%" style="stop-color:#0f1626;stop-opacity:1"/>
<stop offset="100%" style="stop-color:#0a0e1a;stop-opacity:1"/>
</linearGradient>
<radialGradient id="vignette" cx="50%" cy="50%" r="70%">
<stop offset="0%" style="stop-color:transparent;stop-opacity:0"/>
<stop offset="100%" style="stop-color:#000000;stop-opacity:0.6"/>
</radialGradient>
<pattern id="brushLines" x="0" y="0" width="4" height="4" patternUnits="userSpaceOnUse">
<line x1="0" y1="4" x2="4" y2="0" stroke="#ffffff" stroke-width="0.3" opacity="0.03"/>
</pattern>
<pattern id="machineLines" x="0" y="0" width="100" height="3" patternUnits="userSpaceOnUse">
<line x1="0" y1="1.5" x2="100" y2="1.5" stroke="#ffffff" stroke-width="0.2" opacity="0.025"/>
</pattern>
</defs>
<rect width="1920" height="1200" fill="url(#metalBase)"/>
<rect width="1920" height="1200" fill="url(#brushLines)"/>
<rect width="1920" height="1200" fill="url(#machineLines)"/>
<ellipse cx="960" cy="340" rx="1200" ry="280" fill="#ffffff" opacity="0.012"/>
<ellipse cx="960" cy="220" rx="400" ry="170" fill="#00d4ff" opacity="0.015"/>
<rect width="1920" height="1200" fill="url(#vignette)"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd">
<kcfgfile name=""/>
<group name="General">
</group>
</kcfg>
@@ -1,268 +0,0 @@
import QtQuick 2.15
import QtQuick.Controls 2.15
import org.kde.plasma.core 2.0 as PlasmaCore
/*
* NexusOS kscreenlocker theme.
* Mirrors the SDDM NexusOS-QML aesthetic: logo upper-center,
* clock/date bottom-center, centered password box.
*
* kscreenlocker API differences from SDDM:
* - authenticator.tryUnlock(password) instead of sddm.login(...)
* - authenticator.failed / authenticator.succeeded signals
* - No session selector, no power buttons
* - walletModel, userModel available but not mandatory
*/
Rectangle {
id: root
// kscreenlocker injects these from the surrounding PlasmaShell context
property bool locked: true
readonly property color accentColor: "#8cc63f" // brand_green
readonly property color bgDark: "#1e1526" // base_bg
readonly property color textPrimary: "#f2f2f2"
readonly property color textMuted: "#a8a8a8"
readonly property color fieldBg: "#1f2225" // surface_bg
readonly property color fieldBorder: "#4d3461" // menu_border
readonly property color errorColor: "#da4453"
anchors.fill: parent
color: bgDark
// ── Background image (reuses SDDM background asset) ────────────────
Image {
anchors.fill: parent
source: Qt.resolvedUrl("../../assets/background.svg")
fillMode: Image.PreserveAspectCrop
smooth: true
asynchronous: false
}
Rectangle {
anchors.fill: parent
color: "#000000"
opacity: 0.30
}
// ── Logo area ───────────────────────────────────────────────────────
Item {
id: logoArea
width: 100
height: 100
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: parent.height * 0.10
Rectangle {
anchors.centerIn: parent
width: parent.width * 1.6
height: parent.height * 1.6
radius: width / 2
color: accentColor
opacity: 0.06
}
Image {
anchors.fill: parent
source: Qt.resolvedUrl("../../assets/logo.png")
sourceSize: Qt.size(200, 200)
smooth: true
}
}
Text {
text: "NexusOS"
color: textPrimary
font.family: "Sans"
font.pixelSize: 26
font.letterSpacing: 6
font.weight: Font.Light
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: logoArea.bottom
anchors.topMargin: 14
}
// ── Password box ────────────────────────────────────────────────────
Rectangle {
id: loginBox
width: 340
height: loginColumn.height + 56
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: Qt.rgba(30/255, 21/255, 38/255, 0.80)
radius: 12
border.color: fieldBorder
border.width: 1
SequentialAnimation {
id: shakeAnim
NumberAnimation { target: loginBox; property: "x"; to: loginBox.x - 10; duration: 50 }
NumberAnimation { target: loginBox; property: "x"; to: loginBox.x + 10; duration: 50 }
NumberAnimation { target: loginBox; property: "x"; to: loginBox.x - 6; duration: 50 }
NumberAnimation { target: loginBox; property: "x"; to: loginBox.x + 6; duration: 50 }
NumberAnimation { target: loginBox; property: "x"; to: loginBox.x; duration: 40 }
}
Column {
id: loginColumn
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: 28
spacing: 12
// Username label (read-only; kscreenlocker always locks current session)
Text {
width: parent.width
text: kscreenlocker_userName || userModel.data(userModel.index(0, 0), Qt.DisplayRole) || ""
color: textPrimary
font.pixelSize: 14
font.weight: Font.Medium
horizontalAlignment: Text.AlignHCenter
elide: Text.ElideRight
}
// Password field
Rectangle {
width: parent.width
height: 44
color: fieldBg
radius: 6
border.color: passwordInput.activeFocus ? accentColor : fieldBorder
border.width: 1
TextInput {
id: passwordInput
anchors.fill: parent
anchors.leftMargin: 14
anchors.rightMargin: 14
verticalAlignment: TextInput.AlignVCenter
color: textPrimary
font.pixelSize: 14
echoMode: TextInput.Password
focus: true
clip: true
Keys.onReturnPressed: authenticator.tryUnlock(passwordInput.text)
Keys.onEnterPressed: authenticator.tryUnlock(passwordInput.text)
}
Text {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: 14
text: "Password"
color: textMuted
font.pixelSize: 14
visible: passwordInput.text.length === 0 && !passwordInput.activeFocus
}
}
// Error message
Text {
id: errorMsg
width: parent.width
text: ""
color: errorColor
font.pixelSize: 12
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
visible: text !== ""
}
// Unlock button
Rectangle {
id: unlockButton
width: parent.width
height: 44
radius: 6
color: unlockMouse.pressed
? Qt.darker(accentColor, 1.3)
: unlockMouse.containsMouse
? Qt.lighter(accentColor, 1.15)
: accentColor
Behavior on color { ColorAnimation { duration: 150 } }
Text {
anchors.centerIn: parent
text: "UNLOCK"
color: "#0a0a00" // text_on_accent
font.pixelSize: 14
font.letterSpacing: 3
font.weight: Font.DemiBold
}
MouseArea {
id: unlockMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: authenticator.tryUnlock(passwordInput.text)
}
}
}
}
// ── Authenticator connections ───────────────────────────────────────
Connections {
target: authenticator
function onFailed() {
errorMsg.text = "Incorrect password — try again."
passwordInput.text = ""
passwordInput.forceActiveFocus()
shakeAnim.start()
}
function onSucceeded() {
errorMsg.text = ""
}
function onGraceLockedChanged() {}
function onMessage(msg) {}
function onError(err) {
errorMsg.text = err
}
}
// ── Clock / date (bottom) ───────────────────────────────────────────
Column {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: parent.height * 0.05
spacing: 2
Text {
id: clockText
anchors.horizontalCenter: parent.horizontalCenter
color: textPrimary
font.family: "Sans"
font.pixelSize: 42
font.weight: Font.Thin
}
Text {
id: dateText
anchors.horizontalCenter: parent.horizontalCenter
color: textMuted
font.family: "Sans"
font.pixelSize: 14
font.letterSpacing: 2
}
Timer {
interval: 1000
running: true
repeat: true
triggeredOnStart: true
onTriggered: {
var d = new Date()
clockText.text = Qt.formatTime(d, "hh:mm")
dateText.text = Qt.formatDate(d, "dddd, MMMM d")
}
}
}
}
@@ -1,10 +0,0 @@
[Desktop Entry]
Name=NexusOS
Comment=NexusOS lock screen — dark purple, lime-green accents
Type=Service
X-KDE-ServiceTypes=org.kde.kscreenlocker.Greeter
[ScreenLocker]
Name=NexusOS
Description=NexusOS lock screen — dark purple, lime-green accents
MainScript=contents/ui/LockScreenUi.qml
@@ -45,6 +45,30 @@ large.icon.size=32
button.icon.size=16
toolbar.icon.size=16
[GeneralColors]
# Palette. Without this section Kvantum falls back to its light default for
# view backgrounds, which rendered item views (e.g. the Add Bluetooth Device
# device list) as light-grey text on white. Values mirror ~/.config/kdeglobals.
window.color=#1e1526
base.color=#1e1526
alt.base.color=#1f2225
button.color=#2a2e32
light.color=#3a3d41
mid.light.color=#2e3236
dark.color=#140d1a
mid.color=#241a2d
highlight.color=#88008f
inactive.highlight.color=#5e0066
text.color=#f2f2f2
window.text.color=#f2f2f2
button.text.color=#f2f2f2
disabled.text.color=#6e7173
tooltip.text.color=#f2f2f2
highlight.text.color=#ffffff
link.color=#b8e373
link.visited.color=#a232a8
progress.indicator.text.color=#f2f2f2
[PanelButtonCommand]
inherits=PanelButtonTool
frame=false
@@ -0,0 +1,25 @@
[kdeglobals][KDE]
widgetStyle=kvantum-dark
[kdeglobals][General]
ColorScheme=NexusOS
[kdeglobals][Icons]
Theme=NexusOS
[plasmarc][Theme]
name=NexusOS
[Wallpaper]
Image=NexusOS
[kwinrc][org.kde.kdecoration2]
library=org.kde.kwin.aurorae
theme=__aurorae__svg__NexusOS
[kscreenlockerrc][Greeter]
Theme=org.kde.breeze.desktop
[KSplash]
Theme=com.nexusos.desktop
Engine=KSplashQML
@@ -0,0 +1,95 @@
/*
NexusOS Plasma startup splash.
Deliberately plain QtQuick -- no PlasmaCore import. ksplashqml runs this
before the session is up, and the fewer modules it has to resolve at that
point the fewer ways it has to fail; sizes are proportional to the screen
instead of Units.gridUnit for the same reason.
ksplashqml drives `stage` from 0 to 6 as the session comes up, which fills
the progress bar. The content is deliberately opaque from the start rather
than faded in on stage 2 the way Breeze's splash does: if that signal never
arrives -- as under `ksplashqml --test` -- a stage-gated splash shows nothing
but a blank coloured screen. Palette matches assets/themes/_palette.py.
*/
import QtQuick 2.15
Rectangle {
id: root
color: "#1e1526"
property int stage
onStageChanged: {
if (stage == 6) {
outroAnimation.running = true;
}
}
// Same brushed-metal ground as the Plymouth, SDDM and lock screens. Raster,
// not the source SVG: QtSvg is Tiny 1.2 and drops the <pattern> textures.
Image {
anchors.fill: parent
source: "images/background.png"
fillMode: Image.PreserveAspectCrop
smooth: true
asynchronous: false
}
Item {
id: content
anchors.fill: parent
Image {
id: logo
anchors.horizontalCenter: parent.horizontalCenter
y: parent.height * 0.32
source: "images/logo.png"
width: Math.round(parent.width * 0.15)
fillMode: Image.PreserveAspectFit
smooth: true
asynchronous: false
}
Text {
id: brand
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: logo.bottom
anchors.topMargin: Math.round(parent.height * 0.03)
text: "NexusOS"
color: "#f2f2f2"
font.family: "Sans"
font.pixelSize: Math.round(parent.height * 0.026)
font.letterSpacing: 6
font.weight: Font.Light
}
Rectangle {
id: track
anchors.horizontalCenter: parent.horizontalCenter
y: Math.round(parent.height * 0.62)
width: Math.round(parent.width * 0.18)
height: 3
radius: height / 2
color: "#2e3236"
Rectangle {
height: parent.height
radius: parent.radius
color: "#8cc63f"
width: parent.width * Math.min(root.stage / 6, 1)
Behavior on width {
NumberAnimation { duration: 250; easing.type: Easing.InOutQuad }
}
}
}
}
OpacityAnimator {
id: outroAnimation
target: content
from: 1; to: 0
duration: 400
running: false
}
}
@@ -0,0 +1 @@
../../../../../sddm/NexusOS-QML/assets/background.png

Before

Width:  |  Height:  |  Size: 185 KiB

After

Width:  |  Height:  |  Size: 185 KiB

@@ -0,0 +1,22 @@
{
"KPlugin": {
"Authors": [
{
"Name": "NexusOS"
}
],
"Category": "",
"Description": "Dark purple NexusOS desktop with lime-green accents",
"Id": "com.nexusos.desktop",
"License": "GPL",
"Name": "NexusOS",
"ServiceTypes": [
"Plasma/LookAndFeel"
],
"Version": "1.0",
"Website": ""
},
"X-Plasma-APIVersion": "2",
"X-Plasma-MainScript": "defaults",
"KPackageStructure": "Plasma/LookAndFeel"
}
+63
View File
@@ -0,0 +1,63 @@
/*
NexusOS Plasma panel layout — the XFCE panel, rebuilt with native widgets.
Applied through Plasma's scripting API rather than by editing
plasma-org.kde.plasma.desktop-appletsrc directly: the file is owned by a
running plasmashell, which rewrites it from memory on exit and would
clobber anything written underneath it. Run with:
qdbus org.kde.plasmashell /PlasmaShell evaluateScript "$(cat panel-layout.js)"
Source layout is assets/themes/restore-snapshot/xfconf-xml/xfce4-panel.xml:
a 36px full-width top panel, Whisker menu at the far left with the Nexus N
as its button, everything else pushed to the right — tray, volume,
bluetooth, network, battery, clock.
The XFCE panel carried no window list; Plank showed running apps. So this
adds no task manager either, and the dock keeps that job.
Widget mapping from the XFCE plugins:
whiskermenu -> org.kde.plasma.kickoff (same N button icon)
separator (expand) -> org.kde.plasma.panelspacer
systray + notify -> org.kde.plasma.systemtray (notifications live in it)
genmon network -> networkmanagement, inside the tray
genmon bluetooth -> bluetooth, inside the tray
pulseaudio -> volume, inside the tray
power-manager -> battery, inside the tray
clock -> org.kde.plasma.digitalclock
genmon nexus -> not a panel widget; the dock keeps nexus-core
*/
var panel = panelById(panelIds[0]);
if (!panel) {
panel = new Panel;
}
panel.location = "top";
panel.height = 36; // xfce4-panel.xml: size=36
panel.alignment = "left";
panel.hiding = "none";
// Start from a known state so re-running is idempotent rather than additive.
var existing = panel.widgetIds;
for (var i = 0; i < existing.length; i++) {
var w = panel.widgetById(existing[i]);
if (w) { w.remove(); }
}
var launcher = panel.addWidget("org.kde.plasma.kickoff");
launcher.currentConfigGroup = ["General"];
// __NEXUS_ROOT__ is substituted by install-plasma.sh so a clone in another
// directory, or another user, gets a working path rather than this box's.
launcher.writeConfig("icon", "__NEXUS_ROOT__/assets/n-small.png");
launcher.writeConfig("favoritesPortedToKAstats", true);
panel.addWidget("org.kde.plasma.panelspacer");
var tray = panel.addWidget("org.kde.plasma.systemtray");
var clock = panel.addWidget("org.kde.plasma.digitalclock");
clock.currentConfigGroup = ["Appearance"];
clock.writeConfig("showDate", true);
panel.reloadConfig();
@@ -6,7 +6,7 @@ Type=Service
[KPackageStructure]
X-KDE-ServiceTypes=Plasma/Theme
X-KDE-PluginInfo-Author=Jon
X-KDE-PluginInfo-Author=NexusOS
X-KDE-PluginInfo-Email=
X-KDE-PluginInfo-Name=NexusOS
X-KDE-PluginInfo-Version=1.0
@@ -1,7 +1,7 @@
[SddmGreeterTheme]
Name=NexusOS-QML
Description=Dark brushed-metal lockscreen theme with flat N logo, upper-center branding, and centered login box.
Author=Jon
Author=NexusOS
Version=1.0
Website=
Screenshot=
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

@@ -0,0 +1,10 @@
{
"KPlugin": {
"Authors": [{ "Name": "NexusOS" }],
"Id": "NexusOS",
"License": "GPL",
"Name": "NexusOS",
"Version": "1.0"
},
"X-Plasma-APIVersion": "2"
}
+73 -655
View File
@@ -1,702 +1,120 @@
[Icon Theme]
Name=NexusOS
Comment=NexusOS accent icon theme
Inherits=Papirus-Dark,hicolor
Directories=16x16/apps,22x22/apps,24x24/apps,32x32/apps,48x48/apps,64x64/apps,128x128/apps,16x16/places,22x22/places,24x24/places,32x32/places,48x48/places,64x64/places,128x128/places,16x16/actions,22x22/actions,24x24/actions,32x32/actions,48x48/actions,64x64/actions,128x128/actions,scalable/status,8x8/emblems,16x16/devices,16x16/emblems,16x16/emotes,16x16/mimetypes,16x16/panel,16x16/status,16x16@2x/actions,16x16@2x/apps,16x16@2x/devices,16x16@2x/emblems,16x16@2x/emotes,16x16@2x/mimetypes,16x16@2x/panel,16x16@2x/places,16x16@2x/status,18x18/actions,18x18@2x/actions,22x22/animations,22x22/devices,22x22/emblems,22x22/emotes,22x22/mimetypes,22x22/panel,22x22/status,22x22@2x/actions,22x22@2x/animations,22x22@2x/apps,22x22@2x/devices,22x22@2x/emblems,22x22@2x/emotes,22x22@2x/mimetypes,22x22@2x/panel,22x22@2x/places,22x22@2x/status,24x24/animations,24x24/devices,24x24/emblems,24x24/emotes,24x24/mimetypes,24x24/panel,24x24/status,24x24@2x/actions,24x24@2x/animations,24x24@2x/apps,24x24@2x/devices,24x24@2x/emblems,24x24@2x/emotes,24x24@2x/mimetypes,24x24@2x/panel,24x24@2x/places,24x24@2x/status,32x32/devices,32x32/emblems,32x32/emotes,32x32/mimetypes,32x32/status,32x32@2x/actions,32x32@2x/apps,32x32@2x/devices,32x32@2x/emblems,32x32@2x/emotes,32x32@2x/mimetypes,32x32@2x/places,32x32@2x/status,42x42/apps,48x48/devices,48x48/emblems,48x48/emotes,48x48/mimetypes,48x48/status,48x48@2x/actions,48x48@2x/apps,48x48@2x/devices,48x48@2x/emblems,48x48@2x/emotes,48x48@2x/mimetypes,48x48@2x/places,48x48@2x/status,64x64/devices,64x64/mimetypes,64x64@2x/apps,64x64@2x/devices,64x64@2x/mimetypes,64x64@2x/places,84x84/apps,96x96/apps,96x96/devices,96x96/mimetypes,96x96/places,128x128/devices,128x128/mimetypes,symbolic/actions,symbolic/apps,symbolic/devices,symbolic/emblems,symbolic/emotes,symbolic/mimetypes,symbolic/places,symbolic/status,symbolic/up-to-32
# Inherit breeze-dark, not Papirus-Dark. Breeze's icons carry
# ColorScheme-Text / ColorScheme-Highlight classes that Plasma recolours from
# the active colour scheme, so everything this theme does not override picks up
# the NexusOS palette on its own. Papirus hardcodes its blues (#5294e2), which
# no colour scheme can touch — inheriting it left the whole un-themed surface
# permanently blue. hicolor last, as the freedesktop fallback of last resort.
Inherits=breeze-dark,hicolor
# Only directories that actually exist. This list previously declared 124
# sections against 21 real directories, most of them copied from Papirus.
Directories=16x16/apps,16x16/places,16x16/actions,22x22/apps,22x22/places,22x22/actions,24x24/apps,24x24/places,24x24/actions,32x32/apps,32x32/places,32x32/actions,48x48/apps,48x48/places,48x48/actions,64x64/apps,64x64/places,64x64/actions,128x128/apps,128x128/places,128x128/actions
[16x16/apps]
Context=Applications
Size=16
Type=Fixed
[16x16/places]
Context=Places
Size=16
Type=Fixed
[16x16/actions]
Context=Actions
Size=16
Type=Fixed
[22x22/apps]
Context=Applications
Size=22
Type=Fixed
[22x22/places]
Context=Places
Size=22
Type=Fixed
[22x22/actions]
Context=Actions
Size=22
Type=Fixed
[24x24/apps]
Context=Applications
Size=24
Type=Fixed
[24x24/places]
Context=Places
Size=24
Type=Fixed
[24x24/actions]
Context=Actions
Size=24
Type=Fixed
[32x32/apps]
Context=Applications
Size=32
Type=Fixed
[32x32/places]
Context=Places
Size=32
Type=Fixed
[32x32/actions]
Context=Actions
Size=32
Type=Fixed
[48x48/apps]
Context=Applications
Size=48
Type=Fixed
[48x48/places]
Context=Places
Size=48
Type=Fixed
[48x48/actions]
Context=Actions
Size=48
Type=Fixed
[64x64/apps]
Context=Applications
Size=64
Type=Fixed
[128x128/apps]
Context=Applications
Size=128
MinSize=128
MaxSize=512
Type=Scalable
[16x16/places]
Context=Places
Size=16
Type=Fixed
[22x22/places]
Context=Places
Size=22
Type=Fixed
[24x24/places]
Context=Places
Size=24
Type=Fixed
[32x32/places]
Context=Places
Size=32
Type=Fixed
[48x48/places]
Context=Places
Size=48
Type=Fixed
[64x64/places]
Context=Places
Size=64
Type=Fixed
[64x64/actions]
Context=Actions
Size=64
Type=Fixed
[128x128/apps]
Context=Applications
Size=128
Type=Fixed
[128x128/places]
Context=Places
Size=128
MinSize=128
MaxSize=512
Type=Scalable
[16x16/actions]
Context=Actions
Size=16
Type=Fixed
[22x22/actions]
Context=Actions
Size=22
Type=Fixed
[24x24/actions]
Context=Actions
Size=24
Type=Fixed
[32x32/actions]
Context=Actions
Size=32
Type=Fixed
[48x48/actions]
Context=Actions
Size=48
Type=Fixed
[64x64/actions]
Size=64
Context=Actions
Type=Fixed
[128x128/actions]
Context=Actions
Size=128
Context=Actions
Type=Fixed
[scalable/status]
Size=16
Context=Status
MinSize=8
MaxSize=512
Type=Scalable
[8x8/emblems]
Context=Emblems
Size=8
Type=Fixed
[16x16/devices]
Context=Devices
Size=16
Type=Fixed
[16x16/emblems]
Context=Emblems
Size=16
Type=Fixed
[16x16/emotes]
Context=Emotes
Size=16
Type=Fixed
[16x16/mimetypes]
Context=MimeTypes
Size=16
Type=Fixed
[16x16/panel]
Context=Status
Size=16
Type=Fixed
[16x16/status]
Context=Status
Size=16
Type=Fixed
[16x16@2x/actions]
Context=Actions
Size=16
Scale=2
Type=Fixed
[16x16@2x/apps]
Context=Applications
Size=16
Scale=2
Type=Fixed
[16x16@2x/devices]
Context=Devices
Size=16
Scale=2
Type=Fixed
[16x16@2x/emblems]
Context=Emblems
Size=16
Scale=2
Type=Fixed
[16x16@2x/emotes]
Context=Emotes
Size=16
Scale=2
Type=Fixed
[16x16@2x/mimetypes]
Context=MimeTypes
Size=16
Scale=2
Type=Fixed
[16x16@2x/panel]
Context=Status
Size=16
Scale=2
Type=Fixed
[16x16@2x/places]
Context=Places
Size=16
Scale=2
Type=Fixed
[16x16@2x/status]
Context=Status
Size=16
Scale=2
Type=Fixed
[18x18/actions]
Context=Actions
Size=18
Type=Fixed
[18x18@2x/actions]
Context=Actions
Size=18
Scale=2
Type=Fixed
[22x22/animations]
Context=Animations
Size=22
Type=Fixed
[22x22/devices]
Context=Devices
Size=22
Type=Fixed
[22x22/emblems]
Context=Emblems
Size=22
Type=Fixed
[22x22/emotes]
Context=Emotes
Size=22
Type=Fixed
[22x22/mimetypes]
Context=MimeTypes
Size=22
Type=Fixed
[22x22/panel]
Context=Status
Size=22
Type=Fixed
[22x22/status]
Context=Status
Size=22
Type=Fixed
[22x22@2x/actions]
Context=Actions
Size=22
Scale=2
Type=Fixed
[22x22@2x/animations]
Context=Animations
Size=22
Scale=2
Type=Fixed
[22x22@2x/apps]
Context=Applications
Size=22
Scale=2
Type=Fixed
[22x22@2x/devices]
Context=Devices
Size=22
Scale=2
Type=Fixed
[22x22@2x/emblems]
Context=Emblems
Size=22
Scale=2
Type=Fixed
[22x22@2x/emotes]
Context=Emotes
Size=22
Scale=2
Type=Fixed
[22x22@2x/mimetypes]
Context=MimeTypes
Size=22
Scale=2
Type=Fixed
[22x22@2x/panel]
Context=Status
Size=22
Scale=2
Type=Fixed
[22x22@2x/places]
Context=Places
Size=22
Scale=2
Type=Fixed
[22x22@2x/status]
Context=Status
Size=22
Scale=2
Type=Fixed
[24x24/animations]
Context=Animations
Size=24
Type=Fixed
[24x24/devices]
Context=Devices
Size=24
Type=Fixed
[24x24/emblems]
Context=Emblems
Size=24
Type=Fixed
[24x24/emotes]
Context=Emotes
Size=24
Type=Fixed
[24x24/mimetypes]
Context=MimeTypes
Size=24
Type=Fixed
[24x24/panel]
Context=Status
Size=24
Type=Fixed
[24x24/status]
Context=Status
Size=24
Type=Fixed
[24x24@2x/actions]
Context=Actions
Size=24
Scale=2
Type=Fixed
[24x24@2x/animations]
Context=Animations
Size=24
Scale=2
Type=Fixed
[24x24@2x/apps]
Context=Applications
Size=24
Scale=2
Type=Fixed
[24x24@2x/devices]
Context=Devices
Size=24
Scale=2
Type=Fixed
[24x24@2x/emblems]
Context=Emblems
Size=24
Scale=2
Type=Fixed
[24x24@2x/emotes]
Context=Emotes
Size=24
Scale=2
Type=Fixed
[24x24@2x/mimetypes]
Context=MimeTypes
Size=24
Scale=2
Type=Fixed
[24x24@2x/panel]
Context=Status
Size=24
Scale=2
Type=Fixed
[24x24@2x/places]
Context=Places
Size=24
Scale=2
Type=Fixed
[24x24@2x/status]
Context=Status
Size=24
Scale=2
Type=Fixed
[32x32/devices]
Context=Devices
Size=32
Type=Fixed
[32x32/emblems]
Context=Emblems
Size=32
Type=Fixed
[32x32/emotes]
Context=Emotes
Size=32
Type=Fixed
[32x32/mimetypes]
Context=MimeTypes
Size=32
Type=Fixed
[32x32/status]
Context=Status
Size=32
Type=Fixed
[32x32@2x/actions]
Context=Actions
Size=32
Scale=2
Type=Fixed
[32x32@2x/apps]
Context=Applications
Size=32
Scale=2
Type=Fixed
[32x32@2x/devices]
Context=Devices
Size=32
Scale=2
Type=Fixed
[32x32@2x/emblems]
Context=Emblems
Size=32
Scale=2
Type=Fixed
[32x32@2x/emotes]
Context=Emotes
Size=32
Scale=2
Type=Fixed
[32x32@2x/mimetypes]
Context=MimeTypes
Size=32
Scale=2
Type=Fixed
[32x32@2x/places]
Context=Places
Size=32
Scale=2
Type=Fixed
[32x32@2x/status]
Context=Status
Size=32
Scale=2
Type=Fixed
[42x42/apps]
Context=Applications
Size=42
Type=Fixed
[48x48/devices]
Context=Devices
Size=48
Type=Fixed
[48x48/emblems]
Context=Emblems
Size=48
Type=Fixed
[48x48/emotes]
Context=Emotes
Size=48
Type=Fixed
[48x48/mimetypes]
Context=MimeTypes
Size=48
Type=Fixed
[48x48/status]
Context=Status
Size=48
MinSize=48
MaxSize=512
Type=Scalable
[48x48@2x/actions]
Context=Actions
Size=48
Scale=2
Type=Fixed
[48x48@2x/apps]
Context=Applications
Size=48
Scale=2
Type=Fixed
[48x48@2x/devices]
Context=Devices
Size=48
Scale=2
Type=Fixed
[48x48@2x/emblems]
Context=Emblems
Size=48
Scale=2
Type=Fixed
[48x48@2x/emotes]
Context=Emotes
Size=48
Scale=2
Type=Fixed
[48x48@2x/mimetypes]
Context=MimeTypes
Size=48
Scale=2
Type=Fixed
[48x48@2x/places]
Context=Places
Size=48
Scale=2
Type=Fixed
[48x48@2x/status]
Context=Status
Size=48
MinSize=48
MaxSize=512
Scale=2
Type=Scalable
[64x64/devices]
Context=Devices
Size=64
Type=Fixed
[64x64/mimetypes]
Context=MimeTypes
Size=64
Type=Fixed
[64x64@2x/apps]
Context=Applications
Size=64
Scale=2
Type=Fixed
[64x64@2x/devices]
Context=Devices
Size=64
Scale=2
Type=Fixed
[64x64@2x/mimetypes]
Context=MimeTypes
Size=64
Scale=2
Type=Fixed
[64x64@2x/places]
Context=Places
Size=64
Scale=2
Type=Fixed
[84x84/apps]
Context=Applications
Size=84
Type=Fixed
[96x96/apps]
Context=Applications
Size=96
Type=Fixed
[96x96/devices]
Context=Devices
Size=96
Type=Fixed
[96x96/mimetypes]
Context=MimeTypes
Size=96
Type=Fixed
[96x96/places]
Context=Places
Size=96
Type=Fixed
[128x128/devices]
Context=Devices
Size=128
MinSize=128
MaxSize=512
Type=Scalable
[128x128/mimetypes]
Context=MimeTypes
Size=128
MinSize=128
MaxSize=512
Type=Scalable
[symbolic/actions]
Context=Actions
Size=16
MinSize=16
MaxSize=512
Type=Scalable
[symbolic/apps]
Context=Applications
Size=16
MinSize=16
MaxSize=512
Type=Scalable
[symbolic/devices]
Context=Devices
Size=16
MinSize=16
MaxSize=512
Type=Scalable
[symbolic/emblems]
Context=Emblems
Size=16
MinSize=16
MaxSize=512
Type=Scalable
[symbolic/emotes]
Context=Emotes
Size=16
MinSize=16
MaxSize=512
Type=Scalable
[symbolic/mimetypes]
Context=MimeTypes
Size=16
MinSize=16
MaxSize=512
Type=Scalable
[symbolic/places]
Context=Places
Size=16
MinSize=16
MaxSize=512
Type=Scalable
[symbolic/status]
Context=Status
Size=16
MinSize=16
MaxSize=512
Type=Scalable
[symbolic/up-to-32]
Context=Status
Size=16
MinSize=16
MaxSize=32
Type=Scalable
+11 -3
View File
@@ -112,8 +112,11 @@ KDE/
Main.qml # QML login UI — NexusOS purple/green palette
assets/background.svg assets/logo.png
kscreenlocker/NexusOS/ # Runtime screen lock (Meta+L in KDE)
contents/ui/LockScreenUi.qml # matches SDDM aesthetic; kscreenlocker API
look-and-feel/com.nexusos.desktop/ # Global Theme: selects every component
contents/defaults # what System Settings applies in one click
contents/splash/Splash.qml # startup splash, matches Plymouth/SDDM
wallpaper/NexusOS/ # desktop + lock wallpaper (brushed metal)
konsole/
NexusOS.colorscheme # general terminal colors
@@ -146,7 +149,12 @@ cp assets/themes/KDE/konsole/*.colorscheme assets/themes/KDE/konsole/Promethean.
# SDDM palette (already live; installer will redeploy if needed)
```
**Needs KDE session:** Aurorae decoration, Plasma shell theme, kscreenlocker.
**Needs KDE session:** Aurorae decoration, Plasma shell theme, Global Theme.
The lock screen is Breeze's, with the NexusOS wallpaper set on it. Plasma 5.27
draws the lock screen from a look-and-feel package's `contents/lockscreen`, and
replacing that QML risks a lock screen you cannot get back through, so only the
background is ours.
### First boot into Plasma
+9 -1
View File
@@ -74,7 +74,12 @@ echo "NexusOS theme — restoring wiring from $REPO"
echo "[1/4] Symlinks"
link "$REPO/assets/themes/NexusOS" "$HOME/.themes/NexusOS"
# Icons go in BOTH places on purpose. ~/.icons is the GTK/XFCE legacy path and
# is all this used to install; Qt/KF5 searches XDG data dirs only, so under
# Plasma the theme was never found and every icon silently fell back to Breeze
# (`kiconfinder5 nexusos-logo` returned nothing at all).
link "$REPO/assets/themes/NexusOS-icons" "$HOME/.icons/NexusOS"
link "$REPO/assets/themes/NexusOS-icons" "$HOME/.local/share/icons/NexusOS"
link "$REPO/assets/themes/gtk3-user-overrides.css" "$HOME/.config/gtk-3.0/gtk.css"
echo "[2/4] xfconf (xsettings + xfwm4)"
@@ -98,7 +103,10 @@ echo "[4/4] Icon caches"
gtk-update-icon-cache -f -t "$HOME/.icons/NexusOS" 2>/dev/null \
&& say "ok NexusOS icon cache rebuilt" \
|| say "WARN NexusOS icon cache rebuild failed"
INH="$(grep -i '^Inherits=' "$REPO/assets/themes/NexusOS-icons/index.theme" 2>/dev/null | cut -d= -f2)"
# Inherits is a comma-separated list, so check the first (primary) parent
# rather than the whole string — treating "breeze-dark,hicolor" as one theme
# name found no such directory and warned about a fallback that is installed.
INH="$(grep -i '^Inherits=' "$REPO/assets/themes/NexusOS-icons/index.theme" 2>/dev/null | cut -d= -f2 | cut -d, -f1)"
if [[ -n "$INH" ]]; then
INH_OK=0
for dir in /usr/share/icons ~/.icons ~/.local/share/icons; do
+39
View File
@@ -0,0 +1,39 @@
# NexusOS dock theme — matches the XFCE top panel.
# Colors are taken straight from xfce4-panel's background-rgba
# (0.588, 0.152, 0.773, 0.294) scaled to 0-255: 150;;39;;197;;75.
# Flat fill (start == end) because the panel has no gradient.
[PlankTheme]
TopRoundness=10
BottomRoundness=10
LineWidth=1
OuterStrokeColor=150;;39;;197;;110
FillStartColor=150;;39;;197;;75
FillEndColor=150;;39;;197;;75
InnerStrokeColor=150;;39;;197;;40
# Padding is NOT pixels: Plank renders it as value * icon_size / 10. These are
# tuned for the 48px icons set in dconf — 5px top/bottom, 10px left/right.
# Change icon-size and the borders scale with it; recompute as px * 10 / icon_size.
[PlankDockTheme]
HorizPadding=2.0833
TopPadding=1.0417
BottomPadding=1.0417
ItemPadding=2.0
IndicatorSize=6.0
IconShadowSize=1.0
UrgentBounceHeight=1.6667
LaunchBounceHeight=0.625
FadeOpacity=1.0
ClickTime=300
UrgentBounceTime=600
LaunchBounceTime=600
ActiveTime=300
SlideTime=300
FadeTime=250
HideTime=250
GlowSize=30
GlowTime=10000
GlowPulseTime=2000
UrgentHueShift=150
ItemMoveTime=450
CascadeHide=true
@@ -0,0 +1,9 @@
[Desktop Entry]
Type=Application
Name=NexusOS
Comment=Launch the NexusOS assistant (memory + backend + UI)
Exec=/home/jon/nexus-core/management/nexus-app.sh
Icon=/home/jon/nexus-core/assets/n-small.png
Terminal=false
Categories=Utility;
StartupNotify=false
@@ -0,0 +1,10 @@
[Desktop Entry]
Type=Application
Name=Promethean Terminal
Comment=Launch a terminal with the Promethean environment
Exec=/home/jon/.local/kitty.app/bin/kitty --config /home/jon/nexus-core/bin/promethean/kitty.conf --class promethean-terminal -e bash --rcfile /home/jon/nexus-core/.promethean_bashrc -i
Icon=/home/jon/nexus-core/assets/promethean-terminal.png
Terminal=false
Categories=Utility;TerminalEmulator;
StartupNotify=false
StartupWMClass=promethean-terminal
@@ -1,15 +1,6 @@
[Settings]
gtk-application-prefer-dark-theme=true
gtk-button-images=true
gtk-cursor-theme-name=DMZ-White
gtk-cursor-theme-size=24
gtk-decoration-layout=close,minimize,maximize:
gtk-enable-animations=true
gtk-font-name=Ubuntu 10
gtk-cursor-theme-size=24
gtk-cursor-theme-name=DMZ-White
gtk-icon-theme-name=NexusOS
gtk-menu-images=true
gtk-modules=colorreload-gtk-module
gtk-primary-button-warps-slider=false
gtk-theme-name=NexusOS
gtk-toolbar-style=3
gtk-xft-dpi=98304
@@ -1,12 +1,6 @@
[Settings]
gtk-application-prefer-dark-theme=true
gtk-cursor-theme-name=DMZ-White
gtk-cursor-theme-size=24
gtk-decoration-layout=close,minimize,maximize:
gtk-enable-animations=true
gtk-font-name=Ubuntu 10
gtk-cursor-theme-size=24
gtk-cursor-theme-name=DMZ-White
gtk-icon-theme-name=NexusOS
gtk-modules=colorreload-gtk-module
gtk-primary-button-warps-slider=false
gtk-theme-name=NexusOS
gtk-xft-dpi=98304
@@ -0,0 +1,19 @@
[docks/dock1]
alignment='center'
auto-pinning=true
current-workspace-only=false
dock-items=['microsoft-edge.dockitem', 'promethean-terminal.dockitem', 'nexus-core.dockitem', 'code.dockitem', 'thunar.dockitem']
hide-delay=0
hide-mode='intelligent'
icon-size=48
items-alignment='center'
lock-items=false
offset=0
pinned-only=false
pressure-reveal=false
show-dock-item=false
theme='NexusOS'
tooltips-enabled=true
unhide-delay=0
zoom-enabled=false
zoom-percent=150
@@ -1,2 +1,2 @@
[PlankDockItemPreferences]
Launcher=file:///home/jon/.local/share/applications/microsoft-edge.desktop
Launcher=file:///usr/share/applications/microsoft-edge.desktop
@@ -1,2 +0,0 @@
[PlankDockItemPreferences]
Launcher=file:///home/jon/.local/share/applications/nexus-activate.desktop
@@ -1,11 +1,11 @@
<?xml version="1.1" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<channel name="xfce4-desktop" version="1.0">
<property name="backdrop" type="empty">
<property name="screen0" type="empty">
<property name="monitor0" type="empty">
<property name="image-path" type="string" value="/home/jon/nexus-core/assets/background.png"/>
<property name="last-image" type="empty"/>
<property name="last-image" type="string" value="/home/jon/nexus-core/assets/background.png"/>
<property name="last-single-image" type="empty"/>
<property name="brightness" type="empty"/>
<property name="image-show" type="bool" value="true"/>
@@ -13,13 +13,13 @@
</property>
<property name="monitor1" type="empty">
<property name="image-path" type="string" value="/home/jon/nexus-core/assets/background.png"/>
<property name="last-image" type="empty"/>
<property name="last-image" type="string" value="/home/jon/nexus-core/assets/background.png"/>
<property name="last-single-image" type="empty"/>
<property name="brightness" type="empty"/>
</property>
<property name="monitor2" type="empty">
<property name="image-path" type="string" value="/home/jon/nexus-core/assets/background.png"/>
<property name="last-image" type="empty"/>
<property name="last-image" type="string" value="/home/jon/nexus-core/assets/background.png"/>
<property name="last-single-image" type="empty"/>
<property name="brightness" type="empty"/>
</property>
@@ -32,17 +32,17 @@
<property name="workspace1" type="empty">
<property name="color-style" type="int" value="0"/>
<property name="image-style" type="int" value="5"/>
<property name="last-image" type="string" value="/usr/share/xfce4/backdrops/linuxmint.jpg"/>
<property name="last-image" type="string" value="/home/jon/nexus-core/assets/background.png"/>
</property>
<property name="workspace2" type="empty">
<property name="color-style" type="int" value="0"/>
<property name="image-style" type="int" value="5"/>
<property name="last-image" type="string" value="/usr/share/xfce4/backdrops/linuxmint.jpg"/>
<property name="last-image" type="string" value="/home/jon/nexus-core/assets/background.png"/>
</property>
<property name="workspace3" type="empty">
<property name="color-style" type="int" value="0"/>
<property name="image-style" type="int" value="5"/>
<property name="last-image" type="string" value="/usr/share/xfce4/backdrops/linuxmint.jpg"/>
<property name="last-image" type="string" value="/home/jon/nexus-core/assets/background.png"/>
</property>
</property>
<property name="monitoreDP-1" type="empty">
@@ -1,4 +1,4 @@
<?xml version="1.1" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<channel name="xfce4-panel" version="1.0">
<property name="configver" type="int" value="2"/>
@@ -38,7 +38,14 @@
<property name="dark-mode" type="bool" value="true"/>
</property>
<property name="plugins" type="empty">
<property name="plugin-1" type="empty"/>
<property name="plugin-2" type="string" value="power-manager-plugin"/>
<property name="plugin-3" type="empty">
<property name="items" type="empty"/>
</property>
<property name="plugin-4" type="empty">
<property name="items" type="empty"/>
</property>
<property name="plugin-5" type="string" value="separator">
<property name="items" type="array">
<value type="string" value="17640946043.desktop"/>
@@ -81,15 +88,11 @@
</property>
<property name="button-icon" type="string" value="/home/jon/nexus-core/assets/n-small.png"/>
<property name="recent" type="array">
<value type="string" value="microsoft-edge.desktop"/>
<value type="string" value="xfce4-taskmanager.desktop"/>
<value type="string" value="virtualbox.desktop"/>
<value type="string" value="virt-manager.desktop"/>
<value type="string" value="org.gnome.DiskUtility.desktop"/>
<value type="string" value="org.x.editor.desktop"/>
<value type="string" value="promethean-terminal.desktop"/>
<value type="string" value="claude-usage-widget.desktop"/>
<value type="string" value="kitty.desktop"/>
<value type="string" value="putty.desktop"/>
<value type="string" value="code.desktop"/>
</property>
<property name="view-mode" type="int" value="2"/>
@@ -107,6 +110,7 @@
<property name="show-notifications" type="bool" value="true"/>
<property name="known-players" type="string" value="Microsoft Edge"/>
</property>
<property name="plugin-9" type="empty"/>
<property name="plugin-10" type="string" value="notification-plugin"/>
<property name="plugin-11" type="empty"/>
<property name="plugin-12" type="string" value="clock">
@@ -118,8 +122,13 @@
<property name="digital-date-format" type="string" value="%m/%d/%Y"/>
<property name="digital-date-font" type="string" value="Sans 8"/>
</property>
<property name="plugin-13" type="string" value="genmon">
<property name="digital-time-format" type="empty"/>
<property name="digital-layout" type="empty"/>
<property name="digital-date-font" type="empty"/>
<property name="digital-time-font" type="empty"/>
</property>
<property name="plugin-14" type="empty"/>
<property name="plugin-13" type="string" value="genmon"/>
<property name="plugin-15" type="string" value="genmon"/>
<property name="plugin-16" type="string" value="genmon"/>
</property>
@@ -1,4 +1,4 @@
<?xml version="1.1" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<channel name="xsettings" version="1.0">
<property name="Net" type="empty">
@@ -27,6 +27,8 @@
<property name="MonospaceFontName" type="empty"/>
<property name="IconSizes" type="empty"/>
<property name="KeyThemeName" type="empty"/>
<property name="ToolbarStyle" type="empty"/>
<property name="ToolbarIconSize" type="empty"/>
<property name="MenuImages" type="bool" value="false"/>
<property name="ButtonImages" type="empty"/>
<property name="MenuBarAccel" type="empty"/>
@@ -35,8 +37,6 @@
<property name="DecorationLayout" type="string" value="icon,menu:minimize,maximize,close"/>
<property name="DialogsUseHeader" type="empty"/>
<property name="TitlebarMiddleClick" type="empty"/>
<property name="ToolbarStyle" type="empty"/>
<property name="ToolbarIconSize" type="empty"/>
<property name="IMPreeditStyle" type="empty"/>
<property name="IMStatusStyle" type="empty"/>
<property name="IMModule" type="empty"/>