ハセガワ ウォーターラインシリーズ 1/700 駆逐艦 三日月

ここんところ立て続けに駆逐艦を作っているのですが、楽しくて仕方ありません。もっと早く作り始めればよかったーと思わんばかり。サクサクと増えつつある駆逐艦隊が可愛くてたまりません。

それで、前回の「桜」に続いて今回は駆逐艦「三日月」です。
「吹雪」と「桜」がタミヤ製だったのに対して、今回は初のハセガワです。買ってきてから気付いたんですが、ハセガワです。

タミヤの感覚で組もうと思ってたら、出鼻を挫かれました。というか色々な意味で洗礼を受けました。
自分が初心者であって技術がないからというのが最大の理由であって、ハセガワ自体を批判するわけではないのですが、タミヤの感覚で組もうとすると結構大変でした。

  • パーツを置く場所に穴がない。
  • 素人「え!?そこでパーツが分断されてるの!?」っていう位置でパーツが分かれていて、それを接着しなければならない。
  • パーツを置いた後の固定が大変。
  • パリが多い。結合部と必要なパーツの間が曖昧だったり小さすぎたりしてニッパーを入れるのが大変。

全部、組み立てる人のスキルでカバーしなければならないんでしょうが、なかなかこれがツライ…。子供の頃を思い出すと、たしかにタミヤ以外のプラモデルは結構組みにくい印象があったようななかったような。そういうことを再認識させられた感じです。

三日月 大きい画像

手前から三日月(建造中)、桜、吹雪。途中まで組んで、ベースとなる軍艦色を塗った状態です。どうせならと、同型艦は避けて作っていってるんですが、三日月は船首楼が大きく、一段下がったところに艦橋があるのが特徴的で、並べてみると面白いです。
ちなみに、船首楼の上甲板はハルと別パーツでした。

単装砲も結構パリがひどくて磨こうとしてみたんですが、パーツが小さすぎて断念。固定する方法を考えなきゃ…。

タミヤ ウォーターラインシリーズ 1/700 駆逐艦 桜(完成)

駆逐艦「桜」です。

前回の「吹雪」が塗り直しをしたり、要領を得なかったりと、空いた時間を使って作っていたら1週間近くかかっていましたが、今回は3日で完成することができました。下手な素人なりに少しずつ要領を得てきているのかな。

前日、会社の同僚とやったバーベキューの後片付けを終えてから作業に着手。本当は部屋の片付けもしなければいけないんだけど、こういうのはやる気があるうちにやってしまいたいものですもんね!

桜 大きな画像

「吹雪」の時と違って、細かなパーツの接着は爪楊枝をつかっているので、あまりにもあんまりな接着剤跡というのは少なくなりました。大きな失敗といえば、軍艦旗をデカールだと思い込んで水に浸したこと。あわてて取り出して乾燥しました。

また、パーツの塗りも「吹雪」のようにシンナーで一旦全部拭き落として…のようなこともせず、スムーズにいった感じがしました。

思い残すところはたくさんあれど、吹雪より進化していて嬉しい気分。

ここまで2隻、佐世保海軍工廠建造ではない艦を同工廠色で塗っていたのですが、次はいよいよ佐世保生まれの駆逐艦「三日月」です。

駆逐艦「島風」のローポリモデル作成

仕事の絡みもあって、Maya で作成した三次元モデルをゲームエンジン「Unity」に取り込む検証をしようと思いました。 手持ちの Maya は 2009 と、ちょっと古いんですが FBX 形式の読み書きもプラグインで対応しているようでひとまず安心。 Battle Station; Paciffic のような艦隊戦デモでも作れないものかと、例のごとく駆逐艦のローポリモデルを作ろうと思いました。

Maya 自体久々だったからキーバインドやマウス操作にも迷いつつ…。自作の簡易 3D CAD の siren で、スクリプトの動作検証用に作っていた駆逐艦「島風」の船型を流用してみました。

  1. siren で島風スクリプト(Ruby)を実行。
  2. 生成されたモデルは自由曲面で構成されたソリッドモデルだが、STL で一旦ファイルに保存。
  3. Maya で STL の船型を読み込み。
  4. 艦橋や主砲などを置いていき、島風完成!
  5. 完成した島風を FBX で出力して Unity に取り込み。

といった手順です。結果、上手くいきました。

自分が作った CAD で生成されたモデルをゲームエンジンの中で動かすのは小気味良くて楽しいですね。 モデル自体も、かなりやっつけ感がしますが、これはこれで楽しいからOKかな。

島風 大きい画像

タミヤ ウォーターラインシリーズ 1/700 駆逐艦 桜

「吹雪」に続いて、今度は「桜」を作っていきます。 吹雪の船長が 120 メートルと大型な駆逐艦なので、船型を並べてみると大きさの違いが分かります。

桜 大きい画像

価格も吹雪よりも安かったので、デカールは入っておらず、軍艦旗は通常のシール。バラストの金属も入ってませんでした。パーツ数を数えたわけではありませんが、パッと見少なそう。

吹雪よりも小さいということで、もっと細かな作業が要求されそうですが…いつもどおり気楽に作っていこうと思います。

桜 大きい画像

軍艦色で塗装後の様子。

Mr.カラーの佐世保海軍工廠色を吹きまくってますが、この艦の建造は横須賀海軍工廠です。持ってません。上甲板のモールドを見てみると、いかにも金属の滑り止めが掘られている部分とそうでない部分があります。ツルツルな部分はリノリウム甲板かなあ、と思いつつ全体をグレイで吹いてしまいました。パッケージ裏の配色指定ではリノリウム色の塗り分けが書いてありません。あと持ってません。

吹雪の教訓を活かして、主要な上部構造物を配置してから、スプレーしてみました。こうすることにより、接着剤やパーツ同士の継ぎ目の跡が消え…る気がしますが、あんまり変わらない気もしてきました。

機銃のガンメタル色などは、枠から切り離す前にざーっと筆塗りしました。次は細かなパーツを配置していきます。

タミヤ ウォーターラインシリーズ 1/700 駆逐艦 吹雪(完成)

前回に引き続き、タミヤのウォーターラインシリーズの 1/700 スケール 駆逐艦「吹雪」です。

こだわりすぎるとなかなか作業が進まないのでウォーミングアップとして、サクサク作っていこうっていうのがポリシーでやってます。 気楽に作ってるといろいろ苦労するところもあるけれど、中々楽しい。やっぱ楽しく作らないとね!

さて、言い訳はほどほどにして。

吹雪 大きい画像

装載艇を積んで、クリア吹いて、気持ちばかり空中線をつけて…と前回、書いていたんですが、実際にやってみると本当に苦労しました。ここ何年も細かな作業に縁がなかったので、指が震えるし、手元が見えないし。 挙句のはて、接着剤がドバドバっと出て凝固するしで散々です。

あまり資料を参考にもしていないので、色も変です。空中線を張ってみましたが、太さにバラつきがあって違和感が。

まあ、でも遠目に見たらそれほど見れなくもないし、自分にしてはガンバッタ方だと思います!(力説) ツッコミを入れればキリがないので、さっさと次のやつにとりかかります!

次もタミヤのウォーターラインシリーズで、1/700 駆逐艦「桜」です。

Cでバイトコード文字列を実行する

自分用のメモです。

特にこれといって意味がないものですが、Cでバイトコード文字列を実行します。

ソースコード

仮引数 v の中身を直に書き替えているので、あまり行儀の良いコードではないのです。 本来、関数ポインタを渡す qsort() の第4引数にコンパイルした関数のバイト列を文字列(つまりchar*)として記述し、そのバイト列を const void*, const void* を引数にとって int 型を返す関数ポインタにキャストして、qsort() 内からコールバックされます。

インライン・アセンブラならぬ、インライン・バイトコードといったところでしょうか。ハードコーディングされた文字列も、ポインタとして抽象的な解釈がなされるため、よく理にかなった動きをしていると言えます。

このコードを実行すると、引数に与えられた文字列をソートして印字します。

また、上記のようなバイトコード文字列を即時実行させるには、

int n = 10;
int m = 20;
printf("%d\n",
  ((int(*)(int,int))
    "\x55\x89\xe5\x8b\x55\x08\x8b\x45\x0c\x39\xd0\x7d\x02\x89\xd0\x5d\xc3"
  )(n, m));

という記述で、関数名(つまり関数ポインタ)に関数呼び出しであることを示す()をつければ、通常の関数と同様に呼び出すことができます。 上のコードは、渡された n, m を評価し、大きい方を返す関数のバイトコード文字列を実行しています。

バイトコード文字列は、

int max(int a, int b)
{
  return a > b ? a : b;
}

という内容のmax.cがあった場合、

gcc -c max.c
objdump -D max.o

して得られる、関数 max() の部分から得られます。

00000000 <max>:
  0:   55                      push   %ebp
  1:   89 e5                   mov    %esp,%ebp
  3:   8b 55 08                mov    0x8(%ebp),%edx
  6:   8b 45 0c                mov    0xc(%ebp),%eax
  9:   39 d0                   cmp    %edx,%eax
  b:   7d 02                   jge    f <max+0xf>
  d:   89 d0                   mov    %edx,%eax
  f:   5d                      pop    %ebp
 10:   c3                      ret    

バイトコードという表現だと、Java や Ruby の VM に対する中間コードのように聞こえて語弊があるかもしれません。この記事で扱っているのは、あくまでもコンパイル時にコンパイル済みのバイトコードが埋め込まれるようにしているだけであって、実行時評価はされませんし、プラットフォームに依存しています。

シェルスクリプトによる簡易Wikiシステム

以前、PQI Air Card でも動く簡易 Wiki を書いてみました。PQI Air Card 自体、標準で Perl が動いていますし実用性はあんまりないですが、シェルスクリプトベースでも簡単に出来てしまいます。

wiki.sh

メインスクリプトです。

#!/bin/bash

dir=p
#BASENAME="/mnt/sd/DCIM/122_TREK/busybox basename"
BASENAME="basename"
tmp=`$BASENAME $QUERY_STRING`
page=${tmp:-index}

if [ "$REQUEST_METHOD" = "POST" ]; then
  read text
  echo "$text" | sed -f www.sed > $dir/$page
fi

if [ -f $dir/$page ]; then
  body=`cat $dir/$page`
else
  body='This is new page.
Please write body and push the save button.'
fi

title=`echo "$page" | sed 's/_/ /g'`

cat<<EOF
Content-Type: text/html

<TITLE>$title - Wiki</TITLE>
<H1>$title</H1>
<HR>
<H2>CONTENT:</H2>
<PRE>
$body
</PRE>
<HR>
<H2>EDITOR:</H2>
<FORM action=wiki.sh?$page method=post>
<TEXTAREA cols=60 rows=7 name=text>$body</TEXTAREA>
<INPUT type=submit value=SAVE></FORM>
EOF

cat<<EOF
<HR>
<H2>PAGE LIST:</H2>
EOF

for item in `ls $dir`;
do
  echo "<dt><a href=wiki.sh?$item>" $item "</a>"
done

echo "<HR>"
echo "my wiki system by dyama &lt;dyama@member.fsf.org&gt;"

www.sed

URL文字列デコード用 sed ファイル。

#!/bin/sed

s/^text=//
s/+/ /g

s/%0D%0A/\n/g
s/%0A/\n/g
s/%0D/\n/g

s/%21/!/g
s/%3F/?/g
s/%2B/+/g
s/%3D/=/g
s/%7C/|/g
s/%23/#/g
s/%24/$/g
s/%5E/^/g
s/%26/\&/g
s/%28/(/g
s/%29/)/g
s/%5C/\\/g
s/%60/`/g
s/%7E/~/g
s/%5B/[/g
s/%5D/]/g
s/%7B/{/g
s/%7D/}/g
s/%3B/;/g
s/%27/'/g
s/%3A/:/g
s/%22/"/g
s/%3C/</g
s/%3E/>/g
s/%2C/,/g
s/%2F/\//g
s/%09/\t/g

s/%25/%/g

wiki.sh に +rx して、ページ保存用のディレクトリ「./p」を 777 で作成し、wiki.sh にアクセスすると次のように表示されます。

wiki

新規ページを作成するには、URL文字列に?pagenameをつけてアクセスします。wiki.sh の URL がhttp://localhost/wiki.shの場合、http://localhost/wiki.sh?pagenameになります。 ページの削除機能はないので、端末からログインして、ディレクトリ p 以下の対象ファイルを削除すればOKです。

また、SVN などに噛ませてページの更新時毎にディレクトリ p 以下をコミットしてやれば、ヒストリー機能も実現できそうです。楽チンですね。

タミヤ ウォーターラインシリーズ 1/700 駆逐艦 吹雪

数年前に椎間板ヘルニアになってずっと腰痛持ちだったのですが、ここ数日、ひどくなっていて困っています。 椎間板(背骨)の背中側が圧迫されて軟骨がはみ出てて、それが神経を圧迫して腰痛と足のしびれが来ているようです。 なので、ここのところ背中を丸めた猫背状態が一番楽な姿勢になっています。

だからと言うワケでもないのですが、ここ数日、数年ぶりにプラモデルを作っています。全体作ったのは人工衛星はやぶさが地球に機関した後の「はやぶさ」。その前は子供の頃、という状態なのでほとんど素人なのですが、素人なりに作っていて楽しいです。

さて、「艦これ」ブームもあいまってか艦船模型が売れているのは良い傾向です。休日に「西海模型」さんに行くと、店内では大柄なアメリカ海兵たちが独戦艦「ビスマルク」の模型を手にとって何やら話していました。その日は昼と夕方の二度、店に訪ずれたんですが、どちらとも別の海兵たちがいました。こういう光景が日常的なのは、佐世保っていう土地柄なのかもしれません。

今年の2月に亡くなった祖父は、潜水母艦「長鯨」に乗った後、航空母艦「隼鷹」のケップガンをしていて、終戦後、駆逐艦「楠」の副長として幅員作業に従事していたようです。 「隼鷹」は空母として有名だったので、タミヤの1/700を箱のまま持っていましたが、たまたまピットロードの「長鯨」を見つけたので買ってしまいました。この二つはちゃんと作ってみたいのでとりあえずキープということで、練習台としてタミヤの駆逐艦「吹雪」と駆逐艦「桜」を購入。

吹雪「私がやっつけちゃうんだから!」

あんまり気合を入れて作ろうとすると挫折しそうだったので、早速「吹雪」から気軽に作り始めることにしました。 この記事を書いている段階で、装載艇の設置以外はほとんど済ませました。

IJN Destroyer Fubuki 大きいサイズ IJN Destroyer Fubuki 大きいサイズ

自分レベルですので、素組みするだけでも一苦労…。他の人は水偵のフロートとか、どうやって垂直に接着してるんだろうなあ。

  • Mr.Colorのスプレーを使用。スプレーを吹いているくせにムラがはんぱない。塗り直し時した挙句、かなり近くから噴霧したのが原因か…。
  • 細かなところは瞬間接着剤を利用するも、垂らす量がコントロールできずにびしゃびしゃに。
  • 煙突の白ラインなど、一応マスキングしているけれど全体的に雑。主砲の付け値もマスキングすべきだった。
  • 鉄ヤスリじゃなくて紙ヤスリを買ってきて、もっと丁寧にヤスリをかけなければ。

ウェザリング用の塗料も準備しているものの、先が不安で波高しです。あとは装載艇を積んで、クリア吹いて、気持ちばかり空中線をつけて(萎えないうちに)完成までこぎつけたいところです。 練習なのでツッコミを入れていたらキリがないのですが、実際に組んでみて分かったことがあるので、それだけでも儲けということで納得しようと思います。

ちなみに、同じモデルでもこんなに素晴しい感じに作られる人もいます! いいな〜!自分もガンバロウ。

mruby で自作クラスをごにょごにょする

siren では、mruby を組み込んでコマンドドリブンなインタプリタを実装していたので、クラスをまともに使っていませんでしたが、コマンドが多くなるにつれ管理が煩雑になった事や、Ruby のクラスとして強力な機能を実装する目的もあり、改めて mruby のクラスまわりの実装を調べてみました。

C コード上で Ruby クラスを作成

クラスの新規作成

mrb_define_class() を使います。引数は mrb_state*, クラス名, 親クラス。

RClass* prclass = mrb_define_class(mrb, "Myclass", mrb->object_class);

RClass*が返ってきます。C コード中では、このポインタでクラスを指定します。

クラスにメソッドを突っ込む

新規作成したクラス Myclass の中身は空っぽなので、メソッドを突っ込んでみます。

mrb_define_method(mrb, prclass, "myfunc", myfunc, ARGS_NONE());

引数は mrb_state*, ターゲットとなるクラスの RClass*, メソッド名, 実体のC関数, 引数定義です。 RClass* を mrb->kernel_module にすると、Kernel 名前空間に入ってグローバル関数のように使えます。

引数定義

ARGS_NONE() ... 引数なし
MRB_ARGS_REQ(2) | MRB_ARGS_OPT(1) ... 必須引数が2個、省略可能引数が1個

実体の関数

インターフェイスは、戻り値と引数の型に注意するだけでOKです。

mrb_value myfunc(mrb_state* mrb, mrb_value self)
{ 
    mrb_int a;
    mrb_int b;
    int argc = mrb_get_args(mrb, "ii", &a, &b);

    return mrb_fixnum_value(a + b);
}

引数は mrb_get_args() で取得します。

定義済みのクラスを文字列から取得する

名前が分かっているなら RClass* を保持しておく必要はありません。

RClass* prclass2 = mrb_class_get(mrb, "Myclass");

クラスのインスタンス変数を設定・取得する

mrb_obj_iv_set() と mrb_obj_iv_get() を使用します。

RClass* my_class = mrb_define_class(mrb, "Test", mrb->object_class);
mrb_value obj = mrb_class_new_instance(mrb, 0, NULL, my_class);

RObject* pobj = mrb_obj_ptr(obj);
mrb_sym sym = mrb_intern(mrb, "asdf", strlen("asdf"));
mrb_obj_iv_set(mrb, pobj, sym, mrb_fixnum_value(1244));

return mrb_obj_iv_get(mrb, pobj, sym);

クラスからインスタンスを作成

定義したクラスからインスタンスを作成するには mrb_class_new_instance() を使うようです。 引数は mrb_state*, コンストラクタの引数の数、引数、RClass* です。

mrb_value obj = mrb_class_new_instance(mrb, 0, NULL, prclass2);

引数がない場合、0, NULL で良いみたいです。引数は

mrb_value args[3];
args[0] = mrb_fixnum_value(123);
args[1] = mrb_float_value(mrb, 10.4);
args[2] = mrb_nil_value();

のようにこしらえます。

メソッドの削除

コーディングして試してみていませんが、mruby.h に

void mrb_undef_class_method(mrb_state*, struct RClass*, const char*);

がありました。

メソッドを実行する

mrb_funcall(), mrb_funcall_argv(), mrb_funcall_with_block() の3種類が mruby.h に定義されています。

mrb_funcall(mrb, obj, "myfunc", 0);

Ruby スクリプトとして書いたクラスを C プログラムに組み込む

C コードで動的に Ruby のクラスを作れるのは便利なんですが、動的に生成する必要もないものは、普通の Ruby スクリプトとして書いたりデバッグしたりする方が効率的です。

mruby をビルドすると bin ディレクトリに生成される mrbc を使うと、Ruby のスクリプトファイルをバイトコードに変換し、C の配列として扱える C ソースコードファイルに変換してくれます。

Ruby スクリプトから C ソースコードへ変換

次のような内容の vector.rb を準備します。

class Vector
  attr_accessor :x, :y, :z
end

mrbc を使ってコンパイルします。

mrbc -BVector -ovector.c vector.rb
# -B<バイトコード配列名> -o<出力ファイル名> <入力ファイル名>

次のような内容の vector.c が生成されます。

#include <stdint.h>
const uint8_t Vector[] = {
0x52,0x49,0x54,0x45,0x30,0x30,0x30,0x32,0xe8,0xe5,0x00,0x00,0x00,0xa7,0x4d,0x41,
0x54,0x5a,0x30,0x30,0x30,0x30,0x49,0x52,0x45,0x50,0x00,0x00,0x00,0x89,0x30,0x30,
0x30,0x30,0x00,0x00,0x00,0x33,0x00,0x01,0x00,0x03,0x00,0x01,0x00,0x00,0x00,0x05,
0x00,0x80,0x00,0x05,0x01,0x00,0x00,0x05,0x00,0x80,0x00,0x43,0x00,0x80,0x00,0x45,
0x00,0x00,0x00,0x4a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x06,0x56,0x65,
0x63,0x74,0x6f,0x72,0x00,0x00,0x00,0x00,0x4a,0x00,0x01,0x00,0x06,0x00,0x00,0x00,
0x00,0x00,0x06,0x00,0x80,0x00,0x06,0x01,0x00,0x00,0x84,0x01,0x80,0x01,0x04,0x02,
0x00,0x01,0x84,0x00,0x80,0x01,0xa0,0x00,0x80,0x00,0x29,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x04,0x00,0x0d,0x61,0x74,0x74,0x72,0x5f,0x61,0x63,0x63,0x65,0x73,0x73,
0x6f,0x72,0x00,0x00,0x01,0x78,0x00,0x00,0x01,0x79,0x00,0x00,0x01,0x7a,0x00,0x45,
0x4e,0x44,0x00,0x00,0x00,0x00,0x08,
};

アプリケーションをビルドするたびに変換するのもなんですので、ここまでの手順を Makefile なんかに書いておけば良いでしょう。

バイトコード配列を使う

アプリケーションの Makefile やプロジェクト設定で vector.c をビルド対象にして、このバイトコード配列を使っていきます。vector.c は、スクリプト側に変更をかけるたびに上書きで済ませたいので、使うコードは別のファイルがいいでしょう。

別ファイルにて

extern const uint8_t Vector[];

しておくと安心です。

実際の使い方はかなり簡単で、

mrb_load_irep(mrb, Vector);

だけでバイトコードが mrb_state* 空間にロードされます。 あとは、前述のとおり

RClass* prclass = mrb_class_get(mrb, "Vector");

という具合に、名前文字列から RClass* を取得できます。

オマケ

クラスとは関係ありませんが、随所に仕込んでおきたい例外とエラーの表現。

未実装例外

return mrb_exc_new(mrb, E_NOTIMP_ERROR, NULL, 0);

引数エラー例外(メッセージ付)

static const char m[] = "No such specified object.";
return mrb_exc_new(mrb, E_ARGUMENT_ERROR, m, sizeof(m) - 1);

今のところ分かってないこと

new したインスタンスを mrb_state 空間から動的に取得してくる方法が分かりません。インスタンスを取得するにしても、C コード側からは結局は RObject のポインタとしてしか表現されない(名前文字列みたいな「ラベル」もないですし)ので、後から使いたいオブジェクトはどこかにポインタを覚えさせておく必要があるのかもと予想してます。
あんまりよくコードを読んでませんが mrb_state の宣言に RObject* メンバがぶらさがっているんですが、このあたりが実体なのかも。

さようなら Ubuntu、こんにちは Linux Mint

ここ5年ほどメイン機で使っていた Ubuntu にとうとう別れを告げました。 Ubuntu の採用を辞める理由として挙げるとすれば以下の点です。

重い?

ハードウェアは 2012 年の暮れに SONY の公式オンラインストアで購入した VAIO Z で、Core i7 の 8GB RAM、SSD 搭載機です。 購入から1年半が経ちますが、まだまだ陳腐化していないスペックだと思います。グラフィックはインテルのHDグラフィックス…とオンボードのものですが、一昔前の安物グラボに比べれば、よっぽど安定していて高速なハズです。

なので、特に処理能力の限界を感じていたわけではありませんでした。もちろん、無駄に○○しているな〜と感じる点はありましたが、ハードウェア的なボトルネックが顕著になる以前に、私の自宅の WiFi の不安定さであったり、ファイル置き場になっている自宅サーバーのスペック不足でひっかかったりしていました。

Unity デスクトップ環境な Ubuntu 自体は大手ディストリの中でもかなり「重い」部類ではあると思いますが、そんなに苦になることはなかったと思います。

Unity まわりのUI設計のマズさ

動作の軽快さよりも、こちらの方がネックでした。使い勝手が悪いと悪評の高い Unity をやめようと思い、Classic デスクトップ環境に切り替えていた時期もありましたが、やはりしっくり来ず。 特に問題だったのが、タスクバーとメインメニューの統合です。これは登場した当初から叩かれていたので今更詳しく書くのもアレですので、要点だけを書いておきます。

  • 広いデスクトップ上でウィンドウ表示していると、左上のタスクバーにメインメニューがあると、その持ち主であるウィンドウから遠い。これは Mac なんかもそうかな?
  • GIMP などの複数ウィンドウで構成されているアプリケーションの場合、メインウィンドウがアクティブじゃないとメインメニューが表示されなくてかなり困る。つまりツールウィンドウを選択している時にタスクバーにカーソルを持っていっても、期待したメニュー項目がないんですよ。
  • タスクバーにマウス・ホバーさせないとメニューが表示されない。メニューが常に表示されていればマウスをダイレクトにポインティングできますが、一度タスクバーに盲目状態でカーソルを持っていく→表示される→改めて目的のメニュー項目までカーソルを持っていく、のパターンになって、マウス操作主体のアプリケーションだと軽く死ねます。

もともと、「ウィンドウごとにタイトルバーの下にメニュー領域を確保するのがスペース的な無駄だ」という発想だったのか、Mac の UI を真似したのか分かりませんが、使いづらく感じる人のほうが多そうですよね。前者の理由だった場合、Unity デスクトップ環境の左側に表示されているアプリケーションアイコンのほうがよっぽど邪魔です。自動的に隠すこともできますが、それでもアイコンサイズの設定できる最小値が大きすぎます。 最近のディスプレイは、ほとんどがワイド画面であるため、縦方向に領域を占有するメインメニューよりも、横方向に領域を占有するアプリケーションアイコンの方が犠牲になるコストは小さいかもしれませんが、なんだかよく分かりません。また、タブレット PC やスマホなど、タッチ操作をしなければならない端末でも、標準のマウス環境でも、どちらでも対応できるような UI 設計にしている戦略的な意味合いがありそうな気がします。どちらでも対応、と書くと聞こえが良いですが、言い替えると、どちらも中途半端ってことでしょう。こういうデザインのごり押しを見ていると、もはや商売戦略ありきの設計である Windows と何も変わらない気がします。

しかし非標準を許さない

Linux なんかの良いところは、自分の好きな環境を自分で組み合わせて最適なモノに囲まれてコンピュータ・ライフを楽しめるところだと思うんですが、ここまで時代が変わってくると、いろんなフレームワークやらライブラリやら、それを動かすためのフレームワークやら、ちょっとした事でもバックエンドの巨大なものをずるずるとひっぱってきたり、そうしているうちに整合性が取れなくなって、ちょっとした事でも意図したとおりの事ができなくなっちゃったりと、もう訳が分からなくなる事も多いです。

Ubuntu はその良い例で、標準的な考え方と Ubuntu 独自の考え方の相性が悪い印象です。ちょっとしたカスタマイズを施して使っていると、次のメジャーアップデートの際に決まって不整合となってしまい、面倒なことが発生していました。ユーザーに自由という権限を与えない変わりに、ある程度責任を持って「ユーザーが何も考えなくても快適な環境が提供されるシステム」だったら良いのですが、そこまで力及ばず、といったところでしょうかね。

カノニカルが以前、「我々のライバルは Windows ではなく、Mac OS だ。」と宣言していた気がしますが、UNIX を Mac OS にしちゃった Apple と カノニカルの大きな違いは、やっぱり力の強さ(資本や行動力)じゃないでしょうか。UNIX 系 OS でいわゆる非 UNIX ユーザも幸せになれるような環境を提供するには、Mac OS や Android といった、もはや UNIX 系とは思えないくらいの商業的かつパーソナルユーザ視点での作り込み、あるいは作り替えが必要になるんじゃないかなと。

まあ、Ubuntu コミュニティやカノニカルも含め、パーソナルユースの Linux、UNIX 環境に大きく貢献しているのは大きな事実ですので、感謝していますし、これからも発展して欲しいと思っています。

細かいところ

Nautilus が 0 バイトの画像や動画のサムネイルを生成する時にすとんと落ちてしまいます。これは致命的に痛いです。totemか何かでサムネイルを生成しているっぽいですが、Nautilus の設定等々をいじるよりも thunar に切り替えて使うケースが多かったです。また、thunar では、SSHFS でマウントしているネットワークストレージも、動画サムネイルを生成しつつもそこそこ素早くファイル一覧を表示できていたのですが、Nautilus では時間がかかった上にタイムアウトするケースも多く見られました。

うちの環境も原因の一つかもしれませんが、ファイラを替えただけでストレスなくオペレーションができている以上、Nautilus の挙動に問題があるような気もします。

これだけ不安定かつぽこぽこと強制終了していたらネモ船長もたまったもんじゃないです。

Linux Mint

Ubuntu の「かゆいところ」はまだ他にもいろいろありますが、Ubuntu の良いところを引き継ぎつつ、悪いところを排除する目標を掲げている Linux Mint に興味を持ちました。

WiFi の設定

まずはともあれ、ネットにつながってないと困ります。最近の先進的なディストリでは、デフォルトで WiFi が有効になっているので嬉しい限りです。自宅のアクセスポイントを選んでパスワードを入れるだけで繋りました。

Firefox syncの同期

次に、ウェブで情報を得たり、動画を見たりしながらセットアップをするので Firefox syncを同期します。自宅、職場、スマホと同期できるってのは本当に助かりますね。

(2014/5/15追記・最新の Firefox では sync の認証方式が変更されたようです。端末によって新方式と旧方式を同時に運用することはできず、全て新しい Firefox にアップデートして新方式にしないと同期が出来ない模様…。Windows 以外のマシンではしっかりしたバージョン管理システムの自動アプデに任せているから色々面倒だなぁ。
ちなみに、Bluetooth のハードウェア認証のような旧方式は、リカバリーキーやらペアコードやら意味が分からないものが多く、どちらがマスターデータでどちらがスレーブなのか分かりづらかったので、予想していたとおり大不評だったんでしょう。
今回の一般的なアカウントによるサーバ認証方式が採用理由は分かりますが、一度同期して運用しちゃってる設定をバージョンアップで変更しなければならないのは労力ですね)

また、宗教上の理由により検索バーのデフォルトは DuckDuckGo っていうアヒルになっていますが、

http://www.linuxmint.com/searchengines.php

の下部にある「Commercial engines(営利目的の検索エンジン)」の Google のアイコンをクリック後、検索バーのアイコンをクリックして出てくるプルダウンメニューより「”Google”を追加」をクリックすれば追加することができます。
さらに「検索バーの管理…」から Google の優先度を上げてやれば、晴れて Google に監視されっぱなし状態になれます。

Ctrl キーと Caps Lock キーの入れ替え

システム設定の「地域と言語の設定」より、キーボードレイアウト→オプションから変更しました。
Xの設定ファイルをいじって、いじっている途中に Caps Lockを押してしまってイライラしていた時代が懐しい…(でも、もはやGUIなしじゃすぐに設定できない体になってしまいそうです)

ちなみにうちは、日本語環境、日本時刻、英語配列キーボードっていう環境です。

uim と skk の導入

Mint にはデフォルトで日本語 IM が入ってないらしいんですが、SKK 使いの自分としては 使いもしない Anthy などが入っているより好都合です。

sudo aptitude install uim uim-gtk3 uim-skk

としてサクっと入れます。
一度、ログアウトしてセッションを開始し直せば、C-j で日本語入力ができるようになりました。

sshfs の導入

以前のファイルは、別のサーバーマシンに預けているので、sshfs を導入。

sudo aptitude install sshfs

で、一般権限でも fuse できるようにします。

sudo chmod o+rw /dev/fuse
sudo chmod 4755 /bin/fusermount

これでマウント可能になりました。簡単すぎる…!

自分コマンドのパスを通す

HOMEの.ファイルを移す

Dropbox のセットアップ

$ mkdir ~/bin
$ wget -O ~/bin/dropbox.py http://www.dropbox.com/download?dl=packages/dropbox.py
$ chmod a+x ~/bin/dropbox.py
$ dropbox.py start -i

Skype

http://download.skype.com/linux/skype-debian_4.2.0.13-1_i386.deb

DraftSight

http://www.3ds.com/ja/products-services/draftsight/download-draftsight/

libgtk2.0-0:i386
/opt/dassault-systemes/DraftSight/Linux/DraftSight
/opt/dassault-systemes/DraftSight/Linux/DraftSight: error while loading shared libraries: libGLU.so.1: cannot open shared object file: No such file or directory

$ sudo apt-file search libGLU.so.1
libglu1-mesa: /usr/lib/x86_64-linux-gnu/libGLU.so.1
libglu1-mesa: /usr/lib/x86_64-linux-gnu/libGLU.so.1.3.1

sudo aptitude install libglu1-mesa:i386

デスクレットの追加

「システム設定」の「デスクレット」より、デスクレットとよばれるウィジェットをデスクトップに追加できます。
Ubuntu では天気とカレンダーを表示していたのですが、カレンダーがなかったので AccuWeather Desklet だけを入れてみました。

Monodevelop

sudo aptitude install libmono-cairo2.0-cil

virtualbox

sudo aptitude install virtualbox-qt virtualbox-dkms 

gvim