fspanel-0.7/COPYING0100644000076400007640000000202307057722524012211 0ustar zedzedCopyright (C) 2000 Peter Zelezny Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Soft- ware"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following condi- tions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. fspanel-0.7/Makefile0100644000076400007640000000066407256634005012624 0ustar zedzedCC = gcc C_FLAGS = -DNOSTDLIB -DHAVE_XPM -Wall -I/usr/X11R6/include -m386 -malign-loops=2 -malign-jumps=2 -malign-functions=2 L_FLAGS = -nostdlib -O1 -Xlinker -s -L/usr/X11R6/lib -lX11 -lXpm PROGNAME = fspanel $(PROGNAME): Makefile fspanel.c fspanel.h icon.xpm $(CC) $(C_FLAGS) $(L_FLAGS) fspanel.c -o $(PROGNAME) @ls -l $(PROGNAME) clean: rm -f core *.o $(PROGNAME) nohup.out install: $(PROGNAME) cp $(PROGNAME) /usr/local/bin fspanel-0.7/Makefile.freebsd0100644000076400007640000000063707256634042014236 0ustar zedzedCC = gcc C_FLAGS = -DHAVE_XPM -Wall -O1 -I/usr/X11R6/include -m386 -malign-loops=2 -malign-jumps=2 -malign-functions=2 L_FLAGS = -Xlinker -s -L/usr/X11R6/lib -lX11 -lXpm PROGNAME = fspanel $(PROGNAME): Makefile fspanel.c fspanel.h icon.xpm $(CC) $(C_FLAGS) $(L_FLAGS) fspanel.c -o $(PROGNAME) @ls -l $(PROGNAME) clean: rm -f core *.o $(PROGNAME) nohup.out install: $(PROGNAME) cp $(PROGNAME) /usr/local/bin fspanel-0.7/Makefile.generic0100644000076400007640000000055307310370410014220 0ustar zedzedCC = cc C_FLAGS = -DHAVE_XPM -Wall -O1 -I/usr/X11R6/include L_FLAGS = -L/usr/X11R6/lib -lX11 -lXpm PROGNAME = fspanel $(PROGNAME): Makefile fspanel.c fspanel.h icon.xpm $(CC) $(C_FLAGS) $(L_FLAGS) fspanel.c -o $(PROGNAME) strip $(PROGNAME) @ls -l $(PROGNAME) clean: rm -f core *.o $(PROGNAME) nohup.out install: $(PROGNAME) cp $(PROGNAME) /usr/local/bin fspanel-0.7/Makefile.solaris0100644000076400007640000000055207256634030014271 0ustar zedzedCC = gcc C_FLAGS = -O2 -I/usr/include/X11 -I/usr/X11/include L_FLAGS = -Xlinker -s -L/usr/X/lib -L/usr/X11/lib -lX11 PROGNAME = fspanel $(PROGNAME): Makefile fspanel.c fspanel.h icon.xpm $(CC) $(C_FLAGS) $(L_FLAGS) fspanel.c -o $(PROGNAME) @ls -l $(PROGNAME) clean: rm -f core *.o $(PROGNAME) nohup.out install: $(PROGNAME) cp $(PROGNAME) /usr/local/bin fspanel-0.7/README0100644000076400007640000000314307311075142012030 0ustar zedzedF***ing Small Panel ~~~~~~~~~~~~~~~~~~~ What is it and what can it do? It's a panel for Linux that lists all your windows, but the difference is that it's tiny. The binary is about 10k and it takes barely any memory. It works under any gnome compliant window manager (eg. E, SawFish, WindowMaker, IceWM) and supports KDE's mini icons (the KWM_WIN_ICON atom). See http://www.chatjunkies.org/fspanel/ for more information. Changes in 0.7 ~~~~~~~~~~~~~~ * Windows that set their icons after mapping no longer get the generic icon. * A new generic icon (looks better, I think). * Fixed lockup when large amount of windows are open. * Desktop switching arrows look different. * Panel height and width are customizable at the top of fspanel.c. Made the default 24 (previously 22) and font 12. This seems to suite 1024x768 well, change to what suites you. * Now uses the unified window manager spec to find the list of windows. Falls back to gnome spec if unavailable. This might make fspanel work on KDE? Note: this is only partially supported and uses the unified spec only for a client list, everything else still uses the gnome window manager spec. * Optimized more code - i386-linux binary is now 9280 bytes! Changes in 0.6 ~~~~~~~~~~~~~~ * The clock now updates on-the-minute. * Optimized some code - binary is 300 bytes smaller :) * Made it possible to compile without libXpm. * Included some Makefiles for FreeBSD and Solaris. * No crash when display fails to open. Changes in 0.5 ~~~~~~~~~~~~~~ * Fix refresh for XFree86 4. * Fix switching desktops (works in Sawfish now too). * Make windows focus when raising. fspanel-0.7/fspanel.c0100644000076400007640000004754007311075164012761 0ustar zedzed /******************************************************** ** F***ing Small Panel 0.7 Copyright (c) 2000-2001 By ** ** Peter Zelezny ** ** See file COPYING for license details. ** ********************************************************/ #include #include #include #include #include #include #include #include #include #ifdef HAVE_XPM #include #include "icon.xpm" #endif #include "fspanel.h" /* you can edit these */ #define MAX_TASK_WIDTH 145 #define ICONWIDTH 16 #define ICONHEIGHT 16 #define WINHEIGHT 24 #define WINWIDTH (scr_width) #define FONT_NAME "-*-lucida*-m*-r-*-*-12-*-*" /* don't edit these */ #define TEXTPAD 6 #define left_arrow_x 25 #define right_arrow_x 50 Display *dd; Window root_win; Pixmap generic_icon; Pixmap generic_mask; GC fore_gc; XFontStruct *xfs; int scr_screen; int scr_depth; int scr_width; int scr_height; int text_y; /*int time_width;*/ unsigned short cols[] = { 0xd75c, 0xd75c, 0xd75c, /* 0. light gray */ 0xbefb, 0xbaea, 0xbefb, /* 1. mid gray */ 0xaefb, 0xaaea, 0xaefb, /* 2. dark gray */ 0xefbe, 0xefbe, 0xefbe, /* 3. white */ 0x8617, 0x8207, 0x8617, /* 4. darkest gray */ 0x0000, 0x0000, 0x0000 /* 5. black */ }; #define PALETTE_COUNT (sizeof (cols) / sizeof (cols[0]) / 3) unsigned long palette[PALETTE_COUNT]; char *atom_names[] = { "KWM_WIN_ICON", "_MOTIF_WM_HINTS", "_WIN_WORKSPACE", "_WIN_HINTS", "_WIN_LAYER", "_NET_CLIENT_LIST", "_WIN_CLIENT_LIST", "_WIN_WORKSPACE_COUNT", "_WIN_STATE", "WM_STATE" }; #define ATOM_COUNT (sizeof (atom_names) / sizeof (atom_names[0])) Atom atoms[ATOM_COUNT]; #define atom_KWM_WIN_ICON atoms[0] #define atom__MOTIF_WM_HINTS atoms[1] #define atom__WIN_WORKSPACE atoms[2] #define atom__WIN_HINTS atoms[3] #define atom__WIN_LAYER atoms[4] #define atom__NET_CLIENT_LIST atoms[5] #define atom__WIN_CLIENT_LIST atoms[6] #define atom__WIN_WORKSPACE_COUNT atoms[7] #define atom__WIN_STATE atoms[8] #define atom_WM_STATE atoms[9] void * get_prop_data (Window win, Atom prop, Atom type, int *items) { Atom type_ret; int format_ret; unsigned long items_ret; unsigned long after_ret; unsigned char *prop_data; prop_data = 0; XGetWindowProperty (dd, win, prop, 0, 0x7fffffff, False, type, &type_ret, &format_ret, &items_ret, &after_ret, &prop_data); if (items) *items = items_ret; return prop_data; } void set_foreground (int index) { XSetForeground (dd, fore_gc, palette[index]); } void draw_line (taskbar *tb, int x, int y, int a, int b) { XDrawLine (dd, tb->win, fore_gc, x, y, a, b); } void fill_rect (taskbar *tb, int x, int y, int a, int b) { XFillRectangle (dd, tb->win, fore_gc, x, y, a, b); } void scale_icon (task *tk) { int xx, yy, x, y, w, h, d, bw; Pixmap pix, mk = None; XGCValues gcv; GC mgc; XGetGeometry (dd, tk->icon, &pix, &x, &y, &w, &h, &bw, &d); pix = XCreatePixmap (dd, tk->win, ICONWIDTH, ICONHEIGHT, scr_depth); if (tk->mask != None) { mk = XCreatePixmap (dd, tk->win, ICONWIDTH, ICONHEIGHT, 1); gcv.subwindow_mode = IncludeInferiors; gcv.graphics_exposures = False; mgc = XCreateGC (dd, mk, GCGraphicsExposures | GCSubwindowMode, &gcv); } set_foreground (3); /* this is my simple & dirty scaling routine */ for (y = ICONHEIGHT - 1; y >= 0; y--) { yy = (y * h) / ICONHEIGHT; for (x = ICONWIDTH - 1; x >= 0; x--) { xx = (x * w) / ICONWIDTH; if (d != scr_depth) XCopyPlane (dd, tk->icon, pix, fore_gc, xx, yy, 1, 1, x, y, 1); else XCopyArea (dd, tk->icon, pix, fore_gc, xx, yy, 1, 1, x, y); if (mk != None) XCopyArea (dd, tk->mask, mk, mgc, xx, yy, 1, 1, x, y); } } if (mk != None) { XFreeGC (dd, mgc); tk->mask = mk; } tk->icon = pix; } void get_task_hinticon (task *tk) { XWMHints *hin; tk->icon = None; tk->mask = None; hin = (XWMHints *) get_prop_data (tk->win, XA_WM_HINTS, XA_WM_HINTS, 0); if (hin) { if ((hin->flags & IconPixmapHint)) { if ((hin->flags & IconMaskHint)) { tk->mask = hin->icon_mask; } tk->icon = hin->icon_pixmap; tk->icon_copied = 1; scale_icon (tk); } XFree (hin); } if (tk->icon == None) { tk->icon = generic_icon; tk->mask = generic_mask; } } void get_task_kdeicon (task *tk) { unsigned long *data; data = get_prop_data (tk->win, atom_KWM_WIN_ICON, atom_KWM_WIN_ICON, 0); if (data) { tk->icon = data[0]; tk->mask = data[1]; XFree (data); } } int find_desktop (Window win) { int desk = 0; unsigned long *data; data = get_prop_data (win, atom__WIN_WORKSPACE, XA_CARDINAL, 0); if (data) { desk = *data; XFree (data); } return desk; } int is_hidden (Window win) { unsigned long *data; int ret = 0; data = get_prop_data (win, atom__WIN_HINTS, XA_CARDINAL, 0); if (data) { if ((*data) & WIN_HINTS_SKIP_TASKBAR) ret = 1; XFree (data); } return ret; } int is_iconified (Window win) { unsigned long *data; int ret = 0; data = get_prop_data (win, atom_WM_STATE, atom_WM_STATE, 0); if (data) { if (data[0] == IconicState) ret = 1; XFree (data); } return ret; } void add_task (taskbar * tb, Window win, int focus) { task *tk, *list; /* is this window on a different desktop? */ if (tb->my_desktop != find_desktop (win) || is_hidden (win)) return; tk = calloc (1, sizeof (task)); tk->win = win; tk->focused = focus; tk->name = get_prop_data (win, XA_WM_NAME, XA_STRING, 0); tk->iconified = is_iconified (win); get_task_kdeicon (tk); if (tk->icon == None) get_task_hinticon (tk); XSelectInput (dd, win, PropertyChangeMask | FocusChangeMask | StructureNotifyMask); /* now append it to our linked list */ tb->num_tasks++; list = tb->task_list; if (!list) { tb->task_list = tk; return; } while (1) { if (!list->next) { list->next = tk; return; } list = list->next; } } void gui_sync (void) { XSync (dd, False); } void set_prop (Window win, Atom at, long val) { XChangeProperty (dd, win, at, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) &val, 1); } taskbar * gui_create_taskbar (void) { taskbar *tb; Window win; MWMHints mwm; XSizeHints size_hints; XWMHints wmhints; XSetWindowAttributes att; att.background_pixel = palette[0]; att.event_mask = ButtonPressMask | ExposureMask; win = XCreateWindow ( /* display */ dd, /* parent */ root_win, /* x */ 0, /* y */ scr_height - WINHEIGHT, /* width */ WINWIDTH, /* height */ WINHEIGHT, /* border */ 0, /* depth */ CopyFromParent, /* class */ InputOutput, /* visual */ CopyFromParent, /*value mask*/ CWBackPixel | CWEventMask, /* attribs */ &att); /* don't let any windows cover fspanel */ set_prop (win, atom__WIN_LAYER, 10); /* WIN_LAYER_ABOVE_DOCK */ set_prop (win, atom__WIN_STATE, WIN_STATE_STICKY | WIN_STATE_FIXED_POSITION); set_prop (win, atom__WIN_HINTS, WIN_HINTS_SKIP_FOCUS | WIN_HINTS_SKIP_WINLIST | WIN_HINTS_SKIP_TASKBAR | WIN_HINTS_DO_NOT_COVER); /* borderless motif hint */ memset (&mwm, 0, sizeof (mwm)); mwm.flags = MWM_HINTS_DECORATIONS; XChangeProperty (dd, win, atom__MOTIF_WM_HINTS, atom__MOTIF_WM_HINTS, 32, PropModeReplace, (unsigned char *) &mwm, sizeof (MWMHints) / 4); /* make sure the WM obays our window position */ size_hints.flags = PPosition; /*XSetWMNormalHints (dd, win, &size_hints);*/ XChangeProperty (dd, win, XA_WM_NORMAL_HINTS, XA_WM_SIZE_HINTS, 32, PropModeReplace, (unsigned char *) &size_hints, sizeof (XSizeHints) / 4); /* make our window unfocusable */ wmhints.flags = InputHint; wmhints.input = 0; /*XSetWMHints (dd, win, &wmhints);*/ XChangeProperty (dd, win, XA_WM_HINTS, XA_WM_HINTS, 32, PropModeReplace, (unsigned char *) &wmhints, sizeof (XWMHints) / 4); XMapWindow (dd, win); tb = calloc (1, sizeof (taskbar)); tb->win = win; return tb; } void gui_init (void) { XGCValues gcv; XColor xcl; int i, j; char *fontname; i = j = 0; do { xcl.red = cols[i]; i++; xcl.green = cols[i]; i++; xcl.blue = cols[i]; i++; XAllocColor (dd, DefaultColormap (dd, scr_screen), &xcl); palette[j] = xcl.pixel; j++; } while (j < PALETTE_COUNT); fontname = FONT_NAME; do { xfs = XLoadQueryFont (dd, fontname); fontname = "fixed"; } while (!xfs); /*time_width = XTextWidth (xfs, "88:88", 5); */ #define time_width (35) text_y = xfs->ascent + ((WINHEIGHT - xfs->ascent) / 2); gcv.font = xfs->fid; gcv.graphics_exposures = False; fore_gc = XCreateGC (dd, root_win, GCFont | GCGraphicsExposures, &gcv); #ifdef HAVE_XPM XpmCreatePixmapFromData (dd, root_win, icon_xpm, &generic_icon, &generic_mask, NULL); #else generic_icon = 0; #endif } void gui_draw_vline (taskbar * tb, int x) { set_foreground (4); draw_line (tb, x, 0, x, WINHEIGHT); set_foreground (3); draw_line (tb, x + 1, 0, x + 1, WINHEIGHT); } void gui_draw_task (taskbar * tb, task * tk) { int len; int x = tk->pos_x; int taskw = tk->width; if (!tk->name) return; gui_draw_vline (tb, x); /*set_foreground (3); *//* it's already 3 from gui_draw_vline() */ draw_line (tb, x + 1, 0, x + taskw, 0); set_foreground (1); draw_line (tb, x + 1, WINHEIGHT - 1, x + taskw, WINHEIGHT - 1); if (tk->focused) { x++; /*set_foreground (1);*/ /* mid gray */ fill_rect (tb, x + 3, 3, taskw - 5, WINHEIGHT - 6); set_foreground (3); /* white */ draw_line (tb, x + 2, WINHEIGHT - 2, x + taskw - 2, WINHEIGHT - 2); draw_line (tb, x + taskw - 2, 2, x + taskw - 2, WINHEIGHT - 2); set_foreground (0); draw_line (tb, x + 1, 2, x + 1, WINHEIGHT - 2); set_foreground (4); /* darkest gray */ draw_line (tb, x + 2, 2, x + taskw - 2, 2); draw_line (tb, x + 2, 2, x + 2, WINHEIGHT - 3); } else { set_foreground (0); /* mid gray */ fill_rect (tb, x + 2, 1, taskw - 1, WINHEIGHT - 2); } { register int text_x = x + TEXTPAD + TEXTPAD + ICONWIDTH; /* check how many chars can fit */ len = strlen (tk->name); while (XTextWidth (xfs, tk->name, len) >= taskw - (text_x - x) - 2 && len > 0) len--; if (tk->iconified) { /* draw task's name dark (iconified) */ set_foreground (3); XDrawString (dd, tb->win, fore_gc, text_x, text_y + 1, tk->name, len); set_foreground (4); } else { set_foreground (5); } /* draw task's name here */ XDrawString (dd, tb->win, fore_gc, text_x, text_y, tk->name, len); } #ifndef HAVE_XPM if (!tk->icon) return; #endif /* draw the task's icon */ XSetClipMask (dd, fore_gc, tk->mask); XSetClipOrigin (dd, fore_gc, x + TEXTPAD, (WINHEIGHT - ICONHEIGHT) / 2); XCopyArea (dd, tk->icon, tb->win, fore_gc, 0, 0, ICONWIDTH, ICONHEIGHT, x + TEXTPAD, (WINHEIGHT - ICONHEIGHT) / 2); XSetClipMask (dd, fore_gc, None); } void gui_draw_clock (taskbar * tb) { char *time_str; time_t now; int width, old_x, x = WINWIDTH - time_width - (TEXTPAD * 4); old_x = x; width = WINWIDTH - x - 2; now = time (0); time_str = ctime (&now) + 11; gui_draw_vline (tb, x); x += TEXTPAD; /*set_foreground (3); *//* white *//* it's already 3 from gui_draw_vline() */ draw_line (tb, x + 1, WINHEIGHT - 2, old_x + width - TEXTPAD, WINHEIGHT - 2); draw_line (tb, old_x + width - TEXTPAD, 2, old_x + width - TEXTPAD, WINHEIGHT - 2); set_foreground (1); /* mid gray */ fill_rect (tb, x + 1, 2, width - (TEXTPAD * 2) - 1, WINHEIGHT - 4); set_foreground (4); /* darkest gray */ draw_line (tb, x, 2, x + width - (TEXTPAD * 2) - 1, 2); draw_line (tb, x, 2, x, WINHEIGHT - 2); set_foreground (5); XDrawString (dd, tb->win, fore_gc, x + TEXTPAD - 1, text_y, time_str, 5); } void draw_dot (Window win, int x, int y) { set_foreground (4); XDrawPoint (dd, win, fore_gc, x, y); set_foreground (3); XDrawPoint (dd, win, fore_gc, x + 1, y + 1); } void draw_grill (Window win, int x) { int y = 0; while (y < WINHEIGHT - 4) { y += 3; draw_dot (win, x + 3, y); draw_dot (win, x, y); } } void draw_up_triangle (taskbar *tb) { fill_rect (tb, left_arrow_x + 2, (WINHEIGHT - 4) / 2 + 1, 3, 3); draw_line (tb, left_arrow_x, (WINHEIGHT - 4) / 2 + 3, left_arrow_x + 3, (WINHEIGHT - 4) / 2); draw_line (tb, left_arrow_x + 3, (WINHEIGHT - 4) / 2, left_arrow_x + 6, (WINHEIGHT - 4) / 2 + 3); draw_line (tb, left_arrow_x + 1, (WINHEIGHT - 4) / 2 + 3, left_arrow_x + 5, (WINHEIGHT - 4) / 2 + 3); } void draw_down_triangle (taskbar *tb) { draw_line (tb, right_arrow_x, (WINHEIGHT - 4) / 2, right_arrow_x + 3, (WINHEIGHT - 4) / 2 + 3); draw_line (tb, right_arrow_x, (WINHEIGHT - 4) / 2, right_arrow_x + 4, (WINHEIGHT - 4) / 2 + 2); draw_line (tb, right_arrow_x, (WINHEIGHT - 4) / 2, right_arrow_x + 5, (WINHEIGHT - 4) / 2 + 1); draw_line (tb, right_arrow_x, (WINHEIGHT - 4) / 2, right_arrow_x + 6, (WINHEIGHT - 4) / 2); } void gui_draw_taskbar (taskbar * tb) { task *tk; int x, width, taskw; int under = 0; set_foreground (5); /* black */ draw_up_triangle (tb); draw_down_triangle (tb); width = WINWIDTH - 80 - time_width - (TEXTPAD * 4); x = 80; if (tb->num_tasks == 0) goto clear; taskw = width / tb->num_tasks; if (taskw > MAX_TASK_WIDTH) { taskw = MAX_TASK_WIDTH; under = 1; } tk = tb->task_list; while (tk) { tk->pos_x = x; tk->width = taskw - 1; gui_draw_task (tb, tk); x += taskw; tk = tk->next; } if (under) { clear: gui_draw_vline (tb, x); set_foreground (0); fill_rect (tb, x + 2, 0, WINWIDTH, WINHEIGHT); } gui_draw_clock (tb); gui_draw_vline (tb, 8); gui_draw_vline (tb, 74); draw_grill (tb->win, 2); draw_grill (tb->win, WINWIDTH - 6); } task * find_task (taskbar * tb, Window win) { task *list = tb->task_list; while (list) { if (list->win == win) return list; list = list->next; } return 0; } void del_task (taskbar * tb, Window win) { task *next, *prev = 0, *list = tb->task_list; while (list) { next = list->next; if (list->win == win) { /* unlink and free this task */ tb->num_tasks--; if (list->icon_copied) { XFreePixmap (dd, list->icon); if (list->mask != None) XFreePixmap (dd, list->mask); } if (list->name) XFree (list->name); free (list); if (prev == 0) tb->task_list = next; else prev->next = next; return; } prev = list; list = next; } } void taskbar_read_clientlist (taskbar * tb) { Window *win, focus_win; int num, i, rev, desk, new_desk = 0; task *list, *next; desk = find_desktop (root_win); if (desk != tb->my_desktop) { new_desk = 1; tb->my_desktop = desk; } XGetInputFocus (dd, &focus_win, &rev); /* try unified window spec first */ win = get_prop_data (root_win, atom__NET_CLIENT_LIST, XA_WINDOW, &num); if (!win) { /* failed, let's try gnome */ win = get_prop_data (root_win, atom__WIN_CLIENT_LIST, XA_CARDINAL, &num); if (!win) return; } /* remove windows that arn't in the _WIN_CLIENT_LIST anymore */ list = tb->task_list; while (list) { list->focused = (focus_win == list->win); next = list->next; if (!new_desk) for (i = num - 1; i >= 0; i--) if (list->win == win[i]) goto dontdel; del_task (tb, list->win); dontdel: list = next; } /* add any new windows */ for (i = 0; i < num; i++) { if (!find_task (tb, win[i])) add_task (tb, win[i], (win[i] == focus_win)); } XFree (win); } void move_taskbar (taskbar * tb) { int x, y; x = y = 0; if (tb->hidden) x = WINWIDTH - TEXTPAD; if (!tb->at_top) y = scr_height - WINHEIGHT; XMoveWindow (dd, tb->win, x, y); } void switch_desk (taskbar * tb, int rel) { XClientMessageEvent xev; unsigned long *data; int want = tb->my_desktop + rel; if (want < 0) return; data = get_prop_data (root_win, atom__WIN_WORKSPACE_COUNT, XA_CARDINAL, 0); if (data) { register unsigned long max_desks = *data; XFree (data); if (max_desks <= want) return; } xev.type = ClientMessage; xev.window = root_win; xev.message_type = atom__WIN_WORKSPACE; xev.format = 32; xev.data.l[0] = want; XSendEvent (dd, root_win, False, SubstructureNotifyMask, (XEvent *) &xev); } void handle_press (taskbar * tb, int x, int y) { task *tk; if (y > 3 && y < WINHEIGHT - 3) { if (x >= right_arrow_x && x < right_arrow_x + 9) { switch_desk (tb, +1); return; } if (x >= left_arrow_x && x < left_arrow_x + 9) { switch_desk (tb, -1); return; } } /* clicked left grill */ if (x < 6) { if (tb->hidden) tb->hidden = 0; else tb->at_top = !tb->at_top; move_taskbar (tb); return; } /* clicked right grill */ if (x + TEXTPAD > WINWIDTH) { tb->hidden = !tb->hidden; move_taskbar (tb); return; } tk = tb->task_list; while (tk) { if (x > tk->pos_x && x < tk->pos_x + tk->width) { if (tk->iconified) { tk->iconified = 0; tk->focused = 1; XMapWindow (dd, tk->win); } else { if (tk->focused) { tk->iconified = 1; tk->focused = 0; XIconifyWindow (dd, tk->win, scr_screen); } else { tk->focused = 1; XRaiseWindow (dd, tk->win); XSetInputFocus (dd, tk->win, RevertToNone, CurrentTime); } } gui_sync (); gui_draw_task (tb, tk); } else { if (tk->focused) { tk->focused = 0; gui_draw_task (tb, tk); } } tk = tk->next; } } void handle_focusin (taskbar * tb, Window win) { task *tk; tk = tb->task_list; while (tk) { if (tk->focused) { if (tk->win != win) { tk->focused = 0; gui_draw_task (tb, tk); } } else { if (tk->win == win) { tk->focused = 1; gui_draw_task (tb, tk); } } tk = tk->next; } } void handle_propertynotify (taskbar * tb, Window win, Atom at) { task *tk; if (win == root_win) { if (at == atom__NET_CLIENT_LIST || at == atom__WIN_CLIENT_LIST || at == atom__WIN_WORKSPACE) { taskbar_read_clientlist (tb); gui_draw_taskbar (tb); } return; } tk = find_task (tb, win); if (!tk) return; if (at == XA_WM_NAME) { /* window's title changed */ if (tk->name) XFree (tk->name); tk->name = get_prop_data (tk->win, XA_WM_NAME, XA_STRING, 0); gui_draw_task (tb, tk); } else if (at == atom_WM_STATE) { /* iconified state changed? */ if (is_iconified (tk->win) != tk->iconified) { tk->iconified = !tk->iconified; gui_draw_task (tb, tk); } } else if (at == XA_WM_HINTS) { /* some windows set their WM_HINTS icon after mapping */ if (tk->icon == generic_icon) { get_task_hinticon (tk); gui_draw_task (tb, tk); } } } void handle_error (Display * d, XErrorEvent * ev) { } int #ifdef NOSTDLIB _start (void) #else main (int argc, char *argv[]) #endif { taskbar *tb; XEvent ev; fd_set fd; struct timeval tv; int xfd; time_t now; struct tm *lt; dd = XOpenDisplay (NULL); if (!dd) return 0; scr_screen = DefaultScreen (dd); scr_depth = DefaultDepth (dd, scr_screen); scr_height = DisplayHeight (dd, scr_screen); scr_width = DisplayWidth (dd, scr_screen); root_win = RootWindow (dd, scr_screen); /* helps us catch windows closing/opening */ XSelectInput (dd, root_win, PropertyChangeMask); XSetErrorHandler ((XErrorHandler) handle_error); XInternAtoms (dd, atom_names, ATOM_COUNT, False, atoms); gui_init (); tb = gui_create_taskbar (); xfd = ConnectionNumber (dd); gui_sync (); while (1) { now = time (0); lt = gmtime (&now); tv.tv_usec = 0; tv.tv_sec = 60 - lt->tm_sec; FD_ZERO (&fd); FD_SET (xfd, &fd); if (select (xfd + 1, &fd, 0, 0, &tv) == 0) gui_draw_clock (tb); while (XPending (dd)) { XNextEvent (dd, &ev); switch (ev.type) { case ButtonPress: if (ev.xbutton.button == 1) handle_press (tb, ev.xbutton.x, ev.xbutton.y); break; case DestroyNotify: del_task (tb, ev.xdestroywindow.window); /* fall through */ case Expose: gui_draw_taskbar (tb); break; case PropertyNotify: handle_propertynotify (tb, ev.xproperty.window, ev.xproperty.atom); break; case FocusIn: handle_focusin (tb, ev.xfocus.window); break; /*default: printf ("unknown evt type: %d\n", ev.type);*/ } } } /*XCloseDisplay (dd); return 0;*/ } fspanel-0.7/fspanel.h0100644000076400007640000000324007311075166012755 0ustar zedzedtypedef struct task { struct task *next; Window win; Pixmap icon; Pixmap mask; char *name; int pos_x; int width; unsigned int focused:1; unsigned int iconified:1; unsigned int icon_copied:1; } task; typedef struct taskbar { Window win; task *task_list; int num_tasks; int my_desktop; unsigned int hidden:1; unsigned int at_top:1; } taskbar; #define MWM_HINTS_DECORATIONS (1L << 1) typedef struct _mwmhints { unsigned long flags; unsigned long functions; unsigned long decorations; long inputMode; unsigned long status; } MWMHints; #define WIN_STATE_STICKY (1<<0) /* everyone knows sticky */ #define WIN_STATE_MINIMIZED (1<<1) /* ??? */ #define WIN_STATE_MAXIMIZED_VERT (1<<2) /* window in maximized V state */ #define WIN_STATE_MAXIMIZED_HORIZ (1<<3) /* window in maximized H state */ #define WIN_STATE_HIDDEN (1<<4) /* not on taskbar but window visible */ #define WIN_STATE_SHADED (1<<5) /* shaded (NeXT style) */ #define WIN_STATE_HID_WORKSPACE (1<<6) /* not on current desktop */ #define WIN_STATE_HID_TRANSIENT (1<<7) /* owner of transient is hidden */ #define WIN_STATE_FIXED_POSITION (1<<8) /* window is fixed in position even */ #define WIN_STATE_ARRANGE_IGNORE (1<<9) /* ignore for auto arranging */ #define WIN_HINTS_SKIP_FOCUS (1<<0) /* "alt-tab" skips this win */ #define WIN_HINTS_SKIP_WINLIST (1<<1) /* not in win list */ #define WIN_HINTS_SKIP_TASKBAR (1<<2) /* not on taskbar */ #define WIN_HINTS_GROUP_TRANSIENT (1<<3) /* ??????? */ #define WIN_HINTS_FOCUS_ON_CLICK (1<<4) /* app only accepts focus when clicked */ #define WIN_HINTS_DO_NOT_COVER (1<<5) /* attempt to not cover this window */ fspanel-0.7/icon.xpm0100644000076400007640000000114307311075172012627 0ustar zedzed/* XPM */ static char * icon_xpm[] = { "16 16 16 1", " c None", ". c #323232", "+ c #535353", "@ c #4A8A8E", "# c #DEE2E2", "$ c #7E827A", "% c #8A9292", "& c #D6D6D6", "* c #36767E", "= c #9E9E9E", "- c #FAFAFA", "; c #B2B2B2", "> c #DEEEEA", ", c #464646", "' c #5EA2A2", ") c #52969A", " ", " ", " --#>>>>>>#-#-; ", " -&%')))))=&=&+ ", " >;$@*****=;%;+ ", " &$$$$$$$$$$$$, ", " &;;;;;;;;;;;;+ ", " &;;;;;;;;;;;;+ ", " #;;;;;;;;;;;;+ ", " &;;;;;;;;;;;;+ ", " #;;;;;;;;;;;;+ ", " #;;;;;;;;;;;;+ ", " &;;;;;;;;;;;;+ ", " $............. ", " ", " "};