Linuxのデスクトップ環境をi3からswayへ移行してみた

# 動機

- Waylandそろそろ安定してきたっぽいし
- CentOS8でもWaylandデフォルトの模様（CentOSに遅れを取るわけにはいかない！Ubuntu20.04はまだX11だと思われる）
- 周りにi3使っている人が増えてきたので、差別化のため（というか、「あ、まだi3使ってるんだ〜。おれはsway」ってドヤッってしたいため）

# 私の環境

PC: Thinkpad X11 carbon 6gen(2018)
OS：ArchLinux

# 移行方法

1. `sudo pacman -S sway xorg-server-xwayland`
2. ログインマネージャーからswayを選んでログイン

まあそんだけですね。


# 移行直後に起動した感想

- 設定ファイルの場所を変えなくても、i3の設定をそのまま読み込んでくれた (i3blocks)。
- i3の設定ファイルでもエラーも出ない（たぶん無効な設定は無視されている）
- スクロールがなんかヌルヌル動く
- ウィンドウをマウスで操作しやすくなっていた（移動させたりとか）。
- i3にはなかったChromiumに最小化/フローティング化/閉じるボタンが表示されていた

![20200504_04h07m32s_grim.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107220/ef4b8709-e9b8-f185-e6fc-805252eafb98.png)


### 動く

- 画面表示
- 音
- キー入力
- zsh
- tmux
- neovim
- chromium ：xwayland入れないと `cannot open display:`
- dunst
- rofi
- clipmenu
- feh

### なんとなく動いている

- alacritty ：なぜかフォントが小さい、日本語入力できない
- fcitx + mozc ：.xprofileで起動しているはずなのに起動している？？
- i3blocks ：通知領域(NetworkManagerとかIMEとかの)は表示されず

### 動かない

- 壁紙
- i3-easyfocus
- xclip/xsel
- flameshot(スクリーンショットアプリ) ： 黒い画像になる
- peek(スクリーンレコーダー) ：黒い画像が保存される


# 方針

とりあえずi3とswayの設定ファイルを分離して作成する。
共用しても動きそう(vim/neovimみたいな感じで)だが、i3の設定にはif文がないため分割してドッキングする必要がある。とりあえず、i3のものをコピーして作って共用できそうな箇所をあとで整理する。

### 参考資料

ここにi3->swayでの各設定やツールの切り替え方法とかがまとまっている。
https://github.com/swaywm/sway/wiki/i3-Migration-Guide


---


# 修正

## .sway/configを修正

- i3-msg -> swaymsg
- 動いていないアプリの設定を除外

## 壁紙設定

fehが動かないのでswayのoutputというやつを使う

```shell
output "*" background ~/.wallpaper/* fit
```

https://manpages.debian.org/experimental/sway/sway-output.5.en.html


## alacrittyの修正

### alacritty上でfcitxが動作しない

alacritty以外のアプリでは普通に動作している。。。
`WINIT_UNIX_BACKEND=x11 alacritty` だとちゃんと動作した。

### alacrittyのフォントサイズ修正

`WINIT_UNIX_BACKEND=x11 alacritty` だと前と同じサイズで表示されるようになった。


## fcitxが起動している件

lightdmが.xprofileを読み込むみたい。 (/etc/lightdm/Xsession)
Xの設定情報がWaylandで読み込まれるのが気持ち悪いのでxprofile側でガードする。

```shell:.xprofile
if [ "$XDG_SESSION_TYPE" == "wayland" ]; then
  sleep 1
  return # もとのファイルでsourceしているのでexitだと抜けてしまう
fi
```

fcitxはsway側で立ち上げるようにする

```shell:.sway/config
exec --no-startup-id "fcitx -rd"
```


## .xprofileで設定している環境変数設定を置き換える

ターミナルでfcitxを使えるように設定とか、カーソルの移動速度変えたりとかで使う。/etc/environmentに入れるのがよさそうだが dotfiles で管理したい。

Systemd version 233 からは ` ~/.config/environment.d/wayland.conf` 
が使えるみたいなのでこちらに記述

https://wiki.archlinux.jp/index.php/Systemd/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0

しかし、反映されてない模様。どうやらユーザーのsystemdのとき（ `systemctl --user` のやつ)にしか反映されない模様。


***`~/.pam_environment`
こっちに設定してみたらfcitxの環境変数はうまく設定できた。ただし、このファイルではコマンドが打てないのでカーソルの速度変更とかはできず。***

## カーソルの移動速度を変える

なんだかんだ、たぶんこれに一番時間を使った気がする。。。

#### タッチパッド

udevのhwdbでやるとかいろいろやってみたが、swayのinputでやるのが一番よさそう。
https://github.com/swaywm/sway/wiki#input-configuration

```shell:.sway/config
input type:touchpad {
    pointer_accel 0.7
}
```

capsをctrl上書きもできる模様

```shell:.sway/config
input type:keyboard {
    xkb_options ctrl:nocaps
}
```

typeの情報とかは `swaymsg  -t get_inputs` を実行すれば取得できる。


#### トラックポイント

トラックポイントはなぜかタッチパッドと同じ方法ではうまくいかなかった。udevのhwdb使ってもだめだった。

libinputの/etc/libinput/local-overrides.quirksというファイルを新しく作って、上書きするという方法だとうまく速度調整できた。（逆にタッチパッドもここで設定しようと思ったけどそれはうまくいかず。。。）
quirksファイルはすぐに適用される模様（ `libinput quirks list /dev/input/eventXX` で確認したところ ）
https://wayland.freedesktop.org/libinput/doc/latest/trackpoint-configuration.html

```ini:/etc/libinput/local-overrides.quirks
[Trackpoint Override]
MatchUdevType=pointingstick
AttrTrackpointMultiplier=1.5
```

## 通知領域(NetworkManagerとかIMEとかの)は表示されず

今sway側で実装中の模様だからもう少し待つ必要がある。

https://github.com/swaywm/sway/issues/1357
https://github.com/swaywm/sway/pull/5161

network-managerの設定は開く機会も多いと思うが、一応
`nm-connection-editor` と `nmcli`
で同じ代替することができる。


## i3-easyfocusの代替探し

https://github.com/svenstaro/wmfocus/
というRust製のを使ってみたところswayでも動作した。

が、作者は別にswayで動作させることを目的としておらずなぜか動いている状態なので今後どうなるかは不明である。


## xclip/xsel

wl-clipboardを使う。WAYLAND_DISPLAYが定義されているか否かでX11と処理を切り替えられる。

```shell
if [ "$WAYLAND_DISPLAY" != "" ]; then
  if builtin command -v wl-copy > /dev/null 2>&1; then
    xxx
  fi
fi
```


## flameshot(スクリーンショットアプリ) の代替探し

IssueではWayland対応したとの記載もあったが2020/05/03時点では動かなかった。

Google検索やRedditなどでよさげなものを探してみたがあまりいいものは見つからなかった（Wayland対応しているものが少ない・・・）。
https://wiki.archlinux.org/index.php/Screen_capture

結局swayの[i3-Migration-Guide](https://github.com/swaywm/sway/wiki/i3-Migration-Guide) にある `slurp` `grim` にすることにした。
`yay -S slurp grim`
flameshotと比べれば、即時編集や保存先選択などの気の利いた機能はないが、範囲選択キャプチャなどscrotレベルには使えることがわかった。

## peek(スクリーンレコーダー) の代替探し

Issueでは動くという話しもあるが2020/05/03時点では動かなかった。

Google検索やRedditなどでよさげなものを探してみたがあまりいいものは見つからなかった（Wayland対応しているものが少ない・・・）。
https://wiki.archlinux.org/index.php/Wayland#Screen_recording

結局swayの[i3-Migration-Guide](https://github.com/swaywm/sway/wiki/i3-Migration-Guide) にある `wf-recorder` にすることにした。
`yay -S wf-recorder`
GUIがなく少し不便ではあるが使えないことはない。

---


# i3,swayの設定ファイル共通化してみる

ステップとしては以下の通りである
1. i3にて共通で使用できる部分とそうでない部分のファイルを分ける (以下の例では config.baseとconfig.i3部分に相当)
2. 共通して使う部分はsway側からシンボリックリンクを張る
3. 設定ファイル結合スクリプト（次章にサンプルを記載している）を作成し、それを用いてi3,swayが実際に読み込むconfigを作成する

```shell
.i3
├── config # mkconfig.shで自動生成。リードオンリーになっている。ここをいじらない。
├── config.base # sway側と設定共有できる部分を記述
├── config.gaps # i3-gapsの設定を記述
├── config.i3   # i3固有のアプリケーション設定
├── i3blocks.conf
└── scripts
   └── mkconfig.sh

.sway
├── config  # mkconfig.shで自動生成。.sway以下のものだけをまとめる。
├── config.base -> ../.i3/config.base  # i3側の設定と共通化したいものはシンボリックリンクを張る
├── config.gaps -> ../.i3/config.gaps
├── config.input # swayはハードウェアの設定が可能なためその設定はここに記述
├── config.sway # sway固有のアプリケーション設定
└── scripts
   └── mkconfig.sh -> ../../.i3/scripts/mkconfig.sh
```

### 設定ファイル結合スクリプト

```shell:.i3/config.i3
bindsym $mod+Control+Shift+r exec "~/.i3/scripts/mkconfig.sh && i3-msg reload"
```

```shell:.sway/config.sway
bindsym $mod+Shift+r exec "~/.sway/scripts/mkconfig.sh && swaymsg reload"
```

```shell:mkconfig.sh
#!/usr/bin/env bash

ROOT_DIR=$(cd $(dirname $0)/..; pwd)
CONFIG="$ROOT_DIR/config"

[ -e "$CONFIG" ] && rm -f $CONFIG
cat "$ROOT_DIR/config.base" > $CONFIG

shopt -s extglob
if ls $ROOT_DIR/config.!(base*) > /dev/null 2>&1; then
  cat $ROOT_DIR/config.!(base*)  >> $CONFIG
fi

chmod 444 $CONFIG
```

### 外部ディスプレイ設定

ディスプレイ情報取得

```bash
swaymsg -t get_outputs
```

外部ディスプレイへの出力

```bash
swaymsg output HDMI1 pos 0 0
```

xrandr感覚で使える。ただ、 **xrandrではあった接続時にちらつく挙動がまったくないのがすごい。**


---

# sway移行後の感想

使用感としてはよくなってる気がします。ただツール類がまだ整備されてないところもあってX11で簡単にできていたあれがうまくできない的なことは起こり得ると思います（ハードウェア周りとかツール周りが特にそうかと）。
ツール類とかは成熟しているのではと思ってましたが、まだまだサポートしていないもの、絶賛開発中のものが多い印象です。ですので、最近作るものなくなって暇だなーっていう人は移行するといろいろ課題を見つけられておもしろいと思います。
安定思考の人は特段そのままi3でも問題ないように思います。 ***swayになったからといってなにかが劇的に変わるということはなかったです。***

最後にもう少し詳細が知りたい方は、以下のリポジトリに私の設定がまとまっています。
<a href="https://github.com/yutkat/dotfiles"><img src="https://github-link-card.s3.ap-northeast-1.amazonaws.com/yutkat/dotfiles.png" width="460px"></a>