Window Managerをi3にしてみた

もともとCinnamonが好きでManjaroもCinnamonを使っていたんだけど,タイル型のウィンドウマネージャーを使いたくなったので,i3を入れてみた.

最終的な見た目

f:id:h3poteto:20210822172414p:plain

今回使った設定は全部ここに詰め込んだ.

github.com

インストールと起動

i3パッケージを入れると,必要なものを入れてくれる.

$ yay -S i3

あとはログアウトして,ログイン画面でデスクトップ環境をi3選択してログインすれば良い.

この状態だと,i3statusが足らず,ステータスバーにエラーが表示されていた.が,そもそもステータスバーはpolybarにするつもりだったので,これを入れずに先に進む.

ステータスバーをpolybarに変更

github.com

polybarはi3で使えるステータスバーだが,i3statusよりカスタマイズしやすいのでこれを入れる.

$ yay -S polybar

フォントの設定

Linuxにおいてフォントの設定をするというのは,非常にめんどくさいのである.Cinnamonのような一般的なデスクトップ環境であれば,設定用のアプリケーションがバンドルされている.しかし,i3のように普通ではないデスクトップ環境を使う場合,そんなアプリケーションがないので,どこかの定義ファイルを変更しないといけない.

lxappearance

この面倒な設定を統一したインターフェースで提供してくれるのが,lxappearanceだ.これをインストールして,設定画面で適当なテーマとフォントを設定すると,とりあえずマトモなフォントが設定できる.

$ yay -S lxappearance

f:id:h3poteto:20210822134944p:plain

urxvtとemacs

ただし,urxvtとかemacsはlxappearanceの設定を反映してくれない.そのため,ここだけは手動で設定を行う必要がある.

まずurxvtに関しては,~/.Xresources

URxvt.font:                 xft:Ubuntu Mono derivative Powerline-13,\
                            xft:Ricty Diminished Discord

のような記述をすることでフォントを指定できる.

次にemacsだが,

Xft.autohint:   0
Xft.lcdfilter:  lcddefault
Xft.hintstyle:  hintslight
Xft.hinting:    1
Xft.dpi:        96
Xft.antialias:  1
Xft.rgba:       rgb

Emacs.FontBackend: xft
Emacs.font: Ubuntu Mono-12

という指定を行う.xftは非常に重要で,emacsのフォントをxft経由せずにレンダリングすると

f:id:h3poteto:20210822140326p:plain

というなレンダリングになる.これは「.」や「;」を見ると顕著で,明らかにアンチエイリアスか何かに失敗しているようなレンダリングになる.xftを通すことで,

f:id:h3poteto:20210822135033p:plain

のようなレンダリングが可能になる.Emacs 23以降であれば,パッケージ配布されているものでxft対応しているので,自分でコンパイルする必要はない.

通知サーバ

wiki.archlinux.jp

いろいろ乗っているのだが,通知を受けたときに表示するだけではなく,その履歴も表示してほしかった.そのため,通知サーバだけでなく通知センターを持っているものが良い.というわけでLinux Notification Centerを入れた.

github.com

$ yay -S deadd-notification-center-bin

systemdで起動しておけば通知を表示してくれる. こいつはサブコマンドではなくシグナルで通知センターを起動する.そのため,

$ kill -s USR1 $(pidof deadd-notification-center)

とすれば通知センターが起動できる.これをpolybarに仕込んでおく.

[module/deadd]
type = custom/text
content = ""
content-margin = 4
content-underline = ${colors.primary}
click-left = kill -s USR1 $(pidof deadd-notification-center)

f:id:h3poteto:20210822135433p:plain

音量コントロール

polybarに音量が表示されていても,ここでボリューム自体をコントロールすることはできない. 基本的にここではミュートの管理しかできない.

というわけでキーボード・ショートカットでボリュームコントロールを行うように,i3側にショートカットを設定する.

bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +5%
bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -5%
bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle

スクリーンセーバーとロック画面と電源管理

初期状態のi3だと,10分経つと画面が暗転してしまっていた.これは電源管理とスクリーンセーバーの問題だ. これについては,現状の設定値を見ることができる.

$ xset q
...
Pointer Control:
  acceleration:  2/1    threshold:  4
Screen Saver:
  prefer blanking:  yes    allow exposures:  yes
  timeout:  600    cycle:  600
Colors:
  default colormap:  0x20    BlackPixel:  0x0    WhitePixel:  0xffffff
Font Path:
  /usr/share/fonts/misc,/usr/share/fonts/TTF,built-ins
DPMS (Energy Star):
  Standby: 600    Suspend: 600    Off: 600
  DPMS is Enabled
  Monitor is On

この状態だと,スクリーンセーバーが10分で起動する.しかし,何も設定していないスクリーンセーバーは何も表示しない.さらに同時にdpmsによるスタンバイも発生し,画面には何も表示されなくなる.

個人的にはスクリーンセーバーは不要だと思っているので,まずこいつをoffにする.

$ setq s off

次に電源管理.やってほしいことは,1時間で画面電源をオフにした上で,再開時にはログインを求めてほしい.

というわけでまず,

$ xset dmps 3600 3600 3600

しておく. これらは,再起動時にはリセットされてしまうので,~/.profileに書いておく.

次にxss-lockとi3lock-fancyを入れておく.

$ yay -S xss-lock i3lock-fancy

で,i3の設定で

exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock-fancy --nofork

としておく. これで1時間後に画面がオフになり,再開時にはロック画面が表示される.i3lockだと味気ないので,i3lock-fancyに変えてみた.

github.com

見た目のカスタマイズ

i3

タイトルバー

i3デフォルトのウィンドウタイトルバーがちょっと味気ないので,カスタマイズした.

# Window title bar
title_align center
# class                 border  backgr. text    indicator child_border
client.focused          #272c33 #404552 #ffffff #5294e2   #3e646f
client.focused_inactive #313742 #29303a #ffffff #484e50   #313742
client.unfocused        #313742 #29303a #888888 #292d2e   #313742
client.urgent           #2f343a #5294e2 #ffffff #5294e2   #3e646f
client.placeholder      #000000 #0c0c0c #ffffff #000000   #0c0c0c

なんでもいいのだが,俺はArc Darkのテーマが好きなので,それに沿った色使いにしている.

背景と透過

i3はデフォルトでは真っ黒背景である.これが味気ないので,背景を指定した.

exec --no-startup-id "feh --bg-scale $HOME/Pictures/Ubuntu-14-04-Default-Background-Jelly-Fish-004.jpg"

そして,picomで透過設定を入れることにより,フォーカスが当たっていないウィンドウを透過して,背景を表示させることができる.

exec --no-startup-id picom -CGbm 0.75

polybar

polybarに関しては,テーマが結構公開されているので,それを導入するのも一つの手だ.ただし,i3 + polybarでないものは,例えばGNOMEを前提にしている機能が含まれていたりして,そのままでは動かなかったりする. なので,できるたけシンプルなテーマを入れて,自分でカスタマイズするのをオススメする.というか,カスタマイズしやすいのがpolybarの利点なので,自分でカスタマイズしたほうが良い.

[colors]
background = #aa383c4a
background-alt = #404552
foreground = #dfdfdf
foreground-alt = #666
primary = #5294e2
secondary = #4978b3
success = #98c379
warning = #e5c07b
alert = #cc575d

ランチャー

ランチャーはrofiとかが有名だが,もともとulauncherを使っていたので,こいつをそのまま流用している.

[module/launcher]
type=custom/text
content = ""
content-margin = 4
content-underline = ${colors.primary}
click-left = ulauncher

ログアウト/再起動/終了

[module/powermenu]
type = custom/menu

expand-right = false

format-margin = 2
format-spacing = 2
format-underline = ${colors.primary}

label-open = 
label-close = 
label-separator = |

; reboot
menu-0-1 = 
menu-0-1-exec = menu-open-2
; poweroff
menu-0-2 = 
menu-0-2-exec = menu-open-3
; logout
menu-0-0 = 
menu-0-0-exec = menu-open-1

menu-2-0 = 
menu-2-0-exec = reboot

menu-3-0 = 
menu-3-0-exec = poweroff

menu-1-0 = 
menu-1-0-exec = i3-msg exit || openbox --exit

f:id:h3poteto:20210822135557p:plain

screenshot

Cinnamon時代はgnome-screenshotを使っていたんだけど,i3になった時点でGNOMEではなくなったので,これは使えない.

スクリーンショットを撮るプログラムはいろいろあるので,別になにを使っても良いのだが,maimを使うことにした.

$ yay -S maim

で,i3にショートカットを設定しておく.

# Screenshots
bindsym Print exec --no-startup-id maim "/home/$USER/Pictures/Screenshot from $(date \"+%Y-%m-%d-%H-%M-%S\").png"
bindsym Control+Print exec --no-startup-id maim --window $(xdotool getactivewindow) "/home/$USER/Pictures/Screenshot from $(date \"+%Y-%m-%d-%H-%M-%S\").png"
bindsym Shift+Print exec --no-startup-id maim --select "/home/$USER/Pictures/Screenshot from $(date \"+%Y-%m-%d-%H-%M-%S\").png"

そもそもなんでタイル型?

タイル型自体は知っていたんだけど,なかなかふんぎりがつかなくて導入していなかった.というか,導入するには今回書いたように,結構設定を作り込まないといけないというのが理解できていたので,放置していた.

タイル型のメリットは,なんといっても並列作業のやりやすさだろう.コンポジット型で並列作業をやろうと思うと,Alt+Tabによるウィンドウの切り替えが高頻度で発生する. 特に開発時にはターミナルとEmacsとブラウザの行き来が非常に多くなる.ブラウザは別のWorkspaceに押し込んでいるのでいいとしても,それでもターミナルとEmacsの切り替えは頻繁に発生する.また,どこかのウィンドウを見ながら写経するような場合,これもかなり面倒なことになる.自分でウィンドウを横並びに配列して写経するか,重ねた上で透過する等しないといけない.

これは俺の持論なのだが,「パソコンのディスプレイはでかくなればなるほど作業効率が上がる」という話がある.ただし,これには上限があると思っていて,たとえば60インチのディスプレイを買ってきたとして,果たして30インチの2倍作業効率が良くなるかと言えば,たぶんならない.13インチと26インチであればマジで倍くらい楽になるけどね.そう思って今は27インチの1920x1080のディスプレイを使っていた.しかし,これが最近手狭に感じる.一度,27インチで2560x1440のディスプレイで作業する機会があったのだが,これがなかなかよかった.確かに文字は少し小さくなるが,作業領域が圧倒的に増えていた.ただし,一つ問題があって,2560x1440のディスプレイに一つのアプリケーションを全画面表示すると,デッドスペースが多くなりすぎる. 基本的に文字を書く作業をしていると,左上 or 左下を起点に書くことが多い.アラビア語とかではない限り,右から書くことはないのだ.そのため,どうしても右下や右上のスペースが無駄になる.だからといって,手動でウィンドウをならべるのは面倒だった.このときに気づいた.こういうときにタイル型を使えば,作業効率の上限だと思っていた限界を突破できるのでは?

というわけで,先にウィンドウマネージャーの方を導入した(まだ画面は変えていない).いや,でも実際例えば4Kの,QFHDのディスプレイとかを買った場合,4分割したEmacsですら1920x1080の表示領域が与えられるわけで,これはマジでタイル型天国なのでは?と思っている(まだ画面は買っていない).