前回の記事でLinuxマシンを手に入れることになったわけだが、日付時刻まわりの表示がガバガバで萎えたのでなんとかする。
・拡張機能の敗北
GNOME Shellは拡張機能が豊富である。ちょっとググれば、トップバーの時刻表示フォーマットを自由に変更する拡張機能がゴロゴロ出てくる。
ところが、である。なぜかロック画面になるとこれらの拡張機能が全然効かないのである。
「「 日曜日, 8月 25 」」である。見てるだけで眩暈がする。生理的に無理な形式だ。英語圏なら "Sunday, August 25" で何も問題ないのだが、ここは日本なのでなんとかしなくてはいけない。
・諸悪の根源を探る
ここまでロック画面と呼んできた画面は正式には ScreenShield というらしい。調べた感じ結構不評っぽい。
GNOME ShellのGitHubで、この画面を制御しているgnome-shell/js/ui/screenShield.js
のソースコードを見ると、問題の箇所は73行目に見つけることができる。
let date = new Date();
/* Translators: This is a time format for a date in
long format */
let dateFormat = Shell.util_translate_time_string(N_("%A, %B %d")); //←ここ
this._date.text = date.toLocaleFormat(dateFormat);
ばっちりハードコーディングされている。どうして、日付のフォーマットとかいう割と柔軟性が要求される部分をハードコーディングしてしまったのか全く理解できないが、この部分をなんとかする拡張機能を作っていく。
・そもそも拡張機能はどうやって作るのか
詳しいことは公式Wikiの方に書いてあるので大雑把に説明すると、
- Javascriptで、
extension.js
に記述する extension.js
はinit
,enabled
,disabled
の3つの関数を含む必要があるinit
はGNOME Shell起動時に実行enabled
は拡張機能をオンにしたとき実行disabled
は拡張機能をオフにした時実行
さらにここで超・重要なポイントがあるのだが、画面をロックするとdisabled
が呼び出されるのである。つまりロック画面ではすべての拡張機能が強制的にオフになっているわけだ。ロック画面で拡張機能が効かなくなるのも当然である。しかし、裏を返せば、disabled
が何も実行しないようにしてしまえばロック画面でも拡張機能は有効なままにできる。決して推奨されるべき方法ではないが、こうでもしないと目的が達せないので仕方ない。必要悪と割り切って実装していく。
・実装
問題の箇所はClock
クラス内の_updateClock
関数内に記述されているので、Clock
クラスを継承したnewClock
クラスで_updateClock
をオーバーライドし、好みの表示形式でフォーマットする。結局ハードコーディングをハードコーディングで上書きしているだけだが、設定画面などを作り始めると面倒だし、自分用なので気にしないことにする。
const Shell=imports.gi.Shell;
const Shield=imports.ui.screenShield;
let oldClock=Shield.Clock;
let newClock;
function init() {
newClock= class extends Shield.Clock{
_updateClock(){
super._updateClock();
let date = new Date();
let dateFormat = Shell.util_translate_time_string(N_("%Y/%m/%d (%a)"));
this._date.text = date.toLocaleFormat(dateFormat);
}
}
}
function enabled(){
Shield.Clock=newClock;
}
function disabled(){
/* ここが実行されるようにすると
ロック画面で無効になる
Shield.Clock=oldClock;
*/
}
・結果
きわめて自然な形式で表示させることができた。
思ったより簡潔に実装できたので満足している。