When a user successfully logs in, I fork a new process
that starts the window manager and wait for that process
to terminate. Since this is a long running operation, I
need to do this in a new thread so I don't block the GTK
thread.
However, I need to do various GTK operations during
this long running thread, such as updating label text or
hiding the window. I've read online that I should be using
`gdk_threads_add_idle` to do this.
```
static void* login_func(void *data) {
GtkWidget *widget = GTK_WIDGET(data);
const gchar *username =
gtk_entry_get_text(user_text_field);
const gchar *password =
gtk_entry_get_text(pass_text_field);
gdk_threads_add_idle(set_status_label_text,
"Logging in...");
pid_t child_pid;
if (login(username, password, &child_pid)) {
gdk_threads_add_idle(hide_widget, widget);
// Wait for child process to finish (wait for
logout)
int status;
waitpid(child_pid, &status, 0);
gdk_threads_add_idle(show_widget, widget);
gdk_threads_add_idle(set_status_label_text,
"");
logout();
} else {
gdk_threads_add_idle(set_status_label_text,
"Login error");
}
gdk_threads_add_idle(set_password_entry_text,
"");
return NULL;
}
static gboolean key_event(GtkWidget *widget,
GdkEventKey *event) {
if (event->keyval == ENTER_KEY) {
pthread_create(&login_thread, NULL,
login_func, (void*) widget);
} else if (event->keyval == ESC_KEY) {
gtk_main_quit();
}
return FALSE;
}
The problem is when the process I forked ends (the fork
happens in the `login` function, I see my display manager
screen again but I can no longer type in any of the text
boxes.
If there isn't anything obvious wrong in the above
code, I'd appreciate it if someone could run the display
manager and take a look at what's wrong. You can run it
with Xephyr. I start Xephyr with the command `Xephyr -ac
-br -noreset -screen 800x600 :2 &` and then I run
`DISPLAY=:2 ./display-manager`. Note that when you
log in, it executes the contents of ~/.xinitrc. In my
case, I have that set to `exec awesome`, and everything
works fine.
Any help would be appreciated.