Waylandで動くタイル型ウィンドウマネージャ・swayを使う
これはなに?
Arch Linuxを使い始めました。デスクトップ環境/ウィンドウマネージャとしてTiling Wayland Compositorのsway(swaywm)を導入したので、経緯と手こずった点のメモを残しておきます。[1]
テーマはDracula。
設定はお世辞にも綺麗とはいえないdotfilesにあります。
経緯・コンセプト
デスクトップを自作して、Arch Linuxをインストールしました。初めてLinuxに触れたのが今年3月(WSL)だったことを思えば、いくらか拙速の感はありますが、できるところまでは突き進んでみるつもりです。
GUI環境の選択にあたって、以下の希望がありました。
- できるだけキーボードで操作したい
- 制約なくキーバインドをカスタムしたい
- 美麗なデスクトップが作りたい
- せっかくなのでArch Linuxっぽいことがしたい
- なんかModernにキメたい
GNOMEやKDEなどのメジャーなデスクトップ環境は便利で統一感もありますが、依存パッケージを見るとちょっと驚きます。単純に数が多いうえに、ターミナルやファイルマネージャ一つ入れるにも色々な関連サービスが付いてきたり。もちろん、利便性との兼ね合いなのはわかりますが、個人的にはミニマルなArchに入れるには勿体ないと思ってしまうのも事実です。
かといって、いまさらXベースのウィンドウマネージャを使い始めるというのもちょっと癪です。Waylandが掲げる
- ちらつきのない描画
- セキュアなコンテンツ管理
等には心惹かれますし、どうせ最先端のArchを使うならより新しいものに触れたい。
そこでswayです。swayはタイル型ウィンドウマネージャ・i3wmのWaylandにおける代替で、両者はほぼ同じ設定ファイルで動作します。軽快な動作とシンプルさを特徴とし、機能を絞って合理的な作業環境を提供してくれます。
筆者は現在swayをメインとし、i3wmをバックアップ・サブ環境として運用しています。どちらかで詰まってももう一方が使えると安心感がありますし、ともに快適で満足しています。
swayの導入
pacman -S sway xorg-xwayland qt5-wayland
ひたすらWiki やWikiを読むのみですが、いくつか調べた点をメモ。
起動に関する諸々
起動スクリプト
swayの起動について。dbus-run-session sway
での起動を推奨する情報がGentoo Wikiにあったのですが、自分の環境ではこちらを使うとgnome-keyringがキーリングを表示しなくなる現象を確認したため、sway
を使っています。Arch wiki/Sway wikiにも後者しか記載されていません。
また、Waylandバックエンドで一部のアプリを表示するためには環境変数の設定が必要です。これはswayの起動以前に宣言する必要があり、swayのみを使うならPAM^2やsystemd、~/.zshenv
あたりで読み込んでやってもよいのですが、今回はi3wmと併用することを踏まえ、システム全体に手を加えないように起動用スクリプトを作って記述してやります。以下のものは最低限の例なので、二重起動防止などを加えるとよさそうです。
#!/bin/sh
XDG_SESSION_TYPE=wayland
XDG_CURRENT_DESKTOP=sway
XDG_CURRENT_SESSION=sway
LIBSEAT_BACKEND=logind
QT_QPA_PLATFORM=wayland
GDK_DPI_SCALE=1.5
QT_SCALE_FACTOR=1.5
MOZ_ENABLE_WAYLAND=1
WINIT_UNIX_BACKEND=x11
export XDG_SESSION_TYPE XDG_CURRENT_DESKTOP XDG_CURRENT_SESSION LIBSEAT_BACKEND QT_QPA_PLATFORM GDK_DPI_SCALE QT_SCALE_FACTOR MOZ_ENABLE_WAYLAND WINIT_UNIX_BACKEND;
exec sway
ディスプレイマネージャ
swayが公式にサポートしているディスプレイマネージャはありませんが、SDDMやGDM、LightDMあたりからは起動できるようです。自分はLightDMにしました。もちろんコンソールから起動するのもアリでしょう。
pacman -S lightdm lightdm-webkit2-greeter lightdm-webkit-theme-litarvan
greeterのテーマ↓[2]
LightDMはswayのデスクトップエントリ(/usr/share/wayland-sessions/sway.desktop
)を自動で認識して選択肢に表示してくれるので、Wikiに従って設定したら、あとは先程の起動スクリプトを実行するように書き換えたエントリを追加します。
[Desktop Entry]
Name=Sway
Comment=An i3-compatible Wayland compositor
Exec=/usr/local/bin/swayon
Type=Application
分数スケーリング
ディスプレイの解像度次第では、150%くらいの表示倍率がちょうどいい塩梅に思える場合があります。そこで1.5倍にスケーリングしてやりたいところですが、あいにくsway公式は小数スケーリングを推奨していません。
Fractional scaling is supported but is not recommended. Your display does not have fractional pixels - and if you enable fractional scaling we cannot display your windows faithfully, and your image quality will be degraded.
なるほど。
# 公式では非推奨
output HDMI-A-1 scale 1.5
試しにやってみるとsway自体は問題なく動作しますが、XWaylandで動くアプリケーションで表示が滲みます。現状、解決策は整数スケーリングへの変更しかないようです。
代わりに、前述の起動スクリプトで各GUIライブラリごとにスケーリングを設定します。だいたいはこれで調整できます。
GDK_DPI_SCALE=1.5
QT_SCALE_FACTOR=1.5
また、XWaylandアプリのdpiは~/.Xdefaults
で設定できます。
Xft.dpi = 144
GTKテーマ
swayは$XDG_CONFIG_HOME/gtk-3.0/settings.ini
ないし ~/.gtkrc-2.0
で指定されたGTKテーマを読み取りません。これを設定するため、gsettingsコマンドを用いたスクリプトが紹介されています。
# !/bin/sh
# usage: import-gsettings <gsettings key>:<settings.ini key> <gsetting key>:<settings.ini key>...
expression=""
for pair in "$@"; do
IFS=:; set -- $pair
expressions="$expressions -e 's:^$2=(.*)$:gsettings set org.gnome.desktop.interface $1 \1:e'"
done
IFS=
eval exec sed -E $expressions "${XDG_CONFIG_HOME:-$HOME/.config}"/gtk-3.0/settings.ini >/dev/null
これをswayロード時に実行します。
exec_always ~/.bin/import-gsettings.sh \
gtk-theme:gtk-theme-name \
icon-theme:gtk-icon-theme-name \
cursor-theme:gtk-cursor-theme-name
nwg-look
(2022/07/10追記)
なんとsway / wlroots向けの設定エディタがありました。良い話。
個別のウィンドウ設定
(2021/9/4 追記)
いくらタイル型ウィンドウマネージャとはいえ、あらゆるものがタイル型で表示されるのも困ります。そこでウィンドウごとに表示オプションを設定できます。
# allow floating popup exceptions
for_window [app_id="firefox" title="Firefox — 共有インジケータ"] {
floating enable
sticky enable
move up 1065 px
move right 330 px
}
for_window [app_id="thunar" title="ファイル操作進行中"] {
floating enable
}
(中略)
for_window [app_id="guake"] {
floating enable
move up 486 px
}
for_window [app_id="showmethekey-gtk" title="Floating Window - Show Me The Key"] {
floating enable
sticky enable
move up 1065 px
move left 450 px
}
(後略)
指定 | 機能 |
---|---|
floating enable | タイル型に配置しない |
sticky enable | ワークスペースを越えて表示する |
move <direction> <x> px | floatingしたウィンドウの表示を<x> px, <direction> 方向にずらす |
app_id
, class
はcriteriaと呼ばれ、それぞれWaylandアプリ、XWaylandアプリをsway内で判別するために使えます。詳細はman 5 sway
を参照。各ウィンドウのclass
とapp_id
はswaymsg -t get_tree
の出力から確認できます。
画面共有
方法1
swayで一番苦労するのが、ZoomやDiscordにおける画面共有です。同じWaylandでもGNOME向けにはZoomアプリでの画面共有がサポートされているようですが、これはswayでは使えません。
第一の方法は、ブラウザ上でPipeWireによるWebRTCコンテンツ共有を使うことです。
pacman -S pipewire xdg-desktop-portal xdg-desktop-portal-wlr
swayの設定ファイルで適切に環境変数をセットし、xdg-desktop-portal
, xdg-desktop-portal-wlr
のsystemdサービスを有効化します。
exec dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
systemctl --user status xdg-desktop-portal
systemctl --user status xdg-desktop-portal-wlr
この状態でブラウザ版Zoom / ブラウザ版Discordで共有を開始、画面をクリックすると……
OK。
上のMozillaのサイトでもテストできます。
共有時に出てくるインジケータ(画像上部、オレンジ色のやつ)については、ウィンドウ設定でfloating modeに設定して画面端へ追いやってやるとよいでしょう。
方法2
(2021/9/4 追記)
Zoomアプリでも画面共有する方法を考案している方がいらっしゃいました。
上の例ではv4l2loopbackを使用してダミーのカメラデバイスを/dev/video42
などに作り、そこにwf-recorderで取得した画面映像を流し込んでいるようです。このオンオフを切り替えるスクリプトを書いて、適当なキーバインドを割り当てるとよさそうです。
paru -S v4l2loopback-dkms
カメラと画面共有を同時に使う場面はそう多くないことを踏まえると、これでも十分使えるように思います。ただ4K画面をキャストすると、8C16Tのi7-11700Kでも常時10~15%ほどCPUを消費していたため、お手元のリソースと相談したほうがいいかもしれません。
方法3
(2022/07/10追記)
ちなみに、OBSを使うのが嫌でなければ、OBSの仮想カメラを使うのが手っ取り早いです。PipeWire経由の画面キャプチャを流せるので、wf-recorderよりもいくらか軽い気がします。
+α Zoomについて
(2021/9/4 追記)
AUR版のZoomアプリはどうにもswayと相性が悪く、2021/9/3時点の自分の環境ではあらゆるウィンドウが右下にずれる現象を確認しています(発生しない環境もあるようです)。
Snap版のZoomも同様の挙動を見せたため、Flatpak版を導入してみるとうまく動きました。ただし、Flatpakアプリのフォント設定にはちょっと癖があるようです。以下参照。
(2022/07/10 修正)
コメントを頂き、QT_QPA_PLATFORM
の値をxcb
に戻すと発生しないことが確認できました。また、QT_QPA_PLATFORM=wayland
の場合でも、QT_SCALE_FACTOR=1
とすることで防げるようです。
Qt、いつもお前のせいだよ
+β Flatpak版Zoomについて
(2021/10/17 追記)
無敵かと思えたFlatpak版ですが、弱点がありました。なんと(自分の環境では)SSOログインができません。仕方がないので、少しバージョンが古いですがzoom-system-qtを使っています。ただこのバージョンにもまた問題があって、リアクション機能は使えません。
なんでこんなツールが覇権を握ってしまったのでしょう……
(2022/07/10 追記)
Flatpak版ZoomでのSSOログインはxdg-desktop-portal-gtk
をインストールすると動作します。zoom-system-qt
はもはや完全にdeprecatedなので使わないほうがよいです。
ツール群
いくらXアプリがXWayland上で動くとはいえ、WaylandではXが提供していた入出力その他の仕組みも置き換えられています。このため、関連するツール群はそれぞれのコンポジタの実装(swayであればwlroots)に対応したものに置き換える必要があります。
ステータスバー
waybar。CSS風のファイルでスタイリングできます。
ランチャー
有名なrofiも動きますが、シンプルでWaylandネイティブなwofiにしました。GTKベースで、こちらもCSSスタイリングが効きます。
dmenuモードもあり、お好きなメニューを流し込むこともできます。
ターミナルエミュレータ
Alacritty+tmux。AlacrittyのWayland対応は完全ではなく、WaylandバックエンドではIMEウィンドウが表示できないため、うまく日本語入力がしたければX11バックエンドを指定(WINIT_UNIX_BACKEND=x11
)する必要があります。
ブラウザ
Firefox
MOZ_ENABLE_WAYLAND=1
を設定してやるとWaylandネイティブで起動します。
Chrome/Chromium
Chromium、およびそれをベースとしたElectron系アプリ全般はXWaylandでは問題なく動きますが、2021年8月現在、Waylandネイティブ(--enable-features=UseOzonePlatform --ozone-platform=wayland
)で動作させた場合にはIMEが使えません。
入力メソッド
fcitx5-mozc/fcitx5-skk。fcitx(4)と異なり、fcitx5はWaylandでも変換ウィンドウを適切な位置に表示してくれます。
(2021/9/12追記)
大まかにfcitx5と書きましたが、実際に使っているのは辞書強化版のfcitx5-mozc-utです。ビルドに若干時間がかかりますが、目立った不具合なく動作しています。
スクリーンショット・キャプチャ
grim(画面取得ツール)・wf-recorder(画面録画ツール)・slurp(画面選択ツール)の組み合わせ。スクリーンショットについては、AURにあるgrimshotを導入して手間を省くこともできます。
これは悲しいWindowsユーザのキーバインド
# [slurp, copy & save]
bindsym $mod+shift+s exec grimshot --notify copy area | wl-paste -t image/png > ~/Pictures/Screenshots/$(date "+%Y%m%d-%H%M%S")'_grim_area.png'
クリップボード
必須のwl-clipboardに、履歴マネージャーclipmanを合わせると便利です。
少し応用して、ランチャーで履歴選択をすることもできます。
bindsym $mod+v exec clipman pick -t wofi
平文パスワード
clipmanを愚直に使うと、コピーした内容がたとえパスワードであれ、履歴ファイル(~/.local/share/clipman.json
)に平文で残されることになります。これを防ぐため、簡単なスクリプトで特定のアプリケーション(keypassxc, bitwarden)上での履歴保持を禁じるとよさそうです。
スクリーンロック
ディスプレイマネージャに頼らなくとも、アイドルデーモンswayidleとロックツールswaylockの組み合わせが使えます。フォークのswaylock-effectsを使うと多少エフェクトで遊べるようです。
通知デーモン
makoがWaylandネイティブで動きます。X向けのdunstも動くようです。
ところで、READMEにある意味深な画像は……
音量バー・輝度バー
wob。無駄に動かして遊びたくなります。
画面調整
gammastep。Xのredshiftとほぼ同じ設定で動きます。
キー入力の取得
xevの代替としてはwevがあります。また、入力されたキーを画面上に表示するshowmethekeyはWaylandで動作します。
リモートデスクトップ
(2021/10/15追記)
クライアントに関してはなんでも使えますが、サーバーとなると数が少なく、執筆時点ではwayvncが唯一の選択肢のようです。したがってVNCプロトコルのみが使えます。
総評
満足です。いい感じにデスクトップが作れて、結構気に入っています。庭いじりに凝る老人の気持ちがようやくわかりました[3]。
おまけ
↑ i3wm+polybar。どっちが好みかな?
参考
誤り等ありましたらご一報ください。
Discussion