get_size, resize

GtkHeaderBar 付きの GtkWindow のリサイズ。
以前こんなことを書いた。

GTK+ 3.20 GtkHeaderBar and CSS | PaePoi

もう少し細かく判った。

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

class Win(Gtk.ApplicationWindow):
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app)
        # Headerbar
        self.headerbar = Gtk.HeaderBar(show_close_button=True)
        self.set_titlebar(self.headerbar)
        # Button
        button = Gtk.Button(label="Click !!!")
        button.connect("clicked", self.on_button_clicked)
        self.add(button)

    def on_button_clicked(self, button):
        print(self.get_allocated_width(), self.get_allocated_height())
        w, h = self.get_size()
        print(w, h)

class App(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(self)

    def do_activate(self):
        w = Win(self)
        w.show_all()

app = App()
app.run()

aloc_size

get_allocated_* と get_size で値が違う。
ちなみに GtkHeaderbar を消すと同一の値になる。

見た目で解るけどクライアント領域のサイズですね。
window.get_size と window.resize が共通サイズになるようだ。
ということでサイズの保存にはコチラを使いましょう。

ついでに、GVariant.deep_unpack は Gjs でないと使えないのね。
Gjs も地味に便利にしているところがあったのね。

Gjs VariantBuilder

しまった、ポケモン GO にどっぷりハマってもーた。

hf_kari

むったんと五十鈴とくるみんと柊の 4M ゲット、ココミンも確定済。
苗ちゃんごめん、無課金ではランキング上位報酬なんて無理です。

ボケはこれくらいにして。

オジサンはポケモンなんてピカチュウとサトシしか知らないけどやっているよ。
と言ったら驚く人がたまにいる、こっちが驚くってばさ。
こんな人達はポケモン自体の人気でフィーバーしていると思っているようだ。
つまり、まだまだ伸びる可能性があるという恐ろしさ。

すでに個人がアプリを作ったって存在に気付いてくれる人はゼロに近い。
16 年前はゆりあるなんてしょーもないモンが万単位だったのにな。
プログラミングは仕事か個人で使うスクリプトだけの時代がもう来ている。

とにかくポケモン GO (と GF) でサボっていたぶんを取り返さなきゃ。

今回はずっと後回しにしてきた GSettings に配列の配列を保存する方法を調べる。
もちろん Gjs、まあ Python でもほとんど同じだけど。

GSettings への保存は基本的に Variant 型で保存する。
配列にするには VariantBuilder というものを使うようだ。
配列の配列だけどタプルの配列として保存するのが効率よさげ。

this.set_size = [[320, 240], [640, 360], [1280, 720]];

//
// Write
//
let settings = new Gio.Settings({schema:"org.sasakima.y901x"});
let xy = new GLib.Variant("(ii)", this.get_size());
settings.set_value("window-size", xy);
// Error
//let builder = new GLib.VariantBuilder({type: new GLib.VariantType("a(ii)")});
//let builder = new GLib.VariantBuilder(GLib.VariantType("a(ii)"));
let builder = GLib.VariantBuilder.new(new GLib.VariantType("a(ii)"));
for (let i=0; i<3; i++) {
    let t = new GLib.Variant("(ii)", [ this.set_size[i][0], this.set_size[i][1] ]);
    builder.add_value(t);
}
settings.set_value("set-size", builder.end());


//
// Read
//
let settings = new Gio.Settings({schema: "org.sasakima.y901x"});
let [w, h] = settings.get_value("window-size").deep_unpack();
this.resize(w, h);
this.set_size = settings.get_value("set-size").deep_unpack();

これでなんとかなった。

dconf

GLib.VariantBuilder
のように new キーワードを使うとエラー。
この構造体はプロパティが無いので JSON では対応できない、うーむ。

保存で詰まりまくったけど読み込みは簡単すぎ。
get_value して deep_unpack だけで配列の配列が完成、唖然とした。
調子に乗ってサイズ保存もタプルに変更したら前のキーが残ってしまった。
これどうやって消すのかな?今度調べる。

Google Chrome 51 Chach

Google Chrome はキャッシュの仕様が変わってしまったね。
FLV や MP4 の動画キャッシュにヘッダが着くようになった。

Nautilus をスクリプトで拡張 – L’Isola di Niente
つまり上記に書いた手段が使えない。
YouTube は随分前から駄目だけどニコニコなんかはまだキャッシュに残るし。

いやまあ強引にダウンロードする手段はいくらでもあるんだけど。
せっかくキャッシュにあるのにもう一回通信なんてアホ臭い。
GHex 等で地味に余計なヘッダを削るなんて面倒臭い。

ならば余計なヘッダを取っ払ってからコピーすればいいじゃない!
Nautilus スクリプトです、Linux じゃない人は参考程度に。

FLV が取得できなかったので小変更

#!/usr/bin/env python3

"""
    chrome_catch (~/.local/share/nautilus/scripts)
    Copy Chrome Cache File to Nautilus Current Directry
    Google Chrome 51 Version
"""

import os
from gi.repository import GLib

FLV_FILE = "FLV".encode("utf-8")
MP4_FILE = "ftyp".encode("utf-8")

# Src Directory is Google Chrome Cache Path
src_path = os.path.expanduser("~/.cache/google-chrome/Default/Cache")
# Copy Directory is Nautilus current directory
dst_path = GLib.filename_from_uri(GLib.getenv("NAUTILUS_SCRIPT_CURRENT_URI"))[0]

ls = os.listdir(src_path)
for f in ls:
    src = os.path.join(src_path, f)
    # size < 1MB is continue:
    if os.path.getsize(src) < 1048576:
        continue
    with open(src, "rb") as o:
        data = o.read()
        data2 = data
        try:
            i = data.find(MP4_FILE)
            o.seek(i-4)
            with open("{0}/{1}.mp4".format(dst_path, f), "wb") as ff:
                ff.write(o.read())
        except Exception as e:
            pass
        #data2 = o.read()
        try:
            i = data2.find(FLV_FILE)
            o.seek(i)
            with open("{0}/{1}.flv".format(dst_path, f), "wb") as ff:
                ff.write(o.read())
        except Exception as e:
            pass

find で見つからないと例外なのでコレでいいと思う。
早速ニコニコでバイク動画を再生して、よしよし拾うことができた。
いやバイク動画目的ですよ、決してえっち(以下略

PyGObject do_key_press_event

PyGObject でのオーバーライドでハマったので覚書。

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gio, Gdk

class NoActionWindow(Gtk.ApplicationWindow):
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app)
        # connect
        #self.connect("key_press_event", self.on_key_press_event)
        self.show_all()

    def do_key_press_event(self, event):
    #def on_key_press_event(self, widget, event):
        """
            Call the method of the parent
            'gtk_application_set_accels_for_action' does not work.
        """
        # Important!
        Gtk.ApplicationWindow.do_key_press_event(self, event)
        #
        if event.keyval == Gdk.KEY_Escape:
            self.close()
        return False

class NoActionApplication(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(self)

    def do_activate(self):
        # ApplicationMenu
        menu = Gio.Menu()
        menu.append("_Quit", "app.quit_action")
        self.set_app_menu(menu)
        self.set_accels_for_action("app.quit_action", ["<Control>Q"])
        # Action
        quit_action = Gio.SimpleAction(name="quit_action")
        quit_action.connect("activate", self.on_quit_action)
        self.add_action(quit_action)
        #
        self.window = NoActionWindow(self)

    def on_quit_action(self, action, parameter):
        self.quit()

app = NoActionApplication()
app.run()

上記 Important 部を無効にすると Ctrl+Q で終了できない。
このオーバーライドは親の do_key_press_event を呼ぶ必要がある。
connect メソッドならその必要は無いようだ。

こんなしょーもないことを解決するのに三時間くらい使っちまったぜ。
GtkApplication 側に問題があると思いこんでしまうもの、こういう場合。
この連休でアレを完成させるつもりだったけど無理かも。

United RPMS

Fedora に新しいリポジトリができたんだね。
数はまだ少ないけど。

United RPMS by UnitedRPMs

RPM Fusion から何故か無くなった unrar がこっちにはある。
Atom や Opera やよくワカランのやら、ふむふむ。
mplayer 等のマルチメディア系は RPM Fusion と被りまくっているような。

unitedrpms.github.io/README.md at master ? UnitedRPMs/unitedrpms.github.io ? GitHub

インストールは上記、GPG キーのインストールを忘れずに。
gnome-softwere のソフトウエアソースを確認。

unitedrpms1

うん登録されているね。
これで Atom とかはインストールできるけど被っているものはどうなるの?

gaburi

普通にどちらか一方が入るということのようだ。
これなら導入しても特に問題はなさそうだ。

今後どうなるか解らないけど面白いものが登録されるといいな。
まあ筆者の場合は使うアプリがほぼ固定しちゃってるんで意味ないんですけどね。