Compare commits
54 Commits
d6d65118bf
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
f5948bf3c4
|
|||
|
816016c6f0
|
|||
|
ca2f125654
|
|||
|
0ef0ef2562
|
|||
|
29d1278104
|
|||
|
e610a3d878
|
|||
|
f1c943a99b
|
|||
|
46ac48e963
|
|||
|
630f196a5e
|
|||
|
f27a5ff07b
|
|||
|
6e2299e23f
|
|||
|
4cb055fac4
|
|||
|
8683a7db3b
|
|||
|
78ca119a76
|
|||
|
1a286af126
|
|||
|
0ef960ef7b
|
|||
|
271487380c
|
|||
|
3446d3d97e
|
|||
|
b4932ef737
|
|||
|
3a1b467e5c
|
|||
|
fe4232ec8e
|
|||
|
3fa8251a7f
|
|||
|
ee77c305e4
|
|||
|
182cdb5e09
|
|||
|
f70b115dd1
|
|||
|
4e61fd5b6b
|
|||
|
55e575d43e
|
|||
|
b8f9be7da5
|
|||
|
e466c25a3c
|
|||
|
e02dd62343
|
|||
|
1d78c165aa
|
|||
|
30f62648af
|
|||
|
68e07cfcf6
|
|||
|
3aa66a40a4
|
|||
|
b3e29d2c2a
|
|||
|
fc8a0ee32a
|
|||
|
9548735a31
|
|||
|
5a24c866b4
|
|||
|
1bcf373e80
|
|||
|
28df594cc6
|
|||
|
79f7a3c52e
|
|||
|
6903697587
|
|||
|
c94841d0ea
|
|||
|
c7fb195dce
|
|||
|
a752e3d51d
|
|||
|
ee0407750a
|
|||
|
4381caa172
|
|||
|
e0027ec76d
|
|||
|
5abe50ca5f
|
|||
|
c787376451
|
|||
|
fdc2131a9c
|
|||
|
974c8c9a4b
|
|||
|
73d2c3813f
|
|||
|
5fffcbcd53
|
@@ -1,4 +1,6 @@
|
||||
# Proxy, set in environment.d?
|
||||
http_proxy="http://192.168.1.128:26100/"
|
||||
https_proxy="http://192.168.1.128:26100/"
|
||||
http_proxy="http://127.0.0.1:7890/"
|
||||
https_proxy="http://127.0.0.1:7890/"
|
||||
|
||||
# also needs manual configuration in firefox.
|
||||
no_proxy="127.*,192.168.*,10.147.17.*"
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<string>LXGW WenKai Mono</string>
|
||||
<string>Noto Sans Mono CJK SC</string>
|
||||
<string>Noto Color Emoji</string>
|
||||
<string>Monaco Nerd Font Mono</string>
|
||||
<string>MesloLGS NF</string>
|
||||
<string>Comic Mono</string>
|
||||
</edit>
|
||||
</match>
|
||||
@@ -75,7 +75,7 @@
|
||||
</test>
|
||||
<edit binding="strong" mode="prepend" name="family">
|
||||
<string>Comic Mono</string>
|
||||
<string>Monaco Nerd Font Mono</string>
|
||||
<string>MesloLGS NF</string>
|
||||
<string>Noto Sans Mono CJK SC</string>
|
||||
<string>Noto Color Emoji</string>
|
||||
</edit>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
# title=foot
|
||||
# locked-title=no
|
||||
|
||||
font=Monaco Nerd Font Mono:size=11
|
||||
font=MesloLGS NF:size=11
|
||||
# font-bold=<bold variant of regular font>
|
||||
# font-italic=<italic variant of regular font>
|
||||
# font-bold-italic=<bold+italic variant of regular font>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[main]
|
||||
anchor = top
|
||||
font = MonacoNerdFontMono:size=13
|
||||
font = MesloLGSNF:size=13
|
||||
#dpi-aware = no
|
||||
terminal = foot
|
||||
y-margin = 16
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
style=/home/agxcoy/.config/gtklock/style.css
|
||||
time-format=%H:%M:%S
|
||||
date-format=%Y-%m-%d, %A
|
||||
modules=/usr/lib/gtklock/userinfo-module.so
|
||||
monitor-priority=HDMI-A-1;eDP-1
|
||||
|
||||
@@ -7,7 +7,7 @@ window {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-color: rgba(0,0,0,0.3);
|
||||
font-family: 'Monaco Nerd Font Mono';
|
||||
font-family: 'monospace';
|
||||
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.7)
|
||||
}
|
||||
#input-field {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
sort=-time
|
||||
layer=overlay
|
||||
output=eDP-1
|
||||
background-color=#1e1e2e
|
||||
width=360
|
||||
height=560
|
||||
@@ -10,7 +11,7 @@ icons=1
|
||||
max-icon-size=32
|
||||
default-timeout=5000
|
||||
ignore-timeout=1
|
||||
font=MonacoNerdFontMono 11
|
||||
font=MesloLGSNF 11
|
||||
padding=8
|
||||
|
||||
[urgency=low]
|
||||
|
||||
@@ -41,18 +41,19 @@ input {
|
||||
}
|
||||
|
||||
warp-mouse-to-focus
|
||||
|
||||
// also needs ignore in `/etc/systemd/logind.conf`.
|
||||
disable-power-key-handling
|
||||
focus-follows-mouse max-scroll-amount="0%"
|
||||
}
|
||||
|
||||
output "eDP-1" {
|
||||
scale 1.25
|
||||
scale 1.25
|
||||
}
|
||||
|
||||
output "HDMI-A-1" {
|
||||
mode "1920x1080@180.000"
|
||||
//position x=1920 y=0
|
||||
focus-at-startup
|
||||
mode "1920x1080@180.000"
|
||||
//position x=1920 y=0
|
||||
focus-at-startup
|
||||
}
|
||||
|
||||
layout {
|
||||
@@ -72,7 +73,6 @@ layout {
|
||||
// preset-window-heights { }
|
||||
|
||||
default-column-width { proportion 0.5; }
|
||||
// default-column-width {}
|
||||
|
||||
focus-ring {
|
||||
off
|
||||
@@ -120,8 +120,9 @@ layout {
|
||||
}
|
||||
}
|
||||
|
||||
hotkey-overlay {
|
||||
skip-at-startup
|
||||
overview {
|
||||
backdrop-color "#26233a"
|
||||
zoom 0.5
|
||||
}
|
||||
|
||||
layer-rule {
|
||||
@@ -129,26 +130,6 @@ layer-rule {
|
||||
place-within-backdrop true
|
||||
}
|
||||
|
||||
overview {
|
||||
backdrop-color "#26233a"
|
||||
zoom 0.5
|
||||
}
|
||||
|
||||
switch-events {
|
||||
lid-close { spawn "bash" "-c" "swaylock" "&&" "systemctl" "suspend"; }
|
||||
}
|
||||
|
||||
gestures {
|
||||
hot-corners {
|
||||
off
|
||||
}
|
||||
}
|
||||
|
||||
prefer-no-csd
|
||||
|
||||
screenshot-path "~/.tmp/Screenshots/%Y-%m-%d %H-%M-%S.png"
|
||||
// screenshot-path null
|
||||
|
||||
animations {
|
||||
// off
|
||||
|
||||
@@ -193,274 +174,33 @@ animations {
|
||||
}
|
||||
}
|
||||
|
||||
window-rule {
|
||||
geometry-corner-radius 6
|
||||
clip-to-geometry true
|
||||
}
|
||||
include "config.window.kdl"
|
||||
include "config.keyboard.kdl"
|
||||
|
||||
window-rule {
|
||||
match app-id="QQ"
|
||||
default-column-width { proportion 0.6; }
|
||||
open-on-output "eDP-1"
|
||||
block-out-from "screencast"
|
||||
}
|
||||
|
||||
window-rule {
|
||||
match title="^(图片查看器|.*记录)$" app-id="QQ"
|
||||
|
||||
match app-id=r#"^org\.keepassxc\.KeePassXC$"#
|
||||
match app-id=r#"^org\.gnome\.World\.Secrets$"#
|
||||
match app-id=r#"^org\.kde\.ksecretd$"#
|
||||
|
||||
match app-id="pavucontrol-qt"
|
||||
open-floating true
|
||||
}
|
||||
|
||||
window-rule {
|
||||
match title=r#"Code - OSS$"#
|
||||
match title=r#"Visual Studio Code$"#
|
||||
match app-id=r#"^code"#
|
||||
|
||||
match app-id=r#"firefox$"#
|
||||
open-maximized true
|
||||
}
|
||||
|
||||
window-rule {
|
||||
match app-id=r#"firefox$"# title="^Picture-in-Picture$"
|
||||
open-floating true
|
||||
default-floating-position x=8 y=8 relative-to="bottom-right"
|
||||
open-focused false
|
||||
open-on-output "HDMI-A-1"
|
||||
}
|
||||
|
||||
spawn-at-startup "waybar"
|
||||
// spawn-at-startup "waybar"
|
||||
// spawn-sh-at-startup "wl-paste --watch cliphist store"
|
||||
spawn-at-startup "swww-daemon"
|
||||
spawn-at-startup "swww-daemon" "--namespace" "blur"
|
||||
spawn-at-startup "xwayland-satellite"
|
||||
spawn-at-startup "/usr/lib/pam_kwallet_init"
|
||||
|
||||
environment {
|
||||
DISPLAY ":0"
|
||||
//QT_QPA_PLATFORMTHEME "qt6ct"
|
||||
QT_QPA_PLATFORMTHEME "qt6ct"
|
||||
ELECTRON_OZONE_PLATFORM_HINT "auto"
|
||||
}
|
||||
|
||||
binds {
|
||||
Mod+F1 { show-hotkey-overlay; }
|
||||
|
||||
Mod+Return hotkey-overlay-title="Terminal (foot)" { spawn "foot"; }
|
||||
Mod+F9 hotkey-overlay-title="Browser (firefox)" { spawn "firefox"; }
|
||||
Mod+E hotkey-overlay-title="Explorer (yazi)" { spawn "foot" "yazi"; }
|
||||
//Shift+Mod+Return hotkey-overlay-title="Steam" { spawn "steam"; }
|
||||
|
||||
Mod+F12 hotkey-overlay-title="Open Projects ... (VSCode)" { spawn "~/.local/bin/fuzzel-vsc-entries.ps1"; }
|
||||
Mod+Space hotkey-overlay-title="Run a command ... (fuzzel)" { spawn "~/.local/bin/fuzzel-win+r.ps1"; }
|
||||
|
||||
// Applications such as remote-desktop clients and software KVM switches may
|
||||
// request that niri stops processing the keyboard shortcuts defined here
|
||||
// so they may, for example, forward the key presses as-is to a remote machine.
|
||||
// It's a good idea to bind an escape hatch to toggle the inhibitor,
|
||||
// so a buggy application can't hold your session hostage.
|
||||
//
|
||||
// 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.
|
||||
Mod+Alt+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
|
||||
Mod+Shift+Escape hotkey-overlay-title="Exit niri" { quit; }
|
||||
Super+Escape hotkey-overlay-title="Lock the Screen (gtklock)" { spawn "gtklock" "-d"; }
|
||||
XF86PowerOff hotkey-overlay-title="Lock screen and Hibernate ..." { spawn-sh "gtklock -d && sleep 3 && systemctl hibernate"; }
|
||||
|
||||
XF86AudioRaiseVolume hotkey-overlay-title=null allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.01+"; }
|
||||
XF86AudioLowerVolume hotkey-overlay-title=null allow-when-locked=true { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.01-"; }
|
||||
XF86AudioMute hotkey-overlay-title=null allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; }
|
||||
XF86AudioMicMute hotkey-overlay-title=null allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"; }
|
||||
|
||||
//Mod+Shift+M allow-when-locked=true { spawn "swayosd-client" "--input-volume" "mute-toggle"; }
|
||||
|
||||
XF86AudioPlay allow-when-locked=true { spawn "playerctl" "play-pause"; }
|
||||
XF86AudioPause allow-when-locked=true { spawn "playerctl" "play-pause"; }
|
||||
XF86AudioNext allow-when-locked=true { spawn "playerctl" "next"; }
|
||||
XF86AudioPrev allow-when-locked=true { spawn "playerctl" "previous"; }
|
||||
XF86AudioStop allow-when-locked=true { spawn "playerctl" "stop"; }
|
||||
|
||||
XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "+5%"; }
|
||||
XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "5%-"; }
|
||||
|
||||
Alt+Tab hotkey-overlay-title=null repeat=false { toggle-overview; }
|
||||
Alt+F4 { close-window; }
|
||||
|
||||
Mod+Left { focus-column-left; }
|
||||
Mod+Down { focus-window-down; }
|
||||
Mod+Up { focus-window-up; }
|
||||
Mod+Right { focus-column-right; }
|
||||
//Mod+H { focus-column-left; }
|
||||
//Mod+J { focus-window-down; }
|
||||
//Mod+K { focus-window-up; }
|
||||
//Mod+L { focus-column-right; }
|
||||
|
||||
Mod+Shift+Left { move-column-left; }
|
||||
Mod+Shift+Down { move-window-down; }
|
||||
Mod+Shift+Up { move-window-up; }
|
||||
Mod+Shift+Right { move-column-right; }
|
||||
//Mod+Shift+H { move-column-left; }
|
||||
//Mod+Shift+J { move-window-down; }
|
||||
//Mod+Shift+K { move-window-up; }
|
||||
//Mod+Shift+L { move-column-right; }
|
||||
|
||||
// Alternative commands that move across workspaces when reaching
|
||||
// the first or last window in a column.
|
||||
// Mod+J { focus-window-or-workspace-down; }
|
||||
// Mod+K { focus-window-or-workspace-up; }
|
||||
// Mod+Ctrl+J { move-window-down-or-to-workspace-down; }
|
||||
// Mod+Ctrl+K { move-window-up-or-to-workspace-up; }
|
||||
|
||||
Mod+Home { focus-column-first; }
|
||||
Mod+End { focus-column-last; }
|
||||
Mod+Ctrl+Home { move-column-to-first; }
|
||||
Mod+Ctrl+End { move-column-to-last; }
|
||||
|
||||
Mod+Ctrl+Left { focus-monitor-left; }
|
||||
Mod+Ctrl+Down { focus-monitor-down; }
|
||||
Mod+Ctrl+Up { focus-monitor-up; }
|
||||
Mod+Ctrl+Right { focus-monitor-right; }
|
||||
//Mod+Ctrl+H { focus-monitor-left; }
|
||||
//Mod+Ctrl+J { focus-monitor-down; }
|
||||
//Mod+Ctrl+K { focus-monitor-up; }
|
||||
//Mod+Ctrl+L { focus-monitor-right; }
|
||||
|
||||
Mod+Shift+Ctrl+Left { move-column-to-monitor-left; }
|
||||
Mod+Shift+Ctrl+Down { move-column-to-monitor-down; }
|
||||
Mod+Shift+Ctrl+Up { move-column-to-monitor-up; }
|
||||
Mod+Shift+Ctrl+Right { move-column-to-monitor-right; }
|
||||
//Mod+Shift+Ctrl+H { move-column-to-monitor-left; }
|
||||
//Mod+Shift+Ctrl+J { move-column-to-monitor-down; }
|
||||
//Mod+Shift+Ctrl+K { move-column-to-monitor-up; }
|
||||
//Mod+Shift+Ctrl+L { move-column-to-monitor-right; }
|
||||
|
||||
// Alternatively, there are commands to move just a single window:
|
||||
// Mod+Shift+Ctrl+Left { move-window-to-monitor-left; }
|
||||
// ...
|
||||
// And you can also move a whole workspace to another monitor:
|
||||
// Mod+Shift+Ctrl+Left { move-workspace-to-monitor-left; }
|
||||
// ...
|
||||
|
||||
Mod+Page_Down { focus-workspace-down; }
|
||||
Mod+Page_Up { focus-workspace-up; }
|
||||
//Mod+U { focus-workspace-down; }
|
||||
//Mod+I { focus-workspace-up; }
|
||||
Mod+Shift+Page_Down { move-column-to-workspace-down; }
|
||||
Mod+Shift+Page_Up { move-column-to-workspace-up; }
|
||||
//Mod+Shift+U { move-column-to-workspace-down; }
|
||||
//Mod+Shift+I { move-column-to-workspace-up; }
|
||||
|
||||
// Alternatively, there are commands to move just a single window:
|
||||
// Mod+Ctrl+Page_Down { move-window-to-workspace-down; }
|
||||
// ...
|
||||
|
||||
Mod+Ctrl+Page_Down { move-workspace-down; }
|
||||
Mod+Ctrl+Page_Up { move-workspace-up; }
|
||||
//Mod+Ctrl+U { move-workspace-down; }
|
||||
//Mod+Ctrl+I { move-workspace-up; }
|
||||
|
||||
|
||||
Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
|
||||
Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
|
||||
Mod+Shift+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; }
|
||||
Mod+Shift+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; }
|
||||
|
||||
Mod+WheelScrollRight { focus-column-right; }
|
||||
Mod+WheelScrollLeft { focus-column-left; }
|
||||
Mod+Shift+WheelScrollRight { move-column-right; }
|
||||
Mod+Shift+WheelScrollLeft { move-column-left; }
|
||||
// Usually scrolling up and down with Shift in applications results in
|
||||
// horizontal scrolling; these binds replicate that.
|
||||
// Mod+Shift+WheelScrollDown { focus-column-right; }
|
||||
// Mod+Shift+WheelScrollUp { focus-column-left; }
|
||||
// Mod+Ctrl+Shift+WheelScrollDown { move-column-right; }
|
||||
// Mod+Ctrl+Shift+WheelScrollUp { move-column-left; }
|
||||
|
||||
// Similarly, you can bind touchpad scroll "ticks".
|
||||
// Touchpad scrolling is continuous, so for these binds it is split into
|
||||
// discrete intervals.
|
||||
// These binds are also affected by touchpad's natural-scroll, so these
|
||||
// example binds are "inverted", since we have natural-scroll enabled for
|
||||
// touchpads by default.
|
||||
// Mod+TouchpadScrollDown { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02+"; }
|
||||
// Mod+TouchpadScrollUp { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02-"; }
|
||||
|
||||
Mod+1 { focus-workspace 1; }
|
||||
Mod+2 { focus-workspace 2; }
|
||||
Mod+3 { focus-workspace 3; }
|
||||
Mod+4 { focus-workspace 4; }
|
||||
Mod+5 { focus-workspace 5; }
|
||||
Mod+6 { focus-workspace 6; }
|
||||
Mod+7 { focus-workspace 7; }
|
||||
Mod+8 { focus-workspace 8; }
|
||||
Mod+9 { focus-workspace 9; }
|
||||
Mod+Shift+1 { move-column-to-workspace focus=false 1 ; }
|
||||
Mod+Shift+2 { move-column-to-workspace focus=false 2 ; }
|
||||
Mod+Shift+3 { move-column-to-workspace focus=false 3 ; }
|
||||
Mod+Shift+4 { move-column-to-workspace focus=false 4 ; }
|
||||
Mod+Shift+5 { move-column-to-workspace focus=false 5 ; }
|
||||
Mod+Shift+6 { move-column-to-workspace focus=false 6 ; }
|
||||
Mod+Shift+7 { move-column-to-workspace focus=false 7 ; }
|
||||
Mod+Shift+8 { move-column-to-workspace focus=false 8 ; }
|
||||
Mod+Shift+9 { move-column-to-workspace focus=false 9 ; }
|
||||
|
||||
// Alternatively, there are commands to move just a single window:
|
||||
// Mod+Ctrl+1 { move-window-to-workspace 1; }
|
||||
|
||||
// Switches focus between the current and the previous workspace.
|
||||
// Mod+Tab { focus-workspace-previous; }
|
||||
|
||||
Mod+Comma { consume-window-into-column; }
|
||||
Mod+Period { expel-window-from-column; }
|
||||
|
||||
Mod+Shift+V { toggle-window-floating; }
|
||||
Mod+V { switch-focus-between-floating-and-tiling; }
|
||||
|
||||
Mod+BracketLeft { consume-or-expel-window-left; }
|
||||
Mod+BracketRight { consume-or-expel-window-right; }
|
||||
|
||||
Mod+R { switch-preset-column-width; }
|
||||
Mod+Shift+R { switch-preset-window-height; }
|
||||
Mod+Ctrl+R { reset-window-height; }
|
||||
Mod+F11 { maximize-column; }
|
||||
Mod+Shift+F11 { toggle-windowed-fullscreen; }
|
||||
Mod+Ctrl+F11 { fullscreen-window; }
|
||||
Mod+T hotkey-overlay-title="Expand column to available width" { expand-column-to-available-width; }
|
||||
Mod+W hotkey-overlay-title="Tabbed Column Mode" { toggle-column-tabbed-display; }
|
||||
|
||||
Mod+C { center-column; }
|
||||
Mod+Ctrl+C { center-visible-columns; }
|
||||
|
||||
// Finer width adjustments.
|
||||
// This command can also:
|
||||
// * set width in pixels: "1000"
|
||||
// * adjust width in pixels: "-5" or "+5"
|
||||
// * set width as a percentage of screen width: "25%"
|
||||
// * adjust width as a percentage of screen width: "-10%" or "+10%"
|
||||
// Pixel sizes use logical, or scaled, pixels. I.e. on an output with scale 2.0,
|
||||
// set-column-width "100" will make the column occupy 200 physical screen pixels.
|
||||
Mod+Minus { set-column-width "-5%"; }
|
||||
Mod+Equal { set-column-width "+5%"; }
|
||||
|
||||
// Finer height adjustments when in column with other windows.
|
||||
Mod+Shift+Minus { set-window-height "-5%"; }
|
||||
Mod+Shift+Equal { set-window-height "+5%"; }
|
||||
|
||||
// Actions to switch layouts.
|
||||
// Note: if you uncomment these, make sure you do NOT have
|
||||
// a matching layout switch hotkey configured in xkb options above.
|
||||
// Having both at once on the same hotkey will break the switching,
|
||||
// since it will switch twice upon pressing the hotkey (once by xkb, once by niri).
|
||||
// Mod+Space { switch-layout "next"; }
|
||||
// Mod+Shift+Space { switch-layout "prev"; }
|
||||
|
||||
Print hotkey-overlay-title=null { screenshot; }
|
||||
Ctrl+Print { screenshot-screen; }
|
||||
Alt+Print { screenshot-window; }
|
||||
|
||||
// Powers off the monitors. To turn them back on, do any input like
|
||||
// moving the mouse or pressing any other key.
|
||||
//Mod+Shift+P { power-off-monitors; }
|
||||
hotkey-overlay {
|
||||
skip-at-startup
|
||||
hide-not-bound
|
||||
}
|
||||
|
||||
gestures {
|
||||
hot-corners {
|
||||
off
|
||||
}
|
||||
}
|
||||
|
||||
prefer-no-csd
|
||||
|
||||
screenshot-path "~/.tmp/Screenshots/%Y-%m-%d %H-%M-%S.png"
|
||||
// screenshot-path null
|
||||
|
||||
221
.config/niri/config.keyboard.kdl
Normal file
221
.config/niri/config.keyboard.kdl
Normal file
@@ -0,0 +1,221 @@
|
||||
binds {
|
||||
Mod+F1 { show-hotkey-overlay; }
|
||||
|
||||
Mod+Return hotkey-overlay-title="Terminal (foot)" { spawn "foot"; }
|
||||
Mod+F9 hotkey-overlay-title="Browser (chrome)" { spawn "google-chrome-stable"; }
|
||||
Mod+E hotkey-overlay-title="Explorer (yazi)" { spawn "foot" "yazi"; }
|
||||
//Shift+Mod+Return hotkey-overlay-title="Steam" { spawn "steam"; }
|
||||
|
||||
Mod+F12 hotkey-overlay-title="Open Projects ... (VSCode)" { spawn ".fuzzel-vscode"; }
|
||||
Mod+Space hotkey-overlay-title="Run a command ... (fuzzel)" { spawn ".fuzzel-startb"; }
|
||||
|
||||
// Applications such as remote-desktop clients and software KVM switches may
|
||||
// request that niri stops processing the keyboard shortcuts defined here
|
||||
// so they may, for example, forward the key presses as-is to a remote machine.
|
||||
// It's a good idea to bind an escape hatch to toggle the inhibitor,
|
||||
// so a buggy application can't hold your session hostage.
|
||||
//
|
||||
// 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.
|
||||
Mod+Alt+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
|
||||
XF86PowerOff hotkey-overlay-title="Exit niri" { quit; }
|
||||
Super+Escape hotkey-overlay-title="Lock the Screen (gtklock)" { spawn "gtklock" "-d"; }
|
||||
Mod+Delete hotkey-overlay-title="Lock screen and Hibernate ..." allow-when-locked=true {
|
||||
spawn-sh "(pgrep gtklock || gtklock -d) && sleep 1.5 && systemctl hibernate";
|
||||
}
|
||||
|
||||
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-"; }
|
||||
XF86AudioMute hotkey-overlay-title=null allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"; }
|
||||
XF86AudioMicMute hotkey-overlay-title=null allow-when-locked=true { spawn "wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"; }
|
||||
|
||||
//Mod+Shift+M allow-when-locked=true { spawn "swayosd-client" "--input-volume" "mute-toggle"; }
|
||||
|
||||
XF86AudioPlay allow-when-locked=true { spawn "playerctl" "play-pause"; }
|
||||
XF86AudioPause allow-when-locked=true { spawn "playerctl" "play-pause"; }
|
||||
XF86AudioNext allow-when-locked=true { spawn "playerctl" "next"; }
|
||||
XF86AudioPrev allow-when-locked=true { spawn "playerctl" "previous"; }
|
||||
XF86AudioStop allow-when-locked=true { spawn "playerctl" "stop"; }
|
||||
|
||||
XF86MonBrightnessUp allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "+5%"; }
|
||||
XF86MonBrightnessDown allow-when-locked=true { spawn "brightnessctl" "--class=backlight" "set" "5%-"; }
|
||||
|
||||
Alt+Tab hotkey-overlay-title=null repeat=false { toggle-overview; }
|
||||
Alt+F4 { close-window; }
|
||||
|
||||
Mod+Left { focus-column-left; }
|
||||
Mod+Down { focus-window-down; }
|
||||
Mod+Up { focus-window-up; }
|
||||
Mod+Right { focus-column-right; }
|
||||
//Mod+H { focus-column-left; }
|
||||
//Mod+J { focus-window-down; }
|
||||
//Mod+K { focus-window-up; }
|
||||
//Mod+L { focus-column-right; }
|
||||
|
||||
Mod+Shift+Left { move-column-left; }
|
||||
Mod+Shift+Down { move-window-down; }
|
||||
Mod+Shift+Up { move-window-up; }
|
||||
Mod+Shift+Right { move-column-right; }
|
||||
//Mod+Shift+H { move-column-left; }
|
||||
//Mod+Shift+J { move-window-down; }
|
||||
//Mod+Shift+K { move-window-up; }
|
||||
//Mod+Shift+L { move-column-right; }
|
||||
|
||||
// Alternative commands that move across workspaces when reaching
|
||||
// the first or last window in a column.
|
||||
// Mod+J { focus-window-or-workspace-down; }
|
||||
// Mod+K { focus-window-or-workspace-up; }
|
||||
// Mod+Ctrl+J { move-window-down-or-to-workspace-down; }
|
||||
// Mod+Ctrl+K { move-window-up-or-to-workspace-up; }
|
||||
|
||||
Mod+Home { focus-column-first; }
|
||||
Mod+End { focus-column-last; }
|
||||
Mod+Ctrl+Home { move-column-to-first; }
|
||||
Mod+Ctrl+End { move-column-to-last; }
|
||||
|
||||
Mod+Ctrl+Left { focus-monitor-left; }
|
||||
Mod+Ctrl+Down { focus-monitor-down; }
|
||||
Mod+Ctrl+Up { focus-monitor-up; }
|
||||
Mod+Ctrl+Right { focus-monitor-right; }
|
||||
//Mod+Ctrl+H { focus-monitor-left; }
|
||||
//Mod+Ctrl+J { focus-monitor-down; }
|
||||
//Mod+Ctrl+K { focus-monitor-up; }
|
||||
//Mod+Ctrl+L { focus-monitor-right; }
|
||||
|
||||
Mod+Shift+Ctrl+Left { move-column-to-monitor-left; }
|
||||
Mod+Shift+Ctrl+Down { move-column-to-monitor-down; }
|
||||
Mod+Shift+Ctrl+Up { move-column-to-monitor-up; }
|
||||
Mod+Shift+Ctrl+Right { move-column-to-monitor-right; }
|
||||
//Mod+Shift+Ctrl+H { move-column-to-monitor-left; }
|
||||
//Mod+Shift+Ctrl+J { move-column-to-monitor-down; }
|
||||
//Mod+Shift+Ctrl+K { move-column-to-monitor-up; }
|
||||
//Mod+Shift+Ctrl+L { move-column-to-monitor-right; }
|
||||
|
||||
// Alternatively, there are commands to move just a single window:
|
||||
// Mod+Shift+Ctrl+Left { move-window-to-monitor-left; }
|
||||
// ...
|
||||
// And you can also move a whole workspace to another monitor:
|
||||
// Mod+Shift+Ctrl+Left { move-workspace-to-monitor-left; }
|
||||
// ...
|
||||
|
||||
Mod+Page_Down { focus-workspace-down; }
|
||||
Mod+Page_Up { focus-workspace-up; }
|
||||
//Mod+U { focus-workspace-down; }
|
||||
//Mod+I { focus-workspace-up; }
|
||||
Mod+Shift+Page_Down { move-column-to-workspace-down; }
|
||||
Mod+Shift+Page_Up { move-column-to-workspace-up; }
|
||||
//Mod+Shift+U { move-column-to-workspace-down; }
|
||||
//Mod+Shift+I { move-column-to-workspace-up; }
|
||||
|
||||
// Alternatively, there are commands to move just a single window:
|
||||
// Mod+Ctrl+Page_Down { move-window-to-workspace-down; }
|
||||
// ...
|
||||
|
||||
Mod+Ctrl+Page_Down { move-workspace-down; }
|
||||
Mod+Ctrl+Page_Up { move-workspace-up; }
|
||||
//Mod+Ctrl+U { move-workspace-down; }
|
||||
//Mod+Ctrl+I { move-workspace-up; }
|
||||
|
||||
|
||||
Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
|
||||
Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
|
||||
Mod+Shift+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; }
|
||||
Mod+Shift+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; }
|
||||
|
||||
Mod+WheelScrollRight { focus-column-right; }
|
||||
Mod+WheelScrollLeft { focus-column-left; }
|
||||
Mod+Shift+WheelScrollRight { move-column-right; }
|
||||
Mod+Shift+WheelScrollLeft { move-column-left; }
|
||||
// Usually scrolling up and down with Shift in applications results in
|
||||
// horizontal scrolling; these binds replicate that.
|
||||
// Mod+Shift+WheelScrollDown { focus-column-right; }
|
||||
// Mod+Shift+WheelScrollUp { focus-column-left; }
|
||||
// Mod+Ctrl+Shift+WheelScrollDown { move-column-right; }
|
||||
// Mod+Ctrl+Shift+WheelScrollUp { move-column-left; }
|
||||
|
||||
// Similarly, you can bind touchpad scroll "ticks".
|
||||
// Touchpad scrolling is continuous, so for these binds it is split into
|
||||
// discrete intervals.
|
||||
// These binds are also affected by touchpad's natural-scroll, so these
|
||||
// example binds are "inverted", since we have natural-scroll enabled for
|
||||
// touchpads by default.
|
||||
// Mod+TouchpadScrollDown { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02+"; }
|
||||
// Mod+TouchpadScrollUp { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02-"; }
|
||||
|
||||
Mod+1 { focus-workspace 1; }
|
||||
Mod+2 { focus-workspace 2; }
|
||||
Mod+3 { focus-workspace 3; }
|
||||
Mod+4 { focus-workspace 4; }
|
||||
Mod+5 { focus-workspace 5; }
|
||||
Mod+6 { focus-workspace 6; }
|
||||
Mod+7 { focus-workspace 7; }
|
||||
Mod+8 { focus-workspace 8; }
|
||||
Mod+9 { focus-workspace 9; }
|
||||
Mod+Shift+1 { move-column-to-workspace focus=false 1 ; }
|
||||
Mod+Shift+2 { move-column-to-workspace focus=false 2 ; }
|
||||
Mod+Shift+3 { move-column-to-workspace focus=false 3 ; }
|
||||
Mod+Shift+4 { move-column-to-workspace focus=false 4 ; }
|
||||
Mod+Shift+5 { move-column-to-workspace focus=false 5 ; }
|
||||
Mod+Shift+6 { move-column-to-workspace focus=false 6 ; }
|
||||
Mod+Shift+7 { move-column-to-workspace focus=false 7 ; }
|
||||
Mod+Shift+8 { move-column-to-workspace focus=false 8 ; }
|
||||
Mod+Shift+9 { move-column-to-workspace focus=false 9 ; }
|
||||
|
||||
// Alternatively, there are commands to move just a single window:
|
||||
// Mod+Ctrl+1 { move-window-to-workspace 1; }
|
||||
|
||||
// Switches focus between the current and the previous workspace.
|
||||
// Mod+Tab { focus-workspace-previous; }
|
||||
|
||||
Mod+Comma { consume-window-into-column; }
|
||||
Mod+Period { expel-window-from-column; }
|
||||
|
||||
Mod+Shift+V { toggle-window-floating; }
|
||||
Mod+V { switch-focus-between-floating-and-tiling; }
|
||||
|
||||
Mod+BracketLeft { consume-or-expel-window-left; }
|
||||
Mod+BracketRight { consume-or-expel-window-right; }
|
||||
|
||||
Mod+R { switch-preset-column-width; }
|
||||
Mod+Shift+R { switch-preset-window-height; }
|
||||
Mod+Ctrl+R { reset-window-height; }
|
||||
Mod+F11 { maximize-column; }
|
||||
Mod+Shift+F11 { toggle-windowed-fullscreen; }
|
||||
Mod+Ctrl+F11 { fullscreen-window; }
|
||||
Mod+T hotkey-overlay-title="Expand column to available width" { expand-column-to-available-width; }
|
||||
Mod+W hotkey-overlay-title="Tabbed Column Mode" { toggle-column-tabbed-display; }
|
||||
|
||||
Mod+C { center-column; }
|
||||
Mod+Ctrl+C { center-visible-columns; }
|
||||
|
||||
// Finer width adjustments.
|
||||
// This command can also:
|
||||
// * set width in pixels: "1000"
|
||||
// * adjust width in pixels: "-5" or "+5"
|
||||
// * set width as a percentage of screen width: "25%"
|
||||
// * adjust width as a percentage of screen width: "-10%" or "+10%"
|
||||
// Pixel sizes use logical, or scaled, pixels. I.e. on an output with scale 2.0,
|
||||
// set-column-width "100" will make the column occupy 200 physical screen pixels.
|
||||
Mod+Minus { set-column-width "-5%"; }
|
||||
Mod+Equal { set-column-width "+5%"; }
|
||||
|
||||
// Finer height adjustments when in column with other windows.
|
||||
Mod+Shift+Minus { set-window-height "-5%"; }
|
||||
Mod+Shift+Equal { set-window-height "+5%"; }
|
||||
|
||||
// Actions to switch layouts.
|
||||
// Note: if you uncomment these, make sure you do NOT have
|
||||
// a matching layout switch hotkey configured in xkb options above.
|
||||
// Having both at once on the same hotkey will break the switching,
|
||||
// since it will switch twice upon pressing the hotkey (once by xkb, once by niri).
|
||||
// Mod+Space { switch-layout "next"; }
|
||||
// Mod+Shift+Space { switch-layout "prev"; }
|
||||
|
||||
Print hotkey-overlay-title=null { screenshot-screen; }
|
||||
Mod+Shift+S { screenshot; }
|
||||
Alt+Print { screenshot-window; }
|
||||
|
||||
// Powers off the monitors. To turn them back on, do any input like
|
||||
// moving the mouse or pressing any other key.
|
||||
//Mod+Shift+P { power-off-monitors; }
|
||||
}
|
||||
64
.config/niri/config.window.kdl
Normal file
64
.config/niri/config.window.kdl
Normal file
@@ -0,0 +1,64 @@
|
||||
window-rule {
|
||||
geometry-corner-radius 6
|
||||
clip-to-geometry true
|
||||
}
|
||||
|
||||
window-rule {
|
||||
match app-id="QQ"
|
||||
match app-id="Electron" title="MetaCubeXD$"
|
||||
match app-id="wechat"
|
||||
match app-id="org.telegram.desktop"
|
||||
match app-id="nwjs" // mainly for rpgmaker games.
|
||||
// open-on-output "eDP-1"
|
||||
block-out-from "screencast"
|
||||
}
|
||||
|
||||
window-rule {
|
||||
match app-id="com.obsproject.Studio"
|
||||
match app-id="Electron" title="Test" // frg2089.BiliLive.Observer
|
||||
match app-id="Electron" title="Blivechat-Openlive" // blivechat
|
||||
default-column-width { proportion 0.42; }
|
||||
// default-column-display "tabbed"
|
||||
open-on-output "eDP-1"
|
||||
}
|
||||
|
||||
window-rule {
|
||||
match title="^(图片查看器|.*记录)$" app-id="QQ"
|
||||
match app-id="pavucontrol-qt"
|
||||
|
||||
default-column-width { proportion 0.6; }
|
||||
default-window-height { proportion 0.85; }
|
||||
open-floating true
|
||||
}
|
||||
|
||||
window-rule {
|
||||
match app-id="nwjs"
|
||||
|
||||
default-column-width { proportion 0.85; }
|
||||
default-window-height { proportion 0.9; }
|
||||
open-floating true
|
||||
}
|
||||
|
||||
window-rule {
|
||||
match app-id=r#"^org\.keepassxc\.KeePassXC$"#
|
||||
match app-id=r#"^org\.gnome\.World\.Secrets$"#
|
||||
match app-id=r#"^org\.kde\.ksecretd$"#
|
||||
open-floating true
|
||||
}
|
||||
|
||||
window-rule {
|
||||
// match title=r#"Code - OSS$"#
|
||||
match title=r#"Visual Studio Code$"# app-id=r#"^code"#
|
||||
match app-id="krita"
|
||||
|
||||
open-maximized true
|
||||
}
|
||||
|
||||
window-rule {
|
||||
// match app-id=r#"firefox$"# title="^Picture-in-Picture$"
|
||||
match app-id="steam" title="Friends List"
|
||||
open-floating true
|
||||
default-floating-position x=8 y=8 relative-to="bottom-right"
|
||||
open-focused false
|
||||
open-on-output "eDP-1"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
/home/agxcoy/.config/systemd/user/mpris-proxy.service
|
||||
@@ -1 +0,0 @@
|
||||
/home/agxcoy/.config/systemd/user/playerctld.service
|
||||
@@ -1,10 +0,0 @@
|
||||
[Unit]
|
||||
Description=Forward bluetooth media controls to MPRIS
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/mpris-proxy
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
||||
12
.config/systemd/user/on-hourly@.timer
Normal file
12
.config/systemd/user/on-hourly@.timer
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Run %i hourly
|
||||
|
||||
[Timer]
|
||||
OnCalendar=hourly
|
||||
RandomizedDelaySec=1m
|
||||
AccuracySec=1s
|
||||
Persistent=true
|
||||
Unit=%i.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
12
.config/systemd/user/on-monthly@.timer
Normal file
12
.config/systemd/user/on-monthly@.timer
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Run %i monthly
|
||||
|
||||
[Timer]
|
||||
OnCalendar=monthly
|
||||
RandomizedDelaySec=5m
|
||||
AccuracySec=5s
|
||||
Persistent=true
|
||||
Unit=%i.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
12
.config/systemd/user/on-weekly@.timer
Normal file
12
.config/systemd/user/on-weekly@.timer
Normal file
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Run %i weekly
|
||||
|
||||
[Timer]
|
||||
OnCalendar=weekly
|
||||
RandomizedDelaySec=2m
|
||||
AccuracySec=2s
|
||||
Persistent=true
|
||||
Unit=%i.service
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -1,10 +0,0 @@
|
||||
[Unit]
|
||||
Description=Keep track of media player activity
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/playerctld daemon
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
|
||||
@@ -1,8 +1,21 @@
|
||||
{
|
||||
"layer": "top",
|
||||
"modules-left": ["niri/workspaces", "niri/window"],
|
||||
"modules-center": ["clock"],
|
||||
"modules-right": ["mpris", "tray", "battery", "cpu", "memory", "temperature", "pulseaudio"],
|
||||
"modules-left": [
|
||||
"niri/workspaces",
|
||||
"niri/window"
|
||||
],
|
||||
"modules-center": [
|
||||
"clock"
|
||||
],
|
||||
"modules-right": [
|
||||
"mpris",
|
||||
"tray",
|
||||
"battery",
|
||||
"cpu",
|
||||
"memory",
|
||||
"temperature",
|
||||
"pulseaudio"
|
||||
],
|
||||
"sway/scratchpad": {
|
||||
"format": " {count}"
|
||||
},
|
||||
@@ -22,14 +35,16 @@
|
||||
"icon-size": 14,
|
||||
"rewrite": {
|
||||
"(.*) — Mozilla Firefox": "$1",
|
||||
"(.*) - Google Chrome": "$1",
|
||||
"(.*) - Visual Studio Code": "$1",
|
||||
"(.*) - VLC media player": "$1",
|
||||
"Yazi: (.*)": "$1"
|
||||
}
|
||||
},
|
||||
"mpris": {
|
||||
"format": "{status_icon} {artist} - {title}",
|
||||
"format": "{status_icon} {title}",
|
||||
"format-stopped": "",
|
||||
"max-length": 40,
|
||||
"status-icons": {
|
||||
"paused": "",
|
||||
"playing": ""
|
||||
@@ -45,25 +60,41 @@
|
||||
"spacing": 12
|
||||
},
|
||||
"temperature": {
|
||||
"thermal-zone": 1,
|
||||
// "hwmon-path": "/sys/class/hwmon/hwmon2/temp1_input",
|
||||
"critical-threshold": 80,
|
||||
// "thermal-zone": 1,
|
||||
"hwmon-path-abs": "/sys/devices/platform/coretemp.0/hwmon",
|
||||
"input-filename": "temp1_input",
|
||||
"critical-threshold": 90,
|
||||
// "format-critical": "{temperatureC}°C {icon}",
|
||||
"format": "{icon} {temperatureC}°C",
|
||||
"format-icons": ["", "", ""]
|
||||
"format-icons": [
|
||||
"",
|
||||
"",
|
||||
""
|
||||
]
|
||||
},
|
||||
"memory": {
|
||||
"format": " {percentage}%",
|
||||
"interval": 5
|
||||
"format": " {percentage}%",
|
||||
"interval": 5
|
||||
},
|
||||
"cpu": {
|
||||
"format": " {usage}%",
|
||||
"interval": 2
|
||||
"format": " {usage}%",
|
||||
"interval": 2
|
||||
},
|
||||
"battery": {
|
||||
"format": "{icon} {capacity}%",
|
||||
"format-charging": "{icon} {capacity}% ",
|
||||
"format-icons": ["", "", "", "", "", "", "", "", "", ""],
|
||||
"format-icons": [
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
],
|
||||
"interval": 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ window#waybar {
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: "MonaspiceNe Nerd Font";
|
||||
font-family: "Symbols Nerd Font", monospace;
|
||||
font-size: 10pt;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
[mgr]
|
||||
show_hidden = true
|
||||
show_symlink = true
|
||||
mouse_events = ["click"]
|
||||
|
||||
[opener]
|
||||
play = [
|
||||
{ run = 'vlc "$@"', orphan = true, for = "unix" },
|
||||
{ run = 'mpv --force-window %*', orphan = true, for = "windows" },
|
||||
{ run = '''mediainfo "$1"; echo "Press enter to exit"; read _''', block = true, desc = "Show media info", for = "unix" },
|
||||
]
|
||||
|
||||
16
.zprofile
16
.zprofile
@@ -1,11 +1,13 @@
|
||||
# init at each startup
|
||||
mkdir -p /tmp/$USER
|
||||
#ln -sf /tmp/$UID $HOME/.tmp
|
||||
[[ ! -L $HOME/.tmp ]] && rm -f $HOME/.tmp && ln -s /tmp/$USER $HOME/.tmp
|
||||
# to clear history of shells easily operating filesystem.
|
||||
# also powershell/PSReadLine -> /tmp/$USER/terminal
|
||||
mkdir -p /tmp/$USER/terminal
|
||||
|
||||
# avoid dumplicate env appending.
|
||||
[[ -f /run/user/$UID/.zshlogon ]] && return
|
||||
touch /run/user/$UID/.zshlogon
|
||||
# [[ -f /run/user/$UID/.zshlogon ]] && return
|
||||
# touch /run/user/$UID/.zshlogon
|
||||
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
PATH="$HOME/.local/bin:$PATH"
|
||||
PATH="$HOME/.niri-dotfiles/bin:$PATH"
|
||||
|
||||
export -U PATH
|
||||
export EDITOR=nano
|
||||
|
||||
12
.zshrc
12
.zshrc
@@ -19,6 +19,9 @@ fi
|
||||
# History
|
||||
#
|
||||
|
||||
# also export this in bashrc.
|
||||
HISTFILE=/tmp/$USER/terminal/zsh_history
|
||||
|
||||
# Remove older command from the history if a duplicate is to be added.
|
||||
setopt HIST_IGNORE_ALL_DUPS
|
||||
|
||||
@@ -140,4 +143,13 @@ unset key
|
||||
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
|
||||
|
||||
# USER MANUAL CONFIGS
|
||||
|
||||
# https://unix.stackexchange.com/questions/608842/zshrc-export-gpg-tty-tty-says-not-a-tty
|
||||
export GPG_TTY=$TTY
|
||||
|
||||
alias uvenv='source .venv/bin/activate'
|
||||
alias noproxy='env -u http_proxy -u https_proxy'
|
||||
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
||||
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
||||
|
||||
191
bin/.battery-warn
Executable file
191
bin/.battery-warn
Executable file
@@ -0,0 +1,191 @@
|
||||
#!/usr/bin/env python
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
# Copyright © 2021 mpan; <https://mpan.pl/>; CC0 1.0 (THIS SCRIPT!)
|
||||
# Context: <https://bbs.archlinux.org/viewtopic.php?id=269453>
|
||||
# Reference: https://github.com/wogscpar/upower-python
|
||||
|
||||
# -*- encoding: utf-8 -*-
|
||||
# @File : .battery-warn
|
||||
# @Time : 2025/12/29 00:32:53
|
||||
# @Author : SilverAg.L
|
||||
|
||||
# bash pipeline was still too complicated.
|
||||
# Dependencies (pacman): python-dbus, libnotify, pipewire-audio
|
||||
|
||||
import dbus
|
||||
|
||||
from os import getenv
|
||||
from subprocess import run as start_process
|
||||
|
||||
# region config
|
||||
AUD_OUT_EMB = ( # my laptop embedded speaker
|
||||
"alsa_output.pci-0000_00_1f"
|
||||
".3-platform-skl_hda_dsp_generic.HiFi__Speaker__sink"
|
||||
)
|
||||
# better searched by editor like VSCode.
|
||||
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
|
||||
])
|
||||
3
bin/.fuzzel-startb
Executable file
3
bin/.fuzzel-startb
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
option=$(fuzzel --dmenu --prompt-only="Command to execute: ")
|
||||
[ -z "$option" ] || startb -- $option
|
||||
18
bin/.fuzzel-vscode
Executable file
18
bin/.fuzzel-vscode
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
desktop="$HOME/Desktop"
|
||||
|
||||
options=""
|
||||
for item in $(ls $desktop); do
|
||||
if [[ "$item" == *.desktop && -f "$desktop/$item" ]]; then
|
||||
continue
|
||||
fi
|
||||
options+=$item
|
||||
if [[ -d "$desktop/$item" ]]; then
|
||||
options+='/'
|
||||
fi
|
||||
options+="\n"
|
||||
done
|
||||
|
||||
fsarg=$(echo -en "$options" | fuzzel --dmenu --prompt="Open with VSCode: Desktop/")
|
||||
[ -z "$fsarg" ] || startb -- code "$desktop/$fsarg"
|
||||
28
bin/chbg
28
bin/chbg
@@ -1,12 +1,32 @@
|
||||
#!/bin/bash
|
||||
# to change wallpapers both niri workspace and niri tab view
|
||||
[ -z "$1" ] && { echo "Usage: $0 <image-file>"; exit 1; }
|
||||
[ -z "$1" ] && {
|
||||
echo "Usage: ${0##*/} <image-file>"
|
||||
exit 1
|
||||
}
|
||||
fsize=$(magick identify -format "%w %h" -- "$1" 2>/dev/null) || {
|
||||
echo "ERROR: unable to identify. is it an EXISTING ACCESSIBLE IMAGE file?"
|
||||
exit 1
|
||||
}
|
||||
|
||||
WP_DIR="$HOME/.local/share"
|
||||
WP_DIR="${XDG_DATA_HOME:-$HOME/.local/share}"
|
||||
finput=$1
|
||||
|
||||
echo -n "making blurred version... "
|
||||
read -r fw fh <<< "$fsize"
|
||||
(( fw > 3840 && fh > 2160 )) && {
|
||||
finput=$(mktemp "${TMPDIR:-/tmp}/chbg.XXXXXXXX.webp")
|
||||
trap 'rm -f "$finput"' EXIT
|
||||
echo "WARNING: image too large, resizing ..."
|
||||
# echo "DEBUG: resized image at $finput"
|
||||
magick "$1" -resize "3840x2160^" \
|
||||
-quality 90 \
|
||||
-define webp:method=6 \
|
||||
-define webp:alpha-quality=100 "$finput"
|
||||
}
|
||||
|
||||
echo -n "making blurred version of ${1##*/} ... "
|
||||
mkdir -p $WP_DIR
|
||||
cp $1 $WP_DIR/.wallpaper
|
||||
cp $finput $WP_DIR/.wallpaper
|
||||
magick $WP_DIR/.wallpaper -filter Gaussian -blur 0x30 $WP_DIR/.wallpaper_blur
|
||||
echo "Done."
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#!/usr/bin/pwsh
|
||||
|
||||
$desktop="$env:HOME/Desktop"
|
||||
|
||||
$fsarg=(Get-ChildItem $desktop -FollowSymlink | ForEach-Object {
|
||||
if ($_ -is [System.IO.DirectoryInfo]) { return "$($_.Name)/" }
|
||||
else { return $_.Name }
|
||||
} | fuzzel --dmenu --prompt="Open with VSCode (~/Desktop): ")
|
||||
|
||||
$fsarg -and (Start-Process code -ArgumentList @("$desktop/$fsarg"))
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/usr/bin/pwsh
|
||||
|
||||
$option=(fuzzel --dmenu --prompt-only="Command to execute: ")
|
||||
|
||||
$option -and (
|
||||
# garbage `start-process`.
|
||||
systemd-run --user --scope --slice=AgExecBar.slice --unit="$(($option -split " ")[0])-$PID".scope /bin/sh -c "$option"
|
||||
)
|
||||
295
bin/startb
Executable file
295
bin/startb
Executable file
@@ -0,0 +1,295 @@
|
||||
#!/bin/bash
|
||||
# like `start /b` in Windows CMD.
|
||||
|
||||
# goddamn nvm-sh !!!
|
||||
# have to update PATH before launch
|
||||
PATH=$(zsh -c -i 'echo $PATH')
|
||||
export PATH
|
||||
|
||||
# https://vescrity.github.io/post/systemd-desktop-suspend/
|
||||
#systemd-run --user --scope --slice=YukiLauncher.slice --unit="$1-$$".scope /bin/sh -c '"$@"' _ "$@"
|
||||
|
||||
# Generated by GitHub Copilot.
|
||||
# start-bg-journal.sh - start a command as a detached daemon and send stdout/stderr to systemd-journald
|
||||
#
|
||||
# Features:
|
||||
# - Sends stdout+stderr to journald using systemd-cat when available.
|
||||
# - Falls back to writing into a logfile if systemd-cat isn't present or if --log is passed.
|
||||
# - Uses setsid to detach, closes inherited file descriptors (best-effort),
|
||||
# redirects stdin to /dev/null, and execs the target command.
|
||||
# - Supports PID file, umask, and a syslog identifier (tag) and priority for journald.
|
||||
# - Uses positional args ($@) for the command; uses $$ in auto-generated names and prints the child PID ($!).
|
||||
#
|
||||
# Usage:
|
||||
# start-bg-journal.sh [ -t TAG ] [ -r PRIORITY ] [ -l LOGFILE | -d LOGDIR ] [ -p PIDFILE ] [ -u UMASK ] -- command [args...]
|
||||
#
|
||||
# Examples:
|
||||
# ./start-bg-journal.sh -t myapp -- /usr/bin/myapp --config /etc/myapp.conf
|
||||
# ./start-bg-journal.sh -l ./my.log -- /usr/bin/myapp arg1 arg2
|
||||
# ./start-bg-journal.sh -p /run/myapp.pid -t myapp -r info -- /usr/bin/myapp
|
||||
set -euo pipefail
|
||||
|
||||
progname=$(basename "$0")
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $progname [ -t TAG ] [ -r PRIORITY ] [ -l LOGFILE | -d LOGDIR ] [ -p PIDFILE ] [ -u UMASK ] -- command [args...]
|
||||
|
||||
Start command [args...] as a background daemon, sending stdout+stderr to systemd-journald (via systemd-cat)
|
||||
when available. If systemd-cat is not available or if -l/--log is provided, logs are written to a logfile.
|
||||
|
||||
Options:
|
||||
-t, --tag TAG Tag / SYSLOG_IDENTIFIER used by systemd-cat (default: basename(command))
|
||||
-r, --priority PRIO Journal priority (emerg, alert, crit, err, warning, notice, info, debug)
|
||||
-l, --log LOGFILE Write stdout+stderr to LOGFILE instead of journald
|
||||
-d, --dir LOGDIR Directory for autogenerated log files (default: /tmp/$USER/runner)
|
||||
-p, --pidfile PATH Write daemon PID to PATH
|
||||
-u, --umask UMASK Set umask for the daemon (default: 0022)
|
||||
-h, --help Show this help and exit
|
||||
|
||||
When no -l is provided and journald is available, output goes to journald.
|
||||
When -l is not provided and journald is not available, a logfile is auto-generated:
|
||||
<LOGDIR>/<command>.<YYYYMMDD-HHMMSS>.pid<$$>.log
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Defaults
|
||||
logdir="/tmp/$USER/runner"
|
||||
logfile=""
|
||||
pidfile=""
|
||||
umask_val="0022"
|
||||
tag=""
|
||||
priority=""
|
||||
|
||||
# Parse options up to --
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-t|--tag)
|
||||
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||
tag="$2"; shift 2 ;;
|
||||
-r|--priority)
|
||||
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||
priority="$2"; shift 2 ;;
|
||||
-l|--log)
|
||||
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||
logfile="$2"; shift 2 ;;
|
||||
-d|--dir)
|
||||
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||
logdir="$2"; shift 2 ;;
|
||||
-p|--pidfile)
|
||||
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||
pidfile="$2"; shift 2 ;;
|
||||
-u|--umask)
|
||||
if [[ $# -lt 2 ]]; then echo "Missing argument for $1"; usage; fi
|
||||
umask_val="$2"; shift 2 ;;
|
||||
-h|--help)
|
||||
usage ;;
|
||||
--)
|
||||
shift; break ;;
|
||||
-*)
|
||||
echo "Unknown option: $1"; usage ;;
|
||||
*)
|
||||
break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
echo "Error: no command specified."
|
||||
usage
|
||||
fi
|
||||
|
||||
# Build command array from remaining args.
|
||||
cmd=( "$@" )
|
||||
cmd_basename=$(basename "${cmd[0]}")
|
||||
timestamp=$(date +%Y%m%d-%H%M%S)
|
||||
|
||||
# If tag not set, default to command basename
|
||||
if [[ -z "$tag" ]]; then
|
||||
tag="${cmd_basename}"
|
||||
fi
|
||||
|
||||
# Detect systemd-cat
|
||||
systemd_cat_path=""
|
||||
if command -v systemd-cat >/dev/null 2>&1; then
|
||||
systemd_cat_path=$(command -v systemd-cat)
|
||||
fi
|
||||
|
||||
# If user provided logfile explicitly, force file mode
|
||||
use_journal=false
|
||||
if [[ -n "${logfile}" ]]; then
|
||||
use_journal=false
|
||||
else
|
||||
if [[ -n "${systemd_cat_path}" ]]; then
|
||||
use_journal=true
|
||||
else
|
||||
use_journal=false
|
||||
fi
|
||||
fi
|
||||
|
||||
# Prepare logfile if needed
|
||||
mkdir -p -- "${logdir}"
|
||||
if ! $use_journal; then
|
||||
if [[ -z "${logfile}" ]]; then
|
||||
logfile="${logdir}/${cmd_basename}.${timestamp}.pid$$.log"
|
||||
fi
|
||||
# Ensure file exists and is writable
|
||||
: > "${logfile}" || { echo "Cannot write to log file: ${logfile}"; exit 1; }
|
||||
fi
|
||||
|
||||
# Helper: quote command for printing
|
||||
quoted_cmd() {
|
||||
local i out=""
|
||||
for i in "$@"; do
|
||||
printf -v i "%q" "$i"
|
||||
out="${out} ${i}"
|
||||
done
|
||||
printf '%s' "${out# }"
|
||||
}
|
||||
|
||||
# Build the inner script to run under setsid. We inject expanded variables from outer shell.
|
||||
if $use_journal; then
|
||||
# Compose systemd-cat args (escape tag and priority safely)
|
||||
# Note: we rely on simple token expansion; tag/priority are validated minimally below.
|
||||
journal_args=()
|
||||
journal_args+=( "-t" )
|
||||
journal_args+=( "$tag" )
|
||||
if [[ -n "$priority" ]]; then
|
||||
journal_args+=( "-p" )
|
||||
journal_args+=( "$priority" )
|
||||
fi
|
||||
|
||||
# Validate priority loosely (allow common names or numeric)
|
||||
case "$priority" in
|
||||
""|emerg|alert|crit|err|warning|notice|info|debug|0|1|2|3|4|5|6|7) ;;
|
||||
*)
|
||||
echo "Warning: unknown priority '$priority' — journald may reject it." >&2 ;;
|
||||
esac
|
||||
|
||||
# Prepare a single string of quoted journal args for insertion into the -c script
|
||||
# We need to protect values with single quotes if they contain special chars.
|
||||
journal_args_escaped=""
|
||||
for a in "${journal_args[@]}"; do
|
||||
# replace every single quote with '\'"\''
|
||||
a_escaped=${a//\'/\'"\'"\'}
|
||||
journal_args_escaped="$journal_args_escaped '$a_escaped'"
|
||||
done
|
||||
|
||||
inner_script=$(cat <<'EOF'
|
||||
umask __UMASK__
|
||||
cd / || true
|
||||
|
||||
# Close fds (best-effort)
|
||||
if [ -d /proc/self/fd ]; then
|
||||
for fdpath in /proc/self/fd/*; do
|
||||
fdnum=${fdpath##*/}
|
||||
case "$fdnum" in
|
||||
0|1|2) continue ;;
|
||||
esac
|
||||
eval "exec ${fdnum}>&-" 2>/dev/null || true
|
||||
done
|
||||
else
|
||||
maxfd=$(ulimit -n 2>/dev/null || echo 256)
|
||||
case "$maxfd" in (*[!0-9]*|"") maxfd=256 ;; esac
|
||||
fd=3
|
||||
while [ "$fd" -le "$maxfd" ]; do
|
||||
eval "exec ${fd}>&-" 2>/dev/null || true
|
||||
fd=$((fd+1))
|
||||
done
|
||||
fi
|
||||
|
||||
# Redirect stdio: stdin -> /dev/null, stdout+stderr -> systemd-cat (journal)
|
||||
exec </dev/null
|
||||
# Note: the systemd-cat command and its args are inserted by the outer script.
|
||||
exec > >( __SYSTEMD_CAT__ ) 2>&1
|
||||
|
||||
# Exec the target command; "$@" expands to the command and its args passed after --
|
||||
exec "$@"
|
||||
EOF
|
||||
)
|
||||
|
||||
# Substitute placeholders with safe values
|
||||
inner_script=${inner_script//'__UMASK__'/"$umask_val"}
|
||||
# Build the systemd-cat invocation string (path + args) — shell-escaped
|
||||
# We need a single token string like: /bin/systemd-cat -t 'tag' -p 'priority'
|
||||
systemd_cat_cmd="$(printf '%s' "$systemd_cat_path")$journal_args_escaped"
|
||||
# Replace placeholder __SYSTEMD_CAT__ with the built command
|
||||
inner_script=${inner_script//'__SYSTEMD_CAT__'/"$systemd_cat_cmd"}
|
||||
|
||||
# Start the detached process via setsid
|
||||
setsid bash -c "$inner_script" -- "${cmd[@]}" &
|
||||
else
|
||||
# Fallback: redirect to logfile (file mode)
|
||||
inner_script=$(cat <<'EOF'
|
||||
umask __UMASK__
|
||||
cd / || true
|
||||
|
||||
# Close fds (best-effort)
|
||||
if [ -d /proc/self/fd ]; then
|
||||
for fdpath in /proc/self/fd/*; do
|
||||
fdnum=${fdpath##*/}
|
||||
case "$fdnum" in
|
||||
0|1|2) continue ;;
|
||||
esac
|
||||
eval "exec ${fdnum}>&-" 2>/dev/null || true
|
||||
done
|
||||
else
|
||||
maxfd=$(ulimit -n 2>/dev/null || echo 256)
|
||||
case "$maxfd" in (*[!0-9]*|"") maxfd=256 ;; esac
|
||||
fd=3
|
||||
while [ "$fd" -le "$maxfd" ]; do
|
||||
eval "exec ${fd}>&-" 2>/dev/null || true
|
||||
fd=$((fd+1))
|
||||
done
|
||||
fi
|
||||
|
||||
exec </dev/null
|
||||
exec > "__LOGFILE__" 2>&1
|
||||
|
||||
exec "$@"
|
||||
EOF
|
||||
)
|
||||
inner_script=${inner_script//'__UMASK__'/"$umask_val"}
|
||||
# Escape logfile path for safe insertion (single-quote style)
|
||||
log_escaped=${logfile//\'/\'"\'"\'}
|
||||
inner_script=${inner_script//'__LOGFILE__'/"'$log_escaped'"}
|
||||
setsid bash -c "$inner_script" -- "${cmd[@]}" &
|
||||
fi
|
||||
|
||||
child_pid=$!
|
||||
|
||||
# Try to disown if supported
|
||||
if command -v disown >/dev/null 2>&1; then
|
||||
disown "$child_pid" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Optionally write pidfile
|
||||
if [[ -n "${pidfile}" ]]; then
|
||||
mkdir -p -- "$(dirname "${pidfile}")"
|
||||
printf '%s\n' "${child_pid}" > "${pidfile}"
|
||||
fi
|
||||
|
||||
echo "Started command: $(quoted_cmd "${cmd[@]}")"
|
||||
echo "Script PID: $$"
|
||||
echo "Daemon PID: ${child_pid}"
|
||||
if $use_journal; then
|
||||
echo "Output destination: systemd-journald (via $(printf '%s' "$systemd_cat_path"))"
|
||||
echo "Journal tag: ${tag}"
|
||||
if [[ -n "${priority}" ]]; then
|
||||
echo "Journal priority: ${priority}"
|
||||
fi
|
||||
else
|
||||
echo "Log file: ${logfile}"
|
||||
fi
|
||||
if [[ -n "${pidfile}" ]]; then
|
||||
echo "PID file: ${pidfile}"
|
||||
fi
|
||||
echo "Started at: $(date --iso-8601=seconds 2>/dev/null || date +%Y-%m-%dT%H:%M:%S%z)"
|
||||
|
||||
if ! $use_journal; then
|
||||
echo
|
||||
echo "To follow the log: tail -F ${logfile}"
|
||||
else
|
||||
echo
|
||||
echo "To view logs for this tag: journalctl -t ${tag} -f"
|
||||
fi
|
||||
17
hoyocloud-chromium-userscript.js
Normal file
17
hoyocloud-chromium-userscript.js
Normal file
@@ -0,0 +1,17 @@
|
||||
// ==UserScript==
|
||||
// @name Genshin Cloud
|
||||
// @namespace http://tampermonkey.net/
|
||||
// @version 0.1
|
||||
// @description fix a Genshin Impact cloud game bug
|
||||
// @match https://*.mihoyo.com/cloud/*
|
||||
// @grant none
|
||||
// ==/UserScript==
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
const origin = HTMLElement.prototype.requestPointerLock
|
||||
HTMLElement.prototype.requestPointerLock = function () {
|
||||
return origin.call(this)
|
||||
}
|
||||
})();
|
||||
72
readme.md
72
readme.md
@@ -1,56 +1,48 @@
|
||||
# niri 散装配置集(dotfiles)
|
||||
|
||||
> 都怪雪叶!(
|
||||
|
||||
~~by the time I make this repo, I even haven't configure fcitx5. so English README only.~~
|
||||
都怪雪叶!(
|
||||
|
||||
> [!note]
|
||||
> 本仓库的配置管理方案比较原始:逐个做软链接处理。有觉得`stow`等工具好用,想要重新组织文件树的欢迎 pr.
|
||||
> 1. 本仓库的配置管理方案比较原始:逐个做软链接处理。
|
||||
> 个人并不打算无脑用`stow`,尤其不希望一些 systemd 服务和涉及 token 的自用小工具混进来。
|
||||
> 2. 还有一些早期配置在整理本仓库时已经淡忘,由于篇幅和复述可靠性有限,亦不考虑收纳。
|
||||
> 3. 涉及`$HOME`、`~`、`%h`开头(最后一个多见于 systemd 服务)的路径建议自行适配——我的设定你不一定会满意。
|
||||
|
||||
## 鸣谢
|
||||
- 雪叶 [@Vescrity](https://github.com/Vescrity) (Yukitoha)
|
||||
- fizzyizzy05 (Isabelle Jackson, mtf)
|
||||
|
||||
## 已知依赖
|
||||
> [!note]
|
||||
> 从 WSL 里测试开始,配这些组件先后花了我两个多月时间。
|
||||
> 恕我很难回忆出都用过什么。
|
||||
> 仅列出**想得起来的**依赖软件包。
|
||||
|
||||
- `niri`,以及`yay -Si`中指定的可选依赖。
|
||||
- `swww`(从 fizzy 那毛的双层背景方案)
|
||||
- ZshIM (`zim`):主要为了 powerlevel10k.
|
||||
- 不再考虑 `oh-my-zsh`.
|
||||
- 也不需要用包管理器装插件(像语法高亮),这些 zim 默认就集成了。
|
||||
- `powershell-bin`:用于便捷地拉起新进程。
|
||||
|
||||
> 在`.sh`里总是纠结用`command &`还是`nohup`还是别的什么。
|
||||
> 而 pwsh 的`start-process`在 Linux 的实现似乎有用到 xdg-open,直接跑命令的效果又类似`command &`,实际用下来感觉不如 sh。
|
||||
> 但胜在容易写。搁 bash 里写`fuzzel-vsc-entries`就只能字符串拼接之后`echo`进管道,pwsh 则支持直接把 .NET 对象送进管道。
|
||||
|
||||
## 后续替换
|
||||
```
|
||||
alacritty -> foot
|
||||
nautilus (gnome files) -> yazi (console)
|
||||
swaylock -> gtklock
|
||||
gnome-keyring -> kwallet (kd6), kwallet-pam (to auto unlock), kwalletmanager (optional)
|
||||
com.saivert.pwvucontrol (flatpak) -> pavucontrol-qt (extra)
|
||||
...
|
||||
```
|
||||
|依赖|配置|备注|
|
||||
|-|-|-|
|
||||
|niri|`.config/niri/config*.kdl`|只拆分了`window-rule`和`binds`,拆太碎有些视觉效果会失效。|
|
||||
|`fuzzel`|`.config/fuzzel/*`|
|
||||
|`mako`|`.config/mako/*`|
|
||||
|`swww`|`bin/chbg` (bash 脚本)|依赖`imagemagick`。另,可以配合图床等实现定期换壁纸。|
|
||||
|`gtklock`|`.config/gtklock/*`|现阶段无法跟`swayidle`合用,尽管其 Wiki 鼓励这么做。|
|
||||
|`xdg-desktop-portal-(gtk\|gnome)`|`.config/xdg-desktop-portal/*-portals.conf`|GNOME 支持最全,但称不上好看(|
|
||||
|`kwallet`|VSCode 试图登录时会弹出向导让你配的。|替代`gnome-keyring`。建议加装`kwallet-pam`,免得 VSCode 自己尝试解锁结果闪退。|
|
||||
|foot|`.config/foot/foot.ini`|
|
||||
|`zsh`|`.zshrc` `.zprofile`|另使用了 ZshIM 和 powerlevel10k 主题,因此有些配置(如`HISTFILE`)不得不相应地提前。|
|
||||
|yazi|`.config/yazi/*`|替代`nautilus`。另用`fake-nautilus`移除`nautilus`包。|
|
||||
|fastfetch|`.config/fastfetch/*`|
|
||||
|waybar|`.config/waybar/*`|建议搭配`systemctl --user`(参见 [niri 在线文档](https://yalter.github.io/niri/Example-systemd-Setup.html))以便重载配置。|
|
||||
|`mpris`||`systemctl --user`配置自启动(参见 ArchWiki)|
|
||||
|`pavucontrol-qt`|
|
||||
|
||||
## 参考资源与备注
|
||||
- Nerd 字体:[Monaco Nerd Font Mono (MelodyEcho ver.)](https://glowmem.com/upload/articles/archlinux-note/Monaco_Nerd_Font_Mono-Regular.ttf) 或直接`ttf-monaco-nerd-font`(AUR)。后者在 VSCode 里表现不咋地。
|
||||
- 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)。
|
||||
|
||||
> [!note]
|
||||
> 壁纸自己用`chbg`生成。
|
||||
- 深色模式:`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)。我摆烂了。
|
||||
|
||||
> [!important]
|
||||
> Niri 里的 linuxqq 不能直接用`default-electron-flags`。改用以下标签:
|
||||
> - `--enable-platform=wayland`
|
||||
> - `--enable-wayland-ime`
|
||||
> - `--wayland-text-input-version=3`
|
||||
>
|
||||
> 至于原因,可参见 archlinuxcn 社区论坛。
|
||||
- 大多数 Electron 应用需要读`~/.config/*-flags.conf`来适配 Wayland,
|
||||
你可以把`default-electron-flags`相应地软链接过去。**特别地,QQ 需要多加一条**`--wayland-text-input-version=3`。
|
||||
|
||||
> [!note]
|
||||
> `fcitx5`的配置基本上和 Miku 指南所述一致,就不再合进来了;
|
||||
> 其余各 App 仍有一些兼容问题,排查后再更新此文档。
|
||||
- `hoyocloud-chromium-userscript.js`顾名思义,用于**在 Chrome 里**(firefox 不需要)游玩米哈游云游戏的油猴脚本。
|
||||
参见 [Bilibili 专栏](https://www.bilibili.com/opus/842314310196658193)。
|
||||
|
||||
- `bin/.battery-warn`虽说也是自用,但一是配置项并不算敏感,稍微改改`config`段也可以泛用;二是参考文献写得有点啰嗦,我懒得再缝第二遍。
|
||||
个人建议用于**定时任务(cron 或 systemd timer)**。
|
||||
|
||||
Reference in New Issue
Block a user