wmii

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

commit 8ba6c84f1c67dc5fb6a207adc9f1949b400f4b51
parent 717e770e72abcf5bbfa0c8d0d790b8120f5d5134
Author: Kris Maglione <jg@suckless.org>
Date:   Sun, 20 Jan 2008 18:00:21 -0500

Several changes:
	Filter comments out of ctl files.
	Update util/genconfig.
	Add a notification bar (I've had one for some time).
	Make wmiirc more like rc.wmii.

Diffstat:
DISTRIBUTORS | 22+++++++++++-----------
NOTES | 5++++-
README | 10++++++----
cmd/Makefile | 2+-
cmd/wmii.rc.rc | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
cmd/wmii.sh.sh | 158+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
cmd/wmii/fns.h | 1+
cmd/wmii/message.c | 52+++++++++++++++++++++++++++++++++++++++-------------
cmd/wmii/printevent.c | 6+++---
cmd/wmii/utf.c | 2+-
cmd/wmii/xext.c | 6++----
cmd/wmiiloop.sh | 43-------------------------------------------
config.mk | 5++---
mk/hdr.mk | 7+++++++
rc/rc.wmii.rc | 181++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
rc/wmiirc.sh | 117++++++++++++++++++++-----------------------------------------------------------
util/genconfig | 179++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------
17 files changed, 563 insertions(+), 314 deletions(-)

diff --git a/DISTRIBUTORS b/DISTRIBUTORS @@ -1,9 +1,9 @@ The following conditions apply to any distribution which -uses the name wmii. These conditions apply only to wmii +uses the name wmii. These conditions apply only to wmii name, and not to its source code or any other materials. When in doubt about any of these conditions or other matters -of packaging or distrobution, , please contact the wmii +of packaging or distribution, please contact the wmii mailing lists <wmii-hackers@suckless.org> or <wmii@suckless.org>, or Kris Maglione <fbsdaemon@gmail.com>. @@ -13,23 +13,23 @@ version string. This string may normally be set in revision number for builds from a Mercurial tree, so long as the 'hg' command is present and properly functioning. -Any version which not an official release or snapshot MUST -be contain the hg revision number in its version string. -This SHOULD be formated as hgXXXX, where XXXX is the decimal -revision number. +Any version which is not an official release or snapshot +MUST be contain the hg revision number in its version +string. This SHOULD be formatted as hgXXXX, where XXXX is +the decimal revision number. The version string of any snapshot release MUST contain the date of the snapshot in the form YYYYMMDD, and SHOULD -contain the word snap or snapshot. The version string of a -snapshot MAY contain the version of a full release that the -snapshot is expected to lead to, but it MUST be either +contain the word snap or snapshot. The version string of a +snapshot MAY contain the version name of a full release that +the snapshot is expected to lead to, but it MUST be either directly preceded, or directly followed by, the word 'pre', optionally separated by a non-alphanumeric character, -including -~_,./, the version. +including -~_,./. Any binary distribution which is modified in any non-trivial way MUST signify the modifications in its name or version -string. This includes patches to use Xft for font display, +string. This includes patches to use Xft for font display, but does NOT include minor patches to improve consistency with the rest of the system, including changing the default terminal emulator or changing any build flags as set in diff --git a/NOTES b/NOTES @@ -1,3 +1,6 @@ 3.6 Release Notes -wmiirc users: the semantics of WMII_MENU, WMII_9MENU and WMII_TERM have changed. If you're using them in custom scripts you'll need to change them to "eval $WMII_MENU" instead of just "$WMII_MENU". +wmiirc users: the semantics of WMII_MENU, WMII_9MENU and WMII_TERM +have changed. If you're using them in custom scripts you'll need to +change them to "eval $WMII_MENU" instead of just "$WMII_MENU". + diff --git a/README b/README @@ -3,7 +3,7 @@ Abstract window manager improved-improved is a dynamic window manager for X11. It supports classic and tiled window management with extended keyboard, mouse, and 9P-based [1] remote control. -It consists of the wmiiwm(1) window manager and the wmiir(1) +It consists of the wmii(1) window manager and the wmiir(1) the remote access utility. @@ -12,6 +12,7 @@ Requirements In order to build wmii you need the Xlib header files and libixp. xmessage and dmenu are used by the default scripts. libixp and dmenu can be obtained from http://suckless.org/. Either plan9port[2] or 9base is recommended. +If you have the wmii+ixp distribution, libixp is already provided. Installation @@ -48,9 +49,9 @@ which remotely controls the window manager and handles various events. The main rc.wmii script lives in PREFIX/etc/wmii-3.5/, while rc.wmii.local goes in $HOME/.wmii-3.5/. -rc.wmii.local should contain a line containing just: '# Overrides'. You must -set your MODKEY and other configuration variables before this line, if you -wish to change then, and define most functions after it. +If you wish to unbind keys bound by rc.wmii in rc.wmii.local, you +must do so inside the function Action-overridekeys. You may, +however, define new keys or redefine keys anywhere. Credits ------- @@ -87,3 +88,4 @@ References ---------- [1] http://9p.cat-v.org [2] http://plan9.us + diff --git a/cmd/Makefile b/cmd/Makefile @@ -7,9 +7,9 @@ wmiir.c: $(ROOT)/mk/wmii.mk DIRS = wmii TARG = wihack \ wmii.rc \ + wmii.sh \ wmii9menu \ wmii9rc \ - wmiiloop \ wmiir \ wmiistartrc diff --git a/cmd/wmii.rc.rc b/cmd/wmii.rc.rc @@ -1,7 +1,18 @@ +# For the time being, this file follows the lisp bracing +# convention. i.e.: +# if(frob this) { +# frob that +# if(frob theother) { +# unfrob this +# unfrob that}} + wmiiscript=$1 wmiikeys=() +wi_nl=' +' + echo Start $wmiiscript | wmiir write /event >[2]/dev/null \ || exit write @@ -17,13 +28,6 @@ fn sigexit { wi_atexit } -fn Event-Start { - if(~ $1 $wmiiscript) - exit -} - -fn Event-Key { Key-$1 $1 } - fn wi_fatal { echo $scriptname: Fatal: $* exit fatal @@ -51,6 +55,10 @@ fn wi_9menu { -^(sf sb br)^$wmiifocuscol $* } +fn wi_fn-p { + rc -c 'whatis '$1 >[2]/dev/null | grep -s '^fn ' +} + fn wi_proglist { /bin/ls -lL `{echo $* | sed 'y/:/ /'} >[2]/dev/null \ | awk '$1 ~ /^[^d].*x/ { print $NF }' \ @@ -64,9 +72,14 @@ fn wi_actions { } fn wi_script { - prog = `{@{path=$confpath whatis $1} | - grep -v '^fn|= ' || echo /dev/null} - shift; echo $prog $* + noprog=true prog=() { + if(~ $1 -f) { + shift + noprog=/dev/null + } + prog = `{rc -c 'path=$confpath whatis '$1 >[2]/dev/null \ + | grep -v '^fn|= ' || echo $noprog} + shift; echo $prog $*} } @@ -78,9 +91,7 @@ fn wi_initkeys { <{echo $wmiikeys | sort | uniq}} {echo $wmiikeys; wi_getfuns Key} \ | sort | uniq \ - | wmiir write /keys - } - } + | wmiir write /keys }} fn wi_atexit { wi_cleankeys } @@ -91,9 +102,7 @@ fn wi_cleankeys { wmiikeys = `{wmiir read /keys} { comm -23 <{echo $wmiikeys | sort | uniq} \ <{echo $mykeys} \ - | wmiir write /keys - } - } + | wmiir write /keys }} } fn wi_runcmd { @{ @@ -101,16 +110,19 @@ fn wi_runcmd { @{ path=$oldpath if(~ $1 -t) { shift - * = (wihack -tags `{wmiir read /tag/sel/ctl | sed 1q} $*) - } - eval exec $* & - } + * = (wihack -tags `{wmiir read /tag/sel/ctl | sed 1q} $*) } + eval exec $* & } } fn wi_getfuns { env | sed -n 's/^fn#'^$1^'-([^=]+).*/\1/p' } +for(i in Key Event Action) + fns=`{wi_getfuns $i} { + if(! ~ $fns '') + fn $i-^$fns} + fn wi_tags { wmiir ls /tag | sed 's,/,,; /^sel$/d' } @@ -119,9 +131,30 @@ fn wi_eventloop { wi_initkeys wmiir read /event | - while(*=`{read}) { - event = $1; shift - Event-$event $* - } >[2]/dev/null </dev/null + while(ifs=$wi_nl{wi_event=`{read}}) { + ifs=$wi_nl{ + wi_arg=`{echo $wi_event | sed 's/^[^ ]+ //'}} + * = `{echo $wi_event} + event = $1; shift + Event-$event $* + } >[2]/dev/null </dev/null +} + +fn Event-Key { + Key-$1 $1 +} + +fn Event-Start { + if(~ $1 $wmiiscript) + exit +} + +fn Action { + cmd=$1 action=Action-$cmd { shift + if(wi_fn-p $action) + $action $* + if not + wi_runcmd `{wi_script $cmd} $* + } & } diff --git a/cmd/wmii.sh.sh b/cmd/wmii.sh.sh @@ -0,0 +1,158 @@ + +wmiiscript=$1 +if [ -z "$scriptname" ]; then + scriptname="$wmiiscript"; fi +echo Start $wmiiscript | wmiir write /event 2>/dev/null || + exit 1 + +Keys="" +Actions="" +Events="" + +_wi_script() { + cat <<'!' + BEGIN { + arg[1] = "Nop" + body = ""; + } + function addevent() { + if(arg[1] == "Key") + keys[arg[2]] = 1; + + var = arg[1] "s" + printf "%s=\"$%s\n%s\"\n", var, var, arg[2] + + gsub("[^a-zA-Z_0-9]", "_", arg[2]); + if(body != "") + printf "%s_%s() { %s\n }\n", arg[1], arg[2], body + } + + /^(Event|Key|Action)[ \t]/ { + addevent() + split($0, arg) + body = "" + } + /^[ \t]/ { + body = body"\n"$0 + } + + END { + addevent() + } +! +} + +_wi_text() { + eval "cat <<! +$(sed "$_sed" | sed '/^[ ]/s/\([$`]\)/\\\1/g') +" +} + +wi_events() { + _sed="" + if [ "$1" = -s ]; then + _sed="s/^$2//" + shift 2 + fi + eval "$(_wi_text | awk "$(_wi_script)")" +} + +wi_fatal() { + echo $scriptname: Fatal: $* + exit 1 +} + +wi_notice() { + xmessage $scriptname: Notice: $* +} + +wi_readctl() { + wmiir read /ctl | sed -n 's/^'$1' //p' +} + +wmiifont="$(wi_readctl font)" +wmiinormcol="$(wi_readctl normcolors)" +wmiifocuscol="$(wi_readctl focuscolors)" + +wi_menu() { + eval "wi_menu() { $WMII_MENU"' "$@"; }' + wi_menu "$@" +} +wi_9menu() { + eval "wi_9menu() { $WMII_9MENU"' "$@"; }' + wi_9menu "$@" +} + +wi_proglist() { + ls -lL $(echo $* | sed 'y/:/ /') 2>/dev/null \ + | awk '$1 ~ /^[^d].*x/ { print $NF }' \ + | sort | uniq +} + +wi_actions() { + { wi_proglist $WMII_CONFPATH + wi_getfuns Action + } | sort | uniq +} + +conf_which() { + which=$(which which) + prog=$(PATH="$WMII_CONFPATH" $which $1); shift + [ -n "$prog" ] && $prog "$@" +} + +wi_script() { + _noprog=true + if [ "$1" = -f ]; then + shift + _noprog=/dev/null + fi + which=$(which which) + _prog=$(PATH="$WMII_CONFPATH" $which $1 || echo $_noprog); shift + shift; echo "$_prog $*" +} + +wi_runcmd() { + if [ "$1" = -t ]; then + shift + set -- wihack -tags $(wmiir read /tag/sel/ctl | sed 1q) "$*" + fi + eval exec $* & +} + +wi_tags() { + wmiir ls /tag | sed 's,/,,; /^sel$/d' +} + +wi_eventloop() { + echo "$Keys" | wmiir write /keys + + wmiir read /event | while read wi_event + do + OIFS="$IFS"; IFS="$(echo)" + wi_args=$(echo "$wi_event" | sed 's/^[^ ]+ //') + IFS="$OIFS" + set -- $wi_event + event=$1; shift + Event_$event $@ + done 2>/dev/null +} + +wi_events <<'!' +Event Start + if [ "$1" = "$wmiiscript" ]; then + exit + fi +Event Key + fn=$(echo "$@" | sed 's/[^a-zA-Z_0-9]/_/g') + Key_$fn "$@" +! + +Action() { + action=$1; shift + if [ -n "$action" ]; then + Action_$action "$@" \ + || conf_which $action "$@" + fi +} + diff --git a/cmd/wmii/fns.h b/cmd/wmii/fns.h @@ -172,6 +172,7 @@ char* msg_sendclient(View*, IxpMsg*, bool swap); char* readctl_root(void); char* readctl_view(View*); Area* strarea(View*, const char*); +void warning(const char*, ...); /* mouse.c */ void mouse_resize(Client*, bool opaque, Align); diff --git a/cmd/wmii/message.c b/cmd/wmii/message.c @@ -164,7 +164,15 @@ msg_getword(IxpMsg *m) { m->pos += n; eatrunes(m, isspacerune, true); - if(ret == m->end) + /* Filter out comments. */ + if(*ret == '#') { + *ret = '\0'; + m->pos = m->end; + } + if(*ret == '\\') + if(ret[1] == '\\' || ret[1] == '#') + ret++; + if(*ret == '\0') return nil; return ret; } @@ -302,6 +310,8 @@ message_root(void *p, IxpMsg *m) { USED(p); ret = nil; s = msg_getword(m); + if(s == nil) + return nil; switch(getsym(s)) { case LBORDER: @@ -367,6 +377,8 @@ message_view(View *v, IxpMsg *m) { int i; s = msg_getword(m); + if(s == nil) + return nil; switch(getsym(s)) { case LCOLMODE: @@ -400,18 +412,6 @@ message_view(View *v, IxpMsg *m) { /* not reached */ } -static void -printdebug(void) { - int i, j; - - for(i=0, j=0; i < nelem(debugtab); i++) - Debug(1<<i) { - if(j++ > 0) - bufprint(" "); - bufprint("%s", debugtab[i]); - } -} - static char* msg_debug(IxpMsg *m) { char *opt; @@ -706,6 +706,18 @@ msg_sendframe(Frame *f, int sym, bool swap) { return nil; } +static void +printdebug(void) { + int i, j; + + for(i=0, j=0; i < nelem(debugtab); i++) + Debug(1<<i) { + if(j++ > 0) + bufprint(" "); + bufprint("%s", debugtab[i]); + } +} + char* readctl_root(void) { bufclear(); @@ -746,3 +758,17 @@ readctl_view(View *v) { return buffer; } +void +warning(const char *fmt, ...) { + va_list ap; + char *s; + + va_start(ap, fmt); + s = vsmprint(fmt, ap); + va_end(ap); + + event("Warning %s\n", s); + fprint(2, "%s: warning: %s\n", s); + free(s); +} + diff --git a/cmd/wmii/printevent.c b/cmd/wmii/printevent.c @@ -526,9 +526,9 @@ pevent(void *ev, ...) { Bflush(b); } -/******************************************************************************/ -/**** Routines to print out readable values for the field of various events ***/ -/******************************************************************************/ +/*****************************************************************************/ +/*** Routines to print out readable values for the field of various events ***/ +/*****************************************************************************/ static void VerbMotion(XEvent *e) { diff --git a/cmd/wmii/utf.c b/cmd/wmii/utf.c @@ -7,7 +7,7 @@ #include "fns.h" char* -toutf8n(char *str, size_t nstr) { +toutf8n(const char *str, size_t nstr) { static iconv_t cd; static bool haveiconv; char *buf, *pos; diff --git a/cmd/wmii/xext.c b/cmd/wmii/xext.c @@ -22,10 +22,8 @@ xext_init(void) { void xext_event(XEvent *e) { - if(have_RandR && (ulong)(e->type - randr_eventbase) < RRNumberEvents) { - e->type -= randr_eventbase; + if(have_RandR && (ulong)(e->type - randr_eventbase) < RRNumberEvents) randr_event(e); - } } void @@ -61,7 +59,7 @@ randr_screenchange(XRRScreenChangeNotifyEvent *ev) { void randr_event(XEvent *e) { - switch(e->type) { + switch(e->type-randr_eventbase) { default: break; case RRScreenChangeNotify: /* Yuck. */ diff --git a/cmd/wmiiloop.sh b/cmd/wmiiloop.sh @@ -1,43 +0,0 @@ -#!/bin/sh - -eval "text() { - cat <<! -$(sed '/^[[:blank:]]/s/\([$`]\)/\\\1/g') -! -}" - -script() { - cat <<'!' - BEGIN { - arg[1] = "Nop" - body = ""; - } - function addevent() { - if(arg[1] == "Key") - keys[arg[2]] = 1; - - var = arg[1] "s" - printf "%s=\"$%s %s\"\n", var, var, arg[2] - - gsub("[^a-zA-Z_0-9]", "_", arg[2]); - if(body != "") - printf "%s_%s() { %s\n }\n", arg[1], arg[2], body - } - - /^(Event|Key|Action)[ \t]/ { - addevent() - split($0, arg) - body = "" - } - /^[ \t]/ { - body = body"\n"$0 - } - - END { - addevent() - } -! -} - -text | awk "`script`" - diff --git a/config.mk b/config.mk @@ -1,6 +1,6 @@ # Customize below to fit your system -# paths +# Paths PREFIX = /usr/local BIN = $(PREFIX)/bin MAN = $(PREFIX)/share/man @@ -31,7 +31,6 @@ P9PATHS = ${PLAN9}:"'$${HOME}/plan9'":/usr/local/plan9:/usr/local/9:/opt/plan9:/ INCX11 = -I/usr/X11R6/include LIBX11 = -L/usr/X11R6/lib -lX11 LIBICONV = # Leave blank if your libc includes iconv (glibc does) -LIBIXP = $(ROOT)/libixp/libixp.a LIBIXP = $(LIBDIR)/libixp.a # Operating System Configurations @@ -39,7 +38,7 @@ LIBIXP = $(LIBDIR)/libixp.a # *BSD #LIBICONV = -liconv # +Darwin -#STATIC = # Darwon doesn't like static linking +#STATIC = # Darwin doesn't like static linking # Solaris #CFLAGS = -fast $(INCS) diff --git a/mk/hdr.mk b/mk/hdr.mk @@ -84,6 +84,13 @@ LINKSO= LD="$(LD)" LDFLAGS="$(SOLDFLAGS)" $(ROOT)/util/link CLEANNAME=$(ROOT)/util/cleanname include $(ROOT)/config.mk + +# I hate this. +MKCFGSH=if test -f $(ROOT)/config.local.mk; then echo $(ROOT)/config.local.mk; else echo /dev/null; fi +MKCFG:=${shell $(MKCFGSH)} +MKCFG!=${MKCFGSH} +include $(MKCFG) + CFLAGS += -I$$(echo $(INCPATH)|sed 's/:/ -I/g') include $(ROOT)/mk/common.mk diff --git a/rc/rc.wmii.rc b/rc/rc.wmii.rc @@ -12,6 +12,10 @@ DOWN=j LEFT=h RIGHT=l +# Bars +noticetimeout=5 +noticebar=/rbar/!notice + # Theme wmiifont='drift,-*-fixed-*-*-*-*-9-*-*-*-*-*-*-*' wmiifont='-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*' @@ -25,14 +29,12 @@ WMII_TERM=(xterm) # Column Rules wmiir write /colrules <<! /gimp/ -> 17+83+41 -/./ -> 62+38 # Golden Ratio +/.*/ -> 62+38 # Golden Ratio ! # Tagging Rules wmiir write /tagrules <<! -/VLC/ -> ~ -/XMMS.*/ -> ~ -/MPlayer.*/ -> ~ +/MPlayer|VLC/ -> ~ ! # Status Bar Info @@ -43,7 +45,15 @@ fn status { # End Configuration -ifs='' {nl=`{echo}} +# For the time being, this file follows the lisp bracing +# convention. i.e.: +# if(frob this) { +# frob that +# if(frob theother) { +# unfrob this +# unfrob that}} +# Comments welcome. + confpath=`{echo $WMII_CONFPATH | sed 'y/:/ /'} # Events @@ -52,12 +62,18 @@ fn sigexit { wi_cleankeys } -fn Event-CreateTag { echo $wmiinormcol $* | wmiir create /lbar/$"* } -fn Event-DestroyTag { wmiir remove /lbar/$"* } -fn Event-FocusTag { wmiir xwrite /lbar/$"* $wmiifocuscol $* } -fn Event-UnfocusTag { wmiir xwrite /lbar/$"* $wmiinormcol $* } -fn Event-UrgentTag { shift; wmiir xwrite /lbar/$"* '*'$"* } -fn Event-NotUrgentTag { shift; wmiir xwrite /lbar/$"* $"* } +fn Event-CreateTag { + echo $wmiinormcol $* | wmiir create /lbar/$"*} +fn Event-DestroyTag { + wmiir remove /lbar/$"*} +fn Event-FocusTag { + wmiir xwrite /lbar/$"* $wmiifocuscol $*} +fn Event-UnfocusTag { + wmiir xwrite /lbar/$"* $wmiinormcol $*} +fn Event-UrgentTag { + shift; wmiir xwrite /lbar/$"* '*'$"*} +fn Event-NotUrgentTag { + shift; wmiir xwrite /lbar/$"* $"*} fn Event-Unresponsive { client = $1; shift @@ -65,13 +81,19 @@ fn Event-Unresponsive { msg = 'The following client is not responding. What would you like to do?' resp = `{wihack -transient $client \ xmessage -nearmouse -buttons Kill,Wait -print \ - $msg $nl '' `{wmiir read /client/sel/label}} + $msg $wi_nl '' `{wmiir read /client/sel/label}} if(~ $resp Kill) - wmiir xwrite /client/$client/ctl slay - }& -} + wmiir xwrite /client/$client/ctl slay }&} +echo $wmiinormcol | wmiir create $noticebar +fn Event-Notice { + wmiir xwrite $noticebar $wi_arg -fn Event-LeftBarClick { shift; wmiir xwrite /ctl view $* } + /bin/kill $xpid >[2]/dev/null # Let's hope this isn't reused... + { sleep $noticetimeout; wmiir xwrite $noticebar ' ' }& # Bug... + xpid = $apid} + +fn Event-LeftBarClick { + shift; wmiir xwrite /ctl view $*} fn Event-ClientMouseDown { client = $1; button = $2 if(~ $button 3) { @@ -83,33 +105,20 @@ fn Event-ClientMouseDown { wmiir xwrite /client/$client/ctl Fullscreen on } if(! ~ $do '') - menulast = $do; - } -} + menulast = $do;}} menulast = Nop -# Utility -fn 'fn?' {rc -c 'whatis '$1 >[2]/dev/null | grep -s '^fn ' } - # Actions -fn Action { - cmd=$1 action=Action-$cmd { shift - if('fn?' $action) - $action $* - if not - wi_runcmd `{wi_script $cmd} $* - } & -} - fn Action-rehash { comm -23 <{ls $WMII_NS_DIR/proglist.* >[2]/dev/null | awk -F'\.' '{print $NF}'} \ <{ps | awk '{print $2}'} | while(id=`{read}) rm $WMII_NS_DIR/proglist.$id - wi_proglist $PATH >$progs_file -} -fn Action-quit { wmiir xwrite /ctl quit } -fn Action-exec { wmiir xwrite /ctl exec $* } + wi_proglist $PATH >$progs_file} +fn Action-quit { + wmiir xwrite /ctl quit} +fn Action-exec { + wmiir xwrite /ctl exec $*} fn Action-status { flag x -; flag r - if(wmiir remove /rbar/status >[2]/dev/null) @@ -123,14 +132,13 @@ fn Action-status { if(~ $0 rc.wmii.local */rc.wmii.local) wi_notice This file should not be named rc.wmii.local if not - . `{wi_script rc.wmii.local} /dev/null + . `{wi_script -f rc.wmii.local} # Key Bindings fn key { key=() - for(k in Key-$*) if(! 'fn?' $k) key = ($key $k) - ~ $#key 0 -} + for(k in Key-$*) if(! wi_fn-p $k) key = ($key $k) + ~ $#key 0} # This is... ugly. @@ -143,47 +151,62 @@ key $MODKEY-Control-t || fn $key { ifs=() { keys=`{wmiir read /keys} } wmiir xwrite /keys $MODKEY-Control-t wmiir xwrite /ctl grabmod Mod3 - } -} - -key $MODKEY-$LEFT || fn $key { wmiir xwrite /tag/sel/ctl select left } -key $MODKEY-$RIGHT || fn $key { wmiir xwrite /tag/sel/ctl select right } -key $MODKEY-$DOWN || fn $key { wmiir xwrite /tag/sel/ctl select down } -key $MODKEY-$UP || fn $key { wmiir xwrite /tag/sel/ctl select up } - -key $MODKEY-Shift-$LEFT || fn $key { wmiir xwrite /tag/sel/ctl send sel left } -key $MODKEY-Shift-$RIGHT || fn $key { wmiir xwrite /tag/sel/ctl send sel right } -key $MODKEY-Shift-$DOWN || fn $key { wmiir xwrite /tag/sel/ctl send sel down } -key $MODKEY-Shift-$UP || fn $key { wmiir xwrite /tag/sel/ctl send sel up } - -key $MODKEY-f || fn $key { wmiir xwrite /client/sel/ctl Fullscreen toggle } - -key $MODKEY-space || fn $key { wmiir xwrite /tag/sel/ctl select toggle } -key $MODKEY-Shift-space || fn $key { wmiir xwrite /tag/sel/ctl send sel toggle } -key $MODKEY-d || fn $key { wmiir xwrite /tag/sel/ctl colmode sel default } -key $MODKEY-s || fn $key { wmiir xwrite /tag/sel/ctl colmode sel stack } -key $MODKEY-m || fn $key { wmiir xwrite /tag/sel/ctl colmode sel max } - -key $MODKEY-Shift-c || fn $key { wmiir xwrite /client/sel/ctl kill } - -key $MODKEY-a || fn $key { Action `{wi_actions | wi_menu} & } -key $MODKEY-p || fn $key { ifs=() { wi_runcmd -t `{wi_menu <$progs_file} & } } -key $MODKEY-Return || fn $key { wi_runcmd $WMII_TERM & } - -key $MODKEY-t || fn $key { wmiir xwrite /ctl view `{wi_tags | wi_menu} & } + }} + +key $MODKEY-$LEFT || fn $key { + wmiir xwrite /tag/sel/ctl select left} +key $MODKEY-$RIGHT || fn $key { + wmiir xwrite /tag/sel/ctl select right} +key $MODKEY-$DOWN || fn $key { + wmiir xwrite /tag/sel/ctl select down} +key $MODKEY-$UP || fn $key { + wmiir xwrite /tag/sel/ctl select up} + +key $MODKEY-Shift-$LEFT || fn $key { + wmiir xwrite /tag/sel/ctl send sel left} +key $MODKEY-Shift-$RIGHT || fn $key { + wmiir xwrite /tag/sel/ctl send sel right} +key $MODKEY-Shift-$DOWN || fn $key { + wmiir xwrite /tag/sel/ctl send sel down} +key $MODKEY-Shift-$UP || fn $key { + wmiir xwrite /tag/sel/ctl send sel up} + +key $MODKEY-f || fn $key { + wmiir xwrite /client/sel/ctl Fullscreen toggle} + +key $MODKEY-space || fn $key { + wmiir xwrite /tag/sel/ctl select toggle} +key $MODKEY-Shift-space || fn $key { + wmiir xwrite /tag/sel/ctl send sel toggle} +key $MODKEY-d || fn $key { + wmiir xwrite /tag/sel/ctl colmode sel default} +key $MODKEY-s || fn $key { + wmiir xwrite /tag/sel/ctl colmode sel stack} +key $MODKEY-m || fn $key { + wmiir xwrite /tag/sel/ctl colmode sel max} + +key $MODKEY-Shift-c || fn $key { + wmiir xwrite /client/sel/ctl kill} + +key $MODKEY-a || fn $key { + Action `{wi_actions | wi_menu} &} +key $MODKEY-p || fn $key { + ifs=() { wi_runcmd -t `{wi_menu <$progs_file} & }} +key $MODKEY-Return || fn $key { + wi_runcmd $WMII_TERM &} + +key $MODKEY-t || fn $key { + wmiir xwrite /ctl view `{wi_tags | wi_menu} &} key $MODKEY-Shift-t || fn $key { sel = `{wmiir read /client/sel/ctl | sed 1q} \ - wmiir xwrite /client/$sel/tags `{wi_tags | wi_menu} & -} + wmiir xwrite /client/$sel/tags `{wi_tags | wi_menu} &} key $MODKEY-^`{seq 0 9} || fn $key { - wmiir xwrite /ctl view `{echo $1 | sed 's/.*-//'} -} + wmiir xwrite /ctl view `{echo $1 | sed 's/.*-//'}} key Shift-$MODKEY-^`{seq 0 9} || fn $key { - wmiir xwrite /client/sel/tags `{echo $1 | sed 's/.*-//'} -} + wmiir xwrite /client/sel/tags `{echo $1 | sed 's/.*-//'}} -# WM Configuration +#` WM Configuration wmiir write /ctl <<! view 1 grabmod $MODKEY @@ -203,16 +226,16 @@ Action status Action rehash # Tag Bar Setup -ifs=$nl{ - wmiir rm `{comm -23 <{wmiir ls /lbar} <{wi_tags}} +ifs=$wi_nl{ + oldbars=`{comm -23 <{wmiir ls /lbar} <{wi_tags}} + if(! ~ $oldbars '') + wmiir rm /lbar/^$oldbars seltag=`{wmiir read /tag/sel/ctl | sed 1q} for(tag in `{wi_tags}) { if(~ $tag $seltag) echo $wmiifocuscol $tag | wmiir create /lbar/$tag if not - echo $wmiinormcol $tag | wmiir create /lbar/$tag - } -} + echo $wmiinormcol $tag | wmiir create /lbar/$tag}} wi_eventloop diff --git a/rc/wmiirc.sh b/rc/wmiirc.sh @@ -1,5 +1,6 @@ #!/bin/sh -f # Configure wmii +. wmii.sh wmiirc # Configuration Variables MODKEY=Mod1 @@ -9,28 +10,26 @@ LEFT=h RIGHT=l # Colors tuples: "<text> <background> <border>" -WMII_NORMCOLORS='#222222 #5FBF77 #2A7F3F' -WMII_FOCUSCOLORS='#ffffff #153F1F #2A7F3F' +WMII_NORMCOLORS='#000000 #c1c48b #81654f' +WMII_FOCUSCOLORS='#000000 #81654f #000000' WMII_BACKGROUND='#333333' WMII_FONT='-*-fixed-medium-r-*-*-13-*-*-*-*-*-*-*' set -- $(echo $WMII_NORMCOLORS $WMII_FOCUSCOLORS) -WMII_MENU='dmenu -b -fn "$WMII_FONT" -nf '"$1 -nb $2 -sf $4 -sb $5" -WMII_9MENU='wmii9menu -font "$WMII_FONT" -nf '"$1 -nb $2 -sf $4 -sb $5 -br $6" +WMII_MENU='dmenu -b -fn "$WMII_FONT" -nf '"'$1' -nb '$2' -sf '$4' -sb '$5'" +WMII_9MENU='wmii9menu -font "$WMII_FONT" -nf '"'$1' -nb '$2' -sf '$4' -sb '$5' -br '$6'" WMII_TERM="xterm" # Column Rules wmiir write /colrules <<! -/.*/ -> 58+42 +/gimp/ -> 17+83+41 +/.*/ -> 62+38 # Golden Ratio ! # Tagging Rules wmiir write /tagrules <<! -/XMMS.*/ -> ~ -/MPlayer.*/ -> ~ -/.*/ -> sel -/.*/ -> 1 +/MPlayer|VLC/ -> ~ ! # Status Bar Info @@ -39,19 +38,8 @@ status() { } # Event processing -# Processed later by `wmiiloop' and evaled. -# Uncomment the line before the eval and run for details. -eventstuff() { - cat <<'!' +wi_events -s ' ' <<'!' # Events - Event Start - case "$1" in - wmiirc) - exit; - esac - Event Key - fn=$(echo "$@" | sed 's/[^a-zA-Z_0-9]/_/g') - Key_$fn "$@" Event CreateTag echo "$WMII_NORMCOLORS" "$@" | wmiir create "/lbar/$@" Event DestroyTag @@ -89,7 +77,7 @@ eventstuff() { client=$1; button=$2 case "$button" in 3) - do=$(eval $WMII_9MENU -initial "${menulast:-SomeRandomName}" Nop Delete Fullscreen) + do=$(wi_9menu -initial "${menulast:-SomeRandomName}" Nop Delete Fullscreen) case "$do" in Delete) wmiir xwrite /client/$client/ctl kill;; @@ -102,7 +90,7 @@ eventstuff() { Key $MODKEY-Control-t case $(wmiir read /keys | wc -l | tr -d ' \t\n') in 0|1) - echo -n $Keys | tr ' ' '\012' | wmiir write /keys + echo -n "$Keys" | wmiir write /keys wmiir xwrite /ctl grabmod $MODKEY;; *) wmiir xwrite /keys $MODKEY-Control-t @@ -117,11 +105,11 @@ eventstuff() { Key $MODKEY-m wmiir xwrite /tag/sel/ctl colmode sel max Key $MODKEY-a - Action $(actionlist | eval $WMII_MENU) & + Action $(wi_actions | wi_menu) & Key $MODKEY-p - sh -c "$(eval $WMII_MENU <$progsfile)" & + sh -c "$(wi_menu <$progsfile)" & Key $MODKEY-t - wmiir xwrite /ctl "view $(tagsmenu)" & + wmiir xwrite /ctl "view $(wi_tags | wi_menu)" & Key $MODKEY-Return eval $WMII_TERM & Key $MODKEY-Shift-space @@ -131,7 +119,7 @@ eventstuff() { Key $MODKEY-Shift-c wmiir xwrite /client/sel/ctl kill Key $MODKEY-Shift-t - wmiir xwrite "/client/$(wmiir read /client/sel/ctl)/tags" "$(tagsmenu)" & + wmiir xwrite "/client/$(wmiir read /client/sel/ctl)/tags" "$(wi_tags | wi_menu)" & Key $MODKEY-$LEFT wmiir xwrite /tag/sel/ctl select left Key $MODKEY-$RIGHT @@ -150,59 +138,37 @@ eventstuff() { wmiir xwrite /tag/sel/ctl send sel up ! for i in 0 1 2 3 4 5 6 7 8 9; do - cat <<! + wi_events -s ' ' <<! Key $MODKEY-$i wmiir xwrite /ctl view "$i" Key $MODKEY-Shift-$i wmiir xwrite /client/sel/tags "$i" ! done -} # WM Configuration -wmiir write /ctl << EOF -font $WMII_FONT -focuscolors $WMII_FOCUSCOLORS -normcolors $WMII_NORMCOLORS -grabmod $MODKEY -border 1 -EOF +wmiir write /ctl <<! + view 1 + font $WMII_FONT + focuscolors $WMII_FOCUSCOLORS + normcolors $WMII_NORMCOLORS + grabmod $MODKEY + border 1 +! +xsetroot -solid "$WMII_BACKGROUND" & export WMII_MENU WMII_9MENU WMII_FONT WMII_TERM export WMII_FOCUSCOLORS WMII_SELCOLORS WMII_NORMCOLORS -# Feed events to `wmiiloop' for processing -eval "$(eventstuff | sed 's/^[ ]//' | { . wmiiloop; })" - -echo "$Keys" | tr ' ' '\n' | wmiir write /keys - -# Functions -Action() { - action=$1; shift - if [ -n "$action" ]; then - Action_$action "$@" \ - || conf_which $action "$@" - fi -} - -proglist() { - paths=$(echo "$@" | sed 'y/:/ /') - ls -lL $paths 2>/dev/null \ - | awk '$1 ~ /^[^d].*x/ { print $NF }' \ - | sort | uniq -} - # Misc progsfile="$WMII_NS_DIR/.proglist" Action status & -proglist $PATH >$progsfile & - -xsetroot -solid "$WMII_BACKGROUND" & +wi_proglist $PATH >$progsfile & # Setup Tag Bar -(IFS="$(echo)"; wmiir rm $(wmiir ls /lbar)) +(IFS="$(echo)"; wmiir rm $(wmiir ls /lbar | sed 's,^,/lbar/,')) seltag="$(wmiir read /tag/sel/ctl | sed 1q)" -wmiir ls /tag | sed -e 's|/||; /^sel$/d' | while read tag +wi_tags | while read tag do if [ "$tag" = "$seltag" ]; then echo "$WMII_FOCUSCOLORS" "$tag" @@ -211,30 +177,5 @@ do fi | wmiir create "/lbar/$tag" done -# More functions -tagsmenu() { - wmiir ls /tag | sed 's|/||; /^sel$/d' | eval $WMII_MENU -} - -actionlist() { - { proglist $WMII_CONFPATH - echo -n $Actions | tr ' ' '\012' - } | sort | uniq -} - -conf_which() { - which=$(which which) - prog=$(PATH="$WMII_CONFPATH" $which $1); shift - [ -n "$prog" ] && $prog "$@" -} - -# Stop any running instances of wmiirc -echo Start wmiirc | wmiir write /event || exit 1 - -wmiir read /event | while read event -do - set -- $event - event=$1; shift - Event_$event $@ -done 2>/dev/null +wi_eventloop diff --git a/util/genconfig b/util/genconfig @@ -1,21 +1,52 @@ #!/bin/sh -f +# What I wouldn't do for rc... +# Well... it's better than m4shgmake. + CONFIG="$ROOT/config.mk" CONFSTR='# Generated by "make config"' +# ==================== The Messy Part ==================== + #XXX Ignores lines ending in \ parseconfig() { - cat <<! - /^$CONFSTR/ {exit} + cat <<'!' | sed "s/CONFSTR/$CONFSTR/" + /^CONFSTR/ {exit} /^( *#| )/ {next} -! - cat <<'!' - /=/ { + function fixup() { + sub(/ #.*/, "") + sub(/^ */, "") gsub(/'/, "'\"'\"'") - sub(/[ ]*=[ ]*/, "='") - print $0"'" - sub(/=.*/, "") - print $0"_orig=\"$"$0"\"" + sub(/[ ]*\+?=[ ]*/, "='") + sub(/[ ]*$/, "'") + var = $0 + val = $0 + sub(/\+?=.*/, "", var) + sub(/^[^=]+=/, "", val) + } + /\+=/ && !/^ / { + fixup() + if(!set[var]) { + print var"=''" + append[var]++ + } + print var"=\"$" var " \"" val + print var"_orig=\"$" var "\"" + next + } + /=/ && !/^ / { + fixup() + delete append[var] + set[var]++ + + print var"="val + print var"_orig=\"$" var "\"" + } + END{ + for(v in set) + print v "_append=''" + for(v in append) + print v "_append=true" } ! } @@ -24,38 +55,63 @@ findinc() { var="$1"; file="$2"; shift 2 for d in "$@"; do if [ -d "$d" -a -f "$d/$file" ]; then - eval "$var=\"-I$d\""; break; fi - done + eval "$var=\"-I$d\"" + break; fi; done } +soext=.so +aext=.a findlib() { var="$1"; lib="$2"; shift 2 for d in "$@"; do if [ -d "$d" -a -f "$d/$lib.so" -o -f "$d/lib$lib.a" ]; then - eval "$var=\"-L$d -l$lib\""; break; fi - done + _libdir="$d"; _libname="$lib" + eval "$var=\"-L$d -l$lib\"" + break; fi; done +} + +expand() { + _expand="$@"; _expand_old='' + while [ "$_expand" != "$_expand_old" ]; do + _expand_old="$_expand" + eval "_expand=\"$_expand\""; done + echo -n "$_expand" +} + +cfg() { + CFG="$CFG +$@" +} + +equals() { + if [ -z "$append" ]; then + echo -n "="; + else + echo -n "+="; fi } prompt() { var=$1; shift - eval "def=\$$var; orig=\$${var}_orig" + eval "def=\$$var; orig=\$${var}_orig; append=\$${var}_append" unset val if [ -z "$def" -o -n "$force" ]; then echo "$@" - read -p "$var[$def]= " val + read -p "$var[$def]$(equals) " val echo fi if [ -z "$val" ]; then val="$def"; fi - if [ "$val" != "$orig" ]; then - CFG="$CFG -$var=$val"; fi + if [ "$(expand $val)" != "$(expand "$orig")" ]; then + cfg "$var$(equals)$val"; fi } -eval "$(awk "`parseconfig`" <"$CONFIG")" +# The messy sed... Turns $(VAR) into ${VAR}, but not $$(VAR) into $${VAR} +eval "$(sed 's/\([^$]\)\$(\([A-Za-z_]*\))/\1${\2}/g' <"$CONFIG" | awk "`parseconfig`")" CFG="$(sed -n "/^$CONFSTR/q; p" "$CONFIG"; echo "$CONFSTR")" +# ==================== The Fun Part ==================== + cat <<! Configuring for the wmii build. @@ -66,7 +122,7 @@ in which case, you may simply press return to accept them. ! # Guess... -AWKPATH=`which awk` +AWKPATH=$(which awk 2>/dev/null) prompt AWKPATH "Full path to your system's 'awk' program" prompt PLAN9 "Path of a Plan 9 Port or 9base installation" @@ -74,57 +130,101 @@ prompt PLAN9 "Path of a Plan 9 Port or 9base installation" force=1 prompt PREFIX Installation prefix +echo echo "Compilation details (if you don't understand these, just leave the defaults)" +echo prompt CC C object compiler prompt LD 'Linker (this should normally not be "ld")' +set -- $CC +if $1 -v 2>&1 | grep 'gcc version' >/dev/null; then + echo -n You appear to be using gcc. Is this correct? '[yes] ' + while :; do + read resp + case "$resp" in + [Yy][Ee][Ss]|'') + cfg 'include $(ROOT)/mk/gcc.mk' + break;; + [Nn][Oo]) + cfg 'CFLAGS=""' + # Not perfect. Botches system cflags, but we + # need to ditch the gcc ones. + break;; + *) + echo -n 'Please answer yes or no: ' + esac + done + echo +fi + prompt INCPATH Search path for include files prompt LIBS Libraries to be linked with every executable prompt CFLAGS Flags for the C compiler prompt LDFLAGS Flags for the linker -prompt STATIC Extra linker flags to produce a static executable +case $(uname -s) in + [Dd]arwin) cfg 'STATIC=""';; + *) prompt STATIC Extra linker flags to produce a static executable;; +esac unset force # Make some guesses -#for i in LIBX11 LIBICONV LIBIXP INCX11; do -# eval "unset $i ${i}_orig"; done +# Extract the -L paths from ldflags. +ldlibs="$(awk 'BEGIN{ + for(i=1; i <= ARGC; i++) + if(ARGV[i] ~ /-L/) + print ":" substr(ARGV[i], 3) + }' $LDFLAGS)" +# Turn include paths into ../lib paths. +inclibs="$(expand "$INCPATH"|sed 's,/include:,/lib:,g; s,/include$,/lib,')" +# Lace them all together, and expand them. +libs="$(expand "$LIBDIR:$ldlibs:$inclibs:/usr/local/lib:/opt/local/lib")" -libs="$LIBDIR:$(echo "$INCPATH"|sed 's,/include\(:\|$\),/lib\1,g')" -libs="$libs$(echo "$LDFLAGS"|sed 's,-L\([^ ]*\),:\1,g')" -libs="$libs:/usr/local/lib:/opt/local/lib" -eval "libs=\"$libs\"" LIBIXP=${LIBIXP%/libixp.a} INCPATH="$INCPATH:/usr/local/include:/opt/local/include" +incpath="$(expand "$INCPATH")" -oifs="$IFS" -IFS=: -findinc INCX11 X11/Xlib.h $INCPATH \ +oifs="$IFS"; IFS=: +findinc INCX11 X11/Xlib.h $incpath \ /usr/X11R6/include /usr/x11/include /usr/x11/include /usr/X11/include \ /usr/openwin/include /opt/x11/include /opt/X11/include -findinc INCICONV iconv.h $INCPATH +findinc INCICONV iconv.h $incpath findlib LIBX11 X11 $libs \ /usr/X11R6/lib /usr/X11/lib /usr/openwin/lib /usr/x11/lib \ /opt/X11 /opt/x11 /usr/local/lib /opt/local/lib findlib LIBICONV iconv $libs -findlib LIBIXP ixp "$ROOT/lib" $libs -[ -e "$ROOT/libixp" ] && LIBIXP="$ROOT/lib/libixp.a" -LIBIXP=$(echo "$LIBIXP"|sed 's,^-L\([^ ]*\) -l\([^ ]*\)$,\1/lib\2.a,') + +if [ -d "$ROOT/libixp" ]; then + _libdir="$ROOT/lib"; else + soext=.a findlib LIBIXP ixp "$ROOT/lib" $libs; fi +LIBIXP="$_libdir/libixp.a" IFS="$oifs" # Back to prompting echo Library paths... prompt INCX11 Compiler flags to find X11 includes prompt LIBX11 Linker flags to link against libX11 -# Yuck... -if nm -D `ldd /bin/sh | awk '$1 ~ /^libc\.so/ {print $3}'` | - awk '$2 == "T" && $3 == "iconv" {exit 0}; END {exit 1}' + +# Find out if the system libc includes iconv... +# GNU systems tend to make /usr/lib/libc.so or /lib/libc.so +# linker scripts rather than libraries, so I can't parse them. +# As a kludge, I ask ldd what actual libc.so /bin/sh links to, +# which is pretty reliable. It's very unlikely that anyone will +# actually be prompted for this. +# I suppose the auto*hell way would be to just compile +# something against libc. Perhaps another day. +if nm -D $(ldd /bin/sh | awk '$1 ~ /^libc\.so/ {print $3}') | + awk -ve=1 '$2 == "T" && $3 == "iconv" {e=0; exit}; END {exit e}' then - echo "Your system's libc appears to contain iconv" + echo + echo "Your system's libc appears to include iconv." + echo +else + prompt LIBICONV Linker flags to link agains libiconv \ + '(may be left blank if iconv is part of your system libc)' fi -prompt LIBICONV Linker flags to link agains libiconv '(may be left blank if iconv is part of your system libc)' prompt INCICONV Compiler flags to find iconv.h prompt LIBIXP Path to libixp.a @@ -132,3 +232,4 @@ echo Writing config.mk echo "$CFG " >config.mk echo Done. +