为 Gtk window 设置覆盖重定向会导致分段错误

Setting override redirect for Gtk window leads to segmentation fault

我正在尝试创建一个应用程序,我需要在其中绘制一个透明的 window,它保持在所有其他 windows 之上并且对 window 管理器不可见,因此试图将 window 的覆盖重定向设置为 true 。但是为 GdkWindow 设置覆盖重定向会导致分段错误。

#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;
}

使用

使用 gcc 进行编译
gcc -o out main.c `pkg-config --cflags --libs gtk+-3.0`

我在这里错过了什么?任何帮助表示赞赏。谢谢

您的代码失败,因为 gdk_windowNULL

您可以要求 window 使用 gtk_window_present 创建:

void activate(GtkApplication *app) {

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

    gtk_window_present(GTK_WINDOW(window));

    gdk_window_set_override_redirect(gdk_window, TRUE);

    gtk_widget_show_all(window);
}

gtk_widget_get_window() 可以 return NULL。您的代码出现段错误的原因可能是因为您在 NULL 指针上调用 gdk_window_set_override_redirect()

对于 gtk_widget_get_window() 可以 return NULL 的根本原因:GdkWindow 映射到表面的概念;在 X11 中,这称为 XWindow,因此得名。要让合成器显示您的 surface/XWindow,您必须明确 map 它。

GTK 在 GtkWindow 小部件被告知显示自身时(即当您调用 gtk_window_present()gtk_widget_show() 时)执行映射操作。一旦它实际与底层 GdkWindow 相关联,它就会发出“实现”信号,您可以连接到该信号。

因此,换句话说,您可以:

  • 调用 gdk_window_set_override_redirect(); after 显示 window
  • 连接到 window 变量的 "realize" 信号,并在回调
  • 中调用 gdk_window_set_override_redirect();