mikutterコミッタにされった

このたび、栄えあるmikutterコミッタの一員に選ばれましたことは、望外の喜びであります。

思えば、たまに訪れるLinuxデスクトップで遊んでみようという思いつきのたびにmikutterを使い、自分で使うためだけのプラグインをほそぼそと書いては、Linuxデスクトップ自体に飽きてWindowsに戻るということを繰り返してきました。

2017年に入ってすぐの頃、私のtwitterアカウントが一時凍結され、電話認証を要求されるということが2度ほどあり、その直後に私のアカウントで作成していたCK/CSのwrite performが一切禁止されてしまいました。私は当時、Krile StarryEyesを使っていました。karno氏とは面識があったこともあって、何度かpull-reqを送ったりしていましたが、これによりKrileが使えなくなってしまいました。そのため、後継としてWindows上で動くクライアントを模索する中、2016年夏頃に公開されたWindows Subsystem for LinuxFirefoxを動かした記事の存在を思い出した私は、WSL上でmikutterを動かせばいいのではないかと考えました。

WindowsネイティブのRubyでmikutterを動かすことはハードルが高く、特にgtk2やnokogiriのようなgemのビルドが非常に不安定で、しかも32bit版しかサポートされない状況が続いていたため、Windowsでmikutterを使うことは、実験的な意味で成功させるのはともかく、日常的に使用し続けることは半ば以上諦めていたのですが、WSLであれば少なくともビルドの問題はなく、GUIIMEさえなんとかなれば大丈夫だろう、と見通しを立てました。

実際にこれは成功し、現在でもWSL上でmikutterを使用しています。

2017年春のmastodon流行に乗じてインスタンスを立て、秋にはtoshi_aさんがtwitterアカウントを凍結されmikutterのmastodonインスタンスが設立されたことにより、mikutter界隈のmastodon移住の機運が高まり、そこに便乗する形でイキり始めたのが、mikutterコミュニティとの本格的な関わりのスタートであったのかなと思います。この頃に、mikutter redmineへのアカウント登録も行いました。

mikutterとmastodonの関わりにも歴史があり、2017年春の流行の際に、もぐのさんがmikutter丼プラグインを書かれました。

この際に、もぐのさんが言っておられたことが印象的です。

大して若くない私は、この時「ワカモノがんばれ、ちょうがんばれ」と思いつつ、mikutter丼をforkし、独自に手を入れていました。夏頃、mikutterの新機能としてworldというものが追加されるという噂を聞き、内心ワクワクしつつも、実際に試すまでは至りませんでした。

2017年12月に入った頃に、mikutodonの存在を知りました。

このプラグインはなんとストリーミング対応であり、mikutterにおけるmastodon体験をより豊かなものにしました。そら氏は若く、mikutter界隈でもここにpull-reqして育てていこうという雰囲気が強かったのを覚えています。現在でも、「mikutter mastodon」というキーワードでGoogle検索すると、このプラグインがトップに出てきますから、このプラグインデファクトスタンダードだと認識している人も多いのではないでしょうか(冒頭の記事での「いまやmikutterでMastodonを利用するためのプラグインとしてデファクトスタンダードとなっているWorldonプラグイン」はピンと来なかった人も多いと思います)。

2017年12月25日にmikutter 3.6がリリースされました。World、Spell、Dialog DSLと、盛りだくさんの新しい機能がありました。12月28日にはWorld系プラグインを実装する 0日目 下準備 - mikutter blogが公開され、いよいよWorld対応のプラグインの書き方がわかるのかと思いきや、この続きは公開されませんでした*1

mikutodonはworld対応をがんばっていたようですが、どうにもドキュメントがなさすぎる状況で、非常に苦しんでいたようです。その中でも、mastodon WebUIが使用しているwebsocket APIではなく、mastodonの公式ドキュメントが推奨するSSE stream APIへの対応を行なうなど、進歩を見せていましたが、ついにはmikutodonの開発は停滞してしまいました*2

そういった状況の中で、いよいよ、World対応のmastodonクライアントは自作するしかない、という結論に至り、作成したのがWorldonです。

Worldonは、toshi_aさんの「うんこでたボタン」に採用されたことで知名度を上げました。

現状でもbuggyな部分は多々ありますが、継続的に開発を続けています。

Worldon実装の上で、toshi_aさんからは多くの助言を頂き、結果的にmikutterのUIと親和性の高いものにすることができたのかなと思います。

また、開発の上でmikutterのソースコードの数多くの部分を読むことになり、結果的に別のプラグインを書いたり、更には本体への貢献をすることができるようになりました。

こういったことの積み重ねが認められた結果、コミッターに招いていただけたのだと思います。本当にありがとうございます。

ところで

こういった突然のコミッター就任は実は2度目です。

1度目はcpprefjpという、C++標準の日本語リファレンスプロジェクトです。

この時は、以下のような経緯でした。

  1. サイト内のサンプルコードに記載された円周率の定義が間違っていることに気づく
  2. pull-reqを受け付けているということだったので、同様の間違いがある部分を「単に数字だけ置き換えた」pull-reqを送る
  3. メール「コミッターに招待しました」←!!!!????!??!wwwwwwwwwwwwwwwww

なんとC++の規格に対する知識どころか、C++のコードすら1行も書かずにコミッターになってしまったのです。

こういった経験から、今回のmikutterコミッター就任は、突然のことではあったものの、経緯としては非常に常識的な流れで進んでおり、素直に受け入れることができました。

余談ですが、cpprefjpの方には(当然のことながら)怖すぎてあれ以来一切のpull-reqをしていません。

Rubyの方でも、mikutter以外では全く書いていないといっても過言ではないくらいなので、言語や環境に対する知識というのは心もとないものがありますが、今後、少しずつ身につけていきたいと思います。

今後ともよろしくお願いいたします。

*1:現在でもされていません。続きは予約公開しようとしたら公開されなかったのがおもしろいのでそのままらしいです。

*2:そら氏自身は、その後CUIベースのmastodonクライアント ConsoleTooter https://github.com/sora0920/ConsoleTooter を作成されたりしています。

敗北

WSLでGdk::Cursor.new(display, name)を使うと落ちる - cobodoのブログ

Gdk::Cursor.new(display, name)との戦い2 - cobodoのブログ

の続き。

職場環境ではカーソルのサイズが64x64で描画され、しかも32x32でトリミングされるという最悪な状況に陥り、その上解決のめどが立たないため、諦めることにした。

Plugin.create(:legacy_cursor) do
  class Gdk::MiraclePainter < Gtk::Object
    private
    def set_cursor(name)
      type = case name
             when 'pointer'
               Gdk::Cursor::HAND2
             when 'text'
               Gdk::Cursor::XTERM
             else
               Gdk::Cursor::LEFT_PTR
             end
      window = @tree.get_ancestor Gtk::Window
      window.window.cursor = Gdk::Cursor.new(type)
      self
    end
  end
end

諦め、それはモンキーパッチ。

MiraclePainterはmikutter 3.8で大幅に手を入れる予定らしいことと、機能 #1203: Gdk::Cursorのインスタンスを得る方法を変更する - mikutter - やることにより他の箇所に波及することも視野に入れ、追従してメンテナンスしていく必要がある。

Gdk::Cursor.new(display, name)との戦い2

昨日書いたやつの続き。結局あれからTypeError wrong argument type Gdk::DisplayX11 (expected Data)が2回追加で発生した。

カーソルテーマだけでは足りないものがある可能性を考え、デスクトップ環境をまるごと入れることにした。

とはいえ、Unityが動くかというとだいぶ怪しいため、また、合計ファイルサイズ的にあまりデカくても邪魔なため、xfce4を入れた。xfce4はUbuntuフレーバーのひとつであるXubuntuのデフォルトデスクトップ環境であり、Ubuntu的にはわりとサポートが良いデスクトップ環境のはず。

$ sudo apt install xfce4
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下の追加パッケージがインストールされます:
  dbus-x11 desktop-base desktop-file-utils exo-utils gconf2 greybird-gtk-theme gstreamer1.0-plugins-base gtk2-engines-murrine gtk2-engines-pixbuf gtk2-engines-xfce gvfs gvfs-common gvfs-daemons gvfs-libs libart-2.0-2 libatasmart4 libatkmm-1.6-1v5
  libauthen-sasl-perl libavahi-glib1 libbonobo2-0 libbonobo2-common libbonoboui2-0 libbonoboui2-common libcairomm-1.0-1v5 libcanberra-gtk3-0 libcanberra-gtk3-module libcanberra0 libcdparanoia0 libencode-locale-perl libexo-1-0 libexo-common libexo-helpers
  libfile-listing-perl libfont-afm-perl libfontenc1 libgail18 libgarcon-1-0 libgarcon-common libgck-1-0 libgcr-3-common libgcr-base-3-1 libglade2-0 libglibmm-2.4-1v5 libglu1-mesa libgnome-2-0 libgnome-keyring-common libgnome-keyring0 libgnome2-0 libgnome2-bin
  libgnome2-common libgnomecanvas2-0 libgnomecanvas2-common libgnomeui-0 libgnomeui-common libgnomevfs2-0 libgnomevfs2-common libgstreamer-plugins-base1.0-0 libgstreamer1.0-0 libgtkmm-3.0-1v5 libhtml-form-perl libhtml-format-perl libhtml-parser-perl
  libhtml-tagset-perl libhtml-tree-perl libhttp-cookies-perl libhttp-daemon-perl libhttp-date-perl libhttp-message-perl libhttp-negotiate-perl libical1a libimobiledevice6 libio-html-perl libio-socket-ssl-perl libjpeg-progs libjpeg9 libkeybinder-3.0-0
  libkeybinder0 liblwp-mediatypes-perl liblwp-protocol-https-perl libmailtools-perl libnet-http-perl libnet-smtp-ssl-perl libnet-ssleay-perl libnotify-bin libnotify4 libopus0 liborbit-2-0 libpangomm-1.4-1v5 libplist3 libpoppler-glib8 libpoppler58
  libpulse-mainloop-glib0 libsecret-1-0 libsecret-common libsigc++-2.0-0v5 libstartup-notification0 libtheora0 libthunarx-2-0 libtumbler-1-0 libudisks2-0 libupower-glib3 liburi-perl libusbmuxd4 libvisual-0.4-0 libvorbisfile3 libwnck-common libwnck22
  libwww-perl libwww-robotrules-perl libxatracker2 libxfce4panel-2.0-4 libxfce4ui-1-0 libxfce4ui-2-0 libxfce4ui-common libxfce4ui-utils libxfce4util-bin libxfce4util-common libxfce4util7 libxfconf-0-2 libxfont1 libxkbfile1 libxklavier16 libxres1 libxss1 libxv1
  libxvmc1 libxxf86dga1 notification-daemon orage pavucontrol sound-theme-freedesktop tango-icon-theme thunar thunar-data thunar-volman tumbler tumbler-common udisks2 upower usbmuxd x11-apps x11-session-utils x11-utils x11-xkb-utils x11-xserver-utils xbitmaps
  xfce4-appfinder xfce4-notifyd xfce4-panel xfce4-pulseaudio-plugin xfce4-session xfce4-settings xfce4-volumed xfconf xfdesktop4 xfdesktop4-data xfonts-base xfonts-encodings xfonts-scalable xfonts-utils xfwm4 xinit xinput xorg xorg-docs-core xscreensaver
  xscreensaver-data xserver-common xserver-xorg xserver-xorg-core xserver-xorg-input-all xserver-xorg-input-evdev xserver-xorg-input-synaptics xserver-xorg-input-vmmouse xserver-xorg-input-wacom xserver-xorg-video-all xserver-xorg-video-amdgpu
  xserver-xorg-video-ati xserver-xorg-video-fbdev xserver-xorg-video-intel xserver-xorg-video-nouveau xserver-xorg-video-qxl xserver-xorg-video-radeon xserver-xorg-video-vesa xserver-xorg-video-vmware xterm xubuntu-icon-theme
提案パッケージ:
  gconf-defaults-service murrine-themes gvfs-backends libdigest-hmac-perl libgssapi-perl libbonobo2-bin libcanberra-gtk0 libcanberra-pulse gnome-keyring gnome-icon-theme libgnomevfs2-bin libgnomevfs2-extra gamin | fam gnome-mime-data libvisual-0.4-plugins
  gstreamer1.0-tools libdata-dump-perl libusbmuxd-tools libcrypt-ssleay-perl opus-tools poppler-data libauthen-ntlm-perl devhelp sox kdelibs-data thunar-archive-plugin thunar-media-tags-plugin tumbler-plugins-extra reiserfsprogs exfat-utils mesa-utils nickle
  cairo-5c xfce4-goodies xfce4-power-manager gtk3-engines-xfce fortunes-mod pm-utils menu xfwm4-themes xorg-docs xfonts-100dpi xfonts-75dpi x11-xfs-utils xfishtank xdaliclock xscreensaver-gl fortune www-browser qcam | streamer gdm3 | kdm-gdmcompat
  xfonts-100dpi | xfonts-75dpi gpointing-device-settings touchfreeze firmware-amd-graphics xserver-xorg-video-r128 xserver-xorg-video-mach64 xfonts-cyrillic
推奨パッケージ:
  perl5
以下のパッケージが新たにインストールされます:
  dbus-x11 desktop-base desktop-file-utils exo-utils gconf2 greybird-gtk-theme gstreamer1.0-plugins-base gtk2-engines-murrine gtk2-engines-pixbuf gtk2-engines-xfce gvfs gvfs-common gvfs-daemons gvfs-libs libart-2.0-2 libatasmart4 libatkmm-1.6-1v5
  libauthen-sasl-perl libavahi-glib1 libbonobo2-0 libbonobo2-common libbonoboui2-0 libbonoboui2-common libcairomm-1.0-1v5 libcanberra-gtk3-0 libcanberra-gtk3-module libcanberra0 libcdparanoia0 libencode-locale-perl libexo-1-0 libexo-common libexo-helpers
  libfile-listing-perl libfont-afm-perl libfontenc1 libgail18 libgarcon-1-0 libgarcon-common libgck-1-0 libgcr-3-common libgcr-base-3-1 libglade2-0 libglibmm-2.4-1v5 libglu1-mesa libgnome-2-0 libgnome-keyring-common libgnome-keyring0 libgnome2-0 libgnome2-bin
  libgnome2-common libgnomecanvas2-0 libgnomecanvas2-common libgnomeui-0 libgnomeui-common libgnomevfs2-0 libgnomevfs2-common libgstreamer-plugins-base1.0-0 libgstreamer1.0-0 libgtkmm-3.0-1v5 libhtml-form-perl libhtml-format-perl libhtml-parser-perl
  libhtml-tagset-perl libhtml-tree-perl libhttp-cookies-perl libhttp-daemon-perl libhttp-date-perl libhttp-message-perl libhttp-negotiate-perl libical1a libimobiledevice6 libio-html-perl libio-socket-ssl-perl libjpeg-progs libjpeg9 libkeybinder-3.0-0
  libkeybinder0 liblwp-mediatypes-perl liblwp-protocol-https-perl libmailtools-perl libnet-http-perl libnet-smtp-ssl-perl libnet-ssleay-perl libnotify-bin libnotify4 libopus0 liborbit-2-0 libpangomm-1.4-1v5 libplist3 libpoppler-glib8 libpoppler58
  libpulse-mainloop-glib0 libsecret-1-0 libsecret-common libsigc++-2.0-0v5 libstartup-notification0 libtheora0 libthunarx-2-0 libtumbler-1-0 libudisks2-0 libupower-glib3 liburi-perl libusbmuxd4 libvisual-0.4-0 libvorbisfile3 libwnck-common libwnck22
  libwww-perl libwww-robotrules-perl libxatracker2 libxfce4panel-2.0-4 libxfce4ui-1-0 libxfce4ui-2-0 libxfce4ui-common libxfce4ui-utils libxfce4util-bin libxfce4util-common libxfce4util7 libxfconf-0-2 libxfont1 libxkbfile1 libxklavier16 libxres1 libxss1 libxv1
  libxvmc1 libxxf86dga1 notification-daemon orage pavucontrol sound-theme-freedesktop tango-icon-theme thunar thunar-data thunar-volman tumbler tumbler-common udisks2 upower usbmuxd x11-apps x11-session-utils x11-utils x11-xkb-utils x11-xserver-utils xbitmaps
  xfce4 xfce4-appfinder xfce4-notifyd xfce4-panel xfce4-pulseaudio-plugin xfce4-session xfce4-settings xfce4-volumed xfconf xfdesktop4 xfdesktop4-data xfonts-base xfonts-encodings xfonts-scalable xfonts-utils xfwm4 xinit xinput xorg xorg-docs-core xscreensaver
  xscreensaver-data xserver-common xserver-xorg xserver-xorg-core xserver-xorg-input-all xserver-xorg-input-evdev xserver-xorg-input-synaptics xserver-xorg-input-vmmouse xserver-xorg-input-wacom xserver-xorg-video-all xserver-xorg-video-amdgpu
  xserver-xorg-video-ati xserver-xorg-video-fbdev xserver-xorg-video-intel xserver-xorg-video-nouveau xserver-xorg-video-qxl xserver-xorg-video-radeon xserver-xorg-video-vesa xserver-xorg-video-vmware xterm xubuntu-icon-theme
アップグレード: 0 個、新規インストール: 188 個、削除: 0 個、保留: 0 個。
44.1 MB 中 43.7 MB のアーカイブを取得する必要があります。
この操作後に追加で 163 MB のディスク容量が消費されます。
続行しますか? [Y/n]

これでしばらく様子見。さてどうなるか。

WSLといえどもデスクトップ環境をインストールして起動コマンド(この場合startxfce4)を打てばWindowsデスクトップ上にxfce4のパネル等が出現し普通にランチャーとして使うこともでき、ユカイな絵面になるものの、利便性があるかというと別に……といったところ。

WSLでGdk::Cursor.new(display, name)を使うと落ちる

TL;DR

WSLでmikutterを使う時はsudo apt install breeze-cursor-theme chameleon-cursor-themeしてsudo update-alternatives --config x-cursor-themeでどちらかの系統のテーマを選択すれば落ちないこともあるかもしれない。

長い本文

恐らく

機能 #1197: MiraclePainter上でマウスを動かしたときにカーソル形状を適切に変更して欲しい - mikutter - やること

のパッチがマージされて以降、mikutterが落ちるようになった。

/core/mui/cairo_miracle_painter.rb - mikutter - やること

↑ここで落ちる。確かに、MiraclePainterの領域にカーソルを動かしていくと落ちるように見受けられる。ここで渡しているnameを表示させてみると、'default'らしい。えぇ……

エラーメッセージは↓のような感じ。

RuntimeError failed to initialize
{MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:223:in `initialize'
{MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:223:in `new'
{MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:223:in `set_cursor'
{MIKUTTER_DIR}/core/lib/uithreadonly.rb:22:in `block (2 levels) in singleton class'
{MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:183:in `point_moved'
{MIKUTTER_DIR}/core/lib/uithreadonly.rb:22:in `block (2 levels) in singleton class'
{MIKUTTER_DIR}/core/mui/cairo_cell_renderer_message.rb:184:in `block in event_hooks'
{MIKUTTER_DIR}/core/mui/gtk_extension.rb:35:in `block in safety_signal_connect'
{MIKUTTER_DIR}/core/mui/cairo_cell_renderer_message.rb:73:in `signal_emit'
{MIKUTTER_DIR}/core/mui/cairo_cell_renderer_message.rb:73:in `block in tree='
{MIKUTTER_DIR}/core/mui/gtk_extension.rb:35:in `block in safety_signal_connect'
{MIKUTTER_DIR}/core/plugin/gtk/mainloop.rb:10:in `main'
{MIKUTTER_DIR}/core/plugin/gtk/mainloop.rb:10:in `mainloop'
./mikutter.rb:68:in `boot!'
./mikutter.rb:104:in `<main>'

Gdk::Cursor.newのドキュメント Gdk::Cursor - Ruby-GNOME2 Project Website を見ると、

If type_or_name is a String, creates a new cursor by looking up type_or_name in the current cursor theme (Since 2.8)

とある。cursor themeとは、 カーソルテーマ - ArchWiki によると、

ディスプレイサーバーには GUI のナビゲーションや操作を楽にするカーソルテーマが付属しています。ディスプレイサーバーにカーソルテーマは含まれていますが、他のカーソルテーマをインストールして選択することもできます。

ということらしい。VcXsrvがカーソルテーマから名前でカーソルを取得する機能を持っていない、とかいうことなんだろうか。

しかしユーザレベルで上書きできるということは、ディスプレイサーバに問い合わせに行くのは最後だろうから、aptで適当にカーソルテーマを入れればいいのではないか。

というわけで、apt search cursorして、最初に目についたbreeze-cursor-themeを入れてみる。

$ sudo apt install breeze-cursor-theme

今度はすぐには落ちない、が、マウスカーソルをいろいろ動かしてみたら別のエラーで落ちた。

TypeError wrong argument type Gdk::DisplayX11 (expected Data)
{MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:223:in `initialize'
{MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:223:in `new'
{MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:223:in `set_cursor'
{MIKUTTER_DIR}/core/lib/uithreadonly.rb:22:in `block (2 levels) in singleton class'
{MIKUTTER_DIR}/core/mui/cairo_miracle_painter.rb:183:in `point_moved'
{MIKUTTER_DIR}/core/lib/uithreadonly.rb:22:in `block (2 levels) in singleton class'
{MIKUTTER_DIR}/core/mui/cairo_cell_renderer_message.rb:184:in `block in event_hooks'
{MIKUTTER_DIR}/core/mui/gtk_extension.rb:35:in `block in safety_signal_connect'
{MIKUTTER_DIR}/core/mui/cairo_cell_renderer_message.rb:73:in `signal_emit'
{MIKUTTER_DIR}/core/mui/cairo_cell_renderer_message.rb:73:in `block in tree='
{MIKUTTER_DIR}/core/mui/gtk_extension.rb:35:in `block in safety_signal_connect'
{MIKUTTER_DIR}/core/plugin/gtk/mainloop.rb:10:in `main'
{MIKUTTER_DIR}/core/plugin/gtk/mainloop.rb:10:in `mainloop'
./mikutter.rb:68:in `boot!'
./mikutter.rb:104:in `<main>'

そんなこと言われてもですね……

何も変えずにもう一度起動してみたところ、今度は落ちなかった。謎は深まるばかり。

ところで別のテーマに変えてみようと、一旦

$ sudo apt remove breeze-cursor-theme

したところ、次のようなメッセージが出た。

update-alternatives: /usr/share/icons/default/index.theme (x-cursor-theme) を提供するために自動モードで /usr/share/icons/Adwaita/cursor.theme を使います

デフォルトのテーマ、用意されてるじゃん。だとするとVcXsrvのせいではなさそう。

この状態で起動したところ、最初と同じエラーを出して落ちた。原因はAdwaitaテーマ(?)ということでいいのだろうか。

次に

$ sudo apt install oxygen-cursor-theme

してみたところ、今度はウィンドウを表示するだけで落ちる。そもそも、このパッケージのインストール時にはupdate-alternativesが走っていないようだった。

apt search cursorして出てきたそれっぽいパッケージをすべて*1入れ、以下のコマンドで切り替えながらいろいろと試した。

$ sudo update-alternatives --config x-cursor-theme

名前が同系統のものは適当にピックアップして1つずつ試した。

その結果、breeze系とChameleon系のみ、ほとんど落ちないことがわかった。これが何故なのかはわからないし、さっき違うメッセージで落ちたのは再現すらできない。

GNOME系のテーマカスタマイズをしたことは無いので、このあたりの知識が全然足りず、あまり深掘りできなかった。

これらのテーマが具体的にどういう(メタ)データを持っていて、落ちるものと落ちないものがどう違うのか、わかればいいのだけど。

*1:breeze-cursor-theme chameleon-cursor-theme comixcursors-righthanded crystalcursors dmz-cursor-theme human-theme moblin-cursor-theme oxygen-cursor-theme sabily-themes xcursor-themes

WSLでuim-mozcを使う

をやってみた、というだけの記事です。

変更点は以下の通り。

  • 17.04 Zesty Zapusの代わりに、17.10 Artful Ardvarkを使う。
  • uimやmozcの設定まで行なう。

あと2週間とすこしで18.04 Bionic Beaver (LTS)が出るというこの時期は、タイミングとしては微妙なんですが、そもそもWSLのUbuntuで果たしてdo-release-upgradeできるのか、という不安もあり、やってしまいました。

以下、手順です。

/etc/apt/sources.list.d/artful.list を作成する。内容は↓の1行。

deb http://ja.archive.ubuntu.com/ubuntu artful main universe

/etc/apt/preferences.d/artful を作成する。内容は↓の7行。

Package: *
Pin: release n=xenial
Pin-Priority: 990

Package: *
Pin: release n=artful
Pin-Priority: 90

aptのキャッシュを更新してインストールする。

$ sudo apt update
$ sudo apt install -t artful uim-mozc

あらかじめAnthyを使うようにしていた僕の環境では、Mozcは有効になりませんでした。uimの設定をします。

$ uim-pref-gtk

このコマンドでuimの設定ダイアログが開きます。全体設定>入力方式の利用準備>使用可能にする入力方式>編集 を押すと、左側に"Anthy"と"Anthy (UTF-8)"があり、右側に"Mozc"があるので、"Mozc"を左側に移動させます。今回は更にAnthy2つを右側に移動し、Mozcだけが有効なようにしました。

OKを押して閉じます。

次にmozcの設定をします。mozcの設定ダイアログは

$ /usr/lib/mozc/mozc_tool --mode=config_dialog

で起動できます。僕はDvorakJPを使っているので、DvorakJP用のローマ字テーブルをインポートします。またキー設定も適当に調整します。

mozcの単語登録は

$ /usr/lib/mozc/mozc_tool --mode=word_register_dialog

で、辞書ツールは

$ /usr/lib/mozc/mozc_tool --mode=dictionary_tool

で起動できます。

ここまで進めても、mozcが有効にならず、anthyが使われる場合があります。恐らく既に起動しているuimが設定を更新しないのだと思いますが、そういった場合、mikutter自体を含めて、すべてのXアプリケーションを終了する必要があるかもしれません。場合によってはWSLのコンソール自体も一旦閉じましょう。そうすれば有効になると思います。

これでmozcが使えます。

DvorakJP使いとしては、Anthyのローマ字テーブルカスタマイズは微妙で、「n'」で「ない」を入力するような一部のコンビネーションが効かなかったためにストレスがありましたが、mozcにはそういった制限はないため、これで完璧です。

Windows Subsystem for Linuxのインストールからmikutterをそれらしく動かすまで

眼鏡 (@calkinos) | Twitter氏に便利ツールを教えてもらったので書こうと思いました。

こちらのツールを使うと好きなrootfsでWSL環境を生やせるんですね。

というわけでUbuntu on Windows同梱のinstall.tar.gzを使って、普段使いの環境とは別のUbuntuを作り、そこにmikutterを入れてみたので、メモがてら一連の流れを書いておきます。何番煎じだって? きっとなにかの やくにたつから。

なお、バトル要素はありません。

〈2018-04-10 追記〉 mozcを使う場合の記事を書きました。 WSLでuim-mozcを使う - cobodoのブログ

Ubuntu on Windowsのインストール

まずWindows 10でLinuxプログラムを利用可能にするWSL(Windows Subsystem for Linux)をインストールする:Tech TIPS - @ITなどを参考にしてWSLを有効化し、Ubuntuを入れましょう。Ubuntuじゃなくてもいいです。

GitHub - yuk7/WSL-DistroLauncher: WSL Distribution Launcher clone. (Win10 FCU 64bit or later.)にArchなどのrootfsが置いてあるようなのでそちらを使ってもよいはずです。

Linuxとかは全然わかりませんし、この記事ではUbuntuを前提にします。

インストールしたら、まず何はともあれアップデートしましょう。横着なのでいつも↓のようなことをします。

$ for i in update full-upgrade autoremove autoclean; do sudo apt $i -y; done

また、日本語言語パックを入れ、ロケールを設定しておきます。

$ sudo apt install language-pack-ja
$ export LANG=ja_JP.UTF-8
$ echo 'export LANG=ja_JP.UTF-8' >> .bash_profile

あとは必要だと思ったものを適当にaptで入れましょう。gitは既に入っているようです。

(オプション)rbenvのインストール

現在配布されているUbuntu on Windowsは16.04.4 LTSなので、aptでrubyを入れると2.3.0です。最新のmikutterは動作環境をRuby 2.3.0 以降としていますから、問題はないはずです。新しいrubyを使いたい人はrbenvを入れましょう。

ググれば使い方が山ほど出てきますから、ここでは詳しく説明しませんが、Ubuntuの場合、先にbuild-essentialパッケージをインストールする必要があります。このパッケージは、gccなどのコンパイラや、makeなどのビルドツール、それに基本的なライブラリをセットでインストールするメタパッケージです。

$ sudo apt install build-essential

パッケージ数が多いので、多少時間がかかります。

準備できたら、rbenvのインストールに入ります。

$ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
$ cd ~/.rbenv && src/configure && make -C src
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ export PATH="$HOME/.rbenv/bin:$PATH"
$ ~/.rbenv/bin/rbenv init
$ eval "$(rbenv init -)"
$ mkdir -p "$(rbenv root)"/plugins
$ git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build

これでrbenvがインストールされました。~/.bashrc にもeval "$(rbenv init -)"を書いておくと便利だと思います。

次のコマンドを実行すると、正しくインストールされているかチェックしてくれます。

$ curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-doctor | bash

次にrbenvを使ってrubyをビルドしましょう。現在最新の安定版は2.5.1なので、これを入れてみます。が、実はライブラリが足りていないのであらかじめ入れてからビルドしましょう。

$ sudo apt-get install -y libssl-dev libreadline-dev zlib1g-dev
$ rbenv install 2.5.1

この、足りないライブラリをインストールするコマンドはrbenvがビルドに失敗した時に教えてくれます。便利ですが、失敗するまでにも結構時間がかかるので、先に書いておきました。

インストールが済んだら、とりあえずそれを使うようにしておきましょう。

$ rbenv global 2.5.1
$ ruby --version
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]

ついでに、bundlerをインストールしておきます。

$ gem install bundler

mikutterのインストール

本体です。アップデートが楽なようにgit cloneしてしまいましょう。

まず必要なライブラリを入れて*1から、依存gemも入れてしまいます。

$ git clone git://toshia.dip.jp/mikutter.git ~/mikutter
$ cd ~/mikutter
$ git checkout 3.6.5
$ sudo apt install libglib2.0-dev libidn11-dev
$ bundle install --path=vendor/bundle

途中、足りないライブラリがあると、bundlerが自動的にsudo apt-get installしようとするようで、パスワードを求められる場合があります。

ここまででmikutterは動きます。動くはずです。実際には、素の状態だと以下のようなエラーメッセージを吐いて終了します。

$ ruby ./mikutter.rb
Traceback (most recent call last):
        38: from ./mikutter.rb:42:in `<main>'
        37: from /home/cobodo/mikutter/core/miquire.rb:18:in `miquire'
        36: from /home/cobodo/mikutter/core/miquire.rb:75:in `miquire'
        35: from /home/cobodo/mikutter/core/miquire.rb:75:in `each'
        34: from /home/cobodo/mikutter/core/miquire.rb:76:in `block in miquire'
        33: from /home/cobodo/mikutter/core/miquire.rb:95:in `file_or_directory_require'
        32: from /home/cobodo/mikutter/core/miquire.rb:98:in `miquire_original_require'
        31: from /home/cobodo/mikutter/core/miquire.rb:98:in `require'
        30: from /home/cobodo/mikutter/core/boot/load_plugin.rb:10:in `<top (required)>'
        29: from /home/cobodo/mikutter/core/miquire_plugin.rb:96:in `load_all'
        28: from /home/cobodo/mikutter/core/miquire_plugin.rb:36:in `each_spec'
        27: from /home/cobodo/mikutter/core/miquire_plugin.rb:33:in `each'
        26: from /home/cobodo/mikutter/core/miquire_plugin.rb:33:in `each'
        25: from /home/cobodo/mikutter/core/miquire_plugin.rb:38:in `block in each_spec'
        24: from /home/cobodo/mikutter/core/miquire_plugin.rb:98:in `block in load_all'
        23: from /home/cobodo/mikutter/core/miquire_plugin.rb:146:in `load'
        22: from /home/cobodo/mikutter/core/utils.rb:278:in `atomic'
        21: from /home/cobodo/.rbenv/versions/2.5.1/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
        20: from /home/cobodo/mikutter/core/utils.rb:278:in `block in atomic'
        19: from /home/cobodo/mikutter/core/miquire_plugin.rb:147:in `block in load'
        18: from /home/cobodo/mikutter/core/miquire_plugin.rb:147:in `each'
        17: from /home/cobodo/mikutter/core/miquire_plugin.rb:149:in `block (2 levels) in load'
        16: from /home/cobodo/mikutter/core/miquire_plugin.rb:146:in `load'
        15: from /home/cobodo/mikutter/core/utils.rb:278:in `atomic'
        14: from /home/cobodo/.rbenv/versions/2.5.1/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
        13: from /home/cobodo/mikutter/core/utils.rb:278:in `block in atomic'
        12: from /home/cobodo/mikutter/core/miquire_plugin.rb:147:in `block in load'
        11: from /home/cobodo/mikutter/core/miquire_plugin.rb:147:in `each'
        10: from /home/cobodo/mikutter/core/miquire_plugin.rb:149:in `block (2 levels) in load'
         9: from /home/cobodo/mikutter/core/miquire_plugin.rb:146:in `load'
         8: from /home/cobodo/mikutter/core/utils.rb:278:in `atomic'
         7: from /home/cobodo/.rbenv/versions/2.5.1/lib/ruby/2.5.0/monitor.rb:226:in `mon_synchronize'
         6: from /home/cobodo/mikutter/core/utils.rb:278:in `block in atomic'
         5: from /home/cobodo/mikutter/core/miquire_plugin.rb:158:in `block in load'
         4: from /home/cobodo/mikutter/core/miquire_plugin.rb:158:in `load'
         3: from /home/cobodo/mikutter/core/plugin/gtk/gtk.rb:5:in `<top (required)>'
         2: from /home/cobodo/mikutter/core/plugin/gtk/gtk.rb:5:in `require'
         1: from /home/cobodo/mikutter/vendor/bundle/ruby/2.5.0/gems/gtk2-3.2.0/lib/gtk2.rb:13:in `<top (required)>'
/home/cobodo/mikutter/vendor/bundle/ruby/2.5.0/gems/gtk2-3.2.0/lib/gtk2.rb:13:in `init': Cannot open display:  (Gtk::InitError)

それもそのはずで、WSLには画面がなく、従ってGUIも無いのです。

guiプラグインを抜いた状態でmikutterを動かす話はmikutterの薄い本などにしばしば登場しますし、そういった用途であればここまででOKでしょう。

そうではなく、mikutterをGUIで楽しむには、いくつかやらなければならないことがあります。

Windows側へX Windowサーバをインストール

LinuxGUI(の実装のひとつ)はX Window Systemというもので、コレは各GUIアプリケーションがソケット経由で描画情報を送ってサーバ側に描画させる仕組みを取っています。

そこで、Windows側にXサーバを立て、WSL側からそこに描画情報をソケット通信で送れば、Windows上の画面にウィンドウを描画することができるわけです。

Windows上で動くXサーバの実装はいくつかありますが、ここではVcXsrvを使います。

https://sourceforge.net/projects/vcxsrv/

VcXsrvはウィンドウのアイコンをWindowsのタスクバー上でちゃんと出してくれるので好きです。普通にインストールして起動するだけでいいはずです。ファイアウォールの警告が出ると思いますので適当な範囲で許可しましょう。

WSL側で、環境変数DISPLAYに、使用するXサーバを指定して起動してやれば、すぐに表示できます。

$ export DISPLAY=:0.0
$ echo 'export DISPLAY=:0.0' >> ~/.bash_profile
$ ruby ./mikutter.rb

ウィンドウが表示されたと思いますが、文字化けしまくっていると思います。

フォントのインストール

文字化けしているのは日本語フォントが入っていないからです。適当に入れましょう。

$ sudo apt install fonts-noto fonts-noto-cjk fonts-noto-mono ttf-ancient-fonts
$ ruby ./mikutter.rb

今度は文字化けせずに表示されたのではないでしょうか。

他のフォントを使いたい場合は、適当にaptから入れるか、~/.local/share/fontsディレクトリの中に.ttfや.otfのファイルを置いて、

$ sudo fc-cache -fv

しましょう。

ブラウザの起動

mikutterからtwitterの認証を行うにはブラウザの起動が必要なので、設定しましょう。

最近のWSLはWindowsアプリケーションを直接実行できます。つまり、Windows側のブラウザをWSLから起動できるということです。この時、URLを引数に渡せばそのURLが普通に開きます。

mikutterでは、「設定>表示>URLを開く方法」で「次のコマンドを使う」を選択し、WSL側から見たブラウザのexeファイルへのパスを指定すれば、Windows側のブラウザに渡せます。私はFirefox Developer Editionを使用しているので、この場合は/mnt/c/Program Files/Firefox Developer Edition/firefox.exeとなります。

もちろんWSL内部で普通にfirefoxなどをインストールし、mikutterと同様の方法でWindows側のXサーバに描画させてもよいですが、通常はWindows側のブラウザを使った方が便利でしょう。

uim+anthyのインストール

〈2018-04-10 追記〉 mozcを使う場合の記事を書きました。 WSLでuim-mozcを使う - cobodoのブログ 環境変数は以下のものを前提にしているので、mozcを使う場合でもこのまま進めてください。おそらくuimパッケージはインストールする必要があると思います。

次は日本語を入力できるようにしましょう。

Linuxにおける多くの日本語入力システムはプロセス間通信にdbusを使用しています。dbusは基本的にUNIXドメインソケットで通信を行いますが、WSLはまだUNIXドメインソケットに対応していません*2

そこでdbusを使わないものが必要になるわけですが、uimuim-anthyを使えばいいらしいです。インストールしましょう。kasumiはユーザー辞書編集用です。

$ sudo apt install uim uim-anthy kasumi
$ cat >> ~/.bash_profile <<EOL
IM_MODULE=uim
export XMODIFIERS=@im=\$IM_MODULE
export GTK_IM_MODULE=\$IM_MODULE
export QT_IM_MODULE=\$IM_MODULE
EOL
$ IM_MODULE=uim
$ export XMODIFIERS=@im=$IM_MODULE
$ export GTK_IM_MODULE=$IM_MODULE
$ export QT_IM_MODULE=$IM_MODULE

これで、mikutter上で日本語入力ができるようになりました*3

ここまでで、それなりに普通に、mikutterが使えるのではないでしょうか。好きなプラグインを入れましょう。

(オプション)pulseaudioのインストール

イベントが発生した時にみくったーちゃんにしゃべってもらいたいあなたは、更にやることがあります。

WSLにはサウンドデバイスがありません。従ってALSAは動きません。ですから音は鳴りません。

そこでX Windowと同じく、ソケット通信を使います。

WSL内でクライアント用のpulseaudioデーモンを動かし、Windows側でサーバ用のpulseaudioデーモンを動かすのです。すると、WSL側のpulseaudioデーモンが送信した音声データを、Windows側のpulseaudioデーモンがWindowsのサウンドデバイスで再生してくれるのです。

まずWSL内でpulseaudioをインストールしましょう。

$ sudo apt install pulseaudio

次にpulseaudioの設定をします。/etc/pulse/client.confの22行目にある

; default-server =

という行を、次のように書き換えます。

default-server = tcp:localhost

続いて/etc/pulse/default.paテキストエディタで開き、86行目にある

#load-module module-native-protocol-tcp

の先頭の#を消し

load-module module-native-protocol-tcp

とします。

次はWindows側です。www.freedesktop.org内にあるPulseAudioのWindowsサポートに関するページに、

For convenience, a zipfile containing preview binaries is available.

という文とリンクがあると思います。これをダウンロードするとpulseaudio-1.1.zipが落ちてきます。適当なディレクトリに展開します。

展開したファイルのうち、etc/pulse/default.paテキストエディタで開き、61行目の

#load-module module-native-protocol-tcp

load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 auth-anonymous=1

と書き換えます。

コマンドプロンプトを開いて、展開したディレクトリのbin/cdし、pulseaudio.exeを実行します。すると待機状態になります。ここでもファイアウォール警告が出ると思います。適当にやりましょう。

ここで、WSL側で

$ paplay ~/mikutter/core/skin/data/sounds/mikutter-se.wav

を実行すると、「み↓くった~↑♪」としゃべってくれることでしょう。

このpulseaudio.exeは、-dを付けてデーモンモードで起動したりしても、時間経過(もしくは何らかの条件)で勝手に終了してしまうため、WSL側かMSYS2などを使ってコンソールを開きっぱなしにした上で、以下のようなスクリプトで常駐させてやるとよいでしょう。

#!/bin/bash
cd /path/to/pulseaudio-1.1/bin
while ./pulseaudio.exe || true; do
    echo
    echo '!!!pulseaudio restart!!!'
    echo
done

次にmikutterから音を鳴らす方法です。mikutterはデフォルトではaplayコマンドを使ってALSA経由で音を鳴らしますが、これは前述の通り鳴りません。また、GitHub - toshia/mikutter-pulseaudio: mikutterの効果音をPulseAudioを通して再生するというプラグインもありますが、こちらが利用するpacmdコマンド経由の再生は、WSL環境だと何故か効かないようです。

そこで、標準のaplayを使って再生するプラグインを、paplayを使って再生するように改造したものがGitHub - cobodo/mikutter-paplayです。これを使えば、ふぁぼられた時などにmikutterに任意のサウンドを再生させることができます。

使い方は、インストールして、設定>サウンドで選択するだけです。

$ mkdir -p ~/.mikutter/plugin && git clone git://github.com/cobodo/mikutter-paplay ~/.mikutter/plugin/paplay

(オプション)Windows側へBurntToastをインストール

mikutterには通知がある場合にポップアップを出してお知らせする機能がありますが、これはLinuxnotify-sendコマンドを経由しています。これはlibnotify-binパッケージを入れれば実行できますが、実行しても何も表示されません。

そこで、PowerShell経由でWindowsの通知機能を使えるBurntToastというツールをインストールし、WSL側からpowershell.exeを叩いて通知を出すことにしたのがGitHub - cobodo/mikutter-burnt-toastというプラグインです。

まずPowerShellを管理者権限で開き、以下のコマンドを実行してBurntToastをインストールします。

> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
> Install-Module -Name BurntToast

次にこのプラグインをmikutterにインストールします。

$ mkdir -p ~/.mikutter/plugin && git clone git://github.com/cobodo/mikutter-burnt-toast ~/.mikutter/plugin/burnt_toast

設定>BurntToastから、Windows側から見たWSLのrootfsへのパスを設定してください。筆者の環境では以下のような値でした。

C:\Users\cobodo\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc\LocalState\rootfs

これで通知が表示されるようになりますし、履歴も見られます。

f:id:cobodo:20180331033001p:plain

このようにアイコン付きで表示されます。

おわりに

WSLはまだまだ発展途上で、いろいろな機能が足りませんが、ソケット通信とWindows側のexe起動があればどうとでもなることがわかってもらえたと思います。

日本語入力に関しては正直なところ微妙ですが、使えないほどではありません。mozcが動けばいいんですが……

この記事を読んでWSL上でmikutterを楽しむ人が増えれば幸いです。

*1:libidn11-devは、これに依存しているgemがbundlerによる自動インストールに対応しておらず、どのパッケージを入れればいいのか自明ではないので注意。

*2:将来的に対応する予定はあるらしいです。

*3:mikutterはGTKで動くのでQT_IM_MODULEなどは必要ないと思いますが、もののついでです。