DPI Detection
前回は手動でフォントサイズの切り替えを行いましたが、今回はこれをdpi
の変更を検知して自動で切り替わるようにします。
今後の仕様追加・変更によって、より自然に実現できるかもしれませんね〜、などと書いていたら、
window-focus-changedが実装されました🤩
ここでは、二つのプランとして紹介します。おすすめは Plan B です。
実装 - Plan A
さて、これまでにも何度か出てきていたwezterm.on
ですが、以下のような説明がありました。
wezterm.on can register multiple callbacks for the same event; internally an ordered list of callbacks is maintained for each event. When the event is emitted, each of the registered callbacks is called in the order that they were registered.
wezterm.on は、同じイベントに対して複数のコールバックを登録することができます; 内部的には、各イベントに対してコールバックの順序付きリストが維持されます。 イベントが発信されると、登録された各コールバックは、登録された順に呼び出されます。
これを踏まえた上で、update-status
をもう一個作ります。1
There is no defined return value for the event, but its purpose is to allow you the chance to carry out some activity and then ultimately call window:set_right_status or window:set_left_status.
このイベントの戻り値は定義されていませんが、その目的は、何らかの活動を行い、最終的に window:set_right_status または window:set_left_status を呼び出す機会を提供することです。
説明にもある通り、「最終的にwindow:set_right_status
またはwindow:set_left_status
を呼び出す目的」のものであるため、
なんかコレじゃないとは思っていますが、他に方法が見つけられませんでした😢
それではevent.lua
に追記していきます。
local DPI_CHANGE_NUM = 140
local DPI_CHANGE_FONT_SIZE = 10.0
local prev_dpi = 0
wezterm.on('trigger-dpi', function(window, dpi)
local overrides = window:get_config_overrides() or {}
overrides.font_size = dpi >= DPI_CHANGE_NUM and DPI_CHANGE_FONT_SIZE or nil
window:set_config_overrides(overrides)
end)
wezterm.on('update-status', function(window, pane)
local dpi = window:get_dimensions().dpi
if dpi == prev_dpi then
return
end
wezterm.emit('trigger-dpi', window, dpi)
prev_dpi = dpi
end)
dpi
とfont_size
周辺の値はわたしの環境にあわせてぼや〜っと決め打ちにしてるので適宜調整してください。
動作としては、dpi
に変更があったらカスタムイベントのtrigger-dpi
を呼んでフォントサイズを切り替えます。
trigger-dpi
自体は手動でフォントサイズを切り替える処理とほぼ同じですね☺️
理由はちょっとよくわからなかったのですが、
カスタムイベントに渡したwindow
に対してのget_config_overrides().dpi
が上手くいかなかったので、
wezterm.emit('trigger-dpi', window, dpi)
としてdpi
も渡しています。
実装 - Plan B
さて、Plan A よりも自然に目的を達成できそうな、これ。
The window-focus-changed event is emitted when the focus state for a window is changed.
This event is fire-and-forget from the perspective of wezterm; it fires the event to advise of the config change, but has no other expectations.
window-focus-changed イベントは、ウィンドウのフォーカス状態が変更されたときに発行されます。
このイベントは wezterm の観点からは fire-and-forget です; それは設定変更を通知するためにイベントを発生させますが、それ以外のことは期待できません。
それでは満を持して😌
wezterm.on('window-focus-changed', function(window, pane)
local dpi = window:get_dimensions().dpi
if dpi == prev_dpi then
return
end
local overrides = window:get_config_overrides() or {}
overrides.font_size = dpi >= DPI_CHANGE_NUM and DPI_CHANGE_FONT_SIZE or nil
window:set_config_overrides(overrides)
prev_dpi = dpi
end)
コードについては やっぱりtrigger-dpi
とほぼ同じなので割愛。
Plan A との比較ではupdate-status
を使わなくて良くなったのと、カスタムイベントの呼び出しも無くなりました。
ウィンドウをドラッグしたりウィンドウマネージャー等を使ってディスプレイを移した際に切り替わらないという欠点こそあるものの、 とても綺麗な実装になりました😄
Wrap Up
ほとんど問題にならないと思われますが、 頻繁にディスプレイを切り替えるような使い方をする場合は Plan A の方が有用かもしれないので、ひとまず Tips として残しておきます。