Y901x」タグアーカイブ

gtk.Widget.reparent

いいかげんに Y901x もフルスクリーンでコントローラを出すようにしよう。

方法は色々あるんだが、一番簡単なのは show() hide() だけで済ませる方法。
しかしこれではムービー画面が拡大縮小されてみったくない。
WMP12 や Cinema のように浮き上がらせて表示させる、の方法は解らない…

オーソドックスに下からヒョッコリ出てくる方法にでもとりあえずやっとこう。
これも方法が沢山あるけど別ウインドウを作って被せるのが一番簡単だろう。

とりあえずコントローラ用の gtk.Window を gtk.WINDOW_POPUP 指定で作成。
gtk.Widget の reparent() メソッドで parent の gtk.Box をコッチに変更。
unparent() set_parent() を使うとうまくいかなかった、つか実態が消滅するんだが。

parent を変更すると property が消える、パッキング情報は Box 側が持つんだから当然か。
.NET Framework の WPF なら子オブジェクト側が持っているんだよね、色々あってややこしい。
なので set_child_packing メソッドでパッキング情報を追加するのを忘れずにと。

んでディスプレイサイズを取得して…ってどうやるのだ?

ぱぇぽぃ2 ? Blog Archive ? デスクトッププロパティ

なんだ、自分でやっていたや。
でも Python の勉強を始めたばかりな頃にやったことなんで効率悪すぎる。
wnck を使えば簡単だけど KDE 対応でまた…
ということで、何か他の方法は無いか探したら恐るべきコードを発見。

pygtkだけ でスクリーンショットをとる

何コレ、たったこれだけ(八行)で本当に全画面スクリーンショットアプリが完成!
PyGtk 恐るべし、gnome-screenshot が強力すぎて自分で作ろうとは思わないけど。

つーか画面サイズを調べるのって get_geometry() メソッドを呼ぶだけだったのか。
やはり知識が無いと無駄なコードを書くことを自分で証明した。

とにかくコレでディスプレイサイズがゲットできたので作ってしまえだ。
表示後でないと gtk.Widget.allocation.height が取れないのをどうするか悩む。

ごまかしたらイマイチなコードになっちゃった、けど開発途中なんだからいいや。
後マウスカーソルを消す処理もいれたいけど出したいからこのまんま出してしまえ(ぉい!
具体的なコードは Y901x の common.py の CFullCtrl class を見てくれ。
更新毎に少しずつマトモなコードになる、多分。

ということで Y901x-0.2.3 を公開しました、本サイトからぞうぞ。
listbox 表示状態を記憶せず毎回表示していたのも修正した、今まで何故気がつかない…

だから Linux 用を作ったところで全然金にも人気にもならないなんて解っているよ。
いいじゃないか、作りたいんだから。

Y901x-0.2.2

Y901x-0.2.2 公開。

button_release_event の callback で

if self.gesture["result"] == "":
↓
if self.gesture["result"] == "" and self.w.get_title() != "":

とチェックの追加をしてみただけなんだがまだテストが足らないかもしれない。
とりあえず現在までジェスチャと右メニューは同時に出なくなったので多分大丈夫だろう。
ついでに FileChooserDialog にフィルタリングを追加して公開してみる。
とにかくトップページつか公開アプリを更新したかっただけさ。

後はフルスクリーンでボタンやシークバー表示を追加すればプレイヤー基本機能は私的に終了。
Cinema(つまり WMP11 のパクリ) みたくバーのみ浮いた表示にしたいんだがどうすれば…
でもアレって GTK+ らしくないかもしれない。

y901x-0.2.1

y901x-0.2.1 を誰も待っていないだろうけど更新しました。

やっと compiz 3D 無効状態でリストサイズ変更グリップラインが崩れるのを修正できた!
3D で使えば問題無いけど実はずっと気にしていた私であった。

def __on_expose_event(self, widget, event):
    # GetDC()(Windows)
    gc = widget.style.fg_gc[gtk.STATE_NORMAL]
    # Draw Vertical Line
    for i in range(10):
        if i%3 == 0:
            widget.window.draw_line(
                gc,
                event.area.x+i,
                event.area.y,
                event.area.x+i,
                event.area.height)

とやっていたのを

def __on_expose_event(self, widget, event):
    # GetDC()(Windows)
    gc = widget.style.fg_gc[gtk.STATE_NORMAL]
    # Draw Vertical Line
    for i in range(10):
        if i%3 == 0:
            widget.window.draw_line(gc, i, 0, i, widget.allocation.height)

に変更したらアッサリと。
つまり引数で渡される event.area から得られる値は 2D 状態ではアテにならないぞと。
widget から直接大きさを調べて計算すれば 2D でも 3D でも対応できるね。

今まで表示されない部分に一生懸命ラインを引いていたってことか、あーあ、早く気がつけ俺。
他にステータスグリップ描写が変な位置になる不具合も同じ理由だった。

他、覚書ページ作りで思いついたことを地味に導入して本サイトにて公開中。
しかし三ヶ月も放置したのに毎月ダウンロード数が地味に増えているのは何故だろう?
といってもたった二百程度なんだが、Linux 専用だし需要は微妙だしこんなものだろう。

どうでもいいけど本サイトトップページのスクリーンショットは取っ払った。
BlackBerry で見てみたら…まぁそういうわけで。
今後はサイトデザインもスマートフォンを考慮したほうがいいかもね。

Y901x 0.2.0 release

Y901x 0.2.0 公開、トップページから。

beta からの変更点、せっかくだから Mandriva KDE 版にも対応。
Dolphin 及び他からのファイルドロップに対応するためにこうした。

def on_drag_data_received(self, widget, context, x, y, selection_data, info, time):
    # D&D FilenNmes split CRLF or LF
    if "\r\n" in selection_data.data:
        drop = selection_data.data.split("\r\n")[0]
    else:
        drop = selection_data.data.split("\n")[0]
    if "//" in drop:
        self.set_uri(drop)
    else:
        self.set_uri("file://" + drop)

Nautilus は CRLF 区切りで file:// の URI で送られてくる。
Dolphin は LF 区切りだ、後は file:// になっているかで振り分ければいいだろう。
これで多分どんな場合でもドロップに対応できる…かもしれない。

それより Mandriva には install というコマンドがあるお!
./ を付けてでは…しかたがないのでインストールスクリプトは名前を変更!

KDE での D-Bus については dbus-python を入れてくれでいっちゃえ!
試しに入れてみたら動いたからそれでいいや。

GtkAspectFrame の件はかなり前に Blog に書いたのに公開版はまだやっていなかった…

てなわけで思ったより差があるので 0.2.0 とマイナーバージョンアップということにする。
しかし気がつくとトップページの更新を 1 か月以上忘れていた、反省。
やっぱり Blog というか CMS のほうが楽なのでコッチばかり更新になってしまう。

get the X Window ID from gtk.Drawingarea

私は Y901x という GStreamer フロントエンドな動画プレイヤーを作った。
もちろん自分で使っているのだが Mandriva 2010.0 に乗り換えたら落ちまくる。
でもタマに問題なく動く場合もがあるからややこしい。

ついでに、ソースディレクトリに pyc キャッシュを作成しなくなっているのだが…
Mandriva 2010.0 だからなのか? Python がヤメたのか?それとも他の場所にあるのか?

0.1.9 を色々弄くって以下の処理を行っている場所
GtkDrawingArea の X Window ID を得ようとすると X server Error になると解った。

imagesink.set_xwindow_id(self.video_window.window.xid)
# これさえも error
print self.video_window.window.xid

gtk.DrawingArea.window は gtk.gdk.Window であり gtk.gdk.Drawable のメソッドを持つ。
なので xid アトリビュートで X Window ID が得られるようになっている。

コレが現行の GTK+ ではできなくなったのかな?
と疑って xwininfo をインストールして使ってみた。

xwininfo

何も問題無く root window の xid が得られている。
それなら root な gtk.Window.window に割り当てたらどうなる?

imagesink.set_xwindow_id(self.w.window.xid)
#imagesink.set_xwindow_id(self.video_window.window.xid)

fullwindow

コントローラやメニューが塗りつぶされたけどコレなら問題無く xid が指定できる。
ということは gtk.DrawingArea の window.xid の取得方法がマズイということだろう。
ならば簡易なコードを書いて試してみる。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import pygtk
pygtk.require('2.0')
import gtk

class Xid():
    def __init__(self):
        w = gtk.Window()
        vbox = gtk.VBox()
        self.da = gtk.DrawingArea()
        button = gtk.Button("Press me")
        button.connect("clicked", self.show_xid)
        vbox.pack_start(button)
        vbox.pack_start(self.da)
        w.add(vbox)
        w.set_title("xid")
        w.connect("delete-event", gtk.main_quit)
        w.show_all()

    def show_xid(self, widget):
        widget.set_label("gtk.DrawingArea xid: %s" % (self.da.window.xid))

if __name__ == '__main__':
    w = Xid()
    gtk.main()

あらら、この方法では問題無く取得できてしまった。
ということはタイミングが問題なのか、何か event が起こった時に取得すればイケそうだ。
ということで検索しまくった、日本語で見つかるはずがないのでやはりメリケンの Google で。

Re: [pygtk] get the XID from gtk.Drawingarea

expose-event を吐いた所で xid を保存してソレをブチ込めばいいということかな?
でも expose-event を待つ必要があるので __init__ で sys.argv を処理できない。
show シグナルにて sys.argv を処理するように書き換えて実験。
コードの解説は長くなりすぎるからバックアップを見てくれで済ます。

y901x-0.1.10beta.tar.gz

kkobato

あぁやっと Ubuntu 9.04 で使っていた頃のように Mandriva で動くようになった。
GTK+ が厳密になったのか Ubuntu がいいかげんだったのかは今は解らない。
ところで Mandriva でも Ubuntu と同じインストールスクリプトが使えるね。

もうしばらく自分で試してから本サイトの奴は更新します。
Ubuntu 9.10 でも試さなきゃなぁ、多分同じだと思うけど…
てか RPM にしたほうがいいのだろうか?需要はシラネ。