#include "mainloop.h"
#include "action.h"
+#include "client.h"
#include <stdio.h>
#include <stdlib.h>
guint signals_fired[NUM_SIGNALS];
GSList *signal_handlers[NUM_SIGNALS];
- GQueue *action_queue;
+ GSList *action_queue;
};
struct _ObMainLoopTimer
all_loops = g_slist_prepend(all_loops, loop);
- loop->action_queue = g_queue_new();
+ loop->action_queue = NULL;
return loop;
}
}
}
- g_queue_free(loop->action_queue);
+ for (it = loop->action_queue; it; it = g_slist_next(it))
+ action_unref(it->data);
+ g_slist_free(loop->action_queue);
g_free(loop);
}
void ob_main_loop_queue_action(ObMainLoop *loop, ObAction *act)
{
- g_queue_push_tail(loop->action_queue, action_copy(act));
+ loop->action_queue = g_slist_append(loop->action_queue, action_copy(act));
+}
+
+static void ob_main_loop_client_destroy(ObClient *client, gpointer data)
+{
+ ObMainLoop *loop = data;
+ GSList *it;
+
+ for (it = loop->action_queue; it; it = g_slist_next(it)) {
+ ObAction *act = it->data;
+
+ if (act->data.any.c == client)
+ act->data.any.c = NULL;
+ }
}
void ob_main_loop_run(ObMainLoop *loop)
loop->run = TRUE;
loop->running = TRUE;
+ client_add_destructor(ob_main_loop_client_destroy, loop);
+
while (loop->run) {
if (loop->signal_fired) {
guint i;
h->func(&e, h->data);
}
} while (XPending(loop->display));
- } else if ((act = g_queue_pop_head(loop->action_queue))) {
+ } else if (loop->action_queue) {
/* only fire off one action at a time, then go back for more
X events, since the action might cause some X events (like
FocusIn :) */
- act->func(&act->data);
- action_unref(act);
+
+ do {
+ act = loop->action_queue->data;
+ if (act->data.any.client_action == OB_CLIENT_ACTION_ALWAYS &&
+ !act->data.any.c)
+ {
+ loop->action_queue =
+ g_slist_delete_link(loop->action_queue,
+ loop->action_queue);
+ action_unref(act);
+ act = NULL;
+ }
+ } while (!act && loop->action_queue);
+
+ if (act) {
+ act->func(&act->data);
+ loop->action_queue =
+ g_slist_delete_link(loop->action_queue,
+ loop->action_queue);
+ action_unref(act);
+ }
} else {
/* this only runs if there were no x events received */
}
}
+ client_remove_destructor(ob_main_loop_client_destroy);
+
loop->running = FALSE;
}