Search code examples
clinuxgtk

Setting override redirect for Gtk window leads to segmentation fault


I am trying to create an application in which I need to draw on a transparent window which stays above all other windows and invisible to the window manager, hence trying to set the override redirect of a window to true .But setting the override redirect for a GdkWindow causes segmentation fault.

#include <gtk/gtk.h>

void activate(GtkApplication *app) {

    GtkWidget *window = gtk_application_window_new(app);
    GdkWindow *gdk_window = gtk_widget_get_window(window);
    gdk_window_set_override_redirect(gdk_window, TRUE);

    gtk_widget_show_all(window);
}

int main(int argc, char **argv) {

    GtkApplication *app = gtk_application_new("com.github.application.name",
                          G_APPLICATION_FLAGS_NONE);
    g_signal_connect(app, "activate", G_CALLBACK (activate), NULL);

    int status = g_application_run(G_APPLICATION (app), argc, argv);
    g_object_unref(app);

    return status;
}

compiling with gcc using

gcc -o out main.c `pkg-config --cflags --libs gtk+-3.0`

what am I missing here? any help is appreciated. Thanks.


Solution

  • gtk_widget_get_window() can return NULL. The reason your code is segfaulting is probably because you're calling gdk_window_set_override_redirect() on a NULL pointer.

    For the underlying reason why gtk_widget_get_window() can return NULL: a GdkWindow maps to the concept of a surface; in X11 this is called an XWindow, hence the name. To let the compositor show your surface/XWindow, you have to explicitly map it.

    GTK does the mapping operation the moment the GtkWindow widget is told to show itself (ie when you call gtk_window_present() or gtk_widget_show()). Once it actually associates with an underlying GdkWindow, it will emit the "realize" signal to which you can connect to .

    So, in other words, you can either:

    • Call gdk_window_set_override_redirect(); after showing the window
    • Connect to the "realize" signal of your window variable, and call gdk_window_set_override_redirect(); inside the callback