GtkApplication: delete-event and remove_window

destroy and delete-event Signal | PaePoi

の問題がやっと解決した。
正しい手段ではないだろうけどと前置きして。

delete-event を emit してもウインドウは破棄されない。
でも[閉じる]ボタンなら普通に破棄される。
destroy を投げる手段は単独ウインドウならイケるけど複数だと駄目だった。
GtkApplication から remove すれば当然強制破棄される。

だったらこうすりゃいいじゃないか。

#!/usr/bin/env python3

import sys
from gi.repository import Gtk, Gdk

class RemoveWin(Gtk.ApplicationWindow):
    """
        emit delete-event to remove_window
    """
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app)
        button = Gtk.Button("remove_window")
        button.connect("clicked", self.on_button_clicked)
        self.add(button)
        self.resize(320, 240)
        self.show_all()

    def on_button_clicked(self, button, data=None):
        # emit the delete-event
        self.emit("delete-event", Gdk.Event(Gdk.EventType.DELETE))
        # remove
        self.props.application.remove_window(self)

    def do_delete_event(self, event):
        # check the window geometry
        x, y = self.get_size()
        print(x, y) #=> 320 240

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

    def do_window_removed(self, window):
        # check the window geometry
        x, y = window.get_size()
        print(x, y) #=> 320 240 or 123 32
        # call the default
        Gtk.Application.do_window_removed(self, window)

app = App()
app.run(sys.argv)

delete-event を投げて remove_window で強制破棄。
かなり強引な処理だと思うけどこの手段ならボタンやメニューから確実に終了できる。
かつボタンでも[閉じる]ボタンでも delete-event を通る。

ついでに delete_event と window_removed でジオメトリを確認。
window_removed では[閉じる]ボタンの場合はサイズがおかしい。
やっぱり強引すぎるかな…

つまり conf 等に終了時サイズを記録したい場合は delete_event ハンドラ時に。
いや、自アプリで必要だったので。

ところで do_* はハンドラではなく関数のオーバーライドみたい。
ハンドラからこの関数が呼ばれているという解釈でいいのかな。
do_window_removed は多分こうだろうと適当に書いたら普通に通った。
全部のハンドラがこの仕組みではないようだけど覚えておいたほうがいいね。