Use GMainLoop instead of ObtMainLoop
authorDana Jansens <danakj@orodu.net>
Tue, 8 Jun 2010 21:50:23 +0000 (17:50 -0400)
committerDana Jansens <danakj@orodu.net>
Mon, 14 Jun 2010 16:19:01 +0000 (12:19 -0400)
22 files changed:
Makefile.am
obt/mainloop.c [deleted file]
obt/mainloop.h [deleted file]
obt/xevent.c [deleted file]
obt/xevent.h [deleted file]
obt/xqueue.c
obt/xqueue.h
openbox/dock.c
openbox/event.c
openbox/frame.c
openbox/frame.h
openbox/keyboard.c
openbox/menu.c
openbox/menuframe.c
openbox/moveresize.c
openbox/openbox.c
openbox/openbox.h
openbox/ping.c
openbox/popup.c
openbox/popup.h
openbox/screen.c
openbox/startupnotify.c

index 4c670bc..246abed 100644 (file)
@@ -134,8 +134,6 @@ obt_libobt_la_SOURCES = \
        obt/internal.h \
        obt/keyboard.h \
        obt/keyboard.c \
-       obt/mainloop.h \
-       obt/mainloop.c \
        obt/xml.h \
        obt/xml.c \
        obt/ddparse.h \
@@ -147,8 +145,6 @@ obt_libobt_la_SOURCES = \
        obt/prop.h \
        obt/prop.c \
        obt/util.h \
-       obt/xevent.h \
-       obt/xevent.c \
        obt/xqueue.h \
        obt/xqueue.c
 
@@ -437,13 +433,11 @@ obtpubinclude_HEADERS = \
        obt/link.h \
        obt/display.h \
        obt/keyboard.h \
-       obt/mainloop.h \
        obt/xml.h \
        obt/paths.h \
        obt/prop.h \
        obt/util.h \
        obt/version.h \
-       obt/xevent.h \
        obt/xqueue.h
 
 nodist_pkgconfig_DATA = \
diff --git a/obt/mainloop.c b/obt/mainloop.c
deleted file mode 100644 (file)
index 7536625..0000000
+++ /dev/null
@@ -1,698 +0,0 @@
-/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
-
-   obt/mainloop.c for the Openbox window manager
-   Copyright (c) 2006        Mikael Magnusson
-   Copyright (c) 2003-2007   Dana Jansens
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   See the COPYING file for a copy of the GNU General Public License.
-*/
-
-#include "obt/mainloop.h"
-#include "obt/display.h"
-#include "obt/xqueue.h"
-#include "obt/util.h"
-
-#ifdef HAVE_STDIO_H
-#include <stdio.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-
-typedef struct _ObtMainLoopTimer             ObtMainLoopTimer;
-typedef struct _ObtMainLoopSignal            ObtMainLoopSignal;
-typedef struct _ObtMainLoopSignalHandlerType ObtMainLoopSignalHandlerType;
-typedef struct _ObtMainLoopXHandlerType      ObtMainLoopXHandlerType;
-typedef struct _ObtMainLoopFdHandlerType     ObtMainLoopFdHandlerType;
-
-/* this should be more than the number of possible signals on any
-   architecture... */
-#define NUM_SIGNALS 99
-
-/* all created ObtMainLoops. Used by the signal handler to pass along
-   signals */
-static GSList *all_loops;
-
-/* signals are global to all loops */
-static struct {
-    guint installed; /* a ref count */
-    struct sigaction oldact;
-} all_signals[NUM_SIGNALS];
-
-/* a set of all possible signals */
-static sigset_t all_signals_set;
-
-/* signals which cause a core dump, these can't be used for callbacks */
-static gint core_signals[] =
-{
-    SIGABRT,
-    SIGSEGV,
-    SIGFPE,
-    SIGILL,
-    SIGQUIT,
-    SIGTRAP,
-    SIGSYS,
-    SIGBUS,
-    SIGXCPU,
-    SIGXFSZ
-};
-#define NUM_CORE_SIGNALS (sizeof(core_signals) / sizeof(core_signals[0]))
-
-static void sighandler(gint sig);
-static void timer_dispatch(ObtMainLoop *loop, GTimeVal **wait);
-static void fd_handler_destroy(gpointer data);
-static void calc_max_fd(ObtMainLoop *loop);
-
-struct _ObtMainLoop
-{
-    gint ref;
-    Display *display;
-
-    gboolean run;     /* do keep running */
-    gboolean running; /* is still running */
-
-    GSList *x_handlers;
-
-    gint fd_x; /* The X fd is a special case! */
-    gint fd_max;
-    GHashTable *fd_handlers;
-    fd_set fd_set;
-
-    GSList *timers;
-    GTimeVal now;
-    GTimeVal ret_wait;
-
-    gboolean signal_fired;
-    guint signals_fired[NUM_SIGNALS];
-    GSList *signal_handlers[NUM_SIGNALS];
-};
-
-struct _ObtMainLoopTimer
-{
-    gulong delay;
-    GSourceFunc func;
-    gpointer data;
-    GEqualFunc equal;
-    GDestroyNotify destroy;
-
-    /* The timer needs to be freed */
-    gboolean del_me;
-    /* The time the last fire should've been at */
-    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 _ObtMainLoopSignalHandlerType
-{
-    ObtMainLoop *loop;
-    gint signal;
-    gpointer data;
-    ObtMainLoopSignalHandler func;
-    GDestroyNotify destroy;
-};
-
-struct _ObtMainLoopXHandlerType
-{
-    ObtMainLoop *loop;
-    gpointer data;
-    ObtMainLoopXHandler func;
-    GDestroyNotify destroy;
-};
-
-struct _ObtMainLoopFdHandlerType
-{
-    ObtMainLoop *loop;
-    gint fd;
-    gpointer data;
-    ObtMainLoopFdHandler func;
-    GDestroyNotify destroy;
-};
-
-ObtMainLoop *obt_main_loop_new(void)
-{
-    ObtMainLoop *loop;
-
-    loop = g_slice_new0(ObtMainLoop);
-    loop->ref = 1;
-    FD_ZERO(&loop->fd_set);
-    loop->fd_x = -1;
-    loop->fd_max = -1;
-
-    loop->fd_handlers = g_hash_table_new_full(g_int_hash, g_int_equal,
-                                              NULL, fd_handler_destroy);
-
-    g_get_current_time(&loop->now);
-
-    /* only do this if we're the first loop created */
-    if (!all_loops) {
-        guint i;
-        struct sigaction action;
-        sigset_t sigset;
-
-        /* initialize the all_signals_set */
-        sigfillset(&all_signals_set);
-
-        sigemptyset(&sigset);
-        action.sa_handler = sighandler;
-        action.sa_mask = sigset;
-        action.sa_flags = SA_NOCLDSTOP;
-
-        /* grab all the signals that cause core dumps */
-        for (i = 0; i < NUM_CORE_SIGNALS; ++i) {
-            /* SIGABRT is curiously not grabbed here!! that's because when we
-               get one of the core_signals, we use abort() to dump the core.
-               And having the abort() only go back to our signal handler again
-               is less than optimal */
-            if (core_signals[i] != SIGABRT) {
-                sigaction(core_signals[i], &action,
-                          &all_signals[core_signals[i]].oldact);
-                all_signals[core_signals[i]].installed++;
-            }
-        }
-    }
-
-    all_loops = g_slist_prepend(all_loops, loop);
-
-    return loop;
-}
-
-void obt_main_loop_ref(ObtMainLoop *loop)
-{
-    ++loop->ref;
-}
-
-void obt_main_loop_unref(ObtMainLoop *loop)
-{
-    guint i;
-    GSList *it, *next;
-
-    if (loop && --loop->ref == 0) {
-        g_assert(loop->running == FALSE);
-
-        for (it = loop->x_handlers; it; it = next) {
-            ObtMainLoopXHandlerType *h = it->data;
-            next = g_slist_next(it);
-            obt_main_loop_x_remove(loop, h->func);
-        }
-
-        g_hash_table_destroy(loop->fd_handlers);
-
-        for (it = loop->timers; it; it = g_slist_next(it)) {
-            ObtMainLoopTimer *t = it->data;
-            if (t->destroy) t->destroy(t->data);
-            g_slice_free(ObtMainLoopTimer, t);
-        }
-        g_slist_free(loop->timers);
-        loop->timers = NULL;
-
-        for (i = 0; i < NUM_SIGNALS; ++i)
-            for (it = loop->signal_handlers[i]; it; it = next) {
-                ObtMainLoopSignalHandlerType *h = it->data;
-                next = g_slist_next(it);
-                obt_main_loop_signal_remove(loop, h->func);
-            }
-
-        all_loops = g_slist_remove(all_loops, loop);
-
-        /* only do this if we're the last loop destroyed */
-        if (!all_loops) {
-            /* grab all the signals that cause core dumps */
-            for (i = 0; i < NUM_CORE_SIGNALS; ++i) {
-                if (all_signals[core_signals[i]].installed) {
-                    sigaction(core_signals[i],
-                              &all_signals[core_signals[i]].oldact, NULL);
-                    all_signals[core_signals[i]].installed--;
-                }
-            }
-        }
-
-        g_slice_free(ObtMainLoop, loop);
-    }
-}
-
-static void fd_handle_foreach(gpointer key,
-                              gpointer value,
-                              gpointer data)
-{
-    ObtMainLoopFdHandlerType *h = value;
-    fd_set *set = data;
-
-    if (FD_ISSET(h->fd, set))
-        h->func(h->fd, h->data);
-}
-
-void obt_main_loop_run(ObtMainLoop *loop)
-{
-    XEvent e;
-    struct timeval *wait;
-    fd_set selset;
-    GSList *it;
-
-    loop->run = TRUE;
-    loop->running = TRUE;
-
-    while (loop->run) {
-        if (loop->signal_fired) {
-            guint i;
-            sigset_t oldset;
-
-            /* block signals so that we can do this without the data changing
-               on us */
-            sigprocmask(SIG_SETMASK, &all_signals_set, &oldset);
-
-            for (i = 0; i < NUM_SIGNALS; ++i) {
-                while (loop->signals_fired[i]) {
-                    for (it = loop->signal_handlers[i];
-                            it; it = g_slist_next(it)) {
-                        ObtMainLoopSignalHandlerType *h = it->data;
-                        h->func(i, h->data);
-                    }
-                    loop->signals_fired[i]--;
-                }
-            }
-            loop->signal_fired = FALSE;
-
-            sigprocmask(SIG_SETMASK, &oldset, NULL);
-        } else if (loop->display && xqueue_pending_local()) {
-            while (xqueue_next_local(&e) && loop->run) {
-                if (e.type == MappingNotify)
-                    XRefreshKeyboardMapping(&e.xmapping);
-
-                for (it = loop->x_handlers; it; it = g_slist_next(it)) {
-                    ObtMainLoopXHandlerType *h = it->data;
-                    h->func(&e, h->data);
-                }
-            }
-        } else {
-            /* this only runs if there were no x events received */
-            timer_dispatch(loop, (GTimeVal**)&wait);
-
-            selset = loop->fd_set;
-            /* there is a small race condition here. if a signal occurs
-               between this if() and the select() then we will not process
-               the signal until 'wait' expires. possible solutions include
-               using GStaticMutex, and having the signal handler set 'wait'
-               to 0 */
-            if (!loop->signal_fired)
-                select(loop->fd_max + 1, &selset, NULL, NULL, wait);
-
-            /* handle the X events with highest prioirity */
-            if (FD_ISSET(loop->fd_x, &selset))
-                continue;
-
-            g_hash_table_foreach(loop->fd_handlers,
-                                 fd_handle_foreach, &selset);
-        }
-    }
-
-    loop->running = FALSE;
-}
-
-void obt_main_loop_exit(ObtMainLoop *loop)
-{
-    loop->run = FALSE;
-}
-
-/*** XEVENT WATCHERS ***/
-
-void obt_main_loop_x_add(ObtMainLoop *loop,
-                         ObtMainLoopXHandler handler,
-                         gpointer data,
-                         GDestroyNotify notify)
-{
-    ObtMainLoopXHandlerType *h;
-
-    h = g_slice_new(ObtMainLoopXHandlerType);
-    h->loop = loop;
-    h->func = handler;
-    h->data = data;
-    h->destroy = notify;
-
-    if (!loop->x_handlers) {
-        g_assert(obt_display); /* is the display open? */
-
-        loop->display = obt_display;
-        loop->fd_x = ConnectionNumber(loop->display);
-        FD_SET(loop->fd_x, &loop->fd_set);
-        calc_max_fd(loop);
-    }
-
-    loop->x_handlers = g_slist_prepend(loop->x_handlers, h);
-}
-
-void obt_main_loop_x_remove(ObtMainLoop *loop,
-                            ObtMainLoopXHandler handler)
-{
-    GSList *it, *next;
-
-    for (it = loop->x_handlers; it; it = next) {
-        ObtMainLoopXHandlerType *h = it->data;
-        next = g_slist_next(it);
-        if (h->func == handler) {
-            loop->x_handlers = g_slist_delete_link(loop->x_handlers, it);
-            if (h->destroy) h->destroy(h->data);
-            g_slice_free(ObtMainLoopXHandlerType, h);
-        }
-    }
-
-    if (!loop->x_handlers) {
-        FD_CLR(loop->fd_x, &loop->fd_set);
-        calc_max_fd(loop);
-    }
-}
-
-/*** SIGNAL WATCHERS ***/
-
-static void sighandler(gint sig)
-{
-    GSList *it;
-    guint i;
-
-    g_return_if_fail(sig < NUM_SIGNALS);
-
-    for (i = 0; i < NUM_CORE_SIGNALS; ++i)
-        if (sig == core_signals[i]) {
-            /* XXX special case for signals that default to core dump.
-               but throw some helpful output here... */
-
-            fprintf(stderr, "How are you gentlemen? All your base are"
-                    " belong to us. (Openbox received signal %d)\n", sig);
-
-            /* die with a core dump */
-            abort();
-        }
-
-    for (it = all_loops; it; it = g_slist_next(it)) {
-        ObtMainLoop *loop = it->data;
-        loop->signal_fired = TRUE;
-        loop->signals_fired[sig]++;
-    }
-}
-
-void obt_main_loop_signal_add(ObtMainLoop *loop,
-                              gint signal,
-                              ObtMainLoopSignalHandler handler,
-                              gpointer data,
-                              GDestroyNotify notify)
-{
-    ObtMainLoopSignalHandlerType *h;
-
-    g_return_if_fail(signal < NUM_SIGNALS);
-
-    h = g_slice_new(ObtMainLoopSignalHandlerType);
-    h->loop = loop;
-    h->signal = signal;
-    h->func = handler;
-    h->data = data;
-    h->destroy = notify;
-    loop->signal_handlers[h->signal] =
-        g_slist_prepend(loop->signal_handlers[h->signal], h);
-
-    if (!all_signals[signal].installed) {
-        struct sigaction action;
-        sigset_t sigset;
-
-        sigemptyset(&sigset);
-        action.sa_handler = sighandler;
-        action.sa_mask = sigset;
-        action.sa_flags = SA_NOCLDSTOP;
-
-        sigaction(signal, &action, &all_signals[signal].oldact);
-    }
-
-    all_signals[signal].installed++;
-}
-
-void obt_main_loop_signal_remove(ObtMainLoop *loop,
-                                 ObtMainLoopSignalHandler handler)
-{
-    guint i;
-    GSList *it, *next;
-
-    for (i = 0; i < NUM_SIGNALS; ++i) {
-        for (it = loop->signal_handlers[i]; it; it = next) {
-            ObtMainLoopSignalHandlerType *h = it->data;
-
-            next = g_slist_next(it);
-
-            if (h->func == handler) {
-                g_assert(all_signals[h->signal].installed > 0);
-
-                all_signals[h->signal].installed--;
-                if (!all_signals[h->signal].installed) {
-                    sigaction(h->signal, &all_signals[h->signal].oldact, NULL);
-                }
-
-                loop->signal_handlers[i] =
-                    g_slist_delete_link(loop->signal_handlers[i], it);
-                if (h->destroy) h->destroy(h->data);
-
-                g_slice_free(ObtMainLoopSignalHandlerType, h);
-            }
-        }
-    }
-
-}
-
-/*** FILE DESCRIPTOR WATCHERS ***/
-
-static void max_fd_func(gpointer key, gpointer value, gpointer data)
-{
-    ObtMainLoop *loop = data;
-
-    /* key is the fd */
-    loop->fd_max = MAX(loop->fd_max, *(gint*)key);
-}
-
-static void calc_max_fd(ObtMainLoop *loop)
-{
-    loop->fd_max = loop->fd_x;
-
-    g_hash_table_foreach(loop->fd_handlers, max_fd_func, loop);
-}
-
-void obt_main_loop_fd_add(ObtMainLoop *loop,
-                          gint fd,
-                          ObtMainLoopFdHandler handler,
-                          gpointer data,
-                          GDestroyNotify notify)
-{
-    ObtMainLoopFdHandlerType *h;
-
-    h = g_slice_new(ObtMainLoopFdHandlerType);
-    h->loop = loop;
-    h->fd = fd;
-    h->func = handler;
-    h->data = data;
-    h->destroy = notify;
-
-    g_hash_table_replace(loop->fd_handlers, &h->fd, h);
-    FD_SET(h->fd, &loop->fd_set);
-    calc_max_fd(loop);
-}
-
-static void fd_handler_destroy(gpointer data)
-{
-    ObtMainLoopFdHandlerType *h = data;
-
-    FD_CLR(h->fd, &h->loop->fd_set);
-
-    if (h->destroy)
-        h->destroy(h->data);
-    g_slice_free(ObtMainLoopFdHandlerType, h);
-}
-
-void obt_main_loop_fd_remove(ObtMainLoop *loop,
-                             gint fd)
-{
-    g_hash_table_remove(loop->fd_handlers, &fd);
-    calc_max_fd(loop);
-}
-
-/*** TIMEOUTS ***/
-
-#define NEAREST_TIMEOUT(loop) \
-    (((ObtMainLoopTimer*)(loop)->timers->data)->timeout)
-
-static glong timecompare(GTimeVal *a, GTimeVal *b)
-{
-    glong r;
-    if ((r = a->tv_sec - b->tv_sec)) return r;
-    return a->tv_usec - b->tv_usec;
-}
-
-static void insert_timer(ObtMainLoop *loop, ObtMainLoopTimer *ins)
-{
-    GSList *it;
-    for (it = loop->timers; it; it = g_slist_next(it)) {
-        ObtMainLoopTimer *t = it->data;
-        if (timecompare(&ins->timeout, &t->timeout) <= 0) {
-            loop->timers = g_slist_insert_before(loop->timers, it, ins);
-            break;
-        }
-    }
-    if (it == NULL) /* didnt fit anywhere in the list */
-        loop->timers = g_slist_append(loop->timers, ins);
-}
-
-void obt_main_loop_timeout_add(ObtMainLoop *loop,
-                               gulong microseconds,
-                               GSourceFunc handler,
-                               gpointer data,
-                               GEqualFunc cmp,
-                               GDestroyNotify notify)
-{
-    ObtMainLoopTimer *t = g_slice_new(ObtMainLoopTimer);
-
-    g_assert(microseconds > 0); /* if it's 0 it'll cause an infinite loop */
-
-    t->delay = microseconds;
-    t->func = handler;
-    t->data = data;
-    t->equal = cmp;
-    t->destroy = notify;
-    t->del_me = FALSE;
-    g_get_current_time(&loop->now);
-    t->last = t->timeout = loop->now;
-    g_time_val_add(&t->timeout, t->delay);
-
-    insert_timer(loop, t);
-}
-
-void obt_main_loop_timeout_remove(ObtMainLoop *loop,
-                                  GSourceFunc handler)
-{
-    GSList *it;
-
-    for (it = loop->timers; it; it = g_slist_next(it)) {
-        ObtMainLoopTimer *t = it->data;
-        if (t->func == handler)
-            t->del_me = TRUE;
-    }
-}
-
-void obt_main_loop_timeout_remove_data(ObtMainLoop *loop, GSourceFunc handler,
-                                       gpointer data, gboolean cancel_dest)
-{
-    GSList *it;
-
-    for (it = loop->timers; it; it = g_slist_next(it)) {
-        ObtMainLoopTimer *t = it->data;
-        if (t->func == handler && t->equal(t->data, data)) {
-            t->del_me = TRUE;
-            if (cancel_dest)
-                t->destroy = NULL;
-        }
-    }
-}
-
-/* find the time to wait for the nearest timeout */
-static gboolean nearest_timeout_wait(ObtMainLoop *loop, GTimeVal *tm)
-{
-  if (loop->timers == NULL)
-    return FALSE;
-
-  tm->tv_sec = NEAREST_TIMEOUT(loop).tv_sec - loop->now.tv_sec;
-  tm->tv_usec = NEAREST_TIMEOUT(loop).tv_usec - loop->now.tv_usec;
-
-  while (tm->tv_usec < 0) {
-    tm->tv_usec += G_USEC_PER_SEC;
-    tm->tv_sec--;
-  }
-  tm->tv_sec += tm->tv_usec / G_USEC_PER_SEC;
-  tm->tv_usec %= G_USEC_PER_SEC;
-  if (tm->tv_sec < 0)
-    tm->tv_sec = 0;
-
-  return TRUE;
-}
-
-static void timer_dispatch(ObtMainLoop *loop, GTimeVal **wait)
-{
-    GSList *it, *next;
-
-    gboolean fired = FALSE;
-
-    g_get_current_time(&loop->now);
-
-    for (it = loop->timers; it; it = next) {
-        ObtMainLoopTimer *curr;
-
-        next = g_slist_next(it);
-
-        curr = it->data;
-
-        /* since timer_stop doesn't actually free the timer, we have to do our
-           real freeing in here.
-        */
-        if (curr->del_me) {
-            /* delete the top */
-            loop->timers = g_slist_delete_link(loop->timers, it);
-            if (curr->destroy)
-                curr->destroy(curr->data);
-            g_slice_free(ObtMainLoopTimer, curr);
-            continue;
-        }
-
-        /* the queue is sorted, so if this timer shouldn't fire, none are
-           ready */
-        if (timecompare(&NEAREST_TIMEOUT(loop), &loop->now) > 0)
-            break;
-
-        /* 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.
-        */
-        loop->timers = g_slist_delete_link(loop->timers, it);
-        g_time_val_add(&curr->last, curr->delay);
-        if (curr->func(curr->data)) {
-            g_time_val_add(&curr->timeout, curr->delay);
-            insert_timer(loop, curr);
-        } else {
-            if (curr->destroy)
-                curr->destroy(curr->data);
-            g_slice_free(ObtMainLoopTimer, curr);
-        }
-
-        /* the timer queue has been shuffled, start from the beginning
-           (which is the next one to fire) */
-        next = loop->timers;
-
-        fired = TRUE;
-    }
-
-    if (fired) {
-        /* if at least one timer fires, then don't wait on X events, as there
-           may already be some in the queue from the timer callbacks.
-        */
-        loop->ret_wait.tv_sec = loop->ret_wait.tv_usec = 0;
-        *wait = &loop->ret_wait;
-    } else if (nearest_timeout_wait(loop, &loop->ret_wait))
-        *wait = &loop->ret_wait;
-    else
-        *wait = NULL;
-}
diff --git a/obt/mainloop.h b/obt/mainloop.h
deleted file mode 100644 (file)
index f455d62..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
-
-   obt/mainloop.h for the Openbox window manager
-   Copyright (c) 2006        Mikael Magnusson
-   Copyright (c) 2003-2007   Dana Jansens
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   See the COPYING file for a copy of the GNU General Public License.
-*/
-
-#ifndef __obt_mainloop_h
-#define __obt_mainloop_h
-
-#include <X11/Xlib.h>
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-typedef struct _ObtMainLoop ObtMainLoop;
-
-ObtMainLoop *obt_main_loop_new(void);
-void        obt_main_loop_ref(ObtMainLoop *loop);
-void        obt_main_loop_unref(ObtMainLoop *loop);
-
-typedef void (*ObtMainLoopXHandler) (const XEvent *e, gpointer data);
-
-void obt_main_loop_x_add(ObtMainLoop *loop,
-                         ObtMainLoopXHandler handler,
-                         gpointer data,
-                         GDestroyNotify notify);
-void obt_main_loop_x_remove(ObtMainLoop *loop,
-                            ObtMainLoopXHandler handler);
-
-typedef void (*ObtMainLoopFdHandler) (gint fd, gpointer data);
-
-void obt_main_loop_fd_add(ObtMainLoop *loop,
-                          gint fd,
-                          ObtMainLoopFdHandler handler,
-                          gpointer data,
-                          GDestroyNotify notify);
-void obt_main_loop_fd_remove(ObtMainLoop *loop,
-                             gint fd);
-
-typedef void (*ObtMainLoopSignalHandler) (gint signal, gpointer data);
-
-void obt_main_loop_signal_add(ObtMainLoop *loop,
-                              gint signal,
-                              ObtMainLoopSignalHandler handler,
-                              gpointer data,
-                              GDestroyNotify notify);
-void obt_main_loop_signal_remove(ObtMainLoop *loop,
-                                 ObtMainLoopSignalHandler handler);
-
-void obt_main_loop_timeout_add(ObtMainLoop *loop,
-                               gulong microseconds,
-                               GSourceFunc handler,
-                               gpointer data,
-                               GEqualFunc cmp,
-                               GDestroyNotify notify);
-void obt_main_loop_timeout_remove(ObtMainLoop *loop,
-                                  GSourceFunc handler);
-void obt_main_loop_timeout_remove_data(ObtMainLoop *loop,
-                                       GSourceFunc handler,
-                                       gpointer data,
-                                       gboolean cancel_dest);
-
-void obt_main_loop_run(ObtMainLoop *loop);
-void obt_main_loop_exit(ObtMainLoop *loop);
-
-G_END_DECLS
-
-#endif
diff --git a/obt/xevent.c b/obt/xevent.c
deleted file mode 100644 (file)
index 1077165..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
-
-   obt/xevent.c for the Openbox window manager
-   Copyright (c) 2007        Dana Jansens
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   See the COPYING file for a copy of the GNU General Public License.
-*/
-
-#include "obt/xevent.h"
-#include "obt/mainloop.h"
-#include "obt/util.h"
-
-typedef struct _ObtXEventBinding ObtXEventBinding;
-
-struct _ObtXEventHandler
-{
-    gint ref;
-    ObtMainLoop *loop;
-
-    /* An array of hash tables where the key is the window, and the value is
-       the ObtXEventBinding */
-    GHashTable **bindings;
-    gint num_event_types; /* the length of the bindings array */
-};
-
-struct _ObtXEventBinding
-{
-    Window win;
-    ObtXEventCallback func;
-    gpointer data;
-};
-
-static void xevent_handler(const XEvent *e, gpointer data);
-static guint window_hash(Window *w) { return *w; }
-static gboolean window_comp(Window *w1, Window *w2) { return *w1 == *w2; }
-static void binding_free(gpointer b);
-
-ObtXEventHandler* xevent_new(void)
-{
-    ObtXEventHandler *h;
-
-    h = g_slice_new0(ObtXEventHandler);
-    h->ref = 1;
-
-    return h;
-}
-
-void xevent_ref(ObtXEventHandler *h)
-{
-    ++h->ref;
-}
-
-void xevent_unref(ObtXEventHandler *h)
-{
-    if (h && --h->ref == 0) {
-        gint i;
-
-        if (h->loop)
-            obt_main_loop_x_remove(h->loop, xevent_handler);
-        for (i = 0; i < h->num_event_types; ++i)
-            g_hash_table_destroy(h->bindings[i]);
-        g_free(h->bindings);
-
-        g_slice_free(ObtXEventHandler, h);
-    }
-}
-
-void xevent_register(ObtXEventHandler *h, ObtMainLoop *loop)
-{
-    h->loop = loop;
-    obt_main_loop_x_add(loop, xevent_handler, h, NULL);
-}
-
-void xevent_set_handler(ObtXEventHandler *h, gint type, Window win,
-                        ObtXEventCallback func, gpointer data)
-{
-    ObtXEventBinding *b;
-
-    g_assert(func);
-
-    /* make sure we have a spot for the event */
-    if (type + 1 < h->num_event_types) {
-        gint i;
-        h->bindings = g_renew(GHashTable*, h->bindings, type + 1);
-        for (i = h->num_event_types; i < type + 1; ++i)
-            h->bindings[i] = g_hash_table_new_full((GHashFunc)window_hash,
-                                                   (GEqualFunc)window_comp,
-                                                   NULL, binding_free);
-        h->num_event_types = type + 1;
-    }
-
-    b = g_slice_new(ObtXEventBinding);
-    b->win = win;
-    b->func = func;
-    b->data = data;
-    g_hash_table_replace(h->bindings[type], &b->win, b);
-}
-
-static void binding_free(gpointer b)
-{
-    g_slice_free(ObtXEventBinding, b);
-}
-
-void xevent_remove_handler(ObtXEventHandler *h, gint type, Window win)
-{
-    g_assert(type < h->num_event_types);
-    g_assert(win);
-
-    g_hash_table_remove(h->bindings[type], &win);
-}
-
-static void xevent_handler(const XEvent *e, gpointer data)
-{
-    ObtXEventHandler *h;
-    ObtXEventBinding *b;
-
-    h = data;
-
-    if (e->type < h->num_event_types) {
-        const gint all = OBT_XEVENT_ALL_WINDOWS;
-        /* run the all_windows handler first */
-        b = g_hash_table_lookup(h->bindings[e->xany.type], &all);
-        if (b) b->func(e, b->data);
-        /* then run the per-window handler */
-        b = g_hash_table_lookup(h->bindings[e->xany.type], &e->xany.window);
-        if (b) b->func(e, b->data);
-    }
-    else
-        g_message("Unhandled X Event type %d", e->xany.type);
-}
diff --git a/obt/xevent.h b/obt/xevent.h
deleted file mode 100644 (file)
index ec0b66e..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
-
-   obt/xevent.h for the Openbox window manager
-   Copyright (c) 2007        Dana Jansens
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   See the COPYING file for a copy of the GNU General Public License.
-*/
-
-#ifndef __obt_xevent_h
-#define __obt_xevent_h
-
-#include <X11/Xlib.h>
-#include <glib.h>
-
-G_BEGIN_DECLS
-
-struct _ObtMainLoop;
-
-typedef struct _ObtXEventHandler ObtXEventHandler;
-
-typedef void (*ObtXEventCallback) (const XEvent *e, gpointer data);
-
-ObtXEventHandler* xevent_new(void);
-void              xevent_ref(ObtXEventHandler *h);
-void              xevent_unref(ObtXEventHandler *h);
-
-void              xevent_register(ObtXEventHandler *h,
-                                  struct _ObtMainLoop *loop);
-
-#define OBT_XEVENT_ALL_WINDOWS None
-
-void xevent_set_handler(ObtXEventHandler *h, gint type, Window win,
-                        ObtXEventCallback func, gpointer data);
-void xevent_remove_handler(ObtXEventHandler *h, gint type, Window win);
-
-G_END_DECLS
-
-#endif /*__obt_xevent_h*/
index e5d2da3..22a3de2 100644 (file)
@@ -318,3 +318,69 @@ gboolean xqueue_pending_local(void)
     if (!qnum) read_events(FALSE);
     return qnum != 0;
 }
+
+typedef struct _ObtXQueueCB {
+    ObtXQueueFunc func;
+    gpointer data;
+} ObtXQueueCB;
+
+static ObtXQueueCB *callbacks = NULL;
+static guint n_callbacks = 0;
+
+static gboolean event_read(GIOChannel *s, GIOCondition cond, gpointer data)
+{
+    XEvent ev;
+
+    while (xqueue_next_local(&ev)) {
+        guint i;
+        for (i = 0; i < n_callbacks; ++i)
+            callbacks[i].func(&ev, callbacks[i].data);
+    }
+
+    return TRUE; /* repeat */
+}
+
+void xqueue_listen(void)
+{
+    GIOChannel *ch;
+
+    g_assert(obt_display != NULL);
+
+    ch = g_io_channel_unix_new(ConnectionNumber(obt_display));
+    g_io_add_watch(ch, G_IO_IN, event_read, NULL);
+    g_io_channel_unref(ch);
+}
+
+void xqueue_add_callback(ObtXQueueFunc f, gpointer data)
+{
+    guint i;
+
+    g_return_if_fail(f != NULL);
+
+    for (i = 0; i < n_callbacks; ++i)
+        if (callbacks[i].func == f && callbacks[i].data == data)
+            return;
+
+    callbacks = g_renew(ObtXQueueCB, callbacks, n_callbacks + 1);
+    callbacks[n_callbacks].func = f;
+    callbacks[n_callbacks].data = data;
+    ++n_callbacks;
+}
+
+void xqueue_remove_callback(ObtXQueueFunc f, gpointer data)
+{
+    guint i;
+
+    g_return_if_fail(f != NULL);
+
+    for (i = 0; i < n_callbacks; ++i) {
+        if (callbacks[i].func == f && callbacks[i].data == data) {
+            /* remove it */
+            for (; i < n_callbacks - 1; ++i)
+                callbacks[i] = callbacks[i+1];
+            callbacks = g_renew(ObtXQueueCB, callbacks, n_callbacks - 1);
+            --n_callbacks;
+            break;
+        }
+    }
+}
index 8b31278..11cd2bc 100644 (file)
@@ -87,6 +87,15 @@ gboolean xqueue_exists_local(xqueue_match_func match, gpointer data);
 gboolean xqueue_remove_local(XEvent *event_return,
                              xqueue_match_func match, gpointer data);
 
+typedef void (*ObtXQueueFunc)(const XEvent *ev, gpointer data);
+
+/*! Begin listening for X events in the default GMainContext, and feed them
+  to the registered callback functions, added with xqueue_add_callback(). */
+void xqueue_listen(void);
+
+void xqueue_add_callback(ObtXQueueFunc f, gpointer data);
+void xqueue_remove_callback(ObtXQueueFunc f, gpointer data);
+
 G_END_DECLS
 
 #endif
index 3a58344..fa088c6 100644 (file)
@@ -33,6 +33,8 @@
                               ButtonMotionMask)
 
 static ObDock *dock;
+static guint show_timeout_id;
+static guint hide_timeout_id;
 
 StrutPartial dock_strut;
 
@@ -628,15 +630,19 @@ static gboolean hide_timeout(gpointer data)
     dock->hidden = TRUE;
     dock_configure();
 
+    hide_timeout_id = 0;
+
     return FALSE; /* don't repeat */
 }
 
 static gboolean show_timeout(gpointer data)
 {
-    /* hide */
+    /* show */
     dock->hidden = FALSE;
     dock_configure();
 
+    show_timeout_id = 0;
+
     return FALSE; /* don't repeat */
 }
 
@@ -644,21 +650,21 @@ void dock_hide(gboolean hide)
 {
     if (!hide) {
         if (dock->hidden && config_dock_hide) {
-            obt_main_loop_timeout_add(ob_main_loop,
-                                      config_dock_show_delay * 1000,
-                                      show_timeout, NULL,
-                                      g_direct_equal, NULL);
-        } else if (!dock->hidden && config_dock_hide) {
-            obt_main_loop_timeout_remove(ob_main_loop, hide_timeout);
+            show_timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT,
+                                                 config_dock_show_delay,
+                                                 show_timeout, NULL, NULL);
+        } else if (!dock->hidden && config_dock_hide && hide_timeout_id) {
+            if (hide_timeout_id) g_source_remove(hide_timeout_id);
+            hide_timeout_id = 0;
         }
     } else {
         if (!dock->hidden && config_dock_hide) {
-            obt_main_loop_timeout_add(ob_main_loop,
-                                      config_dock_hide_delay * 1000,
-                                      hide_timeout, NULL,
-                                      g_direct_equal, NULL);
-        } else if (dock->hidden && config_dock_hide) {
-            obt_main_loop_timeout_remove(ob_main_loop, show_timeout);
+            hide_timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT,
+                                                 config_dock_show_delay,
+                                                 hide_timeout, NULL, NULL);
+        } else if (dock->hidden && config_dock_hide && show_timeout_id) {
+            if (show_timeout_id) g_source_remove(show_timeout_id);
+            show_timeout_id = 0;
         }
     }
 }
index d3ffae1..9701ad6 100644 (file)
@@ -93,7 +93,7 @@ static gboolean is_enter_focus_event_ignored(gulong serial);
 static void event_ignore_enter_range(gulong start, gulong end);
 
 static void focus_delay_dest(gpointer data);
-static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2);
+static void unfocus_delay_dest(gpointer data);
 static gboolean focus_delay_func(gpointer data);
 static gboolean unfocus_delay_func(gpointer data);
 static void focus_delay_client_dest(ObClient *client, gpointer data);
@@ -112,25 +112,34 @@ static gboolean focus_left_screen = FALSE;
 static gboolean waiting_for_focusin = FALSE;
 /*! A list of ObSerialRanges which are to be ignored for mouse enter events */
 static GSList *ignore_serials = NULL;
+static guint focus_delay_timeout_id = 0;
+static ObClient *focus_delay_timeout_client = NULL;
+static guint unfocus_delay_timeout_id = 0;
+static ObClient *unfocus_delay_timeout_client = NULL;
 
 #ifdef USE_SM
-static void ice_handler(gint fd, gpointer conn)
+static gboolean ice_handler(GIOChannel *source, GIOCondition cond,
+                            gpointer conn)
 {
     Bool b;
     IceProcessMessages(conn, NULL, &b);
+    return TRUE; /* don't remove the event source */
 }
 
 static void ice_watch(IceConn conn, IcePointer data, Bool opening,
                       IcePointer *watch_data)
 {
-    static gint fd = -1;
+    static guint id = 0;
 
     if (opening) {
-        fd = IceConnectionNumber(conn);
-        obt_main_loop_fd_add(ob_main_loop, fd, ice_handler, conn, NULL);
-    } else {
-        obt_main_loop_fd_remove(ob_main_loop, fd);
-        fd = -1;
+        GIOChannel *ch;
+
+        ch = g_io_channel_unix_new(IceConnectionNumber(conn));
+        id = g_io_add_watch(ch, G_IO_IN, ice_handler, conn);
+        g_io_channel_unref(ch);
+    } else if (id) {
+        g_source_remove(id);
+        id = 0;
     }
 }
 #endif
@@ -139,7 +148,7 @@ void event_startup(gboolean reconfig)
 {
     if (reconfig) return;
 
-    obt_main_loop_x_add(ob_main_loop, event_process, NULL, NULL);
+    xqueue_add_callback(event_process, NULL);
 
 #ifdef USE_SM
     IceAddConnectionWatch(ice_watch, NULL);
@@ -806,17 +815,20 @@ void event_enter_client(ObClient *client)
         if (config_focus_delay) {
             ObFocusDelayData *data;
 
-            obt_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
+            if (focus_delay_timeout_id)
+                g_source_remove(focus_delay_timeout_id);
 
             data = g_slice_new(ObFocusDelayData);
             data->client = client;
             data->time = event_time();
             data->serial = event_curserial;
 
-            obt_main_loop_timeout_add(ob_main_loop,
-                                      config_focus_delay * 1000,
-                                      focus_delay_func,
-                                      data, focus_delay_cmp, focus_delay_dest);
+            focus_delay_timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT,
+                                                        config_focus_delay,
+                                                        focus_delay_func,
+                                                        data,
+                                                        focus_delay_dest);
+            focus_delay_timeout_client = client;
         } else {
             ObFocusDelayData data;
             data.client = client;
@@ -841,17 +853,20 @@ void event_leave_client(ObClient *client)
         if (config_focus_delay) {
             ObFocusDelayData *data;
 
-            obt_main_loop_timeout_remove(ob_main_loop, unfocus_delay_func);
+            if (unfocus_delay_timeout_id)
+                g_source_remove(unfocus_delay_timeout_id);
 
             data = g_slice_new(ObFocusDelayData);
             data->client = client;
             data->time = event_time();
             data->serial = event_curserial;
 
-            obt_main_loop_timeout_add(ob_main_loop,
-                                      config_focus_delay * 1000,
-                                      unfocus_delay_func,
-                                      data, focus_delay_cmp, focus_delay_dest);
+            unfocus_delay_timeout_id = g_timeout_add_full(G_PRIORITY_DEFAULT,
+                                                          config_focus_delay,
+                                                          unfocus_delay_func,
+                                                          data,
+                                                          unfocus_delay_dest);
+            unfocus_delay_timeout_client = client;
         } else {
             ObFocusDelayData data;
             data.client = client;
@@ -1060,10 +1075,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
                    delay is up */
                 e->xcrossing.detail != NotifyInferior)
             {
-                if (config_focus_delay)
-                    obt_main_loop_timeout_remove_data(ob_main_loop,
-                                                      focus_delay_func,
-                                                      client, FALSE);
+                if (config_focus_delay && focus_delay_timeout_id)
+                    g_source_remove(focus_delay_timeout_id);
                 if (config_unfocus_leave)
                     event_leave_client(client);
             }
@@ -1113,10 +1126,8 @@ static void event_handle_client(ObClient *client, XEvent *e)
                               e->xcrossing.serial,
                               (client?client->window:0));
                 if (config_focus_follow) {
-                    if (config_focus_delay)
-                        obt_main_loop_timeout_remove_data(ob_main_loop,
-                                                          unfocus_delay_func,
-                                                          client, FALSE);
+                    if (config_focus_delay && unfocus_delay_timeout_id)
+                        g_source_remove(unfocus_delay_timeout_id);
                     event_enter_client(client);
                 }
             }
@@ -2047,12 +2058,15 @@ static gboolean event_handle_user_input(ObClient *client, XEvent *e)
 static void focus_delay_dest(gpointer data)
 {
     g_slice_free(ObFocusDelayData, data);
+    focus_delay_timeout_id = 0;
+    focus_delay_timeout_client = NULL;
 }
 
-static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2)
+static void unfocus_delay_dest(gpointer data)
 {
-    const ObFocusDelayData *f1 = d1;
-    return f1->client == d2;
+    g_slice_free(ObFocusDelayData, data);
+    unfocus_delay_timeout_id = 0;
+    unfocus_delay_timeout_client = NULL;
 }
 
 static gboolean focus_delay_func(gpointer data)
@@ -2082,18 +2096,18 @@ static gboolean unfocus_delay_func(gpointer data)
 
 static void focus_delay_client_dest(ObClient *client, gpointer data)
 {
-    obt_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func,
-                                      client, FALSE);
-    obt_main_loop_timeout_remove_data(ob_main_loop, unfocus_delay_func,
-                                      client, FALSE);
+    if (focus_delay_timeout_client == client && focus_delay_timeout_id)
+        g_source_remove(focus_delay_timeout_id);
+    if (unfocus_delay_timeout_client == client && unfocus_delay_timeout_id)
+        g_source_remove(unfocus_delay_timeout_id);
 }
 
 void event_halt_focus_delay(void)
 {
     /* ignore all enter events up till the event which caused this to occur */
     if (event_curserial) event_ignore_enter_range(1, event_curserial);
-    obt_main_loop_timeout_remove(ob_main_loop, focus_delay_func);
-    obt_main_loop_timeout_remove(ob_main_loop, unfocus_delay_func);
+    if (focus_delay_timeout_id) g_source_remove(focus_delay_timeout_id);
+    if (unfocus_delay_timeout_id) g_source_remove(unfocus_delay_timeout_id);
 }
 
 gulong event_start_ignore_all_enters(void)
index 4f26255..c6a47b0 100644 (file)
@@ -41,7 +41,7 @@
                            EnterWindowMask | LeaveWindowMask)
 
 #define FRAME_ANIMATE_ICONIFY_TIME 150000 /* .15 seconds */
-#define FRAME_ANIMATE_ICONIFY_STEP_TIME (G_USEC_PER_SEC / 60) /* 60 Hz */
+#define FRAME_ANIMATE_ICONIFY_STEP_TIME (1000 / 60) /* 60 Hz */
 
 #define FRAME_HANDLE_Y(f) (f->size.top + f->client->area.height + f->cbwidth_b)
 
@@ -1060,8 +1060,8 @@ static gboolean find_reparent(XEvent *e, gpointer data)
 void frame_release_client(ObFrame *self)
 {
     /* if there was any animation going on, kill it */
-    obt_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
-                                      self, FALSE);
+    if (self->iconify_animation_timer)
+        g_source_remove(self->iconify_animation_timer);
 
     /* check if the app has already reparented its window away */
     if (!xqueue_exists_local(find_reparent, self)) {
@@ -1118,7 +1118,7 @@ void frame_release_client(ObFrame *self)
     window_remove(self->rgriptop);
     window_remove(self->rgripbottom);
 
-    obt_main_loop_timeout_remove_data(ob_main_loop, flash_timeout, self, TRUE);
+    if (self->flash_timer) g_source_remove(self->flash_timer);
 }
 
 /* is there anything present between us and the label? */
@@ -1674,12 +1674,9 @@ void frame_flash_start(ObFrame *self)
     self->flash_on = self->focused;
 
     if (!self->flashing)
-        obt_main_loop_timeout_add(ob_main_loop,
-                                  G_USEC_PER_SEC * 0.6,
-                                  flash_timeout,
-                                  self,
-                                  g_direct_equal,
-                                  flash_done);
+        self->flash_timer = g_timeout_add_full(G_PRIORITY_DEFAULT,
+                                               600, flash_timeout, self,
+                                               flash_done);
     g_get_current_time(&self->flash_end);
     g_time_val_add(&self->flash_end, G_USEC_PER_SEC * 5);
 
@@ -1837,12 +1834,13 @@ void frame_begin_iconify_animation(ObFrame *self, gboolean iconifying)
     }
 
     if (new_anim) {
-        obt_main_loop_timeout_remove_data(ob_main_loop, frame_animate_iconify,
-                                          self, FALSE);
-        obt_main_loop_timeout_add(ob_main_loop,
-                                  FRAME_ANIMATE_ICONIFY_STEP_TIME,
-                                  frame_animate_iconify, self,
-                                  g_direct_equal, NULL);
+        if (self->iconify_animation_timer)
+            g_source_remove(self->iconify_animation_timer);
+        self->iconify_animation_timer =
+            g_timeout_add_full(G_PRIORITY_DEFAULT,
+                               FRAME_ANIMATE_ICONIFY_STEP_TIME,
+                               frame_animate_iconify, self, NULL);
+                               
 
         /* do the first step */
         frame_animate_iconify(self);
index 8f1ed91..b0d9969 100644 (file)
@@ -190,12 +190,14 @@ struct _ObFrame
     gboolean  flashing;
     gboolean  flash_on;
     GTimeVal  flash_end;
+    guint     flash_timer;
 
     /*! Is the frame currently in an animation for iconify or restore.
       0 means that it is not animating. > 0 means it is animating an iconify.
       < 0 means it is animating a restore.
     */
     gint iconify_animation_going;
+    guint iconify_animation_timer;
     GTimeVal  iconify_animation_end;
 };
 
index ad4e4f3..5b8016d 100644 (file)
@@ -40,6 +40,7 @@
 KeyBindingTree *keyboard_firstnode = NULL;
 static ObPopup *popup = NULL;
 static KeyBindingTree *curpos;
+static guint chain_timer = 0;
 
 static void grab_keys(gboolean grab)
 {
@@ -68,6 +69,11 @@ static gboolean chain_timeout(gpointer data)
     return FALSE; /* don't repeat */
 }
 
+static void chain_done(gpointer data)
+{
+    chain_timer = 0;
+}
+
 static void set_curpos(KeyBindingTree *newpos)
 {
     if (curpos == newpos) return;
@@ -93,7 +99,7 @@ static void set_curpos(KeyBindingTree *newpos)
         a = screen_physical_area_primary(FALSE);
         popup_position(popup, NorthWestGravity, a->x + 10, a->y + 10);
         /* 1 second delay for the popup to show */
-        popup_delay_show(popup, G_USEC_PER_SEC, text);
+        popup_delay_show(popup, 1000, text);
         g_free(text);
     } else {
         popup_hide(popup);
@@ -226,7 +232,7 @@ gboolean keyboard_event(ObClient *client, const XEvent *e)
     if (e->xkey.keycode == config_keyboard_reset_keycode &&
         mods == config_keyboard_reset_state)
     {
-        obt_main_loop_timeout_remove(ob_main_loop, chain_timeout);
+        if (chain_timer) g_source_remove(chain_timer);
         keyboard_reset_chains(-1);
         return TRUE;
     }
@@ -243,11 +249,12 @@ gboolean keyboard_event(ObClient *client, const XEvent *e)
                 menu_frame_hide_all();
 
             if (p->first_child != NULL) { /* part of a chain */
-                obt_main_loop_timeout_remove(ob_main_loop, chain_timeout);
+                if (chain_timer) g_source_remove(chain_timer);
                 /* 3 second timeout for chains */
-                obt_main_loop_timeout_add(ob_main_loop, 3 * G_USEC_PER_SEC,
-                                          chain_timeout, NULL,
-                                          g_direct_equal, NULL);
+                chain_timer =
+                    g_timeout_add_full(G_PRIORITY_DEFAULT,
+                                       3000, chain_timeout, NULL,
+                                       chain_done);
                 set_curpos(p);
             } else if (p->chroot)         /* an empty chroot */
                 set_curpos(p);
@@ -322,7 +329,7 @@ void keyboard_startup(gboolean reconfig)
 
 void keyboard_shutdown(gboolean reconfig)
 {
-    obt_main_loop_timeout_remove(ob_main_loop, chain_timeout);
+    if (chain_timer) g_source_remove(chain_timer);
 
     keyboard_unbind_all();
     set_curpos(NULL);
index 1f9874a..374aeec 100644 (file)
@@ -486,10 +486,10 @@ void menu_show(gchar *name, gint x, gint y, gboolean mouse, ObClient *client)
             menu_can_hide = TRUE;
         else {
             menu_can_hide = FALSE;
-            obt_main_loop_timeout_add(ob_main_loop,
-                                      config_menu_hide_delay * 1000,
-                                      menu_hide_delay_func,
-                                      NULL, g_direct_equal, NULL);
+            g_timeout_add_full(G_PRIORITY_DEFAULT,
+                               config_menu_hide_delay,
+                               menu_hide_delay_func,
+                               NULL, NULL);
         }
     }
 }
index 91e7c53..5708cdf 100644 (file)
@@ -44,6 +44,8 @@ GList *menu_frame_visible;
 GHashTable *menu_frame_map;
 
 static RrAppearance *a_sep;
+static guint submenu_show_timer = 0;
+static guint submenu_hide_timer = 0;
 
 static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry,
                                               ObMenuFrame *frame);
@@ -1009,8 +1011,8 @@ gboolean menu_frame_show_topmenu(ObMenuFrame *self, gint x, gint y,
 */
 static void remove_submenu_hide_timeout(ObMenuFrame *child)
 {
-    obt_main_loop_timeout_remove_data(ob_main_loop, submenu_hide_timeout,
-                                      child, FALSE);
+    if (submenu_hide_timer) g_source_remove(submenu_hide_timer);
+    submenu_hide_timer = 0;
 }
 
 gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent,
@@ -1107,7 +1109,8 @@ void menu_frame_hide_all(void)
 
     if (config_submenu_show_delay) {
         /* remove any submenu open requests */
-        obt_main_loop_timeout_remove(ob_main_loop, submenu_show_timeout);
+        if (submenu_show_timer) g_source_remove(submenu_show_timer);
+        submenu_show_timer = 0;
     }
     if ((it = g_list_last(menu_frame_visible)))
         menu_frame_hide(it->data);
@@ -1188,7 +1191,8 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry,
 
     if (config_submenu_show_delay) {
         /* remove any submenu open requests */
-        obt_main_loop_timeout_remove(ob_main_loop, submenu_show_timeout);
+        if (submenu_show_timer) g_source_remove(submenu_show_timer);
+        submenu_show_timer = 0;
     }
 
     self->selected = entry;
@@ -1208,12 +1212,13 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry,
                submenu */
             if (immediate || config_submenu_hide_delay == 0)
                 menu_frame_hide(oldchild);
-            else if (config_submenu_hide_delay > 0)
-                obt_main_loop_timeout_add(ob_main_loop,
-                                          config_submenu_hide_delay * 1000,
-                                          submenu_hide_timeout,
-                                          oldchild, g_direct_equal,
-                                          NULL);
+            else if (config_submenu_hide_delay > 0) {
+                if (submenu_hide_timer) g_source_remove(submenu_hide_timer);
+                submenu_hide_timer =
+                    g_timeout_add_full(G_PRIORITY_DEFAULT,
+                                       config_submenu_hide_delay,
+                                       submenu_hide_timeout, oldchild, NULL);
+            }
         }
     }
 
@@ -1225,12 +1230,15 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry,
             if (oldchild_entry != self->selected) {
                 if (immediate || config_submenu_hide_delay == 0)
                     menu_entry_frame_show_submenu(self->selected);
-                else if (config_submenu_hide_delay > 0)
-                    obt_main_loop_timeout_add(ob_main_loop,
-                                              config_submenu_show_delay * 1000,
-                                              submenu_show_timeout,
-                                              self->selected, g_direct_equal,
-                                              NULL);
+                else if (config_submenu_hide_delay > 0) {
+                    if (submenu_show_timer)
+                        g_source_remove(submenu_show_timer);
+                    submenu_show_timer =
+                        g_timeout_add_full(G_PRIORITY_DEFAULT,
+                                           config_submenu_show_delay,
+                                           submenu_show_timeout,
+                                           self->selected, NULL);
+                }
             }
             /* hide the grandchildren of this menu. and move the cursor to
                the current menu */
index 96cd623..2f68395 100644 (file)
@@ -61,9 +61,11 @@ static guint button;
 static guint32 corner;
 static ObDirection edge_warp_dir = -1;
 static gboolean edge_warp_odd = FALSE;
+static guint edge_warp_timer = 0;
 static ObDirection key_resize_edge = -1;
 #ifdef SYNC
 static guint waiting_for_sync;
+static guint sync_timer = 0;
 #endif
 
 static ObPopup *popup = NULL;
@@ -319,7 +321,8 @@ void moveresize_end(gboolean cancel)
             moveresize_alarm = None;
         }
 
-        obt_main_loop_timeout_remove(ob_main_loop, sync_timeout_func);
+        if (sync_timer) g_source_remove(sync_timer);
+        sync_timer = 0;
 #endif
     }
 
@@ -433,10 +436,8 @@ static void do_resize(void)
 
             waiting_for_sync = 1;
 
-            obt_main_loop_timeout_remove(ob_main_loop, sync_timeout_func);
-            obt_main_loop_timeout_add(ob_main_loop, G_USEC_PER_SEC * 2,
-                                      sync_timeout_func,
-                                      NULL, NULL, NULL);
+            if (sync_timer) g_source_remove(sync_timer);
+            sync_timer = g_timeout_add(2000, sync_timeout_func, NULL);
         }
 #endif
 
@@ -461,8 +462,10 @@ static gboolean sync_timeout_func(gpointer data)
     ++waiting_for_sync; /* we timed out waiting for our sync... */
     do_resize(); /* ...so let any pending resizes through */
 
-    if (waiting_for_sync > SYNC_TIMEOUTS)
+    if (waiting_for_sync > SYNC_TIMEOUTS) {
+        sync_timer = 0;
         return FALSE; /* don't repeat */
+    }
     else
         return TRUE; /* keep waiting */
 }
@@ -649,10 +652,8 @@ static void do_edge_warp(gint x, gint y)
         cancel_edge_warp();
         if (dir != (ObDirection)-1) {
             edge_warp_odd = TRUE; /* switch on the first timeout */
-            obt_main_loop_timeout_add(ob_main_loop,
-                                      config_mouse_screenedgetime * 1000,
-                                      edge_warp_delay_func,
-                                      NULL, NULL, NULL);
+            edge_warp_timer = g_timeout_add(config_mouse_screenedgetime,
+                                            edge_warp_delay_func, NULL);
         }
         edge_warp_dir = dir;
     }
@@ -660,7 +661,8 @@ static void do_edge_warp(gint x, gint y)
 
 static void cancel_edge_warp(void)
 {
-    obt_main_loop_timeout_remove(ob_main_loop, edge_warp_delay_func);
+    if (edge_warp_timer) g_source_remove(edge_warp_timer);
+    edge_warp_timer = 0;
 }
 
 static void move_with_keys(KeySym sym, guint state)
index fb43b97..b2cdc8e 100644 (file)
@@ -46,6 +46,7 @@
 #include "obrender/render.h"
 #include "obrender/theme.h"
 #include "obt/display.h"
+#include "obt/xqueue.h"
 #include "obt/prop.h"
 #include "obt/keyboard.h"
 #include "obt/xml.h"
@@ -83,7 +84,7 @@
 RrInstance   *ob_rr_inst;
 RrImageCache *ob_rr_icons;
 RrTheme      *ob_rr_theme;
-ObtMainLoop  *ob_main_loop;
+GMainLoop    *ob_main_loop;
 gint          ob_screen;
 gboolean      ob_replace_wm = FALSE;
 gboolean      ob_sm_use = TRUE;
@@ -157,18 +158,18 @@ gint main(gint argc, gchar **argv)
         exit(EXIT_SUCCESS);
     }
 
-    ob_main_loop = obt_main_loop_new();
+    ob_main_loop = g_main_loop_new(NULL, FALSE);
 
     /* set up signal handler */
-    obt_main_loop_signal_add(ob_main_loop, SIGUSR1, signal_handler, NULL,NULL);
-    obt_main_loop_signal_add(ob_main_loop, SIGUSR2, signal_handler, NULL,NULL);
-    obt_main_loop_signal_add(ob_main_loop, SIGTERM, signal_handler, NULL,NULL);
-    obt_main_loop_signal_add(ob_main_loop, SIGINT, signal_handler,  NULL,NULL);
-    obt_main_loop_signal_add(ob_main_loop, SIGHUP, signal_handler,  NULL,NULL);
-    obt_main_loop_signal_add(ob_main_loop, SIGPIPE, signal_handler, NULL,NULL);
-    obt_main_loop_signal_add(ob_main_loop, SIGCHLD, signal_handler, NULL,NULL);
-    obt_main_loop_signal_add(ob_main_loop, SIGTTIN, signal_handler, NULL,NULL);
-    obt_main_loop_signal_add(ob_main_loop, SIGTTOU, signal_handler, NULL,NULL);
+//  obt_main_loop_signal_add(ob_main_loop, SIGUSR1, signal_handler, NULL,NULL);
+//  obt_main_loop_signal_add(ob_main_loop, SIGUSR2, signal_handler, NULL,NULL);
+//  obt_main_loop_signal_add(ob_main_loop, SIGTERM, signal_handler, NULL,NULL);
+//  obt_main_loop_signal_add(ob_main_loop, SIGINT, signal_handler,  NULL,NULL);
+//  obt_main_loop_signal_add(ob_main_loop, SIGHUP, signal_handler,  NULL,NULL);
+//  obt_main_loop_signal_add(ob_main_loop, SIGPIPE, signal_handler, NULL,NULL);
+//  obt_main_loop_signal_add(ob_main_loop, SIGCHLD, signal_handler, NULL,NULL);
+//  obt_main_loop_signal_add(ob_main_loop, SIGTTIN, signal_handler, NULL,NULL);
+//  obt_main_loop_signal_add(ob_main_loop, SIGTTOU, signal_handler, NULL,NULL);
 
     ob_screen = DefaultScreen(obt_display);
 
@@ -316,6 +317,10 @@ gint main(gint argc, gchar **argv)
             menu_startup(reconfigure);
             prompt_startup(reconfigure);
 
+            /* do this after everything is started so no events will get
+               missed */
+            xqueue_listen();
+
             if (!reconfigure) {
                 guint32 xid;
                 ObWindow *w;
@@ -367,7 +372,7 @@ gint main(gint argc, gchar **argv)
                 }
             }
 
-            obt_main_loop_run(ob_main_loop);
+            g_main_loop_run(ob_main_loop);
             ob_set_state(reconfigure ?
                          OB_STATE_RECONFIGURING : OB_STATE_EXITING);
 
@@ -741,14 +746,14 @@ void ob_reconfigure(void)
 void ob_exit(gint code)
 {
     exitcode = code;
-    obt_main_loop_exit(ob_main_loop);
+    g_main_loop_quit(ob_main_loop);
 }
 
 void ob_exit_replace(void)
 {
     exitcode = 0;
     being_replaced = TRUE;
-    obt_main_loop_exit(ob_main_loop);
+    g_main_loop_quit(ob_main_loop);
 }
 
 Cursor ob_cursor(ObCursor cursor)
index 229c584..94f4910 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "obrender/render.h"
 #include "obrender/theme.h"
-#include "obt/mainloop.h"
 #include "obt/display.h"
 
 #include <glib.h>
@@ -32,7 +31,7 @@ extern RrInstance *ob_rr_inst;
 extern RrImageCache *ob_rr_icons;
 extern RrTheme    *ob_rr_theme;
 
-extern ObtMainLoop *ob_main_loop;
+extern GMainLoop *ob_main_loop;
 
 /*! The number of the screen on which we're running */
 extern gint     ob_screen;
index bf39a30..7cb4766 100644 (file)
@@ -22,7 +22,6 @@
 #include "event.h"
 #include "debug.h"
 #include "openbox.h"
-#include "obt/mainloop.h"
 #include "obt/prop.h"
 
 typedef struct _ObPingTarget
@@ -30,13 +29,14 @@ typedef struct _ObPingTarget
     ObClient *client;
     ObPingEventHandler h;
     guint32 id;
+    guint loopid;
     gint waiting;
 } ObPingTarget;
 
 static GHashTable *ping_ids     = NULL;
 static guint32     ping_next_id = 1;
 
-#define PING_TIMEOUT (G_USEC_PER_SEC * 3)
+#define PING_TIMEOUT 3000 /* in MS */
 /*! Warn the user after this many PING_TIMEOUT intervals */
 #define PING_TIMEOUT_WARN 2
 
@@ -79,8 +79,8 @@ void ping_start(struct _ObClient *client, ObPingEventHandler h)
     t->client = client;
     t->h = h;
 
-    obt_main_loop_timeout_add(ob_main_loop, PING_TIMEOUT, ping_timeout,
-                              t, g_direct_equal, NULL);
+    t->loopid = g_timeout_add_full(G_PRIORITY_DEFAULT, PING_TIMEOUT,
+                                   ping_timeout, t, NULL);
     /* act like we just timed out immediately, to start the pinging process
        now instead of after the first delay.  this makes sure the client
        ends up in the ping_ids hash table now. */
@@ -158,8 +158,7 @@ static void ping_end(ObClient *client, gpointer data)
     if ((t = g_hash_table_find(ping_ids, find_client, client))) {
         g_hash_table_remove(ping_ids, &t->id);
 
-        obt_main_loop_timeout_remove_data(ob_main_loop, ping_timeout,
-                                          t, FALSE);
+        g_source_remove(t->loopid);
 
         g_slice_free(ObPingTarget, t);
     }
index 7d59d91..e6e1ec5 100644 (file)
@@ -146,11 +146,12 @@ static gboolean popup_show_timeout(gpointer data)
     stacking_raise(INTERNAL_AS_WINDOW(self));
     self->mapped = TRUE;
     self->delay_mapped = FALSE;
+    self->delay_timer = 0;
 
     return FALSE; /* don't repeat */
 }
 
-void popup_delay_show(ObPopup *self, gulong usec, gchar *text)
+void popup_delay_show(ObPopup *self, gulong msec, gchar *text)
 {
     gint l, t, r, b;
     gint x, y, w, h;
@@ -292,12 +293,11 @@ void popup_delay_show(ObPopup *self, gulong usec, gchar *text)
 
     /* do the actual showing */
     if (!self->mapped) {
-        if (usec) {
+        if (msec) {
             /* don't kill previous show timers */
             if (!self->delay_mapped) {
-                obt_main_loop_timeout_add(ob_main_loop, usec,
-                                          popup_show_timeout, self,
-                                          g_direct_equal, NULL);
+                self->delay_timer =
+                    g_timeout_add(msec, popup_show_timeout, self);
                 self->delay_mapped = TRUE;
             }
         } else {
@@ -319,7 +319,8 @@ void popup_hide(ObPopup *self)
 
         event_end_ignore_all_enters(ignore_start);
     } else if (self->delay_mapped) {
-        obt_main_loop_timeout_remove_data(ob_main_loop, popup_show_timeout, self, FALSE);
+        g_source_remove(self->delay_timer);
+        self->delay_timer = 0;
         self->delay_mapped = FALSE;
     }
 }
@@ -365,7 +366,7 @@ void icon_popup_free(ObIconPopup *self)
     }
 }
 
-void icon_popup_delay_show(ObIconPopup *self, gulong usec,
+void icon_popup_delay_show(ObIconPopup *self, gulong msec,
                            gchar *text, RrImage *icon)
 {
     if (icon) {
@@ -378,7 +379,7 @@ void icon_popup_delay_show(ObIconPopup *self, gulong usec,
         self->a_icon->texture[0].type = RR_TEXTURE_NONE;
     }
 
-    popup_delay_show(self->popup, usec, text);
+    popup_delay_show(self->popup, msec, text);
 }
 
 void icon_popup_icon_size_multiplier(ObIconPopup *self, guint wm, guint hm)
@@ -528,7 +529,7 @@ void pager_popup_free(ObPagerPopup *self)
     }
 }
 
-void pager_popup_delay_show(ObPagerPopup *self, gulong usec,
+void pager_popup_delay_show(ObPagerPopup *self, gulong msec,
                             gchar *text, guint desk)
 {
     guint i;
@@ -557,7 +558,7 @@ void pager_popup_delay_show(ObPagerPopup *self, gulong usec,
     self->desks = screen_num_desktops;
     self->curdesk = desk;
 
-    popup_delay_show(self->popup, usec, text);
+    popup_delay_show(self->popup, msec, text);
 }
 
 void pager_popup_icon_size_multiplier(ObPagerPopup *self, guint wm, guint hm)
index f876e3c..6de9d18 100644 (file)
@@ -53,6 +53,7 @@ struct _ObPopup
     guint iconhm; /* icon height multiplier. multipled by the normal height */
     gboolean mapped;
     gboolean delay_mapped;
+    guint delay_timer;
 
     void (*draw_icon)(gint x, gint y, gint w, gint h, gpointer data);
     gpointer draw_icon_data;
@@ -99,7 +100,7 @@ void popup_text_width_to_strings(ObPopup *self, gchar **strings, gint num);
 void popup_set_text_align(ObPopup *self, RrJustify align);
 
 #define popup_show(s, t) popup_delay_show((s),0,(t))
-void popup_delay_show(ObPopup *self, gulong usec, gchar *text);
+void popup_delay_show(ObPopup *self, gulong msec, gchar *text);
 void popup_hide(ObPopup *self);
 
 RrAppearance *popup_icon_appearance(ObPopup *self);
@@ -109,7 +110,7 @@ ObIconPopup *icon_popup_new(void);
 void icon_popup_free(ObIconPopup *self);
 
 #define icon_popup_show(s, t, i) icon_popup_delay_show((s),0,(t),(i))
-void icon_popup_delay_show(ObIconPopup *self, gulong usec,
+void icon_popup_delay_show(ObIconPopup *self, gulong msec,
                            gchar *text, RrImage *icon);
 #define icon_popup_hide(p) popup_hide((p)->popup)
 #define icon_popup_position(p, g, x, y) popup_position((p)->popup,(g),(x),(y))
@@ -128,7 +129,7 @@ ObPagerPopup *pager_popup_new(void);
 void pager_popup_free(ObPagerPopup *self);
 
 #define pager_popup_show(s, t, d) pager_popup_delay_show((s),0,(t),(d))
-void pager_popup_delay_show(ObPagerPopup *self, gulong usec,
+void pager_popup_delay_show(ObPagerPopup *self, gulong msec,
                             gchar *text, guint desk);
 #define pager_popup_hide(p) popup_hide((p)->popup)
 #define pager_popup_position(p, g, x, y) popup_position((p)->popup,(g),(x),(y))
index 47ecc18..353d2de 100644 (file)
@@ -38,7 +38,6 @@
 #include "obt/display.h"
 #include "obt/xqueue.h"
 #include "obt/prop.h"
-#include "obt/mainloop.h"
 
 #include <X11/Xlib.h>
 #ifdef HAVE_UNISTD_H
@@ -71,6 +70,7 @@ Time            screen_desktop_user_time = CurrentTime;
 static Size     screen_physical_size;
 static guint    screen_old_desktop;
 static gboolean screen_desktop_timeout = TRUE;
+static guint    screen_desktop_timer = 0;
 /*! An array of desktops, holding an array of areas per monitor */
 static Rect  *monitor_area = NULL;
 /*! An array of desktops, holding an array of struts */
@@ -80,11 +80,12 @@ static GSList *struts_right = NULL;
 static GSList *struts_bottom = NULL;
 
 static ObPagerPopup *desktop_popup;
+static guint         desktop_popup_timer = 0;
 static gboolean      desktop_popup_perm;
 
 /*! The number of microseconds that you need to be on a desktop before it will
   replace the remembered "last desktop" */
-#define REMEMBER_LAST_DESKTOP_TIME 750000
+#define REMEMBER_LAST_DESKTOP_TIME 750
 
 static gboolean replace_wm(void)
 {
@@ -601,7 +602,8 @@ static void screen_fallback_focus(void)
 static gboolean last_desktop_func(gpointer data)
 {
     screen_desktop_timeout = TRUE;
-    return FALSE;
+    screen_desktop_timer = 0;
+    return FALSE; /* don't repeat */
 }
 
 void screen_set_desktop(guint num, gboolean dofocus)
@@ -683,9 +685,9 @@ void screen_set_desktop(guint num, gboolean dofocus)
         }
     }
     screen_desktop_timeout = FALSE;
-    obt_main_loop_timeout_remove(ob_main_loop, last_desktop_func);
-    obt_main_loop_timeout_add(ob_main_loop, REMEMBER_LAST_DESKTOP_TIME,
-                              last_desktop_func, NULL, NULL, NULL);
+    if (screen_desktop_timer) g_source_remove(screen_desktop_timer);
+    screen_desktop_timer = g_timeout_add(REMEMBER_LAST_DESKTOP_TIME,
+                                         last_desktop_func, NULL);
 
     ob_debug("Moving to desktop %d", num+1);
 
@@ -937,6 +939,7 @@ static guint translate_row_col(guint r, guint c)
 static gboolean hide_desktop_popup_func(gpointer data)
 {
     pager_popup_hide(desktop_popup);
+    desktop_popup_timer = 0;
     return FALSE; /* don't repeat */
 }
 
@@ -959,21 +962,21 @@ void screen_show_desktop_popup(guint d, gboolean perm)
                           MAX(a->width/3, POPUP_WIDTH));
     pager_popup_show(desktop_popup, screen_desktop_names[d], d);
 
-    obt_main_loop_timeout_remove(ob_main_loop, hide_desktop_popup_func);
+    if (desktop_popup_timer) g_source_remove(desktop_popup_timer);
+    desktop_popup_timer = 0;
     if (!perm && !desktop_popup_perm)
         /* only hide if its not already being show permanently */
-        obt_main_loop_timeout_add(ob_main_loop,
-                                  config_desktop_popup_time * 1000,
-                                  hide_desktop_popup_func, desktop_popup,
-                                  g_direct_equal, NULL);
+        desktop_popup_timer = g_timeout_add(config_desktop_popup_time,
+                                            hide_desktop_popup_func,
+                                            desktop_popup);
     if (perm)
         desktop_popup_perm = TRUE;
 }
 
 void screen_hide_desktop_popup(void)
 {
-    obt_main_loop_timeout_remove_data(ob_main_loop, hide_desktop_popup_func,
-                                      desktop_popup, FALSE);
+    if (desktop_popup_timer) g_source_remove(desktop_popup_timer);
+    desktop_popup_timer = 0;
     pager_popup_hide(desktop_popup);
     desktop_popup_perm = FALSE;
 }
index c300d57..16654cf 100644 (file)
@@ -20,6 +20,7 @@
 #include "startupnotify.h"
 #include "gettext.h"
 #include "event.h"
+#include "obt/xqueue.h"
 
 #ifdef HAVE_STDLIB_H
 #  include <stdlib.h>
@@ -67,7 +68,7 @@ void sn_startup(gboolean reconfig)
                                         sn_event_func, NULL, NULL);
     sn_launcher = sn_launcher_context_new(sn_display, ob_screen);
 
-    obt_main_loop_x_add(ob_main_loop, sn_handler, NULL, NULL);
+    xqueue_add_callback(sn_handler, NULL);
 }
 
 void sn_shutdown(gboolean reconfig)
@@ -76,7 +77,7 @@ void sn_shutdown(gboolean reconfig)
 
     if (reconfig) return;
 
-    obt_main_loop_x_remove(ob_main_loop, sn_handler);
+    xqueue_remove_callback(sn_handler, NULL);
 
     for (it = sn_waits; it; it = g_slist_next(it))
         sn_startup_sequence_unref((SnStartupSequence*)it->data);
@@ -139,10 +140,9 @@ static void sn_event_func(SnMonitorEvent *ev, gpointer data)
         sn_waits = g_slist_prepend(sn_waits, seq);
         /* 20 second timeout for apps to start if the launcher doesn't
            have a timeout */
-        obt_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC,
-                                  sn_wait_timeout, seq,
-                                  g_direct_equal,
-                                  (GDestroyNotify)sn_startup_sequence_unref);
+        g_timeout_add_full(G_PRIORITY_DEFAULT,
+                           20 * 1000, sn_wait_timeout, seq,
+                           (GDestroyNotify)sn_startup_sequence_unref);
         change = TRUE;
         break;
     case SN_MONITOR_EVENT_CHANGED:
@@ -153,8 +153,7 @@ static void sn_event_func(SnMonitorEvent *ev, gpointer data)
     case SN_MONITOR_EVENT_CANCELED:
         if ((seq = sequence_find(sn_startup_sequence_get_id(seq)))) {
             sn_waits = g_slist_remove(sn_waits, seq);
-            obt_main_loop_timeout_remove_data(ob_main_loop, sn_wait_timeout,
-                                              seq, FALSE);
+            g_source_remove_by_user_data(seq);
             change = TRUE;
         }
         break;
@@ -260,10 +259,9 @@ void sn_setup_spawn_environment(const gchar *program, const gchar *name,
 
     /* 20 second timeout for apps to start */
     sn_launcher_context_ref(sn_launcher);
-    obt_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC,
-                              sn_launch_wait_timeout, sn_launcher,
-                              g_direct_equal,
-                              (GDestroyNotify)sn_launcher_context_unref);
+    g_timeout_add_full(G_PRIORITY_DEFAULT,
+                       20 * 1000, sn_launch_wait_timeout, sn_launcher,
+                       (GDestroyNotify)sn_launcher_context_unref);
 
     setenv("DESKTOP_STARTUP_ID", id, TRUE);