This commit is contained in:
candle 2026-03-09 00:07:31 -04:00
commit 5eae1ef498
82 changed files with 8204 additions and 0 deletions

28
.config/candle Normal file
View File

@ -0,0 +1,28 @@
              ...                       
          ...........                   
        .......'.......                 
       .....'',,,,''....                
      ....'',;;;;;;,'....               
      ....',;::x::;,;'...               
      ...'',;:d0o:;:,'....              
      ....',;:XXK:;,,;...               
       ...',,kKK0d,,'....               
       .....'dkOkl''....                
         .....lol......                 
       XNNNNNWXkXWWW,                   
       KWNNNNNNONNNNNNNc                
       ONNNNNNNNNNNNNNN,                
      cNNXNNNNXNNXXXXN;                 
      dNXNNNNNXXXNNNNX'                 
        cNNNNNXXXNNNNX,                 
        :NNNNNXXXNNNNXW'                
        ,NNNNXXXXNNNNXN                 
        'NNNNXNNXNNNNk                  
        .NWNNNXXXNNNNk       .N0OxxOx   
    dNXKKNWWWNNNNNNNNKkO0Xd kK.     d0. 
 kkooxO00NWWWWNNNNNNNXlc;'';ld       xd 
 ,:ldk0koOXNNNNNNNNXKOlc:,'...       ol 
    'l:cldxk0KKXKK0kxdlc;'          dx; 
       .;:ldxO0K0Okdl:;'        .WKxo.  
        ldxk0KNWNK0kxdoKXXNWWN0kd       
        'lxOKXNWNXKOxl'                 

View File

@ -0,0 +1,69 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"display": {
"separator": "  ",
"constants": [
"────────────────────────" // {$1}, used in Custom module
],
"key": {
"type": "icon",
"paddingLeft": 2
}
},
"modules": [
{
"type": "colors",
"symbol": "circle",
"paddingLeft": 23,
},
{
"type": "custom", // HardwareStart
// {#1} is equivalent to `\u001b[1m`. {#} is equivalent to `\u001b[m`
"format": "┌{$1} {#1}Hardware{#} {$1}┐"
},
"host",
"cpu",
"gpu",
"disk",
"memory",
"display",
"brightness",
"battery",
"poweradapter",
"bluetooth",
"sound",
"gamepad",
{
"type": "custom", // SoftwareStart
"format": "├{$1} {#1}Software{#} {$1}┤"
},
{
"type": "title",
"keyIcon": "",
"key": "Title", // Title module has no key by default, so that icon is not displayed
"format": "{user-name}@{host-name}"
},
"os",
"kernel",
"lm",
"de",
"wm",
"shell",
"terminal",
"terminalfont",
"theme",
"icons",
"wallpaper",
"packages",
"uptime",
{
"type": "custom", // InformationEnd
"format": "└{$1}──────────{$1}┘"
},
{
"type": "colors",
"symbol": "circle",
"paddingLeft": 23,
}
]
}

View File

@ -0,0 +1,77 @@
{
"$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json",
"logo": {
"type": "small"
},
"display": {
"separator": "  ",
"color": {
"keys": "white"
},
"size": {
"ndigits": 1,
"maxPrefix": "GB"
},
"key": {
"type": "icon"
},
"bar": {
"charelapsed": "=",
"chartotal": "-",
"width": 14
},
"percent": {
"type": 2
}
},
"modules": [
{
"type": "title",
"color": {
"user": "green",
"at": "red",
"host": "blue"
}
},
{
"type": "os",
"keyIcon": "╭─󰗢",
"keyColor": "blue"
},
// {
// "type": "kernel",
// "keyIcon": "├─",
// "keyColor": "blue"
// },
{
"type": "memory",
"keyIcon": "├─",
"keyColor": "blue"
},
{
"type": "packages",
"keyIcon": "├─󰏖",
"keyColor": "red"
},
{
"type": "uptime",
"keyIcon": "├─",
"keyColor": "red"
},
{
"keyIcon": "Weather",
"keyType": "string",
"keyColor": "green",
"type": "command",
"keyIcon": "├─${CONDITION}",
"text": "cat /tmp/wttr.in | tail -n +2 | xargs",
"paddingLeft": -1
},
{
"type": "colors",
"key": "Colors", // For printing icon
"keyIcon": "╰─",
"symbol": "circle"
}
]
}

33
.config/fish/config.fish Normal file
View File

@ -0,0 +1,33 @@
if status is-interactive
# Commands to run in interactive sessions can go here
# /bin/cat /home/$USER/.cache/wal/sequences
if test $fish_pid = (pgrep fish | sed -n '2p')
if test -e /tmp/small.jsonc
fastfetch -c /tmp/small.jsonc
else
fastfetch -c $XDG_CONFIG_HOME/fastfetch/small.jsonc
end
motd
end
function y
set tmp (mktemp -t "yazi-cwd.XXXXXX")
yazi $argv --cwd-file="$tmp"
if read -z cwd <"$tmp"; and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ]
builtin cd -- "$cwd"
end
rm -f -- "$tmp"
end
source /usr/share/wikiman/widgets/widget.fish
set --erase FZF_DEFAULT_OPTS
set -Ux FZF_DEFAULT_OPTS (cat $XDG_CACHE_HOME/wal/colors-fzf) --preview \'fzfp {}\' --bind \'enter:execute\(open \{\}\)\'
fzf_key_bindings
abbr -a !! --position anywhere --function last_history_item
abbr -a dotdot --regex '^\.\.+$' --function multicd
abbr -a cr cargo run
end
set -Ux FZF_DEFAULT_COMMAND 'fd --type f --strip-cwd-prefix --follow'
# fish_add_path /home/candle/.spicetify
zoxide init --cmd cd fish | source

View File

@ -0,0 +1,4 @@
function cat --wraps=bat --wraps=catbat --description 'alias cat bat'
bat $argv
end

View File

@ -0,0 +1,4 @@
function cleanpackages --wraps='pacman -Qqdt | sudo pacman -Rns -' --description 'alias cleanpackages pacman -Qqdt | sudo pacman -Rns -'
pacman -Qqdt | sudo pacman -Rns - $argv
end

View File

@ -0,0 +1,3 @@
function dotfiles --wraps='/usr/bin/git --git-dir=/home/candle/.dotfiles/ --work-tree=/home/candle' --description 'alias dotfiles /usr/bin/git --git-dir=/home/candle/.dotfiles/ --work-tree=/home/candle'
/usr/bin/git --git-dir=/home/candle/.dotfiles/ --work-tree=/home/candle $argv
end

View File

@ -0,0 +1,4 @@
function ff --wraps='fastfetch -c /home/candle/.config/fastfetch/big.jsonc --logo /home/candle/.config/candle' --description 'alias ff fastfetch --logo /home/candle/.config/candle'
fastfetch -c /home/candle/.config/fastfetch/big.jsonc --logo /home/candle/.config/candle $argv
end

View File

@ -0,0 +1 @@
# Disable default vi prompt

View File

@ -0,0 +1,171 @@
function fish_prompt
end # In case this file gets loaded non-interactively, e.g by conda
status is-interactive || exit
_tide_remove_unusable_items
_tide_cache_variables
_tide_parent_dirs
source (functions --details _tide_pwd)
set -l prompt_var _tide_prompt_$fish_pid
set -U $prompt_var # Set var here so if we erase $prompt_var, bg job won't set a uvar
set_color normal | read -l color_normal
status fish-path | read -l fish_path
# _tide_repaint prevents us from creating a second background job
function _tide_refresh_prompt --on-variable $prompt_var --on-variable COLUMNS
set -g _tide_repaint
commandline -f repaint
end
if contains newline $_tide_left_items # two line prompt initialization
test "$tide_prompt_add_newline_before" = true && set -l add_newline '\n'
set_color $tide_prompt_color_frame_and_connection -b normal | read -l prompt_and_frame_color
set -l column_offset 5
test "$tide_left_prompt_frame_enabled" = true &&
set -l top_left_frame "$prompt_and_frame_color╭─" &&
set -l bot_left_frame "$prompt_and_frame_color╰─" &&
set column_offset (math $column_offset-2)
test "$tide_right_prompt_frame_enabled" = true &&
set -l top_right_frame "$prompt_and_frame_color─╮" &&
set -l bot_right_frame "$prompt_and_frame_color─╯" &&
set column_offset (math $column_offset-2)
if test "$tide_prompt_transient_enabled" = true
eval "
function fish_prompt
_tide_status=\$status _tide_pipestatus=\$pipestatus if not set -e _tide_repaint
jobs -q && jobs -p | count | read -lx _tide_jobs
$fish_path -c \"set _tide_pipestatus \$_tide_pipestatus
set _tide_parent_dirs \$_tide_parent_dirs
PATH=\$(string escape \"\$PATH\") CMD_DURATION=\$CMD_DURATION fish_bind_mode=\$fish_bind_mode set $prompt_var (_tide_2_line_prompt)\" &
builtin disown
command kill \$_tide_last_pid 2>/dev/null
set -g _tide_last_pid \$last_pid
end
if not set -q _tide_transient
math \$COLUMNS-(string length -V \"\$$prompt_var[1][1]\$$prompt_var[1][3]\")+$column_offset | read -lx dist_btwn_sides
echo -n $add_newline'$top_left_frame'(string replace @PWD@ (_tide_pwd) \"\$$prompt_var[1][1]\")'$prompt_and_frame_color'
string repeat -Nm(math max 0, \$dist_btwn_sides-\$_tide_pwd_len) '$tide_prompt_icon_connection'
echo \"\$$prompt_var[1][3]$top_right_frame\"
end
echo -n \e\[0J\"$bot_left_frame\$$prompt_var[1][2]$color_normal \"
end
function fish_right_prompt
set -e _tide_transient || string unescape \"\$$prompt_var[1][4]$bot_right_frame$color_normal\"
end"
else
eval "
function fish_prompt
_tide_status=\$status _tide_pipestatus=\$pipestatus if not set -e _tide_repaint
jobs -q && jobs -p | count | read -lx _tide_jobs
$fish_path -c \"set _tide_pipestatus \$_tide_pipestatus
set _tide_parent_dirs \$_tide_parent_dirs
PATH=\$(string escape \"\$PATH\") CMD_DURATION=\$CMD_DURATION fish_bind_mode=\$fish_bind_mode set $prompt_var (_tide_2_line_prompt)\" &
builtin disown
command kill \$_tide_last_pid 2>/dev/null
set -g _tide_last_pid \$last_pid
end
math \$COLUMNS-(string length -V \"\$$prompt_var[1][1]\$$prompt_var[1][3]\")+$column_offset | read -lx dist_btwn_sides
echo -ns $add_newline'$top_left_frame'(string replace @PWD@ (_tide_pwd) \"\$$prompt_var[1][1]\")'$prompt_and_frame_color'
string repeat -Nm(math max 0, \$dist_btwn_sides-\$_tide_pwd_len) '$tide_prompt_icon_connection'
echo -ns \"\$$prompt_var[1][3]$top_right_frame\"\n\"$bot_left_frame\$$prompt_var[1][2]$color_normal \"
end
function fish_right_prompt
string unescape \"\$$prompt_var[1][4]$bot_right_frame$color_normal\"
end"
end
else # one line prompt initialization
test "$tide_prompt_add_newline_before" = true && set -l add_newline '\0'
math 5 -$tide_prompt_min_cols | read -l column_offset
test $column_offset -ge 0 && set column_offset "+$column_offset"
if test "$tide_prompt_transient_enabled" = true
eval "
function fish_prompt
set -lx _tide_status \$status
_tide_pipestatus=\$pipestatus if not set -e _tide_repaint
jobs -q && jobs -p | count | read -lx _tide_jobs
$fish_path -c \"set _tide_pipestatus \$_tide_pipestatus
set _tide_parent_dirs \$_tide_parent_dirs
PATH=\$(string escape \"\$PATH\") CMD_DURATION=\$CMD_DURATION fish_bind_mode=\$fish_bind_mode set $prompt_var (_tide_1_line_prompt)\" &
builtin disown
command kill \$_tide_last_pid 2>/dev/null
set -g _tide_last_pid \$last_pid
end
if set -q _tide_transient
echo -n \e\[0J
add_prefix= _tide_item_character
echo -n '$color_normal '
else
math \$COLUMNS-(string length -V \"\$$prompt_var[1][1]\$$prompt_var[1][2]\")$column_offset | read -lx dist_btwn_sides
string replace @PWD@ (_tide_pwd) $add_newline \$$prompt_var[1][1]'$color_normal '
end
end
function fish_right_prompt
set -e _tide_transient || string unescape \"\$$prompt_var[1][2]$color_normal\"
end"
else
eval "
function fish_prompt
_tide_status=\$status _tide_pipestatus=\$pipestatus if not set -e _tide_repaint
jobs -q && jobs -p | count | read -lx _tide_jobs
$fish_path -c \"set _tide_pipestatus \$_tide_pipestatus
set _tide_parent_dirs \$_tide_parent_dirs
PATH=\$(string escape \"\$PATH\") CMD_DURATION=\$CMD_DURATION fish_bind_mode=\$fish_bind_mode set $prompt_var (_tide_1_line_prompt)\" &
builtin disown
command kill \$_tide_last_pid 2>/dev/null
set -g _tide_last_pid \$last_pid
end
math \$COLUMNS-(string length -V \"\$$prompt_var[1][1]\$$prompt_var[1][2]\")$column_offset | read -lx dist_btwn_sides
string replace @PWD@ (_tide_pwd) $add_newline \$$prompt_var[1][1]'$color_normal '
end
function fish_right_prompt
string unescape \"\$$prompt_var[1][2]$color_normal\"
end"
end
end
eval "function _tide_on_fish_exit --on-event fish_exit
set -e $prompt_var
end"
if test "$tide_prompt_transient_enabled" = true
function _tide_enter_transient
# If the commandline will be executed, or is empty
if commandline --is-valid || test -z "$(commandline)"
# Pager open usually means selecting, not running
# Can be untrue, but it's better than the alternative
if not commandline --paging-mode
set -g _tide_transient
set -g _tide_repaint
commandline -f repaint
end
end
commandline -f execute
end
bind \r _tide_enter_transient
bind \n _tide_enter_transient
bind -M insert \r _tide_enter_transient
bind -M insert \n _tide_enter_transient
end

View File

@ -0,0 +1,9 @@
function fuck -d "Correct your previous console command"
set -l fucked_up_command $history[1]
env TF_SHELL=fish TF_ALIAS=fuck PYTHONIOENCODING=utf-8 thefuck $fucked_up_command THEFUCK_ARGUMENT_PLACEHOLDER $argv | read -l unfucked_command
if [ "$unfucked_command" != "" ]
eval $unfucked_command
builtin history delete --exact --case-sensitive -- $fucked_up_command
builtin history merge
end
end

View File

@ -0,0 +1,232 @@
### key-bindings.fish ###
# ____ ____
# / __/___ / __/
# / /_/_ / / /_
# / __/ / /_/ __/
# /_/ /___/_/ key-bindings.fish
#
# - $FZF_TMUX_OPTS
# - $FZF_CTRL_T_COMMAND
# - $FZF_CTRL_T_OPTS
# - $FZF_CTRL_R_OPTS
# - $FZF_ALT_C_COMMAND
# - $FZF_ALT_C_OPTS
# Key bindings
# ------------
# The oldest supported fish version is 3.1b1. To maintain compatibility, the
# command substitution syntax $(cmd) should never be used, even behind a version
# check, otherwise the source command will fail on fish versions older than 3.4.0.
function fzf_key_bindings
# Check fish version
set -l fish_ver (string match -r '^(\d+).(\d+)' $version 2> /dev/null; or echo 0\n0\n0)
if test \( "$fish_ver[2]" -lt 3 \) -o \( "$fish_ver[2]" -eq 3 -a "$fish_ver[3]" -lt 1 \)
echo "This script requires fish version 3.1b1 or newer." >&2
return 1
else if not type -q fzf
echo "fzf was not found in path." >&2
return 1
end
function __fzf_defaults
# $argv[1]: Prepend to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
# $argv[2..]: Append to FZF_DEFAULT_OPTS_FILE and FZF_DEFAULT_OPTS
test -n "$FZF_TMUX_HEIGHT"; or set -l FZF_TMUX_HEIGHT 40%
string join ' ' -- \
"--height $FZF_TMUX_HEIGHT --min-height=20+ --bind=ctrl-z:ignore" $argv[1] \
(test -r "$FZF_DEFAULT_OPTS_FILE"; and string join -- ' ' <$FZF_DEFAULT_OPTS_FILE) \
$FZF_DEFAULT_OPTS $argv[2..-1]
end
function __fzfcmd
test -n "$FZF_TMUX_HEIGHT"; or set -l FZF_TMUX_HEIGHT 40%
if test -n "$FZF_TMUX_OPTS"
echo "fzf-tmux $FZF_TMUX_OPTS -- "
else if test "$FZF_TMUX" = 1
echo "fzf-tmux -d$FZF_TMUX_HEIGHT -- "
else
echo fzf
end
end
function __fzf_parse_commandline -d 'Parse the current command line token and return split of existing filepath, fzf query, and optional -option= prefix'
set -l fzf_query ''
set -l prefix ''
set -l dir '.'
# Set variables containing the major and minor fish version numbers, using
# a method compatible with all supported fish versions.
set -l -- fish_major (string match -r -- '^\d+' $version)
set -l -- fish_minor (string match -r -- '^\d+\.(\d+)' $version)[2]
# fish v3.3.0 and newer: Don't use option prefix if " -- " is preceded.
set -l -- match_regex '(?<fzf_query>[\s\S]*?(?=\n?$)$)'
set -l -- prefix_regex '^-[^\s=]+=|^-(?!-)\S'
if test "$fish_major" -eq 3 -a "$fish_minor" -lt 3
or string match -q -v -- '* -- *' (string sub -l (commandline -Cp) -- (commandline -p))
set -- match_regex "(?<prefix>$prefix_regex)?$match_regex"
end
# Set $prefix and expanded $fzf_query with preserved trailing newlines.
if test "$fish_major" -ge 4
# fish v4.0.0 and newer
string match -q -r -- $match_regex (commandline --current-token --tokens-expanded | string collect -N)
else if test "$fish_major" -eq 3 -a "$fish_minor" -ge 2
# fish v3.2.0 - v3.7.1 (last v3)
string match -q -r -- $match_regex (commandline --current-token --tokenize | string collect -N)
eval set -- fzf_query (string escape -n -- $fzf_query | string replace -r -a '^\\\(?=~)|\\\(?=\$\w)' '')
else
# fish older than v3.2.0 (v3.1b1 - v3.1.2)
set -l -- cl_token (commandline --current-token --tokenize | string collect -N)
set -- prefix (string match -r -- $prefix_regex $cl_token)
set -- fzf_query (string replace -- "$prefix" '' $cl_token | string collect -N)
eval set -- fzf_query (string escape -n -- $fzf_query | string replace -r -a '^\\\(?=~)|\\\(?=\$\w)|\\\n\\\n$' '')
end
if test -n "$fzf_query"
# Normalize path in $fzf_query, set $dir to the longest existing directory.
if test \( "$fish_major" -ge 4 \) -o \( "$fish_major" -eq 3 -a "$fish_minor" -ge 5 \)
# fish v3.5.0 and newer
set -- fzf_query (path normalize -- $fzf_query)
set -- dir $fzf_query
while not path is -d $dir
set -- dir (path dirname $dir)
end
else
# fish older than v3.5.0 (v3.1b1 - v3.4.1)
if test "$fish_major" -eq 3 -a "$fish_minor" -ge 2
# fish v3.2.0 - v3.4.1
string match -q -r -- '(?<fzf_query>^[\s\S]*?(?=\n?$)$)' \
(string replace -r -a -- '(?<=/)/|(?<!^)/+(?!\n)$' '' $fzf_query | string collect -N)
else
# fish v3.1b1 - v3.1.2
set -- fzf_query (string replace -r -a -- '(?<=/)/|(?<!^)/+(?!\n)$' '' $fzf_query | string collect -N)
eval set -- fzf_query (string escape -n -- $fzf_query | string replace -r '\\\n$' '')
end
set -- dir $fzf_query
while not test -d "$dir"
set -- dir (dirname -z -- "$dir" | string split0)
end
end
if not string match -q -- '.' $dir; or string match -q -r -- '^\./|^\.$' $fzf_query
# Strip $dir from $fzf_query - preserve trailing newlines.
if test "$fish_major" -ge 4
# fish v4.0.0 and newer
string match -q -r -- '^'(string escape --style=regex -- $dir)'/?(?<fzf_query>[\s\S]*)' $fzf_query
else if test "$fish_major" -eq 3 -a "$fish_minor" -ge 2
# fish v3.2.0 - v3.7.1 (last v3)
string match -q -r -- '^/?(?<fzf_query>[\s\S]*?(?=\n?$)$)' \
(string replace -- "$dir" '' $fzf_query | string collect -N)
else
# fish older than v3.2.0 (v3.1b1 - v3.1.2)
set -- fzf_query (string replace -- "$dir" '' $fzf_query | string collect -N)
eval set -- fzf_query (string escape -n -- $fzf_query | string replace -r -a '^/?|\\\n$' '')
end
end
end
string escape -n -- "$dir" "$fzf_query" "$prefix"
end
# Store current token in $dir as root for the 'find' command
function fzf-file-widget -d "List files and folders"
set -l commandline (__fzf_parse_commandline)
set -lx dir $commandline[1]
set -l fzf_query $commandline[2]
set -l prefix $commandline[3]
set -lx FZF_DEFAULT_OPTS (__fzf_defaults \
"--reverse --walker=file,dir,follow,hidden --scheme=path" \
"$FZF_CTRL_T_OPTS --multi --print0")
set -lx FZF_DEFAULT_COMMAND "$FZF_CTRL_T_COMMAND"
set -lx FZF_DEFAULT_OPTS_FILE
set -l result (eval (__fzfcmd) --walker-root=$dir --query=$fzf_query | string split0)
and commandline -rt -- (string join -- ' ' $prefix(string escape -- $result))' '
commandline -f repaint
end
function fzf-history-widget -d "Show command history"
set -l -- command_line (commandline)
set -l -- current_line (commandline -L)
set -l -- total_lines (count $command_line)
set -l -- fzf_query (string escape -- $command_line[$current_line])
set -lx FZF_DEFAULT_OPTS (__fzf_defaults '' \
'--nth=2..,.. --scheme=history --multi --wrap-sign="\t↳ "' \
'--bind=\'shift-delete:execute-silent(eval history delete --exact --case-sensitive -- (string escape -n -- {+} | string replace -r -a "^\d*\\\\\\t|(?<=\\\\\\n)\\\\\\t" ""))+reload(eval $FZF_DEFAULT_COMMAND)\'' \
"--bind=ctrl-r:toggle-sort --highlight-line $FZF_CTRL_R_OPTS" \
'--accept-nth=2.. --read0 --print0 --with-shell='(status fish-path)\\ -c)
set -lx FZF_DEFAULT_OPTS_FILE
set -lx FZF_DEFAULT_COMMAND
if type -q perl
set -a FZF_DEFAULT_OPTS --tac
set FZF_DEFAULT_COMMAND 'builtin history -z --reverse | command perl -0 -pe \'s/^/$.\t/g; s/\n/\n\t/gm\''
else
set FZF_DEFAULT_COMMAND \
'set -l h (builtin history -z --reverse | string split0);' \
'for i in (seq (count $h) -1 1);' \
'string join0 -- $i\t(string replace -a -- \n \n\t $h[$i] | string collect);' \
end
end
# Merge history from other sessions before searching
test -z "$fish_private_mode"; and builtin history merge
if set -l result (eval $FZF_DEFAULT_COMMAND \| (__fzfcmd) --query=$fzf_query | string split0)
if test "$total_lines" -eq 1
commandline -- (string replace -a -- \n\t \n $result)
else
set -l a (math $current_line - 1)
set -l b (math $current_line + 1)
commandline -- $command_line[1..$a] (string replace -a -- \n\t \n $result)
commandline -a -- '' $command_line[$b..-1]
end
end
commandline -f repaint
end
function fzf-cd-widget -d "Change directory"
set -l commandline (__fzf_parse_commandline)
set -lx dir $commandline[1]
set -l fzf_query $commandline[2]
set -l prefix $commandline[3]
set -lx FZF_DEFAULT_OPTS (__fzf_defaults \
"--reverse --walker=dir,follow,hidden --scheme=path" \
"$FZF_ALT_C_OPTS --no-multi --print0")
set -lx FZF_DEFAULT_OPTS_FILE
set -lx FZF_DEFAULT_COMMAND "$FZF_ALT_C_COMMAND"
if set -l result (eval (__fzfcmd) --query=$fzf_query --walker-root=$dir | string split0)
cd -- $result
commandline -rt -- $prefix
end
commandline -f repaint
end
bind \cr fzf-history-widget
bind -M insert \cr fzf-history-widget
if not set -q FZF_CTRL_T_COMMAND; or test -n "$FZF_CTRL_T_COMMAND"
bind \ct fzf-file-widget
bind -M insert \ct fzf-file-widget
end
if not set -q FZF_ALT_C_COMMAND; or test -n "$FZF_ALT_C_COMMAND"
bind \ec fzf-cd-widget
bind -M insert \ec fzf-cd-widget
end
end
### end: key-bindings.fish ###
fzf_key_bindings

View File

@ -0,0 +1,4 @@
function icat --description 'alias icat kitty +kitten icat'
kitty +kitten icat $argv
end

View File

@ -0,0 +1,3 @@
function last_history_item
echo $history[1]
end

View File

@ -0,0 +1,4 @@
function logs --wraps='journalctl --since today | bat --color=always --language=log --paging auto --style=numbers,grid -' --description 'alias logs journalctl --since today | bat --color=always --language=log --paging auto --style=numbers,grid -'
journalctl --since today | bat --color=always --language=log --paging auto --style=numbers,grid - $argv
end

View File

@ -0,0 +1,4 @@
function ls --wraps='eza --color=always --time-style=relative --no-user --no-permissions --no-quotes --long --icons=auto' --description 'List Files'
eza --color=always --time-style=relative --no-user --no-permissions --no-quotes --long --icons=auto $argv
end

View File

@ -0,0 +1,4 @@
function lsa --wraps='eza --color=always --time-style=default --no-quotes --long --icons=auto' --description 'alias lsa eza --color=always --time-style=default --no-quotes --long --icons=auto'
eza --color=always --time-style=default --no-quotes --long --icons=auto $argv
end

View File

@ -0,0 +1,4 @@
function lsl --wraps='eza --color=always --time-style=relative --no-user --no-permissions --no-quotes' --description 'List Files Block'
eza --color=always --time-style=relative --no-user --no-permissions --no-quotes $argv
end

View File

@ -0,0 +1,3 @@
function multicd
echo cd (string repeat -n (math (string length -- $argv[1]) - 1) ../)
end

View File

@ -0,0 +1,4 @@
function packages --wraps="yay -Slq | fzf --preview 'yay -Si {} | bat --color=always --language=yaml --style=grid --plain' --layout=reverse --bind 'enter:execute(yay -S {})+accept'" --description "alias packages yay -Slq | fzf --preview 'yay -Si {} | bat --color=always --language=yaml --style=grid --plain' --layout=reverse --bind 'enter:execute(yay -S {})+accept'"
yay -Slq | fzf --preview 'yay -Si {} | bat --color=always --language=yaml --style=grid --plain' --layout=reverse --bind 'enter:execute(yay -S {})+accept' $argv
end

View File

@ -0,0 +1,4 @@
function pacls --wraps="pacman -Qqe | fzf --preview 'pacman -Qil {} | bat --color=always --language=yaml --style=grid --plain' --layout=reverse --bind 'enter:execute(printf %s {} | wl-copy && pacman -Qil {} | bat --color=always --language=yaml --style=grid,numbers)+accept'" --description "alias pacls pacman -Qqe | fzf --preview 'pacman -Qil {} | bat --color=always --language=yaml --style=grid --plain' --layout=reverse --bind 'enter:execute(printf %s {} | wl-copy && pacman -Qil {} | bat --color=always --language=yaml --style=grid,numbers)+accept'"
pacman -Qqe | fzf --preview 'pacman -Qil {} | bat --color=always --language=yaml --style=grid --plain' --layout=reverse --bind 'enter:execute(printf %s {} | wl-copy && pacman -Qil {} | bat --color=always --language=yaml --style=grid,numbers)+accept' $argv
end

View File

@ -0,0 +1,4 @@
function paclsa --wraps="pacman -Qq | fzf --preview 'pacman -Qil {} | bat --color=always --language=yaml --style=grid --plain' --layout=reverse --bind 'enter:execute(printf %s {} | wl-copy && pacman -Qil {} | bat --color=always --language=yaml --style=grid,numbers)+accept'" --description "alias paclsa pacman -Qq | fzf --preview 'pacman -Qil {} | bat --color=always --language=yaml --style=grid --plain' --layout=reverse --bind 'enter:execute(printf %s {} | wl-copy && pacman -Qil {} | bat --color=always --language=yaml --style=grid,numbers)+accept'"
pacman -Qq | fzf --preview 'pacman -Qil {} | bat --color=always --language=yaml --style=grid --plain' --layout=reverse --bind 'enter:execute(printf %s {} | wl-copy && pacman -Qil {} | bat --color=always --language=yaml --style=grid,numbers)+accept' $argv
end

View File

@ -0,0 +1,4 @@
function refreshmirrors --wraps='sudo reflector -c US -a 12 --sort rate --save /etc/pacman.d/mirrorlist' --description 'alias refreshmirrors reflector -c US -a 12 --sort rate --save /etc/pacman.d/mirrorlist'
sudo reflector -c US -a 12 --sort rate --save /etc/pacman.d/mirrorlist $argv
end

View File

@ -0,0 +1,4 @@
function rm --wraps=trash-put --description 'alias rm trash-put'
trash-put $argv
end

View File

@ -0,0 +1,4 @@
function tp --wraps=trash-put --description 'alias tp trash-put'
trash-put $argv
end

View File

@ -0,0 +1,4 @@
function wget --description 'alias wget wget --hsts-file="$XDG_DATA_HOME/wget-hsts"'
command wget --hsts-file="$XDG_DATA_HOME/wget-hsts" $argv
end

View File

@ -0,0 +1,8 @@
function y
set tmp (mktemp -t "yazi-cwd.XXXXXX")
yazi $argv --cwd-file="$tmp"
if read -z cwd <"$tmp"; and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ]
builtin cd -- "$cwd"
end
rm -f -- "$tmp"
end

14
.config/helix/config.toml Normal file
View File

@ -0,0 +1,14 @@
theme = "base16_default"
[editor.cursor-shape]
insert = "bar"
normal = "block"
select = "underline"
[keys.normal]
C-s = ":w"
"ret" = ["open_below", "normal_mode"]
# "C-S-C" = ":clipboard-yank"
[editor]
bufferline = "multiple"

View File

@ -0,0 +1,26 @@
# See:
# https://docs.helix-editor.com/master/languages.html
# https://github.com/helix-editor/helix/blob/master/languages.toml
# rust
[[language]]
name = "rust"
auto-format = true
[language-server.rust-analyzer]
command = "rust-analyzer"
[language-server.rust-analyzer.config.check]
command = "clippy"
# cpp
[[language]]
name = "cpp"
[language-server.clangd]
command = "clangd"
args = ["--compile-commands-dir", ".cmake"]
[[language]]
name = "python"

462
.config/hypr/hyprland.conf Normal file
View File

@ -0,0 +1,462 @@
# ========
# ========
# !!MONITORS!! #
# --------------------------------------------------------------------------------- #
# !!MONITORS!! #
# run `hyprctl monitors all` to see all your monitors!!!
source = $XDG_CACHE_HOME/wal/colors-hyprland
source = $XDG_CONFIG_HOME/hypr/monitors.conf
source = $XDG_CONFIG_HOME/hypr/wallpaper.conf
exec-once = systemd-timer-notify &
exec-once = [workspace special:magic silent] discord
$fileManager = thunar
$menu = rofi -combi-modi window,drun -show combi -show-icons -theme-str 'window {width: 15%; height: 42%;}'
$browser = rofi -show file-browser-extended -show-icons -theme-str 'window {width: 20%; height: 32%;}'
# $emoji = rofi -modi "emoji:rofimoji" -show emoji -theme-str 'window {width: 20%; height: 12%;}'
# $calc = rofi -show calc -no-show-match -no-sort -theme-str 'window {width: 20%; height: 10%;}'
$screenshot = slurp | grim -g - - | wl-copy
$scripts = $XDG_CONFIG_HOME/hypr/scripts
$power = $scripts/power.sh
$notes = $scripts/notes.sh
$move = $scripts/move.sh
$actions = $scripts/actions.sh
# $picker = hyprpicker -a 2>/dev/null
$notifications = swaync-client -t
# Environment variables
env = ELECTRON_OZONE_PLATFORM_HINT,auto
env = XCURSOR_SIZE,24
env = XCURSOR_THEME,Posy_Cursor
env = HYPRCURSOR_SIZE,24
env = HYPRCURSOR_THEME,Posy_Cursor
$swpw_name = `(echo -n '90' && (hyprctl activeworkspace -j | jq -r '.name')) | sed 's/9090//g' | tr -d '\n'`
$special_workspace_per_workspace = hyprctl dispatch workspace $swpw_name
$move_to_special_workspace_per_workspace = hyprctl dispatch movetoworkspace $swpw_name
# Special Workspace per Workspace bindings
# !!INPUT!! #
# --------------------------------------------------------------------------------- #
# !!INPUT!! #
render = {direct_scanout=1}
# READ https://wiki.hyprland.org/Configuring/Variables/#input IF CONFUSED!
# Example keyboard/mouse input settings.
input {
kb_layout = us
# Set as needed
kb_rules =
kb_variant =
kb_model =
accel_profile = flat
follow_mouse = 1
force_no_accel = true
# Range is -1.0 to 1.0 | 0 means no modification to sensitivity.
sensitivity = 0
touchpad {
natural_scroll = false
}
}
cursor {
no_hardware_cursors = true
}
# !!DESIGN!! #
# --------------------------------------------------------------------------------- #
# !!DESIGN!! #
animations {
enabled = true
bezier = myBezier, 0, 1, 0.18, 1.0
animation = windows, 1, 1.5, myBezier
animation = windowsOut, 1, 2, myBezier, popin 95%
animation = border, 1, 12, myBezier
animation = borderangle, 1, 5, default
animation = fade, 1, 6, default
animation = workspaces, 1, 6, default
}
# The gaps between windows, as well as border colors.
# proportional to the taskbar values.
general {
# Inner and Outer gaps between windows.
gaps_in = 5
gaps_out = 20 14 20 20
# I prefer a thin border
border_size = 2
# Border colors.
col.active_border = $color0
col.inactive_border = $color1
# Set to true enable resizing windows by clicking and dragging on borders and gaps
resize_on_border = true
layout = dwindle
# READ https://wiki.hyprland.org/Configuring/Tearing/ BEFORE TURNING ON!
allow_tearing = false
}
# Window Decorations! Shadow, Blur, etc.
decoration {
rounding = 12
active_opacity = 1
inactive_opacity = 1
# Window Shadow
shadow:enabled = true
shadow:range = 16
shadow:render_power = 5
shadow:color = rgba(0,0,0,0.35)
# Transparent Window Blur
blur{
enabled = true
size = 2
passes = 3
vibrancy = 0.1696
}
}
# Read https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more info on dwindle layout.
dwindle {
pseudotile = true
preserve_split = true
}
# Read https://wiki.hyprland.org/Configuring/Master-Layout/ for more info on master layout.
master {
new_status = master
}
misc {
force_default_wallpaper = 0
disable_hyprland_logo = true
enable_anr_dialog = false
}
# No need for gestures unless you have a touch display.
gestures {
}
# !!KEYBINDS!! #
# --------------------------------------------------------------------------------- #
# !!KEYBINDS!! #
$mainMod = SUPER
bind = $mainMod Shift, L, exit
bind = $mainMod, Return, exec, $TERMINAL
bind = $mainMod, Q, killactive,
bind = $mainMod, G, exec, $screenshot
bind = $mainMod SHIFT, E, exec, $fileManager
bind = $mainMod, V, togglefloating
bind = $mainMod, F, fullscreen
bind = $mainMod, P, pseudo
bind = $mainMod, T, togglesplit
bindr = $mainMod, Tab, exec, pkill rofi || $menu
# bindr = $mainMod Shift, P, exec, pkill hyprpicker || $picker
# bindr = $mainMod Shift, C, exec, pkill rofi || $calc
bindr = $mainMod Shift, T, exec, pkill rofi || $toggles
bindr = $mainMod Shift, R, exec, pkill rofi || $power
bindr = $mainMod, E, exec, pkill rofi || $browser
bindr = $mainMod, N, exec, pkill rofi || $notes
# bindr = $mainMod Shift, M, exec, pkill rofi || $emoji
bindr = $mainMod Shift, Y, exec, pkill rofi || $scripts/runner
bindr = $mainMod, D, exec, pkill rofi || $actions
bindr = $mainMod Shift, W, exec, $move
bindr = $mainMod, W, exec, $move --same
bind = $mainMod, M, exec, pkill rmpc || kitty +kitten panel --edge center --layer overlay --focus-policy on-demand --margin-top 60 --margin-bottom 800 --margin-right 1200 --margin-left 22 rmpc
bind = $mainMod Shift, N, exec, $notifications
bind = $mainMod, A, exec, $special_workspace_per_workspace
bind = $mainMod SHIFT, A, exec, $move_to_special_workspace_per_workspace
# Switch current workspaces with mainMod + [0-9]
bind = $mainMod, 1, workspace, 1
bind = $mainMod, 2, workspace, 2
bind = $mainMod, 3, workspace, 3
bind = $mainMod, 4, workspace, 4
bind = $mainMod, 5, workspace, 5
bind = $mainMod, 6, workspace, 6
bind = $mainMod, 7, workspace, 7
bind = $mainMod, 8, workspace, 8
bind = $mainMod, 9, workspace, 9
bind = $mainMod, 0, workspace, 10
# Move a focused window to a workspace with mainMod + SHIFT + [0-9]
bind = $mainMod SHIFT, 1, movetoworkspace, 1
bind = $mainMod SHIFT, 2, movetoworkspace, 2
bind = $mainMod SHIFT, 3, movetoworkspace, 3
bind = $mainMod SHIFT, 4, movetoworkspace, 4
bind = $mainMod SHIFT, 5, movetoworkspace, 5
bind = $mainMod SHIFT, 6, movetoworkspace, 6
bind = $mainMod SHIFT, 7, movetoworkspace, 7
bind = $mainMod SHIFT, 8, movetoworkspace, 8
bind = $mainMod SHIFT, 9, movetoworkspace, 9
bind = $mainMod SHIFT, 0, movetoworkspace, 10
# Move focus with mainMod + arrow keys
bind = $mainMod, left, movefocus, l
bind = $mainMod, right, movefocus, r
bind = $mainMod, up, movefocus, u
bind = $mainMod, down, movefocus, d
bind = $mainMod, h, movefocus, l
bind = $mainMod, j, movefocus, r
bind = $mainMod, k, movefocus, u
bind = $mainMod, l, movefocus, d
bind = $mainMod, S, togglespecialworkspace, magic
bind = $mainMod SHIFT, S, movetoworkspace, special:magic
# Scroll through existing workspaces with mainMod + scroll
bind = $mainMod, mouse_down, workspace, e+1
bind = $mainMod, mouse_up, workspace, e-1
# Move and Resize windows with mainMod + LMB/RMB and dragging, drag on edges to resize.
bindm = $mainMod, mouse:272, movewindow
bindm = $mainMod, mouse:273, resizewindow
# Laptop multimedia keys for volume and LCD brightness
bindel = ,XF86AudioRaiseVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+
bindel = ,XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
bindel = ,XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
bindel = ,XF86AudioMicMute, exec, wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle
bindel = ,XF86MonBrightnessUp, exec, brightnessctl s 10%+
bindel = ,XF86MonBrightnessDown, exec, brightnessctl s 10%-
# !!WINDOW RULES!! #
# --------------------------------------------------------------------------------- #
# !!WINDOW RULES!! #
# Read https://wiki.hyprland.org/Configuring/Window-Rules/ for more info
# Read https://wiki.hyprland.org/Configuring/Workspace-Rules/ for more info
layerrule {
name = layerrule-1
blur = on
match:namespace = rofi
}
layerrule {
name = layerrule-2
ignore_alpha = 0.01
match:namespace = rofi # This is so entirely transparent things aren't blurred.
}
# Add blur to waybar, for same reason as above. Since we have two versions
# of the waybar design, one with translucency.
layerrule {
name = layerrule-3
blur = on
blur_popups = on
match:namespace = waybar
}
layerrule {
name = layerrule-4
ignore_alpha = 1.0
match:namespace = waybar # this is so entirely transparent things aren't blurred.
}
# Add blur to eww widgets
layerrule {
name = layerrule-5
blur = on
blur_popups = on
ignore_alpha = 0.01
match:namespace = eww
}
# Fix dragging issues with XWayland
windowrule {
name = windowrule-1
no_focus = on
match:class = ^$
match:title = ^$
match:xwayland = 1
match:float = 1
match:fullscreen = 0
match:pin = 0
}
# -------------CUSTOMIZE BELOW------------------------
# Discord
windowrule {
name = windowrule-2
float = on
size = 1200 800
move = (200) (100)
workspace = special:magic
no_screen_share = on
match:class = ^(discord)$
}
# File manager + archiver
windowrule {
name = windowrule-3
float = on
center = on
size = 971 670
opacity = 0.8 0.7
match:class = .*(?i)(thunar)$
}
windowrule {
name = windowrule-4
float = on
center = on
size = 971 670
opacity = 0.8 0.7
match:class = ^(xarchiver)$
}
windowrule {
name = windowrule-5
float = on
center = on
size = 568 138
match:title = ^(File\ Operation\ Progress)$
}
windowrule {
name = windowrule-6
float = on
center = on
size = 971 670
opacity = 0.8 0.7
match:title = ^(Open.*)$
}
# XDG Portal
windowrule {
name = windowrule-7
float = on
center = on
size = 971 670
opacity = 0.8 0.7
match:class = ^(xdg-desktop-portal-gtk)$
}
# Runelite
windowrule {
name = windowrule-8
float = on
match:title = ^(RuneLite)$
}
# Notes dmenu app
windowrule {
name = windowrule-9
float = on
center = on
size = (monitor_w*0.2) (monitor_h*0.25)
opacity = 0.8 0.7
match:class = ^(notes)$
}
# Opacity rules
windowrule {
name = windowrule-10
opacity = 0.8 0.7
match:class = ^(kitty)$
}
windowrule {
name = windowrule-11
opacity = 0.8 0.7
match:class = ^(steam)$
}
windowrule {
name = windowrule-12
opacity = 0.8 0.7
match:class = ^(PrismLauncher)$
}
windowrule {
name = windowrule-13
float = on
match:class = ^(steam)$
match:title = ^(Friends\ List)$
}
windowrule {
name = windowrule-14
float = on
opacity = 0.8 0.7
match:class = ^(io.lampnet.*)$
}
windowrule {
name = windowrule-15
float = on
size = 1496 790
match:title = ^(System Update)$
}
windowrule {
name = windowrule-16
float = on
match:class = ^(mpv)$
}
windowrule {
name = windowrule-17
float = on
match:class = ^(feh)$
}
windowrule {
name = windowrule-18
border_size = 0
no_blur = on
no_shadow = on
match:class = ^(DeskPet)$
}
windowrule {
name = windowrule-19
float = on
move = 2240 54
match:title = ^(Photo\ Gallery)$
}
windowrule {
name = windowrule-20
float = on
move = 2240 54
match:title = ^(Music\ Controller)$
# no_blur = on
# no_shadow = on
}

View File

@ -0,0 +1,2 @@
monitor=DP-1, 2560x1440@144, 0x0, 1
monitor=DP-3, 1920x1080@144, -1920x150, 1

257
.config/hypr/scripts/actions.sh Executable file
View File

@ -0,0 +1,257 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT=$(basename "$0")
BASE_LAUNCHER=('rofi' '-theme-str' 'window {width: 20%;}' '-c' '-dmenu' '-i')
UPDATE_COMMAND="yay -Syu"
CURRENT_THEME=$(wpg -c)
THEME_LIST=$(wpg -l) # | grep -v "$CURRENT_THEME")
log() {
logger -i -t "$SCRIPT" "$*"
}
show_main_menu() {
local options="Services\nSystem\nTools\nPassword"
echo -e "$options" | "${BASE_LAUNCHER[@]}" -l "$(echo -e "$options" | wc -l)" -p "Menu:"
}
show_system_menu() {
local options="Update\nRefresh Mirrors\nPurge Cache"
echo -e "$options" | "${BASE_LAUNCHER[@]}" -l "$(echo -e "$options" | wc -l)" -p "System:"
}
show_tools_menu() {
local options="Calculator\nClipboard\nColor Picker\nScreenshot\nSymbols\nTheme"
echo -e "$options" | "${BASE_LAUNCHER[@]}" -l "$(echo -e "$options" | wc -l)" -p "Tools:"
}
show_screenshot_menu() {
local options="Fullscreen\nSelection"
echo -e "$options" | "${BASE_LAUNCHER[@]}" -l "$(echo -e "$options" | wc -l)" -p "Screenshot:"
}
handle_update() {
local update_script="$UPDATE_COMMAND && echo 'Update completed successfully!' || { echo 'Update failed! Press any key to close...'; read -n 1; }"
$TERMINAL --title "System Update" -e bash -c "$update_script"
}
handle_refresh_mirrors() {
local mirror_script="sudo /usr/bin/reflector -c US -a 12 --sort rate --save /etc/pacman.d/mirrorlist && echo 'Mirrors refreshed successfully!' || { echo 'Mirror refresh failed! Press any key to close...'; read -n 1; }"
$TERMINAL --title "Refresh Mirrors" -e bash -c "$mirror_script"
}
handle_purge_cache() {
local purge_script="systemctl start paccache.service && systemctl start yaycache.service && localepurge && echo 'Cache purged successfully!' || { echo 'Cache purge failed! Press any key to close...'; read -n 1; }"
$TERMINAL --title "Purge Cache" -e bash -c "$purge_script"
}
handle_calculator() {
rofi -show calc -no-show-match -no-sort -i -theme-str 'window {width: 20%; height: 10%;}'
}
handle_clipboard() {
clipcat-menu
}
handle_colorpicker() {
sleep 0.5
hyprpicker 2>/dev/null | wl-copy
}
handle_screenshot() {
local screenshot_type
screenshot_type=$(show_screenshot_menu)
case "$screenshot_type" in
"Fullscreen")
sleep 0.5
local filename="$(date +%Y%m%d-%H%M%S).png"
local current_monitor
current_monitor=$(hyprctl cursorpos -j | jq -r '. as $cursor | hyprctl monitors -j | .[] | select(.x <= $cursor.x and $cursor.x < (.x + .width) and .y <= $cursor.y and $cursor.y < (.y + .height)) | .name' 2>/dev/null || hyprctl monitors -j | jq -r '.[0].name')
grim -o "$current_monitor" "$HOME/Pictures/Screenshots/$filename"
wl-copy < "$HOME/Pictures/Screenshots/$filename"
notify-send "Saved $filename"
;;
"Selection")
sleep 0.5
local filename="$(date +%Y%m%d-%H%M%S).png"
if slurp | grim -g - "$HOME/Pictures/Screenshots/$filename"; then
wl-copy < "$HOME/Pictures/Screenshots/$filename"
notify-send "Saved $filename"
else
return 0
fi
;;
"")
return 0
;;
*)
return 1
;;
esac
}
handle_symbols() {
rofi -modi "emoji:rofimoji" -show emoji -i -theme-str 'window {width: 20%; height: 12%;}'
}
handle_passwords() {
passwordmenu
}
handle_theme() {
if [[ -z "$THEME_LIST" ]]; then
log "No themes available"
return 1
fi
MONITORS=$(hyprctl monitors -j | jq -r '.[].name')
local monitor1
monitor1=$(echo "$MONITORS" | head -n 1)
local monitor2
monitor2=$(echo "$MONITORS" | tail -n 1)
local wallpaper_mode
wallpaper_mode=$(echo -e "Single\nDual" | "${BASE_LAUNCHER[@]}" -l 2 -p "Wallpaper:")
if [[ -z "$wallpaper_mode" ]]; then
return 0
fi
local theme_count
theme_count=$(echo "$THEME_LIST" | wc -l)
local selected_theme
selected_theme=$(echo "$THEME_LIST" | "${BASE_LAUNCHER[@]}" -l "$theme_count" -p "$CURRENT_THEME:")
if [[ -n "$selected_theme" && "$selected_theme" != "$CURRENT_THEME" ]]; then
if [[ "$wallpaper_mode" == "Dual" ]]; then
local second_wallpaper
second_wallpaper=$(echo "$THEME_LIST" | "${BASE_LAUNCHER[@]}" -l "$theme_count" -p "Second Wallpaper:")
if [[ -z "$second_wallpaper" ]]; then
return 0
fi
wpg -s "$selected_theme" -n || {
log "Failed to set theme: $selected_theme"
return 1
}
local wallpaper_conf="$XDG_CONFIG_HOME/hypr/wallpaper.conf"
sed -i "s|exec-once = swaybg -o $monitor1.*|exec-once = swaybg -o $monitor1 -m fill -i \$XDG_CONFIG_HOME/wpg/wallpapers/$selected_theme|" "$wallpaper_conf"
sed -i "s|exec-once = swaybg -o $monitor2.*|exec-once = swaybg -o $monitor2 -m fill -i \$XDG_CONFIG_HOME/wpg/wallpapers/$second_wallpaper|" "$wallpaper_conf"
pkill swaybg
swaybg -o "$monitor1" -i "$XDG_CONFIG_HOME/wpg/wallpapers/$selected_theme" -m fill &
swaybg -o "$monitor2" -i "$XDG_CONFIG_HOME/wpg/wallpapers/$second_wallpaper" -m fill &
log "Successfully set dual wallpapers: $selected_theme ($monitor1) and $second_wallpaper ($monitor2)"
else
wpg -s "$selected_theme" || {
log "Failed to set theme: $selected_theme"
return 1
}
local wallpaper_conf="$XDG_CONFIG_HOME/hypr/wallpaper.conf"
sed -i "s|exec-once = swaybg -o $monitor1.*|exec-once = swaybg -o $monitor1 -m fill -i \$XDG_CONFIG_HOME/wpg/wallpapers/\$(wpg -c)|" "$wallpaper_conf"
sed -i "s|exec-once = swaybg -o $monitor2.*|exec-once = swaybg -o $monitor2 -m fill -i \$XDG_CONFIG_HOME/wpg/wallpapers/\$(wpg -c)|" "$wallpaper_conf"
pkill swaybg
swaybg -o "$monitor1" -i "$XDG_CONFIG_HOME/wpg/wallpapers/$selected_theme" -m fill &
swaybg -o "$monitor2" -i "$XDG_CONFIG_HOME/wpg/wallpapers/$selected_theme" -m fill &
log "Successfully changed theme to: $selected_theme"
fi
fi
}
handle_system() {
local system_action
system_action=$(show_system_menu)
case "$system_action" in
"Update")
handle_update
;;
"Refresh Mirrors")
handle_refresh_mirrors
;;
"Purge Cache")
handle_purge_cache
;;
"")
return 0
;;
*)
log "Unknown system action: $system_action"
return 1
;;
esac
}
handle_tools() {
local tools_action
tools_action=$(show_tools_menu)
case "$tools_action" in
"Calculator")
handle_calculator
;;
"Clipboard")
handle_clipboard
;;
"Color Picker")
handle_colorpicker
;;
"Screenshot")
handle_screenshot
;;
"Symbols")
handle_symbols
;;
"Theme")
handle_theme
;;
"")
return 0
;;
*)
log "Unknown tools action: $tools_action"
return 1
;;
esac
}
main() {
local action
action=$(show_main_menu)
case "$action" in
"Services")
uuctl
;;
"System")
handle_system
;;
"Tools")
handle_tools
;;
"Password")
handle_passwords
;;
"")
exit 0
;;
*)
log "Unknown action: $action"
exit 1
;;
esac
}
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi

110
.config/hypr/scripts/find_song.sh Executable file
View File

@ -0,0 +1,110 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT=$(basename "$0")
LAUNCHER=('rofi' '-theme-str' 'window {width: 20%;}' '-dmenu' '-c' '-l' '4' '-p')
MUSIC_DIR="${XDG_MUSIC_DIR:-$HOME/Music}"
if [[ ! -d "$MUSIC_DIR" ]]; then
notify-send -u critical "Error" "Music directory not found: $MUSIC_DIR"
exit 1
fi
music_files=$(find -L "$MUSIC_DIR" -type f \( \
-iname "*.mp3" -o \
-iname "*.flac" -o \
-iname "*.wav" -o \
-iname "*.ogg" -o \
-iname "*.m4a" -o \
-iname "*.aac" -o \
-iname "*.opus" -o \
-iname "*.wma" \
\) 2>/dev/null | sed "s|^$MUSIC_DIR/||")
list_archive_music() {
local archive_path="$1"
local archive_rel_path="$2"
local music_pattern='\.(mp3|flac|wav|ogg|m4a|aac|opus|wma)$'
case "${archive_path,,}" in
*.zip)
if command -v unzip >/dev/null 2>&1; then
unzip -l "$archive_path" 2>/dev/null | \
awk 'NR>3 {print $NF}' | \
grep -iE "$music_pattern" | \
sed "s|^|$archive_rel_path/|"
fi
;;
*.rar)
if command -v unrar >/dev/null 2>&1; then
unrar lb "$archive_path" 2>/dev/null | \
grep -iE "$music_pattern" | \
sed "s|^|$archive_rel_path/|"
fi
;;
*.7z)
if command -v 7z >/dev/null 2>&1; then
7z l -slt "$archive_path" 2>/dev/null | \
awk '/^Path = / {print substr($0, 8)}' | \
grep -iE "$music_pattern" | \
sed "s|^|$archive_rel_path/|"
fi
;;
*.tar|*.tar.gz|*.tar.bz2|*.tar.xz)
if command -v tar >/dev/null 2>&1; then
tar -tf "$archive_path" 2>/dev/null | \
grep -iE "$music_pattern" | \
sed "s|^|$archive_rel_path/|"
fi
;;
esac
}
archive_music_files=""
while IFS= read -r -d '' archive_file; do
archive_rel_path=$(echo "$archive_file" | sed "s|^$MUSIC_DIR/||")
archive_music=$(list_archive_music "$archive_file" "$archive_rel_path")
if [[ -n "$archive_music" ]]; then
archive_music_files="$archive_music_files$archive_music"$'\n'
fi
done < <(find -L "$MUSIC_DIR" -type f \( \
-iname "*.zip" -o \
-iname "*.rar" -o \
-iname "*.7z" -o \
-iname "*.tar" -o \
-iname "*.tar.gz" -o \
-iname "*.tar.bz2" -o \
-iname "*.tar.xz" \
\) -print0 2>/dev/null)
all_music_files=""
if [[ -n "$music_files" ]]; then
all_music_files="$music_files"
fi
if [[ -n "$archive_music_files" ]]; then
if [[ -n "$all_music_files" ]]; then
all_music_files="$all_music_files"$'\n'"$archive_music_files"
else
all_music_files="$archive_music_files"
fi
fi
all_music_files=$(echo "$all_music_files" | grep -v '^$' | sort)
if [[ -z "$all_music_files" ]]; then
notify-send -u normal "Info" "No music files found in $MUSIC_DIR"
exit 0
fi
selection=$(echo "$all_music_files" | "${LAUNCHER[@]}" "Select song:")
if [[ -z "$selection" ]]; then
exit 0
fi
if rmpc add "$selection"; then
notify-send -u normal "Music" "Added: $(basename "$selection")"
else
notify-send -u critical "Error" "Failed to add: $(basename "$selection")"
exit 1
fi

100
.config/hypr/scripts/move.sh Executable file
View File

@ -0,0 +1,100 @@
#!/usr/bin/env bash
set -uo pipefail
SAME_MONITOR=0
while [ $# -gt 0 ]; do
case "$1" in
--same)
SAME_MONITOR=1
shift
;;
*)
shift
;;
esac
done
WINDOWS=$(hyprctl activewindow -j)
MONITORS=$(hyprctl monitors -j)
WORKSPACES=$(hyprctl workspaces -j)
ACTIVE_WORKSPACE=$(hyprctl activeworkspace -j)
CURRENT_WS_ID=$(echo "$WINDOWS" | jq '.workspace.id')
CURRENT_MONITOR=$(echo "$WINDOWS" | jq -r '.monitor')
CURRENT_NAME=$(echo "$MONITORS" | jq -r ".[$CURRENT_MONITOR].name")
ACTIVE_WS_ID=$(echo "$ACTIVE_WORKSPACE" | jq -r '.id')
TARGET_INDEX=$CURRENT_MONITOR
if [[ $SAME_MONITOR -eq 0 ]]; then
TARGET_INDEX=$((1 - CURRENT_MONITOR))
fi
TARGET=$(echo "$MONITORS" | jq -r ".[$TARGET_INDEX].name")
next_empty_workspace() {
local start_search_id=$1
local current_workspaces=$2
local i=$start_search_id
while jq -e ".[] | select(.id == $i)" <<< "$current_workspaces" > /dev/null; do
i=$((i + 1))
done
echo "$i"
}
check_current_workspaces() {
local target_monitor_name=$1
local ws_json=$2
echo "$ws_json" | jq -r --arg tmn "$target_monitor_name" '
[ .[] | select(.monitor == $tmn and .windows == 0) ] |
if length > 0 then (min_by(.id) | .id) else empty end
'
}
NEW_WORKSPACE=""
if [[ $CURRENT_MONITOR -eq 0 && $SAME_MONITOR -eq 1 ]]; then
if ! jq -e '.[] | select(.id == 2 and .windows > 0)' <<< "$WORKSPACES" > /dev/null; then
NEW_WORKSPACE=2
fi
fi
if [[ -z "$NEW_WORKSPACE" ]]; then
CANDIDATE_WS_ON_MONITOR=$(check_current_workspaces "$TARGET" "$WORKSPACES")
if [[ -n "$CANDIDATE_WS_ON_MONITOR" ]]; then
NEW_WORKSPACE="$CANDIDATE_WS_ON_MONITOR"
fi
fi
if [[ -z "$NEW_WORKSPACE" ]]; then
_START_FIND_ID=1
if [[ $CURRENT_MONITOR -eq 0 && $SAME_MONITOR -eq 0 ]]; then
_START_FIND_ID=2
fi
NEW_WORKSPACE=$(next_empty_workspace "$_START_FIND_ID" "$WORKSPACES")
fi
DEFAULT_WORKSPACE=$((CURRENT_MONITOR + 1))
FLOATING_ADDRESS=$(echo "$WINDOWS" | jq -r 'select(.floating == true) | .address // empty')
if [[ -n "$FLOATING_ADDRESS" ]]; then
hyprctl dispatch "togglefloating address:$FLOATING_ADDRESS"
fi
NO_WINDOWS=$(echo "$WORKSPACES" | jq ".[] | select(.id == $CURRENT_WS_ID) | .windows // 0")
hyprctl dispatch movewindow mon:"$TARGET"
hyprctl dispatch movetoworkspace "$NEW_WORKSPACE"
if [[ $CURRENT_WS_ID -lt 0 ]]; then
# Don't change workspaces when moving from a negative workspace ID
hyprctl dispatch workspace "$ACTIVE_WS_ID"
elif [[ $SAME_MONITOR -eq 1 ]]; then
hyprctl dispatch workspace "$NEW_WORKSPACE"
elif [[ $NO_WINDOWS -eq 1 ]]; then
hyprctl dispatch focusmonitor "$CURRENT_NAME"
hyprctl dispatch workspace "$DEFAULT_WORKSPACE"
else
hyprctl dispatch workspace "$CURRENT_WS_ID"
fi

100
.config/hypr/scripts/notes.sh Executable file
View File

@ -0,0 +1,100 @@
#!/usr/bin/env bash
set -uo pipefail
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
LAUNCHER=('rofi' '-kb-custom-1' 'Alt+d' '-kb-custom-2' 'Alt+n' '-kb-custom-3' 'Alt+e' '-theme-str' 'window {width: 20%;}' '-dmenu' '-c' '-l' '10' '-p')
NOTESDIR="${XDG_DOCUMENTS_DIR:-$HOME/.notes}"
mkdir -p "$NOTESDIR"
newnote() {
local NAME
NAME=$(printf "%s" "$(find "$NOTESDIR" -maxdepth 1 -type f -printf '%T@ %f\n' | sort -rn | cut -d' ' -f2-)" | \
"${LAUNCHER[@]}" "new:" | xargs)
if [[ -z "$NAME" ]]; then
return 1
fi
touch "${NOTESDIR}/${NAME}"
main
}
opennote() {
local NOTE="$1"
$TERMINAL --class notes "$EDITOR" "${NOTESDIR}/${NOTE}"
main
}
deletenote() {
local NOTE="${1:-}"
if [[ -z "$NOTE" ]]; then
NOTE=$(find "$NOTESDIR" -maxdepth 1 -type f -printf '%T@ %f\n' | sort -rn | cut -d' ' -f2- | \
"${LAUNCHER[@]}" "delete:")
fi
[[ -z "$NOTE" ]] && return 1
local CONFIRM
CONFIRM=$(printf "%s\n%s\n" "no" "yes" | \
"${LAUNCHER[@]}" "delete ${NOTE}:")
if [[ "$CONFIRM" == "yes" ]]; then
rm "${NOTESDIR}/${NOTE}"
echo "Deleted ${NOTE}"
fi
main
}
editnote() {
local NOTE="${1:-}"
NAME=$(echo "" | \
"${LAUNCHER[@]}" 'edit:' -filter "$NOTE" -matching prefix)
if [[ -z "$NAME" ]]; then
main
fi
if [[ "${NOTE}" != "${NAME}" ]]; then
mv "${NOTESDIR}/${NOTE}" "${NOTESDIR}/${NAME}"
fi
main
}
main() {
local CHOICE
CHOICE=$(printf "%s" "$(find "$NOTESDIR" -maxdepth 1 -type f -printf '%T@ %f\n' | sort -rn | cut -d' ' -f2-)" | \
"${LAUNCHER[@]}" "notes:")
local EXITCODE=$?
case $EXITCODE in
0) # Enter pressed
case "$CHOICE" in
*) opennote "$CHOICE" ;;
esac
;;
10) # Delete pressed
case "$CHOICE" in
*) deletenote "$CHOICE" ;;
esac
;;
11) # New pressed
case "$CHOICE" in
*) newnote ;;
esac
;;
12)
case "$CHOICE" in
*) editnote "$CHOICE";;
esac
;;
1) # Escape pressed
exit 0
;;
esac
}
main

30
.config/hypr/scripts/power.sh Executable file
View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT=$(basename "$0")
LAUNCHER=('rofi' '-theme-str' 'window {width: 20%;}' '-dmenu' '-c' '-l' '3' '-p')
log() {
logger -i -t "$SCRIPT" "$*"
}
main() {
local CHOICE
CHOICE=$(printf "sleep\nrestart\nshutdown" | "${LAUNCHER[@]}" "power:")
local EXITCODE=$?
case $EXITCODE in
0)
case "$CHOICE" in
"sleep") systemctl suspend;;
"restart") reboot;;
"shutdown") notify-send "Shutdown in 1 minute!" && shutdown;;
esac
;;
1)
exit 0
;;
esac
}
main

View File

@ -0,0 +1,2 @@
exec-once = swaybg -o DP-1 -m fill -i $XDG_CONFIG_HOME/wpg/wallpapers/monk.png
exec-once = swaybg -o DP-3 -m fill -i $XDG_CONFIG_HOME/wpg/wallpapers/river.jpg

3
.config/hypr/xdph.conf Normal file
View File

@ -0,0 +1,3 @@
screencopy {
allow_token_by_default = true
}

2666
.config/kitty/kitty.conf Normal file

File diff suppressed because it is too large Load Diff

403
.config/mpd/mpd.conf Normal file
View File

@ -0,0 +1,403 @@
# An example configuration file for MPD.
# Read the user manual for documentation: http://www.musicpd.org/doc/user/
# Files and directories #######################################################
#
# This setting controls the top directory which MPD will search to discover the
# available audio files and add them to the daemon's online database. This
# setting defaults to the XDG directory, otherwise the music directory will be
# be disabled and audio files will only be accepted over ipc socket (using
# file:// protocol) or streaming files over an accepted protocol.
#
#music_directory "$XDG_MUSIC_DIR"
music_directory "$XDG_MUSIC_DIR"
#
# This setting sets the MPD internal playlist directory. The purpose of this
# directory is storage for playlists created by MPD. The server will use
# playlist files not created by the server but only if they are in the MPD
# format. This setting defaults to playlist saving being disabled.
#
playlist_directory "$XDG_CONFIG_HOME/mpd/playlists"
#playlist_directory "~/.mpd/playlists"
#
# This setting sets the location of the MPD database. This file is used to
# load the database at server start up and store the database while the
# server is not up. This setting defaults to disabled which will allow
# MPD to accept files over ipc socket (using file:// protocol) or streaming
# files over an accepted protocol.
#
db_file "$XDG_CACHE_HOME/mpd/database"
#db_file "~/.mpd/database"
# These settings are the locations for the daemon log files for the daemon.
#
# The special value "syslog" makes MPD use the local syslog daemon. This
# setting defaults to logging to syslog.
#
# If you use systemd, do not configure a log_file. With systemd, MPD
# defaults to the systemd journal, which is fine.
#
#log_file "$XDG_CACHE_HOME/mpd/log"
#log_file "~/.mpd/log"
# This setting sets the location of the file which stores the process ID
# for use of mpd --kill and some init scripts. This setting is disabled by
# default and the pid file will not be stored.
#
# If you use systemd, do not configure a pid_file.
#
pid_file "$XDG_RUNTIME_DIR/mpd/mpd.pid"
#pid_file "~/.mpd/pid"
# This setting sets the location of the file which contains information about
# most variables to get MPD back into the same general shape it was in before
# it was brought down. This setting is disabled by default and the server
# state will be reset on server start up.
#
#state_file "$XDG_RUNTIME_DIR/mpd/state"
#state_file "~/.mpd/state"
#
# The location of the sticker database. This is a database which
# manages dynamic information attached to songs.
#
sticker_file "$XDG_CACHE_HOME/sticker.sql"
#sticker_file "~/.mpd/sticker.sql"
#
###############################################################################
# General music daemon options ################################################
#
# This setting specifies the user that MPD will run as. MPD should never run as
# root and you may use this setting to make MPD change its user ID after
# initialization. This setting is disabled by default and MPD is run as the
# current user.
#
#user "nobody"
#
# This setting specifies the group that MPD will run as. If not specified
# primary group of user specified with "user" setting will be used (if set).
# This is useful if MPD needs to be a member of group such as "audio" to
# have permission to use sound card.
#
#group "nogroup"
#
# This setting sets the address for the daemon to listen on. Careful attention
# should be paid if this is assigned to anything other than the default, any.
# This setting can deny access to control of the daemon. Not effective if
# systemd socket activation is in use.
#
# For network
bind_to_address "localhost"
#
# And for Unix Socket
#bind_to_address "$XDG_RUNTIME_DIR/mpd/socket"
#bind_to_address "~/.mpd/socket"
#
# This setting is the TCP port that is desired for the daemon to get assigned
# to.
#
port "6600"
#
# Suppress all messages below the given threshold. Use "verbose" for
# troubleshooting. Available setting arguments are "notice", "info", "verbose",
# "warning" and "error".
#
#log_level "notice"
#
# Setting "restore_paused" to "yes" puts MPD into pause mode instead
# of starting playback after startup.
#
#restore_paused "no"
#
# This setting enables MPD to create playlists in a format usable by other
# music players.
#
#save_absolute_paths_in_playlists "no"
#
# This setting defines a list of tag types that will be extracted during the
# audio file discovery process. The complete list of possible values can be
# found in the user manual.
#metadata_to_use "artist,album,title,track,name,genre,date,composer,performer,disc"
#
# This example just enables the "comment" tag without disabling all
# the other supported tags:
#metadata_to_use "+comment"
#
# This setting enables automatic update of MPD's database when files in
# music_directory are changed.
#
auto_update "yes"
#
# Limit the depth of the directories being watched, 0 means only watch
# the music directory itself. There is no limit by default.
#
#auto_update_depth "3"
#
###############################################################################
# Symbolic link behavior ######################################################
#
# If this setting is set to "yes", MPD will discover audio files by following
# symbolic links outside of the configured music_directory.
#
follow_outside_symlinks "yes"
#
# If this setting is set to "yes", MPD will discover audio files by following
# symbolic links inside of the configured music_directory.
#
follow_inside_symlinks "yes"
#
###############################################################################
# Zeroconf / Avahi Service Discovery ##########################################
#
# If this setting is set to "yes", service information will be published with
# Zeroconf / Avahi.
#
#zeroconf_enabled "yes"
#
# The argument to this setting will be the Zeroconf / Avahi unique name for
# this MPD server on the network. %h will be replaced with the hostname.
#
#zeroconf_name "Music Player @ %h"
#
###############################################################################
# Permissions #################################################################
#
# If this setting is set, MPD will require password authorization. The password
# setting can be specified multiple times for different password profiles.
#
#password "password@read,add,control,admin"
#
# This setting specifies the permissions a user has who has not yet logged in.
#
#default_permissions "read,add,control,admin"
#
###############################################################################
# Database #######################################################################
#
# An example of a database section instead of the old 'db_file' setting.
# It enables mounting other storages into the music directory.
#
#database {
# plugin "simple"
# path "~/.local/share/mpd/db"
# cache_directory "~/.local/share/mpd/cache"
#}
#
# An example of database config for a satellite setup
#
#music_directory "nfs://fileserver.local/srv/mp3"
#database {
# plugin "proxy"
# host "other.mpd.host"
# port "6600"
#}
# Input #######################################################################
#
input {
plugin "curl"
# proxy "proxy.isp.com:8080"
# proxy_user "user"
# proxy_password "password"
}
#
###############################################################################
# Audio Output ################################################################
#
# MPD supports various audio output types, as well as playing through multiple
# audio outputs at the same time, through multiple audio_output settings
# blocks. Setting this block is optional, though the server will only attempt
# autodetection for one sound card.
#
# An example of an ALSA output:
#
audio_output {
type "pulse"
name "My ALSA Device"
# device "hw:0,0" # optional
mixer_type "hardware" # optional
## mixer_device "default" # optional
## mixer_control "PCM" # optional
## mixer_index "0" # optional
}
#
# An example of an OSS output:
#
#audio_output {
# type "oss"
# name "My OSS Device"
## device "/dev/dsp" # optional
## mixer_type "hardware" # optional
## mixer_device "/dev/mixer" # optional
## mixer_control "PCM" # optional
#}
#
# An example of a shout output (for streaming to Icecast):
#
#audio_output {
# type "shout"
# encoder "vorbis" # optional
# name "My Shout Stream"
# host "localhost"
# port "8000"
# mount "/mpd.ogg"
# password "hackme"
# quality "5.0"
# bitrate "128"
# format "44100:16:1"
## protocol "icecast2" # optional
## user "source" # optional
## description "My Stream Description" # optional
## url "http://example.com" # optional
## genre "jazz" # optional
## public "no" # optional
## timeout "2" # optional
## mixer_type "software" # optional
#}
#
# An example of a recorder output:
#
#audio_output {
# type "recorder"
# name "My recorder"
# encoder "vorbis" # optional, vorbis or lame
# path "/var/lib/mpd/recorder/mpd.ogg"
## quality "5.0" # do not define if bitrate is defined
# bitrate "128" # do not define if quality is defined
# format "44100:16:1"
#}
#
# An example of a httpd output (built-in HTTP streaming server):
#
#audio_output {
# type "httpd"
# name "My HTTP Stream"
# encoder "vorbis" # optional, vorbis or lame
# port "8000"
# bind_to_address "0.0.0.0" # optional, IPv4 or IPv6
## quality "5.0" # do not define if bitrate is defined
# bitrate "128" # do not define if quality is defined
# format "44100:16:1"
# max_clients "0" # optional 0=no limit
#}
#
# An example of a pulseaudio output (streaming to a remote pulseaudio server)
#
#audio_output {
# type "pulse"
# name "My Pulse Output"
# mixer_type "software"
## server "remote_server" # optional
## sink "remote_server_sink" # optional
## media_role "media_role" #optional
#}
#
# An example of a winmm output (Windows multimedia API).
#
#audio_output {
# type "winmm"
# name "My WinMM output"
## device "Digital Audio (S/PDIF) (High Definition Audio Device)" # optional
# or
## device "0" # optional
## mixer_type "hardware" # optional
#}
#
# An example of a wasapi output (Windows multimedia API).
#
#audio_output {
# type "wasapi"
# name "My WASAPI output"
## device "Digital Audio (S/PDIF) (High Definition Audio Device)" # optional
# or
## device "0" # optional
## mixer_type "hardware" # optional
## Exclusive mode blocks all other audio source, and get best audio quality without resampling.
## exclusive "no" # optional
## Enumerate all devices in log.
## enumerate "no" # optional
#}
#
# An example of an openal output.
#
#audio_output {
# type "openal"
# name "My OpenAL output"
## device "Digital Audio (S/PDIF) (High Definition Audio Device)" # optional
#}
#
# An example of an sndio output.
#
#audio_output {
# type "sndio"
# name "sndio output"
# mixer_type "hardware"
#}
#
# An example of an OS X output:
#
#audio_output {
# type "osx"
# name "My OS X Device"
## device "Built-in Output" # optional
## channel_map "-1,-1,0,1" # optional
#}
#
## Example "pipe" output:
#
#audio_output {
# type "pipe"
# name "my pipe"
# command "aplay -f cd 2>/dev/null"
## Or if you're want to use AudioCompress
# command "AudioCompress -m | aplay -f cd 2>/dev/null"
## Or to send raw PCM stream through PCM:
# command "nc example.org 8765"
# format "44100:16:2"
#}
#
## An example of a null output (for no audio output):
#
#audio_output {
# type "null"
# name "My Null Output"
# mixer_type "none" # optional
#}
#
###############################################################################
# Normalization automatic volume adjustments ##################################
#
# This setting specifies the type of ReplayGain to use. This setting can have
# the argument "off", "album", "track" or "auto". "auto" is a special mode that
# chooses between "track" and "album" depending on the current state of
# random playback. If random playback is enabled then "track" mode is used.
# See <https://wiki.hydrogenaud.io/index.php?title=Replaygain> for
# more details about ReplayGain.
# This setting is off by default.
#
#replaygain "album"
#
###############################################################################
# Character Encoding ##########################################################
#
# If file or directory names do not display correctly for your locale then you
# may need to modify this setting.
#
#filesystem_charset "UTF-8"
#
###############################################################################

463
.config/quickshell/Bar.qml Normal file
View File

@ -0,0 +1,463 @@
import Quickshell
import Quickshell.Hyprland
import Quickshell.Widgets
import Quickshell.Services.SystemTray
import Quickshell.Io
import QtQuick
PanelWindow {
id: bar
required property var walColors
required property string motd
required property int notificationCount
required property var latestNotification
property var notifServer: null
required property SystemStats stats
required property string fontFamily
// --- Notification toast state ---
property int _toastCounter: 0
onLatestNotificationChanged: {
if (latestNotification) {
toastModel.append({
toastId: _toastCounter++,
appName: latestNotification.appName || "",
summary: latestNotification.summary || "",
body: latestNotification.body || ""
})
}
}
ListModel {
id: toastModel
}
anchors {
top: true
left: true
right: true
}
color: "transparent"
exclusionMode: ExclusionMode.Normal
exclusiveZone: 34
implicitHeight: 34
// --- Theme colors ---
property color bgColor: (walColors.special && walColors.special.background) ? walColors.special.background : "#1d160d"
property color fgColor: (walColors.special && walColors.special.foreground) ? walColors.special.foreground : "#d8d8d3"
property color accentColor: (walColors.colors && walColors.colors.color1) ? walColors.colors.color1 : "#946F50"
property color accent2Color: (walColors.colors && walColors.colors.color2) ? walColors.colors.color2 : "#BA9351"
property color accent3Color: (walColors.colors && walColors.colors.color3) ? walColors.colors.color3 : "#BA9351"
property color accent4Color: (walColors.colors && walColors.colors.color4) ? walColors.colors.color4 : "#BA9351"
property color accent5Color: (walColors.colors && walColors.colors.color5) ? walColors.colors.color5 : "#BA9351"
property color accent6Color: (walColors.colors && walColors.colors.color6) ? walColors.colors.color6 : "#BA9351"
property color accent7Color: (walColors.colors && walColors.colors.color7) ? walColors.colors.color7 : "#BA9351"
// --- Hyprland state ---
property var hyprMonitor: Hyprland.monitorFor(screen)
property var monitorWorkspaces: {
let vals = Hyprland.workspaces.values
let result = []
for (let i = 0; i < vals.length; i++) {
if (vals[i].monitor === hyprMonitor && vals[i].id > 0)
result.push(vals[i])
}
return result.sort((a, b) => a.id - b.id)
}
property bool specialWorkspaceVisible: false
Connections {
target: Hyprland
function onRawEvent(event) {
if (event.name === "activespecial") {
let parts = event.data.split(",")
let monName = parts[parts.length - 1]
if (monName === hyprMonitor?.name) {
bar.specialWorkspaceVisible = parts[0] !== ""
}
}
}
}
property string windowTitle: {
let title = Hyprland.activeToplevel?.title ?? ""
if (!title || title === "~" || title === "kitty" || title === "fish")
return motd
return title
}
// --- Clock ---
SystemClock {
id: clock
precision: SystemClock.Minutes
}
// --- Bar layout ---
Item {
anchors.fill: parent
anchors.margins: 2
// Left module group
Rectangle {
id: leftGroup
z: 1
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
height: 30
width: leftContent.width + 8
clip: true
color: bar.bgColor
border.color: bar.accentColor
border.width: 2
radius: 100
Behavior on width {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Row {
id: leftContent
anchors.left: parent.left
anchors.leftMargin: 4
anchors.verticalCenter: parent.verticalCenter
spacing: 0
Workspaces {
workspaces: bar.monitorWorkspaces
accentColor: bar.accentColor
fgColor: bar.fgColor
fontFamily: bar.fontFamily
anchors.verticalCenter: parent.verticalCenter
}
}
}
// Special workspace badge
Rectangle {
id: specialBadge
z: 0
anchors.verticalCenter: leftGroup.verticalCenter
height: 28
width: specialText.implicitWidth + (bar.specialWorkspaceVisible ? 30 : 10)
topLeftRadius: 0
bottomLeftRadius: 0
topRightRadius: 100
bottomRightRadius: 100
color: bar.bgColor
border.color: bar.accentColor
border.width: 2
visible: bar.specialWorkspaceVisible
x: bar.specialWorkspaceVisible ? leftGroup.x + leftGroup.width - 10 : leftGroup.x + leftGroup.width - specialBadge.width
Behavior on x {
NumberAnimation { duration: 200; easing.type: Easing.InOutCubic }
}
Behavior on width {
NumberAnimation { duration: 200; easing.type: Easing.InOutCubic }
}
Text {
id: specialText
anchors.centerIn: parent
anchors.horizontalCenterOffset: 4
text: "\uf2d2"
color: bar.fgColor
font.pixelSize: 11
font.family: bar.fontFamily
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: Hyprland.dispatch("togglespecialworkspace magic")
}
}
// Center module group
Rectangle {
id: centerGroup
anchors.centerIn: parent
height: 30
width: centerContent.width + 16
clip: true
color: bar.bgColor
border.color: bar.accentColor
border.width: 2
radius: 100
Behavior on width {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Row {
id: centerContent
anchors.centerIn: parent
spacing: 12
Text {
text: bar.windowTitle
color: bar.fgColor
font.pixelSize: 13
font.family: bar.fontFamily
elide: Text.ElideRight
width: Math.min(implicitWidth, 900)
anchors.verticalCenter: parent.verticalCenter
}
}
}
// Notification toasts
Repeater {
model: toastModel
delegate: NotificationToast {
bgColor: bar.bgColor
fgColor: bar.fgColor
accentColor: bar.accentColor
fontFamily: bar.fontFamily
rightAnchor: rightGroup
sourceModel: toastModel
}
}
// Right module group
Rectangle {
id: rightGroup
z: 1
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
height: 30
width: rightContent.width + 8
clip: true
color: bar.bgColor
border.color: bar.accentColor
border.width: 2
radius: 100
Behavior on x {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Behavior on width {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Row {
id: rightContent
anchors.right: parent.right
anchors.rightMargin: 4
anchors.verticalCenter: parent.verticalCenter
spacing: 5
// Notification count
Item {
id: notifBadgeWrapper
property real targetWidth: bar.notificationCount > 0 ? notifCountText.implicitWidth + 16 : 0
height: 22
width: targetWidth
clip: true
anchors.verticalCenter: parent.verticalCenter
visible: width > 0
Behavior on width {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Rectangle {
anchors.left: parent.left
height: 22
width: notifCountText.implicitWidth + 16
topLeftRadius: 100
bottomLeftRadius: 100
radius: parent.visible ? 4 : 100
color: bar.accent7Color
Behavior on radius {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Text {
id: notifCountText
anchors.centerIn: parent
text: bar.notificationCount + " \uf0f3"
color: bar.bgColor
font.pixelSize: 13
font.family: bar.fontFamily
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
if (!bar.notifServer) return
let notifs = bar.notifServer.trackedNotifications.values
for (let i = notifs.length - 1; i >= 0; i--)
notifs[i].dismiss()
}
}
}
}
// Updates
BarPill {
id: updatesPill
fontFamily: bar.fontFamily
label: stats.updatesCount + (stats.updatesCount === 0 ? " \udb80\udca2" : " \udb84\udf77")
pillColor: bar.accent6Color
textColor: bar.bgColor
tooltipText: stats.updatesList || "Up to date"
topLeftRadius: bar.notificationCount > 0 ? 4 : 100
bottomLeftRadius: bar.notificationCount > 0 ? 4 : 100
Behavior on topLeftRadius {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Behavior on bottomLeftRadius {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.PointingHandCursor
onClicked: mouse => {
if (mouse.button === Qt.RightButton)
stats.checkUpdates()
else
updateProc.running = true
}
}
Process {
id: updateProc
command: ["kitty", "--title", "System Update", "-e", "bash", "-c", "yay && echo 'Update completed successfully!' || { echo 'Update failed! Press any key to close...'; read -n 1; }"]
}
}
// CPU
BarPill {
fontFamily: bar.fontFamily
label: stats.cpuUsage + "% \uf2db"
pillColor: bar.accent5Color
textColor: bar.bgColor
}
// Memory
BarPill {
id: memPill
fontFamily: bar.fontFamily
label: stats.memUsage + "% \uf0c9"
pillColor: bar.accent4Color
textColor: bar.bgColor
tooltipText: stats.memInfo
}
// Temperature
BarPill {
id: tempPill
fontFamily: bar.fontFamily
label: {
let t = stats.temperature
let icon = t >= 80 ? "\uf2c7" : "\uf2c9"
return t + "\u00b0C " + icon
}
pillColor: bar.accent3Color
textColor: bar.bgColor
tooltipText: stats.cpuTemps || "No sensors"
}
// Clock
BarPill {
id: clockPill
fontFamily: bar.fontFamily
label: Qt.formatDateTime(clock.date, "hh:mm")
pillColor: bar.accent2Color
textColor: bar.bgColor
tooltipText: Qt.formatDateTime(clock.date, "dddd, MMMM d, yyyy")
}
// System tray
Rectangle {
height: 22
width: trayRow.width + 16
topLeftRadius: 4
bottomLeftRadius: 4
topRightRadius: 100
bottomRightRadius: 100
color: bar.accentColor
anchors.verticalCenter: parent.verticalCenter
Row {
id: trayRow
anchors.centerIn: parent
spacing: 6
Repeater {
model: SystemTray.items
delegate: Item {
id: trayDelegate
required property var modelData
width: 16
height: 16
anchors.verticalCenter: parent.verticalCenter
Image {
anchors.fill: parent
source: modelData.icon
sourceSize.width: 16
sourceSize.height: 16
fillMode: Image.PreserveAspectFit
}
QsMenuAnchor {
id: menuAnchor
menu: modelData.menu
anchor.window: bar
anchor.rect.x: trayDelegate.mapToItem(bar.contentItem, 0, 0).x
anchor.rect.y: trayDelegate.mapToItem(bar.contentItem, 0, 0).y
anchor.rect.width: trayDelegate.width
anchor.rect.height: trayDelegate.height
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: mouse => {
if (mouse.button === Qt.RightButton)
menuAnchor.open()
else
modelData.activate()
}
}
}
}
}
}
}
}
}
// --- Tooltips ---
BarTooltip {
bgColor: bar.bgColor; fgColor: bar.fgColor; borderColor: bar.accentColor; fontFamily: bar.fontFamily
target: updatesPill; text: updatesPill.tooltipText
}
BarTooltip {
bgColor: bar.bgColor; fgColor: bar.fgColor; borderColor: bar.accentColor; fontFamily: bar.fontFamily
target: memPill; text: memPill.tooltipText
}
BarTooltip {
bgColor: bar.bgColor; fgColor: bar.fgColor; borderColor: bar.accentColor; fontFamily: bar.fontFamily
target: tempPill; text: tempPill.tooltipText
}
BarTooltip {
bgColor: bar.bgColor; fgColor: bar.fgColor; borderColor: bar.accentColor; fontFamily: bar.fontFamily
target: clockPill; text: clockPill.tooltipText
}
}

View File

@ -0,0 +1,44 @@
import QtQuick
Rectangle {
id: pill
required property string label
required property color pillColor
required property color textColor
required property string fontFamily
property string tooltipText: ""
property bool hovered: hoverArea.containsMouse
property alias font: pillText.font
property real textSize: 13
signal clicked()
height: 22
width: pillText.implicitWidth + 16
radius: 4
color: pillColor
anchors.verticalCenter: parent?.verticalCenter
Behavior on width {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Text {
id: pillText
anchors.centerIn: parent
text: pill.label
color: pill.textColor
font.pixelSize: pill.textSize
font.family: pill.fontFamily
}
MouseArea {
id: hoverArea
anchors.fill: parent
hoverEnabled: pill.tooltipText !== ""
cursorShape: Qt.ArrowCursor
onClicked: pill.clicked()
}
}

View File

@ -0,0 +1,41 @@
import Quickshell
import QtQuick
PopupWindow {
id: tooltip
required property color bgColor
required property color fgColor
required property color borderColor
required property string fontFamily
property string text: ""
property Item target: null
visible: text !== "" && target !== null && target.hovered
anchor.item: target
anchor.edges: Edges.Bottom
anchor.gravity: Edges.Bottom
anchor.adjustment: PopupAdjustment.SlideX
implicitWidth: tooltipContent.implicitWidth + 20
implicitHeight: tooltipContent.implicitHeight + 14
color: "transparent"
Rectangle {
anchors.fill: parent
color: tooltip.bgColor
border.color: tooltip.borderColor
border.width: 2
radius: 8
Text {
id: tooltipContent
anchors.centerIn: parent
text: tooltip.text
color: tooltip.fgColor
font.pixelSize: 12
font.family: tooltip.fontFamily
lineHeight: 1.3
}
}
}

View File

@ -0,0 +1,49 @@
import Quickshell
import Quickshell.Io
import QtQuick
Scope {
id: base
property var walColors: ({
special: { background: "#1d160d", foreground: "#d8d8d3" },
colors: {
color0: "#1d160d", color1: "#946F50", color2: "#BA9351",
color3: "#A28E62", color4: "#6E7986", color5: "#76878C",
color6: "#9FA4A4", color7: "#d8d8d3", color8: "#979793"
}
})
property string motd: ""
property string fontFamily: "HurmitNerdFontPropo"
property SystemStats stats: SystemStats {}
Process {
id: colorsProc
command: ["cat", "/home/candle/.cache/wal/colors.json"]
running: true
stdout: StdioCollector {
onDataChanged: {
try {
let parsed = JSON.parse(text)
if (parsed && parsed.special)
base.walColors = parsed
} catch(e) {}
}
}
}
Process {
id: motdProc
command: ["cat", "/home/candle/.MOTD"]
running: true
stdout: StdioCollector {
onDataChanged: {
base.motd = text.trim()
}
}
}
}

View File

@ -0,0 +1,225 @@
import Quickshell
import Quickshell.Services.Mpris
import QtQuick
PanelWindow {
id: controller
required property var walColors
required property string fontFamily
property color bgColor: (walColors.special && walColors.special.background) ? walColors.special.background : "#1d160d"
property color fgColor: (walColors.special && walColors.special.foreground) ? walColors.special.foreground : "#d8d8d3"
property color accentColor: (walColors.colors && walColors.colors.color1) ? walColors.colors.color1 : "#946F50"
property color accent2Color: (walColors.colors && walColors.colors.color2) ? walColors.colors.color2 : "#BA9351"
property color accent3Color: (walColors.colors && walColors.colors.color3) ? walColors.colors.color3 : "#BA9351"
property color accent4Color: (walColors.colors && walColors.colors.color4) ? walColors.colors.color4 : "#BA9351"
property color accent5Color: (walColors.colors && walColors.colors.color5) ? walColors.colors.color5 : "#BA9351"
anchors {
bottom: true
// right: true
}
color: "transparent"
exclusionMode: ExclusionMode.Ignore
implicitHeight: 34
implicitWidth: mainGroup.width + 8
property var player: {
let players = Mpris.players.values
if (!players || players.length === 0) return null
for (let i = 0; i < players.length; i++) {
if (players[i].playbackState === MprisPlaybackState.Playing)
return players[i]
}
return players[0]
}
property bool hovered: hoverArea.containsMouse
Item {
anchors.fill: parent
anchors.margins: 2
MouseArea {
id: hoverArea
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.NoButton
}
Rectangle {
id: mainGroup
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
height: 30
width: infoRow.width + 8
clip: true
color: controller.bgColor
border.color: controller.accentColor
border.width: 2
radius: 100
Behavior on width {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
// Track info (default view)
Row {
id: infoRow
anchors.right: parent.right
anchors.rightMargin: 4
anchors.verticalCenter: parent.verticalCenter
spacing: 5
visible: !controller.hovered
BarPill {
id: trackInfoPill
fontFamily: controller.fontFamily
topLeftRadius: 100
bottomLeftRadius: 100
label: {
if (!controller.player) return "No Player"
let artist = controller.player.trackArtist || ""
let title = controller.player.trackTitle || ""
if (artist && title) return artist + " \u2022 " + title
if (title) return title
return controller.player.identity || "Unknown"
}
pillColor: controller.accent2Color
textColor: controller.bgColor
}
BarPill {
fontFamily: controller.fontFamily
label: {
if (!controller.player) return "\uf04c"
if (controller.player.playbackState === MprisPlaybackState.Playing) return "\uf04b"
if (controller.player.playbackState === MprisPlaybackState.Paused) return "\uf04c"
return "\uf04d"
}
pillColor: controller.accentColor
textColor: controller.bgColor
topLeftRadius: 4
bottomLeftRadius: 4
topRightRadius: 100
bottomRightRadius: 100
}
}
// Controls (hover view)
Row {
id: controlsRow
anchors.right: parent.right
anchors.rightMargin: 4
anchors.verticalCenter: parent.verticalCenter
spacing: 5
visible: controller.hovered
property bool hasShuffle: controller.player && controller.player.shuffleSupported
property bool hasLoop: controller.player && controller.player.loopSupported
property int visibleCount: 3 + (hasShuffle ? 1 : 0) + (hasLoop ? 1 : 0)
property real totalSpacing: (visibleCount - 1) * spacing
property real pillWidth: visibleCount > 0 ? (infoRow.width - totalSpacing) / visibleCount : 40
BarPill {
fontFamily: controller.fontFamily
label: "\uf048"
pillColor: controller.accent5Color
textColor: controller.bgColor
width: controlsRow.pillWidth
topLeftRadius: 100
bottomLeftRadius: 100
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: if (controller.player && controller.player.canGoPrevious) controller.player.previous()
}
}
BarPill {
fontFamily: controller.fontFamily
label: {
if (!controller.player) return "\uf04b"
return controller.player.playbackState === MprisPlaybackState.Playing ? "\uf04c" : "\uf04b"
}
pillColor: controller.accent3Color
textColor: controller.bgColor
width: controlsRow.pillWidth
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: if (controller.player && controller.player.canTogglePlaying) controller.player.togglePlaying()
}
}
BarPill {
id: nextPill
fontFamily: controller.fontFamily
label: "\uf051"
pillColor: controller.accent4Color
textColor: controller.bgColor
width: controlsRow.pillWidth
topRightRadius: (!controlsRow.hasShuffle && !controlsRow.hasLoop) ? 100 : 4
bottomRightRadius: (!controlsRow.hasShuffle && !controlsRow.hasLoop) ? 100 : 4
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: if (controller.player && controller.player.canGoNext) controller.player.next()
}
}
BarPill {
id: shufflePill
fontFamily: controller.fontFamily
label: "\uf074"
pillColor: controller.player && controller.player.shuffle ? controller.accent2Color : controller.accentColor
textColor: controller.bgColor
width: controlsRow.pillWidth
visible: controlsRow.hasShuffle
topRightRadius: !controlsRow.hasLoop ? 100 : 4
bottomRightRadius: !controlsRow.hasLoop ? 100 : 4
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: if (controller.player) controller.player.shuffle = !controller.player.shuffle
}
}
BarPill {
fontFamily: controller.fontFamily
label: {
if (!controller.player) return "\uf01e"
if (controller.player.loopState === MprisLoopState.Track) return "\uf021"
return "\uf01e"
}
pillColor: controller.player && controller.player.loopState !== MprisLoopState.None ? controller.accent2Color : controller.accentColor
textColor: controller.bgColor
width: controlsRow.pillWidth
visible: controlsRow.hasLoop
topRightRadius: 100
bottomRightRadius: 100
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
if (!controller.player) return
if (controller.player.loopState === MprisLoopState.None)
controller.player.loopState = MprisLoopState.Playlist
else if (controller.player.loopState === MprisLoopState.Playlist)
controller.player.loopState = MprisLoopState.Track
else
controller.player.loopState = MprisLoopState.None
}
}
}
}
}
}
}

View File

@ -0,0 +1,116 @@
import QtQuick
Rectangle {
id: toast
required property int index
required property string appName
required property string summary
required property string body
required property int toastId
required property color bgColor
required property color fgColor
required property color accentColor
required property string fontFamily
required property Item rightAnchor
required property var sourceModel
z: 0
y: rightAnchor.y + (rightAnchor.height - height) / 2
height: 28
width: contentRow.implicitWidth + 20
color: bgColor
border.color: accentColor
border.width: 2
topLeftRadius: 100
bottomLeftRadius: 100
visible: false
property bool showing: false
Component.onCompleted: {
visible = true
showing = true
hideTimer.start()
}
x: showing ? rightAnchor.x - width + 30 : rightAnchor.x
Behavior on x {
id: xBehavior
enabled: toast.showing
NumberAnimation {
duration: 400
easing.type: Easing.InOutCubic
onRunningChanged: {
if (!running && !toast.showing) {
toast.visible = false
toast.sourceModel.remove(toast.index)
}
}
}
}
Timer {
id: hideTimer
interval: 5000
onTriggered: {
xBehavior.enabled = true
toast.showing = false
}
}
Row {
id: contentRow
anchors.centerIn: parent
spacing: 8
Text {
text: toast.appName
color: toast.accentColor
font.pixelSize: 11
font.family: toast.fontFamily
font.bold: true
visible: toast.appName !== ""
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: toast.summary
color: toast.fgColor
font.pixelSize: 13
font.family: toast.fontFamily
elide: Text.ElideRight
width: Math.min(implicitWidth, 300)
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: toast.body
color: Qt.rgba(toast.fgColor.r, toast.fgColor.g, toast.fgColor.b, 0.7)
font.pixelSize: 11
font.family: toast.fontFamily
elide: Text.ElideRight
width: Math.min(implicitWidth, 200)
visible: toast.body !== "" && toast.body !== toast.summary
anchors.verticalCenter: parent.verticalCenter
}
Rectangle {
height: 18
width: 20
color: toast.bgColor
}
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: {
hideTimer.stop()
xBehavior.enabled = true
toast.showing = false
}
}
}

View File

@ -0,0 +1,131 @@
import Quickshell
import QtQuick
import Quickshell.Io
FloatingWindow {
id: gallery
required property var walColors
property color bgColor: (walColors.special && walColors.special.background) ? walColors.special.background : "#1d160d"
property color accentColor: (walColors.colors && walColors.colors.color1) ? walColors.colors.color1 : "#946F50"
title: "Photo Gallery"
color: "transparent"
implicitWidth: 300
implicitHeight: 600
required property string photosPath
property var photoFiles: []
property int currentIndex: -1
property int nextIndex: -1
// Slide direction: 0 = from left, 1 = from right
property int slideDirection: 0
// Track which image layer is on top
property bool showingFront: true
Process {
id: listProc
command: ["bash", "-c", "find " + gallery.photosPath + " -maxdepth 1 -type f \\( -iname '*.png' -o -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.webp' \\) | sort"]
running: true
stdout: StdioCollector {
onDataChanged: {
let lines = text.trim().split("\n").filter(l => l.length > 0)
gallery.photoFiles = lines
if (lines.length > 0) {
gallery.currentIndex = Math.floor(Math.random() * lines.length)
}
}
}
}
Timer {
id: cycleTimer
interval: 5000
running: gallery.photoFiles.length > 1
repeat: true
onTriggered: gallery.pickNext()
}
function pickNext() {
if (photoFiles.length < 2) return
let idx
do {
idx = Math.floor(Math.random() * photoFiles.length)
} while (idx === currentIndex)
nextIndex = idx
slideDirection = Math.floor(Math.random() * 4)
showingFront = !showingFront
let incoming = showingFront ? frontImage : backImage
let outgoing = showingFront ? backImage : frontImage
// Stop any running animations and reset positions
incoming.x = 0; incoming.y = 0
outgoing.x = 0; outgoing.y = 0
incoming.source = "file://" + photoFiles[nextIndex]
incoming.z = 1
outgoing.z = 0
let horizontal = slideDirection < 2
let size = horizontal ? implicitWidth : implicitHeight
let sign = (slideDirection === 0 || slideDirection === 3) ? -1 : 1
if (horizontal) {
incoming.x = sign * -size
incomingX.from = sign * -size; incomingX.to = 0
outgoingX.from = 0; outgoingX.to = sign * size
incomingX.target = incoming; outgoingX.target = outgoing
incomingY.target = null; outgoingY.target = null
incomingX.start(); outgoingX.start()
} else {
incoming.y = sign * -size
incomingY.from = sign * -size; incomingY.to = 0
outgoingY.from = 0; outgoingY.to = sign * size
incomingY.target = incoming; outgoingY.target = outgoing
incomingX.target = null; outgoingX.target = null
incomingY.start(); outgoingY.start()
}
currentIndex = nextIndex
}
NumberAnimation { id: incomingX; property: "x"; duration: 400; easing.type: Easing.InOutCubic }
NumberAnimation { id: outgoingX; property: "x"; duration: 400; easing.type: Easing.InOutCubic }
NumberAnimation { id: incomingY; property: "y"; duration: 400; easing.type: Easing.InOutCubic }
NumberAnimation { id: outgoingY; property: "y"; duration: 400; easing.type: Easing.InOutCubic }
Item {
anchors.fill: parent
clip: true
Image {
id: backImage
width: parent.width
height: parent.height
fillMode: Image.PreserveAspectCrop
asynchronous: true
mipmap: true
z: 0
}
Image {
id: frontImage
width: parent.width
height: parent.height
fillMode: Image.PreserveAspectCrop
asynchronous: true
mipmap: true
z: 1
source: gallery.currentIndex >= 0 && gallery.photoFiles.length > 0
? "file://" + gallery.photoFiles[gallery.currentIndex]
: ""
}
}
}

View File

@ -0,0 +1,140 @@
import QtQuick
import Quickshell
import Quickshell.Io
QtObject {
id: stats
property var _prevCpu: null
property int cpuUsage: 0
property int _memTotal: 0
property int _memAvail: 0
property int memUsage: 0
property string memInfo: "0/0"
property int temperature: 0
property int updatesCount: 0
property string updatesList: ""
property string cpuTemps: ""
property var _cpuProc: Process {
command: ["cat", "/proc/stat"]
running: true
stdout: SplitParser {
splitMarker: "\n"
onRead: data => {
if (!data.startsWith("cpu ")) return
let parts = data.trim().split(/\s+/).slice(1).map(Number)
let idle = parts[3] + (parts[4] || 0)
let total = parts.reduce((a, b) => a + b, 0)
if (stats._prevCpu) {
let di = idle - stats._prevCpu.idle
let dt = total - stats._prevCpu.total
stats.cpuUsage = dt > 0 ? Math.round(100 * (1 - di / dt)) : 0
}
stats._prevCpu = { idle: idle, total: total }
}
}
}
property var _memProc: Process {
command: ["cat", "/proc/meminfo"]
running: true
stdout: SplitParser {
splitMarker: "\n"
onRead: data => {
let line = data.trim()
if (line.startsWith("MemTotal:"))
stats._memTotal = parseInt(line.split(/\s+/)[1]) || 0
else if (line.startsWith("MemAvailable:"))
stats._memAvail = parseInt(line.split(/\s+/)[1]) || 0
}
}
onExited: (code, status) => {
if (stats._memTotal > 0) {
stats.memUsage = Math.round(100 * (1 - stats._memAvail / stats._memTotal))
let used = ((stats._memTotal - stats._memAvail) / 1048576).toFixed(1)
let total = (stats._memTotal / 1048576).toFixed(1)
stats.memInfo = used + "G/" + total + "G"
}
}
}
property var _tempProc: Process {
command: [
"bash", "-c",
"for f in /sys/class/hwmon/hwmon*/temp*_input; do " +
" d=$(dirname \"$f\"); b=$(basename \"$f\"); " +
" name=$(cat \"$d/name\" 2>/dev/null || echo unknown); " +
" label=$(cat \"$d/${b%_input}_label\" 2>/dev/null || echo ''); " +
" temp=$(($(cat \"$f\" 2>/dev/null)/1000)); " +
" printf '%s|%s|%s\\n' \"$name\" \"$label\" \"$temp\"; " +
"done 2>/dev/null"
]
running: true
stdout: StdioCollector {
onDataChanged: {
let lines = text.trim().split("\n").filter(l => l.length > 0)
let tempLines = []
let maxTemp = 0
for (let i = 0; i < lines.length; i++) {
let parts = lines[i].split("|")
let name = parts[0] || "unknown"
let label = parts[1] || ""
let temp = parseInt(parts[2]) || 0
if (temp > 0) {
let display = label ? label : name
tempLines.push(display + ": " + temp + "°C")
if (temp > maxTemp) maxTemp = temp
}
}
stats.temperature = maxTemp
stats.cpuTemps = tempLines.join("\n")
}
}
}
property var _pollTimer: Timer {
interval: 3000
running: true
repeat: true
onTriggered: {
if (!stats._cpuProc.running) stats._cpuProc.running = true
if (!stats._memProc.running) stats._memProc.running = true
if (!stats._tempProc.running) stats._tempProc.running = true
}
}
function checkUpdates() {
if (!_updatesProc.running) _updatesProc.running = true
}
property var _updatesProc: Process {
command: [
"bash", "-c",
"(checkupdates 2>/dev/null; yay -Qua 2>/dev/null)"
]
running: true
stdout: StdioCollector {
onDataChanged: {
let lines = text.trim()
let arr = lines ? lines.split("\n") : []
stats.updatesCount = arr.length
stats.updatesList = arr.slice(0, 25).join("\n") + (arr.length > 25 ? "\n..." : "")
}
}
}
property var _updatesTimer: Timer {
interval: 300000
running: true
repeat: true
onTriggered: {
if (!stats._updatesProc.running) stats._updatesProc.running = true
}
}
}

View File

@ -0,0 +1,106 @@
import QtQuick
import Quickshell.Hyprland
Item {
id: root
required property var workspaces
required property color accentColor
required property color fgColor
required property string fontFamily
width: workspacesRow.width
height: 22
Rectangle {
id: wsHighlight
height: 22
color: root.accentColor
z: 0
visible: targetWidth > 0
property real targetX: 0
property real targetWidth: 0
x: targetX
width: targetWidth
topLeftRadius: 4
bottomLeftRadius: 4
topRightRadius: 4
bottomRightRadius: 4
Behavior on x {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Behavior on width {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Behavior on topLeftRadius {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Behavior on bottomLeftRadius {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Behavior on topRightRadius {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
Behavior on bottomRightRadius {
NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
}
}
Row {
id: workspacesRow
spacing: 5
z: 1
Repeater {
model: root.workspaces
delegate: Item {
required property var modelData
required property int index
width: wsText.implicitWidth + 20
height: 22
property bool isActive: modelData.active
Component.onCompleted: if (isActive) updateSlider()
onIsActiveChanged: if (isActive) updateSlider()
onXChanged: if (isActive) updateSlider()
onWidthChanged: if (isActive) updateSlider()
function updateSlider() {
let isOnly = root.workspaces.length === 1
let isFirst = index === 0
let isLast = index === root.workspaces.length - 1
wsHighlight.targetX = x
wsHighlight.targetWidth = width
wsHighlight.topLeftRadius = isOnly ? 100 : (isFirst ? 100 : 4)
wsHighlight.bottomLeftRadius = isOnly ? 100 : (isFirst ? 100 : 4)
wsHighlight.topRightRadius = isOnly ? 100 : (isLast ? 100 : 4)
wsHighlight.bottomRightRadius = isOnly ? 100 : (isLast ? 100 : 4)
}
Text {
id: wsText
anchors.centerIn: parent
text: modelData.name
color: root.fgColor
font.pixelSize: 12
font.family: root.fontFamily
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: Hyprland.dispatch("workspace " + modelData.id)
}
}
}
}
}

View File

@ -0,0 +1,12 @@
//@ pragma UseQApplication
import Quickshell
import QtQuick
ShellRoot {
Base { id: base }
PhotoGallery {
walColors: base.walColors
photosPath: "$XDG_CONFIG_HOME/quickshell/photos"
}
}

View File

@ -0,0 +1,12 @@
//@ pragma UseQApplication
import Quickshell
import QtQuick
ShellRoot {
Base { id: base }
MusicController {
walColors: base.walColors
fontFamily: base.fontFamily
}
}

View File

@ -0,0 +1,48 @@
//@ pragma UseQApplication
import Quickshell
import Quickshell.Hyprland
import Quickshell.Services.Notifications
import QtQuick
ShellRoot {
id: root
Base { id: base }
NotificationServer {
id: notifServer
keepOnReload: true
bodySupported: true
bodyMarkupSupported: true
actionsSupported: true
persistenceSupported: true
onNotification: notification => {
notification.tracked = true
root.latestNotification = notification
}
}
property var notifServerRef: notifServer
property var latestNotification: null
property int notifCount: notifServer.trackedNotifications.values.length
Variants {
model: Quickshell.screens
delegate: Component {
Scope {
property var modelData
Bar {
screen: modelData
walColors: base.walColors
motd: base.motd
notificationCount: root.notifCount
latestNotification: root.latestNotification
notifServer: root.notifServerRef
stats: base.stats
fontFamily: base.fontFamily
}
}
}
}
}

31
.config/rofi/config.rasi Normal file
View File

@ -0,0 +1,31 @@
@theme "~/.cache/wal/colors-rofi-dark.rasi"
configuration {
modes: "window,drun,combi";
font: "mono 12";
/* location: 0;*/
/* yoffset: 0;*/
/* xoffset: 0;*/
/* icon-theme: ;*/
/* sort: false;*/
/* sorting-method: "normal";*/
combi-modes: "window,drun";
display-window: "";
/* display-windowcd: ;*/
/* display-run: ;*/
/* display-ssh: ;*/
display-drun: "";
display-combi: "search:";
/* display-keys: ;*/
display-file-browser-extended: "search:";
display-filebrowser: "search:";
use-hot-keys: true;
timeout {
action: "kb-cancel";
delay: 0;
}
filebrowser {
directory: "~";
directories-first: true;
sorting-method: "name";
}
}

View File

@ -0,0 +1,3 @@
dir "~"
cmd "open"
open-parent-as-self

View File

@ -0,0 +1,12 @@
[Unit]
Description=MOTD Generator
After=graphical-session.target
[Service]
Type=oneshot
ExecStart=motd -o %h/.MOTD
Restart=on-failure
Slice=session.slice
[Install]
WantedBy=graphical-session.target

View File

@ -0,0 +1,10 @@
[Unit]
Description=MOTD update
After=graphical-session.target
[Timer]
OnBootSec=30sec
OnUnitInactiveSec=60min
[Install]
WantedBy=timers.target

View File

@ -0,0 +1,12 @@
[Unit]
Description=mpd-mpris bridge
After=mpd.service
[Service]
Type=simple
ExecStart=mpd-mpris
Restart=on-failure
Slice=session.slice
[Install]
WantedBy=graphical-session.target

View File

@ -0,0 +1,13 @@
[Unit]
Description=Quickshell mainbar
After=graphical-session.target
[Service]
Type=exec
ExecCondition=/lib/systemd/systemd-xdg-autostart-condition "Hyprland" ""
ExecStart=quickshell -p %h/.config/quickshell/shell.qml
Restart=on-failure
Slice=app-graphical.slice
[Install]
WantedBy=graphical-session.target

View File

@ -0,0 +1,13 @@
[Unit]
Description=weather for fast fetch
After=graphical-session.target
[Service]
Type=oneshot
ExecCondition=/lib/systemd/systemd-xdg-autostart-condition "Hyprland" ""
ExecStart=%h/.local/bin/weather
Restart=on-failure
Slice=app-graphical.slice
[Install]
WantedBy=graphical-session.target

View File

@ -0,0 +1,10 @@
[Unit]
Description=weather for fastfetch, runs hourly
After=graphical-session.target
[Timer]
OnBootSec=30sec
OnUnitInactiveSec=60min
[Install]
WantedBy=timers.target

View File

@ -0,0 +1 @@
--color=bg+:{color8},bg:{background},border:{color7},spinner:{color10},hl:{color9},fg:{foreground},header:{color9},info:{color11},pointer:{background},marker:{color5},fg+:{color15},preview-bg:{background},prompt:{color12},hl+:{color10}

View File

@ -0,0 +1,18 @@
$foregroundCol = 0xff{foreground.strip}
$backgroundCol = 0xff{background.strip}
$color0 = 0xff{color0.strip}
$color1 = 0xff{color1.strip}
$color2 = 0xff{color2.strip}
$color3 = 0xff{color3.strip}
$color4 = 0xff{color4.strip}
$color5 = 0xff{color5.strip}
$color6 = 0xff{color6.strip}
$color7 = 0xff{color7.strip}
$color8 = 0xff{color8.strip}
$color9 = 0xff{color9.strip}
$color10 = 0xff{color10.strip}
$color11 = 0xff{color11.strip}
$color12 = 0xff{color12.strip}
$color13 = 0xff{color13.strip}
$color14 = 0xff{color14.strip}
$color15 = 0xff{color15.strip}

View File

@ -0,0 +1,177 @@
* {{
active-background: {color2}80;
active-foreground: @foreground;
normal-background: @background;
normal-foreground: @foreground;
urgent-background: {color1}80;
urgent-foreground: @foreground;
alternate-active-background: @background;
alternate-active-foreground: @foreground;
alternate-normal-background: @background;
alternate-normal-foreground: @foreground;
alternate-urgent-background: @background;
alternate-urgent-foreground: @foreground;
selected-active-background: {color1}40;
selected-active-foreground: @foreground;
selected-normal-background: {color3}40;
selected-normal-foreground: @foreground;
selected-urgent-background: {color4}40;
selected-urgent-foreground: @foreground;
background-color: @background;
background: {background}10;
foreground: {foreground};
border-color: @background;
spacing: 2;
}}
#window {{
background: transparent;
background-color: @background;
border: 0;
border-radius: 3.5px;
}}
#mainbox {{
border: 0;
padding: 0;
border-radius: 3.5px;
}}
#message {{
border: 2px 0px 0px;
border-color: @border-color;
padding: 1px;
}}
#textbox {{
text-color: @foreground;
}}
#inputbar {{
children: [ prompt,textbox-prompt-colon,entry,case-indicator ];
}}
#textbox-prompt-colon {{
expand: false;
str: "";
margin: 0px 0.3em 0em 0em;
text-color: @normal-foreground;
}}
#listview {{
fixed-height: 0;
border: 2px 0px 0px;
border-color: @border-color;
spacing: 2px;
scrollbar: true;
padding: 2px 0px 0px;
}}
#element {{
border: 0;
padding: 1px;
}}
#element-icon {{
size: 2.5em;
}}
#element-text {{
vertical-align: 0.5;
}}
#element-text, element-icon {{
background-color: inherit;
text-color: inherit;
}}
#element.normal.normal {{
background-color: @normal-background;
text-color: @normal-foreground;
}}
#element.normal.urgent {{
background-color: @urgent-background;
text-color: @urgent-foreground;
}}
#element.normal.active {{
background-color: @active-background;
text-color: @active-foreground;
}}
#element.selected.normal {{
background-color: @selected-normal-background;
text-color: @selected-normal-foreground;
}}
#element.selected.urgent {{
background-color: @selected-urgent-background;
text-color: @selected-urgent-foreground;
}}
#element.selected.active {{
background-color: @selected-active-background;
text-color: @selected-active-foreground;
}}
#element.alternate.normal {{
background-color: @alternate-normal-background;
text-color: @alternate-normal-foreground;
}}
#element.alternate.urgent {{
background-color: @alternate-urgent-background;
text-color: @alternate-urgent-foreground;
}}
#element.alternate.active {{
background-color: @alternate-active-background;
text-color: @alternate-active-foreground;
}}
#scrollbar {{
background-color: @selected-normal-background;
width: 4px;
border: 0;
handle-width: 8px;
padding: 0;
}}
#sidebar {{
border: 2px 0px 0px;
border-color: @border-color;
}}
#button {{
text-color: @normal-foreground;
}}
#button.selected {{
background-color: @selected-normal-background;
text-color: @selected-normal-foreground;
}}
#inputbar {{
spacing: 0;
text-color: @normal-foreground;
padding: 1px;
}}
#case-indicator {{
spacing: 0;
text-color: @normal-foreground;
}}
#entry {{
spacing: 0;
text-color: @normal-foreground;
}}
#prompt {{
spacing: 0;
text-color: @normal-foreground;
}}

View File

@ -0,0 +1,35 @@
:root {{
--focus: {color1.rgb};
--clientBG: {background.rgb};
--header_dark: {color0.rgb};
--frameBorder: {color8.rgb};
--online: {color4.rgb};
--ingame: {color2.rgb};
--offline: {color7.rgb}; /* Originally white45 but that makes it too bold */
--golden: {color3.rgb};
--textentry: {color0.rgb};
--white03: 255, 255, 255, 0.03;
--white05: 255, 255, 255, 0.05;
--white08: 255, 255, 255, 0.08;
--white10: 255, 255, 255, 0.10;
--white12: 255, 255, 255, 0.12;
--white20: 255, 255, 255, 0.20;
--white24: 255, 255, 255, 0.24;
--white25: 255, 255, 255, 0.25;
--white35: 255, 255, 255, 0.35;
--white45: 255, 255, 255, 0.45;
--white50: 255, 255, 255, 0.50;
--white75: 255, 255, 255, 0.75;
--white: 255, 255, 255;
--black05: 255, 255, 255, 0.05;
--black10: 0, 0, 0, 0.10;
--black12: 0, 0, 0, 0.12;
--black20: 0, 0, 0, 0.20;
--black24: 0, 0, 0, 0.24;
--black25: 0, 0, 0, 0.25;
--black45: 0, 0, 0, 0.45;
--black50: 0, 0, 0, 0.50;
--black75: 0, 0, 0, 0.75;
--black: 0, 0, 0;
--red: 255, 0, 0;
}}

View File

@ -0,0 +1,130 @@
{{
"$schema": "https://zed.dev/schema/themes/v0.2.0.json",
"name": "WPG",
"author": "pywal",
"themes": [
{{
"name": "WPG Generated",
"appearance": "dark",
"style": {{
"border": "{color8}",
"border.variant": "{color0}",
"border.focused": "{color4}",
"border.selected": "{color4}",
"border.transparent": "#00000000",
"border.disabled": "{color8}",
"elevated_surface.background": "{color0}",
"surface.background": "{color0}",
"background": "{color0}",
"element.background": "{color0}",
"element.hover": "{color8}",
"element.active": "{color8}",
"element.selected": "{color8}",
"element.disabled": "{color0}",
"drop_target.background": "{color8}80",
"ghost_element.background": "#00000000",
"ghost_element.hover": "{color8}",
"ghost_element.active": "{color8}",
"ghost_element.selected": "{color8}",
"ghost_element.disabled": "{color0}",
"text": "{color15}",
"text.muted": "{color7}",
"text.placeholder": "{color8}",
"text.disabled": "{color8}",
"text.accent": "{color4}",
"icon": "{color15}",
"icon.muted": "{color7}",
"icon.disabled": "{color8}",
"icon.placeholder": "{color7}",
"icon.accent": "{color4}",
"status_bar.background": "{color0}",
"title_bar.background": "{color0}",
"title_bar.inactive_background": "{color0}",
"toolbar.background": "{color0}",
"tab_bar.background": "{color0}",
"tab.inactive_background": "{color0}",
"tab.active_background": "{color8}",
"search.match_background": "{color4}66",
"search.active_match_background": "{color3}66",
"panel.background": "{color0}",
"panel.focused_border": null,
"pane.focused_border": null,
"scrollbar.thumb.background": "{color7}4c",
"scrollbar.thumb.hover_background": "{color8}",
"scrollbar.thumb.border": "{color8}",
"scrollbar.track.background": "#00000000",
"scrollbar.track.border": "{color0}",
"editor.foreground": "{color15}",
"editor.background": "{color0}",
"editor.gutter.background": "{color0}",
"editor.subheader.background": "{color0}",
"editor.active_line.background": "{color8}bf",
"editor.highlighted_line.background": "{color8}",
"editor.line_number": "{color8}",
"editor.active_line_number": "{color15}",
"editor.hover_line_number": "{color7}",
"editor.invisible": "{color8}",
"editor.wrap_guide": "{color8}1a",
"editor.active_wrap_guide": "{color8}33",
"editor.document_highlight.read_background": "{color4}1a",
"editor.document_highlight.write_background": "{color8}66",
"terminal.background": "{color0}",
"terminal.foreground": "{color15}",
"terminal.bright_foreground": "{color15}",
"terminal.dim_foreground": "{color7}",
"terminal.ansi.black": "{color0}",
"terminal.ansi.bright_black": "{color8}",
"terminal.ansi.red": "{color1}",
"terminal.ansi.bright_red": "{color9}",
"terminal.ansi.green": "{color2}",
"terminal.ansi.bright_green": "{color10}",
"terminal.ansi.yellow": "{color3}",
"terminal.ansi.bright_yellow": "{color11}",
"terminal.ansi.blue": "{color4}",
"terminal.ansi.bright_blue": "{color12}",
"terminal.ansi.magenta": "{color5}",
"terminal.ansi.bright_magenta": "{color13}",
"terminal.ansi.cyan": "{color6}",
"terminal.ansi.bright_cyan": "{color14}",
"terminal.ansi.white": "{color7}",
"terminal.ansi.bright_white": "{color15}",
"link_text.hover": "{color4}",
"syntax": {{
"attribute": {{ "color": "{color4}" }},
"boolean": {{ "color": "{color3}" }},
"comment": {{ "color": "{color8}" }},
"comment.doc": {{ "color": "{color8}" }},
"constant": {{ "color": "{color3}" }},
"constructor": {{ "color": "{color4}" }},
"embedded": {{ "color": "{color15}" }},
"emphasis": {{ "color": "{color4}" }},
"emphasis.strong": {{ "color": "{color3}", "font_weight": 700 }},
"enum": {{ "color": "{color1}" }},
"function": {{ "color": "{color4}" }},
"hint": {{ "color": "{color6}" }},
"keyword": {{ "color": "{color5}" }},
"label": {{ "color": "{color4}" }},
"link_text": {{ "color": "{color4}" }},
"link_uri": {{ "color": "{color6}" }},
"namespace": {{ "color": "{color15}" }},
"number": {{ "color": "{color3}" }},
"operator": {{ "color": "{color6}" }},
"preproc": {{ "color": "{color15}" }},
"primary": {{ "color": "{color15}" }},
"property": {{ "color": "{color1}" }},
"punctuation": {{ "color": "{color15}" }},
"punctuation.bracket": {{ "color": "{color7}" }},
"punctuation.delimiter": {{ "color": "{color7}" }},
"selector": {{ "color": "{color3}" }},
"string": {{ "color": "{color2}" }},
"string.regex": {{ "color": "{color3}" }},
"tag": {{ "color": "{color4}" }},
"type": {{ "color": "{color6}" }},
"variable": {{ "color": "{color15}" }},
"variant": {{ "color": "{color4}" }}
}}
}}
}}
]
}}

View File

@ -0,0 +1,797 @@
#modded Numix gtkrc
gtk-color-scheme = "bg_color:{color0}
color0:{color0}
color1:{color1}
color2:{color2}
color3:{color3}
color4:{color4}
color5:{color5}
color6:{color6}
color7:{color7}
color8:{color8}
color9:{color9}
color10:{color10}
color11:{color11}
color12:{color12}
color13:{color13}
color14:{color14}
color15:{color15}
text_color:{color15}
selected_bg_color:{active}
selected_fg_color:{color15}
tooltip_bg_color:{color0}
tooltip_fg_color:{color15}
titlebar_bg_color:{color0}
titlebar_fg_color:{color15}
menu_bg_color:{color0}
menu_fg_color:{color15}
link_color:{active}"
gtk-auto-mnemonics = 1
# Default Style
# DO --NOT-- CHANGE ACTIVE
# IT's THE COLOR THAT WPGTK REPLACES
# FEEL FREE TO MODIFY EVERYTHING ELSE IN gtkrc.base
style "murrine-default" {{
GtkArrow::arrow-scaling= 0.6
GtkButton::child-displacement-x = 0
GtkButton::child-displacement-y = 0
GtkButton::default-border = {{ 0, 0, 0, 0 }}
GtkButtonBox::child-min-height = 26
GtkCheckButton::indicator-size = 16
# The following line hints to gecko (and possibly other appliations)
# that the entry should be drawn transparently on the canvas.
# Without this, gecko will fill in the background of the entry.
GtkEntry::honors-transparent-bg-hint = 1
GtkEntry::state-hint = 0
GtkExpander::expander-size = 16
GtkImage::x-ayatana-indicator-dynamic = 1
GtkMenu::horizontal-padding = 0
GtkMenu::vertical-padding = 0
GtkMenuBar::internal-padding = 0
GtkMenuBar::window-dragging = 1
GtkMenuItem::arrow-scaling= 0.5
GtkPaned::handle-size = 1
GtkProgressBar::min-horizontal-bar-height = 12
GtkProgressBar::min-vertical-bar-width = 12
GtkRange::trough-border = 0
GtkRange::slider-width = 8
GtkRange::stepper-size = 12
GtkRange::stepper_spacing = 0
GtkRange::trough-under-steppers = 1
GtkScale::slider-length = 16
GtkScale::slider-width = 16
GtkScale::trough-side-details = 1
GtkScrollbar::activate-slider = 1
GtkScrollbar::has-backward-stepper = 0
GtkScrollbar::has-forward-stepper = 0
GtkScrollbar::has-secondary-backward-stepper = 0
GtkScrollbar::has-secondary-forward-stepper = 0
GtkScrollbar::min-slider-length = 80
GtkScrollbar::slider-width = 8
GtkScrollbar::trough-border = 0
GtkScrolledWindow::scrollbar-spacing = 0
GtkScrolledWindow::scrollbars-within-bevel = 1
GtkSeparatorMenuItem::horizontal-padding = 0
GtkToolbar::internal-padding = 0
GtkTreeView::expander-size = 11
GtkTreeView::vertical-separator = 0
GtkWidget::focus-line-width = 1
# The following line prevents the Firefox tabs
# from jumping a few pixels when you create a new tab
GtkWidget::focus-padding = 0
GtkWidget::wide-separators = 1
GtkWidget::separator-width = 1
GtkWidget::separator-height = 1
GtkWindow::resize-grip-height = 0
GtkWindow::resize-grip-width = 0
WnckTasklist::fade-overlay-rect = 0
GnomeHRef::link_color = @link_color
GtkHTML::link-color = @link_color
GtkIMHtmlr::hyperlink-color = @link_color
GtkIMHtml::hyperlink-color = @link_color
GtkWidget::link-color = @link_color
GtkWidget::visited-link-color = @text_color
GtkToolbar::shadow-type = GTK_SHADOW_NONE # Makes toolbars flat and unified
GtkMenuBar::shadow-type = GTK_SHADOW_NONE # Makes menubars flat and unified
xthickness = 1
ythickness = 1
fg[NORMAL] = @text_color
fg[PRELIGHT] = @text_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @text_color
fg[INSENSITIVE] = mix (0.5, @bg_color, @text_color)
bg[NORMAL] = @bg_color
bg[PRELIGHT] = shade (1.02, @bg_color)
bg[SELECTED] = @selected_bg_color
bg[ACTIVE] = @bg_color
bg[INSENSITIVE] = @bg_color
base[NORMAL] = shade(0.85, @color0)
base[PRELIGHT] = shade (0.85, @color0)
base[SELECTED] = @selected_bg_color
base[ACTIVE] = @selected_bg_color
base[INSENSITIVE] = shade (0.85, @bg_color)
text[NORMAL] = @text_color
text[PRELIGHT] = @text_color
text[SELECTED] = @selected_fg_color
text[ACTIVE] = @selected_fg_color
text[INSENSITIVE] = mix (0.5, @bg_color, @text_color)
engine "murrine" {{
animation = FALSE
arrowstyle = 1 # 0 = normal arrows, 1 = filled arrows
border_shades = {{ 1.0, 1.0 }} # gradient to draw on border
colorize_scrollbar = TRUE
comboboxstyle = 0 # 0 = normal combobox, 1 = colorized combobox below arrow
contrast = 0.0 # overal contrast with borders
focusstyle = 1 # 0 = none, 1 = grey dotted, 2 = colored with fill, 3 = colored glow
glazestyle = 0 # 0 = flat highlight, 1 = curved highlight, 2 = concave, 3 = top curved highlight, 4 = beryl highlight
glowstyle = 0 # 0 = glow on top, 1 = glow on bottom, 2 = glow on top and bottom, 3 = glow on middle vertically, 4 = glow on middle horizontally, 5 = glow on all sides
glow_shade = 1.0 # amount of glow
gradient_shades = {{ 1.0, 1.0, 1.0, 1.0 }} # gradient to draw on widgets
highlight_shade = 1.0 # amount of highlight
lightborder_shade = 1.0 # amount of inset light border
lightborderstyle = 1 # 0 = lightborder on top side, 1 = lightborder on all sides
listviewheaderstyle = 0 # 0 = flat, 1 = glassy, 2 = raised
listviewstyle = 0 # 0 = none, 1 = dotted, 2 = line
menubaritemstyle = 0 # 0 = menuitem look, 1 = button look
menubarstyle = 0 # 0 = flat, 1 = glassy, 2 = gradient, 3 = striped
menuitemstyle = 0 # 0 = flat, 1 = glassy, 2 = striped
menustyle = 0 # 0 = none, 1 = vertical striped
progressbarstyle = 0 # 0 = none, 1 = diagonal striped, 2 = vertical striped
reliefstyle = 0 # 0 = flat, 1 = inset, 2 = shadow, 3 = shadow with gradient, 4 = stronger shadow with gradient
roundness = 0 # roundness of widgets
scrollbarstyle = 0 # 0 = none, 1 = circles, 2 = handles, 3 = diagonal stripes, 4 = diagonal stripes and handles, 5 = horizontal stripes, 6 = horizontal stripes and handles
sliderstyle = 0 # 0 = none, 1 = handles
stepperstyle = 1 # 0 = standard, 1 = integrated stepper handles
toolbarstyle = 0 # 0 = flat, 1 = glassy, 2 = gradient
}}
}}
style "murrine-wide" {{
xthickness = 2
ythickness = 2
}}
style "murrine-wider" {{
xthickness = 3
ythickness = 3
}}
style "murrine-thin" {{
xthickness = 0
ythickness = 0
}}
# Notebook
style "murrine-notebook-bg" {{
bg[NORMAL] = @bg_color
bg[ACTIVE] = shade (0.70, @bg_color)
}}
style "murrine-notebook" = "murrine-notebook-bg" {{
xthickness = 2
ythickness = 2
engine "murrine" {{
roundness = 0
}}
}}
# Various Standard Widgets
style "murrine-button" = "murrine-wider" {{
bg[NORMAL] = shade (1.3, @bg_color)
bg[PRELIGHT] = shade (0.80, @selected_bg_color)
bg[ACTIVE] = shade (1.00, @selected_bg_color)
bg[INSENSITIVE] = shade (0.85, @bg_color)
engine "murrine" {{
}}
}}
style "murrine-scrollbar" {{
bg[NORMAL] = @bg_color
bg[PRELIGHT] = mix (0.31, @text_color, @bg_color)
bg[ACTIVE] = @selected_bg_color
engine "murrine" {{
roundness = 0
contrast = 0.0
border_shades = {{ 0.9, 0.9 }}
trough_shades = {{ 0.97, 0.97 }}
trough_border_shades = {{ 1.0, 1.0 }}
}}
}}
style "murrine-overlay-scrollbar" {{
bg[ACTIVE] = shade (0.8, @bg_color)
bg[INSENSITIVE] = shade (0.97, @bg_color)
base[SELECTED] = shade (0.6, @bg_color)
base[INSENSITIVE] = shade (0.85, @bg_color)
}}
style "murrine-scale" = "murrine-thin" {{
bg[NORMAL] = @bg_color
bg[ACTIVE] = @bg_color
bg[SELECTED] = @selected_bg_color
bg[INSENSITIVE] = shade (0.95, @bg_color)
engine "murrine" {{
roundness = 8
gradient_shades = {{ 1.08, 1.08, 1.08, 1.08 }}
border_shades = {{ 1.0, 1.0 }}
trough_shades = {{ 1.08, 1.08 }}
trough_border_shades = {{ 0.8, 0.8 }}
}}
}}
style "murrine-progressbar" = "murrine-thin" {{
bg[NORMAL] = @bg_color
bg[ACTIVE] = shade(0.60, @bg_color)
fg[PRELIGHT] = @selected_fg_color
engine "murrine" {{
roundness = 0
border_shades = {{ 1.2, 1.2 }}
trough_border_shades = {{ 0.8, 0.8 }}
}}
}}
style "murrine-treeview-header" = "murrine-button" {{
engine "murrine" {{
roundness = 0
}}
}}
style "murrine-treeview" {{
engine "murrine" {{
roundness = 0
}}
}}
style "murrine-frame-title" {{
fg[NORMAL] = lighter (@text_color)
}}
style "murrine-tooltips" {{
xthickness = 5
ythickness = 5
bg[NORMAL] = @tooltip_bg_color
bg[SELECTED] = @tooltip_bg_color
fg[NORMAL] = @text_color
engine "murrine" {{
textstyle = 0
roundness = 0
rgba = FALSE
}}
}}
style "murrine-spinbutton" = "murrine-button" {{
engine "murrine" {{
}}
}}
style "murrine-radiocheck" = "murrine-default" {{
bg[SELECTED] = @bg_color
text[NORMAL] = @selected_bg_color
text[PRELIGHT] = @selected_bg_color
}}
style "murrine-entry" = "murrine-wider" {{
bg[SELECTED] = @selected_bg_color
engine "murrine" {{
border_shades = {{ 1.15, 1.15 }}
}}
}}
style "metacity-frame" = "murrine-default" {{
bg[SELECTED] = @selected_bg_color
}}
style "murrine-statusbar" {{
bg[NORMAL] = @bg_color
}}
style "murrine-comboboxentry" = "murrine-entry" {{ }}
style "murrine-hscale" = "murrine-scale" {{ }}
style "murrine-vscale" = "murrine-scale" {{ }}
style "murrine-hscrollbar" = "murrine-scrollbar" {{ }}
style "murrine-vscrollbar" = "murrine-scrollbar" {{ }}
# Menus
style "murrine-menu" = "murrine-thin" {{
bg[NORMAL] = shade(0.8, @menu_bg_color)
bg[PRELIGHT] = @selected_bg_color
bg[SELECTED] = @selected_bg_color
bg[ACTIVE] = @menu_bg_color
bg[INSENSITIVE] = @menu_bg_color
fg[NORMAL] = @menu_fg_color
fg[PRELIGHT] = @selected_fg_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @selected_fg_color
fg[INSENSITIVE] = mix (0.5, @menu_bg_color, @menu_fg_color)
text[NORMAL] = @menu_fg_color
text[PRELIGHT] = @selected_fg_color
text[SELECTED] = @selected_fg_color
text[ACTIVE] = @selected_fg_color
text[INSENSITIVE] = mix (0.5, @menu_bg_color, @menu_fg_color)
engine "murrine" {{
roundness = 0
}}
}}
style "murrine-menu-item" = "murrine-wider" {{
bg[PRELIGHT] = @selected_bg_color
bg[SELECTED] = @selected_bg_color
bg[ACTIVE] = @selected_bg_color
fg[NORMAL] = @menu_fg_color # Fix for XFCE menu text
fg[PRELIGHT] = @selected_fg_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @selected_fg_color
fg[INSENSITIVE] = mix (0.5, @menu_bg_color, @menu_fg_color)
engine "murrine" {{
textstyle = 0
border_shades = {{ 1.2, 1.2 }}
}}
}}
style "murrine-separator-menu-item" = "murrine-thin" {{ }}
style "murrine-menubar" {{
bg[NORMAL] = @bg_color
bg[PRELIGHT] = mix (0.21, @text_color, @bg_color)
bg[SELECTED] = mix (0.21, @text_color, @bg_color)
bg[ACTIVE] = shade (0.9, @bg_color)
bg[INSENSITIVE] = @bg_color
fg[NORMAL] = @text_color
fg[PRELIGHT] = shade (1.08, @text_color)
fg[SELECTED] = shade (1.08, @text_color)
fg[ACTIVE] = @text_color
fg[INSENSITIVE] = mix (0.5, @bg_color, @text_color)
engine "murrine" {{
roundness = 0
}}
}}
style "murrine-menubaritem" {{
bg[NORMAL] = @bg_color
bg[PRELIGHT] = @selected_bg_color
bg[SELECTED] = @selected_bg_color
bg[ACTIVE] = shade (0.9, @bg_color)
bg[INSENSITIVE] = @bg_color
fg[NORMAL] = @text_color
fg[PRELIGHT] = shade (1.08, @text_color)
fg[SELECTED] = shade (1.08, @text_color)
fg[ACTIVE] = @text_color
fg[INSENSITIVE] = mix (0.5, @bg_color, @text_color)
engine "murrine" {{
roundness = 0
}}
}}
# Toolbars
style "murrine-toolbar" = "murrine-thin" {{
bg[NORMAL] = @bg_color
bg[PRELIGHT] = shade (1.02, @bg_color)
bg[SELECTED] = @selected_bg_color
bg[ACTIVE] = shade (0.9, @bg_color)
bg[INSENSITIVE] = @bg_color
fg[NORMAL] = @text_color
fg[PRELIGHT] = @text_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @text_color
fg[INSENSITIVE] = mix (0.5, @bg_color, @text_color)
engine "murrine" {{
}}
}}
style "murrine-toolbutton" = "murrine-button" {{
bg[NORMAL] = shade (1.08, @bg_color)
bg[PRELIGHT] = shade (1.10, @bg_color)
bg[SELECTED] = @selected_bg_color
bg[ACTIVE] = shade (0.95, @bg_color)
bg[INSENSITIVE] = shade (0.85, @bg_color)
fg[NORMAL] = @text_color
fg[PRELIGHT] = @text_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @text_color
fg[INSENSITIVE] = mix (0.5, @bg_color, @text_color)
engine "murrine" {{
}}
}}
class "GtkToolbar" style "murrine-toolbar"
class "GtkHandleBox" style "murrine-toolbar"
widget_class "*Toolbar*.*Separator*" style "murrine-toolbar"
# Panels
style "murrine-panel" = "murrine-thin" {{
xthickness = 2
bg[NORMAL] = @menu_bg_color
bg[PRELIGHT] = shade(0.8, @selected_bg_color)
bg[SELECTED] = @selected_bg_color
bg[ACTIVE] = @selected_bg_color
bg[INSENSITIVE] = @menu_bg_color
fg[NORMAL] = @text_color
fg[PRELIGHT] = @text_color
fg[SELECTED] = @text_color
fg[ACTIVE] = @text_color
fg[INSENSITIVE] = shade(0.8, @text_color)
base[NORMAL] = @menu_bg_color
base[PRELIGHT] = mix (0.21, @text_color, @menu_bg_color)
base[SELECTED] = @selected_bg_color
base[ACTIVE] = @selected_bg_color
base[INSENSITIVE] = @menu_bg_color
text[NORMAL] = @text_color
text[PRELIGHT] = shade (1.08, @text_color)
text[SELECTED] = shade (1.08, @text_color)
text[ACTIVE] = @text_color
text[INSENSITIVE] = mix (0.5, @menu_bg_color, @text_color)
engine "murrine" {{
roundness = 0
contrast = 0.0
}}
}}
widget "*PanelWidget*" style "murrine-panel"
widget "*PanelApplet*" style "murrine-panel"
widget "*fast-user-switch*" style "murrine-panel"
widget "*CPUFreq*Applet*" style "murrine-panel"
widget "*indicator-applet*" style "murrine-panel"
class "PanelApp*" style "murrine-panel"
class "PanelToplevel*" style "murrine-panel"
widget_class "*PanelToplevel*" style "murrine-panel"
widget_class "*notif*" style "murrine-panel"
widget_class "*Notif*" style "murrine-panel"
widget_class "*Tray*" style "murrine-panel"
widget_class "*tray*" style "murrine-panel"
widget_class "*computertemp*" style "murrine-panel"
widget_class "*Applet*Tomboy*" style "murrine-panel"
widget_class "*Applet*Netstatus*" style "murrine-panel"
widget "*gdm-user-switch-menubar*" style "murrine-panel"
style "bold-panel-item" {{
font_name = "Bold"
engine "murrine" {{
roundness = 0
}}
}}
widget "*Panel*MenuBar*" style "bold-panel-item"
widget "*gimmie*" style "bold-panel-item"
# widget_class "*Mail*" style "murrine-panel" # Disabled to fix Evolution bug
# class "*Panel*" style "murrine-panel" # Disabled to fix bug
# XFCE Styles
style "workspace-switcher" = "murrine-panel" {{
bg[SELECTED] = @selected_bg_color
}}
style "xfce-header" {{
bg[NORMAL] = shade (0.9, @bg_color)
base[NORMAL] = shade (1.18, @bg_color)
}}
style "xfdesktop-windowlist" {{
bg[NORMAL] = @bg_color
fg[INSENSITIVE] = shade (0.95, @bg_color)
text[INSENSITIVE] = shade (0.95, @bg_color)
}}
style "xfdesktop-icon-view" {{
XfdesktopIconView::label-alpha = 0
XfdesktopIconView::selected-label-alpha = 60
XfdesktopIconVIew::ellipsize-icon-labels = 1
base[NORMAL] = @selected_bg_color
base[SELECTED] = @selected_bg_color
base[ACTIVE] = @selected_bg_color
fg[NORMAL] = @selected_fg_color
fg[SELECTED] = @selected_fg_color
fg[ACTIVE] = @selected_fg_color
engine "murrine" {{
textstyle = 5
text_shade = 0.05
}}
}}
style "xfwm-tabwin" {{
Xfwm4TabwinWidget::border-width = 0
Xfwm4TabwinWidget::icon-size = 64
bg[NORMAL] = @menu_bg_color
fg[NORMAL] = @menu_fg_color
engine "murrine" {{
focusstyle = 0
}}
}}
style "xfsm-logout" {{
bg[NORMAL] = @menu_bg_color
bg[ACTIVE] = @menu_bg_color
bg[PRELIGHT] = shade (1.1, @menu_bg_color)
bg[SELECTED] = shade (0.5, @menu_bg_color)
bg[INSENSITIVE] = shade (1.3, @menu_bg_color)
fg[NORMAL] = @menu_fg_color
fg[PRELIGHT] = @menu_fg_color
text[NORMAL] = @menu_fg_color
engine "murrine" {{
}}
}}
style "xfsm-logout-button" {{
bg[NORMAL] = shade (1.2, @menu_bg_color)
bg[PRELIGHT] = shade (1.4, @menu_bg_color)
engine "murrine" {{
}}
}}
widget "*WnckPager*" style "workspace-switcher"
widget "*Xfce*Panel*" style "murrine-panel"
class "*Xfce*Panel*" style "murrine-panel"
# Thunar Styles
style "sidepane" {{
base[NORMAL] = @bg_color
base[INSENSITIVE] = shade(0.90, @bg_color)
bg[NORMAL] = @bg_color
text[NORMAL] = @text_color
}}
widget_class "*ThunarShortcutsView*" style "sidepane"
widget_class "*ThunarTreeView*" style "sidepane"
widget_class "*ThunarLocationEntry*" style "murrine-entry"
# Gtk2 Open-File Dialog
widget_class "*GtkFileChooserWidget.GtkFileChooserDefault.GtkVBox.GtkHPaned.GtkVBox.GtkScrolledWindow.GtkTreeView*" style "sidepane"
widget_class "*GtkFileChooserWidget.GtkFileChooserDefault.GtkVBox.GtkHPaned.GtkVBox.GtkScrolledWindow.<GtkTreeView>.<GtkButton>" style "murrine-treeview-header"
# Google Chrome/Chromium Styles (requires 9.0.597 or newer)
style "chromium-toolbar-button" {{
engine "murrine" {{
roundness = 2
textstyle = 0
}}
}}
style "chrome-gtk-frame" {{
ChromeGtkFrame::frame-color = @titlebar_bg_color
ChromeGtkFrame::inactive-frame-color = @titlebar_bg_color
ChromeGtkFrame::frame-gradient-size = 0
ChromeGtkFrame::frame-gradient-color = @titlebar_bg_color
ChromeGtkFrame::incognito-frame-color = @titlebar_bg_color
ChromeGtkFrame::incognito-inactive-frame-color = @titlebar_bg_color
ChromeGtkFrame::incognito-frame-gradient-size = 0
ChromeGtkFrame::incognito-frame-gradient-color = @titlebar_bg_color
ChromeGtkFrame::scrollbar-trough-color = @bg_color
ChromeGtkFrame::scrollbar-slider-normal-color = mix (0.21, @text_color, @bg_color)
ChromeGtkFrame::scrollbar-slider-prelight-color = mix (0.31, @text_color, @bg_color)
}}
class "ChromeGtkFrame" style "chrome-gtk-frame"
widget_class "*Chrom*Button*" style "chromium-toolbar-button"
# General Styles
class "GtkWidget" style "murrine-default"
class "GtkFrame" style "murrine-wide"
class "MetaFrames" style "metacity-frame"
class "GtkWindow" style "metacity-frame"
class "GtkSeparator" style "murrine-wide"
class "GtkCalendar" style "murrine-wide"
class "GtkSpinButton" style "murrine-spinbutton"
class "GtkScale" style "murrine-scale"
class "GtkVScale" style "murrine-vscale"
class "GtkHScale" style "murrine-hscale"
class "GtkScrollbar" style "murrine-scrollbar"
class "GtkVScrollbar" style "murrine-vscrollbar"
class "GtkHScrollbar" style "murrine-hscrollbar"
class "GtkRadio*" style "murrine-radiocheck"
class "GtkCheck*" style "murrine-radiocheck"
class "GtkEntry" style "murrine-entry"
widget_class "*<GtkNotebook>" style "murrine-notebook"
widget_class "*<GtkNotebook>*<GtkEventBox>" style "murrine-notebook-bg"
widget_class "*<GtkNotebook>*<GtkDrawingArea>" style "murrine-notebook-bg"
widget_class "*<GtkNotebook>*<GtkLayout>" style "murrine-notebook-bg"
widget_class "*.GtkNotebook.*.GtkViewport" style "murrine-notebook"
widget_class "*<GtkButton>" style "murrine-button"
widget_class "*<GtkStatusbar>*" style "murrine-statusbar"
widget_class "*<GtkProgress>" style "murrine-progressbar"
widget_class "*<GtkProgressBar>" style "murrine-progressbar"
widget_class "*<GtkComboBoxEntry>*" style "murrine-comboboxentry"
widget_class "*<GtkCombo>*" style "murrine-comboboxentry"
widget_class "*<GtkMenu>*" style "murrine-menu"
widget_class "*<GtkMenuItem>*" style "murrine-menu-item"
widget_class "*<GtkSeparatorMenuItem>*" style "murrine-separator-menu-item"
widget_class "*Menu*.*Sepa*" style "murrine-separator-menu-item"
widget_class "*<GtkMenuBar>*" style "murrine-menubar"
widget_class "*<GtkMenuBar>*<GtkMenuItem>*" style "murrine-menubaritem"
widget_class "*GtkToolButton*" style "murrine-toolbutton"
widget_class "*GtkToggleToolButton*" style "murrine-toolbutton"
widget_class "*GtkMenuToolButton*" style "murrine-toolbutton"
widget_class "*GtkToolbar*Button" style "murrine-toolbutton"
widget_class "*.<GtkFrame>.<GtkLabel>" style "murrine-frame-title"
widget_class "*.<GtkTreeView>*" style "murrine-treeview"
widget_class "*.<GtkTreeView>.<GtkButton>" style "murrine-treeview-header"
widget_class "*.<GtkCTree>.<GtkButton>" style "murrine-treeview-header"
widget_class "*.<GtkList>.<GtkButton>" style "murrine-treeview-header"
widget_class "*.<GtkCList>.<GtkButton>" style "murrine-treeview-header"
widget "gtk-tooltip*" style "murrine-tooltips"
widget_class "*<GtkScrolledWindow>*<OsScrollbar>" style "murrine-overlay-scrollbar"
# Workarounds and Non-Standard Styling
style "text-is-fg-color-workaround" {{
text[NORMAL] = @text_color
text[PRELIGHT] = @text_color
text[SELECTED] = @selected_fg_color
text[ACTIVE] = @text_color
text[INSENSITIVE] = mix (0.5, @bg_color, @text_color)
}}
widget_class "*.<GtkComboBox>.<GtkCellView>" style "text-is-fg-color-workaround"
style "fg-is-text-color-workaround" {{
fg[NORMAL] = @text_color
fg[PRELIGHT] = @text_color
fg[ACTIVE] = @selected_fg_color
fg[SELECTED] = @selected_fg_color
fg[INSENSITIVE] = darker (@text_color)
}}
widget_class "*<GtkListItem>*" style "fg-is-text-color-workaround"
widget_class "*<GtkCList>" style "fg-is-text-color-workaround"
widget_class "*<EelEditableLabel>" style "fg-is-text-color-workaround"
style "murrine-evo-new-button-workaround" {{
engine "murrine" {{
toolbarstyle = 0
}}
}}
widget_class "EShellWindow.GtkVBox.BonoboDock.BonoboDockBand.BonoboDockItem*" style "murrine-evo-new-button-workaround"
style "inkscape-toolbar-fix" {{
engine "murrine" {{
gradient_shades = {{ 1.0, 1.0, 1.0, 1.0 }}
highlight_shade = 1.0
}}
}}
#widget "*GtkHandleBox*" style "inkscape-toolbar-fix"
#widget "*HandleBox*CommandsToolbar*" style "inkscape-toolbar-fix"
#widget "*HandleBox*SnapToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*SelectToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*NodeToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*TweakToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*ZoomToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*StarToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*RectToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*3DBoxToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*ArcToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*SpiralToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*PencilToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*PenToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*CalligraphyToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*EraserToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*LPEToolToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*DropperToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*ConnectorToolbar*" style "inkscape-toolbar-fix"
widget "*HandleBox*PaintbucketToolbar*" style "inkscape-toolbar-fix"
# Performance Fixes
style "performance-fix" {{
engine "murrine" {{
textstyle = 0
}}
}}
widget_class "*gtkmm__GtkWindow*" style "performance-fix" # Inkscape
widget_class "*GimpDisplayShell*" style "performance-fix" # Gimp
widget_class "*GimpToolbox*" style "performance-fix"
widget_class "*GimpMenuDock*" style "performance-fix"
widget "*OOoFixed*" style "performance-fix" # Openoffice/Libreoffice
widget_class "*MozContainer*" style "performance-fix" # Firefox (Not sure if this one does anything though.)
widget_class "*XfceHeading*" style "xfce-header"
widget_class "*XfceDesktop*" style "xfdesktop-windowlist"
widget_class "*XfdesktopIconView*" style "xfdesktop-icon-view"
widget "xfwm4-tabwin*" style "xfwm-tabwin"
widget_class "*XfsmLogoutDialog*" style "xfsm-logout"
widget_class "*XfsmLogoutDialog*GtkButton" style "xfsm-logout-button"

View File

@ -0,0 +1,93 @@
/* Default color scheme */
@define-color bg_color {color0};
@define-color fg_color {color15};
@define-color base_color {color1};
@define-color text_color {color15};
@define-color selected_bg_color {active};
@define-color selected_fg_color {color15};
@define-color tooltip_bg_color {color0};
@define-color tooltip_fg_color {color15};
/* colormap actually used by the theme, to be overridden in other css files */
@define-color theme_bg_color @bg_color;
@define-color theme_fg_color @fg_color;
@define-color theme_base_color @base_color;
@define-color theme_text_color @text_color;
@define-color theme_selected_bg_color @selected_bg_color;
@define-color theme_selected_fg_color @selected_fg_color;
@define-color theme_tooltip_bg_color @tooltip_bg_color;
@define-color theme_tooltip_fg_color @tooltip_fg_color;
/* shadow effects */
@define-color light_shadow #eeeeee;
@define-color dark_shadow #222222;
/* misc colors used by gtk+ */
@define-color info_fg_color white;
@define-color info_bg_color #BACF66;
@define-color warning_fg_color white;
@define-color warning_bg_color #E6A682;
@define-color question_fg_color white;
@define-color question_bg_color #74C47B;
@define-color error_fg_color white;
@define-color error_bg_color #E682C8;
@define-color link_color mix (@theme_selected_bg_color, black, 0.15);
@define-color success_color #53a93f;
@define-color warning_color #f57900;
@define-color error_color #cc0000;
/* widget colors*/
@define-color border_color #363D43;
@define-color button_normal_color #3F474A;
@define-color button_info_color #72B279;
@define-color button_default_active_color shade(@theme_selected_bg_color, 0.857);
@define-color entry_border_color shade(@theme_base_color, 0.9);
@define-color frame_border_bottom_color #E3E4E7;
@define-color sel_color #B98CD7;
@define-color switch_bg_color #C9CBCF;
@define-color panel_bg_color @bg_color;
@define-color panel_fg_color @fg_color;
@define-color borders #FAFAFA;
@define-color scrollbar_trough shade(@theme_base_color, 0.9);
@define-color scrollbar_slider_prelight mix(@scrollbar_trough, @theme_fg_color, 0.5);
/* osd */
@define-color osd_separator #49525B;
@define-color osd_fg #ABB4BD;
@define-color osd_bg #434A54;
/* window manager colors */
@define-color wm_bg @theme_bg_color;
@define-color wm_title_focused @theme_fg_color;
@define-color wm_title_unfocused @theme_text_color;
@define-color wm_border_focused @border_color;
@define-color wm_border_unfocused @border_color;
@import url("gtk-widgets.css");
@import url("gtk-widgets-assets.css");
@import url("unity.css");
@import url("widgets/button.css");
@import url("widgets/cell-row.css");
@import url("widgets/check-radio.css");
@import url("widgets/column-header.css");
@import url("widgets/calendar.css");
@import url("widgets/entry.css");
@import url("widgets/infobar.css");
@import url("widgets/menu.css");
@import url("widgets/notebook.css");
@import url("widgets/progress-scale.css");
@import url("widgets/scrollbar.css");
@import url("widgets/separator.css");
@import url("widgets/sidebar.css");
@import url("widgets/spinbutton.css");
@import url("widgets/spinner.css");
@import url("widgets/switch.css");
@import url("widgets/color-chooser.css");
@import url("widgets/toolbar.css");
@import url("widgets/header-bar.css");
@import url("widgets/osd.css");
@import url("widgets/csd.css");
@import url("widgets/combobox.css");
@import url("widgets/selection-mode.css");

View File

@ -0,0 +1,108 @@
/* Default color scheme */
@define-color color0 {color0};
@define-color color1 {color1};
@define-color color2 {color2};
@define-color color3 {color3};
@define-color color4 {color4};
@define-color color5 {color5};
@define-color color6 {color6};
@define-color color7 {color7};
@define-color color8 {color8};
@define-color color9 {color9};
@define-color color10 {color10};
@define-color color11 {color11};
@define-color color12 {color12};
@define-color color13 {color13};
@define-color color14 {color14};
@define-color color15 {color15};
@define-color selected_bg_color {active};
@define-color bg_color mix(@color0, @color15, 0.12);
@define-color tooltip_bg_color mix(@color0, @color15, 0.04);
@define-color base_color mix(@color0, @color15, 0);
@define-color fg_color @color15;
@define-color text_color @color15;
@define-color selected_fg_color @color15;
@define-color tooltip_fg_color @color15;
/* colormap actually used by the theme, to be overridden in other css files */
@define-color theme_bg_color @bg_color;
@define-color theme_fg_color @fg_color;
@define-color theme_base_color @base_color;
@define-color theme_text_color @text_color;
@define-color theme_selected_bg_color @selected_bg_color;
@define-color theme_selected_fg_color @selected_fg_color;
@define-color theme_tooltip_bg_color @tooltip_bg_color;
@define-color theme_tooltip_fg_color @tooltip_fg_color;
/* shadow effects */
@define-color light_shadow #eeeeee;
@define-color dark_shadow #222222;
/* misc colors used by gtk+ */
@define-color info_fg_color @text_color;
@define-color info_bg_color @bg_color;
@define-color warning_fg_color @text_color;
@define-color warning_bg_color @bg_color;
@define-color question_fg_color @text_color;
@define-color question_bg_color @theme_selected_bg_color;
@define-color error_fg_color @text_color;
@define-color error_bg_color #f52400;
@define-color link_color mix (@theme_selected_bg_color, black, 0.15);
@define-color success_color #53a93f;
@define-color warning_color #f57900;
@define-color error_color #f52400;
/* widget colors*/
@define-color border_color shade(@theme_selected_bg_color, 0.2);
@define-color button_normal_color shade(@theme_bg_color, 1.20);
@define-color button_info_color @theme_selected_bg_color;
@define-color button_default_active_color @theme_selected_bg_color;
@define-color entry_border_color shade(@theme_base_color, 0.9);
@define-color frame_border_bottom_color shade(@bg_color, 0.8);
@define-color sel_color shade(@theme_selected_bg_color, 0.857);
@define-color switch_bg_color shade(@bg_color, 0.8);
@define-color panel_bg_color @bg_color;
@define-color panel_fg_color @fg_color;
@define-color borders shade(@theme_selected_bg_color, 0.857);
@define-color scrollbar_trough shade(@theme_base_color, 0.9);
@define-color scrollbar_slider_prelight mix(@scrollbar_trough, @theme_fg_color, 0.5);
/* osd */
@define-color osd_separator #49525B;
@define-color osd_fg #ABB4BD;
@define-color osd_bg #434A54;
/* window manager colors */
@define-color wm_bg @theme_bg_color;
@define-color wm_title_focused @theme_fg_color;
@define-color wm_title_unfocused @theme_text_color;
@define-color wm_border_focused @border_color;
@define-color wm_border_unfocused @border_color;
@import url("gtk-widgets.css");
@import url("unity.css");
@import url("widgets/button.css");
@import url("widgets/cell-row.css");
@import url("widgets/check-radio.css");
@import url("widgets/column-header.css");
@import url("widgets/calendar.css");
@import url("widgets/entry.css");
@import url("widgets/infobar.css");
@import url("widgets/menu.css");
@import url("widgets/notebook.css");
@import url("widgets/progress-scale.css");
@import url("widgets/scrollbar.css");
@import url("widgets/separator.css");
@import url("widgets/sidebar.css");
@import url("widgets/chrome.css");
@import url("widgets/spinbutton.css");
@import url("widgets/spinner.css");
@import url("widgets/switch.css");
@import url("widgets/color-chooser.css");
@import url("widgets/toolbar.css");
@import url("widgets/header-bar.css");
@import url("widgets/osd.css");
@import url("widgets/csd.css");
@import url("widgets/combobox.css");
@import url("widgets/selection-mode.css");

19
.config/wpg/wpg.conf Normal file
View File

@ -0,0 +1,19 @@
[settings]
set_wallpaper = true
gtk = true
active = 0
light_theme = false
editor = urxvt -e vim
execute_cmd = true
command = theme-reload
backend = wal
alpha = 100
smart_sort = true
auto_adjust = false
reload = true
terminal = true
keywords = default
vte = true
[keywords]

View File

@ -0,0 +1,9 @@
Net/ThemeName "FlatColor"
Net/IconThemeName "Papirus-Dark"
Gtk/CursorThemeName "Posy_Cursor"
Net/EnableEventSounds 1
EnableInputFeedbackSounds 1
Xft/Antialias 1
Xft/Hinting 1
Xft/HintStyle "hintslight"
Xft/RGBA "rgb"

22
.config/yazi/edit.sh Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -eo pipefail
CWD=$(dirname "$1")
if [ -n "$TMUX" ]; then
if tmux list-panes -F "#{pane_title}" 2>/dev/null | grep -q "^$EDITOR$"; then
tmux send-keys -t "$EDITOR" ":e $1" Enter
else
tmux split-window -h -p 83 -c "$CWD" -P -F "#{pane_id}" "exec $EDITOR '$1'"
tmux select-pane -T "$EDITOR"
tmux split-window -v -p 20 -c "$CWD"
fi
elif [ -n "$KITTY_WINDOW_ID" ]; then
if kitty @ focus-window --match "title:$EDITOR" 2>/dev/null; then
kitty @ send-text --match "title:$EDITOR" ":e $1\x0d"
else
kitty @ launch --title "$EDITOR" --location=vsplit --bias=83 --cwd "$CWD" bash -c "'$EDITOR' '$1'; while true; do '$EDITOR'; done"
kitty @ launch --title "CLI" --dont-take-focus --location=hsplit --bias=20 --cwd "$CWD"
fi
else
"$EDITOR" "$1"
fi

14
.config/yazi/init.lua Normal file
View File

@ -0,0 +1,14 @@
Status:children_add(function()
local h = cx.active.current.hovered
if not h or ya.target_family() ~= "unix" then
return ""
end
return ui.Line {
ui.Span(ya.user_name(h.cha.uid) or tostring(h.cha.uid)):fg("magenta"),
":",
ui.Span(ya.group_name(h.cha.gid) or tostring(h.cha.gid)):fg("magenta"),
" ",
}
end, 500, Status.RIGHT)
require("full-border"):setup()

View File

@ -0,0 +1,7 @@
[[plugin.deps]]
use = "yazi-rs/plugins:full-border"
rev = "1ab21d4"
hash = "3996fc74044bc44144b323686f887e1"
[flavor]
deps = []

7
.config/yazi/yazi.toml Normal file
View File

@ -0,0 +1,7 @@
[mgr]
ratio = [1, 1, 1]
# [opener]
# edit = [
# { run = "~/.config/yazi/edit.sh \"$@\"", block = true }
# ]

9
.fdignore Normal file
View File

@ -0,0 +1,9 @@
.git
build
drive_c
pfx
dosdevices
SteamLinux*
*.mca

160
.local/bin/theme Executable file
View File

@ -0,0 +1,160 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT=$(basename "$0")
CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}"
VCONSOLE_UPDATE="$HOME/.local/bin/vconsole-colors.sh"
WALLPAPER="${CONFIG}/hypr/wallpaper"
QUIET_MODE=false
SKIP_VCONSOLE=false
SKIP_INITRAMFS=false
show_help() {
cat <<EOF
Usage: $0 [OPTIONS] <input_file>
A script to update system theme based on a wallpaper image.
Options:
-h, --help Show this help message and exit
-q, --quiet Quiet mode: Suppress output to the terminal
-n Skip prompting to regenerate initramfs
-nn Skip prompting to update vconsole.conf
Examples:
$0 /path/to/image/sunset.jpg # Normal theme update
$0 -q ~/wallpapers/night.jpg # Quiet mode theme update
$0 -q -n ~/Downloads/nature.jpg # Combine quiet mode and skip initramfs
Requirements:
- Requires an input image file
- Depends on pywal, wpg, swaync, pywalfox, and spicetify
EOF
exit 0
}
validate_image() {
local file="$1"
local mime_type
[[ -f "$file" ]] || die "File '$file' not found."
mime_type=$(file --mime-type -b "$file")
local allowed_types=(
"image/jpeg"
"image/png"
"image/gif"
"image/bmp"
"image/webp"
"image/tiff"
"image/x-icon"
"image/svg+xml"
)
local is_image=false
for type in "${allowed_types[@]}"; do
if [[ "$mime_type" == "$type" ]]; then
is_image=true
break
fi
done
if [[ "$is_image" == false ]]; then
die "File '$file' is not a valid image. Mime type detected: $mime_type"
fi
}
quiet_exec() {
if [[ "$QUIET_MODE" == true ]]; then
"$@" >/dev/null 2>&1 || return 1
else
"$@" || return 1
fi
}
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
show_help
;;
-q|--quiet)
QUIET_MODE=true
shift
;;
-n)
SKIP_INITRAMFS=true
shift
;;
-nn)
SKIP_VCONSOLE=true
shift
;;
*)
break
;;
esac
done
log() {
if [[ "$QUIET_MODE" == false ]]; then
logger -i -t "$SCRIPT" "$*"
fi
}
die() {
logger -i -t "$SCRIPT" ":Error:" "$*"
exit 1
}
[[ $# -eq 1 ]] || die "Usage: $0 [-h] [-q] [-n] [-nn] <input_file>"
IMAGE="$1"
validate_image "$IMAGE"
quiet_exec wal -i "$IMAGE" -n || die "Pywal update failed"
quiet_exec wpg -a "$(echo "$IMAGE")" || die "Pywal adding failed."
quiet_exec wpg -s "$(basename "$IMAGE")" || die "Pywal update failed."
quiet_exec ln -sf "$(realpath "$IMAGE")" "$WALLPAPER"
# quiet_exec eww reload
# quiet_exec swaync-client -R
# quiet_exec killall swaync
quiet_exec pywalfox update
quiet_exec spicetify apply
# quiet_exec swaync-client -rs
notify-send "New theme applied!"
if [[ "$SKIP_VCONSOLE" == false ]]; then
if [[ "$QUIET_MODE" == false ]]; then
read -rp "Update vconsole.conf? (y/N): " VCONSOLE
else
VCONSOLE="y"
fi
if [[ "${VCONSOLE,,}" =~ ^y(es)?$ ]]; then
[[ -f "$VCONSOLE_UPDATE" ]] || die "Vconsole update script not found"
log "Running vconsole-colors update script..."
quiet_exec sudo bash "$VCONSOLE_UPDATE"
if [[ "$SKIP_INITRAMFS" == false ]]; then
if [[ "$QUIET_MODE" == false ]]; then
read -rp "Regenerate initramfs? Colors won't apply until it is. (y/N): " INITRAMFS
else
INITRAMFS="y"
fi
if [[ "${INITRAMFS,,}" =~ ^y(es)?$ ]]; then
log "Regenerating initramfs from theme swap..."
quiet_exec sudo mkinitcpio -P
else
log "Not regenerating initramfs. New colors won't apply until it has been."
fi
fi
else
log "Skipping vconsole.conf update for new theme."
fi
fi
exit 0

38
.local/bin/theme-reload Executable file
View File

@ -0,0 +1,38 @@
#!/bin/bash
COUNT=0
POTENTIAL=0
if command -v eww &> /dev/null; then
eww reload
COUNT=$(( COUNT + $? ))
((POTENTIAL++))
fi
if command -v pywalfox &> /dev/null; then
pywalfox update
COUNT=$(( COUNT + $? ))
((POTENTIAL++))
fi
if command -v spicetify &> /dev/null; then
spicetify apply
COUNT=$(( COUNT + 0 ))
((POTENTIAL++))
fi
if command -v swaync &> /dev/null; then
swaync-client -rs
COUNT=$(( COUNT + $? ))
((POTENTIAL++))
fi
if [[ $COUNT -ne 0 ]] && [[ $COUNT -eq $POTENTIAL ]]; then
notify-send -u critical "Failed to reload."
exit 0
fi
if [[ $COUNT -ne 0 ]]; then
notify-send -u critical "Failed to reload some colors"
else
notify-send "Colors changed" --expire-time=1000
fi
exit 0

26
.local/bin/universal_run.sh Executable file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -eo pipefail
SCRIPT="${BASH_SOURCE[0]}"
fail() {
echo "ERR - $SCRIPT: $1"
exit 1
}
DIR="$1"
if [[ -z $DIR ]]; then
DIR=$(pwd)
fi
if [[ ! -d $DIR ]]; then
echo "Usage: $SCRIPT <Project Directory>"
exit 1
fi
pushd "$DIR" || fail "Couldn't enter directory."
if [[ -x "run.sh" ]]; then
./run.sh
elif [[ -f "Cargo.toml" ]]; then
cargo run
fi
popd >/dev/null || exit 1

89
.local/bin/vconsole-colors.sh Executable file
View File

@ -0,0 +1,89 @@
#!/usr/bin/env bash
SCRIPT_NAME=$(basename "$0")
VERSION="1.0.0"
log() {
local level="$1"
local message="$2"
local timestamp
timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo "[${timestamp}] [${level}] ${message}" >&2
}
check_root() {
if [[ $EUID -ne 0 ]]; then
log "ERROR" "This script must be run with sudo or as root."
exit 1
fi
}
get_real_user() {
USER="${SUDO_USER:-$(whoami)}"
if [[ -z "$USER" ]]; then
log "ERROR" "Unable to determine non-root user."
exit 1
fi
COLOR_FILE="/home/$USER/.cache/wal/colors.sh"
}
validate_color_source() {
if [[ ! -f "$COLOR_FILE" ]]; then
log "ERROR" "Color configuration file not found: $COLOR_FILE"
exit 1
fi
source "$COLOR_FILE"
}
update_vconsole() {
local color_var="$1"
local color_value="$2"
local vconsole_conf="/etc/vconsole.conf"
color_value=$(printf "%s" "$color_value" | tr '[:upper:]' '[:lower:]' | sed 's/^#//')
cp "$vconsole_conf" "${vconsole_conf}.bak"
if grep -q "^COLOR_${color_var}=" "$vconsole_conf"; then
sed -i "s/^COLOR_${color_var}=.*/COLOR_${color_var}=${color_value}/" "$vconsole_conf"
else
echo "COLOR_${color_var}=${color_value}" >> "$vconsole_conf"
fi
}
main() {
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
echo "Usage: (as root) $SCRIPT_NAME [options]"
echo "Updates vconsole.conf with pywal color scheme"
echo " -h, --help Show this help message"
echo " -v, --version Show script version"
exit 0
;;
-v|--version)
echo "$SCRIPT_NAME version $VERSION"
exit 0
;;
*)
log "ERROR" "Unknown option: $1"
exit 1
;;
esac
done
check_root
get_real_user
validate_color_source
for i in {0..15}; do
color_var="color$i"
if [[ -n "${!color_var:-}" ]]; then
update_vconsole "$i" "${!color_var}"
fi
done
log "INFO" "vconsole.conf updated successfully!"
}
main "$@"

25
.local/bin/weather Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_NAME=$(basename "${BASH_SOURCE[0]}")
WEATHER="/tmp/wttr.in"
CONFIG="$XDG_CONFIG_HOME/fastfetch/small.jsonc"
log() {
logger -i -t "$SCRIPT_NAME" "$*"
}
main() {
TIME=$(date +%H:%M)
if [[ "$TIME" < "12:00" ]] && [[ "$TIME" > "00:00" ]]; then
log "Getting weather and sunrise time."
curl -s wttr.in/hartford\?format="%c\n%t\n%S\n" > "$WEATHER"
else
log "Getting weather and sunset time."
curl -s wttr.in/hartford\?format="%c\n%t\n%s\n" > "$WEATHER"
fi
CURRENT=$(cat "$WEATHER")
CONDITION=$(echo "$CURRENT" | head -n 1 | perl -CS -pe 's/\x{FE0F}//g' | tr -d '[:space:]' | xargs) envsubst < "$CONFIG" > /tmp/small.jsonc
}
main

35
.profile Normal file
View File

@ -0,0 +1,35 @@
export TERMINAL=kitty
export BROWSER=librewolf
export EDITOR=helix
export VISUAL=helix
export BAT_THEME=base16
# XDG STANDARD DIRS
export XDG_DATA_HOME="$HOME/.local/share"
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_STATE_HOME="$HOME/.local/state"
export XDG_CACHE_HOME="$HOME/.cache"
# XDG-NINJA FIXES
#
export HISTFILE="$XDG_STATE_HOME/bash/history"
export CARGO_HOME="$XDG_DATA_HOME/cargo"
export CUDA_CACHE_PATH="$XDG_CACHE_HOME/nv"
export GNUPGHOME="$XDG_DATA_HOME/gnupg"
export GTK2_RC_FILES="$XDG_CONFIG_HOME/gtk-2.0/gtkrc"
export XCURSOR_PATH=/usr/share/icons:$XDG_DATA_HOME/icons
export NVM_DIR="$XDG_DATA_HOME/nvm"
export PARALLEL_HOME="$XDG_CONFIG_HOME/parallel"
export RUSTUP_HOME="$XDG_DATA_HOME/rustup"
export W3M_DIR="$XDG_DATA_HOME/w3m"
export NPM_CONFIG_USERCONFIG="$XDG_CONFIG_HOME/npm/npmrc"
export _JAVA_OPTIONS=-Djava.utils.prefs.userRoot="$XDG_CONFIG_HOME/java"
export DOCKER_CONFIG="$XDG_CONFIG_HOME/docker"
export GRADLE_USER_HOME="$XDG_DATA_HOME/gradle"
export SQLITE_HISTORY="$XDG_CACHE_HOME/sqlite_history"
export PATH=$PATH:"$HOME/.local/bin"
# PATH CLEANUP
# shellcheck disable=SC2155
export PATH=$(printf "%s" "$PATH" | awk -v RS=':' '!a[$1]++ { if (NR > 1) printf RS; printf $1 }')

22
README Normal file
View File

@ -0,0 +1,22 @@
Dotfiles I use
Requires:
bat
curl
eza
fd
fish
fastfetch
fzf
helix
hyprland
kitty
mpd
python-pywal
quickshell
rofi
ripgrep
swaybg
wpgtk
yazi