/* Copyright (c) 2000 Linus Nilsson */ #include "yawm.h" #include #include #include #include #include #include #include #define EDGE_SPACE (opt_bw + 1) #define FONT_YOFF (TASKBAR_HEIGHT/2 - opt_bw/2 + (font->ascent+font->descent)/2) void draw_bartime(char *thestring) { if (!thestring) { debug("The argument to draw_bartime was NULL!\n"); exit(1); } /* Add double buffering later */ XClearArea(child_dpy, taskbar, DisplayWidth(child_dpy, 0) - XTextWidth(font, thestring, strlen(thestring)) - EDGE_SPACE, TASKBAR_HEIGHT/2 - (font->ascent + font->descent)/2, XTextWidth(font, thestring, strlen(thestring)), (font->ascent + font->descent), False); XDrawString(child_dpy, taskbar, taskbar_focus_fg_gc, DisplayWidth(child_dpy, 0) - opt_bw - 4 - XTextWidth(font, thestring, strlen(thestring)) - EDGE_SPACE, FONT_YOFF, thestring, strlen(thestring)); XSync(child_dpy, False); } int count_tasks(void) { Client *c = (Client *) malloc (sizeof(Client)); int n = 0; for (c = head_client; c; c = c->next) { n++; } return n; } void draw_tasks(void) { char *tasks_string = (char *) malloc(1024); Client *c = (Client *) malloc (sizeof(Client)); int offset = opt_bw + 1; debug("entered draw_tasks()\n"); for (c = head_client; c != NULL; c = c->next) { debug("loop1"); if (!c->window) { remove_client(c, 0); } else { XFetchName(dpy, c->window, &c->barname); redraw(c); } } while (find_width() > DisplayWidth(dpy, 0) - 200 && count_tasks() <= MAX_CLIENTS_ON_TASKBAR && (c ? strcmp(c->barname, "...") != 0 : 1)) { debug("loop2"); c = find_client_with_longest_name(); dec_barname(find_client_with_longest_name()); } XClearArea(dpy, taskbar, opt_bw, opt_bw, DisplayWidth(dpy, 0) - 200, TASKBAR_HEIGHT - 2*opt_bw, False); if (count_tasks() <= MAX_CLIENTS_ON_TASKBAR) { for (c = head_client; c; c = c->next) { debug("loop3"); if (c->barname) sprintf(tasks_string, "%s", c->barname); if (!tasks_string) { debug("tasks_string is NULL in draw_tasks!\n"); exit(1); } if (offset + XTextWidth(font, tasks_string, strlen(tasks_string)) + 2*SPACE < DisplayWidth(dpy, 0) - 200) { if (c->minimized) { XDrawString(dpy, taskbar, hidden_string_gc, offset + SPACE, FONT_YOFF, tasks_string, strlen(tasks_string)); } else if (tasks_string && c == focused_client) { XDrawString(dpy, taskbar, taskbar_focus_fg_gc, offset + SPACE, FONT_YOFF, tasks_string, strlen(tasks_string)); } else { XDrawString(dpy, taskbar, normal_string_gc, offset + SPACE, FONT_YOFF, tasks_string, strlen(tasks_string)); } XDrawRectangle(dpy, taskbar, border_gc, offset, SPACE, XTextWidth(font, tasks_string, strlen(tasks_string)) + 2*SPACE, font->ascent + font->descent + 2*SPACE); c->left_offset = offset; offset += XTextWidth(font, tasks_string, strlen(tasks_string)) + 3*SPACE + 1; c->right_offset = offset; } else { break; } } } else { XDrawString(dpy, taskbar, focus_string_gc, offset + SPACE, FONT_YOFF, "Too many tasks to show on taskbar", strlen("Too many tasks to show on taskbar")); } XSync(dpy, False); } int find_width(void) { char *tasks_string = (char *) malloc(1024); int offset = opt_bw + 1; Client *c = (Client *) malloc (sizeof(Client)); for (c = head_client; c != NULL; c = c->next) { debug("find width loop\n"); if (c->barname) { sprintf(tasks_string, "%s", c->barname); } offset += XTextWidth(font, tasks_string, strlen(tasks_string)) + 3*SPACE ; } return offset; } Client * find_client_with_longest_name() { int longest_so_far = 0; Client *c = (Client *) malloc (sizeof(Client)); Client *long_c = (Client *) malloc (sizeof(Client)); for (c = head_client; c; c = c->next) { if (strlen(c->barname) > longest_so_far) { long_c = c; longest_so_far = strlen(c->barname); } } return long_c; } void dec_barname(Client *c) { if (!c) { debug("c was NULL in dec_barname()\n"); exit(1); } if (strlen(c->barname) >= 4) { c->barname[strlen(c->barname)-1] = '\0'; c->barname[strlen(c->barname)-1] = '.'; c->barname[strlen(c->barname)-2] = '.'; c->barname[strlen(c->barname)-3] = '.'; } } /* Do initial setup of the taskbar */ void start_taskbar(void) { GC taskbar_gc; XSetWindowAttributes p_attr; p_attr.override_redirect = True; p_attr.background_pixel = taskbar_bg.pixel; p_attr.border_pixel = bd.pixel; p_attr.backing_store = Always; p_attr.event_mask = ChildMask | ButtonPressMask | ExposureMask | CWBackingPixel | CWBackPixel | EnterWindowMask | KeyPressMask; taskbar = XCreateWindow(dpy, root, 0, DisplayHeight(dpy, 0) - TASKBAR_HEIGHT - 2*opt_bw, DisplayWidth(dpy, 0) - 4, //width TASKBAR_HEIGHT, opt_bw, DefaultDepth(dpy, screen), InputOutput, CopyFromParent, CWOverrideRedirect |CWBorderPixel|CWEventMask| CWBackPixel|CWBackingStore, &p_attr); XSelectInput(dpy, taskbar, ChildMask | ColormapChangeMask | EnterWindowMask | LeaveWindowMask | PropertyChangeMask | KeyPressMask| ButtonPressMask); XMapWindow(dpy, taskbar); taskbar_gc = XCreateGC(dpy, taskbar, 0, NULL); XSync(dpy, False); } /* This function name is fucked up. Need to change it */ void taskbar_start(void) { pid_t child_pid; time_t mytime_t; struct tm *mytm; char *time_string = malloc(1024); char *full_string = malloc(1024); child_pid = fork(); if (child_pid == -1) { debug("Unable to fork()!\n"); exit(1); } else if (child_pid == 0) { /* We need a seperate Display to avoid race conditions */ child_dpy = XOpenDisplay(opt_display); while (1) { mytime_t = time(NULL); mytm = localtime(&mytime_t); strftime(time_string, 1024, STRFTIME_STRING, mytm); sprintf(full_string, "%s", //current_desk, time_string); draw_bartime(full_string); sleep(60); } } }