gpt4 book ai didi

退出 fork 窗口管理器后无法输入 GtkEntry

转载 作者:行者123 更新时间:2023-11-30 19:44:24 25 4
gpt4 key购买 nike

更新:我相信这并不是 GtkEntry 特有的,而是键盘输入本身没有发送到程序(不再触发按键事件)。

我正在开发一个显示管理器。我正在 Arch Linux 上进行测试。这个想法是,当用户输入其凭据并按 Enter 键时,显示管理器会 fork 并启动在其 ~/.xinitrc 中指定的窗口管理器。我正在使用 Awesome WM 作为窗口管理器进行测试。当用户退出窗口管理器时,显示管理器应该重新获得控制权,以便用户可以再次登录。

问题是,用户退出窗口管理器后,会显示显示管理器,但我无法再在 GtkEntry 框中键入内容。我可以突出显示文本,甚至可以右键单击并剪切和粘贴,但我无法打字。我在下面做了一个简化的例子。请注意,如果我不启动窗口管理器而是启动诸如 sleep 命令之类的命令,那么一切都会正常工作。

#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

#include <gtk/gtk.h>

#define ENTER_KEY 65293

static pthread_t login_thread;

static void* login_func(void *data) {
pid_t child_pid = fork();
if (child_pid == 0) {
execl("/bin/bash", "/bin/bash", "--login", "/home/gulshan/.xinitrc", NULL); // This doesn't work
// execl("/usr/bin/awesome", "/usr/bin/awesome", NULL); // This doesn't work
// execl("/usr/bin/sleep", "/usr/bin/sleep", "5", NULL); // This works
printf("exec error");
exit(1);
}

// Wait for child process to finish
int status;
waitpid(child_pid, &status, 0);

printf("Returning from login_func\n");
return NULL;
}

static gboolean key_event(GtkWidget *widget, GdkEventKey *event) {
if (event->keyval == ENTER_KEY) {
pthread_create(&login_thread, NULL, login_func, (void*) widget);
}
return FALSE;
}

int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);

GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

gtk_container_add(GTK_CONTAINER(window), gtk_entry_new());
gtk_widget_show_all(window);

g_signal_connect(window, "key-release-event", G_CALLBACK(key_event), NULL);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();

return 0;
}

这是我编译代码的方法:

gcc `pkg-config --cflags --libs gtk+-3.0` -Wall -o test test.c

为了测试此代码,我首先运行:

Xephyr -ac -br -noreset -screen 800x600 :1

这会在一个窗口中启动一个 X 服务器,我可以用它来进行测试。然后我用

开始代码
DISPLAY=:1 ./test

这会在 Xephyr 窗口中启动它。如果您退出显示管理器(在 Awesome 中,您可以右键单击并单击“退出”),您将看到无法再在文本框中键入内容。

最佳答案

我认为你不应该混合线程和fork,请参阅threads-and-fork-think-twice-before-using-them

我已经修改了你的代码:

#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

#include <gtk/gtk.h>

#define ENTER_KEY 65293

static pthread_t login_thread;

static void* login_func(void *data) {
pid_t child_pid = fork();
if (child_pid == 0) {
execl("/usr/bin/awesome", "/usr/bin/awesome", NULL); // This doesn't work
printf("exec error");
exit(1);
}

// Wait for child process to finish
int status;
waitpid(child_pid, &status, 0);

printf("Returning from login_func\n");
return NULL;
}

static gboolean key_event(GtkWidget *widget, GdkEventKey *event) {
if (event->keyval == ENTER_KEY) {
login_func((void *) widget);
}
return FALSE;
}

int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);

GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

gtk_container_add(GTK_CONTAINER(window), gtk_entry_new());
gtk_widget_show_all(window);

g_signal_connect(window, "key-release-event", G_CALLBACK(key_event), NULL);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();

return 0;
}

正如你所看到的,我刚刚删除了该线程。现在,当我从 Awesome 注销时,我可以输入 gtk 条目。

关于退出 fork 窗口管理器后无法输入 GtkEntry,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28287520/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com