From: Andreas Fink Date: Mon, 16 Nov 2009 07:27:28 +0000 (+0000) Subject: *fix* merged tooltip to the new timer syntax X-Git-Url: https://git.dogcows.com/gitweb?a=commitdiff_plain;h=61232646c1684ec38a7281abc473b44fde11efd0;p=chaz%2Ftint2 *fix* merged tooltip to the new timer syntax *todo* check what happens if no clock and no battery are on the panel --- diff --git a/src/config.c b/src/config.c index dee33d2..cc8d9f0 100644 --- a/src/config.c +++ b/src/config.c @@ -518,14 +518,18 @@ void add_entry (char *key, char *value) else if (strcmp (key, "tooltip_show_timeout") == 0) { double timeout = atof(value); int sec = (int)timeout; - int usec = (timeout-sec)*1e6; - g_tooltip.show_timeout.it_value = (struct timeval){.tv_sec=sec, .tv_usec=usec}; + int nsec = (timeout-sec)*1e9; + if (nsec < 0) // can happen because of double is not precise such that (sec > timeout)==TRUE + nsec = 0; + g_tooltip.show_timeout = (struct timespec){.tv_sec=sec, .tv_nsec=nsec}; } else if (strcmp (key, "tooltip_hide_timeout") == 0) { double timeout = atof(value); int sec = (int)timeout; - int usec = (timeout-sec)*1e6; - g_tooltip.hide_timeout.it_value = (struct timeval){.tv_sec=sec, .tv_usec=usec}; + int nsec = (timeout-sec)*1e9; + if (nsec < 0) // can happen because of double is not precise such that (sec > timeout)==TRUE + nsec = 0; + g_tooltip.hide_timeout = (struct timespec){.tv_sec=sec, .tv_nsec=nsec}; } else if (strcmp (key, "tooltip_padding") == 0) { extract_values(value, &value1, &value2, &value3); diff --git a/src/tint.c b/src/tint.c index a25e094..3c535c7 100644 --- a/src/tint.c +++ b/src/tint.c @@ -80,7 +80,6 @@ void init (int argc, char *argv[]) sigaction(SIGTERM, &sa, 0); sigaction(SIGHUP, &sa, 0); signal(SIGCHLD, SIG_IGN); // don't have to wait() after fork() - signal(SIGALRM, tooltip_sighandler); // block all signals, such that no race conditions occur before pselect in our main loop sigset_t block_mask; sigaddset(&block_mask, SIGINT); @@ -827,6 +826,8 @@ int main (int argc, char *argv[]) } } + // we need to iterate over the whole timer list, since fd_set can only be checked with the + // brute force method FD_ISSET for every possible timer timer_iter = timer_list; while (timer_iter) { timer = timer_iter->data; diff --git a/src/tooltip/tooltip.c b/src/tooltip/tooltip.c index d7d4f2e..07af226 100644 --- a/src/tooltip/tooltip.c +++ b/src/tooltip/tooltip.c @@ -23,27 +23,31 @@ #include "server.h" #include "tooltip.h" #include "panel.h" - -// TODO: Use timer_create instead of setitimer, because SIGALRM is not the right signal for this... -// Reason: If we want to implement autohide we have to use another signal... +#include "timer.h" static int x, y, width, height; +// the next functions are helper functions for tooltip handling +void start_show_timeout(); +void start_hide_timeout(); +void stop_timeouts(); + // give the tooltip some reasonable default values Tooltip g_tooltip = { .task = 0, .window = 0, - .show_timeout = { .it_interval={0, 0}, .it_value={0, 0} }, - .hide_timeout = { .it_interval={0, 0}, .it_value={0, 0} }, + .show_timeout = { 0, 0 }, + .hide_timeout = { 0, 0 }, .enabled = False, - .current_state = TOOLTIP_ABOUT_TO_HIDE, .mapped = False, .paddingx = 0, .paddingy = 0, .font_color = { .color={1, 1, 1}, .alpha=1 }, .background_color = { .color={0.5, 0.4, 0.5}, .alpha=1 }, .border = { .color={0, 0, 0}, .alpha=1, .width=1, .rounded=0 }, - .font_desc = 0 + .font_desc = 0, + .show_timer_id = 0, + .hide_timer_id = 0 }; void init_tooltip() @@ -51,6 +55,11 @@ void init_tooltip() if (!g_tooltip.font_desc) g_tooltip.font_desc = pango_font_description_from_string("sans 10"); + if (g_tooltip.show_timer_id == 0) + g_tooltip.show_timer_id = install_timer(0, 0, 0, 0, tooltip_show); + if (g_tooltip.hide_timer_id == 0) + g_tooltip.hide_timer_id = install_timer(0, 0, 0, 0, tooltip_hide); + XSetWindowAttributes attr; attr.override_redirect = True; attr.event_mask = ExposureMask; @@ -61,10 +70,9 @@ void init_tooltip() void cleanup_tooltip() { - alarm(0); + stop_timeouts(); tooltip_hide(); g_tooltip.enabled = False; - g_tooltip.current_state = TOOLTIP_ABOUT_TO_HIDE; if (g_tooltip.task) { g_tooltip.task = 0; } @@ -79,15 +87,6 @@ void cleanup_tooltip() } -void tooltip_sighandler(int sig) -{ - if (g_tooltip.current_state == TOOLTIP_ABOUT_TO_SHOW) - tooltip_show(); - else if (g_tooltip.current_state == TOOLTIP_ABOUT_TO_HIDE) - tooltip_hide(); -} - - void tooltip_trigger_show(Task* task, int x_root, int y_root) { x = x_root; @@ -96,18 +95,11 @@ void tooltip_trigger_show(Task* task, int x_root, int y_root) if (g_tooltip.mapped && g_tooltip.task != task) { g_tooltip.task = task; tooltip_update(); - alarm(0); + stop_timeouts(); } else if (!g_tooltip.mapped) { - g_tooltip.current_state = TOOLTIP_ABOUT_TO_SHOW; g_tooltip.task = task; - struct timeval t = g_tooltip.show_timeout.it_value; - if (t.tv_sec == 0 && t.tv_usec == 0) { - alarm(0); - tooltip_show(); - } - else - setitimer(ITIMER_REAL, &g_tooltip.show_timeout, 0); + start_show_timeout(); } } @@ -118,7 +110,6 @@ void tooltip_show() g_tooltip.mapped = True; XMapWindow(server.dsp, g_tooltip.window); //tooltip_update(); - alarm(0); } } @@ -251,19 +242,12 @@ void tooltip_update() void tooltip_trigger_hide(Tooltip* tooltip) { if (g_tooltip.mapped) { - g_tooltip.current_state = TOOLTIP_ABOUT_TO_HIDE; - struct timeval t = g_tooltip.hide_timeout.it_value; g_tooltip.task = 0; - if (t.tv_sec == 0 && t.tv_usec == 0) { - tooltip_hide(); - alarm(0); - } - else - setitimer(ITIMER_REAL, &g_tooltip.hide_timeout, 0); + start_hide_timeout(); } else { - // tooltip not visible yet, but maybe an alarm is still pending - alarm(0); + // tooltip not visible yet, but maybe a timeout is still pending + stop_timeouts(); } } @@ -275,3 +259,31 @@ void tooltip_hide() XUnmapWindow(server.dsp, g_tooltip.window); } } + + +void start_show_timeout() +{ + reset_timer(g_tooltip.hide_timer_id, 0, 0, 0, 0); + struct timespec t = g_tooltip.show_timeout; + if (t.tv_sec == 0 && t.tv_nsec == 0) + tooltip_show(); + else + reset_timer(g_tooltip.show_timer_id, t.tv_sec, t.tv_nsec, 0, 0); +} + + +void start_hide_timeout() +{ + reset_timer(g_tooltip.show_timer_id, 0, 0, 0, 0); + struct timespec t = g_tooltip.hide_timeout; + if (t.tv_sec == 0 && t.tv_nsec == 0) + tooltip_hide(); + else + reset_timer(g_tooltip.hide_timer_id, t.tv_sec, t.tv_nsec, 0, 0); +} + +void stop_timeouts() +{ + reset_timer(g_tooltip.show_timer_id, 0, 0, 0, 0); + reset_timer(g_tooltip.hide_timer_id, 0, 0, 0, 0); +} diff --git a/src/tooltip/tooltip.h b/src/tooltip/tooltip.h index cddb73c..53f1256 100644 --- a/src/tooltip/tooltip.h +++ b/src/tooltip/tooltip.h @@ -22,18 +22,13 @@ #include "task.h" -enum tooltip_state { - TOOLTIP_ABOUT_TO_SHOW, - TOOLTIP_ABOUT_TO_HIDE, -}; typedef struct { Task* task; Window window; - struct itimerval show_timeout; - struct itimerval hide_timeout; + struct timespec show_timeout; + struct timespec hide_timeout; Bool enabled; - enum tooltip_state current_state; Bool mapped; int paddingx; int paddingy; @@ -41,14 +36,14 @@ typedef struct { config_color font_color; Color background_color; Border border; + int show_timer_id; + int hide_timer_id; } Tooltip; extern Tooltip g_tooltip; - void init_tooltip(); void cleanup_tooltip(); -void tooltip_sighandler(int sig); void tooltip_trigger_show(Task* task, int x, int y); void tooltip_show(); void tooltip_update();