Compare commits

...

12 Commits

Author SHA1 Message Date
Sem
6dfd4eac43 Add base of sddm theme 2026-04-20 21:21:03 +02:00
Sem
f8c8536ce3 added a lil' fella 2026-04-18 00:40:26 +02:00
Sem
24b0c41ffb improve config for cava and add base for equalizer. It works but needs some performance fixes 2026-04-18 00:06:45 +02:00
Sem
7bcd3220dd WIP cava process 2026-04-10 23:58:23 +02:00
Sem
9f5eb82fe1 Add cava and TODO for frequency graph 2026-04-10 00:05:30 +02:00
Sem
9d04b30629 add now playing info 2026-04-07 23:48:02 +02:00
Sem
225538148d Add separate file for workspaces list 2026-04-07 23:37:14 +02:00
Sem
553a7b3ad4 Add comment for nerd fonts cheat sheet 2026-04-07 22:58:10 +02:00
Sem
328dfa1786 Add bluetooth icon 2026-04-07 22:10:33 +02:00
Sem
3f27d6618a Add date and time parsing and add colors from matugen to all current elements of top bar 2026-04-03 21:29:47 +02:00
Sem
506aeeff43 Add showing level of value through bar 2026-04-03 19:52:27 +02:00
Sem
406b8eb628 add overview and use matugen colors on workspace switcher 2026-04-03 18:03:11 +02:00
30 changed files with 2037 additions and 64 deletions

330
cava/config Normal file
View File

@@ -0,0 +1,330 @@
## Configuration file for CAVA.
# Remove the ; to change parameters.
[general]
# Auto reload config if the configuration file has changed. 1 = on, 0 = off.
; live-config = 0
# Smoothing mode. Can be 'normal', 'scientific' or 'waves'. DEPRECATED as of 0.6.0
; mode = normal
# Accepts only non-negative values.
framerate = 60
# 'autosens' will attempt to decrease sensitivity if the bars peak. 1 = on, 0 = off
# new as of 0.6.0 autosens of low values (dynamic range)
# 'overshoot' allows bars to overshoot (in % of terminal height) without initiating autosens. DEPRECATED as of 0.6.0
autosens = 1
; overshoot = 20
# Manual sensitivity in %. If autosens is enabled, this will only be the initial value.
# 200 means double height. Accepts only non-negative values.
sensitivity = 40
# The number of bars (0-512). 0 sets it to auto (fill up console).
# Bars' width and space between bars in number of characters.
bars = 32
; bar_width = 2
; bar_spacing = 1
# bar_height is only used for output in "noritake" format
; bar_height = 32
# For SDL width and space between bars is in pixels, defaults are:
; bar_width = 20
; bar_spacing = 5
# sdl_glsl have these default values, they are only used to calculate max number of bars.
; bar_width = 1
; bar_spacing = 0
# ceter bars in terminal, if there is space.
center_align = 0
# max height of bars in terminal, in percent of terminal height.
; max_height = 100
# Lower and higher cutoff frequencies for lowest and highest bars
# the bandwidth of the visualizer.
# Note: there is a minimum total bandwidth of 43Mhz x number of bars.
# Cava will automatically increase the higher cutoff frequency if needed to satisfy the minimum bandwidth.
; lower_cutoff_freq = 50
; higher_cutoff_freq = 10000
# Seconds with no input before cava goes to sleep mode. Cava will not perform FFT or drawing and
# only check for input once per second. Cava will wake up once input is detected. 0 = disable.
; sleep_timer = 0
[input]
# Audio capturing method. Possible methods are: 'fifo', 'portaudio', 'pipewire', 'alsa', 'pulse', 'sndio', 'oss', 'jack' or 'shmem'
# Defaults to 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', 'portaudio' or 'fifo', in that order, dependent on what support cava was built with.
# On Mac it defaults to 'portaudio' or 'fifo'
# On windows this is automatic and no input settings are needed.
#
# All input methods uses the same config variable 'source'
# to define where it should get the audio.
#
# For pulseaudio and pipewire 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink
# (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them).
#
# For pipewire 'source' will be the object name or object.serial of the device to capture from.
# Both input and output devices are supported. To capture the monitor source of a sink node, append '.monitor' to the sink's object name.
#
# For alsa 'source' will be the capture device.
# For fifo 'source' will be the path to fifo-file.
# For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:EE:FF' will be squeezelite's MAC address
#
# For sndio 'source' will be a raw recording audio descriptor or a monitoring sub-device, e.g. 'rsnd/2' or 'snd/1'. Default: 'default'.
# README.md contains further information on how to setup CAVA for sndio.
#
# For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. Default: '/dev/dsp', i.e. the default audio device.
# README.md contains further information on how to setup CAVA for OSS on FreeBSD.
#
# For jack 'source' will be the name of the JACK server to connect to, e.g. 'foobar'. Default: 'default'.
# README.md contains further information on how to setup CAVA for JACK.
#
; method = pulse
; source = auto
; method = pipewire
; source = auto
; method = alsa
; source = hw:Loopback,1
; method = fifo
; source = /tmp/mpd.fifo
; method = shmem
; source = /squeezelite-AA:BB:CC:DD:EE:FF
; method = portaudio
; source = auto
; method = sndio
; source = default
; method = oss
; source = /dev/dsp
; method = jack
; source = default
# The options 'sample_rate', 'sample_bits', 'channels' and 'autoconnect' can be configured for some input methods:
# sample_rate: fifo, pipewire, sndio, oss
# sample_bits: fifo, pipewire, sndio, oss
# channels: sndio, oss, jack
# autoconnect: jack
# Other methods ignore these settings.
# For pipewire, sample_rate will default to 48000, for all other input methods, sample_rate will default to 44100.
#
# For 'sndio' and 'oss' they are only preferred values, i.e. if the values are not supported
# by the chosen audio device, the device will use other supported values instead.
# Example: 48000, 32 and 2, but the device only supports 44100, 16 and 1, then it
# will use 44100, 16 and 1.
#
#
# The 'pipewire' input method has three options to control linking and mixing:
# active: Force the node to always process. Useful for monitoring sources when no other application is active.
# remix: Allow pipewire to remix audio channels to match cava's channel count. Useful for surround sound.
# virtual: Set the node to virtual, to avoid recording notifications from the DE.
#
; sample_rate = 44100
; sample_bits = 16
; channels = 2
; autoconnect = 2
; active = 1
; remix = 1
; virtual = 1
[output]
# Output method. Can be 'ncurses', 'noncurses', 'raw', 'noritake', 'sdl'
# or 'sdl_glsl'.
# 'noncurses' (default) uses a buffer and cursor movements to only print
# changes from frame to frame in the terminal. Uses less resources and is less
# prone to tearing (vsync issues) than 'ncurses'.
#
# 'raw' is an 8 or 16 bit (configurable via the 'bit_format' option) data
# stream of the bar heights that can be used to send to other applications.
# 'raw' defaults to 1024 bars stereo (512 bars mono), which can be adjusted in the 'bars' option above.
#
# 'noritake' outputs a bitmap in the format expected by a Noritake VFD display
# in graphic mode. It only support the 3000 series graphical VFDs for now.
#
# 'sdl' uses the Simple DirectMedia Layer to render in a graphical context.
# 'sdl_glsl' uses SDL to create an OpenGL context. Write your own shaders or
# use one of the predefined ones.
method = raw
# Orientation of the visualization. Can be 'bottom', 'top', 'left', 'right' or
# 'horizontal'. Default is 'bottom'. 'left and 'right' are only supported on sdl
# and ncruses output. 'horizontal' (bars go up and down from center) is only supported
# on noncurses output.
# Note: many fonts have weird or missing glyphs for characters used in orientations
# other than 'bottom', which can make output not look right.
; orientation = bottom
# Visual channels. Can be 'stereo' or 'mono'.
# 'stereo' mirrors both channels with low frequencies in center.
# 'mono' outputs left to right lowest to highest frequencies.
# 'mono_option' set mono to either take input from 'left', 'right' or 'average'.
# set 'reverse' to 1 to display frequencies the other way around.
channels = mono
mono_option = average
reverse = 0
# Only valid if orientation is set to 'horizontal'.
# Set 'horizontal_stereo' to 1 to have left channel bars at top and right channel at bottom.
# Set 'left_bottom' to 0 to have right channel at top and left channel at bottom.
; horizontal_stereo = 0
; left_bottom = 1
# Raw output target.
# On Linux, a fifo will be created if target does not exist.
# On Windows, a named pipe will be created if target does not exist.
raw_target = /tmp/cava.fifo
# Raw data format. Can be 'binary' or 'ascii'.
data_format = ascii
# Binary bit format, can be '8bit' (0-255) or '16bit' (0-65530).
; bit_format = 16bit
# Ascii max value. In 'ascii' mode range will run from 0 to value specified here
ascii_max_range = 100
# Ascii delimiters. In ascii format each bar and frame is separated by a delimiters.
# Use decimal value in ascii table (i.e. 59 = ';' and 10 = '\n' (line feed)).
bar_delimiter = 59
frame_delimiter = 10
# sdl window size and position. -1,-1 is centered.
; sdl_width = 1024
; sdl_height = 512
; sdl_x = -1
; sdl_y= -1
; sdl_full_screen = 0
# set label on bars on the x-axis. Can be 'frequency' or 'none'. Default: 'none'
# 'frequency' displays the lower cut off frequency of the bar above.
# Only supported on ncurses and noncurses output.
; xaxis = none
# enable synchronized sync. 1 = on, 0 = off
# removes flickering in alacritty terminal emulator.
# defaults to off since the behaviour in other terminal emulators is unknown
; synchronized_sync = 0
# Shaders for sdl_glsl, located in $HOME/.config/cava/shaders
; vertex_shader = pass_through.vert
; fragment_shader = bar_spectrum.frag
; for glsl output mode, keep rendering even if no audio
; continuous_rendering = 0
# disable console blank (screen saver) in tty
# (Not supported on FreeBSD)
; disable_blanking = 0
# show a flat bar at the bottom of the screen when idle, 1 = on, 0 = off
; show_idle_bar_heads = 1
# show waveform instead of frequency spectrum, 1 = on, 0 = off
; waveform = 0
[color]
# Colors can be one of seven predefined: black, blue, cyan, green, magenta, red, white, yellow.
# Or defined by hex code '#xxxxxx' (hex code must be within ''). User defined colors requires
# a terminal that can change color definitions such as Gnome-terminal or rxvt.
# default is to keep current terminal color
; background = default
; foreground = default
# SDL and sdl_glsl only support hex code colors, these are the default:
; background = '#111111'
; foreground = '#33ffff'
# Gradient mode, only hex defined colors are supported,
# background must also be defined in hex or remain commented out. 1 = on, 0 = off.
# You can define as many as 8 different colors. They range from bottom to top of screen
; gradient = 0
; gradient_color_1 = '#59cc33'
; gradient_color_2 = '#80cc33'
; gradient_color_3 = '#a6cc33'
; gradient_color_4 = '#cccc33'
; gradient_color_5 = '#cca633'
; gradient_color_6 = '#cc8033'
; gradient_color_7 = '#cc5933'
; gradient_color_8 = '#cc3333'
# Horizontal is only supported on noncurses output.
# Only one color will be calculated per bar.
; horizontal_gradient = 0
; horizontal_gradient_color_1 = '#c45161'
; horizontal_gradient_color_2 = '#e094a0'
; horizontal_gradient_color_3 = '#f2b6c0'
; horizontal_gradient_color_4 = '#f2dde1'
; horizontal_gradient_color_5 = '#cbc7d8'
; horizontal_gradient_color_6 = '#8db7d2'
; horizontal_gradient_color_7 = '#5e62a9'
; horizontal_gradient_color_8 = '#434279'
# If both vertical and horizontal gradient is enabled, vertical will be blended in this direction.
# Can be 'up', 'down', 'left' or 'right'. 'up' means the vertical gradient will be blended in from
# bottom to top. I.e. the bottom will be only the horizontal
# and top will be only the color of the vertical gradient.
; blend_direction = 'up'
# use theme file instead of defining colors in this file
# themes are located in $HOME/.config/cava/themes
; theme = 'none'
[smoothing]
# Percentage value for integral smoothing. Takes values from 0 - 100.
# Higher values means smoother, but less precise. 0 to disable.
# DEPRECATED as of 0.8.0, use noise_reduction instead
; integral = 77
# Disables or enables the so-called "Monstercat smoothing" with or without "waves". Set to 0 to disable.
; monstercat = 0
; waves = 0
# Set gravity percentage for "drop off". Higher values means bars will drop faster.
# Accepts only non-negative values. 50 means half gravity, 200 means double. Set to 0 to disable "drop off".
# DEPRECATED as of 0.8.0, use noise_reduction instead
gravity = 150
# In bar height, bars that would have been lower that this will not be drawn.
# DEPRECATED as of 0.8.0
; ignore = 0
# Noise reduction, int 0 - 100. default 77
# the raw visualization is very noisy, this factor adjusts the integral and gravity filters to keep the signal smooth
# 100 will be very slow and smooth, 0 will be fast but noisy.
; noise_reduction = 77
[eq]
# This one is tricky. You can have as much keys as you want.
# Remember to uncomment more than one key! More keys = more precision.
# Look at readme.md on github for further explanations and examples.
; 1 = 1 # bass
; 2 = 1
; 3 = 1 # midtone
; 4 = 1
; 5 = 1 # treble

332
cava/example_config Normal file
View File

@@ -0,0 +1,332 @@
## Configuration file for CAVA.
# Lines starting with ; show config parameters and default values.
# Remove the ; to change parameters.
[general]
# Auto reload config if the configuration file has changed. 1 = on, 0 = off.
; live-config = 0
# Accepts only non-negative values.
; framerate = 60
# 'autosens' will attempt to decrease sensitivity if the bars peak and increase slowly as
# long as the bars don't peak. 0 = off, 1 = normal, 2..n = more aggressive.
# increase to make sensitivity increase even faster.
; autosens = 1
# Manual sensitivity in %. If autosens is enabled, this will only be the initial value.
# 200 means double height. Accepts only non-negative values.
; sensitivity = 100
# The number of bars (0-512). 0 sets it to auto (fill up console).
# Bars' width and space between bars in number of characters.
; bars = 0
; bar_width = 2
; bar_spacing = 1
# bar_height is only used for output in "noritake" format
; bar_height = 32
# For SDL width and space between bars is in pixels, defaults are:
; bar_width = 20
; bar_spacing = 5
# sdl_glsl have these default values, they are only used to calculate max number of bars.
; bar_width = 1
; bar_spacing = 0
# center bars in terminal, if there is space.
center_align = 0
# max height of bars in terminal, in percent of terminal height.
; max_height = 100
# Lower and higher cutoff frequencies for lowest and highest bars
# the bandwidth of the visualizer.
# Note: there is a minimum total bandwidth of 43Mhz x number of bars.
# Cava will automatically increase the higher cutoff frequency if needed to satisfy the minimum bandwidth.
; lower_cutoff_freq = 50
; higher_cutoff_freq = 10000
# Seconds with no input before cava goes to sleep mode. Cava will not perform FFT or drawing and
# only check for input once per second. Cava will wake up once input is detected. 0 = disable.
; sleep_timer = 0
[input]
# Audio capturing method. Possible methods are: 'fifo', 'portaudio', 'pipewire', 'alsa', 'pulse', 'sndio', 'oss', 'jack' or 'shmem'
# Defaults to 'oss', 'pipewire', 'sndio', 'jack', 'pulse', 'alsa', 'portaudio' or 'fifo', in that order, dependent on what support cava was built with.
# On Mac it defaults to 'portaudio' or 'fifo'
# On Windows this is automatic and no input settings are needed.
#
# Each input method uses the same config variable 'source'
# to define where it should get the audio.
#
# For pulseaudio and pipewire 'source' will be the source. Default: 'auto', which uses the monitor source of the default sink
# (all pulseaudio sinks(outputs) have 'monitor' sources(inputs) associated with them).
#
# For pipewire 'source' will be the object name or object.serial of the device to capture from.
# Both input and output devices are supported. To capture the monitor source of a sink node, append '.monitor' to the sink's object name.
#
# For alsa 'source' will be the capture device.
# For fifo 'source' will be the path to fifo-file.
# For shmem 'source' will be /squeezelite-AA:BB:CC:DD:EE:FF where 'AA:BB:CC:DD:EE:FF' will be squeezelite's MAC address
#
# For sndio 'source' will be a raw recording audio descriptor or a monitoring sub-device, e.g. 'rsnd/2' or 'snd/1'. Default: 'default'.
# README.md contains further information on how to setup CAVA for sndio.
#
# For oss 'source' will be the path to a audio device, e.g. '/dev/dsp2'. Default: '/dev/dsp', i.e. the default audio device.
# README.md contains further information on how to setup CAVA for OSS on FreeBSD.
#
# For jack 'source' will be the name of the JACK server to connect to, e.g. 'foobar'. Default: 'default'.
# README.md contains further information on how to setup CAVA for JACK.
#
; method = pulse
; source = auto
; method = pipewire
; source = auto
; method = alsa
; source = hw:Loopback,1
; method = fifo
; source = /tmp/mpd.fifo
; method = shmem
; source = /squeezelite-AA:BB:CC:DD:EE:FF
; method = portaudio
; source = auto
; method = sndio
; source = default
; method = oss
; source = /dev/dsp
; method = jack
; source = default
# The options 'sample_rate', 'sample_bits', 'channels' and 'autoconnect' can be configured for some input methods:
# sample_rate: fifo, pipewire, sndio, oss
# sample_bits: fifo, pipewire, sndio, oss
# channels: sndio, oss, jack
# autoconnect: jack
# Other methods ignore these settings.
# For pipewire, sample_rate will default to 48000, for all other input methods, sample_rate will default to 44100.
#
# For 'sndio' and 'oss' they are only preferred values, i.e. if the values are not supported
# by the chosen audio device, the device will use other supported values instead.
# Example: 48000, 32 and 2, but the device only supports 44100, 16 and 1, then it
# will use 44100, 16 and 1.
#
#
# The 'pipewire' input method has three options to control linking and mixing:
# active: Force the node to always process. Useful for monitoring sources when no other application is active.
# remix: Allow pipewire to remix audio channels to match cava's channel count. Useful for surround sound.
# virtual: Set the node to virtual, to avoid recording notifications from the DE.
#
; sample_rate = 44100
; sample_bits = 16
; channels = 2
; autoconnect = 2
; active = 1
; remix = 1
; virtual = 1
[output]
# Output method. Can be 'ncurses', 'noncurses', 'raw', 'noritake', 'sdl'
# or 'sdl_glsl'.
# 'noncurses' (default) uses a buffer and cursor movements to only print
# changes from frame to frame in the terminal. Uses less resources and is less
# prone to tearing (vsync issues) than 'ncurses'.
#
# 'raw' is an 8 or 16 bit (configurable via the 'bit_format' option) data
# stream of the bar heights that can be used to send to other applications.
# 'raw' defaults to 1024 bars stereo (512 bars mono), which can be adjusted in the 'bars' option above.
#
# 'noritake' outputs a bitmap in the format expected by a Noritake VFD display
# in graphic mode. It only support the 3000 series graphical VFDs for now.
#
# 'sdl' uses the Simple DirectMedia Layer to render in a graphical context.
# 'sdl_glsl' uses SDL to create an OpenGL context. Write your own shaders or
# use one of the predefined ones.
; method = noncurses
# Orientation of the visualization. Can be 'bottom', 'top', 'left', 'right' or
# 'horizontal'. Default is 'bottom'. 'left and 'right' are only supported on sdl
# and ncurses output. 'horizontal' (bars go up and down from center) is only supported
# on noncurses output.
# Note: many fonts have weird or missing glyphs for characters used in orientations
# other than 'bottom', which can make output not look right.
orientation = bottom
# Visual channels. Can be 'stereo' or 'mono'.
# 'stereo' mirrors both channels with low frequencies in center.
# 'mono' outputs left to right lowest to highest frequencies.
# 'mono_option' set mono to either take input from 'left', 'right' or 'average'.
# set 'reverse' to 1 to display frequencies the other way around.
channels = mono
mono_option = average
reverse = 0
# Only valid if orientation is set to 'horizontal'.
# Set 'horizontal_stereo' to 1 to have left channel bars at top and right channel at bottom.
# Set 'left_bottom' to 0 to have right channel at top and left channel at bottom.
; horizontal_stereo = 0
; left_bottom = 1
# Raw output target.
# On Linux, a fifo will be created if target does not exist.
# On Windows, a named pipe will be created if target does not exist.
; raw_target = /dev/stdout
# Raw data format. Can be 'binary' or 'ascii'.
; data_format = binary
# Binary bit format, can be '8bit' (0-255) or '16bit' (0-65530).
; bit_format = 16bit
# Ascii max value. In 'ascii' mode range will run from 0 to value specified here
; ascii_max_range = 1000
# Ascii delimiters. In ascii format each bar and frame is separated by a delimiter.
# Use decimal value in ascii table (i.e. 59 = ';' and 10 = '\n' (line feed)).
; bar_delimiter = 59
; frame_delimiter = 10
# sdl window size and position. -1,-1 is centered.
; sdl_width = 1024
; sdl_height = 512
; sdl_x = -1
; sdl_y= -1
; sdl_full_screen = 0
# set label on bars on the x-axis. Can be 'frequency' or 'none'. Default: 'none'
# 'frequency' displays the lower cut off frequency of the bar above.
# Only supported on ncurses and noncurses output.
; xaxis = none
# enable synchronized sync. 1 = on, 0 = off
# removes flickering in alacritty terminal emulator.
# defaults to off since the behaviour in other terminal emulators is unknown
; synchronized_sync = 0
# Shaders for sdl_glsl, located in $HOME/.config/cava/shaders
; vertex_shader = pass_through.vert
# Default spectrum shader
# default value: bar_spectrum.frag
; fragment_shader = bar_spectrum.frag
# other styles shaders
; fragment_shader = eye_of_phi.frag
; fragment_shader = northern_lights.frag
; fragment_shader = spectrogram.frag
; fragment_shader = winamp_line_style_spectrum.frag
# Orion shaders (use with: method = sdl_glsl)
# Static Orion
; fragment_shader = orion_circle.frag
# Rotating Orion
; fragment_shader = orion_circle_rotate.frag
# Orion saturn subring
; fragment_shader = orion_saturn_subring.frag
# Orion saturn core
; fragment_shader = orion_saturn_core.frag
# For glsl output mode, keep rendering even if no audio. 1 = on, 0 = off. Default: 0
# Enable for animated shaders so time-based effects keep updating.
; continuous_rendering = 0
# SDL_GLSL only: gain applied to bar amplitudes before sending to shaders, in percent. Default: 100
# 0 = mute, 100 = unchanged, >100 = amplify (shader input is clamped to the [0..1] range).
; sdl_glsl_gain = 100
# disable console blank (screen saver) in tty. 1 = on, 0 = off. Default: 0
# (Not supported on FreeBSD)
; disable_blanking = 0
# show a flat bar at the bottom of the screen when idle, 1 = on, 0 = off
; show_idle_bar_heads = 1
# show waveform instead of frequency spectrum, 1 = on, 0 = off
; waveform = 0
[color]
# Colors can be one of seven predefined: black, blue, cyan, green, magenta, red, white, yellow.
# Or defined by hex code '#xxxxxx' (hex code must be within ''). User defined colors require
# a terminal that can change color definitions such as Gnome-terminal or rxvt.
# default is to keep current terminal color
; background = default
; foreground = default
# SDL and sdl_glsl only support hex code colors, these are the default:
; background = '#111111'
; foreground = '#33ffff'
# Gradient mode, only hex defined colors are supported,
# background must also be defined in hex or remain commented out. 1 = on, 0 = off.
# You can define as many as 8 different colors. They range from bottom to top of the screen
; gradient = 0
; gradient_color_1 = '#59cc33'
; gradient_color_2 = '#80cc33'
; gradient_color_3 = '#a6cc33'
; gradient_color_4 = '#cccc33'
; gradient_color_5 = '#cca633'
; gradient_color_6 = '#cc8033'
; gradient_color_7 = '#cc5933'
; gradient_color_8 = '#cc3333'
# Horizontal is only supported on noncurses output.
# Only one color will be calculated per bar.
; horizontal_gradient = 0
; horizontal_gradient_color_1 = '#c45161'
; horizontal_gradient_color_2 = '#e094a0'
; horizontal_gradient_color_3 = '#f2b6c0'
; horizontal_gradient_color_4 = '#f2dde1'
; horizontal_gradient_color_5 = '#cbc7d8'
; horizontal_gradient_color_6 = '#8db7d2'
; horizontal_gradient_color_7 = '#5e62a9'
; horizontal_gradient_color_8 = '#434279'
# If both vertical and horizontal gradients are enabled, the vertical one will be blended in this direction.
# Can be 'up', 'down', 'left' or 'right'. 'up' means the vertical gradient will be blended in from
# bottom to top. I.e. the bottom will only be the horizontal
# and top will only be the vertical color of the gradient.
; blend_direction = 'up'
# use theme file instead of defining colors in this file
# themes are located in $HOME/.config/cava/themes
; theme = 'none'
[smoothing]
# Disables or enables the so-called "Monstercat smoothing" with or without "waves". Set to 0 to disable.
; monstercat = 0
; waves = 0
# Noise reduction, int 0 - 100. default 77
# the raw visualization is very noisy, this factor adjusts the integral and gravity filters to keep the signal smooth
# 100 will be very slow and smooth, 0 will be fast but noisy.
; noise_reduction = 77
[eq]
# This one is tricky. You can have as many keys as you want.
# Remember to uncomment more than one key! More keys = more precision.
# Look at readme.md on github for further explanations and examples.
; 1 = 1 # bass
; 2 = 1
; 3 = 1 # midtone
; 4 = 1
; 5 = 1 # treble

View File

@@ -0,0 +1,73 @@
#version 330
in vec2 fragCoord;
out vec4 fragColor;
// bar values. defaults to left channels first (low to high), then right (high to low).
uniform float bars[512];
uniform int bars_count; // number of bars (left + right) (configurable)
uniform int bar_width; // bar width (configurable), not used here
uniform int bar_spacing; // space between bars (configurable)
uniform vec3 u_resolution; // window resolution
// colors, configurable in cava config file (r,g,b) (0.0 - 1.0)
uniform vec3 bg_color; // background color
uniform vec3 fg_color; // foreground color
uniform int gradient_count;
uniform vec3 gradient_colors[8]; // gradient colors
uniform float shader_time; // shader execution time s (not used here)
uniform sampler2D inputTexture; // Texture from the last render pass (not used here)
vec3 normalize_C(float y, vec3 col_1, vec3 col_2, float y_min, float y_max) {
// create color based on fraction of this color and next color
float yr = (y - y_min) / (y_max - y_min);
return col_1 * (1.0 - yr) + col_2 * yr;
}
void main() {
// find which bar to use based on where we are on the x axis
float x = u_resolution.x * fragCoord.x;
int bar = int(bars_count * fragCoord.x);
// calculate a bar size
float bar_size = u_resolution.x / bars_count;
// the y coordinate and bar values are the same
float y = bars[bar];
// make sure there is a thin line at bottom
if (y * u_resolution.y < 1.0) {
y = 1.0 / u_resolution.y;
}
// draw the bar up to current height
if (y > fragCoord.y) {
// make some space between bars basen on settings
if (x > (bar + 1) * (bar_size)-bar_spacing) {
fragColor = vec4(bg_color, 1.0);
} else {
if (gradient_count == 0) {
fragColor = vec4(fg_color, 1.0);
} else {
// find which color in the configured gradient we are at
int color = int((gradient_count - 1) * fragCoord.y);
// find where on y this and next color is supposed to be
float y_min = color / (gradient_count - 1.0);
float y_max = (color + 1.0) / (gradient_count - 1.0);
// make color
fragColor = vec4(normalize_C(fragCoord.y, gradient_colors[color],
gradient_colors[color + 1], y_min, y_max),
1.0);
}
}
} else {
fragColor = vec4(bg_color, 1.0);
}
}

View File

@@ -0,0 +1,117 @@
#version 330
// this shader was stolen from shadertoy user ChunderFPV
#define SCALE 8.0
#define PI radians(180.0)
#define TAU (PI * 2.0)
#define CS(a) vec2(cos(a), sin(a))
#define PT(u, r) smoothstep(0.0, r, r - length(u))
in vec2 fragCoord;
out vec4 fragColor;
uniform float bars[512];
uniform int bars_count; // number of bars (left + right) (configurable)
uniform float shader_time; // shader execution time s
uniform int bar_width; // bar width (configurable), not used here
uniform int bar_spacing; // space between bars (configurable)
uniform vec3 u_resolution; // window resolution
// colors, configurable in cava config file (r,g,b) (0.0 - 1.0)
uniform vec3 bg_color; // background color
uniform vec3 fg_color; // foreground color
uniform int gradient_count;
uniform vec3 gradient_colors[8]; // gradient colors
// gradient map ( color, equation, time, width, shadow, reciprocal )
vec3 gm(vec3 c, float n, float t, float w, float d, bool i) {
float g = min(abs(n), 1.0 / abs(n));
float s = abs(sin(n * PI - t));
if (i)
s = min(s, abs(sin(PI / n + t)));
return (1.0 - pow(abs(s), w)) * c * pow(g, d) * 6.0;
}
// denominator spiral, use 1/n for numerator
// ( screen xy, spiral exponent, decimal, line width, hardness, rotation )
float ds(vec2 u, float e, float n, float w, float h, float ro) {
float ur = length(u); // unit radius
float sr = pow(ur, e); // spiral radius
float a = round(sr) * n * TAU; // arc
vec2 xy = CS(a + ro) * ur; // xy coords
float l = PT(u - xy, w); // line
float s = mod(sr + 0.5, 1.0); // gradient smooth
s = min(s, 1.0 - s); // darken filter
return l * s * h;
}
void main() {
float t = shader_time / PI * 2.0;
vec4 m = vec4(0, 0, 0, 0); // iMouse;
m.xy = m.xy * 2.0 / u_resolution.xy - 1.0; // ±1x, ±1y
if (m.z > 0.0)
t += m.y * SCALE; // move time with mouse y
float z = (m.z > 0.0) ? pow(1.0 - abs(m.y), sign(m.y)) : 1.0; // zoom (+)
float e = (m.z > 0.0) ? pow(1.0 - abs(m.x), -sign(m.x))
: 1.0; // screen exponent (+)
float se = (m.z > 0.0) ? e * -sign(m.y) : 1.0; // spiral exponent
vec3 bg = vec3(0); // black background
float aa = 3.0; // anti-aliasing
for (float j = 0.0; j < aa; j++)
for (float k = 0.0; k < aa; k++) {
vec3 c = vec3(0);
vec2 o = vec2(j, k) / aa;
vec2 uv = (fragCoord * u_resolution.xy - 0.5 * u_resolution.xy + o) /
u_resolution.y * SCALE * z; // apply cartesian, scale and zoom
if (m.z > 0.0)
uv =
exp(log(abs(uv)) * e) * sign(uv); // warp screen space with exponent
float px = length(fwidth(uv)); // pixel width
float x = uv.x; // every pixel on x
float y = uv.y; // every pixel on y
float l = length(uv); // hypot of xy: sqrt(x*x+y*y)
float mc = (x * x + y * y - 1.0) / y; // metallic circle at xy
float g = min(abs(mc), 1.0 / abs(mc)); // gradient
vec3 gold = vec3(1.0, 0.6, 0.0) * g * l;
vec3 blue = vec3(0.3, 0.5, 0.9) * (1.0 - g);
vec3 rgb = max(gold, blue);
float w = 0.1; // line width
float d = 0.4; // shadow depth
c = max(c, gm(rgb, mc, -t, w * bars[0], d, false)); // metallic
c = max(c, gm(rgb, abs(y / x) * sign(y), -t, w * bars[1], d,
false)); // tangent
c = max(c, gm(rgb, (x * x) / (y * y) * sign(y), -t, w * bars[2], d,
false)); // sqrt cotangent
c = max(c, gm(rgb, (x * x) + (y * y), t, w * bars[3], d,
true)); // sqrt circles
c += rgb * ds(uv, se, t / TAU, px * 2.0 * bars[4], 2.0, 0.0); // spiral 1a
c += rgb * ds(uv, se, t / TAU, px * 2.0 * bars[5], 2.0, PI); // spiral 1b
c +=
rgb * ds(uv, -se, t / TAU, px * 2.0 * bars[6], 2.0, 0.0); // spiral 2a
c += rgb * ds(uv, -se, t / TAU, px * 2.0 * bars[7], 2.0, PI); // spiral 2b
c = max(c, 0.0); // clear negative color
c += pow(max(1.0 - l, 0.0), 3.0 / z); // center glow
if (m.z > 0.0) // display grid on click
{
vec2 xyg = abs(fract(uv + 0.5) - 0.5) / px; // xy grid
c.gb += 0.2 * (1.0 - min(min(xyg.x, xyg.y), 1.0));
}
bg += c;
}
bg /= aa * aa;
bg *= sqrt(bg) * 1.5;
fragColor = vec4(bg, 1.0);
}

View File

@@ -0,0 +1,34 @@
#version 330
in vec2 fragCoord;
out vec4 fragColor;
// bar values. defaults to left channels first (low to high), then right (high to low).
uniform float bars[512];
uniform int bars_count; // number of bars (left + right) (configurable)
uniform vec3 u_resolution; // window resolution, not used here
//colors, configurable in cava config file
uniform vec3 bg_color; // background color(r,g,b) (0.0 - 1.0), not used here
uniform vec3 fg_color; // foreground color, not used here
void main()
{
// find which bar to use based on where we are on the x axis
int bar = int(bars_count * fragCoord.x);
float bar_y = 1.0 - abs((fragCoord.y - 0.5)) * 2.0;
float y = (bars[bar]) * bar_y;
float bar_x = (fragCoord.x - float(bar) / float(bars_count)) * bars_count;
float bar_r = 1.0 - abs((bar_x - 0.5)) * 2;
bar_r = bar_r * bar_r * 2;
// set color
fragColor.r = fg_color.x * y * bar_r;
fragColor.g = fg_color.y * y * bar_r;
fragColor.b = fg_color.z * y * bar_r;
}

View File

@@ -0,0 +1,14 @@
#version 330
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
// Output data ; will be interpolated for each fragment.
out vec2 fragCoord;
void main()
{
gl_Position = vec4(vertexPosition_modelspace,1);
fragCoord = (vertexPosition_modelspace.xy+vec2(1,1))/2.0;
}

View File

@@ -0,0 +1,53 @@
#version 330
in vec2 fragCoord;
out vec4 fragColor;
// bar values. defaults to left channels first (low to high), then right (high
// to low).
uniform float bars[512];
uniform int bars_count; // number of bars (left + right) (configurable)
uniform int bar_width; // bar width (configurable), not used here
uniform int bar_spacing; // space between bars (configurable)
uniform vec3 u_resolution; // window resolution
// colors, configurable in cava config file (r,g,b) (0.0 - 1.0)
uniform vec3 bg_color; // background color
uniform vec3 fg_color; // foreground color
uniform int gradient_count;
uniform vec3 gradient_colors[8]; // gradient colors
uniform sampler2D inputTexture; // Texture from the last render pass
vec3 normalize_C(float y, vec3 col_1, vec3 col_2, float y_min, float y_max) {
// create color based on fraction of this color and next color
float yr = (y - y_min) / (y_max - y_min);
return col_1 * (1.0 - yr) + col_2 * yr;
}
void main() {
// find which bar to use based on where we are on the y axis
int bar = int(bars_count * fragCoord.y);
float y = bars[bar];
float band_size = 1.0 / float(bars_count);
float current_band_min = bar * band_size;
float current_band_max = (bar + 1) * band_size;
int hist_length = 512;
float win_size = 1.0 / hist_length;
if (fragCoord.x > 1.0 - win_size) {
if (fragCoord.y > current_band_min && fragCoord.y < current_band_max) {
fragColor = vec4(fg_color * y, 1.0);
}
} else {
vec2 offsetCoord = fragCoord;
offsetCoord.x += float(win_size);
fragColor = texture(inputTexture, offsetCoord);
}
}

View File

@@ -0,0 +1,112 @@
#version 330
// Emulate the "line style" spectrum analyzer from Winamp 2.
// Try this config for a demonstration:
/*
[general]
bar_width = 2
bar_spacing = 0
higher_cutoff_freq = 22000
[output]
method = sdl_glsl
channels = mono
fragment_shader = winamp_line_style_spectrum.frag
[color]
background = '#000000'
gradient = 1
gradient_color_1 = '#319C08'
gradient_color_2 = '#29CE10'
gradient_color_3 = '#BDDE29'
gradient_color_4 = '#DEA518'
gradient_color_5 = '#D66600'
gradient_color_6 = '#CE2910'
[smoothing]
noise_reduction = 10
*/
in vec2 fragCoord;
out vec4 fragColor;
// bar values. defaults to left channels first (low to high), then right (high to low).
uniform float bars[512];
uniform int bars_count; // number of bars (left + right) (configurable)
uniform int bar_width; // bar width (configurable), not used here
uniform int bar_spacing; // space between bars (configurable)
uniform vec3 u_resolution; // window resolution
//colors, configurable in cava config file (r,g,b) (0.0 - 1.0)
uniform vec3 bg_color; // background color
uniform vec3 fg_color; // foreground color
uniform int gradient_count;
uniform vec3 gradient_colors[8]; // gradient colors
vec3 normalize_C(float y,vec3 col_1, vec3 col_2, float y_min, float y_max)
{
//create color based on fraction of this color and next color
float yr = (y - y_min) / (y_max - y_min);
return col_1 * (1.0 - yr) + col_2 * yr;
}
void main()
{
// find which bar to use based on where we are on the x axis
float x = u_resolution.x * fragCoord.x;
int bar = int(bars_count * fragCoord.x);
//calculate a bar size
float bar_size = u_resolution.x / bars_count;
//the y coordinate is stretched by 4X to resemble Winamp
float y = min(bars[bar] * 4.0, 1.0);
// make sure there is a thin line at bottom
if (y * u_resolution.y < 1.0)
{
y = 1.0 / u_resolution.y;
}
vec4 bar_color;
if (gradient_count == 0)
{
bar_color = vec4(fg_color,1.0);
}
else
{
//find color in the configured gradient for the top of the bar
int color = int((gradient_count - 1) * y);
//find where on y this and next color is supposed to be
float y_min = float(color) / (gradient_count - 1.0);
float y_max = float(color + 1) / (gradient_count - 1.0);
//make a solid color for the entire bar
bar_color = vec4(normalize_C(y, gradient_colors[color], gradient_colors[color + 1], y_min, y_max), 1.0);
}
//draw the bar up to current height
if (y > fragCoord.y)
{
//make some space between bars based on settings
if (x > (bar + 1) * (bar_size) - bar_spacing)
{
fragColor = vec4(bg_color,1.0);
}
else
{
fragColor = bar_color;
}
}
else
{
fragColor = vec4(bg_color,1.0);
}
}

View File

@@ -0,0 +1,15 @@
[color]
background = '#001e26'
foreground = '#708183'
gradient = 1
gradient_color_1 = '#268bd2'
gradient_color_2 = '#6c71c4'
gradient_color_3 = '#cb4b16'
horizontal_gradient = 1
horizontal_gradient_color_1 = '#586e75'
horizontal_gradient_color_2 = '#b58900'
horizontal_gradient_color_3 = '#839496'
blend_direction = 'up'

10
cava/themes/tricolor Normal file
View File

@@ -0,0 +1,10 @@
[color]
horizontal_gradient = 1
horizontal_gradient_color_1 = '#c45161'
horizontal_gradient_color_2 = '#e094a0'
horizontal_gradient_color_3 = '#f2b6c0'
horizontal_gradient_color_4 = '#f2dde1'
horizontal_gradient_color_5 = '#cbc7d8'
horizontal_gradient_color_6 = '#8db7d2'
horizontal_gradient_color_7 = '#5e62a9'
horizontal_gradient_color_8 = '#434279'

View File

@@ -3,3 +3,5 @@ exec-once = /usr/bin/qs & # quickshell
# exec-once = hyprpaper # wallpaper # exec-once = hyprpaper # wallpaper
exec-once = awww-daemon # wallpaper exec-once = awww-daemon # wallpaper
exec-once = hyprsunset # night light exec-once = hyprsunset # night light
exec-once = qs -c overview # workspace switcher https://github.com/Shanu-Kumawat/quickshell-overview
# exec-once = cava -p ~/.config/cava/config

View File

@@ -2,3 +2,4 @@
env = XCURSOR_SIZE,24 env = XCURSOR_SIZE,24
env = HYPRCURSOR_SIZE,24 env = HYPRCURSOR_SIZE,24
env = QT_QPA_PLATFORMTHEME,qt6ct

View File

@@ -12,7 +12,7 @@ input {
follow_mouse = 1 follow_mouse = 1
sensitivity = 0 # -1.0 - 1.0, 0 means no modification. sensitivity = -0.8 # -1.0 - 1.0, 0 means no modification.
touchpad { touchpad {
natural_scroll = false natural_scroll = false

View File

@@ -16,6 +16,7 @@ bind = $mainMod, R, exec, $menu
bind = $mainMod, P, exec, $programs bind = $mainMod, P, exec, $programs
bind = $mainMod, L, layoutmsg, togglesplit # dwindle bind = $mainMod, L, layoutmsg, togglesplit # dwindle
bind = $mainMod, code:47, exec, rofi -show emoji bind = $mainMod, code:47, exec, rofi -show emoji
bind = $mainMod, TAB, exec, qs ipc -c overview call overview toggle
# Move focus with mainMod + arrow keys # Move focus with mainMod + arrow keys
bind = $mainMod, J, cyclenext bind = $mainMod, J, cyclenext
@@ -25,6 +26,7 @@ bind = $mainMod SHIFT, o, movefocus, d
bind = $mainMod SHIFT, J, swapnext bind = $mainMod SHIFT, J, swapnext
bind = $mainMod SHIFT, K, swapnext, prev bind = $mainMod SHIFT, K, swapnext, prev
bind = $mainMod, F, fullscreen, toggle
# Switch workspaces with mainMod + [0-9] # Switch workspaces with mainMod + [0-9]
bind = $mainMod, 1, workspace, 1 bind = $mainMod, 1, workspace, 1

View File

@@ -1,3 +1,32 @@
[Appearance] [Appearance]
color_scheme_path=/home/sem/linux-dotfiles/qt6ct/colors/matugen.conf color_scheme_path=/home/sem/.config/qt6ct/colors/matugen.conf
custom_palette=true custom_palette=true
icon_theme=breeze-dark
standard_dialogs=default
style=Breeze
[Fonts]
fixed="Sans Serif,9,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,,0,0"
general="Sans Serif,9,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,,0,0"
[Interface]
activate_item_on_single_click=1
buttonbox_layout=0
cursor_flash_time=1000
dialog_buttons_have_icons=1
double_click_interval=400
gui_effects=@Invalid()
keyboard_scheme=2
menus_have_icons=true
show_shortcuts_in_context_menus=true
stylesheets=@Invalid()
toolbutton_style=4
underline_shortcut=1
wheel_scroll_lines=3
[SettingsWindow]
geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0\0\0\0\x4\xe2\0\0\x2\xa6\0\0\0\0\0\0\0\0\0\0\x4\xe2\0\0\x2\xa6\0\0\0\x1\x2\0\0\0\n\0\0\0\0\0\0\0\0\0\0\0\x4\xe2\0\0\x2\xa6)
[Troubleshooting]
force_raster_widgets=1
ignored_applications=@Invalid()

View File

@@ -0,0 +1,66 @@
{
"appearance": {
"colorSource": "default",
"caelestia": {
"autoRefresh": true,
"refreshInterval": 2000,
"accentProfile": "vibrant"
},
"rounding": {
"unsharpen": 2,
"verysmall": 8,
"small": 12,
"normal": 17,
"large": 23,
"full": 9999,
"screenRounding": 23,
"windowRounding": 18
},
"font": {
"family": {
"main": "JetBrainsMono Nerd Font",
"title": "JetBrainsMono Nerd Font",
"expressive": "JetBrainsMono Nerd Font"
},
"pixelSize": {
"smaller": 12,
"small": 15,
"normal": 16,
"larger": 19,
"huge": 22
}
},
"animation": {
"duration": {
"elementMove": 500,
"elementMoveEnter": 400,
"elementMoveFast": 200
}
},
"sizes": {
"elevationMargin": 10
}
},
"overview": {
"rows": 2,
"columns": 5,
"scale": 0.16,
"enable": true,
"hideEmptyRows": false,
"workspaceSpacing": 5,
"backgroundPadding": 10,
"workspaceNumberBaseSize": 250
},
"position": {
"topMargin": 100
},
"windowPreview": {
"iconToWindowRatio": 0.25,
"iconToWindowRatioCompact": 0.45,
"xwaylandIndicatorToIconRatio": 0.35,
"inactiveMonitorOpacity": 0.4
},
"hacks": {
"arbitraryRaceConditionDelay": 150
}
}

View File

@@ -0,0 +1,56 @@
import QtQuick
import Quickshell.Io
Item {
id: root
signal devicesFound(var devices)
property var connectedDevices: []
function deviceListChanged(newList) {
if (newList.length !== root.connectedDevices.length) {
return true;
}
for (let i = 0; i < newList.length; i++) {
if (newList[i].mac !== root.connectedDevices[i].mac ||
newList[i].name !== root.connectedDevices[i].name) {
return true;
}
}
return false;
}
Process {
id: bluetoothConnectedDevicesProcess
command: ["bluetoothctl", "devices", "Connected"]
stdout: StdioCollector {
onStreamFinished: {
if (!this.text) {
root.connectedDevices = [];
root.devicesFound([]);
return;
}
var devices = this.text.trim().split("\n").map(line => {
var parts = line.split(" ");
return {
mac: parts[1],
name: parts.slice(2).join(" ")
};
});
if (root.deviceListChanged(devices)) {
root.connectedDevices = devices;
root.devicesFound(devices);
}
}
}
}
Timer {
interval: 2000
running: true
repeat: true
onTriggered: bluetoothConnectedDevicesProcess.running = true
}
Component.onCompleted: bluetoothConnectedDevicesProcess.running = true
}

View File

@@ -0,0 +1,25 @@
import QtQuick
import Quickshell
import Quickshell.Io
Item {
id: root
signal cavaDataChanged(string data)
Process {
id: cavaProcess
command: ["cat", "/tmp/cava.fifo"]
stdout: SplitParser {
splitMarker: "\n" // fires onRead() for each newline-delimited chunk
onRead: data => {
root.cavaDataChanged(data);
}
}
}
Component.onCompleted: {
cavaProcess.running = true;
}
}

View File

@@ -0,0 +1,59 @@
import Quickshell.Io
import QtQuick
Item {
id: root
property string artist: ""
property string title: ""
property string artUrl: ""
property bool isPlaying: false
Process {
id: playerctlProc
// we need a separator, so use |||
command: ["playerctl", "metadata", "--format", "{{artist}}|||{{title}}|||{{mpris:artUrl}}|||{{status}}"]
stdout: StdioCollector {
onStreamFinished: {
var text = this.text.trim();
if (!text) {
root.artist = "";
root.title = "";
root.artUrl = "";
return;
}
var parts = text.split("|||");
root.artist = parts[0] || "";
root.title = parts[1] || "";
root.artUrl = parts[2] || "";
}
}
}
Process {
id: playerCtlPlayingProc
command: ["playerctl", "status"]
stdout: StdioCollector {
onStreamFinished: {
var status = this.text.trim();
root.isPlaying = (status === "Playing");
}
}
}
Timer {
interval: 2000
running: true
repeat: true
onTriggered: playerctlProc.running = true
}
Timer {
interval: 1000
running: true
repeat: true
onTriggered: playerCtlPlayingProc.running = true
}
Component.onCompleted: playerctlProc.running = true
}

View File

@@ -10,13 +10,13 @@ Item {
// ===================== // =====================
property int cpuUsage: 0 property int cpuUsage: 0
property int memUsage: 0 property int memUsage: 0
property int gpuUsage: 0
property var lastCpuIdle: 0 property var lastCpuIdle: 0
property var lastCpuTotal: 0 property var lastCpuTotal: 0
Process { Process {
id: cpuProc id: cpuProc
// get cpu usage, first line of /proc/stat
command: ["cat", "/proc/stat"] command: ["cat", "/proc/stat"]
stdout: StdioCollector { stdout: StdioCollector {
onStreamFinished: { onStreamFinished: {
@@ -56,12 +56,28 @@ Item {
var parts = data.trim().split(/\s+/); var parts = data.trim().split(/\s+/);
var total = parseInt(parts[1]) || 1; var total = parseInt(parts[1]) || 1;
var used = parseInt(parts[2]) || 0; var used = parseInt(parts[2]) || 0;
memUsage = Math.round(100 * used / total); root.memUsage = Math.round(100 * used / total);
} }
} }
Component.onCompleted: running = true Component.onCompleted: running = true
} }
Process {
id: gpuProc
command: ["cat", "/sys/class/drm/card1/device/gpu_busy_percent"]
stdout: StdioCollector {
onStreamFinished: {
if (!this.text) {
return;
}
var gpuUsage = parseInt(this.text.trim()) || 0;
root.gpuUsage = gpuUsage;
}
}
}
// Update loop // Update loop
Timer { Timer {
interval: 2000 interval: 2000
@@ -70,6 +86,7 @@ Item {
onTriggered: { onTriggered: {
cpuProc.running = true; cpuProc.running = true;
memProc.running = true; memProc.running = true;
gpuProc.running = true;
} }
} }
} }

View File

@@ -18,6 +18,10 @@ ShellRoot {
id: stats id: stats
} }
NowPlayingService {
id: nowPlayingService
}
Variants { Variants {
model: Quickshell.screens model: Quickshell.screens
@@ -35,7 +39,7 @@ ShellRoot {
anchors.left: true anchors.left: true
anchors.right: true anchors.right: true
implicitHeight: 25 implicitHeight: 25
color: Constants.colBg color: Colors.md3.background
Loader { Loader {
id: wallpaperLoader id: wallpaperLoader
@@ -48,9 +52,13 @@ ShellRoot {
cpuUsage: stats.cpuUsage cpuUsage: stats.cpuUsage
memUsage: stats.memUsage memUsage: stats.memUsage
gpuUsage: stats.gpuUsage
nowPlayingArtist: nowPlayingService.artist
nowPlayingTitle: nowPlayingService.title
nowPlayingArtUrl: nowPlayingService.artUrl
nowPlaying: nowPlayingService.isPlaying
} }
} }
} }
Variants { Variants {
@@ -65,4 +73,3 @@ ShellRoot {
} }
} }
} }

37
quickshell/ui/BarText.qml Normal file
View File

@@ -0,0 +1,37 @@
import QtQuick
import Quickshell
import "../constants"
Item {
id: root
property int value: 0
property string prefix: ""
property string separator: "-"
property int valuePadding: 3
property int padding: 4
property string paddingChar: "0"
width: textItem.implicitWidth + padding
height: textItem.implicitHeight + padding
Rectangle {
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: Math.max(1, root.value / 100 * parent.height)
color: Colors.md3.on_secondary
opacity: 1.0
}
Text {
id: textItem
anchors.centerIn: parent
z: 1
text: root.prefix + root.separator + String(root.value).padStart(root.valuePadding, root.paddingChar)
color: Colors.md3.inverse_primary
font.pixelSize: Constants.fontSize
font.family: Constants.fontFamily
font.bold: true
}
}

View File

@@ -0,0 +1,64 @@
import Quickshell
import Quickshell.Io
import QtQuick
import QtQuick.Layouts
import "../constants"
import "../services"
Text {
id: root
required property TopBar parentWindow;
// Nerd Font Bluetooth icon (nf-fa-bluetooth)
// cheat sheet: https://www.nerdfonts.com/cheat-sheet
// TODO make custom floating panel with animation and buttons to connect/disconnect devices
property string iconGlyph: "\udb80\udcaf"
property string connectedIconGlyph: "\udb80\udcb1"
property string disconnectedIconGlyph: "\udb80\udcaf"
property BluetoothService bluetoothService: BluetoothService {
onDevicesFound: function(devices) {
if (devices.length > 0) {
root.iconGlyph = root.connectedIconGlyph;
root.color = Colors.md3.on_primary_fixed;
} else {
root.iconGlyph = root.disconnectedIconGlyph;
root.color = Colors.md3.primary;
}
}
}
text: iconGlyph
color: Colors.md3.on_primary_fixed
font {
family: Constants.fontFamily
pixelSize: Constants.fontSize
bold: true
}
Process {
id: bluemanManagerProcess
command: ["blueman-manager"]
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
bluemanManagerProcess.running = true;
popupWindow.visible = true;
}
}
PopupWindow {
id: popupWindow
visible: false
implicitWidth: 200
implicitHeight: 100
anchor.window: parentWindow
}
}

View File

@@ -5,7 +5,7 @@ import "../constants"
Text { Text {
id: clock id: clock
color: Constants.colBlue color: Colors.md3.on_primary_fixed
font { font {
family: Constants.fontFamily family: Constants.fontFamily
@@ -14,7 +14,7 @@ Text {
} }
function updateTime() { function updateTime() {
text = Qt.formatDateTime(new Date(), "ddd, MMM dd - HH:mm"); text = Qt.formatDateTime(new Date(), "[dd-MM-yy] - [HH:mm]");
} }
Component.onCompleted: updateTime() Component.onCompleted: updateTime()

View File

@@ -0,0 +1,9 @@
import QtQuick
import "../constants"
// vertical line separator for top bar
Rectangle {
width: 1
height: 16
color: Colors.md3.on_background
}

View File

@@ -0,0 +1,51 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Quickshell.Services.Pipewire
ColumnLayout {
required property PwNode node;
// bind the node so we can read its properties
PwObjectTracker { objects: [ node ] }
RowLayout {
Image {
visible: source != ""
source: {
const icon = node.properties["application.icon-name"] ?? "audio-volume-high-symbolic";
return `image://icon/${icon}`;
}
sourceSize.width: 20
sourceSize.height: 20
}
Label {
text: {
// application.name -> description -> name
const app = node.properties["application.name"] ?? (node.description != "" ? node.description : node.name);
const media = node.properties["media.name"];
return media != undefined ? `${app} - ${media}` : app;
}
}
Button {
text: node.audio.muted ? "unmute" : "mute"
onClicked: node.audio.muted = !node.audio.muted
}
}
RowLayout {
Label {
Layout.preferredWidth: 50
text: `${Math.floor(node.audio.volume * 100)}%`
}
Slider {
Layout.fillWidth: true
value: node.audio.volume
onValueChanged: node.audio.volume = value
}
}
}

View File

@@ -0,0 +1,169 @@
import QtQuick
import QtQuick.Layouts
import "../constants"
import "../services"
Row {
id: root
property string artist: ""
property string title: ""
property string artUrl: ""
property bool isPlaying: false
property int maxTextLength: 50
property int numBands: 32
// if the artist - title text is too long, truncate it
readonly property string displayText: {
const fullText = artist !== "" ? (artist + " - " + title) : title;
return fullText.length > maxTextLength ? fullText.substring(0, maxTextLength - 3) + "..." : fullText;
}
property string dancingLeft: "└(ಠ_ಠ )┐"
property string dancingRight: "┌( ಠ_ಠ)┘"
property string notDancing: "(ಠ ∩ ಠ)"
visible: title !== ""
spacing: 6
Text {
id: littleFella
text: root.dancingLeft
color: Colors.md3.primary
anchors.verticalCenter: parent.verticalCenter
}
//TODO add service that reads the data from cava
// the fifo buffer is in /tmp/cava.fifo. Example data is:
// 5;3;3;3;2;1;1;3;6;18;42;16;6;6;1;1;2;6;2;3;6;6;5;11;11;12;13;66;4;4;24;2;2;24;4;4;66;13;12;11;11;5;6;6;3;2;3;2;1;1;6;6;16;42;19;5;2;1;1;2;3;4;3;7;
// where each number represents the amplitude of a frequency band.
// this can be used to create a simple visualizer
// also add cava to autostart
Image {
width: 18
height: 18
source: root.artUrl
fillMode: Image.PreserveAspectCrop
anchors.verticalCenter: parent.verticalCenter
}
Text {
id: titleText
text: root.displayText
color: Colors.md3.primary
font.family: Constants.fontFamily
font.pixelSize: Constants.fontSize
anchors.verticalCenter: parent.verticalCenter
// z: 1
}
Timer {
interval: 400
running: true
repeat: true
onTriggered: {
if (root.isPlaying) {
littleFella.text = littleFella.text === root.dancingLeft ? root.dancingRight : root.dancingLeft;
} else {
littleFella.text = root.notDancing;
}
}
}
// Item {
// id: titleArea
// anchors.bottom: parent.bottom
// width: titleText.implicitWidth
// height: Math.max(titleText.implicitHeight, visualizer.height)
// Canvas {
// id: visualizer
// anchors.fill: parent
// property var cavaData: []
// property var smoothedData: []
// property real inputMax: 20
// property real attackAlpha: 1.0
// property real releaseAlpha: 0.9
// property real maxStepPerFrame: 50
// property bool needsInit: true
// Component.onCompleted: {
// for (let i = 0; i < root.numBands; i++) {
// cavaData[i] = 0;
// smoothedData[i] = 0;
// }
// needsInit = false;
// }
// function updateData(csvLine) {
// // Fast in-place parse: split once, parse directly into pre-allocated array
// let parts = csvLine.split(";");
// let idx = 0;
// for (let j = 0; j < parts.length && idx < root.numBands; j++) {
// let val = Number(parts[j]);
// if (!isNaN(val))
// cavaData[idx++] = Math.min(100, Math.max(0, val));
// }
// while (idx < root.numBands)
// cavaData[idx++] = 0;
// if (needsInit) {
// for (let i = 0; i < root.numBands; i++)
// smoothedData[i] = cavaData[i];
// needsInit = false;
// } else {
// // Two-speed smoothing in place with early exit if no significant change
// let changed = false;
// for (let i = 0; i < root.numBands; i++) {
// let prev = smoothedData[i];
// let next = cavaData[i];
// let alpha = next >= prev ? attackAlpha : releaseAlpha;
// let blended = prev + (next - prev) * alpha;
// let delta = blended - prev;
// if (Math.abs(delta) > 0.1)
// changed = true;
// if (delta > maxStepPerFrame)
// blended = prev + maxStepPerFrame;
// else if (delta < -maxStepPerFrame)
// blended = prev - maxStepPerFrame;
// smoothedData[i] = blended;
// }
// if (!changed)
// return;
// }
// visualizer.requestPaint();
// }
// onPaint: {
// var ctx = getContext("2d");
// ctx.clearRect(0, 0, width, height);
// if (smoothedData.length === 0) {
// return;
// }
// var barWidth = width / root.numBands;
// ctx.fillStyle = Colors.md3.on_primary;
// for (let i = 0; i < root.numBands; i++) {
// let normalized = (smoothedData[i] || 0) / inputMax;
// if (normalized > 1)
// normalized = 1;
// let barHeight = normalized * height;
// ctx.fillRect(Math.floor(i * barWidth), Math.floor(height - barHeight), Math.ceil(barWidth), Math.floor(barHeight));
// }
// }
// }
// }
// CavaService {
// id: cavaService
// onCavaDataChanged: data => {
// visualizer.updateData(data);
// }
// }
}

View File

@@ -16,6 +16,11 @@ Item {
property int cpuUsage: 0 property int cpuUsage: 0
property int memUsage: 0 property int memUsage: 0
property int gpuUsage: 0
property string nowPlayingArtist: ""
property string nowPlayingTitle: ""
property string nowPlayingArtUrl: ""
property bool nowPlaying: false
RowLayout { RowLayout {
anchors.fill: parent anchors.fill: parent
@@ -27,37 +32,22 @@ Item {
id: workspaceHelpers id: workspaceHelpers
} }
// ===================== WorkspacesList {
// LEFT: Workspaces id: workspacesList
// ===================== }
RowLayout {
spacing: 10
Repeater { // small spacer
model: 9 Item {
anchors.leftMargin: 10
}
Text { NowPlaying {
required property int index artist: root.nowPlayingArtist
title: root.nowPlayingTitle
property int wsId: index + 1 artUrl: root.nowPlayingArtUrl
property var ws: workspaceHelpers.getWorkspace(wsId) isPlaying: root.nowPlaying
Layout.fillHeight: true
text: wsId Layout.alignment: Qt.AlignBottom
color: workspaceHelpers.isWorkspaceActive(wsId) ? Constants.colCyan : (ws ? Constants.colMagenta : Constants.colMuted)
font {
family: Constants.fontFamily
pixelSize: Constants.fontSize
bold: true
}
MouseArea {
anchors.fill: parent
onClicked: Hyprland.dispatch("workspace " + wsId)
}
}
}
} }
// Spacer // Spacer
@@ -71,37 +61,35 @@ Item {
RowLayout { RowLayout {
spacing: 10 spacing: 10
//TODO put this in separate component LineSeparator {}
Text {
id: cpuText BluetoothIcon {
text: "CPU: " + cpuUsage + "%" parentWindow: root
color: Constants.colYellow
font.pixelSize: Constants.fontSize
font.family: Constants.fontFamily
font.bold: true
} }
Rectangle { LineSeparator {}
width: 1
height: 16 BarText {
color: Constants.colMuted prefix: "C"
value: cpuUsage
} }
Text { LineSeparator {}
id: memText
text: "Mem: " + memUsage + "%" BarText {
color: Constants.colCyan prefix: "M"
font.pixelSize: Constants.fontSize value: memUsage
font.family: Constants.fontFamily
font.bold: true
} }
Rectangle { LineSeparator {}
width: 1
height: 16 BarText {
color: Constants.colMuted prefix: "G"
value: gpuUsage
} }
LineSeparator {}
Clock {} Clock {}
} }
} }

View File

@@ -0,0 +1,35 @@
import Quickshell.Hyprland
import QtQuick
import QtQuick.Layouts
import "../constants"
RowLayout {
spacing: 10
Repeater {
model: 10
Text {
required property int index
property int wsId: index + 1
property var ws: workspaceHelpers.getWorkspace(wsId)
text: wsId
color: workspaceHelpers.isWorkspaceActive(wsId) ? Colors.md3.primary : (ws ? Colors.md3.on_background : Colors.md3.on_secondary)
font {
family: Constants.fontFamily
pixelSize: Constants.fontSize
bold: true
}
MouseArea {
anchors.fill: parent
onClicked: Hyprland.dispatch("workspace " + wsId)
}
}
}
}

266
sddm/silent/custom.conf Normal file
View File

@@ -0,0 +1,266 @@
; https://github.com/uiriansan/SilentSDDM/wiki/Customizing
; symlinked this file to /usr/share/sddm/themes/silent/configs/custom.conf
[General]
scale = 1.0
enable-animations = true
animated-background-placeholder = "okarun-turbo-granny-form-and-momo-ayase-from-dandadan-wallpaper-2560x1440_51.jpg"
background-fill-mode = "fill"
[LockScreen]
display = true
padding-top = 0
padding-right = 0
padding-bottom = 0
padding-left = 0
background = "okarun-turbo-granny-form-and-momo-ayase-from-dandadan-wallpaper-2560x1440_51.jpg"
use-background-color = false
background-color = "#000000"
blur = 32
brightness = 0.0
saturation = 0.0
[LockScreen.Clock]
display = true
position = "center-left"
align = "center"
format = "hh:mm:ss"
font-family = "JetBrains Mono Nerd Font"
font-size = 120
font-weight = 900
color = "#cbcbcb"
[LockScreen.Date]
display = true
format = "dddd, MMMM dd, yyyy"
locale = "en_US"
font-family = "JetBrains Mono Nerd Font"
font-size = 25
font-weight = 600
color = "#fbc3c3"
margin-top = -15
[LockScreen.Message]
display = false
position = "bottom-center"
align = "center"
text = "Press da button"
font-family = "JetBrains Mono Nerd Font"
font-size = 12
font-weight = 400
display-icon = true
icon = "enter.svg"
icon-size = 16
color = "#FFFFFF"
paint-icon = true
spacing = 0
[LoginScreen]
background = "okarun-turbo-granny-form-and-momo-ayase-from-dandadan-wallpaper-2560x1440_51.jpg"
use-background-color = false
background-color = "#000000"
blur = 0
brightness = 0.0
saturation = 0.0
[LoginScreen.LoginArea]
position = "left"
margin = 50
[LoginScreen.LoginArea.Avatar]
shape = "circle"
border-radius = 30
active-size = 120
inactive-size = 80
inactive-opacity = 0.35
active-border-size = 3
inactive-border-size = 3
active-border-color = "#fbc3c3"
inactive-border-color = "#c6b3b3"
[LoginScreen.LoginArea.Username]
font-family = "JetBrains Mono Nerd Font"
font-size = 16
font-weight = 700
color = "#ff9e9e"
margin = 10
[LoginScreen.LoginArea.PasswordInput]
width = 200
height = 30
display-icon = true
font-family = "JetBrains Mono Nerd Font"
font-size = 12
icon = "password.svg"
icon-size = 16
content-color = "#f78f8f"
background-color = "#000000"
background-opacity = 0.0
border-size = 2
border-color = "#ffb0b0"
border-radius-left = 10
border-radius-right = 10
margin-top = 10
masked-character = "●"
[LoginScreen.LoginArea.LoginButton]
background-color = "#C3C6FB"
background-opacity = 0.0
active-background-color = "#C3C6FB"
active-background-opacity = 1.0
icon = "arrow-right.svg"
icon-size = 18
content-color = "#C3C6FB"
active-content-color = "#000000"
border-size = 2
border-color = "#C3C6FB"
border-radius-left = 10
border-radius-right = 10
margin-left = 5
show-text-if-no-password = true
hide-if-not-needed = true
font-family = "JetBrains Mono Nerd Font"
font-size = 12
font-weight = 600
[LoginScreen.LoginArea.Spinner]
display-text = true
text = "Logging in"
font-family = "JetBrains Mono Nerd Font"
font-weight = 600
font-size = 14
icon-size = 30
icon = "spinner.svg"
color = "#FFFFFF"
spacing = 5
[LoginScreen.LoginArea.WarningMessage]
font-family = "JetBrains Mono Nerd Font"
font-size = 11
font-weight = 400
normal-color = "#FFFFFF"
warning-color = "#FFFFFF"
error-color = "#FFFFFF"
margin-top = 10
[LoginScreen.MenuArea.Buttons]
margin-top = 0
margin-right = 0
margin-bottom = 100
margin-left = 100
size = 30
border-radius = 5
spacing = 10
font-family = "JetBrains Mono Nerd Font"
[LoginScreen.MenuArea.Popups]
max-height = 300
item-height = 30
item-spacing = 2
padding = 5
display-scrollbar = false
margin = 5
background-color = "#000000"
background-opacity = 1.0
active-option-background-color = "#c3c6fb"
active-option-background-opacity = 1.0
content-color = "#c3c6fb"
active-content-color = "#000000"
font-family = "JetBrains Mono Nerd Font"
border-size = 2
border-color = "#c3c6fb"
font-size = 11
icon-size = 16
[LoginScreen.MenuArea.Session]
display = true
position = "bottom-left"
index = 4
popup-direction = "up"
popup-align = "center"
display-session-name = true
button-width = 100
popup-width = 200
background-color = "#c3c6fb"
background-opacity = 0.0
active-background-opacity = 1.0
content-color = "#C3C6FB"
active-content-color = "#000000"
border-size = 0
font-size = 10
icon-size = 16
[LoginScreen.MenuArea.Layout]
display = true
position = "bottom-left"
index = 3
popup-direction = "up"
popup-align = "center"
popup-width = 180
display-layout-name = true
background-color = "#C3C6FB"
background-opacity = 0.0
active-background-opacity = 1.0
content-color = "#C3C6FB"
active-content-color = "#000000"
border-size = 0
font-size = 10
icon = "language.svg"
icon-size = 16
[LoginScreen.MenuArea.Keyboard]
display = true
position = "bottom-left"
index = 2
background-color = "#C3C6FB"
background-opacity = 0.0
active-background-opacity = 1.0
content-color = "#C3C6FB"
active-content-color = "#000000"
border-size = 0
icon = "keyboard.svg"
icon-size = 16
[LoginScreen.MenuArea.Power]
display = true
position = "bottom-left"
index = 1
popup-direction = "up"
popup-align = "center"
popup-width = 100
background-color = "#C3C6FB"
background-opacity = 0.0
active-background-opacity = 1.0
content-color = "#C3C6FB"
active-content-color = "#000000"
border-size = 0
icon = "power.svg"
icon-size = 16
[LoginScreen.VirtualKeyboard]
scale = 1.0
position = "login"
start-hidden = true
background-color = "#000000"
background-opacity = 1.0
key-content-color = "#C3C6FB"
key-color = "#000000"
key-opacity = 1.0
key-active-background-color = "#000000"
key-active-opacity = 0.0
selection-background-color = "#303030"
selection-content-color = "#C3C6FB"
primary-color = "#8c90c2"
border-size = 2
border-color = "#C3C6FB"
[Tooltips]
enable = true
font-family = "JetBrains Mono Nerd Font"
font-size = 11
content-color = "#C3C6FB"
background-color = "#000000"
background-opacity = 1.0
border-radius = 5
disable-user = false
disable-login-button = false