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; }
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); }
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; }
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); } }
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; }
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; }
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)); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); } } }