add a comparitor to timers. use this in event.c to let you remove timers from the queue selectively for delayed focus
@@ -616,14 +616,14 @@ {
if (!hide) { if (dock->hidden && config_dock_hide) { ob_main_loop_timeout_add(ob_main_loop, config_dock_show_delay, - show_timeout, NULL, NULL); + show_timeout, NULL, g_direct_equal, NULL); } else if (!dock->hidden && config_dock_hide) { ob_main_loop_timeout_remove(ob_main_loop, hide_timeout); } } else { if (!dock->hidden && config_dock_hide) { ob_main_loop_timeout_add(ob_main_loop, config_dock_hide_delay, - hide_timeout, NULL, NULL); + hide_timeout, NULL, g_direct_equal, NULL); } else if (dock->hidden && config_dock_hide) { ob_main_loop_timeout_remove(ob_main_loop, show_timeout); }
@@ -79,6 +79,8 @@ static void event_handle_dockapp(ObDockApp *app, XEvent *e);
static void event_handle_client(ObClient *c, XEvent *e); static void event_handle_group(ObGroup *g, XEvent *e); +static void focus_delay_dest(gpointer data); +static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2); static gboolean focus_delay_func(gpointer data); static void focus_delay_client_dest(ObClient *client, gpointer data);@@ -103,11 +105,6 @@
static guint ignore_enter_focus = 0; static gboolean menu_can_hide; - -static ObFocusDelayData focus_delay_data = { .client = NULL, - .time = CurrentTime }; - - #ifdef USE_SM static void ice_handler(gint fd, gpointer conn)@@ -542,7 +539,7 @@ menu_can_hide = FALSE;
ob_main_loop_timeout_add(ob_main_loop, config_menu_hide_delay * 1000, menu_hide_delay_func, - NULL, NULL); + NULL, g_direct_equal, NULL); if (e->type == ButtonPress || e->type == ButtonRelease || e->type == MotionNotify)@@ -627,19 +624,23 @@ g_assert(config_focus_follow);
if (client_normal(client) && client_can_focus(client)) { if (config_focus_delay) { + ObFocusDelayData *data; + ob_main_loop_timeout_remove(ob_main_loop, focus_delay_func); - focus_delay_data.client = client; - focus_delay_data.time = event_curtime; + data = g_new(ObFocusDelayData, 1); + data->client = client; + data->time = event_curtime; ob_main_loop_timeout_add(ob_main_loop, config_focus_delay, focus_delay_func, - NULL, NULL); + data, focus_delay_cmp, focus_delay_dest); } else { - focus_delay_data.client = client; - focus_delay_data.time = event_curtime; - focus_delay_func(NULL); + ObFocusDelayData data; + data.client = client; + data.time = event_curtime; + focus_delay_func(&data); } } }@@ -760,11 +761,10 @@ client->frame->close_hover = FALSE;
frame_adjust_state(client->frame); break; case OB_FRAME_CONTEXT_FRAME: - if (config_focus_follow && config_focus_delay && - focus_delay_data.client == client) - { - event_halt_focus_delay(); - } + if (config_focus_follow && config_focus_delay) + ob_main_loop_timeout_remove_data(ob_main_loop, + focus_delay_func, + client, FALSE); break; default: break;@@ -1340,13 +1340,26 @@ menu_can_hide = TRUE;
return FALSE; /* no repeat */ } +static void focus_delay_dest(gpointer data) +{ + g_free(data); +} + +static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2) +{ + const ObFocusDelayData *f1 = d1, *f2 = d2; + return f1->client == f2->client; +} + static gboolean focus_delay_func(gpointer data) { + ObFocusDelayData *d = data; Time old = event_curtime; - event_curtime = focus_delay_data.time; - if (focus_client != focus_delay_data.client) { - if (client_focus(focus_delay_data.client) && config_focus_raise) - client_raise(focus_delay_data.client); + + event_curtime = d->time; + if (focus_client != d->client) { + if (client_focus(d->client) && config_focus_raise) + client_raise(d->client); } event_curtime = old; return FALSE; /* no repeat */@@ -1354,8 +1367,8 @@ }
static void focus_delay_client_dest(ObClient *client, gpointer data) { - if (focus_delay_data.client == client) - event_halt_focus_delay(); + ob_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func, + client, FALSE); } static void event_client_dest(ObClient *client, gpointer data)@@ -1366,7 +1379,6 @@ }
void event_halt_focus_delay() { - focus_delay_data.client = NULL; ob_main_loop_timeout_remove(ob_main_loop, focus_delay_func); }
@@ -282,9 +282,6 @@ at all for them.
*/ focus_set_client(NULL); - /* If some delayed focusing is going on, cancel it */ - event_halt_focus_delay(); - if ((new = focus_fallback_target(allow_refocus, old))) client_focus(new); }
@@ -977,6 +977,7 @@ ob_main_loop_timeout_add(ob_main_loop,
G_USEC_PER_SEC * 0.6, flash_timeout, self, + g_direct_equal, flash_done); g_get_current_time(&self->flash_end); g_time_val_add(&self->flash_end, G_USEC_PER_SEC * 5);
@@ -271,7 +271,8 @@ if (p->first_child != NULL) { /* part of a chain */
ob_main_loop_timeout_remove(ob_main_loop, chain_timeout); /* 5 second timeout for chains */ ob_main_loop_timeout_add(ob_main_loop, 5 * G_USEC_PER_SEC, - chain_timeout, NULL, NULL); + chain_timeout, NULL, + g_direct_equal, NULL); grab_keys(FALSE); curpos = p; grab_keys(TRUE);
@@ -99,6 +99,7 @@ {
gulong delay; GSourceFunc func; gpointer data; + GEqualFunc equal; GDestroyNotify destroy; /* The timer needs to be freed */@@ -585,12 +586,14 @@ void ob_main_loop_timeout_add(ObMainLoop *loop,
gulong microseconds, GSourceFunc handler, gpointer data, + GEqualFunc cmp, GDestroyNotify notify) { ObMainLoopTimer *t = g_new(ObMainLoopTimer, 1); 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);@@ -619,7 +622,7 @@ GSList *it;
for (it = loop->timers; it; it = g_slist_next(it)) { ObMainLoopTimer *t = it->data; - if (t->func == handler && t->data == data) { + if (t->func == handler && t->equal(t->data, data)) { t->del_me = TRUE; if (cancel_dest) t->destroy = NULL;
@@ -61,6 +61,7 @@ void ob_main_loop_timeout_add(ObMainLoop *loop,
gulong microseconds, GSourceFunc handler, gpointer data, + GEqualFunc cmp, GDestroyNotify notify); void ob_main_loop_timeout_remove(ObMainLoop *loop, GSourceFunc handler);
@@ -144,6 +144,7 @@ /* 30 second timeout for apps to start if the launcher doesn't
have a timeout */ ob_main_loop_timeout_add(ob_main_loop, 30 * G_USEC_PER_SEC, sn_wait_timeout, seq, + g_direct_equal, (GDestroyNotify)sn_startup_sequence_unref); change = TRUE; break;@@ -256,6 +257,7 @@ /* 30 second timeout for apps to start */
sn_launcher_context_ref(sn_launcher); ob_main_loop_timeout_add(ob_main_loop, 30 * G_USEC_PER_SEC, sn_launch_wait_timeout, sn_launcher, + g_direct_equal, (GDestroyNotify)sn_launcher_context_unref); setenv("DESKTOP_STARTUP_ID", id, TRUE);