Sway on Archlinux

# SwayをArchlinuxで
Archlinuxになれてみようということで、PCにM2SSDを追加して、そちらにarchlinux + swayで現行環境のコピーを作ってみることにしてみました。
その際のTIPSなどをまとめます。

# ArchLinuxの構築
## まずは起動まで
世の中に公開されている手順の通りです。
以前[こちら](https://qiita.com/nfwork01/items/f6a5e642f3ecbe25ecbe)で確認していた通りの手順でだいたいうまくいったのですが、UEFI周りで少々トラブルが。

efibootmgrで、反応がない、、
マザーボード依存だとは思うのですが、起動時にDELなどを押してUEFI画面を起動して、bootの設定をいろいろon/offしていてようやく反応が返ってくれるようになり、grub-installが通りました。

rootのパスワード設定するの忘れててログインできず再度CDブートする羽目になったりしましたが。。ちゃんとやれば大丈夫。

## セキュリティ設定
### nftablesとiptables
iptablesは結構前から順次nftablesに置き換えられている、というのを今回知りまして。。
UI周りがfirewalldなどにラッピングされるようになってるあたりまでは把握していたのですが、追っかけられていなかった。。。

ちなみにubuntuも21.10からnftablesが標準になったそうで。
https://discourse.ubuntu.com/t/impish-indri-release-notes/21951
ただし、iptablesでnftablesを呼び出すという仕組みらしく、nfwコマンドはディフォルトで入っていないです。微妙な、、
https://askubuntu.com/questions/1370901/ubuntu-21-10-switched-to-nftables-so-why-is-iptables-still-available

で、ArchLinuxはというと、標準でiptablesが入っていて、かつそれが他のパッケージの依存元になってしまっているようです。

```
# pacman -Rns iptables
checking dependencies...
error: failed to prepare transaction (could not satisfy dependencies)
:: removing iptables breaks dependency 'iptables' required by iproute2
:: removing iptables breaks dependency 'iptables' required by systemd
```

単純にiptablesをアンインストールして、nftablesを入れる、という手順というわけにはいかなさそうなので、ちょっと調べてみました。
https://wiki.archlinux.jp/index.php/Iptables
https://knowledge.sakura.ad.jp/22636/

解釈があっているか自信がないけれど、

- iptablesを使っているライブラリのために、互換性レイヤを用意している(iptables-nft)
- ユーザがnftablesのネイティブな方法(nft)で設定をするには、nftablesの導入が必要

てところでしょうか。
ですので、nftablesを採用する場合にすべきことは、以下の２つでしょうか。

- iptablesをiptables-nftに置き換える（iproute2とsytemdのため）
- nftablesをインストールする（任意の接続制限をユーザが設定するため）

やってみましょう。

```
# pacman -S iptables-nft
resolving dependencies...
looking for conflicting packages...
:: iptables-nft and iptables are in conflict. Remove iptables? [y/N] y

Packages (2) iptables-1:1.8.7-1 [removal]  iptables-nft-1:1.8.7-1

Total Download Size:   0.42 MiB
Total Installed Size:  2.41 MiB
Net Upgrade Size:      0.00 MiB

:: Proceed with installation? [Y/n] y
:: Retrieving packages...
 iptables-nft-1:1.8.7-1-x86_64                                              433.3 KiB   256 KiB/s 00:02 [#############################################################] 100%
(1/1) checking keys in keyring                                                                          [#############################################################] 100%
(1/1) checking package integrity                                                                        [#############################################################] 100%
(1/1) loading package files                                                                             [#############################################################] 100%
(1/1) checking for file conflicts                                                                       [#############################################################] 100%
(2/2) checking available disk space                                                                     [#############################################################] 100%
:: Processing package changes...
(1/1) removing iptables                                                                                 [#############################################################] 100%
(1/1) installing iptables-nft                                                                           [#############################################################] 100%
:: Running post-transaction hooks...
(1/2) Reloading system manager configuration...
(2/2) Arming ConditionNeedsUpdate...
```

iptablesは、勝手に置き換えをしてくれるのですね。
で、nftablesは特に問題なくインストールが通ります。
ただし、サービス登録は必要。

```
# systemctl enable nftables.service
# systemctl start nftables.service
```

nftablesを入れると、/etc/nftables.confを作成してくれて、sshdとicmpだけ許可してくれるようになってます。
文法はちゃんと勉強しておかないといけないですね。。。
docker導入するとどうなるんだろう、、あれ結構iptablesを派手に弄るのですが、iptables側の設定と両方入れた場合の振る舞いとか。
別途調査しておくか。

### AppArmor, Landlock
やらにゃならんとは思うのですが、かなりこってり調べないといけないので、今回はパス。

# Swayの構築
さて、ここからSwayです。

## インストール
```
# pacman -S sway
```

インストールが終わり次第、ターミナルで「sway」と入力すれば起動しますが、ターミナルエミュレータも何もまだ入っておらず、なんにもできなくなるので、起動はまだ。

## 最低限のパッケージの導入と最低限の設定
まぁターミナルエミュレータさえあればswayに入ってから追加導入できますから、まずはそこから。

### Alacrittyの導入
swayの標準なので、入れておきます。
ただし、これ別途まとめますが、背景画面を設定できなかったり、表示が何故かちょこちょこぶれたりして気持ちよくはないですので、いざというときのため入れておくけど、通常はつかわない、という位置づけのものにします。

```
# pacman -S alcritty
```

### Modの変更
キーバインドについて、標準だと$modがMOD4(super)がディフォ。
i3だとMOD1(alt)がディフォ、、だと思うのだけれど、そこが違和感あったので直します。

```
$ cat .config/sway/config | grep "set \$mod"
set $mod Mod1
```

ModXがどのキーに対応しているかは以下を参照。
https://wiki.archlinux.jp/index.php/Xmodmap

### Aurmanの導入
ここから先の手順で、どうしてもpacman配布のパッケージでは足りないものが出てきます。
ベースで使う環境なので、あまりあちこちからパッケージを集めてくる方針は取りたくないのですが、現状他に妙案ないので、仕方なし。

以下を参考にさせていただき、導入しておきます。
https://www.archlinux.site/2018/08/auraurman.html

## Sway上での設定
ここから先はSwayに入って進めていきます。

```
$ sway -d > ./sway.log >&1
```

### Display
マルチディスプレイを使っている場合、適当なレイアウトで読み込んでくれています。
で、これを自分の使いやすい配置にしないといけません。
GUIで、設定を変えてくれるものはあるのですが、保存はできないので、結局最後はswayのコンフィグにおとさないといけません。

#### 配置の可視化
wdisplaysというものを利用します。

```
$ aurman -S wdisplays
$ wdisplays
```

はい。初っ端からaurmanですね。。
まぁこいつでレイアウトをいじれますので、これで適切な配置を決めてしまいます。

#### 配置の読み取りと保存

```
$ swaymsg -t get_output
```

ズラズラ表示されて見づらいのですけれど、読み取るべきは各ディスプレイの頭にある"HDMI-XX"のような名称、Current mode、Positionの３つ。
これを読み取って、以下のようにswayのconfigに書き足します。

```
$ cat .config/sway/config | grep output
output DVI-D-1 pos 1280 720 res 2560x1440
output HDMI-A-3 pos 3840 0 res 3840x2160
output HDMI-A-1 pos 3840 2160 res 2560x1440
```

で、

```
$ swaymsg exit
$ sway
```

ということで入り直せばOK。
設定の読み直しでも大丈夫とは思いますが、私は何度か（変な設定したせいで）画面クラッシュさせているので、一応入り直してます。

### Audio

```
# pacman -S ffmpeg pulseaudio pavuctontrol
# pacman -S pulseaudio-alsa alsa-utils
$ pavucontrol
``` 

こちら、画面のoutputに余計な設定入れたせいで音が出ないでないと苦しんでいたのですが、変な設定入れてなければpavucontrolでボリューム調節すれば大丈夫、、なはずです。
かなり試行錯誤してしまったので、最小限の手順がわからなくなってしまっているので、後日再度クリアインストールしてそこで試します。

### ブラウザ
ピュアなwaylandできっちり動く、Firefoxを導入します。

```
# pacman -S firefox firefox-i18n-ja adobe-source-han-sans-jp-fonts
```
日本語表示のため、フォントも入れます。
フォントは選択肢が色々ありますが、かなりクセがあり、趣味に合うものを探すのも一苦労です。。
でもこれだけで動きますから、素晴らしい。

### 日本語化

```
# pacman -S fcitx5-qt fcitx5-mozc fcitx5-config-qt qt5-wayland
$ echo "exec fcitx5" >> .config/sway/config
$ fcitx5-configtool
```
これでmozcを登録して、切り替えのキーバインドを自分の好みにすればOK。
ただし、後でxwaylandを入れるのですが、その際には改めて設定を追加しないとFirefoxで日本語入力ができなくなります。

また、アプリが勝手に日本語でディレクトリやファイルを作ってしまった際に、ターミナルで表示してもらえるようにするために少しひねります。

```
# echo ja_JP.UTF-8 UTF-8  >> /etc/locale.gen

$ cat /etc/locale.conf
 LANG=ja_JP.UTF-8
LC_CTYPE="ja_JP.UTF-8"
LC_NUMERIC="C"
LC_TIME="C"
LC_COLLATE="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_PAPER="C"
LC_NAME="C"
LC_ADDRESS="C"
LC_TELEPHONE="C"
LC_MEASUREMENT="C"
LC_IDENTIFICATION="C"
LC_ALL=
```

あとちょっと趣旨が違いますが、Capsはずします。

```
$ echo "input type:keyboard {\n    xkb_options ctrl:nocaps\n}" >> .config/sway/config
```

## ユーティリティ機能の設定
### Menu
dmenuがswayだと(xwaylandを入れないと）動かないです。
。。。結局他のアプリの関係でxwayland入れることにはなるんですけど、まぁ、こういうのは心がけが大事ということで、別の方法をとります。

前に調べたfzfを使って組み上げる方法になるのかな、、と思ったら、Archlinuxのサイトでbemenuが例示されてました。
それ使ってみることにします。

```
# pacman -S bemenu-wayland
$ cat .config/sway/config | grep "set \$menu"
set $menu bemenu-run --nb "#3f3f3f" --nf "#dcdccc" --fn "pango:DejaVu Sans Mono 12"
```

引数が長々入ってますが、これフォントと配色です。
標準だと非常に見づらくて使い物にならん。。

あと、bemenuだと、複数候補があるときに矢印キーの右左で選ぶということができなく、上下の選択になってしまいます。
dmenuと使用感が違っていやなのですが、、仕方なし。

### ScreenShot
地味に重要。
特にこういうサイトに投稿するときは画面取らないといけないときが多々あるので。

Sway、、というかWaylandで、マウスで領域を選んで、というようなことができるものは、残念ながら現状では見つけられませんでした。
ですので、コマンドラインで領域を選択するもの(grim)と、マウスで領域を選択して結果を出力するもの(slurp)を組み合わせる方法を取ります。
以下を参考にさせていただきました。
https://scrapbox.io/onokatio/Wayland%E3%81%A7%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88
https://wiki.archlinux.jp/index.php/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%E3%81%AE%E5%8F%96%E5%BE%97#Wayland

```
# pacman -S grim jq slurp

$ cat .config/sway/scripts/grim.sh
#!/bin/sh
GRIM_DEFAULT_DIR='<Your Directory>' grim -g "$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp)"

$ cat .config/sway/config | grep "bindsym Print"
bindsym Print exec ~/.config/sway/scripts/grim.sh
```

### 動画のキャプチャ
https://wiki.archlinux.jp/index.php/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%BC%E3%83%B3%E3%82%B7%E3%83%A7%E3%83%83%E3%83%88%E3%81%AE%E5%8F%96%E5%BE%97#Wayland

```
# pacman -S wf-recorder

$ cat /usr/local/bin/myrec
#!/bin/bash
dname='/home/hogemin/screenshot'
snapflag='/tmp/screen_capture_frag'

function help () {
  echo "Usage: $0 [-s] [-k]" 1>&2
  exit 1
}

function show () {
  if [ -e "${snapflag}" ]; then
    echo "Recording"
  fi
}

function stop_rec () {
  pid=$(cat ${snapflag})
  kill -9 ${pid}
  rm "${snapflag}"
}

function rec () {
  if [ ! -e "${dname}" ]; then
    mkdir -p "${dname}"
  fi

  fname=${dname}/$(date "+%Y%m%d_%H%M.mp4")

  wf-recorder -f ${fname} -g "$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp)" >/dev/null 2>&1 &
  echo $! > ${snapflag}
}

function run () {
  if [ -e "${snapflag}" ]; then
    stop_rec
  else
    rec
  fi
  pkill -SIGRTMIN+11 i3blocks
}

while getopts sk OPT
do
  case $OPT in
    "s" ) STATUS="TRUE" ;;
    "k" ) KILL="TRUE" ;;
      * ) help ;;
  esac
done

if [ "${STATUS}" = "TRUE" ]; then
  show
elif [ "${KILL}" = "TRUE" ]; then
  if [ -e "${snapflag}" ]; then
    stop_rec
  fi
else
  run
fi

$ cat .config/sway/config | grep "bindsym \$mod+Print"
bindsym $mod+Print exec /usr/local/bin/myrec
```

キーバインドにくくりつけたかったので、スクリプトでラッピングしました。
動画を取る場合は画面を取る場合と違って、コマンド叩いて終了ではなくて、始めた録画を止めないといけません。
ですので、スクリプトの方で少しひねりまして、呼び出されるたびに録画開始/停止をスイッチして行うという実装にして、キーバインド側ではシンプルに毎回同じスクリプトを叩けばいいというようにしました。

また、後述するi3blocksへの表示のために、現在録画が動いているかを確認するためのオプション(-s, show)と、Signal送付（pkill)も設けました。
pkillは使わず、i3blocksで数秒おきにポーリングする実装にしてもいいのですが、秒おきにスクリプトが叩かれるのも気持ちが悪いですので、シグナルでのリアルタイム処理にすることにしました。

### 画像と動画の閲覧
https://github.com/swaywm/sway/wiki/Useful-add-ons-for-sway#image-viewers
画像はとりあえずimv、動画はmviがpacmanでは引っ掛けられなかったので、mpvで。

```
# pacman -S imv mpv
```

### 自分の趣味に合うターミナルエミュレータ
https://wiki.archlinux.jp/index.php/%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E4%B8%80%E8%A6%A7/%E3%83%A6%E3%83%BC%E3%83%86%E3%82%A3%E3%83%AA%E3%83%86%E3%82%A3

感触kittyが良さげだったのですが、高解像度ディスプレイで動かすと若干もっさりする、背景が設定できるけど中央寄せができない（拡大、タイル、左上寄せしかできない、、）ということでNG。。
背景画像の中央表示＋ウィンドウサイズに合わせた拡大縮小をガッツリやってくれるエディタというと、現状使っているxfce4-terminalくらいしか思いつかないので、そちらを継続利用することにします。。

```
# pacman -S xfce4-terminal
```

### VriatualBox
今回最大の問題児です。。
インストールの依存関係的にはxなしで動くように見るのですが、こうなります。。

```
$ virtualbox
Qt WARNING: could not connect to display
Segmentation fault (core dumped)

```

対処としては、今のところはxwaylandを入れざるを得ないようです。

```
# pacman -S xorg-xwayland
```

これで、いつものGUIが開きます。
ただし、これと関係しているのかしていないのか、コンフィグし直せというエラーも出るので、その場合は以下が必要です。

```
# modprove vboxdrv
# /sbin/rcvboxdrv setup
```

### タスクバー
今回、上に書いた「動画のキャプチャ」に関して、キャプチャが動いている最中はそれがわかるように表示したいなぁ、、と思って色々調べた結果、i3blocksを使うことにしました。
で、サンプルの設定とか探していて、結局こちらを参考にさせていただきました。

https://www.simple-web-system.work/entry/2019/12/10/153217

archlinuxのアップデート確認とかも仕込める！
とりあえず直近で使いそうなものを見繕い、動画キャプチャ中は画面に専用の文字が出るようにしてみます。

```
# pacman -S i3blocks awesome-terminal-fonts ttf-font-awesome
# pacman -S sysstat pacman-contrib bc

$ cd .config/i3blocks
$ git clone https://github.com/vivien/i3blocks-contrib

$ cat .config/sway/config | grep status_command
    status_command SCRIPT_PATH=~/.config/i3blocks/i3blocks-contrib i3blocks

$ cat .config/i3blocks/config
command=$SCRIPT_PATH/$BLOCK_NAME/$BLOCK_NAME
separator_block_width=15
markup=none

# Record Mode
[recorder]
command=/usr/local/bin/myrec -s
signal=11

# Arch Update
[arch-update]
interval=3600
markup=pango
LABEL=Updates:

# Volume indicator
[volume]
label=♪
interval=once
signal=10

# Memory usage
[memory]
label=MEM
separator=false
interval=30

[memory]
label=SWAP
instance=swap
separator=false
interval=30

# Disk usage
[disk]
label=HOME
interval=30

# Network interface monitoring
[iface]
color=#00FF00
interval=10
separator=false

[iface]
command=$SCRIPT_PATH/iface/iface -6
color=#00FF00
interval=10
separator=false

[bandwidth]
interval=5

# CPU usage
[cpu_usage]
label=CPU
interval=10
min_width=CPU 100.00%

[load_average]
label=LOAD
interval=10

# Date Time
[time]
command=date '+%Y-%m-%d %H:%M:%S'
interval=5
```

２行目で導入しているのは、i3blocks-contribで今回使うスクリプトが使うパッケージです。
ちょっと表示量が多くなりすぎているし、負荷が変わると表示の横幅が変わってしまうやつがいて、そいつらのせいで横幅がパラパラブレるのはイケてないですね。。
上記の設定だと、bandwidthが暴れます。
あと、表示が多くてちょっとうるさいということもあるので、使うものの整理とスクリプトの中身の精査は一回きっちりしないと行けないですね。

# まとめ
日頃使いで使えるArchLinux環境を、ということでいろいろ試行錯誤しました。
調べもの関係でかなりのパッケージを入れてしまったので、この手順でもう一回クリアインストールして手順のヌケモレがないか見てみようと思います。

他にも利用開始してみたら調べてみたいことも多々あるので。

とりあえずはこんなところで。