Python3 Wnck throw segmentation fault!

I am using Wnck version 3 with python3. The following code cause my program to throw segmentation fault. What is the cause of this issue? and how could I solve it? so I could use Wnck safely. I don’t see an issue with my code a simple variable assignment cause segmentation fault!!!. To reproduce run the following script.

for i in {1..100}; do python3 window.py & sleep 0.5; sudo kill -9 `pgrep -f "python3 window.py"`; done

window.py

import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk

window = Gtk.Window()
window.connect('destroy', Gtk.main_quit)

window.show_all()

Gtk.main()

faulty_code.py

w = None
def on_window_opened(screen, window):
    global w
    if not window:
        return
    w = window
    
def main():
    Gdk.init([])
    loop = GLib.MainLoop.new(None, False)

    screen = Wnck.Screen.get_default()
    screen.connect("window-opened", on_window_opened)

    loop.run()

if __name__ == "__main__":
    main()
    /wnck_sigfault.py:10: Warning: invalid unclassed pointer in cast to 'WnckClassGroup'
    w = window
    /wnck_sigfault.py:10: Warning: g_hash_table_remove_internal: assertion 'hash_table != NULL' failed
    w = window
    Segmentation fault (core dumped)

The issue appears that there is a bug in libwnck when the WnckWindow object lives longer than the associated WnckClassGroup due to a missing g_object_weak_unref. I’ve submitted a MR to fix the issue. Depending on what you do, you can try to compile libwnck with those changes.

As a (unconfirmed) workaround, keep the Wnck.ClassGroup together with the window (use Wnck.Window.get_class_group()) so that both objects are kept alive and make sure to overwrite the class group first and window variable last. (window = ...; class_group = window.get_class_group(); ...; class_group = None; window = None) (One thing I’m not sure about is when the window gets “destroyed” by libwnck what happens with the xwindow id it references, whenever it should be reset to None or not…)

Alternatively, there is Wnck.Window.get_xid() to get an xid and Wnck.Window.get() to retrieve the window by xid.

You probably want to listen to the window-closed signal to remove your window references.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.