+
+void set_task_state(Task *tsk, int state)
+{
+ if (tsk == 0 || state < 0 || state >= TASK_STATE_COUNT)
+ return;
+
+ if (tsk->current_state != state) {
+ GPtrArray* task_group = task_get_tasks(tsk->win);
+ if (task_group) {
+ int i;
+ for (i=0; i<task_group->len; ++i) {
+ Task* tsk1 = g_ptr_array_index(task_group, i);
+ tsk1->current_state = state;
+ tsk1->area.bg = panel1[0].g_task.background[state];
+ tsk1->area.pix = tsk1->state_pix[state];
+ if (tsk1->state_pix[state] == 0)
+ tsk1->area.redraw = 1;
+ if (state == TASK_ACTIVE && g_slist_find(urgent_list, tsk1))
+ del_urgent(tsk1);
+ }
+ panel_refresh = 1;
+ }
+ }
+}
+
+
+void set_task_redraw(Task* tsk)
+{
+ int k;
+ for (k=0; k<TASK_STATE_COUNT; ++k) {
+ if (tsk->state_pix[k]) XFreePixmap(server.dsp, tsk->state_pix[k]);
+ tsk->state_pix[k] = 0;
+ }
+ tsk->area.pix = 0;
+ tsk->area.redraw = 1;
+}
+
+
+void blink_urgent(void* arg)
+{
+ GSList* urgent_task = urgent_list;
+ while (urgent_task) {
+ Task* t = urgent_task->data;
+ if ( t->urgent_tick < max_tick_urgent) {
+ if (t->urgent_tick++ % 2)
+ set_task_state(t, TASK_URGENT);
+ else
+ set_task_state(t, window_is_iconified(t->win) ? TASK_ICONIFIED : TASK_NORMAL);
+ }
+ urgent_task = urgent_task->next;
+ }
+ panel_refresh = 1;
+}
+
+
+void add_urgent(Task *tsk)
+{
+ if (!tsk)
+ return;
+
+ // some programs set urgency hint although they are active
+ if ( task_active && task_active->win == tsk->win )
+ return;
+
+ tsk = task_get_task(tsk->win); // always add the first tsk for a task group (omnipresent windows)
+ tsk->urgent_tick = 0;
+ if (g_slist_find(urgent_list, tsk))
+ return;
+
+ // not yet in the list, so we have to add it
+ urgent_list = g_slist_prepend(urgent_list, tsk);
+
+ if (urgent_timeout == 0)
+ urgent_timeout = add_timeout(10, 1000, blink_urgent, 0);
+}
+
+
+void del_urgent(Task *tsk)
+{
+ urgent_list = g_slist_remove(urgent_list, tsk);
+ if (urgent_list == 0) {
+ stop_timeout(urgent_timeout);
+ urgent_timeout = 0;
+ }
+}