日別アーカイブ: 2019/11/03

GNOME 3.34 modal dialog bug

Fedora 31 の GNOME 3.34 にて。
Gedit でファイルの編集中にする。
F11 でフルスクリーンにする。
Ctrl+W でファイルを閉じようとして modal なアラートを出す。

何じゃこりゃ。

逆にフルスクリーンから戻すともっと悲惨。

自作アプリの Comipoli でファイル切り替えの動作が変だった。
モーダルダイアログを出すと一瞬だけ先頭ページが表示される現象に悩まされた。
これが原因じゃねーか、三日も悩んで損した。

GNOME だから 3.36 になるまでこのままなんだろうな。
しかたがないので Comipoli はしばらく GtkInfoBar に切り替えることに。

モーダルにできないのでキーボード処理は表示時のみ専用ハンドラに逃がして。
何故か use_markup が使えない、文字列だけにするしかないみたい。
gtk_info_bar_set_default_response が何故かエラーになる、困った。
スペースキーをガシガシするだけの特徴は残したいけど自前処理しか手段が無いな。
困った時の g_idle_add だ、この関数マジ便利。

#!/usr/bin/env python3

from gi.repository import GLib, Gtk

class ComipoliInfoBar (Gtk.InfoBar):
    def __init__(self):
        Gtk.InfoBar.__init__(self, no_show_all=True, valign=Gtk.Align.START)
        #
        self.uri = ''
        self.label = Gtk.Label(visible=True)
        area = self.get_content_area()
        area.add(self.label)
        self.ok = self.add_button('_OK', Gtk.ResponseType.OK)
        self.add_button('_Cancel', Gtk.ResponseType.CANCEL)

    def show_message(self, text, uri):
        self.uri = uri
        self.label.set_text(f'Next\n{text}\n\nEsc Cancel')
        GLib.idle_add(self._show_message)

    def _show_message(self):
        self.show()
        self.ok.props.has_focus = True
        return False

を GtkOverlay に乗せて。

class ComipoliWindow(Gtk.ApplicationWindow):
    def __init__(self, app):
        Gtk.ApplicationWindow.__init__(self, application=app)
        # InfoBar
        self.infobar = ComipoliInfoBar()
        self.infobar.connect('response', self.on_next_info)
        #
        # etc...
        #
        overlay = Gtk.Overlay()
        infolay = Gtk.Overlay()
        overlay.add_overlay(self.upperbar)
        overlay.add(infolay)
        infolay.add_overlay(self.infobar)
        infolay.add(self.canvas)
        self.add(overlay)

    def on_next_info(self, widget, res_id):
        if res_id == Gtk.ResponseType.OK:
            self.set_uri(widget.uri)
        widget.hide()

    def change_pixbuf(self, nex):
		#
		# etc...
		#
        next_index = cbzs.index(etc) + 1
        if l > next_index:
            esc = html.escape(cbzs[next_index])
            uri = GLib.filename_to_uri(GLib.build_filenamev([path, cbzs[next_index]]), None)
            self.infobar.show_message(esc, uri)
            ''' GNOME 3.34 bug
            dlg = Gtk.MessageDialog(
                transient_for=self,
                buttons=Gtk.ButtonsType.OK_CANCEL,
                #message_type=Gtk.MessageType.QUESTION,
                text=f'<span bgcolor="red">Next:</span> {esc}',
                use_markup=True,
                secondary_text='ESC Cancel')
            dlg.set_default_response(Gtk.ResponseType.OK)
            if dlg.run() == Gtk.ResponseType.OK:
                uri = GLib.filename_to_uri(GLib.build_filenamev([path, cbzs[next_index]]), None)
                self.set_uri(uri)
            dlg.destroy()
            '''

で。

なんとかなった。
もう少し debug してから更新します。