为 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_window
是 NULL
。
您可以要求 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();
我正在尝试创建一个应用程序,我需要在其中绘制一个透明的 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_window
是 NULL
。
您可以要求 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();