              activate      #!/bin/sh
#!/bin/sh
# Generated by shikumi (spec/home.md section 4.3); links this home's files.
set -f
umask 022
rc=0
fail() { echo "shikumi: home: $*" >&2; rc=1; }
note() { echo "shikumi: home: $*" >&2; }
case ${1:-} in /?*) ;; *) echo "usage: activate <profile path>" >&2; exit 2 ;; esac
case ${HOME:-} in /?*) ;; *) echo "shikumi: home: HOME is not set" >&2; exit 1 ;; esac
base=$1/files
state=$HOME/.local/state/shikumi
reg=$state/home-managed
reg_new=$state/home-managed.new
mkdir -p "$state" || { fail "cannot create $state"; exit 1; }
: > "$reg_new" || { fail "cannot write $reg_new"; exit 1; }
listed() { [ -f "$1" ] || return 1; while IFS= read -r listed_p; do [ "$listed_p" = "$2" ] && return 0; done < "$1"; return 1; }
prune() {
    [ -f "$reg" ] || return 0
    while IFS= read -r prune_p; do
        listed "$reg_new" "$prune_p" && continue
        prune_t=$HOME/$prune_p
        if [ -L "$prune_t" ] && [ "$(readlink "$prune_t")" = "$base/$prune_p" ]; then rm -f "$prune_t" || fail "cannot remove $prune_t"; fi
    done < "$reg"
}
parents() {
    parents_d=${1%/*}
    while [ "$parents_d" != "$HOME" ]; do
        if [ -L "$parents_d" ]; then fail "$parents_d is a symlink, not linking $1"; return 1; fi
        parents_d=${parents_d%/*}
    done
    mkdir -p "${1%/*}"
}
vacate() {
    vacate_t=$HOME/$1
    [ -e "$vacate_t" ] || [ -L "$vacate_t" ] || return 0
    if [ -L "$vacate_t" ] && [ "$(readlink "$vacate_t")" = "$base/$1" ]; then return 0; fi
    vacate_b=$vacate_t.before-shikumi; vacate_i=0
    while [ -e "$vacate_b" ] || [ -L "$vacate_b" ]; do vacate_i=$((vacate_i + 1)); vacate_b=$vacate_t.before-shikumi.$vacate_i; done
    mv "$vacate_t" "$vacate_b" && note "moved $vacate_t to $vacate_b"
}
link() {
    link_t=$HOME/$1
    if [ -L "$link_t" ] && [ "$(readlink "$link_t")" = "$base/$1" ]; then return 0; fi
    parents "$link_t" || return 0
    { vacate "$1" && ln -s "$base/$1" "$link_t"; } || fail "cannot link $link_t"
}
echo '.config/hypr/hyprland.lua' >> "$reg_new"
echo '.config/quickshell/aura/Bar.qml' >> "$reg_new"
echo '.config/quickshell/aura/Diamond.qml' >> "$reg_new"
echo '.config/quickshell/aura/Frame.qml' >> "$reg_new"
echo '.config/quickshell/aura/Launcher.qml' >> "$reg_new"
echo '.config/quickshell/aura/Lock.qml' >> "$reg_new"
echo '.config/quickshell/aura/Login.qml' >> "$reg_new"
echo '.config/quickshell/aura/Notifications.qml' >> "$reg_new"
echo '.config/quickshell/aura/Osd.qml' >> "$reg_new"
echo '.config/quickshell/aura/Theme.qml' >> "$reg_new"
echo '.config/quickshell/aura/shell.qml' >> "$reg_new"
prune
link '.config/hypr/hyprland.lua'
link '.config/quickshell/aura/Bar.qml'
link '.config/quickshell/aura/Diamond.qml'
link '.config/quickshell/aura/Frame.qml'
link '.config/quickshell/aura/Launcher.qml'
link '.config/quickshell/aura/Lock.qml'
link '.config/quickshell/aura/Login.qml'
link '.config/quickshell/aura/Notifications.qml'
link '.config/quickshell/aura/Osd.qml'
link '.config/quickshell/aura/Theme.qml'
link '.config/quickshell/aura/shell.qml'
mv -f "$reg_new" "$reg" || fail "cannot write $reg"
exit $rc
       files              .config              hypr              hyprland.lua      <-- Made by the Aura (desktop/hyprland.lua). The default of the system is
-- in /etc/xdg/hypr. The file of the home profile
-- (homes/<user>/home.lua), in ~/.config/hypr, has priority.

hl.monitor({
    output   = "",
    mode     = "preferred",
    position = "auto",
    scale    = "auto",
})

local terminal = "foot"

hl.on("hyprland.start", function()
    hl.exec_cmd("pipewire")
    hl.exec_cmd("pipewire-pulse")
    hl.exec_cmd("wireplumber")
    hl.exec_cmd("qs -c aura")
end)

hl.on("hyprland.shutdown", function()
    os.execute('pkill -u "$(id -u)" -x wireplumber; pkill -u "$(id -u)" -x pipewire-pulse; pkill -u "$(id -u)" -x pipewire')
    os.execute('fusermount3 -u -z "$XDG_RUNTIME_DIR/doc" 2>/dev/null')
end)

hl.env("XCURSOR_SIZE", "24")
hl.env("HYPRCURSOR_SIZE", "24")

hl.config({
    general = {
        gaps_in     = 5,
        gaps_out    = 12,
        border_size = 2,
        col = {
            active_border   = "rgba(6fd3e8ee)",
            inactive_border = "rgba(24486aaa)",
        },
        layout = "dwindle",
    },
    decoration = {
        rounding = 0,
    },
    animations = {
        enabled = true,
    },
    input = {
        kb_layout    = "br",
        kb_variant   = "abnt2",
        follow_mouse = 1,
    },
    misc = {
        force_default_wallpaper = 0,
        disable_hyprland_logo   = true,
        disable_splash_rendering = true,
        background_color        = "rgb(070b14)",
    },
    ecosystem = {
        no_update_news  = true,
        no_donation_nag = true,
    },
})

local mainMod = "SUPER"

hl.bind(mainMod .. " + Q", hl.dsp.exec_cmd(terminal))
hl.bind(mainMod .. " + Return", hl.dsp.exec_cmd(terminal))
hl.bind(mainMod .. " + C", hl.dsp.window.close())
hl.bind(mainMod .. " + M", hl.dsp.exec_cmd("hyprctl dispatch 'hl.dsp.exit()'"))
hl.bind(mainMod .. " + V", hl.dsp.window.float({ action = "toggle" }))
hl.bind(mainMod .. " + R", hl.dsp.exec_cmd("qs -c aura ipc call launcher toggle"))
hl.bind(mainMod .. " + L", hl.dsp.exec_cmd("qs -c aura ipc call lock lock"))
hl.bind(mainMod .. " + left",  hl.dsp.focus({ direction = "left" }))
hl.bind(mainMod .. " + right", hl.dsp.focus({ direction = "right" }))
hl.bind(mainMod .. " + up",    hl.dsp.focus({ direction = "up" }))
hl.bind(mainMod .. " + down",  hl.dsp.focus({ direction = "down" }))
for i = 1, 10 do
    local key = i % 10
    hl.bind(mainMod .. " + " .. key,         hl.dsp.focus({ workspace = i }))
    hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i }))
end
hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(),   { mouse = true })
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true, repeating = true })
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"),      { locked = true, repeating = true })
hl.bind("XF86AudioMute",        hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"),     { locked = true, repeating = true })
hl.bind("XF86MonBrightnessUp",   hl.dsp.exec_cmd("brightnessctl -q -n set 5%+ && qs -c aura ipc call osd brightness"), { locked = true, repeating = true })
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl -q -n set 5%- && qs -c aura ipc call osd brightness"), { locked = true, repeating = true })
       
quickshell              aura       
       Bar.qml      %import QtQuick
import Quickshell
import Quickshell.Hyprland
import Quickshell.Wayland

PanelWindow {
    id: bar
    required property var modelData
    screen: modelData

    anchors { top: true; left: true; right: true }
    implicitHeight: Theme.barHeight
    color: Theme.panel
    WlrLayershell.namespace: "aura-bar"

    SystemClock { id: clock; precision: SystemClock.Minutes }

    Rectangle {
        anchors.bottom: parent.bottom
        width: parent.width; height: 1
        color: Theme.line
    }

    Row {
        anchors.verticalCenter: parent.verticalCenter
        x: 16
        spacing: 20

        Row {
            anchors.verticalCenter: parent.verticalCenter
            spacing: 8
            Diamond { anchors.verticalCenter: parent.verticalCenter; size: 8; color: Theme.gold }
            Text {
                anchors.verticalCenter: parent.verticalCenter
                text: "AURA"
                color: Theme.gold
                font.family: Theme.titleFont; font.pixelSize: 14; font.letterSpacing: 4
            }
        }

        Row {
            anchors.verticalCenter: parent.verticalCenter
            spacing: 6
            Repeater {
                model: 5
                Diamond {
                    required property int index
                    readonly property int wsId: index + 1
                    readonly property bool focused: Hyprland.focusedWorkspace !== null
                        && Hyprland.focusedWorkspace.id === wsId
                    readonly property bool occupied: Hyprland.workspaces.values.some(w => w.id === wsId)
                    anchors.verticalCenter: parent.verticalCenter
                    size: focused || occupied ? 8 : 6
                    filled: focused
                    color: focused || occupied ? Theme.cyan : Theme.cyanDim
                    lineWidth: occupied ? 1.5 : 1
                }
            }
        }
    }

    Text {
        anchors.centerIn: parent
        width: Math.min(implicitWidth, parent.width * 0.5)
        elide: Text.ElideRight
        text: Hyprland.activeToplevel ? Hyprland.activeToplevel.title : ""
        color: Theme.muted
        font.family: Theme.textFont; font.pixelSize: 13
    }

    Row {
        anchors.verticalCenter: parent.verticalCenter
        anchors.right: parent.right; anchors.rightMargin: 16
        spacing: 12
        Text {
            anchors.baseline: time.baseline
            text: Qt.formatDateTime(clock.date, "ddd dd MMM").toUpperCase()
            color: Theme.muted
            font.family: Theme.titleFont; font.pixelSize: 12; font.letterSpacing: 2
        }
        Text {
            id: time
            text: Qt.formatDateTime(clock.date, "hh:mm")
            color: Theme.gold
            font.family: Theme.titleFont; font.pixelSize: 18; font.letterSpacing: 1
        }
    }
}
       Diamond.qml      import QtQuick

Item {
    id: root
    property real size: 8
    property color color: Theme.cyan
    property bool filled: false
    property real lineWidth: 1.5

    implicitWidth: Math.ceil(root.size * 1.5)
    implicitHeight: implicitWidth

    Rectangle {
        anchors.centerIn: parent
        width: root.size; height: root.size
        rotation: 45
        antialiasing: true
        color: root.filled ? root.color : "transparent"
        border.color: root.color
        border.width: root.filled ? 0 : root.lineWidth
    }
}
       	Frame.qml      	import QtQuick
import QtQuick.Shapes

Item {
    id: root
    property real cut: Theme.cut
    property color fill: Theme.panel
    property color stroke: Theme.line

    Shape {
        anchors.fill: parent
        preferredRendererType: Shape.CurveRenderer
        ShapePath {
            fillColor: root.fill
            strokeColor: root.stroke
            strokeWidth: 1
            startX: root.cut; startY: 0.5
            PathLine { x: root.width - 0.5; y: 0.5 }
            PathLine { x: root.width - 0.5; y: root.height - root.cut }
            PathLine { x: root.width - root.cut; y: root.height - 0.5 }
            PathLine { x: 0.5; y: root.height - 0.5 }
            PathLine { x: 0.5; y: root.cut }
            PathLine { x: root.cut; y: 0.5 }
        }
    }
}
       Launcher.qml      import QtQuick
import Quickshell
import Quickshell.Io
import Quickshell.Wayland

Scope {
    id: root
    property bool open: false
    readonly property var matches: filter(DesktopEntries.applications.values, search.text)

    function filter(apps, query) {
        const q = query.toLowerCase();
        return apps
            .filter(a => !a.noDisplay && (q === ""
                || a.name.toLowerCase().includes(q)
                || a.genericName.toLowerCase().includes(q)))
            .sort((a, b) => a.name.localeCompare(b.name));
    }

    function launch(i) {
        const entry = root.matches[i];
        if (entry) {
            entry.execute();
            root.open = false;
        }
    }

    onOpenChanged: {
        if (open) {
            search.text = "";
            list.currentIndex = 0;
            search.forceActiveFocus();
        }
    }

    IpcHandler {
        target: "launcher"
        function toggle(): void { root.open = !root.open; }
        function show(): void { root.open = true; }
        function hide(): void { root.open = false; }
    }

    PanelWindow {
        id: win
        visible: root.open
        anchors { top: true; bottom: true; left: true; right: true }
        color: "#b8070b14"
        exclusionMode: ExclusionMode.Ignore
        WlrLayershell.layer: WlrLayer.Overlay
        WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive
        WlrLayershell.namespace: "aura-launcher"

        MouseArea { anchors.fill: parent; onClicked: root.open = false }

        Frame {
            id: box
            x: (win.width - width) / 2
            y: 150
            width: 520
            height: content.implicitHeight + 36
            cut: 18
            stroke: Theme.cyan

            MouseArea { anchors.fill: parent }

            Column {
                id: content
                x: 0; y: 22
                width: parent.width
                spacing: 14

                Text {
                    x: 24
                    text: "// LAUNCH"
                    color: Theme.gold
                    font.family: Theme.titleFont; font.pixelSize: 12; font.letterSpacing: 3
                }

                Item {
                    x: 24
                    width: parent.width - 48; height: 34
                    Text {
                        id: arrow
                        anchors.verticalCenter: search.verticalCenter
                        text: ">"
                        color: Theme.cyan
                        font.family: Theme.titleFont; font.pixelSize: 18
                    }
                    TextInput {
                        id: search
                        anchors.left: arrow.right; anchors.leftMargin: 10
                        anchors.right: parent.right
                        color: Theme.text
                        selectionColor: Theme.cyanDim
                        font.family: Theme.textFont; font.pixelSize: 20
                        focus: true
                        onTextChanged: list.currentIndex = 0
                        Keys.onEscapePressed: root.open = false
                        Keys.onDownPressed: list.incrementCurrentIndex()
                        Keys.onUpPressed: list.decrementCurrentIndex()
                        Keys.onReturnPressed: root.launch(list.currentIndex)
                        Keys.onEnterPressed: root.launch(list.currentIndex)
                    }
                    Rectangle {
                        anchors.bottom: parent.bottom
                        width: parent.width; height: 1
                        color: Theme.line
                    }
                }

                ListView {
                    id: list
                    width: parent.width
                    height: Math.min(count, 6) * 52
                    clip: true
                    model: root.matches
                    highlightMoveDuration: 0

                    delegate: Item {
                        id: item
                        required property var modelData
                        required property int index
                        readonly property bool current: ListView.isCurrentItem
                        width: list.width; height: 52

                        Rectangle {
                            anchors.fill: parent
                            color: item.current ? Theme.panelHi : "transparent"
                        }
                        Rectangle {
                            width: 2; height: parent.height
                            color: item.current ? Theme.cyan : "transparent"
                        }
                        Diamond {
                            x: 24
                            anchors.verticalCenter: parent.verticalCenter
                            size: 10
                            color: item.current ? Theme.cyan : Theme.cyanDim
                        }
                        Column {
                            x: 56
                            anchors.verticalCenter: parent.verticalCenter
                            width: parent.width - 80
                            spacing: 2
                            Text {
                                width: parent.width
                                elide: Text.ElideRight
                                text: item.modelData.name
                                color: Theme.text
                                font.family: Theme.textFont; font.pixelSize: 15
                                font.weight: item.current ? Font.DemiBold : Font.Normal
                            }
                            Text {
                                width: parent.width
                                elide: Text.ElideRight
                                visible: text !== ""
                                text: item.modelData.genericName || item.modelData.comment
                                color: Theme.muted
                                font.family: Theme.textFont; font.pixelSize: 12
                            }
                        }
                        MouseArea {
                            anchors.fill: parent
                            hoverEnabled: true
                            onEntered: list.currentIndex = item.index
                            onClicked: root.launch(item.index)
                        }
                    }
                }

                Text {
                    x: 24
                    text: "UP/DOWN SELECT    ENTER OPEN    ESC CLOSE"
                    color: Theme.muted
                    font.family: Theme.titleFont; font.pixelSize: 11; font.letterSpacing: 2
                }
            }
        }
    }
}
       Lock.qml      zimport QtQuick
import Quickshell
import Quickshell.Io
import Quickshell.Services.Pam
import Quickshell.Wayland

Scope {
    id: root
    // the password lives only between Enter and the answer of PAM
    property string password: ""
    property bool failed: false

    function lock() {
        root.failed = false;
        sessionLock.locked = true;
    }

    function submit(password) {
        if (pam.active)
            return;
        root.password = password;
        root.failed = false;
        pam.start();
    }

    IpcHandler {
        target: "lock"
        function lock(): void { root.lock(); }
        // for the scenario: "locked" only after the compositor confirms
        function state(): string {
            return sessionLock.secure ? "locked" : sessionLock.locked ? "locking" : "unlocked";
        }
    }

    PamContext {
        id: pam
        config: "quickshell"
        onPamMessage: {
            if (responseRequired)
                respond(root.password);
        }
        onCompleted: result => {
            root.password = "";
            if (result === PamResult.Success)
                sessionLock.locked = false;
            else
                root.failed = true;
        }
    }

    WlSessionLock {
        id: sessionLock

        WlSessionLockSurface {
            color: Theme.void_

            Login {
                anchors.fill: parent
                user: Quickshell.env("USER") ?? ""
                action: "UNLOCK"
                footer: "SESSION LOCKED"
                busy: pam.active
                message: pam.active ? "Checking..." : root.failed ? "Wrong password. Try again." : ""
                messageIsError: root.failed && !pam.active
                onSubmitted: (user, password) => root.submit(password)
                onEdited: root.failed = false
                Component.onCompleted: focusInput()
            }
        }
    }
}
       	Login.qml      "ˇimport QtQuick
import QtQuick.Shapes
import Quickshell

Rectangle {
    id: root
    property string user: ""
    property bool userEditable: false
    property string action: "UNLOCK"
    property string host: ""
    property string footer: ""
    property string message: ""
    property bool messageIsError: false
    property bool busy: false
    property bool showForm: true

    signal submitted(string user, string password)
    signal edited()

    function focusInput() {
        if (root.userEditable && userInput.text === "")
            userInput.forceActiveFocus();
        else
            field.forceActiveFocus();
    }

    function send() {
        if (root.busy || userInput.text === "" || field.text === "")
            return;
        root.submitted(userInput.text, field.text);
        field.text = "";
    }

    color: Theme.void_

    SystemClock { id: clock; precision: SystemClock.Minutes }

    // the rings and the sights behind the clock and the frame
    Item {
        anchors.centerIn: parent
        width: 760; height: 760

        Rectangle {
            anchors.centerIn: parent
            width: 760; height: 760; radius: 380
            color: "transparent"
            border.color: Theme.panelHi
        }
        Shape {
            anchors.fill: parent
            preferredRendererType: Shape.CurveRenderer
            ShapePath {
                fillColor: "transparent"
                strokeColor: Theme.line
                strokeWidth: 1
                strokeStyle: ShapePath.DashLine
                dashPattern: [2, 12]
                PathAngleArc {
                    centerX: 380; centerY: 380
                    radiusX: 300; radiusY: 300
                    startAngle: 0; sweepAngle: 360
                }
            }
        }
        Rectangle {
            anchors.centerIn: parent
            width: 460; height: 460; radius: 230
            color: "transparent"
            border.color: Theme.line
            opacity: 0.7
        }
        Rectangle { x: 380; y: 0; width: 1; height: 150; color: Theme.line }
        Rectangle { x: 380; y: 610; width: 1; height: 150; color: Theme.line }
        Rectangle { x: 0; y: 380; width: 150; height: 1; color: Theme.line }
        Rectangle { x: 610; y: 380; width: 150; height: 1; color: Theme.line }
    }

    Column {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: box.top
        anchors.bottomMargin: 70
        spacing: 6
        Text {
            anchors.horizontalCenter: parent.horizontalCenter
            text: Qt.formatDateTime(clock.date, "hh:mm")
            color: Theme.gold
            font.family: Theme.titleFont; font.pixelSize: 72; font.letterSpacing: 4
        }
        Text {
            anchors.horizontalCenter: parent.horizontalCenter
            text: Qt.formatDateTime(clock.date, "dddd \u00b7 dd MMM yyyy").toUpperCase()
            color: Theme.muted
            font.family: Theme.titleFont; font.pixelSize: 14; font.letterSpacing: 4.5
        }
    }

    Frame {
        id: box
        visible: root.showForm
        anchors.centerIn: parent
        width: 400
        height: content.implicitHeight + 52
        cut: 18

        Column {
            id: content
            x: 28; y: 26
            width: parent.width - 56
            spacing: 18

            Item {
                width: parent.width; height: 16
                Diamond {
                    id: mark
                    anchors.verticalCenter: parent.verticalCenter
                    size: 8
                    color: Theme.gold
                }
                Text {
                    anchors.left: mark.right; anchors.leftMargin: 10
                    anchors.verticalCenter: parent.verticalCenter
                    text: "AURA R:1"
                    color: Theme.gold
                    font.family: Theme.titleFont; font.pixelSize: 14; font.letterSpacing: 4.5
                }
                Text {
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                    text: root.host.toUpperCase()
                    color: Theme.muted
                    font.family: Theme.titleFont; font.pixelSize: 12; font.letterSpacing: 2.4
                }
            }

            Column {
                width: parent.width
                spacing: 6
                Text {
                    text: "USER"
                    color: userInput.activeFocus ? Theme.cyan : Theme.muted
                    font.family: Theme.titleFont; font.pixelSize: 12; font.letterSpacing: 3
                }
                Rectangle {
                    width: parent.width; height: 44
                    color: Theme.void_
                    border.color: userInput.activeFocus ? Theme.cyan : Theme.line
                    TextInput {
                        id: userInput
                        anchors.fill: parent
                        anchors.leftMargin: 12; anchors.rightMargin: 12
                        verticalAlignment: TextInput.AlignVCenter
                        text: root.user
                        readOnly: !root.userEditable || root.busy
                        activeFocusOnPress: root.userEditable
                        color: Theme.text
                        selectionColor: Theme.cyanDim
                        font.family: Theme.textFont; font.pixelSize: 16
                        onAccepted: field.forceActiveFocus()
                        Keys.onTabPressed: field.forceActiveFocus()
                    }
                }
            }

            Column {
                width: parent.width
                spacing: 6
                Text {
                    text: "PASSWORD"
                    color: field.activeFocus ? Theme.cyan : Theme.muted
                    font.family: Theme.titleFont; font.pixelSize: 12; font.letterSpacing: 3
                }
                Rectangle {
                    width: parent.width; height: 44
                    color: Theme.void_
                    border.color: root.messageIsError ? Theme.drain
                        : field.activeFocus ? Theme.cyan : Theme.line
                    TextInput {
                        id: field
                        anchors.fill: parent
                        anchors.leftMargin: 12; anchors.rightMargin: 12
                        verticalAlignment: TextInput.AlignVCenter
                        echoMode: TextInput.Password
                        passwordCharacter: "\u25c6"
                        readOnly: root.busy
                        color: Theme.text
                        selectionColor: Theme.cyanDim
                        font.family: Theme.textFont; font.pixelSize: 16
                        onTextChanged: root.edited()
                        onAccepted: root.send()
                        Keys.onEscapePressed: text = ""
                        Keys.onBacktabPressed: {
                            if (root.userEditable)
                                userInput.forceActiveFocus();
                        }
                    }
                }
            }

            Item {
                width: parent.width; height: 18
                Diamond {
                    id: sign
                    anchors.verticalCenter: parent.verticalCenter
                    visible: root.message !== ""
                    size: 6
                    filled: true
                    color: root.messageIsError ? Theme.drain : Theme.cyan
                }
                Text {
                    anchors.left: sign.right; anchors.leftMargin: 8
                    anchors.right: parent.right
                    anchors.verticalCenter: parent.verticalCenter
                    elide: Text.ElideRight
                    text: root.message
                    color: root.messageIsError ? Theme.drain : Theme.muted
                    font.family: Theme.textFont; font.pixelSize: 13
                }
            }

            Frame {
                width: parent.width; height: 44
                cut: 10
                fill: root.busy ? Theme.cyanDim : Theme.cyan
                stroke: fill
                Text {
                    anchors.centerIn: parent
                    text: root.action
                    color: Theme.void_
                    font.family: Theme.titleFont; font.pixelSize: 15; font.letterSpacing: 4.8
                }
                MouseArea {
                    anchors.fill: parent
                    onClicked: root.send()
                }
            }
        }
    }

    Text {
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.bottom: parent.bottom
        anchors.bottomMargin: 36
        text: root.footer
        color: Theme.muted
        font.family: Theme.titleFont; font.pixelSize: 12; font.letterSpacing: 3
    }
}
       Notifications.qml      4import QtQuick
import Quickshell
import Quickshell.Services.Notifications
import Quickshell.Wayland

Scope {
    NotificationServer {
        id: server
        bodySupported: true
        actionsSupported: false
        imageSupported: false
        onNotification: n => { n.tracked = true; }
    }

    PanelWindow {
        visible: balloons.count > 0
        anchors { top: true; right: true }
        margins { top: Theme.barHeight + 16; right: 16 }
        implicitWidth: 360
        implicitHeight: column.implicitHeight
        color: "transparent"
        exclusionMode: ExclusionMode.Ignore
        WlrLayershell.layer: WlrLayer.Overlay
        WlrLayershell.namespace: "aura-notifications"

        Column {
            id: column
            width: 360
            spacing: 10

            Repeater {
                id: balloons
                model: server.trackedNotifications

                Item {
                    id: balloon
                    required property var modelData
                    readonly property bool critical: modelData.urgency === NotificationUrgency.Critical
                    // expireTimeout comes in milliseconds, as in D-Bus
                    // (Quickshell 0.3.2 keeps it so, but the
                    // documentation says seconds); -1 is the default of
                    // the server.
                    readonly property int timeout: critical || modelData.expireTimeout === 0 ? 0
                        : modelData.expireTimeout > 0 ? modelData.expireTimeout : 5000
                    property real remaining: 1

                    width: 360
                    height: body.implicitHeight + 30

                    Frame {
                        anchors.fill: parent
                        stroke: balloon.critical ? Theme.drain : Theme.line
                    }

                    Column {
                        id: body
                        x: 18; y: 14
                        width: parent.width - 36
                        spacing: 6

                        Row {
                            spacing: 8
                            Diamond {
                                anchors.verticalCenter: parent.verticalCenter
                                size: 6; filled: true
                                color: balloon.critical ? Theme.drain : Theme.cyan
                            }
                            Text {
                                text: balloon.critical ? "URGENT" : (balloon.modelData.appName || "NOTICE")
                                color: balloon.critical ? Theme.drain : Theme.cyan
                                font.family: Theme.titleFont; font.pixelSize: 12; font.letterSpacing: 3
                                font.capitalization: Font.AllUppercase
                            }
                        }
                        Text {
                            width: parent.width
                            wrapMode: Text.Wrap
                            text: balloon.modelData.summary
                            color: Theme.text
                            font.family: Theme.textFont; font.pixelSize: 15; font.weight: Font.DemiBold
                        }
                        Text {
                            width: parent.width
                            wrapMode: Text.Wrap
                            visible: text !== ""
                            textFormat: Text.PlainText
                            text: balloon.modelData.body
                            color: Theme.muted
                            font.family: Theme.textFont; font.pixelSize: 13
                        }
                    }

                    Rectangle {
                        visible: balloon.timeout > 0
                        x: 1; anchors.bottom: parent.bottom; anchors.bottomMargin: 1
                        width: (parent.width - Theme.cut - 1) * balloon.remaining
                        height: 2
                        color: Theme.cyan
                    }

                    // The expiration and the progress line go through a
                    // Timer, in the event loop, and do not depend on the
                    // frame of the window.
                    readonly property real born: Date.now()
                    Timer {
                        running: balloon.timeout > 0
                        interval: 100; repeat: true
                        onTriggered: {
                            balloon.remaining = Math.max(0, 1 - (Date.now() - balloon.born) / balloon.timeout);
                            if (balloon.remaining === 0)
                                balloon.modelData.expire();
                        }
                    }

                    MouseArea {
                        anchors.fill: parent
                        onClicked: balloon.modelData.dismiss()
                    }
                }
            }
        }
    }
}
       Osd.qml      fimport QtQuick
import Quickshell
import Quickshell.Io
import Quickshell.Services.Pipewire
import Quickshell.Wayland

Scope {
    id: root
    property string kind: "volume"
    property real value: 0
    property bool muted: false
    property bool shown: false
    property bool armed: false

    readonly property var sink: Pipewire.defaultAudioSink

    PwObjectTracker { objects: root.sink ? [ root.sink ] : [] }

    Connections {
        target: root.sink ? root.sink.audio : null
        function onVolumeChanged() { root.showVolume(); }
        function onMutedChanged() { root.showVolume(); }
    }

    Timer { running: true; interval: 2000; onTriggered: root.armed = true }
    Timer { id: hide; interval: 1500; onTriggered: root.shown = false }

    function pop() {
        root.shown = true;
        hide.restart();
    }

    function showVolume() {
        if (!root.armed || !root.sink || !root.sink.audio)
            return;
        root.kind = "volume";
        root.value = root.sink.audio.volume;
        root.muted = root.sink.audio.muted;
        root.pop();
    }

    Process {
        id: readBrightness
        command: [ "brightnessctl", "-m" ]
        stdout: StdioCollector {
            // one line: device,class,current,percent,max
            onStreamFinished: {
                const f = this.text.trim().split(",");
                if (f.length >= 5 && Number(f[4]) > 0) {
                    root.kind = "brightness";
                    root.value = Number(f[2]) / Number(f[4]);
                    root.muted = false;
                    root.pop();
                }
            }
        }
    }

    IpcHandler {
        target: "osd"
        function brightness(): void { readBrightness.running = true; }
        function volume(): void { root.armed = true; root.showVolume(); }
        function state(): string { return root.shown ? root.kind : "hidden"; }
    }

    PanelWindow {
        visible: root.shown
        anchors { bottom: true }
        margins { bottom: 96 }
        implicitWidth: 340
        implicitHeight: 64
        color: "transparent"
        exclusionMode: ExclusionMode.Ignore
        mask: Region {}
        WlrLayershell.layer: WlrLayer.Overlay
        WlrLayershell.namespace: "aura-osd"

        Frame { anchors.fill: parent }

        Row {
            x: 20
            anchors.verticalCenter: parent.verticalCenter
            spacing: 14

            Diamond {
                anchors.verticalCenter: parent.verticalCenter
                size: 8; filled: !root.muted
                color: root.muted ? Theme.drain : Theme.cyan
            }
            Text {
                width: 96
                anchors.verticalCenter: parent.verticalCenter
                text: root.kind === "brightness" ? "BRIGHT" : (root.muted ? "MUTED" : "VOLUME")
                color: root.muted ? Theme.drain : Theme.cyan
                font.family: Theme.titleFont; font.pixelSize: 13; font.letterSpacing: 3
            }
            Item {
                width: 140; height: 6
                anchors.verticalCenter: parent.verticalCenter
                Rectangle { anchors.fill: parent; color: Theme.panelHi }
                Rectangle {
                    width: parent.width * Math.max(0, Math.min(1, root.value))
                    height: parent.height
                    color: root.muted ? Theme.muted : Theme.cyan
                }
            }
            Text {
                anchors.verticalCenter: parent.verticalCenter
                text: Math.round(root.value * 100)
                color: Theme.text
                font.family: Theme.titleFont; font.pixelSize: 15
            }
        }
    }
}
       	Theme.qml      Špragma Singleton
import QtQuick
import Quickshell

Singleton {
    // background and surfaces
    readonly property color void_: "#070b14"
    readonly property color panel: "#0d1626"
    readonly property color panelHi: "#13203a"
    readonly property color line: "#24486a"
    // accents: focus and selection, the mark and the clock, error and
    // urgency
    readonly property color cyan: "#6fd3e8"
    readonly property color cyanDim: "#3b8ea6"
    readonly property color gold: "#d8b25a"
    readonly property color drain: "#e0506a"
    // text
    readonly property color text: "#e4edf5"
    readonly property color muted: "#8ea3b8"

    // Share Tech Mono in the labels, the titles, and the clock; Google
    // Sans Code in the text
    readonly property string titleFont: "Share Tech Mono"
    readonly property string textFont: "Google Sans Code"

    readonly property int barHeight: 36
    readonly property int cut: 14
}
       	shell.qml       ˛import QtQuick
import Quickshell

ShellRoot {
    Variants {
        model: Quickshell.screens
        Bar {}
    }
    Launcher {}
    Notifications {}
    Osd {}
    Lock {}
}
       sw       @/shikumi/software/profile-env-1/gah319gkv351810vy3hv2wjacbpkzl5g