set_accels_for_action

前回書いたように Y901x の ClutterGst 化をしているのですが。
マジで何を今更なことを見つけた。

GtkApplication: GTK+ 3 Reference Manual#gtk-application-add-accelerator

add_accelerator は 3.14 以降は使うなってさ。
おぃおぃ Gedit 標準プラグインが今でも普通に使っているんですけど。

とりあえず Gjs だとこんな感じでいいみたいみたい。
Gio.SimpleAction のほうは今までどおりでいい。
次回の更新で自作の奴も書き換えるか。

const Y901Application = new Lang.Class({
    Name: 'Y901Application',
    Extends: Gtk.Application,

    _init: function() {
        this.parent({});
        //this.add_accelerator("<Control>Q", "win.ctrl_q_action", null);
        this.set_accels_for_action("win.ctrl_q_action", ["<Control>Q"]);
    },
    vfunc_open: function(files, n_file, hint) {
        let uri = files[0].get_uri();
        let w = new Y901Window(this);
        w.set_uri(uri);
    },
    vfunc_activate: function() {
        new Y901Window(this);
    }
});

ついでに Gjs で上記のように open をオーバーライドするには。

let argv = ["y901main.js"];
ARGV.forEach(function(s) {
    argv.push(s);
});
GtkClutter.init(null);
ClutterGst.init(null);
let application = new Y901Application();
application.run(argv);

みたいに配列の先頭に何か突っ込まないと動作しない。
何故こんな仕様にしてしまったんだろう?

他色々と苦しみながらこんな所までやってみた。
DnD で再生、スペースキーでポーズ、シークバーも一応使える。

zep

我ながら以前の面影が何も無いけどどうしよう、名前は変えようか?
シークバーはコラム無しだしポーズボタンも無いし拡大はマウスのみだし。
シークバーも Clutter で作っているので、まだ手探り中なので。

y901x-1.1.x0.tar.gz

ここまでのソースを置いておきます、単なるバックアップですけど。
もし筆者が死んだら誰か続きをやってね。

SKYLAKE on Fedora

GNOME 3.20 が公開されているわけですが。

GNOME 3.20 リリースノート
> OS のアップグレードを簡単に

ということで多分次回以降の Fedora もコレに乗っかってくると思う。
毎回クリーンインストールだった筆者もアップグレードに変更する予定。

ということで、いいかげんにマシンを新しくしようと考えた。
毎回クリーンインストールなのに Phenom2 X4 955, AMD 880G のまま。
AMD 690G to 880G for Ubuntu | PaePoi
五年も使い続けたのか、今時のパソコンは全然壊れないね。

たしか以前 UEFI BIOS とやらで Linux が起動できなくなるとか…
それも全然話題にならなくなったし多分大丈夫、人柱でも上等。

以前電源ボタンの調子が悪かった時に恵安の激安ケースは買ってある。
結局直ったのでそのまんま放置していたけどやっと出番がきた。
SSD, BD-R, その他は使い回し。

Intel CORE I5 6500 (3.2GHz) CPU
ASUS B150M-A マザーボード
CFD DDR4 PC4-17000 4G メモリ x2

セットが昨日 PC DEPOT で 35k だったのを見つけたのでとっとと購入。
おっとマザーボードには日本語マニュアルが付いていたぜ。
早速読んでみるとやはり UEFI か、さてどうなるか。

マニュアルどおりに慎重に組み上げ Fedora 22 入りの SSD を仮組み。
いざ起動、画面に何も映らずビープ音がピー、ピ、ピ、ピー、ピ、ピ…

起動時のBEEP音について|テックウインド株式会社

かなり迷った後に見つけたけどこんな機能があるんだね。
メモリの差し直しで解決したがまだディスプレイには何も映らない。
CMOS クリアとか配線やり直し等色々試すが駄目、夜になったので中断。
今朝起きて駄目元でディスプレイ接続を DVI から HDMI に変更したら映った。
理由は解らないけど参考までに。

F1 を押して UEFI BIOS 画面に、F5 を押してデフォルト設定を適用。
するとあれ?Fedora 22 の起動画面が普通に出て来たぞ。
Fedora 側は何もやっていないのに。

一旦電源を落とし Fedora 23 の SSD に換装、マウスやスピーカーも接続。
Fedora 24 の準備のつもりがまさかの引越し完了、今時の Linux 恐るべし
UEFI は Fedora では何も問題ないようです。

skylake_fedora

しかし速い、同じ 3.2GHz 4 コア CPU のはずなのにまるで違う。
Linux だからと諦めていた Google 画像検索の引っ掛かりが皆無になった。
SKYLAKE のグラフィックはこんなに速いのか、グラボいらねぇ。

起きた問題は一つだけ。
我が Y901x で拡大やフルスクリーンができなくなった。
おまけにメニューが表示されない、何でだよ!

AMD と Intel というグラフィックの違いだろうけど。
ClutterGst 3.0 and GtkHeaderBar | PaePoi
で ClutterGst を使った奴は問題なく拡大できる、Totem も問題ない。
Clutter はグラフィックの違いを気にしなくても大丈夫なのか。

結局もう古い手段では新しいグラフィックに対応できないということのようだ。
マジで ClutterGst 化だな、余計な仕事が増えたぜイエーィ。

osascript Filenames

今回は osascript でファイル名関連をば。

OS?X 10.10 Release Notes

を見つけてやっと Objective-C からの変換方法が解ってきた。
物凄く下のほうにあって見つけにくかったよ。
たとえばこんなふうに引数が二つ以上の場合は先頭を大文字にして合体。

/*
contentsOfDirectoryAtPath:error:
to
contentsOfDirectoryAtPathError
*/

fm = $.NSFileManager.defaultManager
files = fm.contentsOfDirectoryAtPathError(pathB, null)

– fileExistsAtPath:isDirectory: – NSFileManager Class Reference

つまり Objective-C の文法を少し理解していないと変換すらできない。
コロンって引数だったのか、解ってしまえば楽勝だけど。

ディレクトリ内容列挙は NSFileManager でできるようだ。
ということでコードを書いてみる。
実は var とセミコロンはいらないけどキモいので書くことにした。

#!/usr/bin/osascript

ObjC.import("Cocoa");

// NSString
var pathA = $.NSString.alloc.initWithString("~/Documents/");
// ~ to $HOME
var pathB = pathA.stringByExpandingTildeInPath;
console.log("Path @ " + pathB.UTF8String);
// to URI
var uri = $.NSURL.fileURLWithPath(pathB);
console.log("URI @ " + uri.absoluteString.UTF8String);

// FileManager
var fm = $.NSFileManager.defaultManager;
// get files
var files = fm.contentsOfDirectoryAtPathError(pathB, null);
for (var i=0; i<files.count; i++) {
    // error files[i]
    var filename = files.objectAtIndex(i).UTF8String;
    // remove dot file
    if (filename[0] != ".") {
        console.log(filename);
    }
}

おかげで気が付いた、NSArray は添字ではアクセスできない。
JavaScript の配列でないからか、当然 forEach も length も使えない。
UTF8String に変換した後の文字列は添字可能、色々戸惑う。
バインドしているのではなく明確に型を分けているということみたい。

そんなこんなで。
Mac では JavaScript だけでやっていこうと思っていたけどコリャ無理だ。
Objective-C の勉強も始めますか、Fedora では使わないと思うけど。

Ubuntu…

第418回 Ubuntu GNOME 16.04 LTSの変更点:Ubuntu Weekly Recipe|gihyo.jp … 技術評論社

何コレ、標準 Ubuntu って Gedit 3.18 にメニューバーを付けたの?
プラグインはどうすんのよ、メニューバーが無い前提で作っているのに。

筆者は公開プラグインや作り方ページは Ubuntu 未サポートって追記した。
標準の奴はなんとかしているだろうけど、多分。

動作確認するためだけに ISO を落とすなんて絶対にやらないyo。
変えるかフォークでもして別名にしてくれないとマジで困るんだが。

ついでに少し古いけど。

“Ubuntu on Windows”搭載の「Windows 10 Insider Preview」Build 14316が登場 – 窓の杜

ココで言う bash って、いわゆるシェルではなくアプリケーションのようです。
実行パーミッションという概念が無いので shebang も使えないですし。
ls -a は Windows の隠しファイルでなくドットファイルのままだったりして。

せめて Mac の open -a コマンドみたいな、、、
何をやるにもフルパスが必要な OS 仕様ではそれも無理だよなぁ。
使い道がまったく思いつかない。

Canonical は何がしたいのだろう?

Gjs Desktop Mascot

近頃は小ネタばかりでまともなサンプルコードを書いていないと気が付いた。
このブログらしくないので久々に小物アプリ作ってみます。

もちろん JavaScript(Gjs) で。
基本は大分やったと思うので実際に何か作ってみるとどうかを試したい。
経験で実際にアプリを作ってみないと気が付かないことが多いと知っている。

とりあえず今回はデスクトップマスコットを。
背景が透過されている PNG 画像をデスクトップに表示というありがちなもので。

常にすべての GUI アプリの再背面に表示とかイベントの処理とかのサンプルにも。
それなら応用範囲も広がるだろう、と勝手に考える。
何より重要なのが GtkApplication を必ず使う。
でないと後々で困ることになりそうな謎の雰囲気があるのですよ。
GNOME 公式サンプルからして。

ということで。
背景透過画像は以下からカワイイ苗ちゃんを拾って使う。

【ウチ姫】UR++「小粒姫 優木 苗」ステータス・評価まとめ – お姫さま図鑑|ウチ姫公式攻略Wiki – GAMY(ゲーミー)

んで、こんなコードになりました。

#!/usr/bin/gjs

const Gtk = imports.gi.Gtk;
const Gdk = imports.gi.Gdk;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
const GdkPixbuf = imports.gi.GdkPixbuf;
const Lang = imports.lang;

const NaeWindow = new Lang.Class({
    Name: 'NaeWindow',
    Extends: Gtk.ApplicationWindow,

    _init: function(app) {
        this.parent({
            application: app
        });
        // GdkColormap to GdkVisual
        let screen = this.get_screen();
        let visual = screen.get_rgba_visual();
        if (visual != null && screen.is_composited()) {
            this.set_visual(visual);
        } else {
            print("no Composited...");
        }
        this.set_app_paintable(true);
        // Transparent background image
        this.pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size("nae_ur++.png", 300, 300);
        // Event Mouse
        //this.set_events(Gdk.EventMask.BUTTON_PRESS_MASK);
        this.connect("button-press-event", Lang.bind(this, function(widget, event) {
            /* NG
            https://people.gnome.org/~gcampagna/docs/Gdk-3.0/Gdk.Event.html
            
            if (event.type === Gdk.EventType.BUTTON_PRESS) {
                this.begin_move_drag(event.button, event.x_root, event.y_root, event.time);
            */
            if (event.get_event_type() === Gdk.EventType.BUTTON_PRESS) {
                let [res, x_root, y_root] = event.get_root_coords();
                this.begin_move_drag(
                    event.get_button()[1],
                    x_root,
                    y_root,
                    event.get_time()
                );
            } else if (event.get_event_type() == Gdk.EventType.DOUBLE_BUTTON_PRESS) {
                this.close();
            }
        }));
        // Event Draw
        this.connect("draw", Lang.bind(this, function(widget, cr) {
            Gdk.cairo_set_source_pixbuf(cr, this.pixbuf, 0, 0);
            cr.paint();
        }));
        // z-order
        this.set_keep_below(true);
        // etc
        this.set_decorated(false);
        this.resize(300, 300);
        this.show_all();
    }
});

const Application = new Lang.Class({
    Name: 'Application',
    Extends: Gtk.Application,

    _init: function() {
        // TaskBar Title
        GLib.set_prgname("Nae Chan !");
        // property
        this.parent({
            application_id: 'apps.test.NaeChan',
            flags: Gio.ApplicationFlags.FLAGS_NONE
        });
    },
    // override activate signal
    vfunc_activate: function() {
        new NaeWindow(this);
    }
});
let application = new Application();
application.run(ARGV);

desktop_naechan

あぁ、苗ちゃんがいつもデスクトップにいる。
カワイイよぉ、剥製にして飾…(嘘です

最近気が付いた、g_set_prgname でアクティビティ横の文字列を決められる。
たしか Ubuntu は違ったような、まあ猿専用ディストリなんてガン無視でいい。

そんなことより。
button-press-event ハンドラの仕様は何なんだよ!

Gdk.Event

UNION だとこういうバインドしか手段が無いのか、それとも別の理由か。
現状 Python, C のようにメソッドは使えず関数で取得しか手が無い。

ぶっちゃけ。
コレで混乱しなかったらこんな素敵なサイトなんて見つけられなかったぞ!
やはり何か具体的にアプリを作ってみないと解らない事って多い。