Gjs on Visual Studio Code

Fedora 28 でプログラミング。

っても GTK+ の大幅な変更は二年毎になったので 29 までメンテのみ。
半年毎にゴロッと変わる GTK3 初期の頃は今考えると結構楽しかった。

OpenJDK は 1.8 のまま、1.9 から jjs が es6 完全対応なんだが。
Gjs はプロファイラがどうたららしいけど、正直どうでもいい。
Python3 も 3.6 のまま、つーことで何も変化無し。
変わらなすぎて面白くないのは筆者だけなのだろうか。

特に書くこともないので終わり、では悲しいので。
Visual Studio Code で gjs アプリ(comipoli)の F5 実行でも。
長いので以下 vscode と略。

書くまでもなく”ウザい!邪魔!迷惑!”のコード保管は全部無効に。
Visual Studio Code 2018 | PaePoi
現在は更に以下を追加。

// 拡張機能の推奨なんて超迷惑
"extensions.ignoreRecommendations": true,
"extensions.showRecommendationsOnlyOnDemand": true

vscode を起動しウエルカムページから開発したいアプリのディレクトリを開く。
キーボードショートカットの設定を開く。
F5 で検索して Node.js の debug 実行のキーを Delete キーで殺す。
Node.js もやりたい人はデフォルトのキーにしてね、筆者はやらん。

.vscode/tasks.json は以下のように。

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "Start Comipoli",
            "type": "shell",
            "command": "gjs",
            "args": [
                "./comipoli"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "presentation": {
                "focus": true,
                "reveal": "always",
                "panel": "new"
            }
        }
    ]
}


こうしておけば部品ファイルを開いている状態でも実行できて便利。
下に出るコンソールから Ctrl+C で強制終了もできる。
終了したら何かキーを叩けばコンソールは終了してくれる。

後はスニペットをガシガシ登録。
Ctrl+Space を先に打ち込む必要があるのがメンドイぞ!

{
	 "_connect": {
		"prefix": "con",
		"body": [
			"${1:Widget}.connect(\"${2:SignalName}\", ($3)=> {",
            "    $0",
            "});"
		],
		"description": "connect"
	},
	"_imports": {
		"prefix": "imp",
		"body": [
			"const ${1:GLib} = imports.gi.${1};$0"
		],
		"description": "imports"
	}
}

って。
おいおい Gedit より便利じゃなったじゃないか!
シェルスクリプトだけで拡張できる Gedit よりはるかに面倒だが。

でも vscode って思いっきり拡張子依存なのよね。
拡張子が無いファイルを扱うことが多い Linux ではチト困る。
それを補う Gedit のモードラインが再現できればなぁって感じ。

Fedora 28 Upgrade p2

前回書いた Gedit の不具合の軒。
Gedit だけでなく GTK3 全体の GtkEntry, GtkTextView 全部だった。
具体的には。

まず日本語を打ち込み変換する。
そのまま Enter にて確定させずに次の文字を打つ。
今まではそのまま確定されて次の文字が普通に打ち込めた。
Fedora 28 では最初のキーが確定扱いになりそのキーは無かったことになる。
結果、子音が無い状態になるのでボインだらけに

これが Wayland かつ GTK3 アプリでしか起こらないっぽいからややこしい。

Nautilus で Ctrl+l を叩いて試しても同様になると確認できる。
Electron の Visual Studio Code なら問題無かったのはそういうことね。
GTK2 の goodle-chrome のアドレスバーも問題無いね。

症状は解ったけど、どうすりゃいいんだ?
ibus は関係ないみたいだし、うーん。。。。。

ところで。。。。。
Fedora 28 は絵文字の挿入に Ctrl+Shift+e が割り付けされてしまった。
筆者の公開プラグイン html_escape と被る、変更しなきゃ。

ついでに、以前 blog で書いた repert_line だけど
“<Alt><Shift>Down” は駄目だが “<Alt><Super>Down” なら使えるようだ。
こっちのほうが直感的だからコレをデフォルトにしよう。

ということで更新しました。
Gedit 及び Eye of Gnome プラグイン – L’Isola di Niente

それに伴って。
VSCode Linux 版の行コピーデフォルトは Ctrl+Alt+Shift+Down だ。
これは下の仮想デスクトップに移動という GNOME のキーと被る。
Alt+Shift+Down はカーソルコピーという使いそうもない機能なので削除。
コイツを行コピーに割り付けして、よし macOS 版と同じにしたぞと。

今回はヤルこといっぱいあるなぁ。

Fedora 28 Upgrade

Fedora の更新通知が来た。

What’s New in Fedora 28 Workstation – Fedora Magazine

Google Chrome 等のリポジトリが最初から登録されているってことかな?
VirtualBox Guest Additions が最初から入っているということらしい。
Shotwell という古臭い UI のアプリは御役御免になったようだ。
筆者的にはどうでもいい、今回はあまり魅力を感じないな。

普通に gnome-softwere を立ち上げ更新ボタンをクリック。
「更新をダウンロードしています…」でしばし、いやかなり待たされる。
何をやっているかは GUI ではよく解らないな、んでソレが終わると。

この画面になる、[ダウンロード(D)] ボタンをクリック。
これで巨大な本体が落とされる、macOS と比べればカワイイものだが。
ダウンロードが終わるとボタンが [インストール(I)] に変わるのでクリック。
パスワードお打ち込んで、後は全自動なのでスマホゲームでもやって待つ。

再起動で何故か壁紙が白紙に、設定でデフォルトらしきものを割り当て。
それ以外は全部引き継ぎされたようだ。

んと、NVidia ドライバー等は RPM Fusion のサブセットなのか。
google-chrome を勝手に無効にしないでくれよ。
unitedrpms リポジトリは残っている。

Gedit がついに 3.28 にアップグレード!
って Wayland で Ctrl+F9 が使えないままなんですけど。
それよりキーの認識に失敗するのかコレを書いてて母音だらけになるんだが。
Visual Studio Code では問題ないので完全に Gedit がおかしい。

試しに X.org でログインすると問題なくなる、再起動も意味無し。
キーボードを打つのが遅い人なら気にならないと思うけど。

ということでここからは Visual Studio Code で書くことに。
とうとう乗り換えなのかな?モードラインさえ完全に再現してくれればだけど。

GNOME 3.28 Release Notes

GNOME については上記のとおり、Star は macOS の機能とだいたい同じっぽい。
筆者は IconView しか使わないけど、使い道があるならってことで。
Nautilus のタブをドラッグして新しいウインドウに分割ができなくなっているんですが。。。
Shift+Delete で完全削除が何故か無効にされていたので再設定。

前回の更新で唖然とした dconf-editor はまともな UI になった。
org.gnome.desktop.background show-desktop-icons
のキーは残っているけど有効にしても無視されるだけのようだ。
デスクトップにファイルは置けなくなったけど筆者はそもそも無効で使っているし。
てか Tips ページを書き換えしなきゃ。

GNOME Photos がデフォルトで入っていないんですけど?
evince や eog も 3.28 になっているけど違いが解らない。
GNOME MPV, KeePassX, VidCutter 等筆者が他に使っているアプリは問題無し。
自作の Comipoli, Y901x も問題無し、Gedit 以外は普通に使える。

Gedit 以外のエディタを使っていない人はしばらく待ったほうがいいかも。
古い X.org でログインすればいいけど今更って感じだしね。
プログラミング関連は後日。

おまけ。

Ubuntu 18.04 LTSインストール後にすべきこと | マイナビニュース

サルブンツって海外ユーザーまで超後ろ向きで唖然。
大人しく Windows7 でも使っていればいいのにって感じ。

JXA: Image Resize and Save

今回は JXA にて画像のリサイズと保存。

(旧) Cocoaの日々: キャプチャ画像を縮小して保存する

Cocoa は他の OS のグラフィック(デバイス)コンテキストと違っていて
現在フォーカスがあるグラフィックコンテキストに描写する、という手法。
つまり NSImage に NSImage をリサイズして描写するってことみたい。

各画像フォーマットのデータを作成する

NSDictionary を作るのが面倒だなぁ。
変換で楽したいし NSImageCompressionFactor は調べると NSString だし。
ってことで。

ObjC.import("Cocoa");

console.log($.NSImageCompressionFactor.js);
//=> NSImageCompressionFactor

まんまカヨ!

クオリティは 1.0 が最高値みたい
筆者はいつものように GIMP に合わせて 0.85 にしてみる。
ということでこんなコードになりました。

#!/usr/bin/osascript

ObjC.import("Cocoa");

function run(argv) {
    let srcImage = $.NSImage.alloc.initWithContentsOfFile(argv[0]);
    // Create 300x200 Image
    let newImage = $.NSImage.alloc.initWithSize($.NSMakeSize(300, 200));
    newImage.lockFocus;
    $.NSGraphicsContext.saveGraphicsState;
    $.NSGraphicsContext.currentContext.setImageInterpolation($.NSImageInterpolationHigh);
    srcImage.drawInRectFromRectOperationFraction(
        $.NSMakeRect(0, 0, 300, 200),
        $.NSZeroRect,
        $.NSCompositeSourceOver,
        1.0);
    $.NSGraphicsContext.restoreGraphicsState;
    newImage.unlockFocus;
    // JPEG Write;
    let bmp = $.NSBitmapImageRep.imageRepWithData(newImage.TIFFRepresentation);
    bmp.alpha = false;
    let prop = $({"NSImageCompressionFactor": 0.85});
    let data = bmp.representationUsingTypeProperties($.NSJPEGFileType, prop);
    data.writeToFileAtomically($(`${argv[0]}_300x200.jpg`), true);
}

prop の値を変更すると画像のサイズと画質が変わるのが確認できた。
これでサムネイル選択の作成に取りかかれる、最大の難関みたいな気がするけど。

JXA: NSApplication argv

JXA で osacompile にて app 化すると argv が仕事しない件。
NSProcessInfo を使うことで解決した。

function run(argv) {
    $.NSApplication.sharedApplication;
    const window = new MyWindow();
    $.NSApp.setActivationPolicy($.NSApplicationActivationPolicyRegular);
    ObjC.registerSubclass({
        name: "AppDelegate",
        protocols: ["NSApplicationDelegate"],
        methods: {
            "applicationDidFinishLaunching:": {
                types: ["void", ["id"]],
                implementation: (notification)=> {
                    let arr = $.NSProcessInfo.processInfo.arguments.js;
                    if (arr.length > 2) window.setPath(arr[2].js);
                }
            }
        }
    });
    //
    // etc..
    //
    // Not work after compiling
    //if (argv.length < 0) window.setPath(argv[0]);
    $.NSApp.delegate = $.AppDelegate.new;
    $.NSApp.run;
}

引数の数に注意。
[“osascript”, “src”, parm1, param2, …]

これで js のままでも app にコンパイルしても両方仕事する。
スクリプトのまま使うなら argv を使ったほうが簡単だけどね。

ところで前回の zipinfo の件だけど。
macOS の zip は -U オプションすら使えないじゃん。
パッチが当たっていないどころか UNICODE サポートですらないってことだ。
ということでこいつの出力からの変換は不可能であるようだ。

で、zipdetails という perl のコマンドを見つけた。
こいつの出力からなんとかならないかな?
かなり意地悪な zip ファイルを用意して試す。

改行が UNOCODE 未対応のようで化ける、駄目だ。
でも perl でできるということはスクリプトで得られるということだ。
バイナリを見ると、単純にファイル名は構造体にそのまんま入っているヤン。

って、だから JavaScript じゃバイナリは直接扱えないんだってばさ!
UInt8Array に変換すると超激遅なのは Gjs で経験済み。
Objective-c での手段も見つからない、みんな C でやっているの?

もう macOS 版は日本語アーカイブをサポートしない、で終わりにしよう。