Original Webkit Browser @ Fedora 15

HTML5 の勉強、その前に。
WebKit 自作ブラウザが不便すぎ、もう少しまともな形にしよう。

チョロミウム入れようかな、とも思うけど表示テスト以外で使わないだろうし。
テスト用なんだからとにかく最小限機能だけ付けて軽いほうがいいし。
しかし Fedora の Firefox は何故こんなに起動が遅いのやら…
だから Opera が手放せないんだよ、よく落ちるけど。

/usr/share/doc/pywebkitgtk-1.1.8/demos/browser.py
のコードはまだ GTK2, pywebkit のまま、でも参考にはなる。
本格的に作るならキャッシュ指定や Flash, JAVA の利用処理とかが必要になる。
今はワカンネエ。

WebKitGTK+ Reference Manual

仕様を決める、メニューはリロードだけあれば充分かな。
アドレスバーに打ち込んで Enter でも表示できるようにして。
HTML ファイルをドロップの受け入れは WebKit.WebView が勝手にやってくれる。
読み込んだらタイトルバーにタイトルを入れて、ロード中なんかも表示して。
後はリンク先をステータスバーに表示する、こんな仕様で充分だろう。

まてよ?
GtkApplication で動かす場合 Quit 処理はどうするんだろう?
Gtk.main() でのループではないので Gtk.main_quit() はおかしいよな。

GtkApplication

gtk_application_remove_window に自分のポインタを入れればいいってことかな。

def on_quit(self, widget, data=None):
    app = self.get_application()
    app.remove_window(self)

これで終了してくれた、やっぱり Delphi の TApplication もどきだね。
gtk_window_close(GtkWindow) 関数なんてものを用意すると勘違いする人が出そうだしこれでいいだろう。

とりあえず作ってみた。
タブを付けたいところだけどココでは最小限の IE6 スタイルで。

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

import sys
from gi.repository import WebKit, Gtk, Gio, Gdk

menu_xml = """<ui>
    <menubar name="MenuBar">
        <menu action="file">
            <menuitem action="reload"/>
            <separator/>
            <menuitem action="quit"/>
        </menu>
    </menubar>
</ui>"""

class WebKitWindow(Gtk.Window):
    """
        WebKit PyGi Version
        from Fedora 15 x86_64
    """
    def __init__(self):
        # Window
        Gtk.Window.__init__(self)
        self.resize(640, 480)
        self.set_title("WebKit")
        # GtkUIManager and GtkAccelGroup
        self.uimanager = Gtk.UIManager()
        accelgroup = self.uimanager.get_accel_group()
        self.add_accel_group(accelgroup)
        # GtkActionGroup
        self.actiongroup = Gtk.ActionGroup("seeme_menu")
        # GtkActionEntry
        self.ac = [ ("reload", Gtk.STOCK_REFRESH, "_Reload", "F5", "Reload", self.on_reload),
                    ("quit", Gtk.STOCK_QUIT, "_Quit", "<Control>Q", "Quit", self.on_quit),
                    ("file", None, "_File") ]
        self.actiongroup.add_actions(self.ac)
        self.uimanager.insert_action_group(self.actiongroup, 0)
        self.uimanager.add_ui_from_string(menu_xml)
        # menubar
        menubar = self.uimanager.get_widget("/MenuBar")
        # entry
        self.entry = Gtk.Entry()
        self.entry.connect("activate", self.on_entry_activate)
        # WebKit
        self.webview = WebKit.WebView()
        #self.webview.load_uri(HTML_URI)
        self.webview.connect("load-started", self.on_load_started)
        self.webview.connect("load-finished", self.on_load_finished)
        self.webview.connect("title-changed", self.on_title_changed)
        self.webview.connect("hovering-over-link", self.on_hovering_over_link)
        # ScrollWindow
        sw = Gtk.ScrolledWindow()
        sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
        sw.add(self.webview)
        # statusbar
        self.statusbar = Gtk.Statusbar()
        # box
        vbox = Gtk.VBox()
        vbox.pack_start(menubar, False, True, 0)
        vbox.pack_start(self.entry, False, True, 0)
        vbox.pack_start(sw, True, True, 0)
        vbox.pack_start(self.statusbar, False, True, 0)
        self.add(vbox)
        self.show_all()

    def on_load_started(self, webview, frame):
        self.statusbar.push(0, "Loading...")

    def on_load_finished(self, webview, frame):
        self.statusbar.push(0, "")

    def on_title_changed(self, webview, frame, title):
        self.set_title("{0} - WebKit".format(title))
        self.entry.set_text(webview.get_uri())

    def on_hovering_over_link(self, webview, title, uri):
        if uri:
            self.statusbar.push(0, uri)
        else:
            self.statusbar.push(0, "")

    def on_entry_activate(self, entry):
        self.webview.load_uri(entry.get_text())

    def on_reload(self, widget, data=None):
        self.webview.reload()

    def on_quit(self, widget, data=None):
        app = self.get_application()
        app.remove_window(self)

class App(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(
                self,
                application_id="apps.test.webkit",
                flags=Gio.ApplicationFlags.FLAGS_NONE)
        self.connect("activate", self.on_activate)
        
    def on_activate(self, data=None):
        l = self.get_windows()
        if l:
            return
        w = WebKitWindow()
        w.set_application(self)
    
if __name__ == "__main__":
    app = App()
    app.run(sys.argv)

リンク先をステータスバーに表示した後で消す方法に迷ったけど上記でイケた。
リンクをマウスカーソルが外れると uri に NULL がセットされて送られるようです。
GtkApplication 関連以外はほとんど PyGtk と同じでイケます。

どうでもいいけど。
GTK+ 関連のアクセスがドイツやスウェーデンといったヨーロッパからばかりなんだが…
アッチの google で検索してココがヒットするのも変な気分、どのくらい読解できるやら。
まあ私も GTK+ 関連は日本語では探さないんですけどね。