Search code examples
python-3.xsegmentation-faultgtkpygtkpygobject

PyGtk Segmentation with signal "activate link" in a markup-text label


The MWE below simply creates a label with a hyper-text in it. Most of the time (but not every time) it causes a Segmentation fault when I click on that link.

enter image description here

I assume that I missunderstand something about PyGtk and I use it the wrong way?

That is the error output:

Window._on_activate_link()
Fatal Python error: Segmentation fault

Current thread 0x00007fa2718a7740 (most recent call first):
  File "/usr/lib/python3/dist-packages/gi/overrides/Gtk.py", line 1641 in main
  File "./window.py", line 45 in <module>
Speicherzugriffsfehler

Here are informations about my system and versions

Linux-4.19.0-14-amd64-x86_64-with-debian-10.8
Python 3.7.3 CPython
Gtk 3.0
GIO 3.30.4
Cairo 1.16.2

This is the MWE

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import faulthandler; faulthandler.enable()
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk


class FeedybusWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)

        hbox = Gtk.Box(spacing=5)
        self.add(hbox)

        self._feed_label = Gtk.Label(label='')
        self._feed_label.set_use_markup(True)
        self._feed_label.set_markup('<a href="renamelabel">Click me</a>')
        self._feed_label.connect('activate-link', self._on_activate_link)
        hbox.pack_start(self._feed_label, True, True, 20)


        # EVENT: destroy
        self.connect('delete-event', self._on_delete_event)
        self.connect('destroy', self._on_destroy)

    def _on_activate_link(self, label, uri):
        print('Window._on_activate_link()')
        if uri == 'renamelabel':
            self._feed_label.set_markup('<a href="renamelabel">Click me AGAIN</a>')
            return True
 
        return False

    def _on_delete_event(self, window, event=None):
        self.destroy()

    def _on_destroy(self, caller):
        Gtk.main_quit()


if __name__ == '__main__':
    window = FeedybusWindow()
    window.show_all()
    Gtk.main()

EDIT: Of course I can use other GUI elements instead of a Gtk.Label. But this would be a workaround not a solution. The focus of my question is if I am using the Gtk package the wrong way or that there maybe is a bug in Gtk that I should report.


Solution

  • This must be a bug (maybe: https://gitlab.gnome.org/GNOME/gtk/-/issues/1498). I can't see any problems with your code, and I can reproduce the crash on my Ubuntu 20.04 system as well. It seems like setting the label in the activate-link handler is the problem.

    FWIW: A workaround is to set it outside the handler like this:

    def _on_activate_link(self, label, uri):
        print('Window._on_activate_link()')
        if uri == 'renamelabel':
             Gdk.threads_add_idle(GLib.PRIORITY_DEFAULT_IDLE, self._rename)
        return False
    
    def _rename(self):
        self._feed_label.set_markup('<a href="renamelabel">Click me AGAIN</a>')