X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fmainloop.c;h=30ecbebd64a77cc06e0d31a8cdbcfc84a1c2c7e6;hb=cfc8101333535e3336eff5e929839c5262231db6;hp=2af81629e429cc6abeb880c8e59dc0d883f09435;hpb=2442cdfd85e5229c7ee4ac49ca66a7d55ffcb919;p=chaz%2Fopenbox diff --git a/openbox/mainloop.c b/openbox/mainloop.c index 2af81629..30ecbebd 100644 --- a/openbox/mainloop.c +++ b/openbox/mainloop.c @@ -18,8 +18,6 @@ */ #include "mainloop.h" -#include "action.h" -#include "client.h" #include "event.h" #include @@ -90,8 +88,6 @@ struct _ObMainLoop gboolean signal_fired; guint signals_fired[NUM_SIGNALS]; GSList *signal_handlers[NUM_SIGNALS]; - - GSList *action_queue; }; struct _ObMainLoopTimer @@ -108,6 +104,10 @@ struct _ObMainLoopTimer GTimeVal last; /* When this timer will next trigger */ GTimeVal timeout; + + /* Only allow a timer's function to fire once per run through the list, + so that it doesn't get locked in there forever */ + gboolean fired; }; struct _ObMainLoopSignalHandlerType @@ -182,8 +182,6 @@ ObMainLoop *ob_main_loop_new(Display *display) all_loops = g_slist_prepend(all_loops, loop); - loop->action_queue = NULL; - return loop; } @@ -222,8 +220,6 @@ void ob_main_loop_destroy(ObMainLoop *loop) /* only do this if we're the last loop destroyed */ if (!all_loops) { - guint i; - /* grab all the signals that cause core dumps */ for (i = 0; i < NUM_CORE_SIGNALS; ++i) { if (all_signals[core_signals[i]].installed) { @@ -234,10 +230,6 @@ void ob_main_loop_destroy(ObMainLoop *loop) } } - for (it = loop->action_queue; it; it = g_slist_next(it)) - action_unref(it->data); - g_slist_free(loop->action_queue); - g_free(loop); } } @@ -253,37 +245,16 @@ static void fd_handle_foreach(gpointer key, h->func(h->fd, h->data); } -void ob_main_loop_queue_action(ObMainLoop *loop, ObAction *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) { XEvent e; struct timeval *wait; fd_set selset; GSList *it; - ObAction *act; loop->run = TRUE; loop->running = TRUE; - client_add_destructor(ob_main_loop_client_destroy, loop); - while (loop->run) { if (loop->signal_fired) { guint i; @@ -314,34 +285,7 @@ void ob_main_loop_run(ObMainLoop *loop) ObMainLoopXHandlerType *h = it->data; h->func(&e, h->data); } - } while (XPending(loop->display)); - } 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 :) */ - - 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) { - event_curtime = act->data.any.time; - act->func(&act->data); - event_curtime = CurrentTime; - loop->action_queue = - g_slist_delete_link(loop->action_queue, - loop->action_queue); - action_unref(act); - } + } while (XPending(loop->display) && loop->run); } else { /* this only runs if there were no x events received */ @@ -365,8 +309,6 @@ void ob_main_loop_run(ObMainLoop *loop) } } - client_remove_destructor(ob_main_loop_client_destroy); - loop->running = FALSE; } @@ -565,7 +507,7 @@ static glong timecompare(GTimeVal *a, GTimeVal *b) if ((r = b->tv_sec - a->tv_sec)) return r; return b->tv_usec - a->tv_usec; - + } static void insert_timer(ObMainLoop *loop, ObMainLoopTimer *ins) @@ -620,9 +562,11 @@ void ob_main_loop_timeout_remove_data(ObMainLoop *loop, GSourceFunc handler, { GSList *it; + ob_debug("removing data 0x%x\n", data); for (it = loop->timers; it; it = g_slist_next(it)) { ObMainLoopTimer *t = it->data; if (t->func == handler && t->equal(t->data, data)) { + ob_debug("found data 0x%x\n", data); t->del_me = TRUE; if (cancel_dest) t->destroy = NULL; @@ -659,9 +603,15 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait) g_get_current_time(&loop->now); + /* do this first, cuz the list can get reordered */ + for (it = loop->timers; it; it = g_slist_next(it)) { + ObMainLoopTimer *curr = it->data; + curr->fired = FALSE; + } + for (it = loop->timers; it; it = next) { ObMainLoopTimer *curr; - + next = g_slist_next(it); curr = it->data; @@ -671,18 +621,24 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait) */ if (curr->del_me) { /* delete the top */ - loop->timers = g_slist_delete_link(loop->timers, it); + loop->timers = g_slist_delete_link(loop->timers, it); if (curr->destroy) curr->destroy(curr->data); g_free(curr); continue; } - /* the queue is sorted, so if this timer shouldn't fire, none are + /* the queue is sorted, so if this timer shouldn't fire, none are ready */ if (timecompare(&NEAREST_TIMEOUT(loop), &loop->now) < 0) break; + /* don't let it fire again this time around. otherwise, if the first + timer in the queue becomes ready, we'll loop on the later ones + forever if they repeat */ + if (curr->fired) + continue; + /* we set the last fired time to delay msec after the previous firing, then re-insert. timers maintain their order and may trigger more than once if they've waited more than one delay's worth of time. @@ -698,6 +654,7 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait) g_free(curr); } + curr->fired = TRUE; fired = TRUE; }