Webブラウザでninix-aya(新春一発ネタ)

単にninix-aya 4.99.xでGDKのバックエンドをBroadwayにしただけですが何か。

Screenshot from 2015-01-03 16:33:25

 

まず、Broadway display serverを起動します。

% broadwayd

次に、Webブラウザで http://localhost:8080/ にアクセス。

最後に、環境変数を設定してninix-ayaを起動します。

% GTK_IM_MODULE= GTK_MODULES=”” GDK_BACKEND=broadway BROADWAY_DISPLAY=:0 ninix

 

そろそろ決断

色々試して来ましたが、Python3+Qt5が最も可能性がありそうです。

  • Python3+Gtk3 → PyCairoの件が不調。それ以外は特に問題は無いのですが。
  • Python2+Gtk2 → いずれObsoleteになる。
  • Ruby+Gtk3 → 移植が必要なコードの量が一人でやるには多過ぎる。(特に栞)
  • Python3+Qt5 → そのまま移植出来ない部分(メニューなど)はあるが、致命的でない。栞のコードなどがそのまま使える。ツールキット移行のメリットも多そう。

Qt5の印象ですが、APIがQtで閉じていて、Gtkよりもマルチプラットホームである点が魅力的ですね。

3つの関門

ninix-ayaをQt(PySide)に移行する場合に考えなければいけない点ですが、ninix-ayaが必要とする機能で大きなものが3つあります.

  • pnrおよび pnaとshaped windowへの対応
  • メニューの背景画像対応(特に選択された項目だけ画像を変えられるか)
  • バルーンの実装に必要な機能が揃っているか

試してみたところpnr, pnaとshaped windowは問題なく実現出来ますね.(処理速度の面からはチェックしていませんが.) むしろ実装はGtk+より簡単で拍子抜けしました.

今後しばらくの間はGtk+3だけでなくQtへの移行も検討していきます.

_gtkhack復活

とりあえずGitのmasterリポジトリの方に_gtkhackを追加しました.

pygtkにあったgtk.gdk.pixbuf.get_pixels_arrayとGtk.Window.input_shape_combine_regionの代替メソッドを追加してあります. 興味のある方はどうぞ.

7月上旬に_gtkhackが入ったninix-aya 4.99.14をリリースする予定です.

 

予定変更

ninix-aya 4.4.1のリリースはキャンセルして4.99.xの開発を再開します.

かつてninix-ayaがGtk+2に移行する前(2003/04/08 period 30)に使っていたのと同じ手を使います.
しばらくの間 4.99.xの方で_gtkhackを復活させ, pygtkにあったgtk.gdk.Pixbuf.get_pixels_arrayと同様の機能を実装して使うことにします.

_gtkhackモジュールを追加したバージョン(4.99.14)は7月リリース予定です.

# それでもcairo_region_tをサポートするためのpycairoとpygobjectのパッチは必要です. 🙁
# そこまでの代替機能を_gtkhackに入れるかどうかはこれから考えます.

 

 

GtkTextViewいけるかも

バルーンに使おうと思っているのはGtkTextViewです.

Gtk+2の時には色々試して上手くいかなかったのですが, Gtk+ 3.1.4(ChangeLog)でRGBAを使えるようになっているというので再挑戦しています.

背景を透明にして文字や画像をTextBufferに追加出来ることは確認しました. 🙂
意外なことに下のコードだけで(特別なことをしなくても)スクロールバーまで消えてくれています.


import cairo
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GdkPixbuf

def redraw(darea, cr):
cr.set_source_rgba(0, 0, 0, 0)
cr.set_operator(cairo.OPERATOR_SOURCE)
cr.paint()
del cr

def main():
path = ‘test.png’
pixbuf = GdkPixbuf.Pixbuf.new_from_file(path)
win = Gtk.Window()
win.set_app_paintable(True)
screen = win.get_screen()
visual = screen.get_rgba_visual()
win.set_visual(visual)
#win.set_focus_on_map(False)
#win.set_title(title)
#win.set_decorated(False)
#win.set_resizable(False)
win.connect(‘delete_event’, Gtk.main_quit)

darea = Gtk.DrawingArea()
darea.connect(‘draw’, redraw)
darea.set_size_request(320, 240)
darea.show()
sw = Gtk.ScrolledWindow()
sw.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.ALWAYS)
sw.show()
tv = Gtk.TextView()
tv.set_wrap_mode(Gtk.WrapMode.CHAR)
tv.override_background_color(Gtk.StateFlags.NORMAL, Gdk.RGBA(0, 0, 0, 0))
tv.show()
sw.add(tv)
tv.set_size_request(200, 150)
sw.set_size_request(200, 150)
fixed = Gtk.Fixed()
fixed.show()
win.add(fixed)
fixed.put(darea, 0, 0)
fixed.put(sw, 30, 40)
win.show_all()
tb = tv.get_buffer()
tb.set_text(‘test\n\n\n’)
it = tb.get_iter_at_mark(tb.get_insert())
tb.insert_pixbuf(it, pixbuf)

if __name__ == “__main__”:
main()
Gtk.main()