Beispiel #1
0
int get_title(Task *tsk)
{
	Panel *panel = tsk->area.panel;
	char *title, *name;

	if (!panel->g_task.text &&
		!panel->g_task.tooltip_enabled &&
		taskbar_sort_method != TASKBAR_SORT_TITLE)
		return 0;

	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 = calloc(10, 1);
				strcpy(name, "Untitled");
			}
		}
	}

	// add space before title
	title = calloc(strlen(name)+2, 1);
	if (panel->g_task.icon) strcpy(title, " ");
	else title[0] = 0;
	strcat(title, name);
	if (name) XFree (name);

	if (tsk->title) {
		// check unecessary title change
		if (strcmp(tsk->title, title) == 0) {
			free(title);
			return 0;
		}
		else
			free(tsk->title);
	}

	tsk->title = title;
	GPtrArray* task_group = task_get_tasks(tsk->win);
	if (task_group) {
		for (size_t i = 0; i<task_group->len; ++i) {
			Task* tsk2 = g_ptr_array_index(task_group, i);
			tsk2->title = tsk->title;
			set_task_redraw(tsk2);
		}
	}
	return 1;
}
Beispiel #2
0
void task_refresh_tasklist ()
{
	Window *win;
	int num_results, i;

	if (!taskbar_enabled) return;
	win = server_get_property (server.root_win, server.atom._NET_CLIENT_LIST, XA_WINDOW, &num_results);
	if (!win) return;

	GList* win_list = g_hash_table_get_keys(win_to_task_table);
	GList* it;
	for (it=win_list; it; it=it->next) {
		for (i = 0; i < num_results; i++)
			if (*((Window*)it->data) == win[i])
				break;
		if (i == num_results)
			taskbar_remove_task(it->data, 0, 0);
	}
	g_list_free(win_list);

	// Add any new
	for (i = 0; i < num_results; i++)
		if (!task_get_task (win[i]))
			add_task (win[i]);

	XFree (win);
}
Beispiel #3
0
GSList *get_desktop_names()
{
	if (server.viewports) {
		GSList *list = NULL;
		for (int j = 0; j < server.num_desktops; j++) {
			list = g_slist_append(list, g_strdup_printf("%d", j + 1));
		}
		return list;
	}

	int count;
	GSList *list = NULL;
	gchar *data_ptr =
		server_get_property(server.root_win, server.atom._NET_DESKTOP_NAMES, server.atom.UTF8_STRING, &count);
	if (data_ptr) {
		list = g_slist_append(list, g_strdup(data_ptr));
		for (int j = 0; j < count - 1; j++) {
			if (*(data_ptr + j) == '\0') {
				gchar *ptr = (gchar *)data_ptr + j + 1;
				list = g_slist_append(list, g_strdup(ptr));
			}
		}
		XFree(data_ptr);
	}
	return list;
}
Beispiel #4
0
void get_root_pixmap()
{
	Pixmap ret = None;

	Atom pixmap_atoms[] = {server.atom._XROOTPMAP_ID, server.atom._XROOTMAP_ID};
	for (int i = 0; i < sizeof(pixmap_atoms) / sizeof(Atom); ++i) {
		unsigned long *res = (unsigned long *)server_get_property(server.root_win, pixmap_atoms[i], XA_PIXMAP, NULL);
		if (res) {
			ret = *((Pixmap *)res);
			XFree(res);
			break;
		}
	}
	server.root_pmap = ret;

	if (server.root_pmap == None) {
		fprintf(stderr, "tint2 : pixmap background detection failed\n");
	} else {
		XGCValues gcv;
		gcv.ts_x_origin = 0;
		gcv.ts_y_origin = 0;
		gcv.fill_style = FillTiled;
		uint mask = GCTileStipXOrigin | GCTileStipYOrigin | GCFillStyle | GCTile;

		gcv.tile = server.root_pmap;
		XChangeGC(server.display, server.gc, mask, &gcv);
	}
}
Beispiel #5
0
void server_get_number_of_desktops()
{
	if (server.viewports) {
		free(server.viewports);
		server.viewports = NULL;
	}

	server.num_desktops = get_property32(server.root_win, server.atom._NET_NUMBER_OF_DESKTOPS, XA_CARDINAL);
	if (server.num_desktops > 1)
		return;

	int num_results;
	long *work_area_size = server_get_property(server.root_win, server.atom._NET_WORKAREA, XA_CARDINAL, &num_results);
	if (!work_area_size)
		return;
	int work_area_width = work_area_size[0] + work_area_size[2];
	int work_area_height = work_area_size[1] + work_area_size[3];
	XFree(work_area_size);

	long *x_screen_size =
		server_get_property(server.root_win, server.atom._NET_DESKTOP_GEOMETRY, XA_CARDINAL, &num_results);
	if (!x_screen_size)
		return;
	int x_screen_width = x_screen_size[0];
	int x_screen_height = x_screen_size[1];
	XFree(x_screen_size);

	int num_viewports = MAX(x_screen_width / work_area_width, 1) * MAX(x_screen_height / work_area_height, 1);
	if (num_viewports <= 1) {
		server.num_desktops = 1;
		return;
	}

	server.viewports = calloc(num_viewports, sizeof(Viewport));
	int k = 0;
	for (int i = 0; i < MAX(x_screen_height / work_area_height, 1); i++) {
		for (int j = 0; j < MAX(x_screen_width / work_area_width, 1); j++) {
			server.viewports[k].x = j * work_area_width;
			server.viewports[k].y = i * work_area_height;
			server.viewports[k].width = work_area_width;
			server.viewports[k].height = work_area_height;
			k++;
		}
	}

	server.num_desktops = num_viewports;
}
Beispiel #6
0
gboolean window_is_hidden(Window win)
{
	Window window;
	int count;

	Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
	for (int i = 0; i < count; i++) {
		if (at[i] == server.atom._NET_WM_STATE_SKIP_TASKBAR) {
			XFree(at);
			return TRUE;
		}
		// do not add transient_for windows if the transient window is already in the taskbar
		window = win;
		while (XGetTransientForHint(server.display, window, &window)) {
			if (get_task_buttons(window)) {
				XFree(at);
				return TRUE;
			}
		}
	}
	XFree(at);

	at = server_get_property(win, server.atom._NET_WM_WINDOW_TYPE, XA_ATOM, &count);
	for (int i = 0; i < count; i++) {
		if (at[i] == server.atom._NET_WM_WINDOW_TYPE_DOCK || at[i] == server.atom._NET_WM_WINDOW_TYPE_DESKTOP ||
			at[i] == server.atom._NET_WM_WINDOW_TYPE_TOOLBAR || at[i] == server.atom._NET_WM_WINDOW_TYPE_MENU ||
			at[i] == server.atom._NET_WM_WINDOW_TYPE_SPLASH) {
			XFree(at);
			return TRUE;
		}
	}
	XFree(at);

	for (int i = 0; i < num_panels; i++) {
		if (panels[i].main_win == win) {
			return TRUE;
		}
	}

	// specification
	// Windows with neither _NET_WM_WINDOW_TYPE nor WM_TRANSIENT_FOR set
	// MUST be taken as top-level window.
	return FALSE;
}
Beispiel #7
0
int get_current_desktop()
{
	if (!server.viewports) {
		return MAX(0,
				   MIN(server.num_desktops - 1,
					   get_property32(server.root_win, server.atom._NET_CURRENT_DESKTOP, XA_CARDINAL)));
	}

	int num_results;
	long *work_area_size = server_get_property(server.root_win, server.atom._NET_WORKAREA, XA_CARDINAL, &num_results);
	if (!work_area_size)
		return 0;
	int work_area_width = work_area_size[0] + work_area_size[2];
	int work_area_height = work_area_size[1] + work_area_size[3];
	XFree(work_area_size);

	if (work_area_width <= 0 || work_area_height <= 0)
		return 0;

	long *viewport = server_get_property(server.root_win, server.atom._NET_DESKTOP_VIEWPORT, XA_CARDINAL, &num_results);
	if (!viewport)
		return 0;
	int viewport_x = viewport[0];
	int viewport_y = viewport[1];
	XFree(viewport);

	long *x_screen_size =
		server_get_property(server.root_win, server.atom._NET_DESKTOP_GEOMETRY, XA_CARDINAL, &num_results);
	if (!x_screen_size)
		return 0;
	int x_screen_width = x_screen_size[0];
	XFree(x_screen_size);

	int ncols = x_screen_width / work_area_width;

	//	fprintf(stderr, "\n");
	//	fprintf(stderr, "Work area size: %d x %d\n", work_area_width, work_area_height);
	//	fprintf(stderr, "Viewport pos: %d x %d\n", viewport_x, viewport_y);
	//	fprintf(stderr, "Viewport i: %d\n", (viewport_y / work_area_height) * ncols + viewport_x / work_area_width);

	int result = (viewport_y / work_area_height) * ncols + viewport_x / work_area_width;
	return MAX(0, MIN(server.num_desktops - 1, result));
}
Beispiel #8
0
int get_window_desktop(Window win)
{
	int desktop = get_property32(win, server.atom._NET_WM_DESKTOP, XA_CARDINAL);
	if (desktop == ALL_DESKTOPS)
		return desktop;
	if (!server.viewports)
		return CLAMP(desktop, 0, server.num_desktops - 1);

	int x, y, w, h;
	get_window_coordinates(win, &x, &y, &w, &h);

	desktop = get_current_desktop();
	// Window coordinates are relative to the current viewport, make them absolute
	x += server.viewports[desktop].x;
	y += server.viewports[desktop].y;

	if (x < 0 || y < 0) {
		int num_results;
		long *x_screen_size =
			server_get_property(server.root_win, server.atom._NET_DESKTOP_GEOMETRY, XA_CARDINAL, &num_results);
		if (!x_screen_size)
			return 0;
		int x_screen_width = x_screen_size[0];
		int x_screen_height = x_screen_size[1];
		XFree(x_screen_size);

		// Wrap
		if (x < 0)
			x += x_screen_width;
		if (y < 0)
			y += x_screen_height;
	}

	int best_match = -1;
	int match_right = 0;
	int match_bottom = 0;
	// There is an ambiguity when a window is right on the edge between viewports.
	// In that case, prefer the viewports which is on the right and bottom of the window's top-left corner.
	for (int i = 0; i < server.num_desktops; i++) {
		if (x >= server.viewports[i].x && x <= (server.viewports[i].x + server.viewports[i].width) &&
			y >= server.viewports[i].y && y <= (server.viewports[i].y + server.viewports[i].height)) {
			int current_right = x < (server.viewports[i].x + server.viewports[i].width);
			int current_bottom = y < (server.viewports[i].y + server.viewports[i].height);
			if (best_match < 0 || (!match_right && current_right) || (!match_bottom && current_bottom)) {
				best_match = i;
			}
		}
	}

	if (best_match < 0)
		best_match = 0;
	// fprintf(stderr, "window %lx %s : viewport %d, (%d, %d)\n", win, get_task(win) ? get_task(win)->title : "??",
	// best_match+1, x, y);
	return best_match;
}
Beispiel #9
0
int window_is_hidden (Window win)
{
	Window window;
	Atom *at;
	int count, i;

	at = server_get_property (win, server.atom._NET_WM_STATE, XA_ATOM, &count);
	for (i = 0; i < count; i++) {
		if (at[i] == server.atom._NET_WM_STATE_SKIP_TASKBAR) {
			XFree(at);
			return 1;
		}
		// do not add transient_for windows if the transient window is already in the taskbar
		if ( XGetTransientForHint(server.dsp, win, &window) && task_get_tasks(window) ) {
			XFree(at);
			return 1;
		}
	}
	XFree(at);

	at = server_get_property (win, server.atom._NET_WM_WINDOW_TYPE, XA_ATOM, &count);
	for (i = 0; i < count; i++) {
		if (at[i] == server.atom._NET_WM_WINDOW_TYPE_DOCK || at[i] == server.atom._NET_WM_WINDOW_TYPE_DESKTOP || at[i] == server.atom._NET_WM_WINDOW_TYPE_TOOLBAR || at[i] == server.atom._NET_WM_WINDOW_TYPE_MENU || at[i] == server.atom._NET_WM_WINDOW_TYPE_SPLASH) {
			XFree(at);
			return 1;
		}
	}
	XFree(at);

	for (i=0 ; i < nb_panel ; i++) {
		if (panel1[i].main_win == win) {
			return 1;
		}
	}

	// specification
	// Windows with neither _NET_WM_WINDOW_TYPE nor WM_TRANSIENT_FOR set
	// MUST be taken as top-level window.
	return 0;
}
Beispiel #10
0
gboolean window_is_skip_taskbar(Window win)
{
	int count;

	Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
	for (int i = 0; i < count; i++) {
		if (at[i] == server.atom._NET_WM_STATE_SKIP_TASKBAR) {
			XFree(at);
			return 1;
		}
	}
	XFree(at);
	return FALSE;
}
Beispiel #11
0
gboolean window_is_urgent(Window win)
{
	int count;

	Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
	for (int i = 0; i < count; i++) {
		if (at[i] == server.atom._NET_WM_STATE_DEMANDS_ATTENTION) {
			XFree(at);
			return TRUE;
		}
	}
	XFree(at);
	return FALSE;
}
Beispiel #12
0
gboolean window_is_iconified(Window win)
{
	// EWMH specification : minimization of windows use _NET_WM_STATE_HIDDEN.
	// WM_STATE is not accurate for shaded window and in multi_desktop mode.
	int count;
	Atom *at = server_get_property(win, server.atom._NET_WM_STATE, XA_ATOM, &count);
	for (int i = 0; i < count; i++) {
		if (at[i] == server.atom._NET_WM_STATE_HIDDEN) {
			XFree(at);
			return TRUE;
		}
	}
	XFree(at);
	return FALSE;
}
Beispiel #13
0
int window_is_urgent (Window win)
{
	Atom *at;
	int count, i;

	at = server_get_property (win, server.atom._NET_WM_STATE, XA_ATOM, &count);
	for (i = 0; i < count; i++) {
		if (at[i] == server.atom._NET_WM_STATE_DEMANDS_ATTENTION) {
			XFree(at);
			return 1;
		}
	}
	XFree(at);
	return 0;
}
Beispiel #14
0
GSList *server_get_name_of_desktop ()
{
	int count, j;
	GSList *list = NULL;
	gchar *data_ptr, *ptr;
	data_ptr = server_get_property (server.root_win, server.atom._NET_DESKTOP_NAMES, server.atom.UTF8_STRING, &count);
	if (data_ptr) {
		list = g_slist_append(list, g_strdup(data_ptr));
		for (j = 0; j < count-1; j++) {
			if (*(data_ptr + j)	== '\0') {
				ptr = (gchar*)data_ptr + j + 1;
				list = g_slist_append(list, g_strdup(ptr));
			}
		}
		XFree(data_ptr);
	}
	return list;
}
Beispiel #15
0
void get_icon (Task *tsk)
{
	Panel *panel = tsk->area.panel;
	if (!panel->g_task.icon) return;
	size_t i;
	Imlib_Image img = NULL;
	XWMHints *hints = 0;
	gulong *data = 0;

	int k;
	for (k=0; k<TASK_STATE_COUNT; ++k) {
		if (tsk->icon[k]) {
			imlib_context_set_image(tsk->icon[k]);
			imlib_free_image();
			tsk->icon[k] = 0;
		}
	}

	data = server_get_property (tsk->win, server.atom._NET_WM_ICON, XA_CARDINAL, (int*)&i);
	if (data) {
		// get ARGB icon
		int w, h;
		gulong *tmp_data;

		tmp_data = get_best_icon (data, get_icon_count (data, i), i, &w, &h, panel->g_task.icon_size1);
#ifdef __x86_64__
		DATA32 icon_data[w * h];
		size_t length = w * h;
		for (i = 0; i < length; ++i)
			icon_data[i] =  tmp_data[i];
		img = imlib_create_image_using_copied_data (w, h, icon_data);
#else
		img = imlib_create_image_using_data (w, h, (DATA32*)tmp_data);
#endif
	}
	else {
		// get Pixmap icon
		hints = XGetWMHints(server.dsp, tsk->win);
		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;
				uint32_t border_width, bpp;
				uint32_t w, h;

				//printf("  get pixmap\n");
				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);
			}
		}
	}
	if (img == NULL) {
		imlib_context_set_image(default_icon);
		img = imlib_clone_image();
	}

	// transform icons
	imlib_context_set_image(img);
	imlib_image_set_has_alpha(1);
	int w, h;
	w = imlib_image_get_width();
	h = imlib_image_get_height();
	Imlib_Image orig_image = imlib_create_cropped_scaled_image(0, 0, w, h, panel->g_task.icon_size1, panel->g_task.icon_size1);
	imlib_free_image();

	imlib_context_set_image(orig_image);
	tsk->icon_width = imlib_image_get_width();
	tsk->icon_height = imlib_image_get_height();
	for (k=0; k<TASK_STATE_COUNT; ++k) {
		imlib_context_set_image(orig_image);
		tsk->icon[k] = imlib_clone_image();
		imlib_context_set_image(tsk->icon[k]);
		DATA32 *data32;
		if (panel->g_task.alpha[k] != 100 || panel->g_task.saturation[k] != 0 || panel->g_task.brightness[k] != 0) {
			data32 = imlib_image_get_data();
			adjust_asb(data32, tsk->icon_width, tsk->icon_height, panel->g_task.alpha[k], (float)panel->g_task.saturation[k]/100, (float)panel->g_task.brightness[k]/100);
			imlib_image_put_back_data(data32);
		}
	}
	imlib_context_set_image(orig_image);
	imlib_free_image();

	if (hints)
		XFree(hints);
	if (data)
		XFree (data);

	GPtrArray* task_group = task_get_tasks(tsk->win);
	if (task_group) {
		for (i=0; i<task_group->len; ++i) {
			Task* tsk2 = g_ptr_array_index(task_group, i);
			tsk2->icon_width = tsk->icon_width;
			tsk2->icon_height = tsk->icon_height;
			int k;
			for (k=0; k<TASK_STATE_COUNT; ++k)
				tsk2->icon[k] = tsk->icon[k];
			set_task_redraw(tsk2);
		}
	}
}