Integrate swaybg and swayosd into the new shell
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
hl.on("hyprland.start", function()
|
||||
hl.exec_cmd("uwsm-app -- hypridle")
|
||||
hl.exec_cmd("omarchy-restart-shell")
|
||||
hl.exec_cmd("uwsm-app -- hypridle")
|
||||
hl.exec_cmd("uwsm-app -- fcitx5 --disable notificationitem")
|
||||
hl.exec_cmd("uwsm-app -- swaybg -i ~/.config/omarchy/current/background -m fill")
|
||||
hl.exec_cmd("/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1")
|
||||
hl.exec_cmd("omarchy-first-run")
|
||||
hl.exec_cmd("omarchy-powerprofiles-init")
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
-- Volume, brightness, keyboard backlight, and touchpad controls.
|
||||
o.bind("XF86AudioRaiseVolume", "Volume up", "omarchy-swayosd-client --output-volume raise", { locked = true, repeating = true })
|
||||
o.bind("XF86AudioLowerVolume", "Volume down", "omarchy-swayosd-client --output-volume lower", { locked = true, repeating = true })
|
||||
o.bind("XF86AudioMute", "Mute", "omarchy-swayosd-client --output-volume mute-toggle", { locked = true, repeating = true })
|
||||
o.bind("XF86AudioMicMute", "Mute microphone", "omarchy-audio-input-mute", { locked = true, repeating = true })
|
||||
o.bind("XF86AudioRaiseVolume", "Volume up", "omarchy-audio-output-volume raise", { locked = true, repeating = true })
|
||||
o.bind("XF86AudioLowerVolume", "Volume down", "omarchy-audio-output-volume lower", { locked = true, repeating = true })
|
||||
o.bind("XF86AudioMute", "Mute", "omarchy-audio-output-volume mute-toggle", { locked = true })
|
||||
o.bind("XF86AudioMicMute", "Mute microphone", "omarchy-audio-input-mute", { locked = true })
|
||||
o.bind("XF86MonBrightnessUp", "Brightness up", "omarchy-brightness-display +5%", { locked = true, repeating = true })
|
||||
o.bind("XF86MonBrightnessDown", "Brightness down", "omarchy-brightness-display 5%-", { locked = true, repeating = true })
|
||||
o.bind("SHIFT + XF86MonBrightnessUp", "Brightness maximum", "omarchy-brightness-display 100%", { locked = true, repeating = true })
|
||||
@@ -15,15 +15,15 @@ o.bind("XF86TouchpadOn", "Enable touchpad", "omarchy-toggle-touchpad on", { lock
|
||||
o.bind("XF86TouchpadOff", "Disable touchpad", "omarchy-toggle-touchpad off", { locked = true })
|
||||
|
||||
-- Precise volume and brightness controls.
|
||||
o.bind("ALT + XF86AudioRaiseVolume", "Volume up precise", "omarchy-swayosd-client --output-volume +1", { locked = true, repeating = true })
|
||||
o.bind("ALT + XF86AudioLowerVolume", "Volume down precise", "omarchy-swayosd-client --output-volume -1", { locked = true, repeating = true })
|
||||
o.bind("ALT + XF86AudioRaiseVolume", "Volume up precise", "omarchy-audio-output-volume +1", { locked = true, repeating = true })
|
||||
o.bind("ALT + XF86AudioLowerVolume", "Volume down precise", "omarchy-audio-output-volume -1", { locked = true, repeating = true })
|
||||
o.bind("ALT + XF86MonBrightnessUp", "Brightness up precise", "omarchy-brightness-display +1%", { locked = true, repeating = true })
|
||||
o.bind("ALT + XF86MonBrightnessDown", "Brightness down precise", "omarchy-brightness-display 1%-", { locked = true, repeating = true })
|
||||
|
||||
-- Media controls.
|
||||
o.bind("XF86AudioNext", "Next track", "omarchy-swayosd-client --playerctl next", { locked = true })
|
||||
o.bind("XF86AudioPause", "Pause", "omarchy-swayosd-client --playerctl play-pause", { locked = true })
|
||||
o.bind("XF86AudioPlay", "Play", "omarchy-swayosd-client --playerctl play-pause", { locked = true })
|
||||
o.bind("XF86AudioPrev", "Previous track", "omarchy-swayosd-client --playerctl previous", { locked = true })
|
||||
o.bind("XF86AudioNext", "Next track", "omarchy-audio-player next", { locked = true })
|
||||
o.bind("XF86AudioPause", "Pause", "omarchy-audio-player play-pause", { locked = true })
|
||||
o.bind("XF86AudioPlay", "Play", "omarchy-audio-player play-pause", { locked = true })
|
||||
o.bind("XF86AudioPrev", "Previous track", "omarchy-audio-player previous", { locked = true })
|
||||
|
||||
o.bind("SUPER + XF86AudioMute", "Switch audio output", "omarchy-audio-output-switch", { locked = true })
|
||||
|
||||
@@ -79,7 +79,7 @@ Omarchy is built on:
|
||||
| **Omarchy shell** | Status bar + notifications (Quickshell) | `~/.config/omarchy/shell.json` |
|
||||
| **Walker** | App launcher | `~/.config/walker/` |
|
||||
| **Alacritty/Foot/Kitty/Ghostty** | Terminals | `~/.config/<terminal>/` |
|
||||
| **SwayOSD** | On-screen display | `~/.config/swayosd/` |
|
||||
| **Omarchy OSD** | On-screen display | Quickshell plugin |
|
||||
|
||||
## Command Discovery
|
||||
|
||||
@@ -111,7 +111,7 @@ Run `omarchy --help` for the full list. The most common groups:
|
||||
| Group | Purpose | Example |
|
||||
|-------|---------|---------|
|
||||
| `omarchy refresh` | Reset config to defaults (backs up first) | `omarchy refresh shell` |
|
||||
| `omarchy restart` | Restart a service/app | `omarchy restart shell` |
|
||||
| `omarchy restart` | Restart a service/app | `omarchy-restart-shell` |
|
||||
| `omarchy toggle` | Toggle feature on/off | `omarchy toggle nightlight` |
|
||||
| `omarchy theme` | Theme management | `omarchy theme set <name>` |
|
||||
| `omarchy install` | Install optional software / packages | `omarchy install docker dbs` |
|
||||
@@ -160,7 +160,7 @@ inside a single long-running Quickshell process (`omarchy-shell`).
|
||||
The shell hot-reloads `shell.json` on save — no restart needed for layout
|
||||
changes. For more invasive changes (new plugin, packaged update):
|
||||
|
||||
**Commands:** `omarchy restart shell`, `omarchy refresh shell`, `omarchy launch settings`
|
||||
**Commands:** `omarchy-restart-shell`, `omarchy refresh shell`, `omarchy launch settings`
|
||||
|
||||
### Terminals
|
||||
|
||||
@@ -201,7 +201,7 @@ cp ~/.config/hypr/bindings.conf ~/.config/hypr/bindings.conf.bak.$(date +%s)
|
||||
|
||||
# 4. Apply changes
|
||||
# - Hyprland: auto-reloads on save, but MUST validate with `hyprctl reload` and `hyprctl configerrors`
|
||||
# - Omarchy shell: shell.json hot-reloads; use `omarchy restart shell` for plugin/widget code changes
|
||||
# - Omarchy shell: shell.json hot-reloads; use `omarchy-restart-shell` for plugin/widget code changes
|
||||
# - Walker: MUST restart with `omarchy restart walker`
|
||||
# - Terminals: MUST restart with `omarchy restart terminal`
|
||||
```
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
"setup.config.hypridle": {"icon":"","label":"Hypridle","keywords":"idle","action":"omarchy-launch-config-editor ~/.config/hypr/hypridle.conf && omarchy-restart-hypridle"},
|
||||
"setup.config.hyprlock": {"icon":"","label":"Hyprlock","keywords":"lock","action":"omarchy-launch-config-editor ~/.config/hypr/hyprlock.conf"},
|
||||
"setup.config.hyprsunset": {"icon":"","label":"Hyprsunset","keywords":"night light","action":"omarchy-launch-config-editor ~/.config/hypr/hyprsunset.conf && omarchy-restart-hyprsunset"},
|
||||
"setup.config.swayosd": {"icon":"","label":"Swayosd","action":"omarchy-launch-config-editor ~/.config/swayosd/config.toml && omarchy-restart-swayosd"},
|
||||
"setup.config.osd": {"icon":"","label":"OSD","action":"omarchy launch settings"},
|
||||
"setup.config.walker": {"icon":"","label":"Walker","keywords":"launcher","action":"omarchy-launch-config-editor ~/.config/walker/config.toml && omarchy-restart-walker"},
|
||||
"setup.config.bar": {"icon":"","label":"Bar","keywords":"quickshell shell config","action":"omarchy-launch-settings bar"},
|
||||
"setup.config.xcompose": {"icon":"","label":"XCompose","keywords":"compose key","action":"omarchy-launch-config-editor ~/.XCompose && omarchy-restart-xcompose"},
|
||||
@@ -311,7 +311,7 @@
|
||||
"update.channel.dev": {"icon":"🔴","label":"Dev","keywords":"development","action":"omarchy-launch-floating-terminal-with-presentation 'omarchy-channel-set dev'"},
|
||||
"update.process.hypridle": {"icon":"","label":"Hypridle","keywords":"restart","action":"omarchy-restart-hypridle"},
|
||||
"update.process.hyprsunset": {"icon":"","label":"Hyprsunset","keywords":"restart","action":"omarchy-restart-hyprsunset"},
|
||||
"update.process.swayosd": {"icon":"","label":"Swayosd","keywords":"restart","action":"omarchy-restart-swayosd"},
|
||||
"update.process.osd": {"icon":"","label":"OSD","keywords":"restart","action":"omarchy-restart-shell"},
|
||||
"update.process.walker": {"icon":"","label":"Walker","keywords":"restart launcher","action":"omarchy-restart-walker"},
|
||||
"update.process.shell": {"icon":"","label":"Shell","keywords":"restart bar quickshell omarchy-shell","action":"omarchy-restart-shell"},
|
||||
"update.config.hyprland": {"icon":"","label":"Hyprland","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-hyprland"},
|
||||
@@ -319,7 +319,7 @@
|
||||
"update.config.hyprlock": {"icon":"","label":"Hyprlock","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-hyprlock"},
|
||||
"update.config.hyprsunset": {"icon":"","label":"Hyprsunset","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-hyprsunset"},
|
||||
"update.config.plymouth": {"icon":"","label":"Plymouth","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-plymouth"},
|
||||
"update.config.swayosd": {"icon":"","label":"Swayosd","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-swayosd"},
|
||||
"update.config.osd": {"icon":"","label":"OSD","keywords":"refresh","action":"omarchy-restart-shell"},
|
||||
"update.config.tmux": {"icon":"","label":"Tmux","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-tmux"},
|
||||
"update.config.walker": {"icon":"","label":"Walker","keywords":"refresh","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-walker"},
|
||||
"update.config.shell": {"icon":"","label":"Shell","keywords":"refresh bar quickshell","action":"omarchy-launch-floating-terminal-with-presentation omarchy-refresh-shell"},
|
||||
|
||||
@@ -121,7 +121,7 @@ quickshell ipc -p $OMARCHY_PATH/default/quickshell/omarchy-shell call shell ping
|
||||
```
|
||||
|
||||
Hyprland starts the shell through `omarchy-restart-shell` on boot.
|
||||
Use `omarchy restart shell` to reload the long-running shell process.
|
||||
Use `omarchy-restart-shell` to reload the long-running shell process.
|
||||
|
||||
A convenience wrapper, [`omarchy-shell-ipc`](../../../bin/omarchy-shell-ipc),
|
||||
starts the shell if it is not already running, then forwards a `call`. It
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string omarchyPath: ""
|
||||
property var shell: null
|
||||
property var manifest: null
|
||||
|
||||
readonly property string home: Quickshell.env("HOME")
|
||||
readonly property string currentBackgroundLink: home + "/.config/omarchy/current/background"
|
||||
|
||||
property string currentBackground: ""
|
||||
property string displayedBackground: ""
|
||||
property string incomingBackground: ""
|
||||
property string oldBackground: ""
|
||||
property bool finishingTransition: false
|
||||
property int backgroundVersion: 0
|
||||
property real revealProgress: 1
|
||||
|
||||
function imageUrl(path) {
|
||||
if (!path) return ""
|
||||
return "file://" + path
|
||||
}
|
||||
|
||||
function refreshBackground() {
|
||||
if (!readlinkProc.running) readlinkProc.running = true
|
||||
}
|
||||
|
||||
function setBackground(path) {
|
||||
path = String(path || "").trim()
|
||||
if (!path || path === currentBackground) return
|
||||
currentBackground = path
|
||||
backgroundVersion += 1
|
||||
|
||||
if (!displayedBackground) {
|
||||
displayedBackground = path
|
||||
revealProgress = 1
|
||||
return
|
||||
}
|
||||
|
||||
revealAnimation.stop()
|
||||
finishingTransition = false
|
||||
oldBackground = displayedBackground
|
||||
incomingBackground = path
|
||||
revealProgress = 0
|
||||
}
|
||||
|
||||
function openSelector() {
|
||||
if (!bgSwitchProc.running) bgSwitchProc.running = true
|
||||
}
|
||||
|
||||
Process {
|
||||
id: bgSwitchProc
|
||||
command: ["bash", "-lc", "background=$(omarchy-theme-bg-switcher); [[ -n $background ]] && omarchy-theme-bg-set \"$background\""]
|
||||
onExited: root.refreshBackground()
|
||||
}
|
||||
|
||||
Process {
|
||||
id: readlinkProc
|
||||
command: ["readlink", "-f", root.currentBackgroundLink]
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: root.setBackground(String(text || "").trim())
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 100
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: root.refreshBackground()
|
||||
}
|
||||
|
||||
NumberAnimation {
|
||||
id: revealAnimation
|
||||
target: root
|
||||
property: "revealProgress"
|
||||
from: 0
|
||||
to: 1
|
||||
duration: 420
|
||||
easing.type: Easing.InOutCubic
|
||||
onFinished: {
|
||||
if (root.incomingBackground) {
|
||||
root.displayedBackground = root.incomingBackground
|
||||
root.finishingTransition = true
|
||||
}
|
||||
root.revealProgress = 1
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: refreshBackground()
|
||||
|
||||
Variants {
|
||||
model: Quickshell.screens
|
||||
|
||||
PanelWindow {
|
||||
id: panel
|
||||
required property var modelData
|
||||
|
||||
screen: modelData
|
||||
visible: true
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
color: "transparent"
|
||||
property bool maskReady: false
|
||||
WlrLayershell.namespace: "omarchy-background"
|
||||
WlrLayershell.layer: WlrLayer.Background
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
|
||||
Image {
|
||||
id: base
|
||||
anchors.fill: parent
|
||||
source: root.imageUrl(root.displayedBackground)
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
asynchronous: true
|
||||
cache: false
|
||||
onStatusChanged: {
|
||||
if (status === Image.Ready && root.finishingTransition) {
|
||||
root.incomingBackground = ""
|
||||
root.oldBackground = ""
|
||||
root.finishingTransition = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: incomingFrame
|
||||
anchors.fill: parent
|
||||
source: root.imageUrl(root.incomingBackground)
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
asynchronous: true
|
||||
cache: false
|
||||
visible: root.incomingBackground !== "" && status === Image.Ready
|
||||
opacity: root.revealProgress >= 1 ? 1 : 0.001
|
||||
onStatusChanged: if (status === Image.Ready && root.incomingBackground) revealCanvas.prepareImage()
|
||||
}
|
||||
|
||||
Image {
|
||||
id: oldFrame
|
||||
anchors.fill: parent
|
||||
source: root.imageUrl(root.oldBackground)
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
asynchronous: true
|
||||
cache: false
|
||||
visible: root.oldBackground !== "" && root.revealProgress < 1
|
||||
onStatusChanged: if (status === Image.Ready && root.incomingBackground) revealCanvas.requestPaint()
|
||||
}
|
||||
|
||||
Canvas {
|
||||
id: revealCanvas
|
||||
anchors.fill: parent
|
||||
visible: root.incomingBackground !== "" && root.revealProgress < 1 && incomingFrame.status === Image.Ready && oldFrame.status === Image.Ready
|
||||
opacity: panel.maskReady ? 1 : 0
|
||||
renderTarget: Canvas.FramebufferObject
|
||||
renderStrategy: Canvas.Immediate
|
||||
|
||||
readonly property real slant: -0.18
|
||||
|
||||
function prepareImage() {
|
||||
var src = root.imageUrl(root.incomingBackground)
|
||||
if (!src) return
|
||||
if (isImageLoaded(src)) {
|
||||
requestPaint()
|
||||
} else if (!isImageLoading(src)) {
|
||||
loadImage(src)
|
||||
}
|
||||
}
|
||||
|
||||
onImageLoaded: function(url) {
|
||||
if (url === root.imageUrl(root.incomingBackground)) requestPaint()
|
||||
}
|
||||
|
||||
onPaint: {
|
||||
var ctx = getContext("2d")
|
||||
ctx.reset()
|
||||
ctx.clearRect(0, 0, width, height)
|
||||
|
||||
var src = root.imageUrl(root.incomingBackground)
|
||||
if (!src || incomingFrame.status !== Image.Ready || root.revealProgress >= 1) return
|
||||
if (!isImageLoaded(src)) {
|
||||
prepareImage()
|
||||
return
|
||||
}
|
||||
|
||||
var iw = incomingFrame.sourceSize.width
|
||||
var ih = incomingFrame.sourceSize.height
|
||||
if (iw <= 0 || ih <= 0 || width <= 0 || height <= 0) return
|
||||
|
||||
var sx = 0
|
||||
var sy = 0
|
||||
var sw = iw
|
||||
var sh = ih
|
||||
if (iw / ih > width / height) {
|
||||
sw = ih * width / height
|
||||
sx = (iw - sw) / 2
|
||||
} else {
|
||||
sh = iw * height / width
|
||||
sy = (ih - sh) / 2
|
||||
}
|
||||
|
||||
var center = width / 2
|
||||
var reach = width / 2 + Math.abs(slant) * height + 4
|
||||
var spread = reach * root.revealProgress
|
||||
var leftTop = center - spread
|
||||
var leftBottom = center - spread + slant * height
|
||||
var rightTop = center + spread
|
||||
var rightBottom = center + spread + slant * height
|
||||
|
||||
ctx.save()
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(center, 0)
|
||||
ctx.lineTo(leftTop, 0)
|
||||
ctx.lineTo(leftBottom, height)
|
||||
ctx.lineTo(center, height)
|
||||
ctx.closePath()
|
||||
ctx.clip()
|
||||
ctx.drawImage(src, sx, sy, sw, sh, 0, 0, width, height)
|
||||
ctx.restore()
|
||||
|
||||
ctx.save()
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(center, 0)
|
||||
ctx.lineTo(rightTop, 0)
|
||||
ctx.lineTo(rightBottom, height)
|
||||
ctx.lineTo(center, height)
|
||||
ctx.closePath()
|
||||
ctx.clip()
|
||||
ctx.drawImage(src, sx, sy, sw, sh, 0, 0, width, height)
|
||||
ctx.restore()
|
||||
|
||||
if (!panel.maskReady && root.incomingBackground && root.revealProgress === 0) {
|
||||
Qt.callLater(function() {
|
||||
panel.maskReady = true
|
||||
revealAnimation.restart()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
function onRevealProgressChanged() { revealCanvas.requestPaint() }
|
||||
function onIncomingBackgroundChanged() {
|
||||
panel.maskReady = false
|
||||
revealCanvas.prepareImage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onDoubleClicked: root.openSelector()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "omarchy.background",
|
||||
"name": "Background",
|
||||
"version": "1.0.0",
|
||||
"author": "Omarchy",
|
||||
"description": "Desktop background renderer with click handling and transitions",
|
||||
"kinds": ["service"],
|
||||
"activation": "startup",
|
||||
"entryPoints": { "service": "Background.qml" }
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import qs.Commons
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property string omarchyPath: ""
|
||||
property var shell: null
|
||||
property var manifest: null
|
||||
|
||||
property bool opened: false
|
||||
property string icon: ""
|
||||
property string message: ""
|
||||
property int value: 0
|
||||
property int maxValue: 100
|
||||
property bool hasProgress: true
|
||||
|
||||
function clamp(v, min, max) { return Math.max(min, Math.min(max, v)) }
|
||||
|
||||
function iconFor(name, percent) {
|
||||
var n = String(name || "").toLowerCase()
|
||||
if (n === "volume-muted" || n === "volume-mute" || n === "muted" || n === "mute") return ""
|
||||
if (n === "volume-low") return ""
|
||||
if (n === "volume-medium") return ""
|
||||
if (n === "volume-high" || n === "volume") return ""
|
||||
if (n === "microphone-muted" || n === "microphone-off" || n === "mic-muted" || n === "mic-off") return ""
|
||||
if (n === "microphone" || n === "mic") return ""
|
||||
if (n === "keyboard") return ""
|
||||
if (n === "brightness" || n === "display") return ""
|
||||
if (n === "touchpad") return ""
|
||||
if (n === "touch" || n === "touchscreen") return ""
|
||||
if (n === "media" || n === "player") return ""
|
||||
if (percent <= 0) return ""
|
||||
if (percent <= 33) return ""
|
||||
if (percent <= 66) return ""
|
||||
return ""
|
||||
}
|
||||
|
||||
function show(iconName, rawMessage, rawValue, rawMax, rawProgressText) {
|
||||
maxValue = Math.max(1, parseInt(rawMax || "100", 10))
|
||||
var parsed = parseInt(rawValue || "0", 10)
|
||||
hasProgress = rawValue !== "" && !isNaN(parsed) && rawMessage === ""
|
||||
value = hasProgress ? clamp(parsed, 0, maxValue) : 0
|
||||
message = String(rawMessage || (hasProgress ? (rawProgressText || Math.round(value * 100 / maxValue) + "%") : ""))
|
||||
icon = iconFor(iconName, hasProgress ? Math.round(value * 100 / maxValue) : -1)
|
||||
opened = true
|
||||
hideTimer.restart()
|
||||
}
|
||||
|
||||
function open(payloadJson) {
|
||||
try {
|
||||
var p = JSON.parse(payloadJson || "{}")
|
||||
show(p.icon || "", p.message || "", p.value === undefined ? "" : String(p.value), p.max === undefined ? "100" : String(p.max), p.progressText || "")
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
function close() { opened = false }
|
||||
|
||||
Timer {
|
||||
id: hideTimer
|
||||
interval: 1200
|
||||
onTriggered: root.opened = false
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "osd"
|
||||
function show(payloadJson: string): string {
|
||||
root.open(payloadJson)
|
||||
return "ok"
|
||||
}
|
||||
function close(): string { root.close(); return "ok" }
|
||||
function state(): string { return root.opened ? "open" : "closed" }
|
||||
function ping(): string { return "ok" }
|
||||
}
|
||||
|
||||
PanelWindow {
|
||||
id: panel
|
||||
visible: root.opened
|
||||
anchors { top: true; bottom: true; left: true; right: true }
|
||||
color: "transparent"
|
||||
WlrLayershell.namespace: "omarchy-osd"
|
||||
WlrLayershell.layer: WlrLayer.Overlay
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
|
||||
Rectangle {
|
||||
id: card
|
||||
width: 269
|
||||
height: 68
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: 67
|
||||
color: Color.alpha(Color.background, 0.97)
|
||||
border.color: Color.foreground
|
||||
border.width: 2
|
||||
radius: 0
|
||||
opacity: root.opened ? 1 : 0
|
||||
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 16
|
||||
spacing: 16
|
||||
Text {
|
||||
width: 28
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: root.icon
|
||||
font.family: "JetBrainsMono Nerd Font"
|
||||
font.pixelSize: 27
|
||||
color: Color.foreground
|
||||
}
|
||||
Rectangle {
|
||||
visible: root.hasProgress
|
||||
width: visible ? 142 : 0
|
||||
height: 6
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: Color.alpha(Color.foreground, 0.45)
|
||||
Rectangle {
|
||||
height: parent.height
|
||||
width: parent.width * (root.hasProgress ? root.value / root.maxValue : 0)
|
||||
color: Color.accent
|
||||
}
|
||||
}
|
||||
Text {
|
||||
width: root.hasProgress ? 41 : 190
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: root.message
|
||||
font.family: "JetBrainsMono Nerd Font"
|
||||
font.bold: true
|
||||
font.pixelSize: 14
|
||||
color: Color.foreground
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"id": "omarchy.osd",
|
||||
"name": "On-screen display",
|
||||
"version": "1.0.0",
|
||||
"description": "Quickshell volume, brightness, and status overlays.",
|
||||
"kinds": ["panel"],
|
||||
"activation": "persistent",
|
||||
"keepLoaded": true,
|
||||
"entryPoints": { "panel": "Osd.qml" }
|
||||
}
|
||||
@@ -5,28 +5,67 @@
|
||||
"centerAnchor": "calendar",
|
||||
"layout": {
|
||||
"left": [
|
||||
{ "id": "omarchy" },
|
||||
{ "id": "workspaces" }
|
||||
{
|
||||
"id": "omarchy"
|
||||
},
|
||||
{
|
||||
"id": "workspaces"
|
||||
}
|
||||
],
|
||||
"center": [
|
||||
{ "id": "calendar", "format": "dddd HH:mm", "formatAlt": "dd MMMM 'W'ww yyyy", "verticalFormat": "HH\n—\nmm" },
|
||||
{ "id": "weatherFlyout" },
|
||||
{ "id": "update" },
|
||||
{ "id": "voxtype" },
|
||||
{ "id": "screenRecording" },
|
||||
{ "id": "idle" },
|
||||
{ "id": "notifications" }
|
||||
{
|
||||
"id": "calendar",
|
||||
"format": "dddd HH:mm",
|
||||
"formatAlt": "dd MMMM 'W'ww yyyy",
|
||||
"verticalFormat": "HH\n\u2014\nmm"
|
||||
},
|
||||
{
|
||||
"id": "weatherFlyout"
|
||||
},
|
||||
{
|
||||
"id": "update"
|
||||
},
|
||||
{
|
||||
"id": "voxtype"
|
||||
},
|
||||
{
|
||||
"id": "screenRecording"
|
||||
},
|
||||
{
|
||||
"id": "idle"
|
||||
},
|
||||
{
|
||||
"id": "notifications"
|
||||
}
|
||||
],
|
||||
"right": [
|
||||
{ "id": "tray" },
|
||||
{ "id": "bluetoothPanel" },
|
||||
{ "id": "networkPanel" },
|
||||
{ "id": "audioPanel" },
|
||||
{ "id": "battery" },
|
||||
{ "id": "systemStats" },
|
||||
{ "id": "controlCenter" }
|
||||
{
|
||||
"id": "tray"
|
||||
},
|
||||
{
|
||||
"id": "bluetoothPanel"
|
||||
},
|
||||
{
|
||||
"id": "networkPanel"
|
||||
},
|
||||
{
|
||||
"id": "audioPanel"
|
||||
},
|
||||
{
|
||||
"id": "battery"
|
||||
},
|
||||
{
|
||||
"id": "systemStats"
|
||||
},
|
||||
{
|
||||
"id": "controlCenter"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"plugins": []
|
||||
"plugins": [
|
||||
{
|
||||
"id": "omarchy.osd"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -55,7 +55,8 @@ ShellRoot {
|
||||
},
|
||||
plugins: [
|
||||
{ id: "omarchy.settings" },
|
||||
{ id: "omarchy.image-picker" }
|
||||
{ id: "omarchy.image-picker" },
|
||||
{ id: "omarchy.osd" }
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
@define-color background-color {{ background }};
|
||||
@define-color border-color {{ foreground }};
|
||||
@define-color label {{ foreground }};
|
||||
@define-color image {{ foreground }};
|
||||
@define-color progress {{ accent }};
|
||||
Reference in New Issue
Block a user