Fix dangling pointers causing erratic timer behaviour (affects taskbar with spacing); use calloc instead of malloc for safer initializations

git-svn-id: http://tint2.googlecode.com/svn/trunk@758 121b4492-b84c-0410-8b4c-0d4edfb3f3cc
This commit is contained in:
o9000
2015-04-17 20:17:25 +00:00
committed by mrovi9000@gmail.com
parent 778b9f0ebf
commit 66cae4bb7c
17 changed files with 135 additions and 123 deletions

View File

@@ -2,26 +2,38 @@
# For information on manually configuring tint2 see http://code.google.com/p/tint2/wiki/Configure # For information on manually configuring tint2 see http://code.google.com/p/tint2/wiki/Configure
# Background definitions # Background definitions
# ID 1 # Background 1: panel
rounded = 7 rounded = 7
border_width = 2 border_width = 1
background_color = #000000 60 background_color = #000000 60
border_color = #FFFFFF 16 border_color = #FFFFFF 16
# ID 2 # Background 2: normal/iconified tasks
rounded = 5 rounded = 5
border_width = 0 border_width = 0
background_color = #777777 40 background_color = #777777 20
border_color = #FFFFFF 48 border_color = #777777 30
# ID 3 # Background 3: active tasks
rounded = 5 rounded = 5
border_width = 1 border_width = 1
background_color = #777777 40 background_color = #777777 20
border_color = #FFFFFF 60 border_color = #ffffff 40
# Background 4: urgent tasks
rounded = 5
border_width = 1
background_color = #aa4400 100
border_color = #aa7733 100
# Background 5: tooltips
rounded = 2
border_width = 1
background_color = #ffffaa 100
border_color = #999999 100
# Panel # Panel
panel_items = LTSC panel_items = LTSBC
panel_monitor = all panel_monitor = all
panel_position = bottom center horizontal panel_position = bottom center horizontal
panel_size = 95% 30 panel_size = 95% 30
@@ -34,8 +46,8 @@ panel_background_id = 1
# Panel Autohide # Panel Autohide
autohide = 0 autohide = 0
autohide_show_timeout = 0.3 autohide_show_timeout = 0
autohide_hide_timeout = 2 autohide_hide_timeout = 0.5
autohide_height = 2 autohide_height = 2
strut_policy = follow_size strut_policy = follow_size
@@ -63,13 +75,13 @@ task_maximum_size = 140 35
task_padding = 6 2 task_padding = 6 2
task_background_id = 2 task_background_id = 2
task_active_background_id = 3 task_active_background_id = 3
task_urgent_background_id = 2 task_urgent_background_id = 4
task_iconified_background_id = 2 task_iconified_background_id = 2
task_tooltip = 0 task_tooltip = 1
urgent_nb_of_blink = 100000 urgent_nb_of_blink = 100000
# Task Icons # Task Icons
task_icon_asb = 80 0 0 task_icon_asb = 100 0 0
task_active_icon_asb = 100 0 0 task_active_icon_asb = 100 0 0
task_urgent_icon_asb = 100 0 0 task_urgent_icon_asb = 100 0 0
task_iconified_icon_asb = 70 0 0 task_iconified_icon_asb = 70 0 0
@@ -86,8 +98,8 @@ font_shadow = 0
mouse_left = toggle_iconify mouse_left = toggle_iconify
mouse_middle = none mouse_middle = none
mouse_right = close mouse_right = close
mouse_scroll_up = toggle mouse_scroll_up = prev_task
mouse_scroll_down = iconify mouse_scroll_down = next_task
# System Tray # System Tray
systray_padding = 0 4 5 systray_padding = 0 4 5
@@ -101,18 +113,18 @@ time1_format = %H:%M
time1_font = sans 8 time1_font = sans 8
time2_format = %A %d %B time2_format = %A %d %B
time2_font = sans 7 time2_font = sans 7
clock_font_color = #FFFFFF 74 clock_font_color = #FFFFFF 90
clock_padding = 1 0 clock_padding = 1 0
clock_background_id = 0 clock_background_id = 0
clock_rclick_command = orage clock_rclick_command = orage
# Tooltips # Tooltips
tooltip_padding = 2 2 tooltip_padding = 2 2
tooltip_show_timeout = 0.7 tooltip_show_timeout = 0.5
tooltip_hide_timeout = 0.3 tooltip_hide_timeout = 0.1
tooltip_background_id = 1 tooltip_background_id = 5
tooltip_font = sans 10 tooltip_font = sans 9
tooltip_font_color = #000000 80 tooltip_font_color = #222222 100
# Battery # Battery
battery_low_status = 10 battery_low_status = 10
@@ -120,7 +132,7 @@ battery_low_cmd = notify-send "battery low"
battery_hide = 98 battery_hide = 98
bat1_font = sans 8 bat1_font = sans 8
bat2_font = sans 6 bat2_font = sans 6
battery_font_color = #FFFFFF 74 battery_font_color = #FFFFFF 94
battery_padding = 1 0 battery_padding = 1 0
battery_background_id = 0 battery_background_id = 0

View File

@@ -274,9 +274,8 @@ void init_battery()
} }
#endif #endif
if (battery_timeout == 0) { if (!battery_timeout)
battery_timeout = add_timeout(10, 10000, update_battery_tick, 0); battery_timeout = add_timeout(10, 10000, update_battery_tick, 0, &battery_timeout);
}
} }

View File

@@ -152,9 +152,9 @@ void init_clock()
if (!clock_timeout) { if (!clock_timeout) {
if (time_format_needs_sec_ticks(time1_format) || if (time_format_needs_sec_ticks(time1_format) ||
time_format_needs_sec_ticks(time2_format)) { time_format_needs_sec_ticks(time2_format)) {
clock_timeout = add_timeout(10, 1000, update_clocks_sec, 0); clock_timeout = add_timeout(10, 1000, update_clocks_sec, 0, &clock_timeout);
} else { } else {
clock_timeout = add_timeout(10, 1000, update_clocks_min, 0); clock_timeout = add_timeout(10, 1000, update_clocks_min, 0, &clock_timeout);
} }
} }
} }

View File

@@ -52,7 +52,7 @@ void expand_exec(DesktopEntry *entry, const char *path)
// %c -> Name // %c -> Name
// %k -> path // %k -> path
if (entry->exec) { if (entry->exec) {
char *exec2 = malloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) + (entry->icon ? strlen(entry->icon) : 1) + 100); char *exec2 = calloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) + (entry->icon ? strlen(entry->icon) : 1) + 100, 1);
char *p, *q; char *p, *q;
// p will never point to an escaped char // p will never point to an escaped char
for (p = entry->exec, q = exec2; *p; p++, q++) { for (p = entry->exec, q = exec2; *p; p++, q++) {

View File

@@ -561,8 +561,8 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
char *theme_name = ((IconTheme*)theme->data)->name; char *theme_name = ((IconTheme*)theme->data)->name;
char *dir_name = ((IconThemeDir*)dir->data)->name; char *dir_name = ((IconThemeDir*)dir->data)->name;
char *extension = (char*) ext->data; char *extension = (char*) ext->data;
char *file_name = malloc(strlen(base_name) + strlen(theme_name) + char *file_name = calloc(strlen(base_name) + strlen(theme_name) +
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100); strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100, 1);
// filename = directory/$(themename)/subdirectory/iconname.extension // filename = directory/$(themename)/subdirectory/iconname.extension
sprintf(file_name, "%s/%s/%s/%s%s", base_name, theme_name, dir_name, icon_name, extension); sprintf(file_name, "%s/%s/%s/%s%s", base_name, theme_name, dir_name, icon_name, extension);
if (DEBUG_ICON_SEARCH) if (DEBUG_ICON_SEARCH)
@@ -620,8 +620,8 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
for (ext = extensions; ext; ext = g_slist_next(ext)) { for (ext = extensions; ext; ext = g_slist_next(ext)) {
char *base_name = (char*) base->data; char *base_name = (char*) base->data;
char *extension = (char*) ext->data; char *extension = (char*) ext->data;
char *file_name = malloc(strlen(base_name) + strlen(icon_name) + char *file_name = calloc(strlen(base_name) + strlen(icon_name) +
strlen(extension) + 100); strlen(extension) + 100, 1);
// filename = directory/iconname.extension // filename = directory/iconname.extension
sprintf(file_name, "%s/%s%s", base_name, icon_name, extension); sprintf(file_name, "%s/%s%s", base_name, icon_name, extension);
if (DEBUG_ICON_SEARCH) if (DEBUG_ICON_SEARCH)

View File

@@ -391,7 +391,7 @@ void free_icon(Imlib_Image icon)
void launcher_action(LauncherIcon *icon, XEvent* evt) void launcher_action(LauncherIcon *icon, XEvent* evt)
{ {
char *cmd = malloc(strlen(icon->cmd) + 10); char *cmd = calloc(strlen(icon->cmd) + 10, 1);
sprintf(cmd, "(%s&)", icon->cmd); sprintf(cmd, "(%s&)", icon->cmd);
#if HAVE_SN #if HAVE_SN
SnLauncherContext* ctx; SnLauncherContext* ctx;

View File

@@ -235,14 +235,14 @@ static XSettingsList *parse_settings (unsigned char *data, size_t len)
goto out; goto out;
} }
setting = malloc (sizeof *setting); setting = calloc (1, sizeof *setting);
if (!setting) { if (!setting) {
result = XSETTINGS_NO_MEM; result = XSETTINGS_NO_MEM;
goto out; goto out;
} }
setting->type = XSETTINGS_TYPE_INT; /* No allocated memory */ setting->type = XSETTINGS_TYPE_INT; /* No allocated memory */
setting->name = malloc (name_len + 1); setting->name = calloc (name_len + 1, 1);
if (!setting->name) { if (!setting->name) {
result = XSETTINGS_NO_MEM; result = XSETTINGS_NO_MEM;
goto out; goto out;
@@ -276,7 +276,7 @@ static XSettingsList *parse_settings (unsigned char *data, size_t len)
goto out; goto out;
} }
setting->data.v_string = malloc (v_int + 1); setting->data.v_string = calloc (v_int + 1, 1);
if (!setting->data.v_string) { if (!setting->data.v_string) {
result = XSETTINGS_NO_MEM; result = XSETTINGS_NO_MEM;
goto out; goto out;
@@ -400,7 +400,7 @@ XSettingsClient *xsettings_client_new (Display *display, int screen, XSettingsNo
{ {
XSettingsClient *client; XSettingsClient *client;
client = malloc (sizeof *client); client = calloc (1, sizeof *client);
if (!client) if (!client)
return NULL; return NULL;

View File

@@ -34,12 +34,12 @@ xsettings_setting_copy (XSettingsSetting *setting)
XSettingsSetting *result; XSettingsSetting *result;
size_t str_len; size_t str_len;
result = malloc (sizeof *result); result = calloc (1, sizeof *result);
if (!result) if (!result)
return NULL; return NULL;
str_len = strlen (setting->name); str_len = strlen (setting->name);
result->name = malloc (str_len + 1); result->name = calloc (str_len + 1, 1);
if (!result->name) if (!result->name)
goto err; goto err;
@@ -57,7 +57,7 @@ xsettings_setting_copy (XSettingsSetting *setting)
break; break;
case XSETTINGS_TYPE_STRING: case XSETTINGS_TYPE_STRING:
str_len = strlen (setting->data.v_string); str_len = strlen (setting->data.v_string);
result->data.v_string = malloc (str_len + 1); result->data.v_string = calloc (str_len + 1, 1);
if (!result->data.v_string) if (!result->data.v_string)
goto err; goto err;
@@ -90,7 +90,7 @@ xsettings_list_copy (XSettingsList *list)
{ {
XSettingsList *new_node; XSettingsList *new_node;
new_node = malloc (sizeof *new_node); new_node = calloc (1, sizeof *new_node);
if (!new_node) if (!new_node)
goto error; goto error;
@@ -180,7 +180,7 @@ xsettings_list_insert (XSettingsList **list,
XSettingsList *iter; XSettingsList *iter;
XSettingsList *last = NULL; XSettingsList *last = NULL;
node = malloc (sizeof *node); node = calloc (1, sizeof *node);
if (!node) if (!node)
return XSETTINGS_NO_MEM; return XSETTINGS_NO_MEM;
node->setting = setting; node->setting = setting;

View File

@@ -126,6 +126,7 @@ void cleanup_panel()
if (p->main_win) if (p->main_win)
XDestroyWindow(server.dsp, p->main_win); XDestroyWindow(server.dsp, p->main_win);
p->main_win = 0; p->main_win = 0;
stop_timeout(p->autohide_timeout);
} }
free(panel_items_order); free(panel_items_order);
@@ -167,7 +168,7 @@ void init_panel()
else else
nb_panel = server.nb_monitor; nb_panel = server.nb_monitor;
panel1 = malloc(nb_panel * sizeof(Panel)); panel1 = calloc(nb_panel, sizeof(Panel));
for (i=0 ; i < nb_panel ; i++) { for (i=0 ; i < nb_panel ; i++) {
memcpy(&panel1[i], &panel_config, sizeof(Panel)); memcpy(&panel1[i], &panel_config, sizeof(Panel));
} }
@@ -231,7 +232,7 @@ void init_panel()
} }
if (panel_autohide) if (panel_autohide)
add_timeout(panel_autohide_hide_timeout, 0, autohide_hide, p); autohide_trigger_hide(p);
visible_taskbar(p); visible_taskbar(p);
} }
@@ -811,10 +812,7 @@ Area* click_area(Panel *panel, int x, int y)
void stop_autohide_timeout(Panel* p) void stop_autohide_timeout(Panel* p)
{ {
if (p->autohide_timeout) { stop_timeout(p->autohide_timeout);
stop_timeout(p->autohide_timeout);
p->autohide_timeout = 0;
}
} }
@@ -875,10 +873,7 @@ void autohide_trigger_show(Panel* p)
{ {
if (!p) if (!p)
return; return;
if (p->autohide_timeout) change_timeout(&p->autohide_timeout, panel_autohide_show_timeout, 0, autohide_show, p);
change_timeout(p->autohide_timeout, panel_autohide_show_timeout, 0, autohide_show, p);
else
p->autohide_timeout = add_timeout(panel_autohide_show_timeout, 0, autohide_show, p);
} }
@@ -893,8 +888,5 @@ void autohide_trigger_hide(Panel* p)
if (XQueryPointer(server.dsp, p->main_win, &root, &child, &xr, &yr, &xw, &yw, &mask)) if (XQueryPointer(server.dsp, p->main_win, &root, &child, &xr, &yr, &xw, &yw, &mask))
if (child) return; // mouse over one of the system tray icons if (child) return; // mouse over one of the system tray icons
if (p->autohide_timeout) change_timeout(&p->autohide_timeout, panel_autohide_hide_timeout, 0, autohide_hide, p);
change_timeout(p->autohide_timeout, panel_autohide_hide_timeout, 0, autohide_hide, p);
else
p->autohide_timeout = add_timeout(panel_autohide_hide_timeout, 0, autohide_hide, p);
} }

View File

@@ -295,14 +295,14 @@ void get_monitors()
} }
printf("xRandr: Found crtc's: %d\n", res->ncrtc ); printf("xRandr: Found crtc's: %d\n", res->ncrtc );
server.monitor = malloc(res->ncrtc * sizeof(Monitor)); server.monitor = calloc(res->ncrtc, sizeof(Monitor));
for (i=0; i<res->ncrtc; ++i) { for (i=0; i<res->ncrtc; ++i) {
XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(server.dsp, res, res->crtcs[i]); XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(server.dsp, res, res->crtcs[i]);
server.monitor[i].x = crtc_info->x; server.monitor[i].x = crtc_info->x;
server.monitor[i].y = crtc_info->y; server.monitor[i].y = crtc_info->y;
server.monitor[i].width = crtc_info->width; server.monitor[i].width = crtc_info->width;
server.monitor[i].height = crtc_info->height; server.monitor[i].height = crtc_info->height;
server.monitor[i].names = malloc((crtc_info->noutput+1) * sizeof(gchar*)); server.monitor[i].names = calloc((crtc_info->noutput+1), sizeof(gchar*));
for (j=0; j<crtc_info->noutput; ++j) { for (j=0; j<crtc_info->noutput; ++j) {
XRROutputInfo* output_info = XRRGetOutputInfo(server.dsp, res, crtc_info->outputs[j]); XRROutputInfo* output_info = XRRGetOutputInfo(server.dsp, res, crtc_info->outputs[j]);
printf("xRandr: Linking output %s with crtc %d\n", output_info->name, i); printf("xRandr: Linking output %s with crtc %d\n", output_info->name, i);
@@ -315,7 +315,7 @@ void get_monitors()
nbmonitor = res->ncrtc; nbmonitor = res->ncrtc;
} }
else if (info && nbmonitor > 0) { else if (info && nbmonitor > 0) {
server.monitor = malloc(nbmonitor * sizeof(Monitor)); server.monitor = calloc(nbmonitor, sizeof(Monitor));
for (i=0 ; i < nbmonitor ; i++) { for (i=0 ; i < nbmonitor ; i++) {
server.monitor[i].x = info[i].x_org; server.monitor[i].x = info[i].x_org;
server.monitor[i].y = info[i].y_org; server.monitor[i].y = info[i].y_org;
@@ -353,7 +353,7 @@ next:
if (!server.nb_monitor) { if (!server.nb_monitor) {
server.nb_monitor = 1; server.nb_monitor = 1;
server.monitor = malloc(sizeof(Monitor)); server.monitor = calloc(1, sizeof(Monitor));
server.monitor[0].x = server.monitor[0].y = 0; server.monitor[0].x = server.monitor[0].y = 0;
server.monitor[0].width = DisplayWidth (server.dsp, server.screen); server.monitor[0].width = DisplayWidth (server.dsp, server.screen);
server.monitor[0].height = DisplayHeight (server.dsp, server.screen); server.monitor[0].height = DisplayHeight (server.dsp, server.screen);

View File

@@ -496,8 +496,7 @@ void remove_icon(TrayWindow *traywin)
XDestroyWindow(server.dsp, traywin->id); XDestroyWindow(server.dsp, traywin->id);
XSync(server.dsp, False); XSync(server.dsp, False);
XSetErrorHandler(old); XSetErrorHandler(old);
if (traywin->render_timeout) stop_timeout(traywin->render_timeout);
stop_timeout(traywin->render_timeout);
g_free(traywin); g_free(traywin);
// check empty systray // check empty systray
@@ -619,8 +618,8 @@ void systray_render_icon(TrayWindow* traywin)
{ {
if (FORCE_COMPOSITED_RENDERING || server.real_transparency || systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0) { if (FORCE_COMPOSITED_RENDERING || server.real_transparency || systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0) {
// wine tray icons update whenever mouse is over them, so we limit the updates to 50 ms // wine tray icons update whenever mouse is over them, so we limit the updates to 50 ms
if (traywin->render_timeout == 0) if (!traywin->render_timeout)
traywin->render_timeout = add_timeout(50, 0, systray_render_icon_now, traywin); traywin->render_timeout = add_timeout(50, 0, systray_render_icon_now, traywin, &traywin->render_timeout);
} }
else { else {
// Pixmap pix = XCreatePixmap(server.dsp, server.root_win, traywin->width, traywin->height, server.depth); // Pixmap pix = XCreatePixmap(server.dsp, server.root_win, traywin->width, traywin->height, server.depth);

View File

@@ -87,7 +87,7 @@ Task *add_task (Window win)
if (new_tsk.desktop != ALLDESKTOP && new_tsk.desktop != j) continue; if (new_tsk.desktop != ALLDESKTOP && new_tsk.desktop != j) continue;
tskbar = &panel1[monitor].taskbar[j]; tskbar = &panel1[monitor].taskbar[j];
new_tsk2 = malloc(sizeof(Task)); new_tsk2 = calloc(1, sizeof(Task));
memcpy(&new_tsk2->area, &panel1[monitor].g_task.area, sizeof(Area)); memcpy(&new_tsk2->area, &panel1[monitor].g_task.area, sizeof(Area));
new_tsk2->area.parent = tskbar; new_tsk2->area.parent = tskbar;
new_tsk2->win = new_tsk.win; new_tsk2->win = new_tsk.win;
@@ -115,7 +115,7 @@ Task *add_task (Window win)
g_ptr_array_add(task_group, new_tsk2); g_ptr_array_add(task_group, new_tsk2);
//printf("add_task panel %d, desktop %d, task %s\n", i, j, new_tsk2->title); //printf("add_task panel %d, desktop %d, task %s\n", i, j, new_tsk2->title);
} }
Window* key = malloc(sizeof(Window)); Window* key = calloc(1, sizeof(Window));
*key = new_tsk.win; *key = new_tsk.win;
g_hash_table_insert(win_to_task_table, key, task_group); g_hash_table_insert(win_to_task_table, key, task_group);
set_task_state(new_tsk2, new_tsk.current_state); set_task_state(new_tsk2, new_tsk.current_state);
@@ -195,14 +195,14 @@ int get_title(Task *tsk)
if (!name || !strlen(name)) { if (!name || !strlen(name)) {
name = server_get_property (tsk->win, server.atom.WM_NAME, XA_STRING, 0); name = server_get_property (tsk->win, server.atom.WM_NAME, XA_STRING, 0);
if (!name || !strlen(name)) { if (!name || !strlen(name)) {
name = malloc(10); name = calloc(10, 1);
strcpy(name, "Untitled"); strcpy(name, "Untitled");
} }
} }
} }
// add space before title // add space before title
title = malloc(strlen(name)+2); title = calloc(strlen(name)+2, 1);
if (panel->g_task.icon) strcpy(title, " "); if (panel->g_task.icon) strcpy(title, " ");
else title[0] = 0; else title[0] = 0;
strcat(title, name); strcat(title, name);
@@ -620,7 +620,7 @@ void add_urgent(Task *tsk)
urgent_list = g_slist_prepend(urgent_list, tsk); urgent_list = g_slist_prepend(urgent_list, tsk);
if (!urgent_timeout) if (!urgent_timeout)
urgent_timeout = add_timeout(10, 1000, blink_urgent, 0); urgent_timeout = add_timeout(10, 1000, blink_urgent, 0, &urgent_timeout);
Panel *panel = tsk->area.panel; Panel *panel = tsk->area.panel;
if (panel->is_hidden) if (panel->is_hidden)

View File

@@ -109,7 +109,6 @@ void cleanup_taskbar()
urgent_list = NULL; urgent_list = NULL;
stop_timeout(urgent_timeout); stop_timeout(urgent_timeout);
urgent_timeout = NULL;
} }

View File

@@ -1350,7 +1350,7 @@ start:
cmd_length += 2; // &) cmd_length += 2; // &)
cmd_length += 1; // terminator cmd_length += 1; // terminator
char *cmd = malloc(cmd_length); char *cmd = calloc(cmd_length, 1);
cmd[0] = '\0'; cmd[0] = '\0';
strcat(cmd, "("); strcat(cmd, "(");
strcat(cmd, dnd_launcher_exec); strcat(cmd, dnd_launcher_exec);

View File

@@ -86,7 +86,7 @@ void init_tooltip()
void tooltip_trigger_show(Area* area, Panel* p, XEvent *e) void tooltip_trigger_show(Area* area, Panel* p, XEvent *e)
{ {
// Position the tooltip in the center of the area // Position the tooltip in the center of the area
x = area->posx + area->width / 2 + e->xmotion.x_root - e->xmotion.x; x = area->posx + MIN(area->width / 3, 22) + e->xmotion.x_root - e->xmotion.x;
y = area->posy + area->height / 2 + e->xmotion.y_root - e->xmotion.y; y = area->posy + area->height / 2 + e->xmotion.y_root - e->xmotion.y;
just_shown = 1; just_shown = 1;
g_tooltip.panel = p; g_tooltip.panel = p;
@@ -108,7 +108,6 @@ void tooltip_show(void* arg)
XTranslateCoordinates( server.dsp, server.root_win, g_tooltip.panel->main_win, x, y, &mx, &my, &w); XTranslateCoordinates( server.dsp, server.root_win, g_tooltip.panel->main_win, x, y, &mx, &my, &w);
Area* area; Area* area;
area = click_area(g_tooltip.panel, mx, my); area = click_area(g_tooltip.panel, mx, my);
stop_tooltip_timeout();
if (!g_tooltip.mapped && area->_get_tooltip_text) { if (!g_tooltip.mapped && area->_get_tooltip_text) {
tooltip_copy_text(area); tooltip_copy_text(area);
g_tooltip.mapped = True; g_tooltip.mapped = True;
@@ -275,7 +274,6 @@ void tooltip_trigger_hide(Tooltip* tooltip)
void tooltip_hide(void* arg) void tooltip_hide(void* arg)
{ {
stop_tooltip_timeout();
if (g_tooltip.mapped) { if (g_tooltip.mapped) {
g_tooltip.mapped = False; g_tooltip.mapped = False;
XUnmapWindow(server.dsp, g_tooltip.window); XUnmapWindow(server.dsp, g_tooltip.window);
@@ -286,26 +284,19 @@ void tooltip_hide(void* arg)
void start_show_timeout() void start_show_timeout()
{ {
if (g_tooltip.timeout) change_timeout(&g_tooltip.timeout, g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
change_timeout(g_tooltip.timeout, g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
else
g_tooltip.timeout = add_timeout(g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
} }
void start_hide_timeout() void start_hide_timeout()
{ {
if (g_tooltip.timeout) change_timeout(&g_tooltip.timeout, g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
change_timeout(g_tooltip.timeout, g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
else
g_tooltip.timeout = add_timeout(g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
} }
void stop_tooltip_timeout() void stop_tooltip_timeout()
{ {
stop_timeout(g_tooltip.timeout); stop_timeout(g_tooltip.timeout);
g_tooltip.timeout = NULL;
} }

View File

@@ -44,6 +44,7 @@ struct _timeout {
void (*_callback)(void*); void (*_callback)(void*);
void* arg; void* arg;
multi_timeout* multi_timeout; multi_timeout* multi_timeout;
timeout **self;
}; };
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(void*), void* arg, timeout* t); void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(void*), void* arg, timeout* t);
@@ -74,6 +75,8 @@ void cleanup_timeout()
timeout* t = timeout_list->data; timeout* t = timeout_list->data;
if (t->multi_timeout) if (t->multi_timeout)
stop_multi_timeout(t); stop_multi_timeout(t);
if (t->self)
*t->self = NULL;
free(t); free(t);
timeout_list = g_slist_remove(timeout_list, t); timeout_list = g_slist_remove(timeout_list, t);
} }
@@ -95,25 +98,26 @@ void cleanup_timeout()
* however it's save to call it. * however it's save to call it.
**/ **/
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg) timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg, timeout **self)
{ {
timeout* t = malloc(sizeof(timeout)); timeout* t = calloc(1, sizeof(timeout));
t->multi_timeout = 0; t->self = self;
add_timeout_intern(value_msec, interval_msec, _callback, arg, t); add_timeout_intern(value_msec, interval_msec, _callback, arg, t);
return t; return t;
} }
void change_timeout(timeout *t, int value_msec, int interval_msec, void(*_callback)(), void* arg) void change_timeout(timeout **t, int value_msec, int interval_msec, void(*_callback)(), void* arg)
{ {
if ( g_slist_find(timeout_list, t) == 0 && g_hash_table_lookup(multi_timeouts, t) == 0) if (!((timeout_list && g_slist_find(timeout_list, *t)) ||
printf("programming error: timeout already deleted..."); (multi_timeouts && g_hash_table_lookup(multi_timeouts, *t))))
*t = add_timeout(value_msec, interval_msec, _callback, arg, t);
else { else {
if (t->multi_timeout) if ((*t)->multi_timeout)
remove_from_multi_timeout((timeout*)t); remove_from_multi_timeout(*t);
else else
timeout_list = g_slist_remove(timeout_list, t); timeout_list = g_slist_remove(timeout_list, *t);
add_timeout_intern(value_msec, interval_msec, _callback, arg, (timeout*)t); add_timeout_intern(value_msec, interval_msec, _callback, arg, *t);
} }
} }
@@ -149,31 +153,40 @@ void callback_timeout_expired()
if (compare_timespecs(&t->timeout_expires, &cur_time) <= 0) { if (compare_timespecs(&t->timeout_expires, &cur_time) <= 0) {
// it's time for the callback function // it's time for the callback function
t->_callback(t->arg); t->_callback(t->arg);
// If _callback() calls stop_timeout(t) the timer 't' was freed and is not in the timeout_list
if (g_slist_find(timeout_list, t)) { if (g_slist_find(timeout_list, t)) {
// if _callback() calls stop_timeout(t) the timeout 't' was freed and is not in the timeout_list // Timer still exists
timeout_list = g_slist_remove(timeout_list, t); timeout_list = g_slist_remove(timeout_list, t);
if (t->interval_msec > 0) if (t->interval_msec > 0) {
add_timeout_intern(t->interval_msec, t->interval_msec, t->_callback, t->arg, t); add_timeout_intern(t->interval_msec, t->interval_msec, t->_callback, t->arg, t);
else } else {
// Destroy single-shot timer
if (t->self)
*t->self = NULL;
free(t); free(t);
}
} }
} } else {
else
return; return;
}
} }
} }
void stop_timeout(timeout* t) void stop_timeout(timeout* t)
{ {
if (!multi_timeouts || !t) if (!t)
return; return;
// if not in the list, it was deleted in callback_timeout_expired // if not in the list, it was deleted in callback_timeout_expired
if (g_slist_find(timeout_list, t) || g_hash_table_lookup(multi_timeouts, t)) { if ((timeout_list && g_slist_find(timeout_list, t)) ||
if (t->multi_timeout) (multi_timeouts && g_hash_table_lookup(multi_timeouts, t))) {
remove_from_multi_timeout((timeout*)t); if (multi_timeouts && t->multi_timeout)
timeout_list = g_slist_remove(timeout_list, t); remove_from_multi_timeout(t);
free((void*)t); if (timeout_list)
timeout_list = g_slist_remove(timeout_list, t);
if (t->self)
*t->self = NULL;
free(t);
} }
} }
@@ -198,7 +211,7 @@ void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(), v
gint compare_timeouts(gconstpointer t1, gconstpointer t2) gint compare_timeouts(gconstpointer t1, gconstpointer t2)
{ {
return compare_timespecs(&((timeout*)t1)->timeout_expires, return compare_timespecs(&((timeout*)t1)->timeout_expires,
&((timeout*)t2)->timeout_expires); &((timeout*)t2)->timeout_expires);
} }
@@ -262,12 +275,13 @@ int align_with_existing_timeouts(timeout *t)
if (t->interval_msec % t2->interval_msec == 0 || t2->interval_msec % t->interval_msec == 0) { if (t->interval_msec % t2->interval_msec == 0 || t2->interval_msec % t->interval_msec == 0) {
if (multi_timeouts == 0) if (multi_timeouts == 0)
multi_timeouts = g_hash_table_new(0, 0); multi_timeouts = g_hash_table_new(0, 0);
if (!t->multi_timeout && !t2->multi_timeout) if (!t->multi_timeout && !t2->multi_timeout) {
// both timeouts can be aligned, but there is no multi timeout for them // both timeouts can be aligned, but there is no multi timeout for them
create_multi_timeout(t, t2); create_multi_timeout(t, t2);
else } else {
// there is already a multi timeout, so we append the new timeout to the multi timeout // there is already a multi timeout, so we append the new timeout to the multi timeout
append_multi_timeout(t, t2); append_multi_timeout(t, t2);
}
return 1; return 1;
} }
} }
@@ -295,10 +309,10 @@ int calc_multi_timeout_interval(multi_timeout_handler* mth)
void create_multi_timeout(timeout* t1, timeout* t2) void create_multi_timeout(timeout* t1, timeout* t2)
{ {
multi_timeout* mt1 = malloc(sizeof(multi_timeout)); multi_timeout* mt1 = calloc(1, sizeof(multi_timeout));
multi_timeout* mt2 = malloc(sizeof(multi_timeout)); multi_timeout* mt2 = calloc(1, sizeof(multi_timeout));
multi_timeout_handler* mth = malloc(sizeof(multi_timeout_handler)); multi_timeout_handler* mth = calloc(1, sizeof(multi_timeout_handler));
timeout* real_timeout = malloc(sizeof(timeout)); timeout* real_timeout = calloc(1, sizeof(timeout));
mth->timeout_list = 0; mth->timeout_list = 0;
mth->timeout_list = g_slist_prepend(mth->timeout_list, t1); mth->timeout_list = g_slist_prepend(mth->timeout_list, t1);
@@ -331,7 +345,7 @@ void append_multi_timeout(timeout* t1, timeout* t2)
t1 = tmp; t1 = tmp;
} }
multi_timeout* mt = malloc(sizeof(multi_timeout)); multi_timeout* mt = calloc(1, sizeof(multi_timeout));
multi_timeout_handler* mth = g_hash_table_lookup(multi_timeouts, t1); multi_timeout_handler* mth = g_hash_table_lookup(multi_timeouts, t1);
mth->timeout_list = g_slist_prepend(mth->timeout_list, t2); mth->timeout_list = g_slist_prepend(mth->timeout_list, t2);

View File

@@ -21,7 +21,6 @@
#include <glib.h> #include <glib.h>
extern GSList* timeout_list;
extern struct timeval next_timeout; extern struct timeval next_timeout;
@@ -30,26 +29,33 @@ typedef struct _timeout timeout;
// timer functions // timer functions
/** /**
* Single shot timer (i.e. timer with interval_msec == 0) are deleted automatically as soon as they expire * Single shot timers (i.e. timers with interval_msec == 0) are deleted automatically as soon as they expire,
* i.e. you do not need to stop them, however it is safe to call stop_timeout for these timers. * i.e. you do not need to stop them, however it is safe to call stop_timeout for these timers.
* You can pass the address of the variable storing the pointer to the timer as 'self' in add_timeout, in which
* case it is used to clear the pointer if the timer is destroyed automatically. This enforces the timeout pointers
* to be either valid or NULL.
* Periodic timeouts are aligned to each other whenever possible, i.e. one interval_msec is an * Periodic timeouts are aligned to each other whenever possible, i.e. one interval_msec is an
* integral multiple of the other. * integral multiple of the other.
**/ **/
/** default global data **/ /** Initializes default global data. **/
void default_timeout(); void default_timeout();
/** freed memory : stops all timeouts **/ /** Cleans up: stops all timers and frees memory. **/
void cleanup_timeout(); void cleanup_timeout();
/** installs a timeout with the first timeout of 'value_msec' and then a periodic timeout with /** Installs a timer with the first timeout after 'value_msec' and then an optional periodic timeout every
* 'interval_msec'. '_callback' is the callback function when the timer reaches the timeout. * 'interval_msec' (set it to 0 to prevent periodic timeouts).
* returns a pointer to the timeout, which is needed for stopping it again * '_callback' is the function called when the timer reaches the timeout.
* 'arg' is the argument passed to the callback function.
* 'self' is an optional pointer to a timeout* variable. If non-NULL, the variable is set to NULL when the timer
* is destroyed (with stop_timeout, cleanup_timeout or when the timer expires and it is single-shot).
* Returns a pointer to the timer, which is needed for stopping/changing it.
**/ **/
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg); timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg, timeout **self);
/** changes timeout 't'. If timeout 't' does not exist, nothing happens **/ /** Changes timer 't'. If it does not exist, a new timer is created, with self set to 't'. **/
void change_timeout(timeout* t, int value_msec, int interval_msec, void (*_callback)(void*), void* arg); void change_timeout(timeout** t, int value_msec, int interval_msec, void (*_callback)(void*), void* arg);
/** stops the timeout 't' **/ /** stops the timeout 't' **/
void stop_timeout(timeout* t); void stop_timeout(timeout* t);