用 Noctalia Shell 替代各种琐碎组件
This commit is contained in:
@@ -180,4 +180,4 @@ find-next=Control+n
|
|||||||
# select-row=BTN_LEFT-3
|
# select-row=BTN_LEFT-3
|
||||||
|
|
||||||
[main]
|
[main]
|
||||||
include=/usr/share/foot/themes/rose-pine
|
include=~/.config/foot/themes/noctalia
|
||||||
|
|||||||
@@ -25,3 +25,4 @@ selection-text = e0def4ff
|
|||||||
selection-match = ebbcbaff
|
selection-match = ebbcbaff
|
||||||
prompt = 908caaff
|
prompt = 908caaff
|
||||||
input = 9ccfd8ff
|
input = 9ccfd8ff
|
||||||
|
include=~/.config/fuzzel/themes/noctalia
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ binds {
|
|||||||
//Shift+Mod+Return hotkey-overlay-title="Steam" { spawn "steam"; }
|
//Shift+Mod+Return hotkey-overlay-title="Steam" { spawn "steam"; }
|
||||||
|
|
||||||
Mod+F12 hotkey-overlay-title="打开桌面项目 ... (VSCode)" { spawn ".fuzzel-vscode"; }
|
Mod+F12 hotkey-overlay-title="打开桌面项目 ... (VSCode)" { spawn ".fuzzel-vscode"; }
|
||||||
Mod+Space hotkey-overlay-title="运行命令 ... (fuzzel)" { spawn ".fuzzel-startb"; }
|
Mod+R hotkey-overlay-title="运行命令 ... (fuzzel)" { spawn ".fuzzel-startb"; }
|
||||||
|
Mod+Space hotkey-overlay-title="启动面板 (Noctalia)" { spawn-sh "qs -c noctalia-shell ipc call launcher toggle"; }
|
||||||
|
|
||||||
// Applications such as remote-desktop clients and software KVM switches may
|
// Applications such as remote-desktop clients and software KVM switches may
|
||||||
// request that niri stops processing the keyboard shortcuts defined here
|
// request that niri stops processing the keyboard shortcuts defined here
|
||||||
@@ -20,12 +21,11 @@ binds {
|
|||||||
// The allow-inhibiting=false property can be applied to other binds as well,
|
// The allow-inhibiting=false property can be applied to other binds as well,
|
||||||
// which ensures niri always processes them, even when an inhibitor is active.
|
// which ensures niri always processes them, even when an inhibitor is active.
|
||||||
Mod+Alt+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
|
Mod+Alt+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
|
||||||
XF86PowerOff hotkey-overlay-title="大退(注销)" { quit; }
|
XF86PowerOff hotkey-overlay-title="电源管理 (Noctalia)" { spawn-sh "qs -c noctalia-shell ipc call sessionMenu toggle"; }
|
||||||
Super+Escape hotkey-overlay-title="锁屏 (gtklock)" { spawn "gtklock" "-d"; }
|
Super+Escape hotkey-overlay-title="锁屏 (Noctalia)" { spawn-sh "qs -c noctalia-shell ipc call lockScreen lock"; }
|
||||||
Mod+Delete hotkey-overlay-title="锁屏并休眠 ..." allow-when-locked=true {
|
Mod+Delete hotkey-overlay-title="锁屏并睡眠... (Noctalia)" allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call sessionMenu lockAndSuspend"; }
|
||||||
spawn-sh "(pgrep gtklock || gtklock -d) && sleep 1.5 && systemctl hibernate";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 有兴趣可以自己替换成 noctalia 的命令行。我是发现保持现状依然可以看到视觉反馈,没必要替换。
|
||||||
XF86AudioRaiseVolume hotkey-overlay-title=null allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.05+"; }
|
XF86AudioRaiseVolume hotkey-overlay-title=null allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.05+"; }
|
||||||
XF86AudioLowerVolume hotkey-overlay-title=null allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.05-"; }
|
XF86AudioLowerVolume hotkey-overlay-title=null allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.05-"; }
|
||||||
XF86AudioMute hotkey-overlay-title=null allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; }
|
XF86AudioMute hotkey-overlay-title=null allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; }
|
||||||
@@ -33,12 +33,14 @@ binds {
|
|||||||
|
|
||||||
//Mod+Shift+M allow-when-locked=true { spawn "swayosd-client" "--input-volume" "mute-toggle"; }
|
//Mod+Shift+M allow-when-locked=true { spawn "swayosd-client" "--input-volume" "mute-toggle"; }
|
||||||
|
|
||||||
XF86AudioPlay allow-when-locked=true { spawn "playerctl" "play-pause"; }
|
// 这块还真得换。`yay -Rs waybar` 发现 playerctl 也给带走了。
|
||||||
XF86AudioPause allow-when-locked=true { spawn "playerctl" "play-pause"; }
|
XF86AudioPlay allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media playPause"; }
|
||||||
XF86AudioNext allow-when-locked=true { spawn "playerctl" "next"; }
|
XF86AudioPause allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media playPause"; }
|
||||||
XF86AudioPrev allow-when-locked=true { spawn "playerctl" "previous"; }
|
XF86AudioNext allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media next"; }
|
||||||
XF86AudioStop allow-when-locked=true { spawn "playerctl" "stop"; }
|
XF86AudioPrev allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media previous"; }
|
||||||
|
XF86AudioStop allow-when-locked=true { spawn-sh "qs -c noctalia-shell ipc call media stop"; }
|
||||||
|
|
||||||
|
// 结果 Noctalia 自己就依赖 brightnessctl。那留着。
|
||||||
XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "+5%"; }
|
XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "+5%"; }
|
||||||
XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "5%-"; }
|
XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "5%-"; }
|
||||||
|
|
||||||
@@ -179,14 +181,14 @@ binds {
|
|||||||
Mod+BracketLeft { consume-or-expel-window-left; }
|
Mod+BracketLeft { consume-or-expel-window-left; }
|
||||||
Mod+BracketRight { consume-or-expel-window-right; }
|
Mod+BracketRight { consume-or-expel-window-right; }
|
||||||
|
|
||||||
Mod+R { switch-preset-column-width; }
|
Mod+X { switch-preset-column-width; }
|
||||||
Mod+Shift+R { switch-preset-window-height; }
|
Mod+Shift+X { switch-preset-window-height; }
|
||||||
Mod+Ctrl+R { reset-window-height; }
|
Mod+Ctrl+X { reset-window-height; }
|
||||||
Mod+F11 { maximize-column; }
|
Mod+F11 { maximize-column; }
|
||||||
Mod+Shift+F11 { toggle-windowed-fullscreen; }
|
Mod+Shift+F11 { toggle-windowed-fullscreen; }
|
||||||
Mod+Ctrl+F11 { fullscreen-window; }
|
Mod+Ctrl+F11 { fullscreen-window; }
|
||||||
Mod+T hotkey-overlay-title="Expand column to available width" { expand-column-to-available-width; }
|
Mod+T hotkey-overlay-title="将整列窗口撑满整个显示器" { expand-column-to-available-width; }
|
||||||
Mod+W hotkey-overlay-title="Tabbed Column Mode" { toggle-column-tabbed-display; }
|
Mod+W hotkey-overlay-title="用页签表示(所选)窗口所在列" { toggle-column-tabbed-display; }
|
||||||
|
|
||||||
Mod+C { center-column; }
|
Mod+C { center-column; }
|
||||||
Mod+Ctrl+C { center-visible-columns; }
|
Mod+Ctrl+C { center-visible-columns; }
|
||||||
|
|||||||
@@ -5,9 +5,28 @@ window-rule {
|
|||||||
clip-to-geometry true
|
clip-to-geometry true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window-rule {
|
||||||
|
// 以下应用不应该开模糊——开了模糊也只是附上一层边框色,并不具备通常意义上的亚克力、云母质感。
|
||||||
|
// 排除列表随时更新。因为我测不过来。
|
||||||
|
// 另注:为什么不用正则组合成一行?正则越长性能开销越大。况且单独的应用方便用注释切换。
|
||||||
|
exclude app-id="QQ"
|
||||||
|
exclude app-id="wechat"
|
||||||
|
exclude app-id="steam"
|
||||||
|
exclude app-id="google-chrome"
|
||||||
|
exclude app-id="org.telegram.desktop"
|
||||||
|
exclude app-id=".exe$" // wine
|
||||||
|
exclude title=r#"Visual Studio Code$"# app-id=r#"^code"#
|
||||||
|
// match app-id="(foot|obs)"
|
||||||
|
opacity 0.8
|
||||||
|
background-effect {
|
||||||
|
blur true
|
||||||
|
xray false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
window-rule {
|
window-rule {
|
||||||
match app-id="QQ"
|
match app-id="QQ"
|
||||||
match app-id="Electron" title="MetaCubeXD$"
|
match app-id="[Ee]lectron" title="MetaCubeXD$"
|
||||||
match app-id="wechat"
|
match app-id="wechat"
|
||||||
match app-id="org.telegram.desktop"
|
match app-id="org.telegram.desktop"
|
||||||
match app-id="nwjs" // mainly for rpgmaker games.
|
match app-id="nwjs" // mainly for rpgmaker games.
|
||||||
@@ -27,8 +46,8 @@ window-rule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
window-rule {
|
window-rule {
|
||||||
match app-id="Electron" title="Test" // frg2089.BiliLive.Observer
|
match app-id="[Ee]lectron" title="Test" // frg2089.BiliLive.Observer
|
||||||
match app-id="Electron" title="Blivechat-Openlive" // blivechat
|
match app-id="[Ee]lectron" title="Blivechat-Openlive" // blivechat
|
||||||
default-column-width { proportion 0.42; }
|
default-column-width { proportion 0.42; }
|
||||||
// default-column-display "tabbed"
|
// default-column-display "tabbed"
|
||||||
open-on-output "eDP-1"
|
open-on-output "eDP-1"
|
||||||
|
|||||||
+17
-6
@@ -1,4 +1,4 @@
|
|||||||
// edited. thx to fizzyizzy05.
|
// edited. thx to fizzyizzy05 & silvaire-qwq.
|
||||||
input {
|
input {
|
||||||
keyboard {
|
keyboard {
|
||||||
xkb {
|
xkb {
|
||||||
@@ -58,8 +58,9 @@ output "HDMI-A-1" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
layout {
|
layout {
|
||||||
gaps 6
|
gaps 8
|
||||||
|
|
||||||
|
background-color "transparent"
|
||||||
center-focused-column "never"
|
center-focused-column "never"
|
||||||
|
|
||||||
preset-column-widths {
|
preset-column-widths {
|
||||||
@@ -127,10 +128,17 @@ overview {
|
|||||||
}
|
}
|
||||||
|
|
||||||
layer-rule {
|
layer-rule {
|
||||||
match namespace="^wallpaper$"
|
match namespace="^noctalia-overview*"
|
||||||
place-within-backdrop true
|
place-within-backdrop true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layer-rule {
|
||||||
|
match namespace="^noctalia-(background|launcher-overlay|dock)-.*$"
|
||||||
|
background-effect {
|
||||||
|
xray false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
animations {
|
animations {
|
||||||
// off
|
// off
|
||||||
|
|
||||||
@@ -175,15 +183,15 @@ animations {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 我看雪叶是把能拆的大板块都拆得一干二净,但就我这份配置而言,拆两份常用的出来已经足矣了。
|
// 我看雪叶是把能拆的大板块都拆得一干二净,但就我这份配置而言,拆两份常用的出来已经足矣。
|
||||||
// 部分视觉效果拆出去可能还会失效(比如窗口边框)。
|
// 部分视觉效果拆出去可能还会失效(比如窗口边框)。
|
||||||
include "config-window.kdl"
|
include "config-window.kdl"
|
||||||
include "config-keyboard.kdl"
|
include "config-keyboard.kdl"
|
||||||
|
|
||||||
// spawn-at-startup "waybar" // 建议交给 systemctl --user,它自己没法热重载。
|
// spawn-at-startup "waybar" // 建议交给 systemctl --user,它自己没法热重载。
|
||||||
// spawn-sh-at-startup "wl-paste --watch cliphist store"
|
// spawn-sh-at-startup "wl-paste --watch cliphist store"
|
||||||
spawn-at-startup "awww-daemon"
|
// spawn-at-startup "awww-daemon"
|
||||||
// spawn-at-startup "awww-daemon" "--namespace" "blur"
|
spawn-at-startup "qs" "-c" "noctalia-shell"
|
||||||
spawn-at-startup "xwayland-satellite"
|
spawn-at-startup "xwayland-satellite"
|
||||||
spawn-at-startup "/usr/lib/pam_kwallet_init"
|
spawn-at-startup "/usr/lib/pam_kwallet_init"
|
||||||
|
|
||||||
@@ -208,3 +216,6 @@ prefer-no-csd
|
|||||||
// 我自己搞了个软链接,把截图丢进 tmpfs 里了。参见 .zshrc。
|
// 我自己搞了个软链接,把截图丢进 tmpfs 里了。参见 .zshrc。
|
||||||
screenshot-path "~/.tmp/Screenshots/%Y-%m-%d %H-%M-%S.png"
|
screenshot-path "~/.tmp/Screenshots/%Y-%m-%d %H-%M-%S.png"
|
||||||
// screenshot-path null
|
// screenshot-path null
|
||||||
|
|
||||||
|
include "./noctalia.kdl"
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[flavor]
|
||||||
|
dark = "noctalia"
|
||||||
|
light = "noctalia"
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
*.tar.zst
|
*.tar.zst
|
||||||
fake-nautilus/**/
|
fake-nautilus/**/
|
||||||
.config/environment.d/[^0-9]*.conf
|
.config/environment.d/[^0-9]*.conf
|
||||||
|
*noctalia*
|
||||||
|
|||||||
@@ -1,192 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
|
||||||
# Copyright © 2021 mpan; <https://mpan.pl/>; CC0 1.0 (THIS SCRIPT!)
|
|
||||||
# Arch 论坛贴: <https://bbs.archlinux.org/viewtopic.php?id=269453>
|
|
||||||
# UPower 实现: https://github.com/wogscpar/upower-python
|
|
||||||
|
|
||||||
# -*- encoding: utf-8 -*-
|
|
||||||
# @File : .battery-warn
|
|
||||||
# @Time : 2025/12/29 00:32:53
|
|
||||||
# @Author : SilverAg.L
|
|
||||||
|
|
||||||
# 搁 bash 折腾管道还是太原始了。
|
|
||||||
# 包依赖 (pacman): python-dbus, libnotify, pipewire-audio
|
|
||||||
|
|
||||||
import dbus
|
|
||||||
|
|
||||||
from os import getenv
|
|
||||||
from subprocess import run as start_process
|
|
||||||
|
|
||||||
# region config
|
|
||||||
# 哪怕设备名也不稳定。pipewire 滚了几轮,桌面扬声器居然不见了。
|
|
||||||
# AUD_OUT_EMB = ( # my laptop embedded speaker
|
|
||||||
# "alsa_output.pci-0000_00_1f"
|
|
||||||
# ".3-platform-skl_hda_dsp_generic.HiFi__Speaker__sink"
|
|
||||||
# )
|
|
||||||
# 环境变量展开这一块。同时也是为了查找起来方便。毕竟已经有 gtklock 这个例外了。
|
|
||||||
AUD_FILE = "~/.local/share/.low_power.wav".replace("~", getenv("HOME"), 1)
|
|
||||||
# endregion config
|
|
||||||
|
|
||||||
|
|
||||||
class UPowerManager():
|
|
||||||
def __init__(self):
|
|
||||||
self.UPOWER_NAME = "org.freedesktop.UPower"
|
|
||||||
self.UPOWER_PATH = "/org/freedesktop/UPower"
|
|
||||||
|
|
||||||
self.DBUS_PROPERTIES = "org.freedesktop.DBus.Properties"
|
|
||||||
self.bus = dbus.SystemBus()
|
|
||||||
|
|
||||||
def __upower(self, subpath=None, *, interface=None):
|
|
||||||
if not subpath:
|
|
||||||
subpath = ""
|
|
||||||
upower_proxy = self.bus.get_object(
|
|
||||||
self.UPOWER_NAME,
|
|
||||||
self.UPOWER_PATH + subpath
|
|
||||||
)
|
|
||||||
if interface is None:
|
|
||||||
interface = self.UPOWER_NAME
|
|
||||||
return dbus.Interface(upower_proxy, interface)
|
|
||||||
|
|
||||||
def __device(self, devpath):
|
|
||||||
devproxy = self.bus.get_object(self.UPOWER_NAME, devpath)
|
|
||||||
return dbus.Interface(devproxy, self.DBUS_PROPERTIES)
|
|
||||||
|
|
||||||
def detect_devices(self):
|
|
||||||
return self.__upower().EnumerateDevices()
|
|
||||||
|
|
||||||
def get_display_device(self):
|
|
||||||
return self.__upower().GetDisplayDevice()
|
|
||||||
|
|
||||||
def get_critical_action(self):
|
|
||||||
return self.__upower().GetCriticalAction()
|
|
||||||
|
|
||||||
def get_device_info(self, dev, property):
|
|
||||||
return self.__device(dev).Get(
|
|
||||||
self.UPOWER_NAME + ".Device", property)
|
|
||||||
|
|
||||||
def get_full_device_info(self, dev):
|
|
||||||
return {
|
|
||||||
'HasHistory': self.get_device_info(dev, "HasHistory"),
|
|
||||||
'HasStatistics': self.get_device_info(dev, "HasStatistics"),
|
|
||||||
'IsPresent': self.get_device_info(dev, "IsPresent"),
|
|
||||||
'IsRechargeable': self.get_device_info(dev, "IsRechargeable"),
|
|
||||||
'Online': self.get_device_info(dev, "Online"),
|
|
||||||
'PowerSupply': self.get_device_info(dev, "PowerSupply"),
|
|
||||||
'Capacity': self.get_device_info(dev, "Capacity"),
|
|
||||||
'Energy': self.get_device_info(dev, "Energy"),
|
|
||||||
'EnergyEmpty': self.get_device_info(dev, "EnergyEmpty"),
|
|
||||||
'EnergyFull': self.get_device_info(dev, "EnergyFull"),
|
|
||||||
'EnergyFullDesign': self.get_device_info(dev, "EnergyFullDesign"),
|
|
||||||
'EnergyRate': self.get_device_info(dev, "EnergyRate"),
|
|
||||||
'Luminosity': self.get_device_info(dev, "Luminosity"),
|
|
||||||
'Percentage': self.get_device_info(dev, "Percentage"),
|
|
||||||
'Temperature': self.get_device_info(dev, "Temperature"),
|
|
||||||
'Voltage': self.get_device_info(dev, "Voltage"),
|
|
||||||
'TimeToEmpty': self.get_device_info(dev, "TimeToEmpty"),
|
|
||||||
'TimeToFull': self.get_device_info(dev, "TimeToFull"),
|
|
||||||
'IconName': self.get_device_info(dev, "IconName"),
|
|
||||||
'Model': self.get_device_info(dev, "Model"),
|
|
||||||
'NativePath': self.get_device_info(dev, "NativePath"),
|
|
||||||
'Serial': self.get_device_info(dev, "Serial"),
|
|
||||||
'Vendor': self.get_device_info(dev, "Vendor"),
|
|
||||||
'State': self.get_device_info(dev, "State"),
|
|
||||||
'Technology': self.get_device_info(dev, "Technology"),
|
|
||||||
'Type': self.get_device_info(dev, "Type"),
|
|
||||||
'WarningLevel': self.get_device_info(dev, "WarningLevel"),
|
|
||||||
'UpdateTime': self.get_device_info(dev, "UpdateTime")
|
|
||||||
}
|
|
||||||
|
|
||||||
def is_lid_present(self):
|
|
||||||
return bool(self.__upower(interface=self.DBUS_PROPERTIES).Get(
|
|
||||||
self.UPOWER_NAME, 'LidIsPresent'))
|
|
||||||
|
|
||||||
def is_lid_closed(self):
|
|
||||||
return bool(self.__upower(interface=self.DBUS_PROPERTIES).Get(
|
|
||||||
self.UPOWER_NAME, 'LidIsClosed'))
|
|
||||||
|
|
||||||
def on_battery(self):
|
|
||||||
return bool(self.__upower(interface=self.DBUS_PROPERTIES).Get(
|
|
||||||
self.UPOWER_NAME, 'OnBattery'))
|
|
||||||
|
|
||||||
def has_wakeup_capabilities(self):
|
|
||||||
return bool(self.__upower(
|
|
||||||
"/Wakeups",
|
|
||||||
interface=self.DBUS_PROPERTIES
|
|
||||||
).Get(self.UPOWER_NAME + '.Wakeups', 'HasCapability'))
|
|
||||||
|
|
||||||
def get_wakeups_data(self):
|
|
||||||
return self.__upower(
|
|
||||||
"/Wakeups",
|
|
||||||
interface=self.UPOWER_NAME + '.Wakeups'
|
|
||||||
).GetData()
|
|
||||||
|
|
||||||
def get_wakeups_total(self):
|
|
||||||
return self.__upower(
|
|
||||||
"/Wakeups",
|
|
||||||
interface=self.UPOWER_NAME + '.Wakeups'
|
|
||||||
).GetTotal()
|
|
||||||
|
|
||||||
def is_loading(self, battery):
|
|
||||||
return int(self.get_device_info(battery, "State")) == 1
|
|
||||||
|
|
||||||
def get_state(self, battery):
|
|
||||||
return {
|
|
||||||
0: "Unknown",
|
|
||||||
1: "Loading",
|
|
||||||
2: "Discharging",
|
|
||||||
3: "Empty",
|
|
||||||
4: "Fully charged",
|
|
||||||
5: "Pending charge",
|
|
||||||
6: "Pending discharge"
|
|
||||||
}.get(int(self.get_device_info(battery, "State")), "Unknown")
|
|
||||||
|
|
||||||
def is_supplying_battery(self, battery):
|
|
||||||
return (
|
|
||||||
int(self.get_device_info(battery, "Type")) == 2
|
|
||||||
and bool(self.get_device_info(battery, "PowerSupply"))
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def push_notification(title, message, timeout=10000):
|
|
||||||
BUS_NAME = INTERFACE = "org.freedesktop.Notifications"
|
|
||||||
OBJECT_PATH = "/org/freedesktop/Notifications"
|
|
||||||
|
|
||||||
notify = dbus.Interface(
|
|
||||||
dbus.SessionBus().get_object(BUS_NAME, OBJECT_PATH),
|
|
||||||
INTERFACE
|
|
||||||
)
|
|
||||||
notify.Notify(
|
|
||||||
"battery-warn-script", # app_name
|
|
||||||
0, # replaces_id
|
|
||||||
"", # app_icon
|
|
||||||
title, # summary
|
|
||||||
message, # body
|
|
||||||
[], # actions
|
|
||||||
{}, # hints
|
|
||||||
timeout # expire_timeout
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
upowr = UPowerManager()
|
|
||||||
if not upowr.on_battery():
|
|
||||||
exit(0)
|
|
||||||
|
|
||||||
low_power_detected = False
|
|
||||||
for device in upowr.detect_devices():
|
|
||||||
if not upowr.is_supplying_battery(device):
|
|
||||||
continue
|
|
||||||
# seems waybar visual is 1% lower than actual.
|
|
||||||
if upowr.get_device_info(device, "Percentage") < 21:
|
|
||||||
bat_id = upowr.get_device_info(device, "NativePath")
|
|
||||||
push_notification(
|
|
||||||
"Power Hint",
|
|
||||||
f"{bat_id} is running out. Recharge soon!"
|
|
||||||
)
|
|
||||||
low_power_detected = True
|
|
||||||
if low_power_detected:
|
|
||||||
start_process([
|
|
||||||
"pw-play",
|
|
||||||
# f"--target={AUD_OUT_EMB}",
|
|
||||||
AUD_FILE
|
|
||||||
])
|
|
||||||
@@ -1,61 +1,78 @@
|
|||||||
# niri 散装配置集(dotfiles)
|
# niri 散装配置集(dotfiles)
|
||||||
|
|
||||||
都怪雪叶!(
|
都怪雪叶!
|
||||||
|
|
||||||
> [!note]
|
|
||||||
> 1. Liteyuki Gitea 黑色主题对`这样的`代码块不太友好,为方便阅读我尽量少这么写。
|
|
||||||
> 1. 本仓库的配置管理方案比较原始:逐个做软链接处理。
|
|
||||||
> 个人并不打算无脑用 stow ,尤其不希望一些 systemd 服务和涉及 token 的自用小工具混进来。
|
|
||||||
> 2. 还有一些早期配置在整理本仓库时已经淡忘,由于篇幅和复述可靠性有限,亦不考虑收纳。
|
|
||||||
> 3. 涉及家目录`$HOME`、`~`、`%h`开头(最后一个多见于 systemd 服务)的路径建议自行适配——我的设定你不一定会满意。
|
|
||||||
> - 另注:gtklock 没有办法取巧,只能填绝对路径。算是为数不多的漏网之鱼。
|
|
||||||
|
|
||||||
## 鸣谢
|
## 鸣谢
|
||||||
- 雪叶 [@Vescrity](https://github.com/Vescrity) (Yukitoha)
|
- 雪叶 [@Vescrity](https://github.com/Vescrity) (Yukitoha)
|
||||||
- fizzyizzy05 (Isabelle Jackson)
|
- fizzyizzy05 (Isabelle Jackson)
|
||||||
|
- [@silvaire-qwq](https://github.com/silvaire-qwq)
|
||||||
|
|
||||||
## 已知依赖
|
## 注意事项
|
||||||
> 仅列出**想得起来的**依赖软件包。
|
懒得写说明文档了。姑且列个表吧。
|
||||||
|
|
||||||
|依赖|配置|
|
- sddm -> niri -> xdg-portal
|
||||||
|-|-|
|
1. sddm 主题:sddm-sugar-candy-git
|
||||||
|niri|.config/niri/config*.kdl|
|
2. `[General]` 开启 Numlock
|
||||||
|➡️ fuzzel|.config/fuzzel/*|
|
3. niri 配置位于:.config/niri
|
||||||
|➡️ mako|.config/mako/*|
|
- 姑且按修改频次拆分为 config-*.kdl。不建议拆太多,视觉效果容易失效。
|
||||||
|➡️ awww 和 swaybg|bin/chbg (bash 脚本);swaybg.service|
|
- 启用 niri 原生窗口模糊需要从源码构建(即**换用 niri-git^AUR^**)
|
||||||
|➡️ gtklock|.config/gtklock/*|
|
- 部分应用(典型如 Chromium 应用和 wine 调起的 Windows 应用)无法应用模糊效果:参见`config-window.kdl`内注释。
|
||||||
|➡️ xdg-desktop-portal-(gtk\|gnome)|.config/xdg-desktop-portal/*-portals.conf|
|
4. 本仓库的方案**不需要**装大多数 niri 可选依赖。至少只需要以下包:
|
||||||
|➡️ kwallet|VSCode 试图登录时会弹出向导让你配的。|
|
- xdg-desktop-portal-*
|
||||||
|foot|.config/foot/foot.ini|
|
- xwayland-satellite
|
||||||
|➡️ zsh|.zshrc .zprofile|
|
5. 我个人把密码管理器交给 kwallet(可在 .config/xdg-desktop-portal/niri-portals.conf 里查改)。
|
||||||
|yazi|.config/yazi/*|
|
- 装 kwallet 建议加装 kwallet-pam,免得 VSCode 等应用自己尝试解锁结果闪退。
|
||||||
|fastfetch|.config/fastfetch/*|
|
|
||||||
|waybar|.config/waybar/*|
|
|
||||||
|➡️ mpris|`systemctl --user`配置自启动(参见 ArchWiki)|
|
|
||||||
|➡️ pavucontrol-qt|
|
|
||||||
|
|
||||||
> 备注(太长了统一丢在下面):
|
- niri -> noctalia -> foot, yazi, mpris, fuzzel...
|
||||||
> - niri 配置只拆分了 window-rule 和 binds(即`config-*.kdl),拆太碎有些视觉效果会失效。
|
1. 由于引入 Noctalia Shell,另自动集成了配色模板。模板\*可以做到\*随壁纸切换自动更变色调,故本仓库**不包含**它们。
|
||||||
> - Chrome 的消息推送都是无脑标 CRITICAL 级,没有办法调持续时间,量一多还会卡在那里,只能`makoctl reload`强制重载。
|
2. 由于 noctalia 接管了大部分桌面 UI,以下散装部件弃用(配置移至 .deprecated ):
|
||||||
> - chbg 依赖 imagemagick。awww 目前对多个命名空间的加载有问题:[\#521](https://codeberg.org/LGFae/awww/issues/521)。经各种方案的实地测试,最终还是考虑 swaybg 服务 + awww 混合。
|
- waybar (含 pavucontrol-qt), mako, gtklock
|
||||||
> - gtklock 自身无法挂多个后台(即只能有一个`gtklock -d`,多了会报错),虽然也算侧面实现了单例,但搭配 swayidle 和 swaylock 可能不算好用。我是只在休眠快捷键里简单做了下 pgrep 检查。
|
- bin/chbg (含 swaybg 和 awww)
|
||||||
> - niri 设计上就是用 gnome 作 xdg 后端,也就它支持最全。但 gnome 界面算不上好看,所以也有一些人考虑局部更换为 gtk 或 kde。像我就用 kwallet 替代 gnome-keyring。
|
3. fuzzel 无法弃用:*我需要将 VSC 打开的项目锁死在桌面范围内*,而 Noctalia 插件做不到。
|
||||||
> - 装 kwallet 建议加装 kwallet-pam,免得 VSCode 自己尝试解锁结果闪退。
|
- 当然 Mod+Space 仍调整为 Noctalia 启动面板。毕竟 .fuzzel-startb 只能当 Win+R 用。
|
||||||
> - 有关终端:我另使用了 ZshIM 和 powerlevel10k 主题,因此会掺入自动生成的初始化命令。
|
3. noctalia 自身设置可以通过 GUI 微调:面板里有设置。配置文件恕不提供(懒得维护了)。
|
||||||
> - 有关 fake-nautilus:我是觉得 nautilus 不好看。在雪叶的指导下搞了个空包替代这个 gnome 后端必需的依赖。
|
4. 尚不确定 noctalia 里的媒体组件是否还需要 mpris(毕竟原本是 waybar 在管)。对其的设置参见 Arch Wiki。
|
||||||
> - waybar(和 swaybg)重载:建议搭配`systemctl --user`(参见 [niri 在线文档](https://yalter.github.io/niri/Example-systemd-Setup.html))以便重载配置。若是用 niri 的 spawn-at-startup,杀进程重启、挂后台可谓相当麻烦。
|
|
||||||
|
|
||||||
## 参考资源与备注
|
> 统一交给 noctalia 还是散装,见仁见智。我觉得好看就行。
|
||||||
- Nerd 字体:[Monaco Nerd Font Mono](https://glowmem.com/upload/articles/archlinux-note/Monaco_Nerd_Font_Mono-Regular.ttf) (MelodyEcho ver.) 或直接 [MesloLGS NF](https://github.com/romkatv/powerlevel10k/blob/master/font.md) (for p10k)。
|
|
||||||
|
|
||||||
- 深色模式:`gsettings set org.gnome.desktop.interface color-scheme prefer-dark`
|
- foot -> zsh, fastfetch
|
||||||
GTK/QT 深色主题:参见 [Arch Wiki](https://wiki.archlinux.org/title/Uniform_look_for_Qt_and_GTK_applications#Styles_for_both_Qt_and_GTK)。我摆烂了。
|
1. zsh 另装了 ZshIM(即 ZIM)和 powerlevel10k 主题。
|
||||||
|
2. 请酌情调整 .zprofile 里的 PATH 路径。
|
||||||
|
3. 有一些仅当前用户安装的包管理器(bun、uv、nvm)也在 .zshrc 初始化配置。酌情挑选需要的设置行。
|
||||||
|
|
||||||
- 大多数 Electron 应用需要读`~/.config/*-flags.conf`来适配 Wayland,
|
## 其他组件
|
||||||
你可以把`default-electron-flags`相应地软链接过去。**特别地,QQ 需要多加一条**`--wayland-text-input-version=3`。
|
|
||||||
|
|
||||||
- `hoyocloud-chromium-userscript.js`顾名思义,用于**在 Chrome 里**(firefox 不需要)游玩米哈游云游戏的油猴脚本。
|
### default-electron-flags
|
||||||
|
|
||||||
|
用于 electron/chromium 应用(如 chrome、VSCode、linuxqq)的命令行标签。可以这么软链接:
|
||||||
|
```bash
|
||||||
|
ln -s ./default-electron-flags ~/.config/chrome-flags.conf
|
||||||
|
```
|
||||||
|
但 qq-flags.conf 略为不同:
|
||||||
|
```
|
||||||
|
-enable-platform=wayland --enable-wayland-ime --wayland-text-input-version=3
|
||||||
|
```
|
||||||
|
|
||||||
|
### hoyocloud-chromium-userscript.js
|
||||||
|
|
||||||
|
用于 Chrome(火狐不需要)的米哈游云游戏油猴脚本。
|
||||||
参见 [Bilibili 专栏](https://www.bilibili.com/opus/842314310196658193)。
|
参见 [Bilibili 专栏](https://www.bilibili.com/opus/842314310196658193)。
|
||||||
|
|
||||||
- `bin/.battery-warn`虽说也是自用,但一是配置项并不算敏感,稍微改改`config`段也可以泛用;二是参考文献写得有点啰嗦,我懒得再缝第二遍。
|
### fake-nautilus
|
||||||
个人建议用于**定时任务(cron 或 systemd timer)**。
|
|
||||||
|
经雪叶指导搞出来的空包。现在执行 nautilus 会发个通知:*Doki Doki Forever!*
|
||||||
|
|
||||||
|
旨在替换 gnome portal 的必需依赖 nautilus(就是 GNOME 文件浏览器),因为太丑了。
|
||||||
|
|
||||||
|
## 补充说明
|
||||||
|
Nerd 字体:[Monaco Nerd Font Mono](https://glowmem.com/upload/articles/archlinux-note/Monaco_Nerd_Font_Mono-Regular.ttf) (MelodyEcho ver.) 或直接 [MesloLGS NF](https://github.com/romkatv/powerlevel10k/blob/master/font.md) (for p10k)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
深色模式:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gsettings set org.gnome.desktop.interface color-scheme prefer-dark
|
||||||
|
```
|
||||||
|
|
||||||
|
GTK/QT 深色主题:参见 [Arch Wiki](https://wiki.archlinux.org/title/Uniform_look_for_Qt_and_GTK_applications#Styles_for_both_Qt_and_GTK)。我摆烂了。
|
||||||
|
|||||||
Reference in New Issue
Block a user