wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit c629223ec96dae16f7dbf99d745c195619106c55
parent a5ca79195869ee5d85069b44e568f00a49322656
Author: Kris Maglione <kris@suckless.org>
Date:   Sun, 27 Jun 2010 17:47:45 -0400

[python] Use distutils to compile and install pygmi/pyxp.

Diffstat:
.hgignore | 2++
NEWS | 5+++--
PKGBUILD | 53++++++++++++++++++++++++++++++++++++-----------------
alternative_wmiircs/plan9port/wmiirc | 29+++++++++++++++--------------
alternative_wmiircs/python/Makefile | 6+++---
alternative_wmiircs/python/pygmi.py | 14++++++++++++++
alternative_wmiircs/python/pygmi/fs.py | 91++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
alternative_wmiircs/python/pyxp.py | 14++++++++++++++
alternative_wmiircs/python/pyxp/client.py | 12++++++------
alternative_wmiircs/python/wmiirc | 5-----
config.mk | 3+++
mk/hdr.mk | 40++++++++++++++++++----------------------
mk/python.mk | 14++++++++++++++
util/compile | 5++++-
util/link | 5++++-
15 files changed, 203 insertions(+), 95 deletions(-)

diff --git a/.hgignore b/.hgignore @@ -14,3 +14,5 @@ syntax: glob config.local.mk cmd/menu/bindings.c *.pkg.tar.?z +alternative_wmiircs/python/build/ +alternative_wmiircs/python/dist/ diff --git a/NEWS b/NEWS @@ -1,15 +1,16 @@ 3.10b1: - * Xft is now loaded on demand. * /colrules widths may now be specified in pixels. * /tagrules has been replaced with the more general /rules + * The format of the bar files has changed. * Add witray system tray program. * Floating clients can be collapsed by clicking their layout boxes. * Dock windows act more like dock windows. - * Fixed some managed move bugs. * The FocusFloating and FocusColumn events have been removed. * The tag '!' is no longer special. + * Xft is now loaded on demand. 3.9.2: + * Fixed some managed move bugs. * Work around mawk bug that broke wmiirc. 3.9.1: diff --git a/PKGBUILD b/PKGBUILD @@ -1,34 +1,53 @@ -pkgname=wmii-hg -pkgver=2740 +pkgname=(wmii-hg pyxp-hg pygmi-hg) +pkgver=2746 pkgrel=1 pkgdesc="The latest hg pull of wmii, a lightweight, dynamic window manager for X11" url="http://wmii.suckless.org" license=(MIT) arch=(i686 x86_64) -depends=(libx11 libxinerama libxrandr) -makedepends=(mercurial "libixp-hg>="$(sed -rn <mk/wmii.mk 's/.*IXP_NEEDAPI=([0-9]+).*/\1/p')) -optdepends=("plan9port: for use of the alternative plan9port wmiirc" \ - "python: for use of the alternative Python wmiirc" \ - "ruby-rumai: for use of the alternative Ruby wmiirc" \ - "libxft: for anti-aliased font support") -provides=(wmii) -conflicts=(wmii) +makedepends=(mercurial python "libixp-hg>="$(sed -rn <mk/wmii.mk 's/.*IXP_NEEDAPI=([0-9]+).*/\1/p')) +options=(!strip) source=() FORCE_VER=$(hg log -r . --template {rev}) -build() -{ +_make() { cd $startdir - flags=(PREFIX=/usr \ - ETC=/etc \ - DESTDIR="$pkgdir") + make PREFIX=/usr \ + PYPREFIX=--prefix=/usr \ + ETC=/etc \ + DESTDIR="$pkgdir" \ + "$@" +} + +build() { + _make "${flags[@]}" || return 1 +} - make "${flags[@]}" || return 1 - make "${flags[@]}" install || return 1 +package_wmii-hg() { + depends=(libx11 libxinerama libxrandr) + optdepends=("plan9port: for use of the alternative plan9port wmiirc" \ + "pygmi: for use of the alternative Python wmiirc" \ + "ruby-rumai: for use of the alternative Ruby wmiirc" \ + "libxft: for anti-aliased font support") + provides=(wmii) + conflicts=(wmii) + _make install PYMODULES= || return 1 install -m644 -D ./debian/file/wmii.desktop "$pkgdir/etc/X11/sessions/wmii.desktop" install -m644 -D ./LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE" } +package_pyxp-hg() { + arch=(any) + depends=(python) + _make -C alternative_wmiircs/python pyclean pyxp.install +} + +package_pygmi-hg() { + arch=(any) + depends=(pyxp-hg) + _make -C alternative_wmiircs/python pyclean pygmi.install +} + diff --git a/alternative_wmiircs/plan9port/wmiirc b/alternative_wmiircs/plan9port/wmiirc @@ -1,13 +1,15 @@ #!/bin/sh -f -p="$PATH" -which rc >/dev/null || PATH="$PLAN9:$p" -which rc >/dev/null || PATH="/usr/local/plan9/bin:$p" -which rc >/dev/null || PATH="/usr/local/9/bin:$p" -which rc >/dev/null || PATH="/opt/plan9/bin:$p" -which rc >/dev/null || PATH="/opt/9/bin:$p" -which rc >/dev/null || PATH="/usr/plan9/bin:$p" -which rc >/dev/null || PATH="/usr/9/bin:$p" -test $#* '=' 0 || exec rc $0 +test $#* '=' 0 || { + p="$PATH" + which rc >/dev/null || PATH="$PLAN9:$p" + which rc >/dev/null || PATH="/usr/local/plan9/bin:$p" + which rc >/dev/null || PATH="/usr/local/9/bin:$p" + which rc >/dev/null || PATH="/opt/plan9/bin:$p" + which rc >/dev/null || PATH="/opt/9/bin:$p" + which rc >/dev/null || PATH="/usr/plan9/bin:$p" + which rc >/dev/null || PATH="/usr/9/bin:$p" + exec rc $0 +} cd scriptname=$0 @@ -30,8 +32,8 @@ noticebar=/rbar/!notice # Theme wmiifont='drift,-*-fixed-*-*-*-*-9-*-*-*-*-*-*-*' wmiifont='-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*' -wmiinormcol=`{echo '#000000 #c1c48b #81654f'} -wmiifocuscol=`{echo '#000000 #81654f #000000'} +wmiinormcol=('#000000' '#c1c48b' '#81654f') +wmiifocuscol=('#000000' '#81654f' '#000000') wmiibackground='#333333' wmiifloatbackground='#222222' fn setbackground { xsetroot -solid $* } @@ -191,9 +193,8 @@ fn key { key=() for(k) { if(! ~ $k $_keys) { - ifs=() { wmiikeyhelp = `{awk 'BEGIN { - printf "%s %- 20s %s\n", ENVIRON["wmiikeyhelp"], ENVIRON["k"], ENVIRON["help"] - exit }'} } + ifs=() { wmiikeyhelp = `{ + printf "%s %- 20s %s\n" $wmiikeyhelp $k $help}} key = ($key Key-$k)}} ~ $#key 0} diff --git a/alternative_wmiircs/python/Makefile b/alternative_wmiircs/python/Makefile @@ -2,13 +2,13 @@ ROOT=../.. include $(ROOT)/mk/hdr.mk include $(ROOT)/mk/wmii.mk +PYMODULES = pyxp pygmi + DOCS = README EXECS = wmiirc TEXT = wmiirc.py -DIRS = pygmi \ - pyxp DIR = $(GLOBALCONF)/python DOCDIR = $(DOC)/alternative_wmiircs/python -include $(ROOT)/mk/dir.mk +include $(ROOT)/mk/python.mk diff --git a/alternative_wmiircs/python/pygmi.py b/alternative_wmiircs/python/pygmi.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +from distutils.core import setup + +setup(name='pygmi', + version='0.2', + description='Python wmii interaction library', + author='Kris Maglione', + author_email='maglione.k@gmail.com', + url='http://wmii.suckless.org', + packages=['pygmi'], + license='MIT', + ) + diff --git a/alternative_wmiircs/python/pygmi/fs.py b/alternative_wmiircs/python/pygmi/fs.py @@ -28,11 +28,27 @@ class Never(Toggle.__class__): pass def constrain(min, max, val): - if val < min: - return min - if val > max: - return max - return val + return min if val < min else max if val > max else val + +class Map(collections.Mapping): + def __init__(self, cls, *args): + self.cls = cls + self.args = args + def __repr__(self): + return 'Map(%s%s)' % (self.cls.__name__, (', %s' % ', '.join(map(repr, self.args)) if self.args else '')) + def __getitem__(self, item): + ret = self.cls(*(self.args + (item,))) + if not ret.exists: + raise KeyError('no such %s %s' % (self.cls.__name__.lower(), repr(item))) + return ret + def __len__(self): + return len(iter(self)) + def __keys__(self): + return [v for v in self.cls.all(*self.args)] + def __iter__(self): + return (v for v in self.cls.all(*self.args)) + def iteritems(self): + return ((v, self.cls(*(self.args + (v,)))) for v in self.cls.all(*self.args)) class Ctl(object): """ @@ -65,7 +81,13 @@ class Ctl(object): """ Arguments are joined by ascii spaces and written to the ctl file. """ - client.awrite(self.ctl_path, u' '.join(map(unicode, args))) + def next(file, exc=None, tb=None): + if file: + self.file = file + file.awrite(u' '.join(map(unicode, args))) + if self.file: + return next(file) + client.acreate(self.ctl_path, callback=next, mode=OWRITE) def __getitem__(self, key): for line in self.ctl_lines(): @@ -128,7 +150,7 @@ class Ctl(object): @prop(doc="If #ctl_hasid is set, returns the id of this ctl file.") def id(self): if self._id is None and self.ctl_hasid: - return client.read(self.ctl_path).split('\n', 1)[0] + return self.name_read(client.read(self.ctl_path).split('\n', 1)[0]) return self._id class Dir(Ctl): @@ -140,6 +162,8 @@ class Dir(Ctl): represented by this class reside. e.g., /client, /tag """ ctl_hasid = True + name_read = unicode + name_write = unicode def __init__(self, id): """ @@ -154,7 +178,7 @@ class Dir(Ctl): if isinstance(id, Dir): id = id.id if id != 'sel': - self._id = id + self._id = self.name_read(id) def __eq__(self, other): return (self.__class__ == other.__class__ and @@ -218,16 +242,22 @@ class Dir(Ctl): @prop(doc="The path to this directory") def path(self): - return '%s/%s' % (self.base_path, self._id or 'sel') + return '%s/%s' % (self.base_path, self.name_write(self._id or 'sel')) + @prop(doc="True if the given object exists in the wmii filesystem") + def exists(self): + return bool(client.stat(self.path)) @classmethod def all(cls): """ Returns all of the objects that exist for this type of directory. """ - return (cls(s.name) + return (cls.name_read(s.name) for s in client.readdir(cls.base_path) if s.name != 'sel') + @classmethod + def map(cls, *args): + return Map(cls, *args) def __repr__(self): return '%s(%s)' % (self.__class__.__name__, @@ -243,6 +273,15 @@ class Client(Dir): 'group': (lambda s: int(s, 16), str), 'pid': (int, None), } + @staticmethod + def name_read(name): + if isinstance(name, int): + return name + try: + return int(name, 16) + except: + return unicode(name) + name_write = lambda self, name: name if isinstance(name, basestring) else '%#x' % name allow = Dir.ctl_property('allow') fullscreen = Dir.toggle_property('fullscreen') @@ -531,7 +570,8 @@ class Button(Ctl): self.base_path = self.sides[side] self.ctl_path = '%s/%s' % (self.base_path, self.name) self.file = None - self.create(colors, label) + if colors or label: + self.create(colors, label) def create(self, colors=None, label=None): def fail(resp, exc, tb): @@ -548,11 +588,18 @@ class Button(Ctl): self.file.aremove() self.file = None + @property + def exists(self): + return bool(self.file and File.stat(self.file)) + @classmethod def all(cls, side): - return (Button(side, s.name) + return (s.name for s in client.readdir(cls.sides[side]) if s.name != 'sel') + @classmethod + def map(cls, *args): + return Map(cls, *args) class Rules(collections.MutableMapping, utf8): @@ -586,8 +633,7 @@ class Rules(collections.MutableMapping, utf8): def __len__(self): return len(tuple(self.iteritems())) def __iter__(self): - for k, v in self.iteritems(): - yield k + return (k for k, v in self.iteritems()) def __list__(self): return list(iter(self)) def __tuple__(self): @@ -609,8 +655,7 @@ class Rules(collections.MutableMapping, utf8): return u''.join(unicode(value) for (key, value) in self.iteritems()) or u'\n' def iteritems(self): - for item in self._items: - yield item + return iter(self._items) def items(self): return list(self._items()) @@ -659,8 +704,7 @@ class Rule(collections.MutableMapping, utf8): def __len__(self): return len(self._items) def __iter__(self): - for k in iter(self._items): - yield k + return iter(self._items) def __list__(self): return list(iter(self)) def __tuple__(self): @@ -687,8 +731,7 @@ class Rule(collections.MutableMapping, utf8): for (k, v) in self.iteritems())) def iteritems(self): - for i in self._items: - yield i + return iter(self._items) def items(self): return list(self._items) @@ -702,10 +745,10 @@ class wmii(Ctl): 'border': (int, str), } - clients = property(lambda self: Client.all()) - tags = property(lambda self: Tag.all()) - lbuttons = property(lambda self: Button.all('left')) - rbuttons = property(lambda self: Button.all('right')) + clients = Client.map() + tags = Tag.map() + lbuttons = Button.map('left') + rbuttons = Button.map('right') rules = Rules('/rules') diff --git a/alternative_wmiircs/python/pyxp.py b/alternative_wmiircs/python/pyxp.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python + +from distutils.core import setup + +setup(name='pyxp', + version='0.2', + description='Python 9P client library', + author='Kris Maglione', + author_email='maglione.k@gmail.com', + url='http://wmii.suckless.org', + packages=['pyxp'], + license='MIT', + ) + diff --git a/alternative_wmiircs/python/pyxp/client.py b/alternative_wmiircs/python/pyxp/client.py @@ -202,7 +202,7 @@ class Client(object): try: with self._walk(path) as fid: resp = self._dorpc(fcall.Tstat(fid= fid)) - st = resp.stat() + st = resp.stat self._clunk(fid) return st except RPCError: @@ -328,7 +328,10 @@ class File(object): def close(self): assert not self.closed self.closed = True - self._cleanup() + try: + self._cleanup() + except: + pass self.tg = None self.fid = None self.client = None @@ -338,9 +341,6 @@ class File(object): try: self._dorpc(fcall.Tremove()) finally: - try: - self.close() - except Exception: - pass + self.close() # vim:se sts=4 sw=4 et: diff --git a/alternative_wmiircs/python/wmiirc b/alternative_wmiircs/python/wmiirc @@ -1,9 +1,4 @@ #!/usr/bin/env python -import os, sys -path = [] -for p in os.environ.get("WMII_CONFPATH", "").split(':'): - path += [p, p + '/python'] -sys.path = path + sys.path from pygmi import events import wmiirc diff --git a/config.mk b/config.mk @@ -8,6 +8,7 @@ PREFIX = /usr/local ETC = $(PREFIX)/etc LIBDIR = $(PREFIX)/lib INCLUDE = $(PREFIX)/include + PYPREFIX = --prefix=$(PREFIX) # Includes and libs INCLUDES = -I. -I$(ROOT)/include -I$(INCLUDE) -I/usr/include @@ -26,6 +27,8 @@ LD = cc # Archiver AR = ar crs +PYTHON = python + X11PACKAGES = x11 xinerama xrender xrandr INCX11 = $$(pkg-config --cflags $(X11PACKAGES)) LIBIXP = $(LIBDIR)/libixp.a diff --git a/mk/hdr.mk b/mk/hdr.mk @@ -22,12 +22,12 @@ FILTER = cat EXCFLAGS = $(INCLUDES) -D_XOPEN_SOURCE=600 -COMPILE_FLAGS = $(EXCFLAGS) $(CFLAGS) $$(pkg-config --cflags $(PACKAGES)) -COMPILE = $(SHELL) $(ROOT)/util/compile "$(CC)" "$(COMPILE_FLAGS)" -COMPILEPIC = $(SHELL) $(ROOT)/util/compile "$(CC)" "$(COMPILE_FLAGS) $(SOCFLAGS)" +COMPILE_FLAGS = $(EXCFLAGS) $(CFLAGS) +COMPILE = $(SHELL) $(ROOT)/util/compile "$(CC)" "$(PACKAGES)" "$(COMPILE_FLAGS)" +COMPILEPIC = $(SHELL) $(ROOT)/util/compile "$(CC)" "$(PACKAGES)" "$(COMPILE_FLAGS) $(SOCFLAGS)" -LINK = $(SHELL) $(ROOT)/util/link "$(LD)" "$$(pkg-config --libs $(PACKAGES)) $(LDFLAGS) $(LIBS)" -LINKSO = $(SHELL) $(ROOT)/util/link "$(LD)" "$$(pkg-config --libs $(PACKAGES)) $(SOLDFLAGS) $(LIBS) $(SHARED)" +LINK = $(SHELL) $(ROOT)/util/link "$(LD)" "$(PACKAGES)" "$(LDFLAGS) $(LIBS)" +LINKSO = $(SHELL) $(ROOT)/util/link "$(LD)" "$(PACKAGES)" "$(SOLDFLAGS) $(LIBS) $(SHARED)" CLEANNAME=$(SHELL) $(ROOT)/util/cleanname @@ -36,7 +36,7 @@ TAGFILES= CTAGS=ctags -PACKAGES = 2>/dev/null +PACKAGES = # and this: # Try to find a sane shell. /bin/sh is a last resort, because it's @@ -56,14 +56,13 @@ MKCFG!=$(MKCFGSH) include $(MKCFG) .SILENT: -.SUFFIXES: .out .o .o_pic .c .pdf .sh .rc .$(SOEXT) .awk .1 .3 .man1 .man3 .depend .install .uninstall .clean +.SUFFIXES: .$(SOEXT) .1 .3 .awk .build .c .clean .depend .install .man1 .man3 .o .o_pic .out .pdf .py .rc .sh .uninstall all: MAKEFILES=.depend .c.depend: echo MKDEP $< - [ -n "$(noisycc)" ] && echo $(MKDEP) $(COMPILE_FLAGS) $< || true - eval "$(MKDEP) $(COMPILE_FLAGS)" $< | sed '1s|.*:|$(<:%.c=%.o):|' >>.depend + $(DEBUG) eval "$(MKDEP) $(COMPILE_FLAGS)" $< | sed '1s|.*:|$(<:%.c=%.o):|' >>.depend .sh.depend .rc.depend .1.depend .3.depend .awk.depend: : @@ -83,33 +82,30 @@ MAKEFILES=.depend echo FILTER $(BASE)$< [ -n "$(<:%.sh=)" ] || $(BINSH) -n $< set -e; \ - [ -n "$(noisycc)" ] && set -x; \ - $(FILTER) $< >$@; \ - chmod 0755 $@ + $(DEBUG) $(FILTER) $< >$@; \ + $(DEBUG) chmod 0755 $@ .man1.1 .man3.3: echo TXT2TAGS $(BASE)$< - [ -n "$(noisycc)" ] && set -x; \ - txt2tags -o- $< >$@ + $(DEBUG) txt2tags -o- $< >$@ + +DEBUG = _debug() { [ -n "$$noisycc" ] && echo >&2 $$@ || true; "$$@"; }; _debug INSTALL= _install() { set -e; \ dashb=$$1; [ $$1 = -b ] && shift; \ d=$(DESTDIR)$$3; f=$$d/$$(basename $$4); \ if [ ! -d $$d ]; then echo MKDIR $$3; mkdir -p $$d; fi; \ echo INSTALL $$($(CLEANNAME) $(BASE)$$2); \ - [ -n "$(noisycc)" ] && set -x; \ - rm -f $$f; \ + $(DEBUG) rm -f $$f; \ if [ "$$dashb" = -b ]; \ - then cp -f $$2 $$f; \ - else $(FILTER) <$$2 >$$f; \ + then $(DEBUG) cp -f $$2 $$f; \ + else $(DEBUG) $(FILTER) <$$2 >$$f; \ fi; \ - chmod $$1 $$f; \ - set +x; \ + $(DEBUG) chmod $$1 $$f; \ }; _install UNINSTALL= _uninstall() { set -e; \ echo UNINSTALL $$($(CLEANNAME) $(BASE)$$1); \ - [ -n "$(noisycc)" ] && set -x; \ - rm -f $(DESTDIR)$$2/$$(basename $$3); \ + $(DEBUG) rm -f $(DESTDIR)$$2/$$(basename $$3); \ }; _uninstall .out.install: diff --git a/mk/python.mk b/mk/python.mk @@ -0,0 +1,14 @@ + +# all: pybuild +install: $(PYMODULES:%=%.install) +clean: pyclean + +.py.install: + echo PYTHON install $* $(PYPREFIX) + DESTDIR=$(DESTDIR); \ + $(DEBUG) $(PYTHON) $< install -cO1 --root=$${DESTDIR:-/} $(PYPREFIX) +pyclean: + echo CLEAN build/ + rm -rf build + +.PHONY: pybuild pyclean diff --git a/util/compile b/util/compile @@ -1,7 +1,10 @@ #!/bin/sh -f CC=$1 -CFLAGS=$2; shift 2 +PACKAGES=$2 +CFLAGS=$3; shift 3 + +[ -n "$PACKAGES" ] && CFLAGS="$CFLAGS $(pkg-config --cflags $PACKAGES)" outfile="$1"; shift bin="$(echo $0 | sed 's,/[^/]*$,,')" diff --git a/util/link b/util/link @@ -1,7 +1,10 @@ #!/bin/sh -f LD=$1 -LDFLAGS=$2; shift 2 +PACKAGES=$2 +LDFLAGS=$3; shift 3 + +[ -n "$PACKAGES" ] && LDFLAGS="$(pkg-config --libs $PACKAGES) $LDFLAGS" outfile="$1"; shift bin="$(echo $0 | sed 's,/[^/]*$,,')"