Playing with mlterm #3

背景をスケスケにする

mltermで何ができるかは、だいたいmanに書いてあるのでまずはそれを読むべし。それによると、まず –depth というコマンドラインスイッチ及び depth という ~/.mlterm/main に書ける設定項目があり、それによってスクリーンの色深度を指定する。

   --depth=value
          Specify visual depth. (8,16,24,32) If depth is 32, you can enable semi-transparency by specifying opacity as the value of --alpha option or "rgba:RR/GG/BB/AA" as the value of --bg option.

そして、これを32にするとalphaオプションや、背景色に対するアルファ値込みの色指定が有効になるそうだ。

また、これはとは別に–transbg / use_transbgというフラグがあり、これにより疑似透過が有効になるとのこと。疑似って?

ということで mainファイルにいろいろ書き込む方法でやってみると、depthを32にし、bg_colorをrgba:RR/GG/BB/AA 形式で指定すると確かにスケスケになるようだ。一方alpha の効果はなかった。また、use_transbgをいずれの値にしても特に変化はなかった。少しドキュメントとの乖離があるが、これがおま環なのか、あるいはwayland環境だとこういう動作なのかは分からない。

ウィンドウのサイズ、表示位置を指定する

–geometry / geometry というオプションがあり、WIDTHxHEIGHT+LEFT+TOPの形式で指定できる。また、inner_borderというCSSで言うところのpaddingみたいなオプションでウィンドウの端から実際に文字が描写される領域までの間隔をピクセル数を指定できる。なお単純な10進数値の他に\d+,\d+という形式も受け付けて、その場合はそれぞれの数値がいわゆるpaddingLeftとpaddingTopに相当する。

Playing with mlterm #2

ということでmltermで遊んでみる。

アイコンを変更する

mltermのアイコンはmlterm-commonパッケージに収められており、/usr/share/pixmaps に配置される。だいこん感。

惜しいのは解像度が最大でも48×48で、現在の環境だとぼけぼけに拡大して表示されてしまう。とりあえずmlterm_48x48.xpmを補完なしで2倍に拡大してそれを使うようにした。もともとピクセルアート的なアイコンなのでそこまで違和感はない。

mltermのアイコンは/usr/share/applications/mlterm.desktopファイル内で指定されている。ちなみにアイコンをフルパスで指定しなかった場合にどこが参照されるかは定義されている

Playing with mlterm

端末エミュレータの話。基本的にvimが起動しっぱなしのコード書き専用端末はBlack Box(のnightly版)。他方、割と雑用的に使う端末は以前の記事の通りWezTermを試している。

WezTermのprosのひとつは、とにかく設定の自由度が高い上にluaでなんでもできてしまう点だろう。Gnome TerminalだとAlt+1〜Alt+9で開いたタブを直接選択する機能があるが(Black Boxもそうである)、WezTermにはない。ないが、単にそういうキーバインディングを設定すれば対応できてしまう。よい。

一方でよくない点もいくつかある。WezTermの売りのひとつはGPUを活用した高速なレンダリングである。WezTermの他にもうちGPU使ってるんで超速いっすよ!という端末はいくつかあるのでホットなトピックなのだろう。しかし、個人的には端末の高速レンダリングがそんなに嬉しいか? という感じがしてあんまり刺さらないんですよね。それに、端末上でtmuxを介するとだいたいここで大きく律速されてしまうので実質的にはあまり効果が感じられないという観点もある。

それと、おそらくはGPUのハンドリングにまつわる話なのだと思うのだけど起動中の占有メモリがけっこう半端なくなる時があるのも気になる。

その他、IMのハンドリングに若干のバグが残っておりたまにIMをアクティブにできなくなる、その上デスクトップ全体で文字入力ができなくなってしまうことがある(なぜかGnomeデスクトップ自身とIMの状態を共有してるっぽく、Gnomeのアプリ検索とかで一旦IMをアクティブにしてからWebTermに戻ると復帰したりする)、クリップボードから貼り付けるとおかしな文字選択状態になる、画面の最終桁からワイドな文字の入力を始めると次行からの表示がしっちゃかめっちゃかになるなど日本語の表示と入力に関して改善の余地がある。

そんなこんなで新しいバージョンがリリースされるのを待ち侘びているのだけど、最終バージョンが2024年の2月ということで相当待たないといけない予感がしている。それならば、その間に別の端末を試してみるか。

というわけで本題のmltermである。実はmlterm自体はLinux環境をセットアップするたびたいてい入れてたのだけど、常用の端末にはなってなかった。viやvimは入力モードを抜けるとカーソルが1文字左に戻るのだがこの仕様を便利だと思ったことはない。そこで

inoremap <silent> <Esc> <Esc>`^

というように定義して入力モードを抜けたら入力モードに入る前のマークへ強制的にカーソルを置くようにしている。しかしこの定義がなぜかmltermでだけカーソルが戻らない上に勝手にundoが実行されるという奇妙な動作になってしまいmlterm上でvimが使い物にならないのである。

実は同じような誤動作はWezTermでも起こるのだが、こちらの場合はリポジトリに置いてあるWezTerm用のterminfoを与えると直る。じゃあmltermもそうじゃないのということになるが、どうもmlterm用のterminfoは何が正しいのかよく分からず、放置していた。こういう話もある。

ところが、最近上記の定義をなんとなくmltermで動かしてみたところ、あれ?なんか普通に動くではないか。そこで、ちゃんと使ってみようかということになったのだ。

keyd is awesome

太古の昔はコンピュータに繋がってるキーボードはひとつだけで、しかも静的に接続されていたが今はそうではなく複数の、しかも異なるレイアウトのキーボードを動的に繋げたり外したりすることができる…のだが、ソフトウェア側でそれに対応しているのかはよく分からない。OSのキーボードの設定とかで接続されているキーボードごとに割り当てるレイアウトを決められるとかそういうものは見たことがない。

さて調べてみたところkeydというものがあり、ちょっと試している。上述の問題はデバイスIDを明示することで少し解決できる。それ以外にも非常に自由度の高いリマップを行える。

ちなみにちょっとしたリマップの機能はgnome自身も持っている(正確には、リアルタイムでsetxkbmapに対する定義を行うような機構だと思う)のでkeydをメインで使う場合はgnomeのそれは触らない方がよいかもしれない。すなわち、org.gnome.desktop.input-sourcesxkb-optionsを単に空([])にする。

$ gsettings set org.gnome.desktop.input-sources xkb-options “[]”

もしこれに何か定義されている場合、例えば['ctrl:swapcaps', 'ctrl:ctrl_ralt', 'compose:menu']と言った値が入っている。そのまんま、setxkbmapのオプションに与えるアレの配列である。なおアレのリストはsetxkbmap -print -v 10で出力されるrulesファイルの中に書いてある。たとえば/usr/share/X11/xkb/rules/evdevとかだ。

インストール

いろいろ調べるとkeydのインストールはgithubからcloneしてmakeみたいなことを指示している文書が多いが、masterブランチは開発中のものなのでcloneするのはstableとタグが付けられたコミットの方がいい(とreadmeに書いてある)。その他いくつかのディストロについては一応パッケージが用意されている。以下ubuntuの場合。ubuntuでは現在ppaを経由することになっているが、とても便利なツールなのでそのうち標準のリポジトリに入る気がする。

$ sudo apt-add-repository ppa:keyd-team/ppa $ sudo apt update $ sudo apt install keyd

これでインストールされる実行形式は、そのままだとあまりにジェネリックすぎるためか、keyd.rvaiyaという名前になっていた。man の項目も同様にman 1 keyd.rvaiya

インストール後はsystemdのシステムサービスが登録されているのでそれを有効にすると起動時から有効になる。

$ sudo systemctl enable keyd --now

トラブルシューティング

さて設定をどこにどう書くかとか何ができるかは上記の通りmanを見れば全部記述してあるのでここには書かないのだがハマりポイントをいくつか覚え書きしておきたい。

  • 冒頭に書いたとおりgnomeでxkb-optionsを設定しているとかち合う恐れがあるので、それは空にしておいた方がよい。もしかしたら/etc/default/keyboard内に書くXKBOPTIONSも空でよいかもしれない。
  • 今使ってるマシンにはThinkPad USB Keyboard with TrackPointという赤いぽっち付きのキーボードを繋げているのだがこのキーボード、キーボード部分とポインティングデバイス部分のデバイスIDが同じであるためにちょっとした混乱が起きるので一工夫が必要(後述)。

デバイスIDを共有するデバイスの取り扱い

keydは試験的にポインティングデバイスも取り扱うようになっているが(これはボタンが10個とか100個とか付いてるマウスもkeydの作法でリマップできたら便利かもという発想であろう)、そうするとポインティングデバイスとしての固有の動作が無効になってしまい、件のキーボードの場合例えばポインタのアクセラレーションや中ボタン+トラックポイントによるスクロール操作が全部パーになってしまうのであった。

keydはデバイスIDを共有する複数のデバイスに対してはちょっとしたチェックサムを生成して区別できるようになっているので(keyd.rvaiya monitorとすることで確認できる)設定ファイルで該当するデバイスを除外する:

$ sudo keyd.rvaiya monitor device added: 17ef:6009:eee4ba01 Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint (/dev/input/event2) device added: 17ef:6009:ab84dcc1 Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint (/dev/input/event3) Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint 17ef:6009:eee4ba01 m up Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint 17ef:6009:eee4ba01 capslock up Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint 17ef:6009:eee4ba01 capslock down Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint 17ef:6009:eee4ba01 c down

この例だとキー押下イベントを発生させているのはeee4ba01の方でab84dcc1がポインティングデバイスだと判断できるので、/etc/keyd/default.confの冒頭を

[ids] * -17ef:6009:ab84dcc1

などとして該当するデバイスIDを除外すればよい。

というわけでkeydを通してcapslockをctrlに、右altをctrlにした。長々と書いた割にリマップ内容は極ふつーというオチ。

Emin #4

Chromeが135.0.7049.95に更新されたのだが、これに対して–gtk-version=3を与えると何かが盛大に壊れ、ページのkeydownまわりとか、あるいはコンテンツスクリプトからバックグラウンドへのメッセージングとか、とりとめなく色んなところがおかしくなるようだ。

Emin #3

ところでEmacsのキーバインディングを実装すると言っても、当然ながらほんの一部であってそんな大したものではない。ただし実装しておーこれは意外に便利かも? と思ったものもある。

EmacsはM-/ でdynamic abbrevという機能が働くが、これを似たようなものを実装した。例えば入力中にサジェストが表示されるサイトなんかでM-/を押すとそのサジェスト候補が自動入力される。候補が複数ある場合はそのままM-/を押していけば順繰りに入力される。

それからこれはEmacsとは全然関係ないが、カーソル位置の四則演算式をその結果で置き換える機能をM-cに割り当てた。また、C-mを押すと、入力している要素が属するフォームをサブミットするようにした。

Emin #2

そういうわけで、月末までEmacsバインディングのないChromeで過ごさざるを得なくなったわけなのだが、当然の成り行きながらCtrl+HやCtrl+Wをうっかり押してしまいぎょえー!となるアクシデントが頻発して気が狂いそうになっている。どうにかならないの。

Emacsバインディングと言えば、過去にjavascriptレベルで実装したことがある。赤福プラスは *.2chan.net 上でのみ、Search Cobb は検索文字列入力欄のみEmacsバインディングが有効になっている。ちなみに両者の違いは、前者がフクザツな作り(各ハンドラが非同期でもよいとか、Firefoxでも動くとか)で後者がシンプルということだ。

この実装済みながら、適用範囲が限られているものをwebページ全体に押し広げればなんとかならないだろうか。

ということで、SearchCobbのそれを拡張することにした。

言うまでもないがこのソリューションだとアドレスバー、拡張が管理するドキュメント、Webコンポーネントの中身などには効果が及ばないため完全ではないのだけど、しかしないよりははるかにマシである。

ところでこのgtk4でgtk-key-themeが効かなくなっちゃう問題ってXとかで検索しても特にホットな話題でもなんでもないみたいなんだけど、そういうものなんだなあ…。

Emin

Chromeが135.0.7049.84に更新された…のだが、gtk-key-themeで定義しているキーバインディングが効かなくなった。

どうやらそのバージョンあたりからgtk4を優先的に使用するようになったらしいのだが、そもそもgtk4にキーバインディングの仕組み自体がないのだそうだ。

gtk3を優先的に使用させる方法はないのか? と探してみたが、–gtk-version=4 というコマンドラインスイッチはあるのにこれを3にしてもそうならない。strace -e openat /opt/google/chrome/chrome 2>&1 | grep gtk などとやっても依然としてgtk-4.0なんちゃらが読み込まれる。

このgtkのバージョン指定の問題は、136で解決されるそうなのでとりあえず今月末あたりにそれがリリースされれば、Chromeの起動時に –gtk-version=3 を与えてやることで再びキーバインディングが有効になるだろう。たぶん。

しかしこれもgtk3がサポートされる期間の話なので油断はできない。そもそもどうしてgtk4でキーバインディングの仕組みが削除されたのか? と言えば、この仕組みがcssの定義に乗っかってるからであって、キーバインディングの定義ってcssの範疇じゃなくない? 消してよくない? という話になり、そして特に代替もないままとりあえずドロップされたという経緯のようだ。ドロップされたのが6年前で、今に至るまで代替機能は開発されていない。

Transparency has gone.

最近Ubuntu 24.04.1 LTSに上げたわけなのだけど、

  • Wayland 環境で
  • 背景を半透明にする機能を備えたアプリケーションを
  • フルスクリーン表示にすると

その半透明機能が効かなくなるという現象が発生して困っている。たとえばgnome-terminalとかだ。端末の背景がスケスケの助になるのはカッコいいだけではなくちゃんと実用的なので、そうならないと日々の作業が直接的に不便になって困る。

調べてみるとこれはmutter(Waylandにおけるコンポジタ─すべてのウィンドウとデスクトップのビットマップを合成するプログラム)の仕様がそう変わったから、のようだ。フルスクリーンの状態ならそのアプリケーションが全てのピクセルについて責任を持とう、みたいなポリシーなんだろうか。
https://gitlab.gnome.org/GNOME/mutter/-/issues/2520

その理屈自体は筋が通っているかもしれないが、しかし実際影響が大きすぎるので、なんか代替の仕様が必要なんじゃない?みたいな話にもなっている…が、あまり動きは活発ではない。
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/116

とりあえずのワークアラウンドとしてはフルスクリーンではなくウィンドウを最大化すればいいわけなのだが、そうするとタイトルバーが無駄にピクセルを消費してとても邪魔なのである。これをどうにかしたい。

ここで、探してみるとウィンドウを最大化したときタイトルバーを隠しますと謳うgnomeエクステンションがあったりするのだけど、入れてもそうならない。gnomeエクステンションの仕様はちょくちょく破壊的な変更を伴うのか動作するバージョンの範囲が狭いものが多いのであまりに当てにならない。
https://github.com/hardpixel/unite-shell

ということで別の何かを探してみると、Black Boxという端末エミュレータがある。
https://gitlab.gnome.org/raggesilver/blackbox
新しい端末を作りました!ってお出しされた場合、肝心の端末のコア部分が既存のライブラリなのか、それを含めて自作なのかで評価の軸が変わってくる。このアプリケーションの場合コアはlibvteなので、主に評価すべきはそのガワの部分である(ただしflatpakパッケージとして公開されていて、最新のlibvteを内包している…という工夫がされている。そのため、sixelも使えてしまう)。

で、ガワの部分だけどタイトルバー(とタブバー)を隠すというオプションがあり、その通りに動作する。また、タイトルバーがありそうな位置にマウスポインタを持ってくるとニュッと出てくる動作にすることもできる。おー。いいじゃん。これにしよう。

…となりそうなのだけど、別の所から問題が出てくる。前述の通りこれはflatpakパッケージで、起動中flatpak-session-helperなるプログラムも漏れなく動いているわけなのだが、何か知らないがこれが常時数%〜十数%のCPUパワーを消費してマシンのファンをファンファンさせるのであった。なにこれぇ。
https://github.com/flatpak/xdg-dbus-proxy/issues/51

しかし原因がBlack Boxなのか、flatpak-session-helperなのかよく分かっていない。Black BoxにはNightly版もあるのでこれを使うようにして様子を見てみよう。

Let’s search inside web pages

たいていのブラウザに組み込みのページ内検索機能があり、Chromeにもある。ただし、ブラウザがもっと小規模なアプリケーションだった頃からある機能のせいか微妙に素朴な動きしかしてくれない。例えば標準で正規表現が使えると嬉しいのだけど、できない。ページの密度が高くなってくると単に色でハイライトされたキーワードを見つけづらかったりするのも不便。検索ダイアログをEscapeでしか閉じられないのもめんどう。

そこで必要な機能を備えた拡張を作るかということになる。もちろん正規表現でページ検索できる拡張はすでにたくさんあるのだが…例えば現代だとそこかしこに絵文字が使われてるわけだが、最新の絵文字は複数のコードポイントから形成されてたりする。つまり検索を行う拡張側でも正確な書記素クラスタの認識ができないとハイライト処理などが盛大に壊れたりする可能性があり…実際いくつか試してみたところ盛大に壊れる。

また、正規表現によるページ内検索を実装する場合、要素を走査して要素ごとに検索を行う場合とそれ以外が考えられる。前者だと パンケーキとどら焼きって<b>ぶっちゃけ同じ</b>だよね のようなテキスト全体を検索することができない。既存の拡張は、全て試したわけではないが、だいたい半々くらいに分けられると思う。シンプルな実装の方が堅牢だし応答もよいだろうから明確に優劣があるわけではないのだが、まあできるのなら要素をまたいだ検索が可能な方がよい。

ついでに言うと migemo 検索ができると若干嬉しい。若干というのは、Chrome で migemo 検索というのは10年くらい前にはそういう拡張があったのだが、知らないうちに公開停止になっていて、しかもそれが特に話題にもなってないっぽくて、特に代替の拡張も登場しないまま10年経っているという現実が引っかかるからである。要するに非常にニッチにしか刺さらなくて、あんまり広い需要はないし売りにもならないのかもしれない。まあ個人的にはあれば嬉しい。

以上の要件を勘案すると、じゃあ新しいの作るかーということになる。

* * *

というわけで、作った