elsa in mac

hyprland 에서 cava를 바탕화면 좌/우측에 위젯처럼 고정 배치하는 방법 본문

Mac(OS X)/Asahi Linux

hyprland 에서 cava를 바탕화면 좌/우측에 위젯처럼 고정 배치하는 방법

elsa in mac 2024. 3. 7. 01:49

CAVA는 cross-platfom Audio Visualizer 로 오디오 출력에 대한 spectrum 에니메이션을 표시해 주는 terminal 기반의 CLI 도구 입니다.

이번 포스트에서는 Linux의 Hyprland WM을 사용하는 환경에서 화면의 왼쪽과 오른쪽 가장자리에 각각 left/right channel로 cava를 위젯처럼 고정 배치하는 방법을 알아 보도록 하겠습니다.  이 방법을 적용하기 위해서는 hyprland를 설치하고 설정을 수정 할 수 있는 수준이 되어야 합니다.

hyprland에서 cava를 위젯처럼 화면 좌/우에 배치한 모습

 

1. hyprland gap 설정
우선, 위의 스샷과 같이 cava를 표시할 빈 영역을 마련해야 합니다. 이를 위해서는 아래와 같이 hyprland의 gneneral 설정에서 gaps_out 을 충분히 줘야 합니다

general {
:
  gaps_in   = 10
  gaps_out  = 220
:
}

gaps_in은 윈도우 간의 이격, gaps_out은 전체 모니터 영역에서 작업영역(workspace) 간의 이격을 의미합니다.  gaps_in이 10 으로 설정했으니 이는 window들 간에 10px 만큼의 gap을 주겠다는 것이고, gaps_out이 220이라면, 이는 전체 화면에서 상/하/좌/우 각각 220px 만큼의 여유 공간을 주겠다는 의미가 됩니다.

그런데, 위의 스샷을 보면 상/하 보다 좌/우의 여백이 좁은 것을 알 수 있습니다. 바뀌 발하면 좌우가 상하보다 긴 직사각형 작업공간을 보여 주고 있습니다. gaps_out은 상/하/좌/우 공히 동일한 gap을 주게 됩니다. 좌/우를 좀 더 넓게 쓰고 싶다면 monitor 설정에서 offset을 설정해야 합니다.

# Hi Refresh Rate
monitor=HDMI-A-1,highrr,auto,1              # monitor scaling 설정 1(100%)
monitor=HDMI-A-1,addreserved, 0,0,-90,-90   # left, right 각각 90px 씩 넓힌다.

위의 설정은 monitor의 좌/우를 90 px씩 넓히는 설정입니다.

 

2. alacritty terminal emulator 설정
cava는 앞서 언급했듯이 terminal에서 실행되는 CLI 도구 입니다. 따라서, 터미널 앱을 띄워서 cava를 실행해야 합니다. 저의 경우에는 foot terminal app을 사용하고, alacritty의 경우에는 cava를 띄우는 목적으로 사용합니다.  여담으로 macOS에서는 kitty를 주력으로 사용해 왔지만, Linux에서는 resource를 보다 작게 점유하고 빠른 foot 터미널을 주력으로 사용합니다.

우선 alacritty를 설치한 후, 기본 설정파일을 설정해 줍니다. alacritty은 ~/.config/alacritty/alacritty.toml 파일이 기본 설정 파일 입니다.  설정은 사용자의 취향에 따라 다르게 설정할 수 있습니다.  [window] 섹션의 opacity를 0으로 주면 배경이 완전히 날라간 투명 창이 됩니다. 0.5 정도 주면 반투명 배경을 갖게 됩니다.

import = ["~/.config/alacritty/catppuccin/catppuccin-mocha.toml"]
live_config_reload = true

[env]
TERM = "xterm-256color"

[font]
size = 13

[font.normal]
family = "Sarasa Term K Nerd Font"
style  = "Normal"

[font.offset]
x = 0
y = 2

[window]
decorations     = "None"
dynamic_padding = false
opacity         = 0.5

[window.padding]
x = 18
y = 16

alacritty를 실행할 때, 왼쪽과 오른쪽에 각각 하나씩 실행을 시켜야 하고, 실행과 동시에 cava를 실행시켜야 합니다. 이를 위해서 설정파일을 2개를 별도로 준비해야 합니다. 

기본적으로 좌/우측 두 개를 구분해서 설정하고 실행시키는 이유는 mono-left 와 mono-right로 채널을 구분하여 cava를 표시하기 위해서 입니다.

위의 설정파일을 alacritty-cava-left.toml 과 alacritty-cava-right.toml 로 복사를 한 후, 각각의 파일 끝에 아래와 같은 내용을 추가해 줍니다.  얘를 들어 alacritty-cava-left.toml에는 아래와 같이 run-cava-left.sh를 실행 시키는 shell 옵션을 추가해 좁니다.  alacritty-cava-right.toml 에는 run-cava-right.sh 를 실행하는 것으로 설정하면 되겠습니다.

[shell]
program = "/home/elsa/.config/cava/run-cava-left.sh"

alacritty의 설정 파일에 [shell]을 정의하지 않으면, 실행될때 기본적으로 .zshrc가 실행됩니다.

 

3. cava 실행 shell script
그럼 이번엔, run-cava-left(right).sh 의 내용을 봅니다.

#!/bin/sh
cava -p ~/.config/cava/config-left

위의 코드는 run-cava-left.sh의 내용 입니다. cava를 -p 옵션으로 해서 config-left 파일을 참조하여 실행하라는 간단한 명령입니다.

정석은 alacritty의 설정파일에서 [shell] 항목에서 직접 cava를 실행시키면 되는데, 실제로 이걸 적용해 보면 실행이 되지 않습니다. 버그인지 아니면 아직 구현이 안된 것인지의 여부는 판단이 되지 않습니다. 암튼, 안됩니다 그래서 어쩔 수 없이 shell script를 하나 만들고 그 안에서 cava를 실행하는 방법을 적용한 것입니다.  config-left 와 config-right는 ~/.config/cava/config 파일을 복사한 후, channels과 mon option을 각각 left와 right로 수정한 파일 입니다.

:
:
[output]

# Output method. Can be 'ncurses', 'noncurses', 'raw' or 'sdl'.
# 'noncurses' uses a custom framebuffer technique and prints only changes
# from frame to frame in the terminal. 'ncurses' is default if supported.
#
# '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 200 bars, which can be adjusted in the 'bars' option above.
#
# 'sdl' uses the Simple DirectMedia Layer to render in a graphical context.
method = ncurses

# 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'.
channels = mono
mono_option = left
:
:

위의 코드는 config-left 파일의 내용으로 , 위에 보는 바와 같이 중간에 [output] 항목에서 channels를 mono로 그리고 mono_option을 left로 정의한 것을 알 수 있습니다. 그럼 당연히 config-right 파일은 mono_option이 right로 정의 하면 됩니다.

 

4. 로그인과 동시에 자동 실행하기
이젠, 로그인을 하여 hyprland WM을 실행할 때, 자동으로 cava가 실행되게 해줘야 합니다. hyprland의 설정에 다음을 추가해 줍니다.

exec-once = alacritty --config-file ~/.config/alacritty/cava-left.toml  --title cava-left  &                                   # for CAVA
exec-once = alacritty --config-file ~/.config/alacritty/cava-right.toml --title cava-right &                                  # for CAVA

alacritty를 백그라운드로 실행 시키는데, config-file을 각각 정의해 주고, 끝에 보면 title을 각각 설정해 주고 있습니다. title을 정의하는 것은 hyprland의 windowrule을 사용하여 alacritty의 실행 시 위치와 크기 등을 각각 설정해야 하기 때문입니다.

 

5. 실행 시 위치와 크기를 설정하는 방법
hyprland에서 특정 윈도우의 실행 시 위치와 크기를 고정하고 focus를 제거하여 마치 위젯처럼 배치하려면 windowrule을 정의하면 됩니다.

# left cava
windowrule = move 10   500, title:^(cava-left)$		# 위치
windowrule = size 100 1000, title:^(cava-left)$		# 크기
windowrule = float,         title:^(cava-left)$		# floating (tiling 방지)
windowrule = pin,           title:^(cava-left)$		# pin 설정 (workspace가 변경되도 계속 표시)
windowrule = nofocus,       title:^(cava-left)$		# focus를 제거

# right cava
windowrule = move 3725 500, title:^(cava-right)$
windowrule = size 100 1000, title:^(cava-right)$
windowrule = float,         title:^(cava-right)$
windowrule = pin,           title:^(cava-right)$
windowrule = nofocus,       title:^(cava-right)$

위의 코드는 특정 title을 갖는 윈도우에 windowrule를 정의한 것입니다. cava-left라는 title을 갖는 window의 경우 10,500 위치에서 100,1000의 크기로 window를 설정하고 float시켜서 윈도우가 tiling 되지 않게 방지합니다. 마지막으로 nofocus 룰을 적용하여 focus를 무시하게 합니다.

여기까지 하면, 모든 기본적인 작업은 완료가 되 것입니다. 이제 logout/login한 후 음악을 틀면 좌/우 각 cava에서 각 채널의 스펙트럼 에니메이션을 볼 수 있습니다.

 

6. pywal을 사용하고 있다면...
pywal은 특정 이미지에서 대표 색상을 추출하여 color palette를 구성해 주는 CLI 도구 입니다. 기본적으로 설치를 하게 되면 cava에 대한 gradiation color palette를 뽑아 주지요. hyperland 설정에서 pywal을 적용하고 있다면 배경화면이 변경될 때 마다 해당 배경 이미지의 color palette를 추출한 후, 이를 바탕으로 cava config을 갱신 시켜주게 됩니다. 해당 config파일은 ~/.cache/wal/cava-colors 파일이 해당됩니다.  이 파일의 reference는 ~/.config/wal/templetes/cava-colors 파일 입니다.

따라서, cava의 기본 설정을 변경하려면, ~/.config/wal/templetes/cava-colors 파일을 수정해야 합니다. pywal은 배경화면이 바뀔 때마다 이 파일을 가져다가 내부의 gradient 파일의 컬러 테이블을 업데이트하게 됩니다.

그럼, 이 변경된 cava-colors 파일을 기준으로 config-left 와 config-right를 만들어 줘야 합니다. 아래 코드는 이것을 자동으로 해 주는 간단한 shell script 파일 입니다. 완쪽과 오른쪽 채널에 대해 각각 shell script를 다른 이름으로 만들어 줍니다.

#!/bin/bash

# 원본 파일 절대경로
original_config="/home/elsa/.cache/wal/cava-colors"

# 복사 대상 파일 절대경로
target_config="/home/elsa/.config/cava/config-left"

# 원하는 변경 내용
change1="channels = mono"
change2="mono_option = left"

# 원본 파일을 복사하여 대상 파일로 생성
cp "$original_config" "$target_config"

# sed를 사용하여 복사한 파일에서 변경 내용 수정
sed -i "s/; channels = stereo/$change1/g" "$target_config"
sed -i "s/; mono_option = average/$change2/g" "$target_config"

 

배경화면을 변경했을 때 실행되는 shell script 가 있다면, 해당 shell script에서 위의 스크립트를 실행하여 config-left와 config-right를 갱신해 준 후, pkill -USR2 cava 명령으로 cava window을 모두 종료 시킨 후, 다시 실행시켜 주면 됩니다. 

alacritty --config-file ~/.config/alacritty/cava-left.toml  --title cava-left  &                                   # for CAVA
alacritty --config-file ~/.config/alacritty/cava-right.toml --title cava-right &                                  # for CAVA

위의 방법은 기본적으로 window의 title을 기준으로 특정윈도우를 위젯처럼 화면에 고정시킬 수 있는 hyprland의 기능을 이용한 것입니다. 따라서, 비단 이번 포스트에서 살펴본 것 처럼 2개의 cava를 각가 좌우에 배치할 수도 있고, 아니면 화면 하단에 1개의 cava를 배치할 수도 있고, 또는 cava가 아닌 다른 기능을 위해서 응용할 수 도 있습니다.

공유하기 링크
Comments