add quick actions tab
This commit is contained in:
@@ -1,28 +1,19 @@
|
||||
|
||||
calendar {
|
||||
padding: 5pt;
|
||||
padding: 2pt 1pt;
|
||||
font-size: 10pt;
|
||||
|
||||
:selected {
|
||||
@include color-accent;
|
||||
}
|
||||
|
||||
.header {
|
||||
header {
|
||||
padding: 2pt 0;
|
||||
@include color-body;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
@include color-accent;
|
||||
font-weight: bold;
|
||||
:selected { @include color-accent; }
|
||||
.highlight { @include color-accent; font-weight: bold; }
|
||||
:indeterminate { color: $base03; }
|
||||
}
|
||||
|
||||
label {
|
||||
font-size: 20pt;
|
||||
@include color-accent;
|
||||
}
|
||||
|
||||
:indeterminate {
|
||||
color: $base03;
|
||||
}
|
||||
}
|
||||
.cal-box .sys-section-header { margin-bottom: 4pt; }
|
||||
|
||||
|
||||
.hour, .month {
|
||||
@@ -46,7 +37,36 @@ calendar {
|
||||
|
||||
// Clock window accents
|
||||
.weather-accent { background-color: $base0A; }
|
||||
.cal-accent { background-color: $base0B; }
|
||||
.bri-accent { background-color: $base09; }
|
||||
.vol-accent { background-color: $base0D; }
|
||||
.quick-accent { background-color: $base0E; }
|
||||
|
||||
// Quick actions
|
||||
.quick-grid { margin-top: 2pt; }
|
||||
|
||||
.quick-btn {
|
||||
@include background-base2;
|
||||
@include border-radius;
|
||||
padding: 8pt 4pt;
|
||||
margin: 4px;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
border: none;
|
||||
|
||||
&:hover {
|
||||
@include background-active;
|
||||
.quick-icon, .quick-label {color: $base01;}
|
||||
}
|
||||
}
|
||||
|
||||
.quick-btn-active {
|
||||
.quick-icon { @include color-accent; }
|
||||
.quick-label { @include color-accent; }
|
||||
}
|
||||
|
||||
.quick-icon { font-size: 1.5em; @include color-body; }
|
||||
.quick-label { font-size: 0.68em; margin-top: 3pt; @include color-body; }
|
||||
|
||||
// Weather section
|
||||
.weather-main { margin-bottom: 8pt; }
|
||||
@@ -57,10 +77,18 @@ calendar {
|
||||
|
||||
// Volume section
|
||||
.ctrl-row { margin-bottom: 4pt; }
|
||||
.ctrl-icon { font-size: 1.1em; min-width: 22pt; @include color-body; }
|
||||
.ctrl-icon { font-size: 1.1em; min-width: 22pt; @include border-radius; @include color-body; }
|
||||
.ctrl-icon:hover { @include background-active; }
|
||||
.ctrl-muted { @include color-inactive; }
|
||||
.ctrl-value { font-size: 0.72em; min-width: 28pt; @include color-active; }
|
||||
|
||||
scale.ctrl-slider.ctrl-slider-muted {
|
||||
trough {
|
||||
highlight { background-color: $base03; }
|
||||
slider { background-color: $base03; }
|
||||
}
|
||||
}
|
||||
|
||||
scale.ctrl-slider {
|
||||
padding: 2pt 4pt;
|
||||
trough {
|
||||
|
||||
28
modules/home/wayland/apps/eww/bar/scripts/brightness
Executable file
28
modules/home/wayland/apps/eww/bar/scripts/brightness
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
BACKLIGHT="/sys/class/backlight"
|
||||
DEV=$(ls "$BACKLIGHT" 2>/dev/null | head -n1)
|
||||
|
||||
gen_output() {
|
||||
if [ -z "$DEV" ]; then
|
||||
echo '{"percent":0,"available":false}'
|
||||
return
|
||||
fi
|
||||
max=$(cat "$BACKLIGHT/$DEV/max_brightness")
|
||||
cur=$(cat "$BACKLIGHT/$DEV/actual_brightness" 2>/dev/null || cat "$BACKLIGHT/$DEV/brightness")
|
||||
percent=$(awk -v c="$cur" -v m="$max" 'BEGIN{print int(c/m*100+0.5)}')
|
||||
printf '{"percent":%d,"available":true}\n' "$percent"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
set)
|
||||
[ -z "$DEV" ] && exit 0
|
||||
brightnessctl -d "$DEV" set "${2}%" -q 2>/dev/null
|
||||
;;
|
||||
*)
|
||||
gen_output
|
||||
[ -z "$DEV" ] && exit 0
|
||||
# Poll for changes every 2s (sysfs files don't support inotify reliably)
|
||||
while true; do sleep 2; gen_output; done
|
||||
;;
|
||||
esac
|
||||
13
modules/home/wayland/apps/eww/bar/scripts/nightlight
Executable file
13
modules/home/wayland/apps/eww/bar/scripts/nightlight
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
case "$1" in
|
||||
status)
|
||||
pgrep -x wlsunset >/dev/null 2>&1 && echo true || echo false
|
||||
;;
|
||||
*)
|
||||
if pgrep -x wlsunset >/dev/null 2>&1; then
|
||||
pkill -x wlsunset && echo false
|
||||
else
|
||||
wlsunset -T 4500 -t 3200 & echo true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
9
modules/home/wayland/apps/eww/bar/scripts/power-save
Executable file
9
modules/home/wayland/apps/eww/bar/scripts/power-save
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
current=$(eww state 2>/dev/null | grep '^power-save:' | awk '{print $2}')
|
||||
if [ "$current" = "true" ]; then
|
||||
powerprofilesctl set balanced 2>/dev/null || true
|
||||
echo false
|
||||
else
|
||||
powerprofilesctl set power-saver 2>/dev/null || true
|
||||
echo true
|
||||
fi
|
||||
5
modules/home/wayland/apps/eww/bar/scripts/screenshot
Executable file
5
modules/home/wayland/apps/eww/bar/scripts/screenshot
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
DIR="$HOME/Pictures/Screenshots"
|
||||
mkdir -p "$DIR"
|
||||
FILE="$DIR/$(date +%Y-%m-%d_%H-%M-%S).png"
|
||||
grim -g "$(slurp)" "$FILE" && wl-copy < "$FILE"
|
||||
@@ -12,13 +12,14 @@ gen_output() {
|
||||
lvl=$(awk -v n="$percent" 'BEGIN{print int(n/34)}')
|
||||
sink_muted=$(ismuted "SINK")
|
||||
source_muted=$(ismuted "SOURCE")
|
||||
sink=$(wpctl inspect @DEFAULT_AUDIO_SINK@ 2>/dev/null | grep -m1 'node\.nick' | sed 's/.*= "\(.*\)"/\1/')
|
||||
|
||||
[ "$sink_muted" = 0 ] && icon="" || icon="${volicons[$lvl]}"
|
||||
[ "$source_muted" = 0 ] && mic_icon="" || mic_icon=""
|
||||
|
||||
printf '{"icon":"%s","percent":%s,"sink_muted":%s,"mic_icon":"%s","microphone":%s,"source_muted":%s}\n' \
|
||||
printf '{"icon":"%s","percent":%s,"sink_muted":%s,"mic_icon":"%s","microphone":%s,"source_muted":%s,"sink":"%s"}\n' \
|
||||
"$icon" "$percent" "$([ "$sink_muted" = 0 ] && echo true || echo false)" \
|
||||
"$mic_icon" "$(vol SOURCE)" "$([ "$source_muted" = 0 ] && echo true || echo false)"
|
||||
"$mic_icon" "$(vol SOURCE)" "$([ "$source_muted" = 0 ] && echo true || echo false)" "$sink"
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
@@ -26,7 +27,18 @@ case "$1" in
|
||||
setvol) setvol "$2" "$3" ;;
|
||||
*)
|
||||
gen_output
|
||||
pw-cli -m 2>/dev/null | rg --line-buffered "PipeWire:Interface:Client" | while read -r _; do
|
||||
|
||||
tmp=$(mktemp -d)
|
||||
pipe="$tmp/vol-events"
|
||||
mkfifo "$pipe"
|
||||
trap 'rm -rf "$tmp"; kill 0 2>/dev/null' EXIT INT TERM
|
||||
|
||||
# 1s polling fallback
|
||||
(while true; do sleep 1; echo poll; done) > "$pipe" &
|
||||
# PipeWire property-change events (fires on mute/volume change)
|
||||
(pw-cli -m 2>/dev/null | grep --line-buffered "changed") > "$pipe" &
|
||||
|
||||
while IFS= read -r _ < "$pipe"; do
|
||||
gen_output
|
||||
done
|
||||
;;
|
||||
|
||||
2
modules/home/wayland/apps/eww/bar/scripts/wallpaper
Executable file
2
modules/home/wayland/apps/eww/bar/scripts/wallpaper
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/usr/bin/env bash
|
||||
nohup bash "$HOME/.config/script/wallpaper.sh" >/dev/null 2>&1 &
|
||||
@@ -4,9 +4,13 @@
|
||||
"scripts/weather")
|
||||
|
||||
(deflisten volume
|
||||
:initial '{"icon":"","percent":50,"sink_muted":false,"mic_icon":"","microphone":50,"source_muted":false}'
|
||||
:initial '{"icon":"","percent":50,"sink_muted":false,"mic_icon":"","microphone":50,"source_muted":false,"sink":""}'
|
||||
"scripts/volume")
|
||||
|
||||
(deflisten brightness
|
||||
:initial '{"percent":0,"available":false}'
|
||||
"scripts/brightness")
|
||||
|
||||
; --- Weather ---
|
||||
|
||||
(defwidget weather-section []
|
||||
@@ -14,9 +18,9 @@
|
||||
(section-header
|
||||
:title {weather.city != "" ? "Weather · ${weather.city}" : "Weather"}
|
||||
:accent "weather-accent")
|
||||
(box :orientation "h" :space-evenly false :valign "center" :class "weather-main"
|
||||
(label :class "weather-icon" :text {weather.icon})
|
||||
(box :orientation "v" :space-evenly false
|
||||
(box :orientation "h" :space-evenly false :halign "center" :class "weather-main"
|
||||
(label :class "weather-icon" :valign "center" :text {weather.icon})
|
||||
(box :orientation "v" :space-evenly false :valign "center"
|
||||
(label :class "weather-temp" :text "${weather.temp}°C")
|
||||
(label :class "weather-desc" :text {weather.desc})))
|
||||
(box :orientation "h" :space-evenly true :class "weather-stats"
|
||||
@@ -40,13 +44,16 @@
|
||||
(label :text icon))
|
||||
(scale
|
||||
:min 0 :max 100 :value value
|
||||
:hexpand true :class "ctrl-slider"
|
||||
:onchange onchange)
|
||||
(label :class "ctrl-value" :halign "end" :text "${value}%")))
|
||||
:hexpand true
|
||||
:class "ctrl-slider ${muted ? 'ctrl-slider-muted' : ''}"
|
||||
:onchange {muted ? "true" : onchange})
|
||||
(label :class "ctrl-value ${muted ? 'ctrl-muted' : ''}" :halign "end" :text "${value}%")))
|
||||
|
||||
(defwidget volume-section []
|
||||
(box :orientation "v" :space-evenly false :class "sys-section"
|
||||
(section-header :title "Volume" :accent "vol-accent")
|
||||
(section-header
|
||||
:title {volume.sink != "" ? "Volume · ${volume.sink}" : "Volume"}
|
||||
:accent "vol-accent")
|
||||
(vol-row
|
||||
:icon {volume.icon}
|
||||
:value {volume.percent}
|
||||
@@ -60,13 +67,68 @@
|
||||
:onchange "scripts/volume setvol SOURCE {}"
|
||||
:onclick "scripts/volume mute SOURCE")))
|
||||
|
||||
; --- Quick Actions ---
|
||||
|
||||
(defvar power-save false)
|
||||
(defvar night-light false)
|
||||
|
||||
(defwidget quick-btn [icon label onclick active]
|
||||
(button :class "quick-btn ${active ? 'quick-btn-active' : ''}"
|
||||
:onclick onclick
|
||||
(box :orientation "v" :space-evenly false :halign "center" :valign "center"
|
||||
(label :class "quick-icon" :text icon)
|
||||
(label :class "quick-label" :text label))))
|
||||
|
||||
(defwidget quick-section []
|
||||
(box :orientation "v" :space-evenly false :class "sys-section"
|
||||
(section-header :title "Quick Actions" :accent "quick-accent")
|
||||
(box :orientation "h" :homogeneous true :class "quick-grid"
|
||||
(quick-btn
|
||||
:icon "" :label "Wallpaper"
|
||||
:onclick "scripts/wallpaper"
|
||||
:active false)
|
||||
(quick-btn
|
||||
:icon "" :label "Power Save"
|
||||
:onclick "eww update power-save=$(scripts/power-save)"
|
||||
:active {power-save})
|
||||
(quick-btn
|
||||
:icon "" :label "Night Light"
|
||||
:onclick "eww update night-light=$(scripts/nightlight)"
|
||||
:active {night-light})
|
||||
(quick-btn
|
||||
:icon "" :label "Screenshot"
|
||||
:onclick "scripts/screenshot"
|
||||
:active false))))
|
||||
|
||||
; --- Brightness ---
|
||||
|
||||
(defwidget brightness-section []
|
||||
(box :orientation "v" :space-evenly false :class "sys-section"
|
||||
:visible {brightness.available}
|
||||
(section-header :title "Brightness" :accent "bri-accent")
|
||||
(box :orientation "h" :space-evenly false :valign "center" :class "ctrl-row"
|
||||
(label :class "ctrl-icon" :text "")
|
||||
(scale
|
||||
:min 1 :max 100 :value {brightness.percent}
|
||||
:hexpand true
|
||||
:class "ctrl-slider"
|
||||
:onchange "scripts/brightness set {}")
|
||||
(label :class "ctrl-value" :halign "end" :text "${brightness.percent}%"))))
|
||||
|
||||
; --- Root ---
|
||||
|
||||
(defwidget clock-win []
|
||||
(box :class "sys-win" :orientation "v" :space-evenly false
|
||||
(volume-section)
|
||||
(brightness-section)
|
||||
(box :class "section-sep")
|
||||
(quick-section)
|
||||
(box :class "section-sep")
|
||||
(weather-section)
|
||||
(box :class "section-sep")
|
||||
(calendar)
|
||||
(box :class "section-sep")
|
||||
(volume-section)))
|
||||
(box :orientation "v" :space-evenly false :class "sys-section cal-box"
|
||||
(section-header :title "Calendar" :accent "cal-accent")
|
||||
(calendar :show-week-numbers false))
|
||||
))
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{ ... }: {
|
||||
{ lib, ... }: {
|
||||
services.fwupd.enable = true;
|
||||
hardware.enableAllFirmware = false;
|
||||
services.power-profiles-daemon.enable = lib.mkDefault true;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{ lib, config, pkgs, ... }: {
|
||||
config = lib.mkIf (config.syscfg.make.power) {
|
||||
services.power-profiles-daemon.enable = false; # conflicts with TLP
|
||||
services.tlp = {
|
||||
enable = true;
|
||||
settings = {
|
||||
|
||||
Reference in New Issue
Block a user