lsw

lists window titles of X clients to stdout
git clone git://git.suckless.org/lsw
Log | Files | Refs | README | LICENSE

commit c43d205c65f6223efd93b1b01c6e76e80737b15e
parent 84e6fd3cd229b57d894d6ed9db6517580d8189ef
Author: Connor Lane Smith <cls@lubutu.com>
Date:   Thu, 19 May 2011 17:04:03 +0100

refactored, manpage, -l flag
Diffstat:
LICENSE | 3++-
Makefile | 13++++++++-----
README | 2+-
config.mk | 17+++++++----------
lsw.1 | 19+++++++++++++++++++
lsw.c | 119+++++++++++++++++++++++++++++++++++++++++--------------------------------------
6 files changed, 99 insertions(+), 74 deletions(-)

diff --git a/LICENSE b/LICENSE @@ -1,6 +1,7 @@ MIT/X Consortium License -(C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> +© 2011 Connor Lane Smith <cls@lubutu.com> +© 2006-2011 Anselm R Garbe <anselm@garbe.us> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/Makefile b/Makefile @@ -1,5 +1,5 @@ # lsw - list window names -# (C)opyright MMVI Anselm R. Garbe +# See LICENSE file for copyright and license details. include config.mk @@ -7,7 +7,6 @@ SRC = lsw.c OBJ = ${SRC:.c=.o} all: options lsw - @echo finished options: @echo lsw build options: @@ -16,13 +15,12 @@ options: @echo "CC = ${CC}" .c.o: - @echo CC $< + @echo CC -c $< @${CC} -c ${CFLAGS} $< lsw: ${OBJ} - @echo LD $@ + @echo CC -o $@ @${CC} -o $@ ${OBJ} ${LDFLAGS} - @strip $@ clean: @echo cleaning @@ -41,9 +39,14 @@ install: all @mkdir -p ${DESTDIR}${PREFIX}/bin @cp -f lsw ${DESTDIR}${PREFIX}/bin @chmod 755 ${DESTDIR}${PREFIX}/bin/lsw + @echo installing manual page to ${DESTDIR}${MANPREFIX}/man1/lsw.1 + @sed "s/VERSION/${VERSION}/g" < lsw.1 > ${DESTDIR}${MANPREFIX}/man1/lsw.1 + @chmod 644 ${DESTDIR}${MANPREFIX}/man1/lsw.1 uninstall: @echo removing executable file from ${DESTDIR}${PREFIX}/bin @rm -f ${DESTDIR}${PREFIX}/bin/lsw + @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 + @rm -f ${DESTDIR}${MANPREFIX}/man1/lsw.1 .PHONY: all options clean dist install uninstall diff --git a/README b/README @@ -21,4 +21,4 @@ necessary as root): Running lsw ----------- -Simply invoke the 'lsw' command. +See the man page for details. diff --git a/config.mk b/config.mk @@ -1,7 +1,5 @@ # lsw version -VERSION = 0.1 - -# Customize below to fit your system +VERSION = 0.2 # paths PREFIX = /usr/local @@ -11,14 +9,13 @@ X11INC = /usr/X11R6/include X11LIB = /usr/X11R6/lib # includes and libs -INCS = -I/usr/lib -I${X11INC} -LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 +INCS = -I${X11INC} +LIBS = -L${X11LIB} -lX11 # flags -CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\" -LDFLAGS = ${LIBS} -#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" -#LDFLAGS = -g ${LIBS} +CPPFLAGS = -DVERSION=\"${VERSION}\" +CFLAGS = -ansi -pedantic -Wall -Os ${INCS} ${CPPFLAGS} +LDFLAGS = -s ${LIBS} -# compiler +# compiler and linker CC = cc diff --git a/lsw.1 b/lsw.1 @@ -0,0 +1,19 @@ +.TH LSW 1 lsw\-VERSION +.SH NAME +lsw \- list window titles +.SH SYNOPSIS +.B lsw +.RB [ \-l ] +.RB [ \-v ] +.RI [ windows ...] +.SH DESCRIPTION +.B lsw +prints the titles of the given X windows' children to stdout. If no windows are +given the root window is used. +.SH OPTIONS +.TP +.B \-l +lsw lists each window's XID as well as its title. +.TP +.B \-v +prints version information to stdout, then exits. diff --git a/lsw.c b/lsw.c @@ -1,6 +1,4 @@ -/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> - * See LICENSE file for license details. - */ +/* See LICENSE file for copyright and license details. */ #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -8,70 +6,77 @@ #include <X11/Xlib.h> #include <X11/Xutil.h> -static char buf[1024]; +static void getname(Window win, char *buf, size_t size); +static void lsw(Window win); + static Atom netwmname; +static Bool longfmt = False; static Display *dpy; -static void -getname(Window w) { - char **list = NULL; - int n; - XTextProperty prop; - - prop.nitems = 0; - buf[0] = 0; - XGetTextProperty(dpy, w, &prop, netwmname); - if(!prop.nitems) - XGetWMName(dpy, w, &prop); - if(!prop.nitems) - return; - if(prop.encoding == XA_STRING) - strncpy(buf, (char *)prop.value, sizeof(buf)); - else { - if(XmbTextPropertyToTextList(dpy, &prop, &list, &n) >= Success - && n > 0 && *list) - { - strncpy(buf, *list, sizeof(buf)); - XFreeStringList(list); - } - } - XFree(prop.value); -} - int main(int argc, char *argv[]) { - unsigned int i, num; - Window *wins, d1, d2; - XWindowAttributes wa; - Window win; + int i; - if((argc > 1) && !strncmp(argv[1], "-v", 3)) { - fputs("lsw-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout); - exit(EXIT_SUCCESS); - } - if(!(dpy = XOpenDisplay(0))) { + if(!(dpy = XOpenDisplay(NULL))) { fputs("lsw: cannot open display\n", stderr); exit(EXIT_FAILURE); } - if(argc == 2) - win = atoi(argv[1]); - else - win = DefaultRootWindow(dpy); - netwmname = XInternAtom(dpy, "_NET_WM_NAME", False); - if(XQueryTree(dpy, win, &d1, &d2, &wins, &num)) { - for(i = 0; i < num; i++) { - if(!XGetWindowAttributes(dpy, wins[i], &wa)) - continue; - if(wa.override_redirect) - continue; - getname(wins[i]); - if(buf[0]) - fprintf(stdout, "%s\n", buf); + + for(i = 1; i < argc; i++) + if(!strcmp(argv[i], "-v")) { + puts("lsw-"VERSION", © 2006-2011 lsw engineers, see LICENSE for details"); + exit(EXIT_SUCCESS); } + else if(!strcmp(argv[i], "-l")) + longfmt = True; + else + break; + + if(i == argc) + lsw(DefaultRootWindow(dpy)); + while(i < argc) + lsw(strtol(argv[i++], NULL, 0)); + + return EXIT_SUCCESS; +} + +void +lsw(Window win) { + char buf[BUFSIZ]; + unsigned int i, n; + Window *wins, dw; + XWindowAttributes wa; + + if(!XQueryTree(dpy, win, &dw, &dw, &wins, &n)) + return; + for(i = 0; i < n; i++) + if(XGetWindowAttributes(dpy, win, &wa) && !wa.override_redirect) { + getname(wins[i], buf, sizeof buf); + if(longfmt) + printf("0x%07lx %s\n", wins[i], buf); + else if(buf[0] != '\0') + puts(buf); + } + XFree(wins); +} + +void +getname(Window win, char *buf, size_t size) { + char **list = NULL; + int n; + XTextProperty prop; + + buf[0] = '\0'; + if(!XGetTextProperty(dpy, win, &prop, netwmname) || prop.nitems == 0) + if(!XGetWMName(dpy, win, &prop) || prop.nitems == 0) + return; + + if(prop.encoding == XA_STRING) + strncpy(buf, (char *)prop.value, size); + else if(!XmbTextPropertyToTextList(dpy, &prop, &list, &n) && n > 0) { + strncpy(buf, list[0], size); + XFreeStringList(list); } - if(wins) - XFree(wins); - XCloseDisplay(dpy); - return 0; + XFree(prop.value); }