diff --git a/include/data.h b/include/data.h index d7ba8af4..6cf3515e 100644 --- a/include/data.h +++ b/include/data.h @@ -17,6 +17,7 @@ #include #include #include +#include #include "queue.h" @@ -305,7 +306,7 @@ struct Window { bool needs_take_focus; /** When this window was marked urgent. 0 means not urgent */ - time_t urgent; + struct timeval urgent; /** Whether this window accepts focus. We store this inverted so that the * default will be 'accepts focus'. */ diff --git a/src/handlers.c b/src/handlers.c index 596d15a6..1fb2bdd4 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -11,6 +11,7 @@ #include "all.h" #include +#include #include #include #define SN_API_NOT_YET_FROZEN 1 @@ -844,7 +845,8 @@ static bool handle_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_ if (!con->urgent && focused == con) { DLOG("Ignoring urgency flag for current client\n"); - con->window->urgent = 0; + con->window->urgent.tv_sec = 0; + con->window->urgent.tv_usec = 0; goto end; } @@ -853,9 +855,10 @@ static bool handle_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_ //CLIENT_LOG(con); if (con->window) { if (con->urgent) { - con->window->urgent = time(NULL); + gettimeofday(&con->window->urgent, NULL); } else { - con->window->urgent = 0; + con->window->urgent.tv_sec = 0; + con->window->urgent.tv_usec = 0; } } LOG("Urgency flag changed to %d\n", con->urgent); diff --git a/src/match.c b/src/match.c index c460d422..e92a95d2 100644 --- a/src/match.c +++ b/src/match.c @@ -13,6 +13,12 @@ */ #include "all.h" +/* From sys/time.h, not sure if it’s available on all systems. */ +# define _i3_timercmp(a, b, CMP) \ + (((a).tv_sec == (b).tv_sec) ? \ + ((a).tv_usec CMP (b).tv_usec) : \ + ((a).tv_sec CMP (b).tv_sec)) + /* * Initializes the Match data structure. This function is necessary because the * members representing boolean values (like dock) need to be initialized with @@ -125,13 +131,13 @@ bool match_matches_window(Match *match, i3Window *window) { Con *con = NULL; if (match->urgent == U_LATEST) { /* if the window isn't urgent, no sense in searching */ - if (window->urgent == 0) { + if (window->urgent.tv_sec == 0) { return false; } /* if we find a window that is newer than this one, bail */ TAILQ_FOREACH(con, &all_cons, all_cons) { if ((con->window != NULL) && - (con->window->urgent > window->urgent)) { + _i3_timercmp(con->window->urgent, window->urgent, >)) { return false; } } @@ -140,14 +146,14 @@ bool match_matches_window(Match *match, i3Window *window) { if (match->urgent == U_OLDEST) { /* if the window isn't urgent, no sense in searching */ - if (window->urgent == 0) { + if (window->urgent.tv_sec == 0) { return false; } /* if we find a window that is older than this one (and not 0), bail */ TAILQ_FOREACH(con, &all_cons, all_cons) { if ((con->window != NULL) && - (con->window->urgent != 0) && - (con->window->urgent < window->urgent)) { + (con->window->urgent.tv_sec != 0) && + _i3_timercmp(con->window->urgent, window->urgent, <)) { return false; } } diff --git a/testcases/t/113-urgent.t b/testcases/t/113-urgent.t index 9c3dbab6..04f72c3d 100644 --- a/testcases/t/113-urgent.t +++ b/testcases/t/113-urgent.t @@ -95,10 +95,6 @@ is($x->input_focus, $different_window->id, 'new window focused again'); $top->add_hint('urgency'); sync_with_i3; -# Unfortunately, we cannot get rid of this delay. We need it because i3 stores -# the time of an urgency hint with second precision. -sleep 1; - $bottom->add_hint('urgency'); sync_with_i3; @@ -123,10 +119,6 @@ is($x->input_focus, $different_window->id, 'new window focused again'); $top->add_hint('urgency'); sync_with_i3; -# Unfortunately, we cannot get rid of this delay. We need it because i3 stores -# the time of an urgency hint with second precision. -sleep 1; - $bottom->add_hint('urgency'); sync_with_i3;