feat: add KDE Plasma customization scripts and docs
This commit is contained in:
173
README.md
Normal file
173
README.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# manjaro_kde_custom
|
||||
|
||||
我当前这台 Manjaro + KDE Plasma 6 机器的美化配置归档。
|
||||
|
||||
## 内容
|
||||
|
||||
- `scripts/recalc-plasma-bottom-docks.sh`
|
||||
- 自动按当前显示器数量/尺寸重算底部 dock
|
||||
- 确保每块启用中的屏幕都有一个底部 dock
|
||||
- dock 统一保持:底部、居中、浮动、自动隐藏、长度随内容变化 (`fit`)
|
||||
- `systemd/plasma-dock-autofit.service`
|
||||
- 登录后执行一次自动重算
|
||||
- `systemd/plasma-dock-autofit.path`
|
||||
- 监听 `~/.config/kwinoutputconfig.json`,显示器布局变化时自动重算
|
||||
- `presets/LogicDock/settings.json`
|
||||
- 当前实际使用中的 Panel Colorizer 自定义预设
|
||||
- 基于内置 Dock 预设修改而来,当前特点:
|
||||
- 更圆的圆角
|
||||
- 更大的 padding / spacing
|
||||
- 更明显的阴影
|
||||
- 更适合多屏下的底部自动隐藏 dock
|
||||
- `docs/dock-launchers.txt`
|
||||
- 当前主 dock 固定的启动器列表
|
||||
- `install.sh`
|
||||
- 一键安装脚本
|
||||
- `uninstall.sh`
|
||||
- 卸载自动重算脚本与 systemd 用户服务
|
||||
|
||||
## 这套美化当前依赖
|
||||
|
||||
- KDE Plasma 6
|
||||
- [Panel Colorizer](https://github.com/luisbocanegra/plasma-panel-colorizer)
|
||||
- 当前全局主题:`com.github.vinceliuice.Layan`
|
||||
- 可选:`kvantum` / `kvantum-qt5`
|
||||
|
||||
> 当前机器使用的是 Layan 全局主题;dock 的圆角和悬浮视觉主要由 Panel Colorizer 提供。
|
||||
|
||||
## 安装
|
||||
|
||||
### 1. 安装依赖
|
||||
|
||||
Manjaro / Arch:
|
||||
|
||||
```bash
|
||||
sudo pacman -S spectacle python python-dbus python-gobject kvantum kvantum-qt5 papirus-icon-theme
|
||||
```
|
||||
|
||||
Panel Colorizer:
|
||||
|
||||
```bash
|
||||
yay -S plasma6-applets-panel-colorizer
|
||||
```
|
||||
|
||||
Layan 主题请通过 KDE Store 安装,或者使用你自己的 Plasma 6 主题。
|
||||
|
||||
### 2. 安装本仓库配置
|
||||
|
||||
在仓库根目录执行:
|
||||
|
||||
```bash
|
||||
./install.sh
|
||||
```
|
||||
|
||||
它会做这些事:
|
||||
|
||||
- 安装自动重算脚本到 `~/.local/bin/`
|
||||
- 安装用户级 systemd 服务到 `~/.config/systemd/user/`
|
||||
- 安装 `LogicDock` 预设到 `~/.config/panel-colorizer/presets/LogicDock`
|
||||
- 启用并立即运行自动重算服务
|
||||
|
||||
### 3. 生效逻辑
|
||||
|
||||
- 登录后自动执行一次
|
||||
- 当 KDE 显示器布局配置发生变化时自动执行
|
||||
- 会自动为每块启用中的屏幕创建/修正底部 dock
|
||||
|
||||
## 当前 dock 行为
|
||||
|
||||
- 底部
|
||||
- 居中
|
||||
- 浮动
|
||||
- 自动隐藏
|
||||
- 长度按内容动态扩展,不固定留大空白
|
||||
- 每块屏幕都各自有 dock
|
||||
- 显示器变化后自动重算
|
||||
|
||||
## Panel Colorizer 预设说明
|
||||
|
||||
当前使用的是 `LogicDock` 预设,而不是单纯的内置 `Dock`:
|
||||
|
||||
- 更大的圆角:更接近 mac 风格
|
||||
- 更大的左右内边距:图标不会太挤
|
||||
- 更大的 widget spacing:dock 视觉更舒展
|
||||
- 阴影稍加强:悬浮感更明显
|
||||
|
||||
如果你想手动应用这个预设:
|
||||
|
||||
1. 确保 bottom dock 里已经有 `Panel Colorizer`
|
||||
2. 右键 `Panel Colorizer` → 配置
|
||||
3. Presets → 选择 `LogicDock`
|
||||
|
||||
## Kvantum 说明
|
||||
|
||||
Kvantum 是 Qt 应用控件主题引擎,主要影响:
|
||||
|
||||
- 按钮
|
||||
- 输入框
|
||||
- 菜单
|
||||
- 滚动条
|
||||
|
||||
它**不负责** Plasma 面板布局本身。
|
||||
|
||||
a. 安装:
|
||||
|
||||
```bash
|
||||
sudo pacman -S kvantum kvantum-qt5
|
||||
```
|
||||
|
||||
b. 打开:
|
||||
|
||||
```bash
|
||||
kvantummanager
|
||||
```
|
||||
|
||||
c. 在 KDE 中启用:
|
||||
|
||||
- 系统设置 → 应用程序样式 → Qt 程序样式 → 选择 `Kvantum`
|
||||
|
||||
## 恢复 / 卸载
|
||||
|
||||
```bash
|
||||
./uninstall.sh
|
||||
```
|
||||
|
||||
如果只想临时停用:
|
||||
|
||||
```bash
|
||||
systemctl --user disable --now plasma-dock-autofit.path plasma-dock-autofit.service
|
||||
```
|
||||
|
||||
## 额外推荐的小组件
|
||||
|
||||
### 官方最稳
|
||||
|
||||
- `System Monitor Memory`
|
||||
- `System Monitor Net`
|
||||
|
||||
官方页:
|
||||
- https://apps.kde.org/plasma-systemmonitor/
|
||||
|
||||
### 看上传/下载速度
|
||||
|
||||
- `Network Bandwidth Monitor - Qt6`
|
||||
- KDE Store: https://store.kde.org/p/2280811
|
||||
|
||||
### 轻量看 RAM / 温度
|
||||
|
||||
- `KVitals`
|
||||
- KDE Discuss: https://discuss.kde.org/t/kvitals-a-lightweight-plasma-6-panel-widget-for-system-vitals/44363
|
||||
|
||||
## 备注
|
||||
|
||||
这个仓库归档的是**我当前机器上实际跑通的一套配置**。
|
||||
|
||||
如果后面 Plasma / Panel Colorizer 升级后行为变化,建议:
|
||||
|
||||
1. 先执行 `./install.sh` 重新覆盖脚本和服务
|
||||
2. 注销并重新登录一次
|
||||
3. 再手动执行一次:
|
||||
|
||||
```bash
|
||||
~/.local/bin/recalc-plasma-bottom-docks.sh
|
||||
```
|
||||
1
docs/dock-launchers.txt
Normal file
1
docs/dock-launchers.txt
Normal file
@@ -0,0 +1 @@
|
||||
applications:systemsettings.desktop,preferred://filemanager,preferred://browser
|
||||
1
docs/look-and-feel.txt
Normal file
1
docs/look-and-feel.txt
Normal file
@@ -0,0 +1 @@
|
||||
LookAndFeelPackage=com.github.vinceliuice.Layan
|
||||
19
docs/packages.txt
Normal file
19
docs/packages.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
# Required / recommended packages
|
||||
# Install according to your preference.
|
||||
|
||||
# Required for the dock setup
|
||||
spectacle
|
||||
python
|
||||
python-dbus
|
||||
python-gobject
|
||||
plasma6-applets-panel-colorizer
|
||||
|
||||
# Theme / style used on this machine
|
||||
Layan KDE Global Theme (KDE Store)
|
||||
|
||||
# Optional Qt style engine
|
||||
kvantum
|
||||
kvantum-qt5
|
||||
|
||||
# Recommended icon themes
|
||||
papirus-icon-theme
|
||||
14
install.sh
Executable file
14
install.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
REPO_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
||||
mkdir -p "$HOME/.local/bin" "$HOME/.config/systemd/user" "$HOME/.config/panel-colorizer/presets"
|
||||
install -m 755 "$REPO_DIR/scripts/recalc-plasma-bottom-docks.sh" "$HOME/.local/bin/recalc-plasma-bottom-docks.sh"
|
||||
install -m 644 "$REPO_DIR/systemd/plasma-dock-autofit.service" "$HOME/.config/systemd/user/plasma-dock-autofit.service"
|
||||
install -m 644 "$REPO_DIR/systemd/plasma-dock-autofit.path" "$HOME/.config/systemd/user/plasma-dock-autofit.path"
|
||||
rm -rf "$HOME/.config/panel-colorizer/presets/LogicDock"
|
||||
cp -a "$REPO_DIR/presets/LogicDock" "$HOME/.config/panel-colorizer/presets/LogicDock"
|
||||
systemctl --user daemon-reload
|
||||
systemctl --user enable --now plasma-dock-autofit.service plasma-dock-autofit.path
|
||||
"$HOME/.local/bin/recalc-plasma-bottom-docks.sh"
|
||||
echo 'Installed. If Panel Colorizer was just updated, log out and back in once.'
|
||||
4540
presets/LogicDock/settings.json
Normal file
4540
presets/LogicDock/settings.json
Normal file
File diff suppressed because it is too large
Load Diff
148
scripts/recalc-plasma-bottom-docks.sh
Executable file
148
scripts/recalc-plasma-bottom-docks.sh
Executable file
@@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
CONFIG_FILE="$HOME/.config/plasma-org.kde.plasma.desktop-appletsrc"
|
||||
CUSTOM_PRESET_DIR="$HOME/.config/panel-colorizer/presets/LogicDock"
|
||||
USER_BUILTIN_PRESET_DIR="$HOME/.local/share/plasma/plasmoids/luisbocanegra.panel.colorizer/contents/ui/presets/Dock"
|
||||
SYSTEM_BUILTIN_PRESET_DIR="/usr/share/plasma/plasmoids/luisbocanegra.panel.colorizer/contents/ui/presets/Dock"
|
||||
PRESET_DIR="$CUSTOM_PRESET_DIR"
|
||||
[[ -d "$PRESET_DIR" ]] || PRESET_DIR="$USER_BUILTIN_PRESET_DIR"
|
||||
[[ -d "$PRESET_DIR" ]] || PRESET_DIR="$SYSTEM_BUILTIN_PRESET_DIR"
|
||||
|
||||
wait_for_plasma() {
|
||||
for _ in $(seq 1 30); do
|
||||
if qdbus6 org.kde.plasmashell /PlasmaShell org.freedesktop.DBus.Introspectable.Introspect >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
get_screen_count() {
|
||||
python - <<'PY'
|
||||
import re, subprocess
|
||||
text = subprocess.check_output(["kscreen-doctor", "-o"], text=True, errors="ignore")
|
||||
text = re.sub(r'\x1b\[[0-9;]*[A-Za-z]', '', text)
|
||||
blocks = re.split(r'(?=Output: )', text)
|
||||
count = 0
|
||||
for block in blocks:
|
||||
if not block.startswith('Output: '):
|
||||
continue
|
||||
if re.search(r'^\s*enabled\s*$', block, re.M):
|
||||
count += 1
|
||||
print(max(count, 1))
|
||||
PY
|
||||
}
|
||||
|
||||
get_bottom_colorizers() {
|
||||
python - <<'PY'
|
||||
import configparser, json, os, pathlib, re
|
||||
cfg = pathlib.Path(os.path.expanduser('~/.config/plasma-org.kde.plasma.desktop-appletsrc'))
|
||||
cp = configparser.RawConfigParser(interpolation=None)
|
||||
cp.optionxform = str
|
||||
cp.read(cfg)
|
||||
items = []
|
||||
for sec in cp.sections():
|
||||
m = re.fullmatch(r'Containments\]\[(\d+)', sec)
|
||||
if not m:
|
||||
continue
|
||||
cid = int(m.group(1))
|
||||
if cp.get(sec, 'plugin', fallback='') != 'org.kde.panel':
|
||||
continue
|
||||
if cp.get(sec, 'location', fallback='') not in ('4', 'bottom'):
|
||||
continue
|
||||
for asec in cp.sections():
|
||||
am = re.fullmatch(rf'Containments\]\[{cid}\]\[Applets\]\[(\d+)', asec)
|
||||
if not am:
|
||||
continue
|
||||
if cp.get(asec, 'plugin', fallback='') != 'luisbocanegra.panel.colorizer':
|
||||
continue
|
||||
aid = int(am.group(1))
|
||||
items.append({'containment': cid, 'applet': aid})
|
||||
print(json.dumps(sorted(items, key=lambda x: (x['containment'], x['applet']))))
|
||||
PY
|
||||
}
|
||||
|
||||
ensure_bottom_panels() {
|
||||
local screen_count="$1"
|
||||
local targets
|
||||
targets=$(python - <<PY
|
||||
n = int(${screen_count})
|
||||
print(','.join(str(i) for i in range(n)))
|
||||
PY
|
||||
)
|
||||
|
||||
qdbus6 org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "
|
||||
function bottomPanelOnScreen(screenId) {
|
||||
for (var i = 0; i < panelIds.length; ++i) {
|
||||
var p = panelById(panelIds[i]);
|
||||
if (p.location == 'bottom' && p.screen == screenId) return p;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function clamp(v, lo, hi) {
|
||||
return Math.max(lo, Math.min(hi, v));
|
||||
}
|
||||
var targetScreens = [${targets}];
|
||||
for (var i = 0; i < targetScreens.length; ++i) {
|
||||
var sid = targetScreens[i];
|
||||
var panel = bottomPanelOnScreen(sid);
|
||||
if (!panel) {
|
||||
panel = new Panel;
|
||||
panel.screen = sid;
|
||||
panel.location = 'bottom';
|
||||
panel.addWidget('org.kde.plasma.icontasks');
|
||||
panel.addWidget('luisbocanegra.panel.colorizer');
|
||||
}
|
||||
var g = screenGeometry(sid);
|
||||
var h = Math.round(clamp(g.height * 0.048, 70, 76));
|
||||
panel.thickness = h;
|
||||
panel.height = h;
|
||||
panel.lengthMode = 'fit';
|
||||
panel.alignment = 'center';
|
||||
panel.floating = true;
|
||||
panel.hiding = 'autohide';
|
||||
panel.opacity = 'adaptive';
|
||||
}
|
||||
"
|
||||
}
|
||||
|
||||
apply_colorizer_preset() {
|
||||
local json
|
||||
json="$(get_bottom_colorizers)"
|
||||
[[ -z "$json" || "$json" == "[]" ]] && return 0
|
||||
python - <<'PY' "$json" "$PRESET_DIR" "$CONFIG_FILE"
|
||||
import json, subprocess, sys, time
|
||||
pairs = json.loads(sys.argv[1])
|
||||
preset_dir = sys.argv[2]
|
||||
config_file = sys.argv[3]
|
||||
for item in pairs:
|
||||
cid = item['containment']
|
||||
aid = item['applet']
|
||||
service = f'luisbocanegra.panel.colorizer.c{cid}.w{aid}'
|
||||
for _ in range(12):
|
||||
try:
|
||||
subprocess.check_call(['qdbus6', service, '/preset', 'preset', preset_dir], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
break
|
||||
except subprocess.CalledProcessError:
|
||||
time.sleep(0.5)
|
||||
subprocess.call([
|
||||
'kwriteconfig6', '--file', config_file,
|
||||
'--group', 'Containments', '--group', str(cid),
|
||||
'--group', 'Applets', '--group', str(aid),
|
||||
'--group', 'Configuration', '--group', 'General',
|
||||
'--key', 'hideWidget', 'true'
|
||||
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
PY
|
||||
}
|
||||
|
||||
main() {
|
||||
wait_for_plasma || exit 0
|
||||
local screen_count
|
||||
screen_count="$(get_screen_count)"
|
||||
ensure_bottom_panels "$screen_count"
|
||||
apply_colorizer_preset
|
||||
}
|
||||
|
||||
main "$@"
|
||||
10
systemd/plasma-dock-autofit.path
Normal file
10
systemd/plasma-dock-autofit.path
Normal file
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Watch for KDE display layout changes and recalculate Plasma docks
|
||||
|
||||
[Path]
|
||||
PathChanged=%h/.config/kwinoutputconfig.json
|
||||
PathModified=%h/.config/kwinoutputconfig.json
|
||||
Unit=plasma-dock-autofit.service
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
10
systemd/plasma-dock-autofit.service
Normal file
10
systemd/plasma-dock-autofit.service
Normal file
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Recalculate Plasma bottom docks for current screens
|
||||
After=plasma-plasmashell.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=%h/.local/bin/recalc-plasma-bottom-docks.sh
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
8
uninstall.sh
Executable file
8
uninstall.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
systemctl --user disable --now plasma-dock-autofit.path plasma-dock-autofit.service || true
|
||||
rm -f "$HOME/.config/systemd/user/plasma-dock-autofit.path" "$HOME/.config/systemd/user/plasma-dock-autofit.service"
|
||||
rm -f "$HOME/.local/bin/recalc-plasma-bottom-docks.sh"
|
||||
rm -rf "$HOME/.config/panel-colorizer/presets/LogicDock"
|
||||
systemctl --user daemon-reload
|
||||
echo 'Removed auto-fit service, script and custom preset.'
|
||||
Reference in New Issue
Block a user