Ubuntu で「変換」キーを Shift にする話 (xkb + dconf)
一月強の間日本を留守にしていたら、デスクトップの Ubuntu が起動しなくなっていた。
出発前から、フリーズが頻発していて、何かおかしかったので、覚悟はしていたが、思ったよりも復旧作業が大変で、ほぼ丸三日かけて、一昨日ようやく完了した。
その際、今まで xmodmap を用いて設定していたキーの再設定の挙動が不安定になったので、xkb をいじってみることにした。
そのメモ。
以下のサイトを参考にしました;
XKBの設定ファイルを直接編集してキーボードレイアウトをカスタマイズする - Qiita
An Unreliable Guide to XKB Configuration
なお、本記事は筆者の当時の環境を前提に書いている個人的なメモなので、他の環境でどうなのかは知りません。
万が一真似するとしても、自己責任でお願いします。
Ubuntu のバージョンだけ一応書いておくと、Ubuntu 16.04 です。
小手調べ:「Caps-Lock」を「左 Ctrl] にする
「変換」キーの話をする前に、簡単なものから。
「Caps-Lock」を「左 Ctrl」にするのは、得に何も考えずに、次のコマンドをたたけば良い:
$ dconf write /org/gnome/desktop/input-sources/xkb-options "['ctrl:nocaps']"
このコマンドは、dconf というものを通じて、xkb に「Caps-Lock」を「左 Ctrl」にせよ、というオプションをわたしてくれる。
自分は dconf の仕組みがよくわかっていないんだけれど、Windows でいうところのレジストリみたいなものらしい*1。
自分が知っている限りでは
- 設定ファイルは、(local なものは) $HOME/.config/dconf/user にある (system global なものは別の場所)
- 値はキーによって管理されている
- キーは階層構造の中に格納されている
これはバイナリファイルなので、直接は編集できないのだが、それを編集するためのコマンドラインツールが dconf といいうこと。
他にも gsettings でも設定できるが、違いがよくわからない。
また、dconf-editor という GUI ツールもあって、これは以下のコマンドでインストールできる (Ubuntu 16.04 の場合):
$ sudo apt install dconf-editor
新たにレポジトリとかを追加しなくてよいのが非常に好ましい。
こちらを使うと、階層構造がより直感的に理解できるようになる。
例えば、上で dconf を用いて行った設定は、dconf-editor では、ツリーを org→gnome→desktop→input-sources と辿ると、「xkb-options」というキーが見つかるので、それをダブルクリックして編集することでもできる。
なお、これらの設定は、dconf に頼らなくても X の設定を直接いじってもできる。
ただ、こうしてしまうと Gnome とか Unity とかの設定と競合するかも知れないと思い、今回は dconf 経由で xkb を設定する方法を考えることにする。
xkb-options に書けるもの
さて、dconf の中にあるキー「xkb-options」に書けるオプションは、勿論 xkb が認識するものでなければならない。
その一覧を知るためには、xkb の現在の設定を見ることがヒントになる:
$ setxkbmap -print -verbose 10 Setting verbose level to 10 locale is C Trying to load rules file ./rules/evdev... Trying to load rules file /usr/share/X11/xkb/rules/evdev... Success. Applied rules from evdev: rules: evdev model: pc105 layout: jp,us variant: , options: ctrl:nocaps, Trying to build keymap using the following components: keycodes: evdev+aliases(qwerty) types: complete compat: complete symbols: pc+jp+us:2+inet(evdev)+ctrl(nocaps)+jphenk(rshift)+jpmuhen(lshift) geometry: pc(pc105) xkb_keymap { xkb_keycodes { include "evdev+aliases(qwerty)" }; xkb_types { include "complete" }; xkb_compat { include "complete" }; xkb_symbols { include "pc+jp+us:2+inet(evdev)+ctrl(nocaps)" }; xkb_geometry { include "pc(pc105)" }; };
「options」に上で設定した「ctrl:nocaps」が確認できるのと、xkb_keymap の xkb_symbols の末尾に「ctrl(nocaps)」も確認できる。
参考文献によると、これらの値は /usr/share/X11/xkb/rules/evdev というファイルの記述に則って設定される:
$ cat /usr/share/X11/xkb/rules/evdev ... ! option = symbols ... caps:ctrl_modifier = +capslock(ctrl_modifier) ctrl:nocaps = +ctrl(nocaps) ctrl:lctrl_meta = +ctrl(lctrl_meta) ...
直感的には、「ctrl:nocaps」というオプションが渡された時「xkb_symbols」に「ctrl(nocaps)」を加えなさい、というように読める。
では、この「ctrl(nocaps)」というものの実体がどこにあるかといえば、/usr/share/X11/xkb/symbols/ 以下のファイルに書かれているらしい。
例えば、このフォルダには「ctrl」というファイルがあり、それは以下のようになっている:
// Eliminate CapsLock, making it another Ctrl. partial modifier_keys xkb_symbols "nocaps" { replace key <CAPS> { [ Control_L, Control_L ] }; modifier_map Control { <CAPS>, <LCTL> }; }; ...
ここまで来れば、xkb に渡すオプションを自分で追加する方法は何となく推測できる。
そうすれば、dconf を通じて好きなようにキー配置をいじれるじゃないか。
「変換」キーを「右 Shift」にする
それでは、設定ファイルを書くのだが、そもそも書式がわからない。
しかし、とりあえずはファイル「ctrl」とか「caps」とかを真似ておけばよかろう。
"<CAPS>" が「Caps-Lock」キーを表わしているようなので、「変換」キーを表わす記号を調べれば良い。
このあたりは、同フォルダに「jp」というファイルがあり、その中に以下の記述がある:
... key <NFER> { [ Muhenkan ] }; key <XFER> { type[Group1]="PC_ALT_LEVEL2", symbols[Group1]= [ Henkan, Mode_switch ] }; ...
また、「inet」というファイルにも次の記述がある:
... key <HKTG> { [ Hiragana_Katakana ] }; key <HENK> { [ Henkan ] }; key <MUHE> { [ Muhenkan ] }; ...
setxkbmap -print で見ると「inet」の方が後に読み込まれており、xkb は後に読んだ方を優先するので、ここでは "<HENK>" を採用。
ファイル /usr/share/X11/xkb/symbols/jphenk を作成して、以下を書き込む:
partial modifier_keys xkb_symbols "rshift" { replace key <HENK> { [ Shift_R, Shift_R ] }; modifier_map Shift { <HENK>, <RFSH> }; };
さらに、これを xkb に有効な設定であることを伝えるために、以下の二行を /usr/share/X11/xkb/rules/evdev の末尾に以下を追加*2
! option = symbols jphenk:rshift = +jphenk(rshift)
これで、xkb は「jphenk:rshift」をオプションとして認識してくれる。
$ dconf write /org/gnome/desktop/input-sources/xkb-options "['ctrl:nocaps', 'jphenk:rshift']"
まとめ
- オプションの一覧は、setxkbmap -print -verbose 10 とした時の rules の項にあるファイルにあり、そこに追加することで、自分でオプションを定義できる!
- オプションの実体は、/usr/share/X11/xkb/symbols/ 以下に適切な書式で記述する。
今回の試行錯誤の成果物を github に上げておきます。
https://github.com/Junology/dotfiles/tree/master/xkb
C++ まちがいさがし
デバッグ用に、初期化リストの中で出力を行える次のクラスを考える:
// cdebug.hpp #include <iostream> class CDebug { protected: int N; public: CDebug(int val) : N(val) { std::cout << val << std::endl; } void print() { std::cout << N << std::endl; } };
使ってみる。
テンプレート引数の値を表示するプログラム:
// main.cpp #include "cdebug.hpp" template <int N> class Test : public CDebug { public: Test() : CDebug(N) {} }; class Run { private: Test<10> test; public: Run() : test() {} }; int main(int argc, char *argv[]) { Run run; return 0; }
実行結果
$ g++ main.cpp $ ./a.out -1218330636
!!??
これに半日消費させられた... orz
Canon の ScanGear2 が落ちる
プリンタを新しくしたのだけれど、ドライバ付属のスキャンソフトである ScanGear2 が落ちる。
Ubuntu 12.04 で、最新版ではないのもいけないのだけれど。
ソースコードを見て、一箇所直したら動いたので、patch だけメモ。
--- canon_mfp_tools.c_old 2016-01-30 00:34:39.896069000 +0900 +++ canon_mfp_tools.c 2016-01-30 00:35:15.664070144 +0900 @@ -340,7 +340,7 @@ goto onErr; } /* search canon mfp */ - numdev = libusb_get_device_list(NULL, &g_devlist); + numdev = libusb_get_device_list(g_context, &g_devlist); if((int)numdev == 0) { err = CN_USB_WRITE_ERROR; goto onErr;
こんな適当な修正で直るものなんだな。
追記
上の修正だけだと、スキャンの時に落ちる。
もう一箇所修正が必要:
--- scanmain.c_old 2016-01-30 13:54:12.583522651 +0900 +++ scanmain.c 2016-01-30 13:54:17.171522588 +0900 @@ -298,7 +298,7 @@ int i; int ret = -1; int status; - char *buf; + char *buf = NULL; int errCode; int readBytes = 0; int result = CIJSC_SCANMAIN_SCAN_FINISHED;
ポインタはちゃんと初期化しましょう。
これ多分 gcc のバージョンによっては問題にならないんだろうけども。
それはそうと、ソースを見てみると、goto のオンパレードで、少なからず不安な気持ちにさせられた。
円周上の点を有理点で近似したかった
講義のレポートで、 で図を書く時に必要になったので、メモ。
の貧弱な数値計算環境では、sin, cos を気軽に計算することは、多大なコストを要する。
そこで、出来るだけ簡単な有理点で近似してやろうということになった。
アイデアは簡単で、三角関数の間の関係式を駆使すると、 とすると、次が成立する。
ここで、 なる有理数ならば、
となり、中々きれいな形になることが知られている。
の近似は、出来るだけ簡単な有理数になって欲しいので、Farey 列を用いる。
Farey 列については、Farey sequence - Wikipedia, the free encyclopedia を参照して下さい。
Haskell で書いてみる:
farey n = farey' n [(0,1),(1,1)] where farey' n (h:[]) = [h] farey' n ((a,b):t@((c,d):_)) = if b+d<= n then farey' n $ (a,b):(a+c,b+d):t else (a,b):farey' n t ratioapprox n x = rapprox x $ farey n where rapprox _ (y:[]) = y rapprox x (y:t@((r,s):_)) = if s*x<=r then near x y (r,s) else rapprox x t near a (b,c) (d,e) = case compare (a*c*e-b*e) (c*d-a*c*e) of LT -> (b,c) GT -> (d,e) EQ -> if (c <= e) then (b,c) else (d,e) ratiotriple n t = restriple where (p,q) = ratioapprox n $ tan (t/2) restriple = (q*q-p*p,2*p*q,p*p+q*q)
関数 ratiotriple は、精度 n と角度 t を受け取り、 に近くにある円周上の有理点に対応するピタゴラスの三数を返す。
精度というのは、 の近似値を出す時、分母をどれだけ大きく取るかの上限。
色々試してみるとわかるが、必ずしも結果の三数は互いに素でない。
つまり、非自明な約分で結果的に簡単な比になる場合を見落としている可能性はあるが、ご愛嬌。
ghci で動かすと以下のような結果に
*Main> ratiotriple 10 (pi/12) (63.0,16.0,65.0)
ちなみに
*Main> 180*atan (16/63)/pi 14.250032697803595
なので、まあ、運が悪くなければ悪くはない精度か。
(追記)
しかし、どうせハードコーディングにならざるを得ないので、10進展開でも問題無いということに気付いてしまった。
Haskell とか C++ のテンプレートに慣れ過ぎているせいで、コンパイラがこれ程計算を嫌がる処理系で、上手に息ができない病気になってしまっている。
面白かったから、記事自身は残しておきます。
圏論から逃げない2. 集合論的な像と普遍性
前回は、「部分集合」の概念を一般の圏に拡張した。
今回と次回では、「像」の一般化を試みる。
今回は特に、集合論的に定義された「像」が、圏 においてどのような圏論的性質を持つのかを調べる。
での像と、その universal property
過去にこんな記事を書いていた。
ここでの命題を少し整形すると、同様の証明で次の命題が示せる。
この命題 1は、写像の「像」が、圏 での universal property で特徴付けられることを示唆している。
そこで、もう少し命題 1を詳しく見てみる。
まず、 が条件式 を満たすとは、どういうことか。
となるような写像 の組は、次の集合の元として書ける:
ただし、 はどちらも である。
特に、colimit の定義を考えることで、これは次の集合 と同一視できる。
すると、 は、合成
による の像であり、同様に は
による の像である。
命題 1は、これらが一致する時、 が唯一存在して と分解することを主張している。
米田の補題より、米田埋め込み が fully faithful であることに注意すると、以上の議論より、次がわかる。
系 2
自然な入射 は、圏 においての次の同型を誘導する:
勿論系 2は、直接示すことができる。
また、上での議論からわかるように、系 2は命題 1と同じことを言っている。
しかし、集合論的な定義の「気持ち」を大事にしたかったので、上のような順序にした。
での像の双対と、その universal property
さて、通常の写像の像については前節の通りであるが、集合論的には、もう一つ「像」と呼べるものがある。
について、 を「 による値が同じ」ことによる同値関係で割った商集合を と書くことにする。
自然な全射を とし、 を が誘導する写像とすると、 は次のように分解する:
この分解に関して、命題 1の双対が成立する。
(証明)
とおくことで、自然な同一視 がある。
この時の に関する条件より、次が成立する:
従って の商集合としての定義より、 が唯一つ誘導され、 とできる。
(証明終わり)
「部分集合」と「特性関数」が互いに双対であるという考え方からすると、上の証明は、命題 1の証明の双対になっている。
命題 1の場合と同様な考察によって、 の圏論的な記述が求まる。
系 4
自然な全射 は、圏 において次の同型を誘導する:
以上のように、 は「像」の双対概念であると考えることができるので、 を の「余像」と呼ぶ。
これらを用いると、 は次のように分解する:
圏 においては、勿論 は全単射、すなわち同型であり、さらに は strict epimorphism、 は strict monomorphism である。
次回は、この分解を一般の圏で構成する。
圏論から逃げない1. 部分, 商
今まで漠然と知っていた、圏論における集合論のアナロジーをまとめる。
以下、を一般の圏とする。
部分集合と商集合
部分集合や商集合のアナロジーを考えるためには、包含写像や商写像の一般化を考えれば良い。
定義
を の subobject とする。
- の subobject とは、monomorphism の 上の同型類のこと.
- の quotient とは、epimorphism の 上の同型類のこと.
ここで、monomorphism と が 上同型であるとは、次の四角形が可換になるような同型 が存在すること:
ただし、「同型類」という概念がきちんと意味を持つかどうかは問わないことにする。
epimorphism と が 上で同型であることも、同様に定義する。
これらの定義は、モダンには次のように書ける。
の射を、monomorphism, epimorphism のみにした部分圏をそれぞれ と書く(この表記は Reedy category の場合の真似で、多分一般的でない)。
に対して、圏 , をそれぞれ slice category, coslice category によって定義する。
次の圏の同値に注意する:
命題 1
圏 , の 各 morphism set は、高々一点の集合である。
(証明)
上に挙げた同型より、 について示せば十分である。
slice category としての定義より、 の object は、 と monomorphism の組 である。
また、射 は、 の射(すなわち monomorphism) で となるものである。
今、 を の射とする。
すると、 であるが、 は monomorphism なので を得る。
これが示すべきことであった。
(証明終わり)
一般に圏 に対し、その同型類を と書く。
すると、subobject は の元であるということができる。
quotient についても同様である。
上の命題より、これらはさらに豊かな構造を持つ。
系 2
subobject 全体のなすクラス 及び quotient 全体のなすクラス には、自然に半順序構造が誘導される。
Strict morphisms
純粋な集合や加群では、包含写像や商写像は単なる単射、全射であり、理念としては上の定義でも良さそうである。
しかし、上の定義では少し弱いところがあり、例えば monomorphism かつ epimorphism であっても、同型とは限らない。
また、位相空間のことを思い出すと、単射が必ずしも埋め込み写像とは限らないことに注意する。
このような、「埋め込み」の概念も、圏での議論に一般化できる。
議論を簡単にするため、 は pushout と pullback を持つ場合を考える。
この時、 には equalizer, coequalizer が常に存在することに注意する。
定義
は pushout, pullback を持つ圏とし、 を の射とする。
- が strict monomorphism であるとは、 がある の equalizer として書けることである。
- が strict epimorphism であるとは、 がある の coequalizer として書けることである。
勿論 strict monomorphism は monomorphism であり、strict epimorphism は epimorphism である。
例- の時、全ての単射、全射はそれぞれ strict monomorphism, strict epimorphism である。
- の時、 が strict monomorphism であることと、 が埋め込み写像であることと同値であり、 が埋め込みであれば、 は自然な全射 と定値写像とのイコライザーである。
- の時、 が strict epimorphism であることと、 が商写像であることは同値である。
- の時、 が strict monomorphism であることと、 が正規部分群の埋め込みであることは同値である(kernel は常に正規部分群であることに注意)。
- の時、全ての全射は strict epimorphism である。これは、準同型定理により が成立することによる。
これら例で挙げたように、strict monomorphism や strict epismorphism はそれぞれ包含写像、商写像と思って良い。
strict morphism によって、subobject, quotient のより強い概念が定義できる。
定義
とする。
- において、 で が strict monomorphism であるもの全体のなす full subcategory を と書く.
- の要素を strict subobject と呼ぶ.
- において、 で が strict epimorphism であるもの全体のなす full subcategory を と書く.
- の要素を strict quotient と呼ぶ.
定義からわかるように、圏同値 がある。
また、命題1より の morphism set も高々一点からなり、その同型類には順序構造が入る。
strict subobject, strict quotient は、ただの subobject, quotient よりも強い概念であり、集合論における「全射、単射」の類似がより良く成立する。
例えば、次が成立する。
命題 3
を の射とすると、次は同値
- は同型
- は strict monomorphism かつ epimorphism
- は monomorphism かつ strict epimorphism
(証明)
1⇔2 のみ示す(1⇔3 も同様)。
同型は の equalizer なので、1⇒2 は明らか。
今 は epimorphism であり、 の equalizer であると仮定する。
定義より だが、 は epimorphism なので、 を得る。
同一射の equalizer は同型なので、 は同型である。
(証明終わり)
環構造復習1:巡回群上の環構造
巡回群 に、 から誘導された自然な環構造が入ることは、環論を勉強し始めて、最初に学ぶこと。
ここで、アーベル群 上の環構造というのは、写像
で、分配則と結合則を満たすものである(加えて単位元 の存在を含める場合もある)。
今回は、特に が巡回群であった場合に、上のような がどれだけ存在するのかを調べる。
加法の構造は、 に始めから備わっているものと考えて、本記事では、環とは、組 のこととする。
を 上の積と呼ぶ。
また、 上のアーベル群の演算は で書くことにする。
前半で、単位元を仮定しない環構造について調べ、最後に、巡回群上では、単位元を持つ環構造は、ただ一つ( から誘導される自然なもの)しかないことを示す。
環構造の再定義 -分配則再考-
最初に、分配則をおさらいする。
が分配則を満たすとは、次の2式
を満たすことである。
今、 はアーベル群であり、 と に対して
と書くことにすると、上式より、さらに
を満たすこともわかる。
環論を経て、加群の理論に慣れた人なら、上2式を見て、すぐにテンソル積を連想するはず。
すなわち、分配則を満たす積 とは、実はアーベル群の準同型
に他ならない。
ただし、本記事では、 である。
こう思った時、 の結合則は、次の四角形が可換であるということと同値になる。
diagram 1 |
以上をまとめると、「環構造」は正確には次のように定義できる。
定義
アーベル群 上の環構造とは、アーベル群の準同型 であって、diagram 1 を可換にするものである。
この定義のもと、以下で具体的に巡回群上の環構造を決定する。
無限巡回群の環構造
と書くと紛らわしいので、環構造を仮定しない、ただの無限巡回群を と書き、 には自然な環構造を入れて、環であるとする。
また、 の生成元 を固定する。
前節の定義から、無限巡回群 上の環構造は容易に決定できる。
まず、準同型 はどれだけあるか。
アーベル群の圏における随伴(adjoint) に注意すると、次の同型がわかる。
ここで、一番右の同型は の合成による自然な環構造についての、環としての同型である。
この同型で、 に対応する準同型を とすると、 は次で与えられることは容易に確認できる。
for
また、各 に対して、任意の で
となり、この両者は等しい、すなわち、次の四角形は可換である。
diagram 2 |
よって、全ての について、 は 上の環構造である。
以上から、の議論をまとめることで、次の命題を得る。
命題 1
無限巡回群 上の環構造全体は、次の集合と一致する。
さて、環 とは何か。
実は次の同型が成立する。
命題 2
次の環の同型がある。
ただし、 は の部分環である。
(証明)
環同型写像は で与えられる。
まず、これがアーベル群の準同型であることが直ちにわかり、
有限巡回群の環構造
位数 の有限巡回群 上の環構造も、 での議論とほぼ平行に進む。
ただし、平行の議論にするために、少し議論を要する。
まず、 の生成元 に対し、 で定義される準同型 を と書いてしまうことにすると、次の完全列ができる。
この完全列を用いて、次が証明できる。
補題 3
はアーベル群であり、各元 の位数は の約数であるとする(従って )。
この時、自然な全射 は、次のアーベル群の同型を誘導する:
(証明)
右側の同型は明らかなので、左側の同型を示す。
の左完全性より、次は完全列である:
ここで、 に関する仮定より、準同型 は である。
このことと上の完全列より、次は完全列:
これより、求める同型を得る。
(証明終わり)
系 4
- as abelian groups.
これがわかれば、後の議論は の場合と完全に平行に進む。
系 4 より、次の同型が得られる。
ここで、右側の同型は環の同型である。
この同型において、 に対応する の元を とおくと、各 が の場合の と同様に、結合則を満たすことが確認できる。
従って、次の結果を得る。
命題 5
有限巡回群 の環構造全体は、次の集合と一致する。
単位元を持つ環構造
上で求めたものの中から、単位元を持つ環構造を探す。
まず、位数とは関係の無い議論から入る。
を一般に で生成される巡回群とする。
随伴同型によって であり、この同型をきちんと記述すると、 に対応する は次のように書ける:
さて、これより が単位元であるための条件を求める。
前節までで求めた環構造は、全て可換なものなので、左単位元の条件を求めれば良い。
が左単位元であるとは、任意の に対して であることである。
すなわち、 であり、このような が存在するためには、 の像が を含んでいなければならない。
は巡回群なので、 も で生成される巡回群であることに注意すると、 上の環構造 が左単位元を持つための必要十分条件は、 が全射であることである。