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年経っているという現実が引っかかるからである。要するに非常にニッチにしか刺さらなくて、あんまり広い需要はないし売りにもならないのかもしれない。まあ個人的にはあれば嬉しい。

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

* * *

というわけで、作った

Installing Vimium

そういえばずっと以前にブラウザをvimっぽくする拡張の評価をいろいろして、最終的にcVimを選択したことがあった。それでずっとcVimを使っていたのだけど、メンテされなくなって随分経ち、いろいろと不具合が目立ってきたので別の何かに乗り換えることにした。

乗り換え先はタイトルの通りVimiumだ。VimiumはcVimに比べると

  • 内包している機能を直接呼び出すコマンドラインモードがない
  • 編集できる要素に対する拡張の余地がない

という明確なconsがあるが、それ以外はまあ何とかなる。軽いしよくできている。今までありがとうcVim…!

Playing with WezTerm

サムネイルを表示するlsというものを作ったのだけど、サムネイル、つまりsixel形式の画像データをどの端末エミュレータでも表示できるわけではないので、現時点では対応できる端末が限られている。

例えばUbuntuに最初から入ってる端末はlibvteというgnomeのコンポーネントを利用してその機能を提供しているのだけど、現時点ではsixelを表示できない(ただし、libvteのソースにはすでに対応コードが入っていて鋭意テスト中のようなので使えるようになるのは時間の問題だろう)。

そんなわけで、sixelが使える別の端末を探したところ、WezTermがよくできているようなので常用を試している。ちなみに、インストールする手段が複数提供されていてflatpak経由がかんたんなのだが、flatpakアプリケーションであるが故の不具合がちらほらあってハマる(マウスポインタがちょくちょく消えるとかfcitx5がよく壊れるとかluaで利用できるAPIが一部正しく動作しないとか)のでaptで入れるかappimageを利用するのがいいだろう。豆知識。

あと数年したら端末で画像を表示することが当たり前になって黒い背景に文字だけの時代は過去のものになるよ。マジで。

The death sentence from Google

以前書いたChromeの拡張の中にTabQueueというものがある。

これは主に3つの機能を備えていて:

  • タブをアクティブにした順番を覚えてくれる。あるタブを閉じた場合、その前にアクティブだったタブを再度アクティブにする。これはPresto Operaの同機能の移植である
  • タブを開いたとき、自動的にそれをフォアグランドにする
  • グローバルなホットキーをひとつ定義でき、それを押すとアクティブタブオーダーをポップできる。デフォルトではCtrl+,である。例えば右端のタブでyoutubeを開いて何かの動画を流しているがボリュームの調整だとか、何かちょっとした操作をしたいとする。そんな場合はg$で右端のタブに飛び(これはcVImの機能だが)、何か動画を操作し、Ctrl+,を押すと元のタブに戻れる。

というわけでかなりニッチな個人的ニーズを満たすものではあるがそれだけに欠かせないものであり毎日あたり前に使っている。

で。

先日Googleからメールが来て曰く、「TabQueueはウェブストアのポリシーに違反しています!説明に表記されている機能を提供していません!14日以内にアクションがない場合はウェブストアから削除される可能性があります!」…というのである。

何言ってんだおめえぶっころがすぞ…という感じである。何かよく分からないので無視している。ちなみにすでに14日以上経過している。

In The Court Of The Crimson King #2

またもや音声の再生についてである。しつこい。ここまで様々な小細工を施してみたのだが、結局ノイズの軽減には成功しているものの排除に至ってない。つまり根本的なノイズの原因が分かってない。youtubeなどで動画を見ているとノイズが起こらないときは起こらないが起こるときは起こる。なんとアナログな。

で、結論から述べるとpulseaudioのサンプルレートとハードウェアの再生レートのミスマッチが根本的な原因のようだ。前者が44100Hzで後者が48000Hzだったのでリサンプリング時にノイズが入る、らしい。いやどうしてノイズを入れるんだ綺麗にリサンプリングしてくれ。

まあそれはさておき /etc/pulse/daemon.conf を編集し

default-sample-rate = 48000
alternate-sample-rate = 48000

などと追記する。pulseaudioの現在の状態は pacmd info で確認できる。これで劇的にノイズがなくなる。てかね…こんなもん…自動でやってよ…pulseaudio…何なんだ…お前は…。

ところでそうなると、これまでにやった小細工は要らないのか? という点が気になる。

そこでサンプルレートの変更は固定し、他の小細工はいろいろ有効にしたり外したりして聞き比べてみたのだが、結局いずれも有効にするのが一番良いようだ。無駄にならなくて良かった。

それにしてもxubuntuを使ってた頃はここまでノイズが気になることはなかったのだけど。何が起こったんだろうか。

In The Court Of The Crimson King

音声の再生について、プチノイズが出まくる件は解決したのだが、実はそれ以外の問題もある。これは言葉で表現するのが難しいのだが…再生の途中で瞬間的なスキップがけっこうちょくちょく発生する。時間をほんの一瞬だけ吹っ飛ばし…その時間内のこの世のものは全て消し飛ぶ。最終的に何か音が飛んだな?という結果だけが残る。

これはノイズというよりは要するにPCMデバイスにデータを叩き込むスケジューリングの問題に思える。しかしGHzでプロセッサがぶん回る時代にそんなことあるのか?

というわけでまたしてもarchlinuxのwikiを参照すると、なにやらPulseAudioの動作に伝統的な割り込み方式と新しいタイムベースのスケジューリングというものがあるらしく、後者で問題が起こるハードウェアもあるのだそうだ(前者で起こるハードウェアもある)。とりあえず/etc/pulse/default.pa

load-module module-udev-detect tsched=0

などと追加して割り込み(何の割り込み? PCMデータを突っ込んだ後のDMAの転送終了割り込みとか?)駆動を指定させたところ、だいぶマシになった。完全になくなったわけではないが…。

いやしかし、それにしても、intelチップセット内蔵のオーディオデバイスなんて最強にポピュラーなハードウェアなのになんでこんなちまちま設定を与えてやらないと上手く動かないのか。こういっちゃなんだけど、PulseAudioってちょっとポンコツなんじゃないの?

聞くところによるとubuntuではそろそろPulseAudioはobsoleteで、新しくPipeWireが音声と映像の再生を管理するようになるらしいので、そこでタナボタ式に解決したりしたら嬉しい。

Revive Window Placements

Chromeを起動し、ウィンドウを適当に配置し、一旦終了する。そして再度起動すると、各ウィンドウのタブ、位置、状態(通常か最大化かなど)が再現される、はずだ。

ところがこの新しいubuntuの環境ではこの動作が正しく行われないのである。

そして単に再現されないだけではなく、さらに謎のルールが付加されているように見える。右側のようなウィンドウのようなサイズだと、そのまま再現されるのだが、その奥のほぼ全画面のウィンドウは何やら「このウィンドウ、ほぼ全画面だから全画面で表示してあげるね!」的な配慮が働くのか、最大化状態に上書きされてしまう。

なんだこれは。

アプリケーションの起動時にウィンドウの状態を再現する処理というのは、一義的にはそのアプリケーション自身が行うはずだが、それはウィンドウマネージャーやらデスクトップ環境やらが何もしないということでもない。実際gnomeにも新しく開くウィンドウを中央に表示する云々のゆるやかに位置を指定するオプションがある。そういうわけで、このChromeの奇妙な動作が誰の仕業なのかはよく分からない。

しかしそれならば、Chromeの起動後に好きにすればいいわけで、Chromeの拡張を書き、独自にウィンドウの配置を覚えておき、起動後にそれを再現するようにしてみた。ウィンドウが最大化状態で表示された後でシュッと縮むような様子を目で確認できるような動作になるけど、まあしょうがない。

この拡張は割と使いでがあるような気もするが、公開の必要はあるだろうか。このChromeの変な動作が他の環境でもよくあることなのか、おま環なのかどうかもう少し調べてみたい。

  *
勝手に最大化はorg.gnome.mutter auto-maximizeで制御されるようだ。これをfalseにすると終了時の配置がその通り再現されるようになった。なんだよこのオプション!なんだよこのオプション!

Pop noise

前の投稿でも書いたが音声を再生すると妙にプチノイズが入る。これをなんとかしたい。

まず環境から確認しておくとIntelチップセット内蔵のオーディオデバイスがあり、snd_hda_intelカーネルモジュールが読み込まれている。またUSB DACを刺しているので、snd_usb_audioモジュールも読み込まれている。ただしUSB側はあくまで出力用のデバイスなのでオーディオデータの生成はあくまでチップセットが行う。

ちなみに内蔵スピーカーやらHDMI出力やらを担当するために?ALC269VBも載っていて認識されているがこれはまあ気にしなくていいだろう。

さてこの問題自体は割とFAQらしいのでみんな大好きarchlinuxのwikiにトラブルシューティングがまとまっている。要するにデバイスに省電力状態というものがあり、その状態が変わるときにプチノイズが発生するっぽいので状態が遷移するのを禁止しようというわけだ。

とりあえずmodinfoしてみると:

filename:       /lib/modules/5.15.0-47-generic/kernel/sound/pci/hda/snd-hda-intel.ko
description:    Intel HDA driver
license:        GPL
srcversion:     EB88CE4FDDC8DBA5650936E
(snip)
depends:        snd-hda-core,snd-hda-codec,snd-pcm,snd,snd-intel-dspcfg
retpoline:      Y
intree:         Y
name:           snd_hda_intel
vermagic:       5.15.0-47-generic SMP mod_unload modversions 
sig_id:         PKCS#7
signer:         Build time autogenerated kernel key
(snip)
parm:           index:Index value for Intel HD audio interface. (array of int)
parm:           id:ID string for Intel HD audio interface. (array of charp)
parm:           enable:Enable Intel HD audio interface. (array of bool)
parm:           model:Use the given board model. (array of charp)
parm:           position_fix:DMA pointer read method.(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+, 6 = FIFO). (array of int)
parm:           bdl_pos_adj:BDL position adjustment offset. (array of int)
parm:           probe_mask:Bitmask to probe codecs (default = -1). (array of int)
parm:           probe_only:Only probing and no codec initialization. (array of int)
parm:           jackpoll_ms:Ms between polling for jack events (default = 0, using unsol events only) (array of int)
parm:           single_cmd:Use single command to communicate with codecs (for debugging only). (bint)
parm:           enable_msi:Enable Message Signaled Interrupt (MSI) (bint)
parm:           patch:Patch file for Intel HD audio interface. (array of charp)
parm:           beep_mode:Select HDA Beep registration mode (0=off, 1=on) (default=1). (array of bool)
parm:           dmic_detect:Allow DSP driver selection (bypass this driver) (0=off, 1=on) (default=1); deprecated, use snd-intel-dspcfg.dsp_driver option instead (bool)
parm:           power_save:Automatic power-saving timeout (in second, 0 = disable). (xint)
parm:           pm_blacklist:Enable power-management denylist (bool)
parm:           power_save_controller:Reset controller in power save mode. (bool)
parm:           align_buffer_size:Force buffer and period sizes to be multiple of 128 bytes. (bint)
parm:           snoop:Enable/disable snooping (bint)

なるほどとても親切だ。ところで件のwikiだとpower_saveだけを0にするか、さらにpower_save_controllerもオフにするか2つの選択肢を挙げているわけだが、前者に意味はあるのだろうか。power_saveを0にした場合(=disable)の動作の詳細が分からないが、デバイスが暇になった場合即省電力状態に入らせるということならプチノイズ回避にはならないのでは? いろいろ試してみよう。

まずpower_saveを0にしただけで様子を見たところ、10秒に一度プチ!が出る感じなのが20秒に一度くらいになったようだ。なるほど効果は少しはあるのか。次にpower_save_controllerに’N’を書き込んでみたところ、こちらは覿面にプチノイズがなくなった。なるほど。

というわけで、これを永続化した設定にするため/etc/modprobe.d/の下に適当なファイルを作って

options snd_hda_intel power_save=0 power_save_controller=N

という感じの内容で保存。wikiにも書いてあるがラップトップの場合電源状態によってこの辺の設定が再設定されうるので、そういう場合は/etc/pm/power.d/下にも何かいろいろと仕込む必要があるかもしれない。

ところで省電力機能というのは当然消費電力を通常より低くするのだろう。その代わり音質が犠牲になるトレードオフがあるのだとしたら、バッテリー駆動のときだけオーディオデバイスの省電力機能をオンにする…とかにすればいいと思うのだけど、なぜ常に省電力オンなのかはよく分からない。

thumbnails on Nautilus

  • webpのサムネイル
    $ sudo apt install webp
    $ vim ~/.local/share/thumbnailers/webp.thumbnailer

    [Thumbnailer Entry]
    Exec=/usr/bin/dwebp %i -scale %s %s -o %o
    MimeType=image/x-webp;image/webp;
  • 動画のサムネイル
    $ sudo apt install ffmpegthumbnailer
  • サムネイルキャッシュの更新
    $ rm ~/.cache/thumbnails/fail/gnome-thumbnail-factory/*
    $ nautilus -q
  • 音声を再生する際プチノイズが入ることがある: サウンドデバイスが省電力モードになっているのが原因、かもしれない
    $ echo '0' | sudo tee /sys/module/snd_hda_intel/parameters/power_save