Update: I believe this isn't specific to GtkEntry, but more that the keyboard input itself isn't being sent to the program (key events are no longer triggered).
I'm working on a display manager. I'm testing on Arch Linux. The idea is that when the user types in their credentials and hit enter, the display manager forks and launches the window manager specified in their ~/.xinitrc
. I'm testing with Awesome WM as the window manager. When the user exits the window manager, the display manager should then get back control so the user can log in again.
The issue is that after the user exits the window manager, the display manager is shown but I can't type into the GtkEntry box anymore. I can highlight the text and even right click and cut and paste, but I can't type. I've made a simplified example below. Note that if instead of launching the window manager I launch something like the sleep
command, everything works fine.
#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;
}
Here's how I compile the code:
gcc `pkg-config --cflags --libs gtk+-3.0` -Wall -o test test.c
To test this code, I start by running:
Xephyr -ac -br -noreset -screen 800x600 :1
This starts an X server in a window that I can use for testing. Then I start the code with
DISPLAY=:1 ./test
Which starts it in the Xephyr window. If you quit out of the display manager (in Awesome, you can right click and click "quit"), you'll see that you can't type in the text box anymore.