2008-10-02 18:47:02 +00:00
|
|
|
/**************************************************************************
|
|
|
|
*
|
|
|
|
* Tint2 : task
|
2009-01-17 14:07:56 +00:00
|
|
|
*
|
2008-10-02 18:47:02 +00:00
|
|
|
* Copyright (C) 2007 Pål Staurland (staura@gmail.com)
|
|
|
|
* Modified (C) 2008 thierry lorthiois (lorthiois@bbsoft.fr)
|
2009-01-17 14:07:56 +00:00
|
|
|
*
|
2008-10-02 18:47:02 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License version 2
|
|
|
|
* as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
**************************************************************************/
|
|
|
|
|
|
|
|
#include <X11/Xlib.h>
|
|
|
|
#include <X11/Xutil.h>
|
|
|
|
#include <X11/Xatom.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <glib.h>
|
2009-10-19 18:27:25 +00:00
|
|
|
#include <unistd.h>
|
2008-10-02 18:47:02 +00:00
|
|
|
|
|
|
|
#include "window.h"
|
|
|
|
#include "task.h"
|
|
|
|
#include "server.h"
|
|
|
|
#include "panel.h"
|
2009-09-14 21:28:17 +00:00
|
|
|
#include "tooltip.h"
|
2009-11-15 16:55:50 +00:00
|
|
|
#include "timer.h"
|
2008-10-02 18:47:02 +00:00
|
|
|
|
2009-11-15 16:55:50 +00:00
|
|
|
static int urgent_timer = 0;
|
2008-10-02 18:47:02 +00:00
|
|
|
|
2009-11-16 17:17:53 +00:00
|
|
|
const char* task_get_tooltip(void* obj)
|
|
|
|
{
|
|
|
|
Task* t = obj;
|
|
|
|
return t->title;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-06-29 19:50:29 +00:00
|
|
|
Task *add_task (Window win)
|
2008-10-02 18:47:02 +00:00
|
|
|
{
|
2009-07-26 13:46:50 +00:00
|
|
|
if (!win) return 0;
|
|
|
|
if (window_is_hidden(win)) return 0;
|
2008-10-02 18:47:02 +00:00
|
|
|
|
2009-07-26 13:46:50 +00:00
|
|
|
int monitor;
|
2009-01-20 00:19:05 +00:00
|
|
|
|
2009-02-07 23:28:13 +00:00
|
|
|
Task new_tsk;
|
2009-07-26 13:46:50 +00:00
|
|
|
new_tsk.win = win;
|
|
|
|
new_tsk.desktop = window_get_desktop (win);
|
2009-10-16 19:38:43 +00:00
|
|
|
if (nb_panel > 1) {
|
|
|
|
monitor = window_get_monitor (win);
|
|
|
|
if (monitor >= nb_panel) monitor = 0;
|
|
|
|
}
|
2009-07-26 13:46:50 +00:00
|
|
|
else monitor = 0;
|
2009-10-16 19:38:43 +00:00
|
|
|
new_tsk.area.panel = &panel1[monitor];
|
2009-01-20 00:19:05 +00:00
|
|
|
|
2009-02-07 23:28:13 +00:00
|
|
|
// allocate only one title and one icon
|
|
|
|
// even with task_on_all_desktop and with task_on_all_panel
|
2009-07-26 13:46:50 +00:00
|
|
|
new_tsk.title = 0;
|
2009-09-19 20:56:15 +00:00
|
|
|
new_tsk.icon = new_tsk.icon_active = NULL;
|
2009-07-26 13:46:50 +00:00
|
|
|
get_title(&new_tsk);
|
|
|
|
get_icon(&new_tsk);
|
2009-01-20 21:16:54 +00:00
|
|
|
|
2009-07-26 13:46:50 +00:00
|
|
|
//printf("task %s : desktop %d, monitor %d\n", new_tsk->title, desktop, monitor);
|
|
|
|
XSelectInput (server.dsp, new_tsk.win, PropertyChangeMask|StructureNotifyMask);
|
2009-02-07 23:28:13 +00:00
|
|
|
|
|
|
|
Taskbar *tskbar;
|
2009-07-26 13:46:50 +00:00
|
|
|
Task *new_tsk2=0;
|
2009-02-07 23:28:13 +00:00
|
|
|
int i, j;
|
2009-09-25 21:40:06 +00:00
|
|
|
for (i=0 ; i < nb_panel ; i++) {
|
|
|
|
for (j=0 ; j < panel1[i].nb_desktop ; j++) {
|
|
|
|
if (new_tsk.desktop != ALLDESKTOP && new_tsk.desktop != j) continue;
|
|
|
|
if (nb_panel > 1 && panel1[i].monitor != monitor) continue;
|
2009-02-07 23:28:13 +00:00
|
|
|
|
2009-07-26 13:46:50 +00:00
|
|
|
tskbar = &panel1[i].taskbar[j];
|
|
|
|
new_tsk2 = malloc(sizeof(Task));
|
|
|
|
memcpy(&new_tsk2->area, &panel1[i].g_task.area, sizeof(Area));
|
|
|
|
new_tsk2->area.parent = tskbar;
|
2009-02-07 23:28:13 +00:00
|
|
|
new_tsk2->win = new_tsk.win;
|
|
|
|
new_tsk2->desktop = new_tsk.desktop;
|
2009-09-26 11:04:02 +00:00
|
|
|
if (new_tsk2->desktop == ALLDESKTOP && server.desktop != j) {
|
|
|
|
// hide ALLDESKTOP task on non-current desktop
|
|
|
|
new_tsk2->area.on_screen = 0;
|
|
|
|
}
|
2009-02-07 23:28:13 +00:00
|
|
|
new_tsk2->title = new_tsk.title;
|
2009-11-16 17:17:53 +00:00
|
|
|
new_tsk2->area._get_tooltip_text = task_get_tooltip;
|
2009-09-19 20:56:15 +00:00
|
|
|
new_tsk2->icon = new_tsk.icon;
|
|
|
|
new_tsk2->icon_active = new_tsk.icon_active;
|
2009-02-07 23:28:13 +00:00
|
|
|
new_tsk2->icon_width = new_tsk.icon_width;
|
|
|
|
new_tsk2->icon_height = new_tsk.icon_height;
|
2009-07-26 13:46:50 +00:00
|
|
|
tskbar->area.list = g_slist_append(tskbar->area.list, new_tsk2);
|
|
|
|
tskbar->area.resize = 1;
|
2009-02-07 23:28:13 +00:00
|
|
|
//printf("add_task panel %d, desktop %d, task %s\n", i, j, new_tsk2->title);
|
|
|
|
}
|
|
|
|
}
|
2009-06-29 19:50:29 +00:00
|
|
|
return new_tsk2;
|
2008-10-02 18:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void remove_task (Task *tsk)
|
|
|
|
{
|
2009-07-26 13:46:50 +00:00
|
|
|
if (!tsk) return;
|
2009-01-20 21:16:54 +00:00
|
|
|
|
2009-07-26 13:46:50 +00:00
|
|
|
Window win = tsk->win;
|
|
|
|
int desktop = tsk->desktop;
|
2009-02-07 23:28:13 +00:00
|
|
|
|
|
|
|
// free title and icon just for the first task
|
|
|
|
// even with task_on_all_desktop and with task_on_all_panel
|
|
|
|
//printf("remove_task %s %d\n", tsk->title, tsk->desktop);
|
|
|
|
if (tsk->title)
|
|
|
|
free (tsk->title);
|
2009-09-19 20:56:15 +00:00
|
|
|
if (tsk->icon) {
|
|
|
|
imlib_context_set_image(tsk->icon);
|
|
|
|
imlib_free_image();
|
|
|
|
imlib_context_set_image(tsk->icon_active);
|
|
|
|
imlib_free_image();
|
|
|
|
tsk->icon = tsk->icon_active = NULL;
|
2009-08-28 12:14:45 +00:00
|
|
|
}
|
2009-02-07 23:28:13 +00:00
|
|
|
|
|
|
|
int i, j;
|
2009-07-26 13:46:50 +00:00
|
|
|
Task *tsk2;
|
|
|
|
Taskbar *tskbar;
|
2009-02-07 23:28:13 +00:00
|
|
|
for (i=0 ; i < nb_panel ; i++) {
|
|
|
|
for (j=0 ; j < panel1[i].nb_desktop ; j++) {
|
2009-02-10 23:16:10 +00:00
|
|
|
if (desktop != ALLDESKTOP && desktop != j) continue;
|
2009-02-07 23:28:13 +00:00
|
|
|
|
|
|
|
GSList *l0;
|
|
|
|
tskbar = &panel1[i].taskbar[j];
|
|
|
|
for (l0 = tskbar->area.list; l0 ; ) {
|
|
|
|
tsk2 = l0->data;
|
|
|
|
l0 = l0->next;
|
|
|
|
if (win == tsk2->win) {
|
|
|
|
tskbar->area.list = g_slist_remove(tskbar->area.list, tsk2);
|
2009-07-26 13:46:50 +00:00
|
|
|
tskbar->area.resize = 1;
|
2009-02-07 23:28:13 +00:00
|
|
|
|
|
|
|
if (tsk2 == task_active)
|
|
|
|
task_active = 0;
|
|
|
|
if (tsk2 == task_drag)
|
|
|
|
task_drag = 0;
|
2009-11-19 13:53:01 +00:00
|
|
|
if (is_urgent(tsk2))
|
|
|
|
del_urgent(tsk2);
|
2009-02-07 23:28:13 +00:00
|
|
|
|
|
|
|
XFreePixmap (server.dsp, tsk2->area.pix.pmap);
|
|
|
|
XFreePixmap (server.dsp, tsk2->area.pix_active.pmap);
|
|
|
|
free(tsk2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-10-02 18:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void get_title(Task *tsk)
|
|
|
|
{
|
2009-07-26 13:46:50 +00:00
|
|
|
Panel *panel = tsk->area.panel;
|
|
|
|
char *title, *name;
|
|
|
|
|
2009-09-14 21:28:17 +00:00
|
|
|
if (!panel->g_task.text && !g_tooltip.enabled) return;
|
2009-07-26 13:46:50 +00:00
|
|
|
|
|
|
|
name = server_get_property (tsk->win, server.atom._NET_WM_VISIBLE_NAME, server.atom.UTF8_STRING, 0);
|
|
|
|
if (!name || !strlen(name)) {
|
|
|
|
name = server_get_property (tsk->win, server.atom._NET_WM_NAME, server.atom.UTF8_STRING, 0);
|
|
|
|
if (!name || !strlen(name)) {
|
|
|
|
name = server_get_property (tsk->win, server.atom.WM_NAME, XA_STRING, 0);
|
|
|
|
if (!name || !strlen(name)) {
|
|
|
|
name = malloc(10);
|
|
|
|
strcpy(name, "Untitled");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-10-02 18:47:02 +00:00
|
|
|
|
2009-07-26 13:46:50 +00:00
|
|
|
// add space before title
|
|
|
|
title = malloc(strlen(name)+2);
|
|
|
|
if (panel->g_task.icon) strcpy(title, " ");
|
|
|
|
else title[0] = 0;
|
|
|
|
strcat(title, name);
|
|
|
|
if (name) XFree (name);
|
2008-11-12 23:23:15 +00:00
|
|
|
|
2009-02-07 23:28:13 +00:00
|
|
|
tsk->area.redraw = 1;
|
2009-07-26 13:46:50 +00:00
|
|
|
if (tsk->title)
|
|
|
|
free(tsk->title);
|
|
|
|
tsk->title = title;
|
2008-10-02 18:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void get_icon (Task *tsk)
|
|
|
|
{
|
2009-07-26 13:46:50 +00:00
|
|
|
Panel *panel = tsk->area.panel;
|
|
|
|
if (!panel->g_task.icon) return;
|
2009-09-25 19:11:50 +00:00
|
|
|
int i;
|
|
|
|
Imlib_Image img = NULL;
|
|
|
|
XWMHints *hints = 0;
|
|
|
|
long *data = 0;
|
2009-02-07 23:28:13 +00:00
|
|
|
|
2009-09-19 20:56:15 +00:00
|
|
|
if (tsk->icon) {
|
|
|
|
imlib_context_set_image(tsk->icon);
|
|
|
|
imlib_free_image();
|
|
|
|
imlib_context_set_image(tsk->icon_active);
|
|
|
|
imlib_free_image();
|
|
|
|
tsk->icon = tsk->icon_active = NULL;
|
2009-02-07 23:28:13 +00:00
|
|
|
}
|
2009-07-26 13:46:50 +00:00
|
|
|
tsk->area.redraw = 1;
|
|
|
|
|
2009-09-25 19:11:50 +00:00
|
|
|
data = server_get_property (tsk->win, server.atom._NET_WM_ICON, XA_CARDINAL, &i);
|
2009-07-26 13:46:50 +00:00
|
|
|
if (data) {
|
|
|
|
// get ARGB icon
|
2009-09-19 13:17:44 +00:00
|
|
|
int w, h;
|
2009-07-26 13:46:50 +00:00
|
|
|
long *tmp_data;
|
|
|
|
|
2009-09-19 20:56:15 +00:00
|
|
|
tmp_data = get_best_icon (data, get_icon_count (data, i), i, &w, &h, panel->g_task.icon_size1);
|
2009-07-26 13:46:50 +00:00
|
|
|
|
|
|
|
#ifdef __x86_64__
|
2009-09-30 17:52:32 +00:00
|
|
|
DATA32 icon_data[w * h];
|
2009-09-19 20:56:15 +00:00
|
|
|
int length = w * h;
|
|
|
|
for (i = 0; i < length; ++i)
|
|
|
|
icon_data[i] = tmp_data[i];
|
2009-10-17 07:03:44 +00:00
|
|
|
img = imlib_create_image_using_copied_data (w, h, icon_data);
|
2009-07-26 13:46:50 +00:00
|
|
|
#else
|
2009-09-19 20:56:15 +00:00
|
|
|
img = imlib_create_image_using_data (w, h, (DATA32*)tmp_data);
|
2009-07-26 13:46:50 +00:00
|
|
|
#endif
|
2009-09-07 21:41:21 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// get Pixmap icon
|
2009-09-25 19:11:50 +00:00
|
|
|
hints = XGetWMHints(server.dsp, tsk->win);
|
2009-09-19 05:30:43 +00:00
|
|
|
if (hints) {
|
|
|
|
if (hints->flags & IconPixmapHint && hints->icon_pixmap != 0) {
|
|
|
|
// get width, height and depth for the pixmap
|
|
|
|
Window root;
|
|
|
|
int icon_x, icon_y;
|
|
|
|
uint border_width, bpp;
|
2009-09-19 13:17:44 +00:00
|
|
|
uint w, h;
|
2009-09-19 05:30:43 +00:00
|
|
|
|
2009-09-19 20:56:15 +00:00
|
|
|
//printf(" get pixmap\n");
|
2009-09-19 05:30:43 +00:00
|
|
|
XGetGeometry(server.dsp, hints->icon_pixmap, &root, &icon_x, &icon_y, &w, &h, &border_width, &bpp);
|
|
|
|
imlib_context_set_drawable(hints->icon_pixmap);
|
|
|
|
img = imlib_create_image_from_drawable(hints->icon_mask, 0, 0, w, h, 0);
|
2009-01-29 22:43:31 +00:00
|
|
|
}
|
2009-02-11 22:25:53 +00:00
|
|
|
}
|
2009-09-07 21:41:21 +00:00
|
|
|
}
|
2009-09-19 20:56:15 +00:00
|
|
|
if (img == NULL) {
|
|
|
|
imlib_context_set_image(default_icon);
|
|
|
|
img = imlib_clone_image();
|
|
|
|
}
|
2009-08-28 12:14:45 +00:00
|
|
|
|
2009-09-19 20:56:15 +00:00
|
|
|
// transform icons
|
|
|
|
imlib_context_set_image(img);
|
2009-09-20 08:02:39 +00:00
|
|
|
imlib_image_set_has_alpha(1);
|
2009-09-25 19:11:50 +00:00
|
|
|
int w, h;
|
|
|
|
w = imlib_image_get_width();
|
|
|
|
h = imlib_image_get_height();
|
|
|
|
tsk->icon = imlib_create_cropped_scaled_image(0, 0, w, h, panel->g_task.icon_size1, panel->g_task.icon_size1);
|
2009-09-19 20:56:15 +00:00
|
|
|
imlib_free_image();
|
|
|
|
|
|
|
|
imlib_context_set_image(tsk->icon);
|
|
|
|
tsk->icon_width = imlib_image_get_width();
|
|
|
|
tsk->icon_height = imlib_image_get_height();
|
|
|
|
tsk->icon_active = imlib_clone_image();
|
|
|
|
|
|
|
|
DATA32 *data32;
|
|
|
|
if (panel->g_task.alpha != 100 || panel->g_task.saturation != 0 || panel->g_task.brightness != 0) {
|
|
|
|
data32 = imlib_image_get_data();
|
|
|
|
adjust_asb(data32, tsk->icon_width, tsk->icon_height, panel->g_task.alpha, (float)panel->g_task.saturation/100, (float)panel->g_task.brightness/100);
|
|
|
|
imlib_image_put_back_data(data32);
|
|
|
|
}
|
2009-08-28 12:14:45 +00:00
|
|
|
|
2009-09-19 20:56:15 +00:00
|
|
|
if (panel->g_task.alpha_active != 100 || panel->g_task.saturation_active != 0 || panel->g_task.brightness_active != 0) {
|
|
|
|
imlib_context_set_image(tsk->icon_active);
|
|
|
|
data32 = imlib_image_get_data();
|
|
|
|
adjust_asb(data32, tsk->icon_width, tsk->icon_height, panel->g_task.alpha_active, (float)panel->g_task.saturation_active/100, (float)panel->g_task.brightness_active/100);
|
|
|
|
imlib_image_put_back_data(data32);
|
2009-08-29 12:00:11 +00:00
|
|
|
}
|
2009-09-25 19:11:50 +00:00
|
|
|
|
|
|
|
if (hints)
|
|
|
|
XFree(hints);
|
|
|
|
if (data)
|
|
|
|
XFree (data);
|
2008-10-02 18:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void draw_task_icon (Task *tsk, int text_width, int active)
|
|
|
|
{
|
2009-09-19 20:56:15 +00:00
|
|
|
if (tsk->icon == NULL || tsk->icon_active == NULL) return;
|
2009-07-26 13:46:50 +00:00
|
|
|
|
2009-08-28 12:14:45 +00:00
|
|
|
// Find pos
|
2009-07-26 13:46:50 +00:00
|
|
|
int pos_x;
|
|
|
|
Panel *panel = (Panel*)tsk->area.panel;
|
|
|
|
if (panel->g_task.centered) {
|
|
|
|
if (panel->g_task.text)
|
|
|
|
pos_x = (tsk->area.width - text_width - panel->g_task.icon_size1) / 2;
|
|
|
|
else
|
|
|
|
pos_x = (tsk->area.width - panel->g_task.icon_size1) / 2;
|
|
|
|
}
|
|
|
|
else pos_x = panel->g_task.area.paddingxlr + panel->g_task.area.pix.border.width;
|
|
|
|
|
2009-08-28 12:14:45 +00:00
|
|
|
// Render
|
2009-09-19 20:56:15 +00:00
|
|
|
Pixmap *pmap;
|
|
|
|
if (active == 0) {
|
|
|
|
imlib_context_set_image (tsk->icon);
|
|
|
|
pmap = &tsk->area.pix.pmap;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
imlib_context_set_image (tsk->icon_active);
|
|
|
|
pmap = &tsk->area.pix_active.pmap;
|
|
|
|
}
|
2009-07-26 13:46:50 +00:00
|
|
|
imlib_context_set_drawable (*pmap);
|
2009-09-19 20:56:15 +00:00
|
|
|
imlib_render_image_on_drawable (pos_x, panel->g_task.icon_posy);
|
2008-10-02 18:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-02-28 23:04:53 +00:00
|
|
|
void draw_task (void *obj, cairo_t *c, int active)
|
2008-10-02 18:47:02 +00:00
|
|
|
{
|
2009-07-26 13:46:50 +00:00
|
|
|
Task *tsk = obj;
|
|
|
|
PangoLayout *layout;
|
|
|
|
config_color *config_text;
|
|
|
|
int width=0, height;
|
|
|
|
Panel *panel = (Panel*)tsk->area.panel;
|
2009-01-17 14:07:56 +00:00
|
|
|
|
2009-07-26 13:46:50 +00:00
|
|
|
if (panel->g_task.text) {
|
2009-01-17 14:07:56 +00:00
|
|
|
/* Layout */
|
|
|
|
layout = pango_cairo_create_layout (c);
|
2009-02-07 23:28:13 +00:00
|
|
|
pango_layout_set_font_description (layout, panel->g_task.font_desc);
|
2009-01-17 14:07:56 +00:00
|
|
|
pango_layout_set_text (layout, tsk->title, -1);
|
2008-10-02 18:47:02 +00:00
|
|
|
|
2009-01-17 14:07:56 +00:00
|
|
|
/* Drawing width and Cut text */
|
2009-02-25 20:04:43 +00:00
|
|
|
// pango use U+22EF or U+2026
|
2009-01-17 14:07:56 +00:00
|
|
|
pango_layout_set_width (layout, ((Taskbar*)tsk->area.parent)->text_width * PANGO_SCALE);
|
|
|
|
pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
|
2008-10-02 18:47:02 +00:00
|
|
|
|
2009-01-17 14:07:56 +00:00
|
|
|
/* Center text */
|
2009-02-07 23:28:13 +00:00
|
|
|
if (panel->g_task.centered) pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
|
2009-01-17 14:07:56 +00:00
|
|
|
else pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
|
2008-10-02 18:47:02 +00:00
|
|
|
|
2009-01-17 14:07:56 +00:00
|
|
|
pango_layout_get_pixel_size (layout, &width, &height);
|
2008-10-02 18:47:02 +00:00
|
|
|
|
2009-02-07 23:28:13 +00:00
|
|
|
if (active) config_text = &panel->g_task.font_active;
|
|
|
|
else config_text = &panel->g_task.font;
|
2008-10-02 18:47:02 +00:00
|
|
|
|
2009-01-17 14:07:56 +00:00
|
|
|
cairo_set_source_rgba (c, config_text->color[0], config_text->color[1], config_text->color[2], config_text->alpha);
|
2008-10-02 18:47:02 +00:00
|
|
|
|
2009-01-17 14:07:56 +00:00
|
|
|
pango_cairo_update_layout (c, layout);
|
2009-02-07 23:28:13 +00:00
|
|
|
cairo_move_to (c, panel->g_task.text_posx, panel->g_task.text_posy);
|
2009-01-17 14:07:56 +00:00
|
|
|
pango_cairo_show_layout (c, layout);
|
2008-10-02 18:47:02 +00:00
|
|
|
|
2009-02-07 23:28:13 +00:00
|
|
|
if (panel->g_task.font_shadow) {
|
2009-01-17 14:07:56 +00:00
|
|
|
cairo_set_source_rgba (c, 0.0, 0.0, 0.0, 0.5);
|
|
|
|
pango_cairo_update_layout (c, layout);
|
2009-02-07 23:28:13 +00:00
|
|
|
cairo_move_to (c, panel->g_task.text_posx + 1, panel->g_task.text_posy + 1);
|
2009-01-17 14:07:56 +00:00
|
|
|
pango_cairo_show_layout (c, layout);
|
|
|
|
}
|
|
|
|
g_object_unref (layout);
|
2009-07-26 13:46:50 +00:00
|
|
|
}
|
2008-10-02 18:47:02 +00:00
|
|
|
|
2009-07-26 13:46:50 +00:00
|
|
|
if (panel->g_task.icon) {
|
|
|
|
// icon use same opacity as text
|
|
|
|
draw_task_icon (tsk, width, active);
|
|
|
|
}
|
2008-10-02 18:47:02 +00:00
|
|
|
}
|
|
|
|
|
2009-08-28 12:14:45 +00:00
|
|
|
|
2009-11-18 05:13:38 +00:00
|
|
|
Task *next_task(Task *tsk)
|
|
|
|
{
|
|
|
|
GSList *l0;
|
|
|
|
int i, j;
|
|
|
|
Task *tsk1;
|
|
|
|
|
|
|
|
for (i=0 ; i < nb_panel ; i++) {
|
|
|
|
for (j=0 ; j < panel1[i].nb_desktop ; j++) {
|
|
|
|
for (l0 = panel1[i].taskbar[j].area.list; l0 ; l0 = l0->next) {
|
|
|
|
tsk1 = l0->data;
|
|
|
|
if (tsk1 == tsk) {
|
|
|
|
if (l0->next == NULL) l0 = panel1[i].taskbar[j].area.list;
|
|
|
|
else l0 = l0->next;
|
|
|
|
return l0->data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Task *prev_task(Task *tsk)
|
|
|
|
{
|
|
|
|
GSList *l0;
|
|
|
|
int i, j;
|
|
|
|
Task *tsk1, *tsk2;
|
|
|
|
|
|
|
|
for (i=0 ; i < nb_panel ; i++) {
|
|
|
|
for (j=0 ; j < panel1[i].nb_desktop ; j++) {
|
|
|
|
tsk2 = NULL;
|
|
|
|
for (l0 = panel1[i].taskbar[j].area.list; l0 ; l0 = l0->next) {
|
|
|
|
tsk1 = l0->data;
|
|
|
|
if (tsk1 == tsk) {
|
|
|
|
if (l0 == panel1[i].taskbar[j].area.list) {
|
|
|
|
l0 = g_slist_last ( l0 );
|
|
|
|
tsk2 = l0->data;
|
|
|
|
}
|
|
|
|
return tsk2;
|
|
|
|
}
|
|
|
|
tsk2 = tsk1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-10-23 21:28:44 +00:00
|
|
|
void active_task()
|
|
|
|
{
|
|
|
|
GSList *l0;
|
|
|
|
int i, j;
|
|
|
|
Task *tsk1, *tsk2;
|
|
|
|
|
|
|
|
if (task_active) {
|
|
|
|
for (i=0 ; i < nb_panel ; i++) {
|
|
|
|
for (j=0 ; j < panel1[i].nb_desktop ; j++) {
|
|
|
|
for (l0 = panel1[i].taskbar[j].area.list; l0 ; l0 = l0->next) {
|
|
|
|
tsk1 = l0->data;
|
|
|
|
tsk1->area.is_active = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
task_active = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
Window w1 = window_get_active ();
|
2009-10-23 22:20:42 +00:00
|
|
|
//printf("Change active task %ld\n", w1);
|
|
|
|
|
2009-10-23 21:28:44 +00:00
|
|
|
tsk2 = task_get_task(w1);
|
|
|
|
if (!tsk2) {
|
|
|
|
Window w2;
|
|
|
|
if (XGetTransientForHint(server.dsp, w1, &w2) != 0)
|
|
|
|
if (w2) tsk2 = task_get_task(w2);
|
|
|
|
}
|
2009-11-11 20:09:34 +00:00
|
|
|
if ( is_urgent(tsk2) ) {
|
|
|
|
del_urgent(tsk2);
|
2009-10-23 21:28:44 +00:00
|
|
|
}
|
|
|
|
// put active state on all task (multi_desktop)
|
|
|
|
if (tsk2) {
|
|
|
|
for (i=0 ; i < nb_panel ; i++) {
|
|
|
|
for (j=0 ; j < panel1[i].nb_desktop ; j++) {
|
|
|
|
for (l0 = panel1[i].taskbar[j].area.list; l0 ; l0 = l0->next) {
|
|
|
|
tsk1 = l0->data;
|
|
|
|
if (tsk1->win == tsk2->win) {
|
|
|
|
tsk1->area.is_active = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
task_active = tsk2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-11 20:09:34 +00:00
|
|
|
|
2009-11-15 16:55:50 +00:00
|
|
|
void blink_urgent()
|
|
|
|
{
|
|
|
|
GSList* urgent_task = urgent_list;
|
|
|
|
while (urgent_task) {
|
|
|
|
Task_urgent* t = urgent_task->data;
|
|
|
|
if ( t->tick < max_tick_urgent) {
|
|
|
|
t->tsk->area.is_active = !t->tsk->area.is_active;
|
|
|
|
t->tsk->area.redraw = 1;
|
|
|
|
t->tick++;
|
|
|
|
}
|
|
|
|
urgent_task = urgent_task->next;
|
|
|
|
}
|
2009-11-16 10:06:45 +00:00
|
|
|
panel_refresh = 1;
|
2009-11-15 16:55:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-11 20:09:34 +00:00
|
|
|
void add_urgent(Task *tsk)
|
|
|
|
{
|
|
|
|
// first check if task is already in the list and reset the counter
|
|
|
|
GSList* urgent_task = urgent_list;
|
|
|
|
while (urgent_task) {
|
|
|
|
Task_urgent* t = urgent_task->data;
|
|
|
|
if (t->tsk == tsk) {
|
|
|
|
t->tick = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
urgent_task = urgent_task->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
// not yet in the list, so we have to add it
|
|
|
|
Task_urgent* t = malloc(sizeof(Task_urgent));
|
|
|
|
if (!t)
|
|
|
|
return;
|
|
|
|
t->tsk = tsk;
|
|
|
|
t->tick = 0;
|
|
|
|
urgent_list = g_slist_prepend(urgent_list, t);
|
2009-11-15 16:55:50 +00:00
|
|
|
|
|
|
|
if (urgent_timer == 0)
|
|
|
|
urgent_timer = install_timer(0, 1000000, 1, 0, blink_urgent);
|
|
|
|
else
|
|
|
|
reset_timer(urgent_timer, 0, 1000000, 1, 0);
|
2009-11-11 20:09:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void del_urgent(Task *tsk)
|
|
|
|
{
|
|
|
|
GSList* urgent_task = urgent_list;
|
|
|
|
while (urgent_task) {
|
|
|
|
Task_urgent* t = urgent_task->data;
|
|
|
|
if (t->tsk == tsk) {
|
|
|
|
urgent_list = g_slist_remove(urgent_list, t);
|
|
|
|
free(t);
|
|
|
|
if (!urgent_list)
|
2009-11-15 16:55:50 +00:00
|
|
|
reset_timer(urgent_timer, 0, 0, 0, 0);
|
2009-11-11 20:09:34 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
urgent_task = urgent_task->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int is_urgent(Task *tsk)
|
|
|
|
{
|
|
|
|
GSList* urgent_task = urgent_list;
|
|
|
|
while (urgent_task) {
|
|
|
|
Task_urgent* t = urgent_task->data;
|
|
|
|
if (t->tsk == tsk)
|
|
|
|
return 1;
|
|
|
|
urgent_task = urgent_task->next;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|