update:lockscreen migration

This commit is contained in:
2026-06-08 15:57:40 +09:00
parent e3c9138be5
commit 2965a3a3cd
19 changed files with 22 additions and 15 deletions

View File

@@ -0,0 +1,3 @@
HandleLidSwitch=hibernate
HandleLidSwitchDocked=hibernate
LidSwitchIgnoreInhibited=no

View File

@@ -0,0 +1,6 @@
#!/bin/bash
LOCK="$HOME/.config/qylock-ready/lock-before-sleep.sh"
killall swayidle 2>/dev/null || true
sleep 0.1
swayidle -w \
before-sleep "bash $LOCK" &

View File

@@ -0,0 +1,4 @@
#!/bin/bash
LOCK="$HOME/.local/share/quickshell-lockscreen/lock.sh"
bash "$LOCK"
# swaylock -i ~/pictures/flower.jpg --effect-blur 7x5 --effect-vignette 0.5:0.5 --clock --indicator --ring-color E8D4A0FF --key-hl-color F4A261FF --bs-hl-color EE9B00FF --inside-color 00000088 --text-color FFFFFFFF --line-color 00000000 --separator-color 00000000

View File

@@ -0,0 +1,163 @@
#!/bin/bash
if ! command -v gum &> /dev/null; then
echo "❌ Error: 'gum' is not installed."
echo "Install with: go install github.com/charmbracelet/gum@latest"
exit 1
fi
if ! command -v wlsunset &> /dev/null; then
echo "❌ Error: 'wlsunset' is not installed."
echo "Install with your package manager (e.g., pacman -S wlsunset)"
exit 1
fi
LAT_LON_FILE="$HOME/.config/wlsunset/location"
PRIMARY="#cba6f7"
SECONDARY="#89b4fa"
SUCCESS="#a6e3a1"
WARNING="#f9e2af"
DANGER="#f38ba8"
ACCENT="#f5c2e7"
MUTED="#6c7086"
BTN_TOGGLE=" ╭─────────────────────────────╮
│ Toggle │
╰─────────────────────────────╯"
BTN_FORCE=" ╭─────────────────────────────╮
│ Force On │
╰─────────────────────────────╯"
BTN_CHANGE_LOC=" ╭─────────────────────────────╮
│ Change Location │
╰─────────────────────────────╯"
BTN_CHANGE_STR=" ╭─────────────────────────────╮
│ Change Strength │
╰─────────────────────────────╯"
BTN_EXIT=" ╭─────────────────────────────╮
│ Exit │
╰─────────────────────────────╯"
show_header() {
TERM_WIDTH=$(tput cols)
total_width=$((TERM_WIDTH - 2))
# Main title box
gum style \
--foreground "$ACCENT" \
--border-foreground "$ACCENT" \
--border "rounded" \
--width $total_width \
--align "center" \
--padding "2 0" \
"🌅 NIGHT LIGHT 🌙"
echo ""
if pidof wlsunset > /dev/null; then
status=" ACTIVE"
foreground_color=$SUCCESS
else
status=" INACTIVE"
foreground_color=$MUTED
fi
gum join --horizontal \
"$(gum style --width $total_width --align "center" --foreground "$foreground_color" --padding "0 2" --margin "0 1" "$status")" \
echo ""
}
get_status() {
if pidof wlsunset > /dev/null; then
echo " ACTIVE"
else
echo " INACTIVE"
fi
}
show_menu() {
term_width=$(tput cols)
button_width=33
padding=$(( (term_width - button_width) / 2 ))
pad_str=$(printf "%*s" $padding "")
# Pad each button using sed to add padding to every line
padded_buttons=()
for btn in "$BTN_TOGGLE" "$BTN_FORCE" "$BTN_CHANGE_LOC" "$BTN_CHANGE_STR" "$BTN_EXIT"; do
padded_btn=$(echo "$btn" | sed "s/^/$pad_str/")
padded_buttons+=("$padded_btn")
done
choice=$(gum choose \
--header "" \
--cursor " " \
--cursor.foreground "$PRIMARY" \
--selected.foreground "$SUCCESS" \
--item.foreground "$SECONDARY" \
"${padded_buttons[@]}")
echo "$choice"
}
if [ -f "$LAT_LON_FILE" ]; then
source "$LAT_LON_FILE"
else
location=$(curl -s "https://ipinfo.io/loc")
if [ ! -z "$location" ]; then
LAT=$(echo "$location" | cut -d',' -f1)
LON=$(echo "$location" | cut -d',' -f2)
else
# random default in LA
LAT=34.0522
LON=-118.2437
fi
echo -e "LAT=$LAT\nLON=$LON\nSTRENGTH=4750" > "$LAT_LON_FILE"
fi
expand_terminal() {
# launching via rofi doesnt expand terminal at start
gum style --width 120 " " > /dev/null 2>&1 || true
gum style --width 120 --foreground "#00000000" " "
printf "\033[1A\033[K" # Move up and clear line
}
case "$1" in
"init")
# turn on
wlsunset -l $LAT -L $LON -t $STRENGTH
;;
*)
expand_terminal
show_header
choice=$(show_menu)
case "$choice" in
*"Toggle"*)
if pidof wlsunset > /dev/null; then
if killall wlsunset; then
gum style --foreground "$MUTED" "Disabled night light"
notify-send "wlsunset" " Disabled night light"
else
notify-send "wlsunset" " Failed to disable night light"
fi
else
setsid wlsunset -l "$LAT" -L "$LON" -t $STRENGTH & disown
gum style --foreground "$SUCCESS" "Enabled night light"
notify-send "wlsunset" " Enabled night light"
fi
exit 0
;;
*"Force"*)
setsid wlsunset -s 00:00 -S 23:59 -t $STRENGTH & disown
notify-send "wlsunset" " Force enabled night light"
exit 0
;;
*"Exit"*)
clear
gum style --foreground "$MUTED" --align "center" "👋 Goodbye!"
exit 0
;;
*)
echo " choice not found"
exit 0
;;
esac
;;
esac

View File

@@ -0,0 +1,38 @@
border-size=1
border-radius=8
font=Geist 10
max-visible=3
width=330
padding=8
margin=14,15,0,0
anchor=top-right
default-timeout=5000
ignore-timeout=0
icons=1
max-icon-size=48
icon-path=/usr/share/icons/Adwaita
markup=1
actions=1
format=<b>%s</b>\n%b
background-color=#3D344580
[urgency=low]
default-timeout=3000
border-color=#6c7086
text-color=#B1B4C7
[urgency=normal]
border-color=#e1b4e2
text-color=#E6D4E6
[urgency=critical]
border-color=#f38ba8
background-color=#f38ba81a
text-color=#f38ba8
default-timeout=0

View File

@@ -0,0 +1,8 @@
# Custom qylock system
Purpose of this is to add a lock file to safely initialize the lockscreen after hibernate
shim from original qylock is required:
```
ln -sfn $HOME/.local/share/quickshell-lockscreen/shim $HOME/.config/qylock-ready/shim
```

View File

@@ -0,0 +1,55 @@
#!/usr/bin/env bash
set -euo pipefail
CUSTOM_DIR="/home/kokopi/.config/qylock-ready"
UPSTREAM_DIR="/home/kokopi/.local/share/quickshell-lockscreen"
QML="$CUSTOM_DIR/lock_shell_ready.qml"
READY_FILE="$(mktemp -u "${XDG_RUNTIME_DIR:-/tmp}/qylock-ready.XXXXXX")"
cleanup() {
rm -f "$READY_FILE"
}
trap cleanup EXIT
# Match upstream lock.sh environment setup
export QML2_IMPORT_PATH="$UPSTREAM_DIR/imports:${QML2_IMPORT_PATH:-}"
export QML_XHR_ALLOW_FILE_READ=1
export XDG_SESSION_TYPE="${XDG_SESSION_TYPE:-$(loginctl show-session "$(loginctl | grep "$(whoami)" | awk '{print $1}')" -p Type --value 2>/dev/null || echo wayland)}"
CONFIG_FILE="$HOME/.config/qylock/theme"
if [ -n "${1:-}" ]; then
export QS_THEME="${1:-nier-automata}"
elif [ -f "$CONFIG_FILE" ]; then
export QS_THEME="${1:-nier-automata}"
else
export QS_THEME="${1:-nier-automata}"
fi
if [ -d "$UPSTREAM_DIR/../themes" ] && [ ! -d "$UPSTREAM_DIR/themes_link" ]; then
export QS_THEME_PATH="$UPSTREAM_DIR/../themes/$QS_THEME"
else
export QS_THEME_PATH="$UPSTREAM_DIR/themes_link/$QS_THEME"
fi
rm -f "$READY_FILE"
killall -9 hyprlock swaylock wlogout 2>/dev/null || true
QYLOCK_READY_FILE="$READY_FILE" quickshell -p "$QML" &
pid=$!
for _ in $(seq 1 200); do
if [[ -e "$READY_FILE" ]]; then
exit 0
fi
if ! kill -0 "$pid" 2>/dev/null; then
wait "$pid"
echo "qylock exited before becoming ready" >&2
exit 1
fi
sleep 0.05
done
echo "qylock did not become ready in time" >&2
exit 1

View File

@@ -0,0 +1,135 @@
import QtQuick
import Quickshell
import Quickshell.Wayland
import QtMultimedia
import "./shim"
ShellRoot {
id: shellRoot
property string baseDir: "/home/kokopi/.local/share/quickshell-lockscreen"
property string activeTheme: Quickshell.env("QS_THEME") || "nier-automata"
property string themePath: Quickshell.env("QS_THEME_PATH") || (baseDir + "/themes_link/" + activeTheme)
property string readyFile: Quickshell.env("QYLOCK_READY_FILE") || ""
property bool readySent: false
readonly property var sddm: sddmShim.sddm
readonly property var config: sddmShim.config
readonly property var userModel: sddmShim.userModel
readonly property var sessionModel: sddmShim.sessionModel
readonly property bool isWayland: Quickshell.env("XDG_SESSION_TYPE") === "wayland"
property bool authenticated: false
property bool sessionLocked: true
property bool isTesting: Quickshell.env("QS_TESTING") === "1"
function signalReady() {
if (readySent || readyFile === "")
return
readySent = true
Quickshell.execDetached([
"sh", "-c",
"umask 077; : > \"$1\"",
"sh", readyFile
])
}
SddmShim {
id: sddmShim
themePath: shellRoot.themePath
}
Connections {
target: sddmShim.sddm
function onLoginSucceeded() {
shellRoot.authenticated = true
shellRoot.sessionLocked = false
if (Quickshell.env("XDG_CURRENT_DESKTOP") === "Hyprland" || Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE") !== "") {
Quickshell.execDetached(["hyprctl", "keyword", "misc:allow_session_lock_restore", "1"]);
}
Quickshell.execDetached(["loginctl", "unlock-session"]);
quitTimer.start()
}
}
Timer {
id: quitTimer
interval: 1500
onTriggered: Qt.quit()
}
Component {
id: themeComponent
Loader {
anchors.fill: parent
source: "file://" + shellRoot.themePath + "/Main.qml"
onLoaded: item.forceActiveFocus()
onStatusChanged: {
if (status === Loader.Error) {
console.error("FAILED to load theme:", source)
}
}
}
}
Loader {
id: waylandLoader
active: shellRoot.isWayland
sourceComponent: Component {
WlSessionLock {
id: lock
locked: shellRoot.sessionLocked
onSecureStateChanged: {
if (secure)
shellRoot.signalReady()
}
surface: Component {
WlSessionLockSurface {
color: "black"
Loader {
anchors.fill: parent
sourceComponent: themeComponent
}
}
}
}
}
}
Loader {
id: x11Loader
active: !shellRoot.isWayland
sourceComponent: Component {
Variants {
model: Quickshell.screens
delegate: Window {
id: window
required property var modelData
screen: modelData
width: isTesting ? 1280 : screen.width
height: isTesting ? 720 : screen.height
visible: shellRoot.sessionLocked
visibility: isTesting ? Window.Windowed : Window.FullScreen
Component.onCompleted: shellRoot.signalReady()
onClosing: (close) => {
close.accepted = shellRoot.authenticated || shellRoot.isTesting;
}
flags: Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.MaximizeUsingFullscreenGeometryHint
color: "black"
Loader {
anchors.fill: parent
sourceComponent: themeComponent
}
}
}
}
}
}

View File

@@ -0,0 +1,85 @@
{
"layer": "top",
"position": "top",
"width": "auto",
"height": 36,
"modules-left": ["ext/workspaces"],
"modules-center": ["clock"],
"modules-right": ["bluetooth", "wireplumber", "network", "cpu", "memory", "battery", "custom/power"],
"custom/power": {
"format-icons": ["<span color='#e2d0a3'></span>"],
"format": "{icon}",
"tooltip": false,
"on-click": "~/.local/bin/rofi-power-manager.sh"
},
"ext/workspaces": {
"disable-scroll": true,
"ignore-hidden": true,
"all-outputs": false,
"on-click": "activate",
"format": "{name}"
},
"cpu": {
"format-icons": ["<span color='#8aade0'></span>"],
"format": "{usage}% {icon}",
"tooltip": false
},
"memory": {
"format-icons": ["<span color='#8aade0'></span>"],
"format": "{}% {icon}"
},
"network": {
"max-length": 10,
"format-wifi": "{essid} <span color='#8aade0'></span>",
"format-ethernet": "{ipaddr}/{cidr} ",
"tooltip-format": "{ifname} via {gwaddr} ",
"format-linked": "{ifname} (No IP) ",
"format-disconnected": "Disconnected ⚠",
"on-click": "ghostty -e nmtui & disown"
// "format-alt": "{ifname}: {ipaddr}/{cidr}",
},
"clock": {
"format": "{:%b %d - %H:%M}",
"tooltip-format": "<span size='11pt' font='Geist Mono'>{calendar}</span>",
"calendar": {
"mode": "month",
"mode-mon-col": 4,
"on-scroll" : 1,
"format": {
"today": "<span color='#3d3555' background='#a5c5a5'><b>{}</b></span>"
}
},
"actions": {
"on-click-right": "mode",
"on-scroll-up": "shift_down",
"on-scroll-down": "shift_up"
}
},
"bluetooth": {
"format": "",
"format-disabled": "<span color='#db9a9a'>󰂲</span>",
"tooltip": false,
"on-click": "blueman-manager"
},
"wireplumber": {
"format": "{volume}% <span color='#8aade0'>{icon}</span>",
"format-icons": {
"default": ["", "", ""]
},
"format-muted": "<span color='#8aade0'></span>",
"on-click": "pavucontrol"
},
"battery": {
"states": {
// "good": 95,
"warning": 30,
"critical": 15
},
"format": "{capacity}% {icon}",
"format-full": "{capacity}% {icon}",
"format-charging": "{capacity}% ",
"format-alt": "{time} {icon}",
"format-icons": ["<span color='#8aade0'></span>", "<span color='#8aade0'></span>", "<span color='#8aade0'></span>", "<span color='#8aade0'></span>", "<span color='#8aade0'></span>"]
}
}

View File

@@ -0,0 +1,84 @@
* {
font-family: "Geist", sans-serif;
min-height: 0;
}
window#waybar {
background: rgba(33, 28, 46, 0.6);
color: rgb(205, 214, 244);
}
window#waybar > box.horizontal:dir(ltr) {
margin-top: 6px;
margin-bottom: 6px;
margin-left: 12px;
margin-right: 16px;
}
#workspaces button {
font-family: "Octal", monospace;
font-weight: bold;
font-size: 12px;
padding: 0 6px;
margin: 0 3px;
background:rgba(137, 180, 250, 0.15);
color: rgba(208, 181, 210, 0.65);
border: none;
}
#workspaces button.focused,
#workspaces button.active {
color: rgb(30, 30, 46);
background: rgb(180, 190, 254);
padding: 0 12px;
}
#workspaces button.focused:hover,
#workspaces button.active:hover {
background: rgba(180, 190, 254, 0.75);
}
#workspaces button:hover {
background: rgba(255, 255, 255, 0.1);
}
#clock {
padding: 0 15px;
background: rgba(137, 180, 250, 0.15);
border-radius: 10px;
}
tooltip {
border: 1px solid #d093d1;
background: #3d3555;
}
tooltip label {
padding: 10px;
}
label#wireplumber,
label#bluetooth,
label#network,
label#battery,
label#cpu,
label#custom-power,
label#memory {
padding: 0 9px;
border-radius: 10px;
margin: 0 3px;
}
label#custom-power {
margin-right: 0;
padding-right: 0;
}
label#wireplumber,
label#bluetooth,
label#network {
background:rgba(137, 180, 250, 0.15);
}
label#battery,
label#cpu,
label#memory {
background: rgba(208, 181, 210, 0.15);
}

View File

@@ -0,0 +1,94 @@
{
"layer": "top",
"position": "top",
"width": "auto",
"height": 36,
"modules-left": ["ext/workspaces"],
"modules-center": ["clock"],
"modules-right": ["bluetooth", "wireplumber", "network", "custom/usb", "cpu", "memory", "battery", "custom/power"],
"custom/power": {
"format-icons": ["<span color='#e2d0a3'></span>"],
"format": "{icon}",
"tooltip": false,
"on-click": "~/.local/bin/rofi-power-manager.sh"
},
"ext/workspaces": {
"disable-scroll": true,
"ignore-hidden": true,
"all-outputs": false,
"on-click": "activate",
"format": "{name}"
},
"cpu": {
"format-icons": ["<span color='#8aade0'></span>"],
"format": "{usage}% {icon}",
"tooltip": false
},
"memory": {
"format-icons": ["<span color='#8aade0'></span>"],
"format": "{}% {icon}"
},
"network": {
"max-length": 10,
"format-wifi": "{essid} <span color='#8aade0'></span>",
"format-ethernet": "{ipaddr}/{cidr} ",
"tooltip-format": "{ifname} via {gwaddr} ",
"format-linked": "{ifname} (No IP) ",
"format-disconnected": "Disconnected ⚠",
"on-click": "ghostty -e nmtui & disown"
// "format-alt": "{ifname}: {ipaddr}/{cidr}",
},
"clock": {
"format": "{:%b %d - %H:%M}",
"tooltip-format": "<span size='11pt' font='Geist Mono'>{calendar}</span>",
"calendar": {
"mode": "month",
"mode-mon-col": 4,
"on-scroll" : 1,
"format": {
"today": "<span color='#3d3555' background='#a5c5a5'><b>{}</b></span>"
}
},
"actions": {
"on-click-right": "mode",
"on-scroll-up": "shift_down",
"on-scroll-down": "shift_up"
}
},
"bluetooth": {
"format": "",
"format-disabled": "<span color='#db9a9a'>󰂲</span>",
"tooltip": false,
"on-click": "blueman-manager"
},
"wireplumber": {
"format": "{volume}% <span color='#8aade0'>{icon}</span>",
"format-icons": {
"default": ["", "", ""]
},
"format-muted": "<span color='#8aade0'></span>",
"on-click": "pavucontrol"
},
"battery": {
"states": {
// "good": 95,
"warning": 30,
"critical": 15
},
"format": "{capacity}% {icon}",
"format-full": "{capacity}% {icon}",
"format-charging": "{capacity}% ",
"format-alt": "{time} {icon}",
"format-icons": ["<span color='#8aade0'></span>", "<span color='#8aade0'></span>", "<span color='#8aade0'></span>", "<span color='#8aade0'></span>", "<span color='#8aade0'></span>"]
},
"custom/usb": {
// "format": "{} {icon}",
"format": "{icon}",
"format-icons": ["<span color='#8aade0'>󰉉</span>"],
// "interval": 15,
// "exec": "lsblk -nlo NAME,MOUNTPOINT | grep '/run/media' | wc -l",
"on-click": "env GDK_BACKEND=x11 thunar /run/media/$USER",
"tooltip": false
}
}

View File

@@ -0,0 +1,86 @@
* {
font-family: "Geist", sans-serif;
min-height: 0;
}
window#waybar {
background: rgba(33, 28, 46, 0.6);
color: rgb(205, 214, 244);
}
window#waybar > box.horizontal:dir(ltr) {
margin-top: 6px;
margin-bottom: 6px;
margin-left: 12px;
margin-right: 16px;
}
#workspaces button {
font-family: "Octal", monospace;
font-weight: bold;
font-size: 12px;
padding: 0 6px;
margin: 0 3px;
background:rgba(137, 180, 250, 0.15);
color: rgba(208, 181, 210, 0.65);
border: none;
}
#workspaces button.focused,
#workspaces button.active {
color: rgb(30, 30, 46);
background: rgb(180, 190, 254);
padding: 0 12px;
}
#workspaces button.focused:hover,
#workspaces button.active:hover {
background: rgba(180, 190, 254, 0.75);
}
#workspaces button:hover {
background: rgba(255, 255, 255, 0.1);
}
#clock {
padding: 0 15px;
background: rgba(137, 180, 250, 0.15);
border-radius: 10px;
}
tooltip {
border: 1px solid #d093d1;
background: #3d3555;
}
tooltip label {
padding: 10px;
}
label#wireplumber,
label#bluetooth,
label#network,
label#battery,
label#cpu,
label#custom-power,
label#custom-usb,
label#memory {
padding: 0 9px;
border-radius: 10px;
margin: 0 3px;
}
label#custom-power {
margin-right: 0;
padding-right: 0;
}
label#wireplumber,
label#bluetooth,
label#custom-usb,
label#network {
background:rgba(137, 180, 250, 0.15);
}
label#battery,
label#cpu,
label#memory {
background: rgba(208, 181, 210, 0.15);
}

View File

@@ -0,0 +1,27 @@
[Settings]
language = en
folder = ~/pictures
monitors = All
wallpaper = ~/pictures/flower.jpg
show_path_in_tooltip = True
backend = swww
fill = fill
sort = name
color = #ffffff
subfolders = False
all_subfolders = False
show_hidden = False
show_gifs_only = False
zen_mode = False
post_command =
number_of_columns = 3
swww_transition_type = wave
swww_transition_step = 63
swww_transition_angle = 55
swww_transition_duration = 1
swww_transition_fps = 60
mpvpaper_sound = False
mpvpaper_options =
use_xdg_state = False
stylesheet = /home/kokopi/.config/waypaper/style.css