mirror of
https://github.com/0intro/wmii
synced 2024-11-24 06:39:47 +03:00
Change format of bar files. Refactor fs.c. Add M-n/M-b to rc scripts. Add showkeys to plan9port rc. Update docs. Linkify code fragments in wmii.tex.
This commit is contained in:
parent
ec18eb22e9
commit
68b77ab4e8
@ -61,8 +61,8 @@ wmiir write /rules <<!
|
||||
|
||||
# Status Bar Info
|
||||
fn status {
|
||||
echo -n `{uptime | sed 's/.*://; s/,//g'} '|' \
|
||||
`{date} }
|
||||
echo -n label `{uptime | sed 's/.*://; s/,//g'} '|' \
|
||||
`{date} }
|
||||
|
||||
# Generic overridable startup details
|
||||
fn startup { witray & }
|
||||
@ -86,19 +86,19 @@ fn sigexit {
|
||||
wi_cleankeys}
|
||||
|
||||
fn Event-CreateTag {
|
||||
echo $wmiinormcol $* | wmiir create /lbar/$"*}
|
||||
echo colors $wmiinormcol $wi_newline label $* | wmiir create /lbar/$"*}
|
||||
fn Event-DestroyTag {
|
||||
wmiir remove /lbar/$"*}
|
||||
fn Event-FocusTag {
|
||||
wmiir xwrite /lbar/$"* $wmiifocuscol $*}
|
||||
wmiir xwrite /lbar/$"* colors $wmiifocuscol}
|
||||
fn Event-UnfocusTag {
|
||||
wmiir xwrite /lbar/$"* $wmiinormcol $*}
|
||||
wmiir xwrite /lbar/$"* colors $wmiinormcol}
|
||||
fn Event-UrgentTag {
|
||||
shift
|
||||
wmiir xwrite /lbar/$"* '*'$"*}
|
||||
wmiir xwrite /lbar/$"* label '*'$"*}
|
||||
fn Event-NotUrgentTag {
|
||||
shift
|
||||
wmiir xwrite /lbar/$"* $"*}
|
||||
wmiir xwrite /lbar/$"* label $"*}
|
||||
fn Event-AreaFocus {
|
||||
if(~ $1 '~')
|
||||
setbackground $wmiifloatbackground
|
||||
@ -116,7 +116,7 @@ fn Event-Unresponsive {
|
||||
wmiir xwrite /client/$client/ctl slay
|
||||
}&}
|
||||
fn Event-Notice {
|
||||
wmiir xwrite $noticebar $wi_arg
|
||||
wmiir xwrite $noticebar label $wi_arg
|
||||
|
||||
/bin/kill $xpid >[2]/dev/null # Let's hope this isn't reused...
|
||||
{ sleep $noticetimeout; wmiir xwrite $noticebar ' ' }& # Bug...
|
||||
@ -152,21 +152,24 @@ fn Event-LeftBarMouseDown {
|
||||
wi_fnmenu LBar $* &}
|
||||
|
||||
# Actions
|
||||
fn Action-exec {
|
||||
wmiir xwrite /ctl exec $*}
|
||||
fn Action-quit {
|
||||
wmiir xwrite /ctl quit}
|
||||
fn Action-rehash {
|
||||
comm -23 <{ls `{namespace}^/proglist.* >[2]/dev/null | awk -F'.' '{print $NF}'} \
|
||||
<{ps | awk '{print $2}'} |
|
||||
while(id=`{read})
|
||||
rm `{namespace}^/proglist.$id
|
||||
wi_proglist $PATH >$progs_file}
|
||||
fn Action-quit {
|
||||
wmiir xwrite /ctl quit}
|
||||
fn Action-exec {
|
||||
wmiir xwrite /ctl exec $*}
|
||||
fn Action-showkeys {
|
||||
echo $wmiikeyhelp | xmessage -file -
|
||||
}
|
||||
fn Action-status {
|
||||
flag x -; flag r -
|
||||
if(wmiir remove /rbar/status >[2]/dev/null)
|
||||
sleep 2
|
||||
echo $wmiinormcol | wmiir create /rbar/status
|
||||
echo colors $wmiinormcol | wmiir create /rbar/status
|
||||
while(status | wmiir write /rbar/status)
|
||||
sleep 1
|
||||
}
|
||||
@ -181,14 +184,77 @@ startup
|
||||
|
||||
# Key Bindings
|
||||
_keys = `{wi_getfuns Key}
|
||||
fn keygroup {
|
||||
wmiikeyhelp = $wmiikeyhelp ^ $wi_newline ^ ' ' ^ $"* ^ $wi_newline}
|
||||
fn key {
|
||||
help=$1; shift
|
||||
key=()
|
||||
for(k) if(! ~ $k $_keys) key = ($key Key-$k)
|
||||
for(k) {
|
||||
if(! ~ $k $_keys) {
|
||||
ifs=() { wmiikeyhelp = `{awk 'BEGIN {
|
||||
printf "%s %- 20s %s\n", ENVIRON["wmiikeyhelp"], ENVIRON["k"], ENVIRON["help"]
|
||||
exit }'} }
|
||||
key = ($key Key-$k)}}
|
||||
~ $#key 0}
|
||||
|
||||
# This is... ugly.
|
||||
keygroup Moving around
|
||||
key 'Select the client to the left' $MODKEY-$LEFT || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl select left}
|
||||
key 'Select the client to the right' $MODKEY-$RIGHT || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl select right}
|
||||
key 'Select the client below' $MODKEY-$DOWN || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl select down}
|
||||
key 'Select the client above' $MODKEY-$UP || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl select up}
|
||||
|
||||
key $MODKEY-Control-t || fn $key {
|
||||
key 'Toggle between floating and managed layers' $MODKEY-space || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl select toggle}
|
||||
|
||||
keygroup Moving through stacks
|
||||
key 'Select the stack below' $MODKEY-Control-$DOWN || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl select down stack}
|
||||
key 'Select the stack above' $MODKEY-Control-$UP || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl select up stack}
|
||||
|
||||
keygroup Moving clients around
|
||||
key 'Move selected client to the left' $MODKEY-Shift-$LEFT || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl send sel left}
|
||||
key 'Move selected client to the right' $MODKEY-Shift-$RIGHT || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl send sel right}
|
||||
key 'Move selected client down' $MODKEY-Shift-$DOWN || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl send sel down}
|
||||
key 'Move selected client up' $MODKEY-Shift-$UP || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl send sel up}
|
||||
|
||||
key 'Toggle selected client between floating and managed layers' $MODKEY-Shift-space || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl send sel toggle}
|
||||
|
||||
keygroup Client actions
|
||||
key 'Toggle selected client''s fullsceen state' $MODKEY-f || fn $key {
|
||||
wmiir xwrite /client/sel/ctl Fullscreen toggle}
|
||||
key 'Close client' $MODKEY-Shift-c || fn $key {
|
||||
wmiir xwrite /client/sel/ctl kill}
|
||||
|
||||
keygroup Changing column modes
|
||||
key 'Set column to default mode' $MODKEY-d || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl colmode sel default-max}
|
||||
key 'Toggle between floating and managed layers' $MODKEY-s || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl colmode sel stack-max}
|
||||
key 'Set column to max mode' $MODKEY-m || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl colmode sel stack+max}
|
||||
|
||||
keygroup Running programs
|
||||
key 'Open wmii actions menu' $MODKEY-a || fn $key {
|
||||
Action `{wi_actions | wimenu -h $hist.action -n $histlen} &}
|
||||
key 'Open program menu' $MODKEY-p || fn $key {
|
||||
ifs=() { cmd = `{wimenu -h $hist.prog -n $histlen <$progs_file} }
|
||||
wi_runcmd $cmd & }
|
||||
|
||||
key 'Launch a terminal' $MODKEY-Return || fn $key {
|
||||
wi_runcmd $WMII_TERM &}
|
||||
|
||||
keygroup Other
|
||||
key 'Toggle all other key bindings' $MODKEY-Control-t || fn $key {
|
||||
switch(`{wmiir read /keys | wc -l}) {
|
||||
case 0 1
|
||||
wmiir xwrite /keys $keys
|
||||
@ -199,66 +265,22 @@ key $MODKEY-Control-t || fn $key {
|
||||
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-Control-$DOWN || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl select down stack}
|
||||
key $MODKEY-Control-$UP || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl select up stack}
|
||||
|
||||
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-max}
|
||||
key $MODKEY-s || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl colmode sel stack-max}
|
||||
key $MODKEY-m || fn $key {
|
||||
wmiir xwrite /tag/sel/ctl colmode sel stack+max}
|
||||
|
||||
key $MODKEY-Shift-c || fn $key {
|
||||
wmiir xwrite /client/sel/ctl kill}
|
||||
|
||||
key $MODKEY-a || fn $key {
|
||||
Action `{wi_actions | wimenu -h $hist.action -n $histlen} &}
|
||||
key $MODKEY-p || fn $key {
|
||||
ifs=() { cmd = `{wimenu -h $hist.prog -n $histlen <$progs_file} }
|
||||
wi_runcmd $cmd & }
|
||||
|
||||
key $MODKEY-Return || fn $key {
|
||||
wi_runcmd $WMII_TERM &}
|
||||
|
||||
key $MODKEY-t || fn $key {
|
||||
keygroup Tag actions
|
||||
key 'Change to another tag' $MODKEY-t || fn $key {
|
||||
tag=`{wi_tags | wimenu -h $hist.tag -n 50} && wmiir xwrite /ctl view $tag &}
|
||||
key $MODKEY-Shift-t || fn $key {
|
||||
key 'Retag the selected client' $MODKEY-Shift-t || fn $key {
|
||||
sel=`{wi_selclient} {
|
||||
tag=`{wi_tags | wimenu -h $hist.tag -n 50} && wmiir xwrite /client/$sel/tags $tag } &}
|
||||
key 'Move to the next tag' $MODKEY-n || fn $key {
|
||||
wmiir xwrite /ctl view `{wi_tags | wi_nexttag}}
|
||||
key 'Move to the previous tag' $MODKEY-b || fn $key {
|
||||
wmiir xwrite /ctl view `{wi_tags | sort -r | wi_nexttag}}
|
||||
|
||||
key $MODKEY-^`{seq 0 9} || fn $key {
|
||||
key 'Move to the numbered view' $MODKEY-^`{seq 0 9} || fn $key {
|
||||
wmiir xwrite /ctl view `{echo $1 | sed 's/.*-//'}}
|
||||
key Shift-$MODKEY-^`{seq 0 9} || fn $key {
|
||||
key 'Retag selected client with the numbered tag' Shift-$MODKEY-^`{seq 0 9} || fn $key {
|
||||
wmiir xwrite /client/sel/tags `{echo $1 | sed 's/.*-//'}}
|
||||
|
||||
#` WM Configuration
|
||||
# WM Configuration
|
||||
wmiir write /ctl <<!
|
||||
grabmod $MODKEY
|
||||
border 2
|
||||
@ -286,10 +308,8 @@ ifs=$wi_newline {
|
||||
seltag=`{wi_seltag}
|
||||
for(tag in `{wi_tags}) {{
|
||||
if(~ $tag $seltag)
|
||||
echo $wmiifocuscol $tag
|
||||
echo colors $wmiifocuscol $wi_newline label $tag
|
||||
if not
|
||||
echo $wmiinormcol $tag
|
||||
echo colors $wmiinormcol $wi_newline label $tag
|
||||
} | wmiir create /lbar/$tag}}
|
||||
|
||||
wi_eventloop
|
||||
|
||||
|
@ -452,82 +452,6 @@ class Tag(Dir):
|
||||
frame = self.framespec(frame)
|
||||
self['grow'] = '%s %s %s' % (frame, dir, str(amount or ''))
|
||||
|
||||
class Button(object):
|
||||
sides = {
|
||||
'left': 'lbar',
|
||||
'right': 'rbar',
|
||||
}
|
||||
def __init__(self, side, name, colors=None, label=None):
|
||||
self.side = side
|
||||
self.name = name
|
||||
self.base_path = self.sides[side]
|
||||
self.path = '%s/%s' % (self.base_path, self.name)
|
||||
self.file = None
|
||||
self._colors = wmii.cache['normcolors']
|
||||
self._label = ''
|
||||
if colors or label:
|
||||
self.create(colors, label)
|
||||
|
||||
def create(self, colors=None, label=None):
|
||||
def fail(resp, exc, tb):
|
||||
self.file = None
|
||||
if not self.file:
|
||||
self.file = client.create(self.path, ORDWR)
|
||||
if colors or label:
|
||||
self.file.awrite(self.getval(colors, label), offset=0, fail=fail)
|
||||
|
||||
def remove(self):
|
||||
if self.file:
|
||||
self.file.aremove()
|
||||
self.file = None
|
||||
|
||||
def getval(self, colors=None, label=None):
|
||||
if label is not None:
|
||||
self._label = label
|
||||
if colors is not None:
|
||||
self._colors = colors
|
||||
return ' '.join([Color(c).hex for c in self._colors or self.colors] + [unicode(self._label or '')])
|
||||
|
||||
colors = property(
|
||||
lambda self: self.file and Colors(self.file.read(offset=0).split(' ')[:3]) or (),
|
||||
lambda self, val: self.create(colors=val))
|
||||
|
||||
label = property(
|
||||
lambda self: self.file and self.file.read(offset=0).split(' ', 3)[3] or '',
|
||||
lambda self, val: self.create(label=val))
|
||||
|
||||
@classmethod
|
||||
def all(cls, side):
|
||||
return (Button(side, s.name)
|
||||
for s in client.readdir(cls.sides[side])
|
||||
if s.name != 'sel')
|
||||
|
||||
class Colors(utf8):
|
||||
def __init__(self, foreground=None, background=None, border=None):
|
||||
vals = foreground, background, border
|
||||
self.vals = tuple(map(Color, vals))
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.vals)
|
||||
def __list__(self):
|
||||
return list(self.vals)
|
||||
def __tuple__(self):
|
||||
return self.vals
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, val):
|
||||
return cls(*val.split(' '))
|
||||
|
||||
def __getitem__(self, key):
|
||||
if isinstance(key, basestring):
|
||||
key = {'foreground': 0, 'background': 1, 'border': 2}[key]
|
||||
return self.vals[key]
|
||||
|
||||
def __unicode__(self):
|
||||
return ' '.join(c.hex for c in self.vals)
|
||||
def __repr__(self):
|
||||
return 'Colors(%s, %s, %s)' % tuple(repr(c.rgb) for c in self.vals)
|
||||
|
||||
class Color(utf8):
|
||||
def __init__(self, colors):
|
||||
if isinstance(colors, Color):
|
||||
@ -563,6 +487,73 @@ class Color(utf8):
|
||||
def __repr__(self):
|
||||
return 'Color(%s)' % repr(self.rgb)
|
||||
|
||||
class Colors(utf8):
|
||||
def __init__(self, foreground=None, background=None, border=None):
|
||||
vals = foreground, background, border
|
||||
self.vals = tuple(map(Color, vals))
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.vals)
|
||||
def __list__(self):
|
||||
return list(self.vals)
|
||||
def __tuple__(self):
|
||||
return self.vals
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, val):
|
||||
return cls(*val.split(' '))
|
||||
|
||||
def __getitem__(self, key):
|
||||
if isinstance(key, basestring):
|
||||
key = {'foreground': 0, 'background': 1, 'border': 2}[key]
|
||||
return self.vals[key]
|
||||
|
||||
def __unicode__(self):
|
||||
return ' '.join(c.hex for c in self.vals)
|
||||
def __repr__(self):
|
||||
return 'Colors(%s, %s, %s)' % tuple(repr(c.rgb) for c in self.vals)
|
||||
|
||||
class Button(Ctl):
|
||||
sides = {
|
||||
'left': 'lbar',
|
||||
'right': 'rbar',
|
||||
}
|
||||
ctl_types = {
|
||||
'colors': (Colors.from_string, lambda c: str(Colors(*c))),
|
||||
}
|
||||
colors = Dir.ctl_property('colors')
|
||||
label = Dir.ctl_property('label')
|
||||
|
||||
def __init__(self, side, name, colors=None, label=None):
|
||||
super(Button, self).__init__()
|
||||
self.side = side
|
||||
self.name = name
|
||||
self.base_path = self.sides[side]
|
||||
self.ctl_path = '%s/%s' % (self.base_path, self.name)
|
||||
self.file = None
|
||||
self.create(colors, label)
|
||||
|
||||
def create(self, colors=None, label=None):
|
||||
def fail(resp, exc, tb):
|
||||
self.file = None
|
||||
if not self.file:
|
||||
self.file = client.create(self.ctl_path, ORDWR)
|
||||
if colors:
|
||||
self.colors = colors
|
||||
if label:
|
||||
self.label = label
|
||||
|
||||
def remove(self):
|
||||
if self.file:
|
||||
self.file.aremove()
|
||||
self.file = None
|
||||
|
||||
@classmethod
|
||||
def all(cls, side):
|
||||
return (Button(side, s.name)
|
||||
for s in client.readdir(cls.sides[side])
|
||||
if s.name != 'sel')
|
||||
|
||||
class Rules(collections.MutableMapping, utf8):
|
||||
|
||||
_items = ()
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
wmiiscript=$1
|
||||
wmiikeys=()
|
||||
wmiikeyhelp=''
|
||||
|
||||
wi_newline='
|
||||
'
|
||||
@ -134,15 +135,21 @@ fn wi_selclient {
|
||||
wmiir read /client/sel/ctl | sed 1q
|
||||
}
|
||||
|
||||
fn wi_readevent {
|
||||
wmiir read /event
|
||||
fn wi_nexttag {
|
||||
awk -v 'curtag='^`{wi_seltag} '
|
||||
NR==1 {first = $0}
|
||||
$0==curtag { if(getline) print $0; else print first; exit }'
|
||||
}
|
||||
|
||||
fn wi_eventloop {
|
||||
wi_initkeys
|
||||
|
||||
wi_readevent |
|
||||
while(ifs=$wi_ewlinel{wi_event=`{read}}) {
|
||||
{
|
||||
if(~ $1 -i)
|
||||
cat
|
||||
if not
|
||||
wmiir read /event
|
||||
} | while(ifs=$wi_newline{wi_event=`{read}}) {
|
||||
ifs=$wi_newline{
|
||||
wi_arg=`{echo $wi_event | sed 's/^[^ ]+ //'}}
|
||||
* = `{echo $wi_event}
|
||||
|
@ -86,10 +86,6 @@ _wi_script() {
|
||||
|
||||
_wi_text() {
|
||||
cat <<'!'
|
||||
Event Start
|
||||
if [ "$1" = "$wmiiscript" ]; then
|
||||
exit
|
||||
fi
|
||||
Event Key
|
||||
Key "$@"
|
||||
!
|
||||
@ -188,6 +184,12 @@ wi_selclient() {
|
||||
wmiir read /client/sel/ctl | sed 1q | tr -d '\012'
|
||||
}
|
||||
|
||||
wi_nexttag() {
|
||||
awk -v curtag=$(wi_seltag) '
|
||||
NR==1 {first = $0}
|
||||
$0==curtag { if(getline) print $0; else print first; exit }'
|
||||
}
|
||||
|
||||
wi_eventloop() {
|
||||
echo "$Keys" | wmiir write /keys
|
||||
|
||||
@ -201,6 +203,8 @@ wi_eventloop() {
|
||||
unset IFS
|
||||
set -- $wi_event
|
||||
event=$1; shift
|
||||
[ "$event" = Start -a "$1" = "$wmiiscript" ] &&
|
||||
exit
|
||||
( Event $event "$@" )
|
||||
done
|
||||
true
|
||||
|
@ -194,34 +194,6 @@ bar_draw(WMScreen *s) {
|
||||
copyimage(s->barwin, r, disp.ibuf, ZP);
|
||||
}
|
||||
|
||||
void
|
||||
bar_load(Bar *b) {
|
||||
IxpMsg m;
|
||||
char *p, *q;
|
||||
|
||||
p = b->buf;
|
||||
m = ixp_message(p, strlen(p), 0);
|
||||
|
||||
if(!waserror()) { /* Ignore errors. */
|
||||
msg_parsecolors(&m, &b->col);
|
||||
poperror();
|
||||
}
|
||||
|
||||
q = (char*)m.end-1;
|
||||
while(q >= (char*)m.pos && *q == '\n')
|
||||
*q-- = '\0';
|
||||
|
||||
q = b->text;
|
||||
utflcpy(q, (char*)m.pos, sizeof b->text);
|
||||
|
||||
p[0] = '\0';
|
||||
strlcat(p, b->col.colstr, sizeof b->buf);
|
||||
strlcat(p, " ", sizeof b->buf);
|
||||
strlcat(p, b->text, sizeof b->buf);
|
||||
|
||||
bar_draw(b->screen);
|
||||
}
|
||||
|
||||
Bar*
|
||||
bar_find(Bar *bp, const char *name) {
|
||||
Bar *b;
|
||||
|
@ -303,7 +303,8 @@ struct View {
|
||||
#endif
|
||||
|
||||
/* global variables */
|
||||
EXTERN struct {
|
||||
typedef struct Defs Defs;
|
||||
EXTERN struct Defs {
|
||||
CTuple focuscolor;
|
||||
CTuple normcolor;
|
||||
Font* font;
|
||||
|
@ -69,7 +69,6 @@ void bar_destroy(Bar**, Bar*);
|
||||
void bar_draw(WMScreen*);
|
||||
Bar* bar_find(Bar*, const char*);
|
||||
void bar_init(WMScreen*);
|
||||
void bar_load(Bar*);
|
||||
void bar_resize(WMScreen*);
|
||||
void bar_sety(WMScreen*, int);
|
||||
void bar_setbounds(WMScreen*, int, int);
|
||||
@ -210,6 +209,7 @@ void spawn_command(const char*);
|
||||
|
||||
/* message.c */
|
||||
char* mask(char**, int*, int*);
|
||||
char* message_bar(Bar*, IxpMsg*);
|
||||
char* message_client(Client*, IxpMsg*);
|
||||
char* message_root(void*, IxpMsg*);
|
||||
char* message_view(View*, IxpMsg*);
|
||||
@ -219,6 +219,7 @@ char* msg_getword(IxpMsg*, char*);
|
||||
void msg_parsecolors(IxpMsg*, CTuple*);
|
||||
char* msg_selectarea(Area*, IxpMsg*);
|
||||
char* msg_sendclient(View*, IxpMsg*, bool swap);
|
||||
char* readctl_bar(Bar*);
|
||||
char* readctl_client(Client*);
|
||||
char* readctl_root(void);
|
||||
char* readctl_view(View*);
|
||||
|
193
cmd/wmii/fs.c
193
cmd/wmii/fs.c
@ -123,6 +123,28 @@ static IxpDirtab* dirtab[] = {
|
||||
[FsDTag] = dirtab_tag,
|
||||
};
|
||||
typedef char* (*MsgFunc)(void*, IxpMsg*);
|
||||
typedef char* (*BufFunc)(void*);
|
||||
|
||||
typedef struct ActionTab ActionTab;
|
||||
static struct ActionTab {
|
||||
MsgFunc msg;
|
||||
BufFunc read;
|
||||
size_t buffer;
|
||||
size_t size;
|
||||
int max;
|
||||
} actiontab[] = {
|
||||
[FsFBar] = { .msg = (MsgFunc)message_bar, .read = (BufFunc)readctl_bar },
|
||||
[FsFCctl] = { .msg = (MsgFunc)message_client, .read = (BufFunc)readctl_client },
|
||||
[FsFRctl] = { .msg = (MsgFunc)message_root, .read = (BufFunc)readctl_root },
|
||||
[FsFTctl] = { .msg = (MsgFunc)message_view, .read = (BufFunc)readctl_view },
|
||||
[FsFTindex] = { .msg = (MsgFunc)0, .read = (BufFunc)view_index },
|
||||
[FsFColRules] = { .buffer = offsetof(Ruleset, string), .size = offsetof(Ruleset, size) },
|
||||
[FsFKeys] = { .buffer = offsetof(Defs, keys), .size = offsetof(Defs, keyssz) },
|
||||
[FsFRules] = { .buffer = offsetof(Ruleset, string), .size = offsetof(Ruleset, size) },
|
||||
[FsFClabel] = { .buffer = offsetof(Client, name), .max = sizeof ((Client*)0)->name },
|
||||
[FsFCtags] = { .buffer = offsetof(Client, tags), .max = sizeof ((Client*)0)->tags },
|
||||
[FsFprops] = { .buffer = offsetof(Client, props), .max = sizeof ((Client*)0)->props },
|
||||
};
|
||||
|
||||
void
|
||||
event(const char *format, ...) {
|
||||
@ -335,6 +357,9 @@ lookup_file(IxpFileId *parent, char *name)
|
||||
case FsFColRules:
|
||||
file->p.rule = &def.colrules;
|
||||
break;
|
||||
case FsFKeys:
|
||||
file->p.ref = &def;
|
||||
break;
|
||||
case FsFRules:
|
||||
file->p.rule = &def.rules;
|
||||
break;
|
||||
@ -374,21 +399,19 @@ fs_walk(Ixp9Req *r) {
|
||||
|
||||
static uint
|
||||
fs_size(IxpFileId *f) {
|
||||
switch(f->tab.type) {
|
||||
default:
|
||||
return 0;
|
||||
case FsFColRules:
|
||||
case FsFRules:
|
||||
return f->p.rule->size;
|
||||
case FsFKeys:
|
||||
return def.keyssz;
|
||||
case FsFCtags:
|
||||
return strlen(f->p.client->tags);
|
||||
case FsFClabel:
|
||||
return strlen(f->p.client->name);
|
||||
case FsFprops:
|
||||
return strlen(f->p.client->props);
|
||||
}
|
||||
ActionTab *t;
|
||||
|
||||
t = &actiontab[f->tab.type];
|
||||
if(f->tab.type < nelem(actiontab))
|
||||
if(t->size)
|
||||
return structmember(f->p.ref, int, t->size);
|
||||
else if(t->buffer && t->max)
|
||||
return strlen(structptr(f->p.ref, char, t->buffer));
|
||||
else if(t->buffer)
|
||||
return strlen(structmember(f->p.ref, char*, t->buffer));
|
||||
else if(t->read)
|
||||
return strlen(t->read(f->p.ref));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -422,9 +445,11 @@ void
|
||||
fs_read(Ixp9Req *r) {
|
||||
char *buf;
|
||||
IxpFileId *f;
|
||||
int n;
|
||||
ActionTab *t;
|
||||
int n, found;
|
||||
|
||||
f = r->fid->aux;
|
||||
found = 0;
|
||||
|
||||
if(!ixp_srv_verifyfile(f, lookup_file)) {
|
||||
ixp_respond(r, Enofile);
|
||||
@ -440,53 +465,26 @@ fs_read(Ixp9Req *r) {
|
||||
ixp_pending_respond(r);
|
||||
return;
|
||||
}
|
||||
switch(f->tab.type) {
|
||||
case FsFprops:
|
||||
ixp_srv_readbuf(r, f->p.client->props, strlen(f->p.client->props));
|
||||
ixp_respond(r, nil);
|
||||
return;
|
||||
case FsFColRules:
|
||||
case FsFRules:
|
||||
ixp_srv_readbuf(r, f->p.rule->string, f->p.rule->size);
|
||||
ixp_respond(r, nil);
|
||||
return;
|
||||
case FsFKeys:
|
||||
ixp_srv_readbuf(r, def.keys, def.keyssz);
|
||||
ixp_respond(r, nil);
|
||||
return;
|
||||
case FsFCtags:
|
||||
ixp_srv_readbuf(r, f->p.client->tags, strlen(f->p.client->tags));
|
||||
ixp_respond(r, nil);
|
||||
return;
|
||||
case FsFClabel:
|
||||
ixp_srv_readbuf(r, f->p.client->name, strlen(f->p.client->name));
|
||||
ixp_respond(r, nil);
|
||||
return;
|
||||
case FsFBar:
|
||||
ixp_srv_readbuf(r, f->p.bar->buf, strlen(f->p.bar->buf));
|
||||
ixp_respond(r, nil);
|
||||
return;
|
||||
case FsFRctl:
|
||||
buf = readctl_root();
|
||||
ixp_srv_readbuf(r, buf, strlen(buf));
|
||||
ixp_respond(r, nil);
|
||||
return;
|
||||
case FsFCctl:
|
||||
buf = readctl_client(f->p.client);
|
||||
ixp_srv_readbuf(r, buf, strlen(buf));
|
||||
ixp_respond(r, nil);
|
||||
return;
|
||||
case FsFTindex:
|
||||
buf = view_index(f->p.view);
|
||||
ixp_srv_readbuf(r, buf, strlen(buf));
|
||||
ixp_respond(r, nil);
|
||||
return;
|
||||
case FsFTctl:
|
||||
buf = readctl_view(f->p.view);
|
||||
n = strlen(buf);
|
||||
t = &actiontab[f->tab.type];
|
||||
if(f->tab.type < nelem(actiontab)) {
|
||||
if(t->read)
|
||||
buf = t->read(f->p.ref);
|
||||
else if(t->buffer && t->max)
|
||||
buf = structptr(f->p.ref, char, t->buffer);
|
||||
else if(t->buffer)
|
||||
buf = structmember(f->p.ref, char*, t->buffer);
|
||||
else
|
||||
goto done;
|
||||
n = t->size ? structmember(f->p.ref, int, t->size) : strlen(buf);
|
||||
ixp_srv_readbuf(r, buf, n);
|
||||
ixp_respond(r, nil);
|
||||
return;
|
||||
found++;
|
||||
}
|
||||
done:
|
||||
switch(f->tab.type) {
|
||||
default:
|
||||
if(found)
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* This should not be called if the file is not open for reading. */
|
||||
@ -495,12 +493,13 @@ fs_read(Ixp9Req *r) {
|
||||
|
||||
void
|
||||
fs_write(Ixp9Req *r) {
|
||||
MsgFunc mf;
|
||||
IxpFileId *f;
|
||||
ActionTab *t;
|
||||
char *errstr;
|
||||
char *p;
|
||||
uint i;
|
||||
int found;
|
||||
|
||||
found = 0;
|
||||
errstr = nil;
|
||||
if(r->ifcall.io.count == 0) {
|
||||
ixp_respond(r, nil);
|
||||
return;
|
||||
@ -517,25 +516,30 @@ fs_write(Ixp9Req *r) {
|
||||
return;
|
||||
}
|
||||
|
||||
t = &actiontab[f->tab.type];
|
||||
if(f->tab.type < nelem(actiontab)) {
|
||||
if(t->msg) {
|
||||
errstr = ixp_srv_writectl(r, t->msg);
|
||||
r->ofcall.io.count = r->ifcall.io.count;
|
||||
}
|
||||
else if(t->buffer && t->max)
|
||||
ixp_srv_writebuf(r, (char*[]){ structptr(f->p.ref, char, t->buffer) },
|
||||
t->size ? structptr(f->p.ref, uint, t->size) : nil,
|
||||
t->max);
|
||||
else if(t->buffer)
|
||||
ixp_srv_writebuf(r, structptr(f->p.ref, char*, t->buffer),
|
||||
t->size ? structptr(f->p.ref, uint, t->size) : nil,
|
||||
t->max);
|
||||
else
|
||||
goto done;
|
||||
ixp_respond(r, nil);
|
||||
found++;
|
||||
}
|
||||
done:
|
||||
switch(f->tab.type) {
|
||||
case FsFColRules:
|
||||
case FsFRules:
|
||||
ixp_srv_writebuf(r, &f->p.rule->string, &f->p.rule->size, 0);
|
||||
ixp_respond(r, nil);
|
||||
break;
|
||||
case FsFKeys:
|
||||
ixp_srv_writebuf(r, &def.keys, &def.keyssz, 0);
|
||||
ixp_respond(r, nil);
|
||||
break;
|
||||
case FsFClabel:
|
||||
ixp_srv_data2cstring(r);
|
||||
utfecpy(f->p.client->name,
|
||||
f->p.client->name + sizeof client->name,
|
||||
r->ifcall.io.data);
|
||||
frame_draw(f->p.client->sel);
|
||||
update_class(f->p.client);
|
||||
r->ofcall.io.count = r->ifcall.io.count;
|
||||
ixp_respond(r, nil);
|
||||
break;
|
||||
case FsFCtags:
|
||||
ixp_srv_data2cstring(r);
|
||||
@ -543,28 +547,6 @@ fs_write(Ixp9Req *r) {
|
||||
r->ofcall.io.count = r->ifcall.io.count;
|
||||
ixp_respond(r, nil);
|
||||
break;
|
||||
case FsFBar:
|
||||
i = strlen(f->p.bar->buf);
|
||||
p = f->p.bar->buf;
|
||||
ixp_srv_writebuf(r, &p, &i, 279);
|
||||
bar_load(f->p.bar);
|
||||
r->ofcall.io.count = i - r->ifcall.io.offset;
|
||||
ixp_respond(r, nil);
|
||||
break;
|
||||
case FsFCctl:
|
||||
mf = (MsgFunc)message_client;
|
||||
goto msg;
|
||||
case FsFTctl:
|
||||
mf = (MsgFunc)message_view;
|
||||
goto msg;
|
||||
case FsFRctl:
|
||||
mf = (MsgFunc)message_root;
|
||||
goto msg;
|
||||
msg:
|
||||
errstr = ixp_srv_writectl(r, mf);
|
||||
r->ofcall.io.count = r->ifcall.io.count;
|
||||
ixp_respond(r, errstr);
|
||||
break;
|
||||
case FsFEvent:
|
||||
if(r->ifcall.io.data[r->ifcall.io.count-1] == '\n')
|
||||
event("%.*s", (int)r->ifcall.io.count, r->ifcall.io.data);
|
||||
@ -575,7 +557,8 @@ fs_write(Ixp9Req *r) {
|
||||
break;
|
||||
default:
|
||||
/* This should not be called if the file is not open for writing. */
|
||||
die("Write called on an unwritable file");
|
||||
if(!found)
|
||||
die("Write called on an unwritable file");
|
||||
}
|
||||
poperror();
|
||||
return;
|
||||
@ -652,7 +635,6 @@ fs_remove(Ixp9Req *r) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch(f->tab.type) {
|
||||
default:
|
||||
ixp_respond(r, Enoperm);
|
||||
@ -661,9 +643,12 @@ fs_remove(Ixp9Req *r) {
|
||||
s = f->p.bar->screen;
|
||||
bar_destroy(f->next->p.bar_p, f->p.bar);
|
||||
bar_draw(s);
|
||||
ixp_respond(r, nil);
|
||||
break;
|
||||
case FsDClient:
|
||||
client_kill(f->p.client, true);
|
||||
break;
|
||||
}
|
||||
ixp_respond(r, nil);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -29,6 +29,7 @@ enum {
|
||||
LBORDER,
|
||||
LCLIENT,
|
||||
LCOLMODE,
|
||||
LCOLORS,
|
||||
LDEBUG,
|
||||
LDOWN,
|
||||
LEXEC,
|
||||
@ -42,6 +43,7 @@ enum {
|
||||
LGROW,
|
||||
LINCMODE,
|
||||
LKILL,
|
||||
LLABEL,
|
||||
LLEFT,
|
||||
LNORMCOLORS,
|
||||
LNUDGE,
|
||||
@ -68,6 +70,7 @@ char *symtab[] = {
|
||||
"border",
|
||||
"client",
|
||||
"colmode",
|
||||
"colors",
|
||||
"debug",
|
||||
"down",
|
||||
"exec",
|
||||
@ -81,6 +84,7 @@ char *symtab[] = {
|
||||
"grow",
|
||||
"incmode",
|
||||
"kill",
|
||||
"label",
|
||||
"left",
|
||||
"normcolors",
|
||||
"nudge",
|
||||
@ -471,6 +475,31 @@ getframe(View *v, int scrn, IxpMsg *m) {
|
||||
return f;
|
||||
}
|
||||
|
||||
char*
|
||||
readctl_bar(Bar *b) {
|
||||
bufclear();
|
||||
bufprint("colors %s\n", b->col.colstr);
|
||||
bufprint("label %s\n", b->text);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char*
|
||||
message_bar(Bar *b, IxpMsg *m) {
|
||||
|
||||
switch(getsym(msg_getword(m, nil))) {
|
||||
case LCOLORS:
|
||||
msg_parsecolors(m, &b->col);
|
||||
break;
|
||||
case LLABEL:
|
||||
utflcpy(b->text, (char*)m->pos, sizeof b->text);
|
||||
break;
|
||||
default:
|
||||
error(Ebadvalue);
|
||||
}
|
||||
bar_draw(b->screen);
|
||||
return nil;
|
||||
}
|
||||
|
||||
char*
|
||||
readctl_client(Client *c) {
|
||||
bufclear();
|
||||
|
305
doc/wmii.tex
305
doc/wmii.tex
@ -13,7 +13,12 @@
|
||||
\usepackage{xcolor}
|
||||
\usepackage[xetex,breaklinks,colorlinks,linkcolor=black]{hyperref}
|
||||
|
||||
% Indexes
|
||||
\let\EA=\expandafter
|
||||
|
||||
\newif\ifexpandfragments
|
||||
\newif\ifdefinefragments
|
||||
|
||||
%% Indexes
|
||||
\makeindex
|
||||
\let\primary=\textbf
|
||||
|
||||
@ -26,36 +31,63 @@
|
||||
|
||||
\def\man#1#2{#2\textbf{(#1)}}
|
||||
|
||||
% Key specs
|
||||
\makeatletter
|
||||
|
||||
%% Key specs
|
||||
\def\key#1{{\small$\langle$\addfontfeature{Numbers=Lining}#1\/$\rangle$}}
|
||||
\let\<=<
|
||||
\catcode`\<=\active
|
||||
\def<#1>{\key{#1}}
|
||||
|
||||
% Display ‹...› and «...» as text in left and right pointing
|
||||
% angle brackets. I use «» and ‹› because my terminal doesn't
|
||||
% display left and right pointing angle brackets properly, and
|
||||
% Xorg's compose maps don't provide them, anyway.
|
||||
%% Display ‹...› and «...» as text in left and right pointing
|
||||
%% angle brackets. I use «» and ‹› because my terminal doesn't
|
||||
%% display left and right pointing angle brackets properly, and
|
||||
%% Xorg's compose maps don't provide them, anyway.
|
||||
\def\«{«}\def\‹{‹}
|
||||
\catcode`\«=\active
|
||||
\catcode`\‹=\active
|
||||
\def‹#1›{$\langle${\itshape#1}$\rangle$}
|
||||
\def«#1»{$\langle\langle${\itshape#1}$\rangle\rangle$}
|
||||
|
||||
\catcode`\∅=\active
|
||||
\def∅{\box0}
|
||||
\def«{%
|
||||
\let\dofragment@target=\hyperlink%
|
||||
\@ifnextchar*\dofragment@@\dofragment@}
|
||||
\def\dofragment@@*{%
|
||||
\let\dofragment@target=\hypertarget%
|
||||
\dofragment@}
|
||||
\def\dofragment@#1»{%
|
||||
\setbox0=\hbox{$\langle\langle${\itshape#1}$\rangle\rangle$}%
|
||||
\ifexpandfragments%
|
||||
\def\a{\sp\sp\comment \boxzero^^J}%
|
||||
\begingroup%
|
||||
\def\ { }\xdef\@frag@name{#1}%
|
||||
\endgroup%
|
||||
\UseFragment{∅}\@frag@name%
|
||||
\else%
|
||||
\dofragment@target{frag:#1}{\box0}%
|
||||
\fi}
|
||||
|
||||
% Display |...| as verbatim, teletype text.
|
||||
\DefineShortVerb{\|}
|
||||
|
||||
\makeatletter
|
||||
\let\idx@@heading\chapter
|
||||
\let\:=:
|
||||
\catcode`\:=\active
|
||||
\def:{\@ifnextchar:{\coloncoloneq}{\:}}
|
||||
\def\coloncoloneq#1{\@ifnextchar={$\Coloneqq$\coloncoloneqq}{\:\:}}
|
||||
\def\coloncoloneqq#1{}
|
||||
\def\:{:}
|
||||
\iffalse
|
||||
\catcode`\:=\active
|
||||
\gdef:{\@ifnextchar:{\coloncoloneq}{\:}}
|
||||
\gdef\coloncoloneq#1{\@ifnextchar={$\Coloneqq$\coloncoloneqq}{\:\:}}
|
||||
\gdef\coloncoloneqq#1{}
|
||||
\fi
|
||||
\def\≔{≔}
|
||||
\catcode`\≔=\active
|
||||
\def≔{\ensuremath{\Coloneqq}}
|
||||
|
||||
% Create a verbatim {code} environment which highlights strings
|
||||
% and comments. Several unicode characters are hacked to replace
|
||||
% the grabbed characters, since we can't escape them in the
|
||||
% verbatim environment.
|
||||
%% Create a verbatim {code} environment which highlights strings
|
||||
%% and comments. Several unicode characters are hacked to replace
|
||||
%% the grabbed characters, since we can't escape them in the
|
||||
%% verbatim environment.
|
||||
\colorlet{comment}{gray}
|
||||
\colorlet{string}{red!100!black!90}
|
||||
\let\‘=‘
|
||||
@ -67,17 +99,66 @@
|
||||
\catcode`‘=\active
|
||||
\def“¶1”{{\color{string}\“¶1”}}%
|
||||
\def‘¶1’{{\color{string}\‘¶1’}}%
|
||||
\def\comment{\itshape\color{comment}\let“=\“\let‘=\‘\#}
|
||||
\def\docodes{\catcode`\#=\active\catcode`“=\active\catcode`‘=\active\catcode`\☺=0}
|
||||
\def\dodefineactive{
|
||||
\let#=\comment
|
||||
}
|
||||
\DefineVerbatimEnvironment{code}{Verbatim}{xleftmargin=2em,gobble=2,%
|
||||
codes={\catcode`\#=\active\catcode`\:=\active\catcode`“=\active\catcode`‘=\active},%
|
||||
defineactive={%
|
||||
\def#{\itshape\color{comment}\let“=\“\let‘=\‘\#}%
|
||||
}}
|
||||
codes={\docodes},%
|
||||
defineactive={\dodefineactive}}
|
||||
\catcode`\#=6
|
||||
\catcode`“=12
|
||||
\catcode`‘=12
|
||||
|
||||
% Convenience defs for the various wmii commands, and a few
|
||||
% others.
|
||||
%% Save code fragments for piecing together later
|
||||
\begingroup
|
||||
\catcode`\@=0
|
||||
@catcode`\\=12
|
||||
@gdef@bcode{@detokenize{\begin{code}^^J}}
|
||||
@gdef@ecode{@detokenize{\end{code}^^J}}
|
||||
@catcode`@ =12@gdef@sp{ }
|
||||
@endgroup
|
||||
|
||||
% Ripped from fancyverb
|
||||
% I'm currently rather unfond of it.
|
||||
\def\Fragment{\FV@Environment{}{Fragment}}
|
||||
\def\FVB@Fragment#1{%
|
||||
\@bsphack
|
||||
\begingroup
|
||||
\FV@UseKeyValues
|
||||
\gdef\Fragment@Name{#1}%
|
||||
\xdef\Fragment@Prefix{\«*#1» \≔^^J}
|
||||
\xdef\TheFragment{}
|
||||
\def\FV@ProcessLine##1{%
|
||||
\edef\frag{\detokenize{##1^^J}}%
|
||||
\xdef\TheFragment{\TheFragment\frag}}%
|
||||
\FV@Scan}
|
||||
\def\FVE@Fragment{%
|
||||
\EA\global\EA\let
|
||||
\csname SV@\Fragment@Name\endcsname\TheFragment%
|
||||
\endgroup%
|
||||
\EA\UseFragment\EA{\Fragment@Prefix}\Fragment@Name}
|
||||
\DefineVerbatimEnvironment{Fragment}{Fragment}{}
|
||||
|
||||
\def\UseFragment#1#2{
|
||||
\begingroup
|
||||
% \message{UseFragment #2^^J}
|
||||
\EA\let\EA\a\csname SV@#2\endcsname
|
||||
\ifx\a\undefined\def\a{\ldots}\fi
|
||||
\ifx\FV@EnvironName\relax%
|
||||
\edef\a{\bcode\detokenize{++#1}\a\ecode}\else%
|
||||
\edef\a{\detokenize{#1}\a}\fi%
|
||||
\newtoks\tokens
|
||||
\EA\tokens\EA{\a}
|
||||
\everyeof{\noexpand}%
|
||||
% \EA\message\EA{\the\tokens}
|
||||
\scantokens\EA{\the\tokens}
|
||||
\endgroup
|
||||
}
|
||||
|
||||
%% Convenience defs for the various wmii commands, and a few
|
||||
%% others.
|
||||
\def\wmii{\texttt{wmii}}
|
||||
\def\wiIXmenu{\texttt{wi9menu}}
|
||||
\def\wimenu{\texttt{wimenu}}
|
||||
@ -125,7 +206,6 @@ This file is distributed under the same terms as wmii:
|
||||
\parindent=0pt
|
||||
\parskip=1em
|
||||
|
||||
\catcode`\:=12
|
||||
Copyright © 2009 Kris Maglione <\href{mailto:maglione.k@gmail.com}{maglione.k@gmail.com}>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@ -635,8 +715,7 @@ windows, and changes of focus and views.
|
||||
We'll start building our configuration with an event processing
|
||||
framework:
|
||||
|
||||
\begin{code}
|
||||
«Event Loop» ::=
|
||||
\begin{Fragment}{Event Loop}
|
||||
# Broadcast a custom event
|
||||
wmiir xwrite /event Start wmiirc
|
||||
|
||||
@ -657,13 +736,12 @@ framework:
|
||||
«Event Handlers»
|
||||
esac
|
||||
done
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
Now, we need to consider which types of events we'll need to
|
||||
handle:
|
||||
|
||||
\begin{code}
|
||||
«Event Handlers» ::=
|
||||
\begin{Fragment}{Event Handlers}
|
||||
«View Button Events»
|
||||
«Urgency Events»
|
||||
«Unresponsive Clients»
|
||||
@ -671,37 +749,45 @@ handle:
|
||||
«Key Events»
|
||||
«Client Menu Events»
|
||||
«Tag Menu Events»
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\section{Bar Items}
|
||||
|
||||
The bar is described by the files in the two directories |/lbar/| and
|
||||
|/rbar/| for buttons on the left and right side of the bar,
|
||||
respectively. The format of the files is:
|
||||
respectively. The files act as control files (section
|
||||
\ref{sec:controlfiles}) with the contents:
|
||||
|
||||
\begin{code}
|
||||
‹Color Tuple› ‹Label›
|
||||
color ‹Color Tuple›
|
||||
label ‹Label›
|
||||
\end{code}
|
||||
|
||||
although the color tuple may be elided in cases where the label
|
||||
doesn't match its format.
|
||||
|
||||
A ‹Color Tuple› is defined as:
|
||||
|
||||
\begin{code}
|
||||
‹tuple› ::= ‹foreground color› ‹background color› ‹border color›
|
||||
‹color› ::= #‹6 character RGB hex color code›
|
||||
‹Color Tuple› ≔ ‹foreground color› ‹background color› ‹border color›
|
||||
‹* Color› ≔ ‹RGB color› | ‹RGBA color›
|
||||
‹RGB color› ≔ #‹6 character RGB hex color code›
|
||||
‹RGBA color› ≔ rgba:‹red›/‹green›/‹blue›/‹alpha›
|
||||
\end{code}
|
||||
|
||||
\noindent
|
||||
where all of the colors are represented as lowercase,
|
||||
hexidecimal values. In the case of RGBA colors, they may be 1--4
|
||||
characters long, though they will be standardized internally to
|
||||
2 characters.
|
||||
|
||||
\medskip
|
||||
|
||||
Let's define our basic theme information now:
|
||||
|
||||
\begin{code}
|
||||
«Theme Definitions» ::=
|
||||
\begin{Fragment}{Theme Definitions}
|
||||
normcolors=‘#000000 #c1c48b #81654f’
|
||||
focuscolors=‘#000000 #81654f #000000’
|
||||
background=‘#333333’
|
||||
font=‘drift,-*-fixed-*-*-*-*-9-*-*-*-*-*-*-*’
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\subsection{View Buttons}
|
||||
|
||||
@ -712,8 +798,7 @@ our view event handlers:
|
||||
\index{events!DestroyTag}
|
||||
\index{events!FocusTag}
|
||||
\index{events!UnfocusTag}
|
||||
\begin{code}
|
||||
«View Button Events» ::=
|
||||
\begin{Fragment}{View Button Events}
|
||||
CreateTag) # CreateTag ‹Tag Name›
|
||||
echo $normcolors $1 | wmiir create /lbar/$1;;
|
||||
DestroyTag) # DestroyTag ‹Tag Name›
|
||||
@ -722,7 +807,7 @@ our view event handlers:
|
||||
wmiir xwrite /lbar/$1 $focuscolors $1;;
|
||||
UnfocusTag) # UnfocusTag ‹Tag Name›
|
||||
wmiir xwrite /lbar/$1 $normcolors $1;;
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\subsection{Urgency}
|
||||
|
||||
@ -732,13 +817,12 @@ Windows can specify that they require attention, and in X11
|
||||
parlance, this is called urgency. When a window requests
|
||||
attention as such, or declares that it's been satisfied, \wmii\
|
||||
broadcasts an event for the client and an event for each view
|
||||
that it belongs to, and fills in the client's layout box. It's
|
||||
the job of a script to decide how to handle it above and beyond
|
||||
that. The standard scripts simply mark urgent views with an
|
||||
asterisk:
|
||||
that it belongs to. It also fills in the layout box of any
|
||||
client deemed urgent. It's the job of a script to decide how to
|
||||
handle urgency events above and beyond that basic measure. The
|
||||
standard scripts simply mark urgent views with an asterisk:
|
||||
|
||||
\begin{code}
|
||||
«Urgency Events» ::=
|
||||
\begin{Fragment}{Urgency Events}
|
||||
# The urgency events are ‘Client’ events when the program
|
||||
# owning the window sets its urgency state. They're ‘Manager’
|
||||
# events when wmii or the wmii user sets the state.
|
||||
@ -746,7 +830,7 @@ asterisk:
|
||||
wmiir xwrite /lbar/$2 $2;;
|
||||
NotUrgentTag) # NotUrgentTag ‹‘Client’ or ‘Manager’› ‹Tag Name›
|
||||
wmiir xwrite /lbar/$2 $2;;
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
\index{events!UrgentTag|)}
|
||||
\index{events!NotUrgentTag|)}
|
||||
|
||||
@ -756,18 +840,17 @@ The standard scripts provide a custom Notice event for
|
||||
displaying status information. The events appear in the long bar
|
||||
between the left and right sides for five seconds.
|
||||
|
||||
\begin{code}
|
||||
«Notice Events» ::=
|
||||
\begin{Fragment}{Notice Events}
|
||||
Notice)
|
||||
wmiir xwrite /rbar/!notice $line
|
||||
kill $xpid 2>/dev/null # Let's hope this isn't reused...
|
||||
{ sleep 5; wmiir xwrite /rbar/!notice ‘ ’; } &
|
||||
xpid = $!;;
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\section{Keys}
|
||||
|
||||
\label{keybindings}
|
||||
\label{sec:keybindings}
|
||||
\index{key bindings}
|
||||
\index{filesystem!/!keys}
|
||||
\index{filesystem!/!event}
|
||||
@ -798,8 +881,7 @@ Examples of key bindings:
|
||||
|
||||
Now, let's bind the keys we plan on using:
|
||||
|
||||
\begin{code}
|
||||
«Bind Keys» ::=
|
||||
\begin{Fragment}{Bind Keys}
|
||||
{
|
||||
cat <<!
|
||||
Mod4-space
|
||||
@ -828,12 +910,11 @@ Now, let's bind the keys we plan on using:
|
||||
echo Mod4-Shift-$i
|
||||
done
|
||||
} | wmiir write /keys
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
and lay a framework for processing their events:
|
||||
|
||||
\begin{code}
|
||||
«Key Events» ::=
|
||||
\begin{Fragment}{Key Events}
|
||||
Key) # Key ‹Key Name›
|
||||
case $1 in
|
||||
«Motion Keys»
|
||||
@ -844,7 +925,7 @@ and lay a framework for processing their events:
|
||||
«Tag Selection Keys»
|
||||
«Tagging Keys»
|
||||
esac;;
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\section{Click Menus}
|
||||
|
||||
@ -853,15 +934,16 @@ reach for the keyboard. To help cope, \wmii\ provides a
|
||||
mouse-driven, single-click menu. The default configuration uses
|
||||
it for client and tag menus.
|
||||
|
||||
\begin{code}
|
||||
«Click Menu Initialization» ::=
|
||||
\begin{Fragment}{Click Menu Initialization}
|
||||
clickmenu() {
|
||||
if res=$(wmii9menu -- “$@”); then eval “$res”; fi
|
||||
}
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\section{Control Files}
|
||||
|
||||
\label{sec:controlfiles}
|
||||
|
||||
Several directories including the root, have control files,
|
||||
named |ctl|. These files are used to control the object (e.g., a
|
||||
client or tag) represented by the directory. Each line of the
|
||||
@ -937,7 +1019,10 @@ client. The files in these directories are:
|
||||
\item[pid] Read-only value of the PID of the program that
|
||||
owns the window, if the value is available and the
|
||||
process is on the same machine as wmii.
|
||||
\item[slay] When written, the client is killed peremptorily.
|
||||
\item[slay] When written, the client is disconnected
|
||||
peremptorily. If the client's PID is available and the
|
||||
process is the same machine as wmii, its parent process
|
||||
is killed
|
||||
\item[tags] The client's tags. The same as the tags file.
|
||||
\item[urgent] The client's urgency state. When |on|, the
|
||||
client's layout box will be highlighted. Possible values
|
||||
@ -953,19 +1038,21 @@ client. The files in these directories are:
|
||||
\item[tags]
|
||||
\index{filesystem!/client/*/@\clientlabel!tags}
|
||||
The client's tags. Tag names are separated by |+|, |-|, or
|
||||
|^| signs. Tags beginning and ending with |/| are treated as
|
||||
regular expressions, which place the client on any extant
|
||||
matching tag\footnote{While a client with a regex tag will
|
||||
always appear in all matching views, it will not keep those
|
||||
views in existence. When the last client explicitly tagged
|
||||
with a view is removed, the view is deleted as soon as it
|
||||
becomes inactive.}. If the written value begins with a |+|,
|
||||
|-|, or |^|, the tags are updated rather than overwritten.
|
||||
Tag names which directly follow a |-| sign are removed
|
||||
rather than added, while those following a |^| are toggled.
|
||||
Regular expression tags which directly follow a minus sign
|
||||
are treated as exclusion expressions. For example, the tag
|
||||
string |+/foo/-/food/| will match the tag
|
||||
|^| signs. Tag names which directly follow a |+| sign are
|
||||
added, while whose following a |-| sign are removed and
|
||||
those following a |^| are toggled. If the value written
|
||||
begins with one of these characters, the value is appended
|
||||
to the clients tags rather than replacing them.
|
||||
|
||||
Tags formatted as |/‹regex›/| are treated as regular
|
||||
expressions, which place the client on any extant matching
|
||||
tag\footnote{While a client with a regex tag will always
|
||||
appear in all matching views, it will not keep those views
|
||||
in existence. When the last client explicitly tagged with a
|
||||
view is removed, the view is deleted as soon as it becomes
|
||||
inactive.}. Regular expression tags which directly follow a
|
||||
minus sign are treated as exclusion expressions. For
|
||||
example, the tag string |+/foo/-/food/| will match the tag
|
||||
|foobar|, but not the tag |foodstand|.
|
||||
\end{description}
|
||||
|
||||
@ -975,16 +1062,14 @@ client. The files in these directories are:
|
||||
|
||||
To control clients, we'll add the following key bindings:
|
||||
|
||||
\begin{code}
|
||||
«Client Command Keys» ::=
|
||||
\begin{Fragment}{Client Command Keys}
|
||||
Mod4-Shift-c) wmiir xwrite /client/sel/ctl kill;;
|
||||
Mod4-f) wmiir xwrite /client/sel/ctl Fullscreen toggle;;
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
And to manage their tags, we'll need:
|
||||
|
||||
\begin{code}
|
||||
«Tagging Keys» ::=
|
||||
\begin{Fragment}{Tagging Keys}
|
||||
Mod4-Shift-t)
|
||||
# Get the selected client's id
|
||||
c=$(wmiir read /client/sel/ctl | sed 1q)
|
||||
@ -994,19 +1079,18 @@ And to manage their tags, we'll need:
|
||||
wmiir xwrite /client/$c/tags $tag;;
|
||||
Mod4-Shift-[0-9])
|
||||
wmiir xwrite /client/sel/tags ${1##*-};;
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\subsection{Click Menus}
|
||||
|
||||
\index{events!ClientMouseDown}
|
||||
\begin{code}
|
||||
«Client Menu Events» ::=
|
||||
\begin{Fragment}{Client Menu Events}
|
||||
ClientMouseDown) # ClientMouseDown ‹Client ID› ‹Button›
|
||||
[ $2 = 3 ] && clickmenu \
|
||||
“Delete:wmiir xwrite /client/$1/ctl kill” \
|
||||
“Kill: wmiirxwrite /client/$1/ctl slay” \
|
||||
“Fullscreen:wmiir xwrite /client/$1/ctl fullscreen on”
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\subsection{Unresponsive Clients}
|
||||
|
||||
@ -1015,8 +1099,7 @@ When \wmii\ tries to close a window, it waits 8 seconds for the
|
||||
client to respond, and then lets its scripts decide what to do
|
||||
with it. The stock scripts prompt the user for input:
|
||||
|
||||
\begin{code}
|
||||
«Unresponsive Clients» ::=
|
||||
\begin{Fragment}{Unresponsive Clients}
|
||||
UnresponsiveClient) # UnresponsiveClient ‹Client ID›
|
||||
{
|
||||
# Use wihack to make the xmessage a transient window of
|
||||
@ -1029,7 +1112,7 @@ with it. The stock scripts prompt the user for input:
|
||||
$(wmiir read /client/$1/label))
|
||||
[ $resp = Kill ] && wmiir xwrite /client/$1/ctl slay
|
||||
} &;;
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
\index{events!UnresponsiveClient|)}
|
||||
|
||||
\section{Views}
|
||||
@ -1117,36 +1200,36 @@ in these directories are:
|
||||
|
||||
We'll use the following key bindings to interact with views:
|
||||
|
||||
\begin{code}
|
||||
«Motion Keys» ::=
|
||||
\begin{Fragment}{Motion Keys}
|
||||
Mod4-h) wmiir xwrite /tag/sel/ctl select left;;
|
||||
Mod4-l) wmiir xwrite /tag/sel/ctl select right;;
|
||||
Mod4-k) wmiir xwrite /tag/sel/ctl select up;;
|
||||
Mod4-j) wmiir xwrite /tag/sel/ctl select down;;
|
||||
Mod4-space) wmiir xwrite /tag/sel/ctl select toggle;;
|
||||
\end{Fragment}
|
||||
|
||||
«Client Movement Keys» ::=
|
||||
\begin{Fragment}{Client Movement Keys}
|
||||
Mod4-Shift-h) wmiir xwrite /tag/sel/ctl send sel left;;
|
||||
Mod4-Shift-l) wmiir xwrite /tag/sel/ctl send sel right;;
|
||||
Mod4-Shift-k) wmiir xwrite /tag/sel/ctl send sel up;;
|
||||
Mod4-Shift-j) wmiir xwrite /tag/sel/ctl send sel down;;
|
||||
Mod4-Shift-space) wmiir xwrite /tag/sel/ctl send sel toggle;;
|
||||
\end{Fragment}
|
||||
|
||||
«Column Mode Keys» ::=
|
||||
\begin{Fragment}{Column Mode Keys}
|
||||
Mod4-d) wmiir xwrite /tag/sel/ctl colmode sel -stack-max;;
|
||||
Mod4-s) wmiir xwrite /tag/sel/ctl colmode sel stack-max;;
|
||||
Mod4-m) wmiir xwrite /tag/sel/ctl colmode sel stack+max;;
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\subsection{Click Menus}
|
||||
|
||||
\index{events!LeftBarMouseDown}
|
||||
\begin{code}
|
||||
«Tag Menu Events» ::=
|
||||
\begin{Fragment}{Tag Menu Events}
|
||||
LeftBarMouseDown) # LeftBarMouseDown ‹Button› ‹Bar Name›
|
||||
[ $1 = 3 ] && clickmenu \
|
||||
“Delete:delete_view $2”
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\section{Command and Program Execution}
|
||||
|
||||
@ -1160,28 +1243,26 @@ commands.
|
||||
We use |wmiir setsid| to launch programs with their own session
|
||||
IDs to prevent untoward effects when this script dies.
|
||||
|
||||
\begin{code}
|
||||
«Command Execution Initialization» ::=
|
||||
\begin{Fragment}{Command Execution Initialization}
|
||||
terminal() { wmiir setsid xterm “$@” }
|
||||
proglist() {
|
||||
IFS=:
|
||||
wmiir proglist $1 | sort | uniq
|
||||
unset IFS
|
||||
}
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\subsection{Key Bindings}
|
||||
\begin{code}
|
||||
«Command Execution Keys» ::=
|
||||
\begin{Fragment}{Command Execution Keys}
|
||||
Mod4-Return) terminal & ;;
|
||||
Mod4-p) eval exec wmiir setsid "$(proglist $PATH | wimenu)" &;;
|
||||
Mod4-p) eval exec wmiir setsid “$(proglist $PATH | wimenu)” &;;
|
||||
Mod4-a) {
|
||||
set -- $(proglist $WMII_CONFPATH | wimenu)
|
||||
which=$(which which)
|
||||
prog=$(PATH=$WMII_CONFPATH $which $1); shift
|
||||
eval exec $prog “$@”
|
||||
} &;;
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\section{The Root}
|
||||
|
||||
@ -1243,9 +1324,9 @@ The root filesystem contains the following:
|
||||
searched for the executable. Otherwise, the whole
|
||||
argument is passed to the shell for evaluation.
|
||||
\end{description}
|
||||
\item[keys] The global keybindings. See section \ref{keybindings}.
|
||||
\item[keys] The global keybindings. See section \ref{sec:keybindings}.
|
||||
\index{filesystem!/!keys|primary}
|
||||
\item[event] The global event feed. See section \ref{keybindings}.
|
||||
\item[event] The global event feed. See section \ref{sec:keybindings}.
|
||||
\index{filesystem!/!event|primary}
|
||||
\item[colrules]
|
||||
\index{filesystem!/!colrules}
|
||||
@ -1260,7 +1341,7 @@ The root filesystem contains the following:
|
||||
Where,
|
||||
|
||||
\begin{code}
|
||||
‹width› := ‹percent of screen› | ‹pixels›px
|
||||
‹width› ≔ ‹percent of screen› | ‹pixels›px
|
||||
\end{code}
|
||||
|
||||
When a new column, ‹n›, is created on a view whose name
|
||||
@ -1306,8 +1387,7 @@ The root filesystem contains the following:
|
||||
We'll need to let \wmii\ know about our previously defined theme
|
||||
information:
|
||||
|
||||
\begin{code}
|
||||
«Configuration» ::=
|
||||
\begin{Fragment}{Configuration}
|
||||
«Theme Definitions»
|
||||
|
||||
xsetroot -solid $background
|
||||
@ -1318,14 +1398,13 @@ information:
|
||||
font $font
|
||||
grabmod Mod4
|
||||
!
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\subsection{Key Bindings}
|
||||
|
||||
And we need a few more key bindings to select our views:
|
||||
|
||||
\begin{code}
|
||||
«Tag Selection Keys» ::=
|
||||
\begin{Fragment}{Tag Selection Keys}
|
||||
Mod4-t)
|
||||
# Prompt the user for a tag
|
||||
tags=$(wmiir ls /tag | sed ‘s,/,,; /^sel$/d’ | wimenu)
|
||||
@ -1333,7 +1412,7 @@ And we need a few more key bindings to select our views:
|
||||
wmiir xwrite /ctl view $tags;;
|
||||
Mod4-[0-9])
|
||||
wmiir xwrite /ctl view ${1##*-};;
|
||||
\end{code}
|
||||
\end{Fragment}
|
||||
|
||||
\section{Tieing it All Together}
|
||||
|
||||
@ -1501,7 +1580,7 @@ For clarity, here is the end result:
|
||||
|
||||
# «Command Execution Keys»
|
||||
Mod4-Return) terminal & ;;
|
||||
Mod4-p) eval exec wmiir setsid "$(proglist $PATH | wimenu)" &;;
|
||||
Mod4-p) eval exec wmiir setsid “$(proglist $PATH | wimenu)” &;;
|
||||
Mod4-a) {
|
||||
set -- $(proglist $WMII_CONFPATH | wimenu)
|
||||
prog=$(PATH=$WMII_CONFPATH which $1); shift
|
||||
|
@ -17,8 +17,10 @@
|
||||
#ifndef offsetof
|
||||
# define offsetof(type, member) ((size_t)&((type*)0)->member)
|
||||
#endif
|
||||
#define structptr(ptr, type, offset) \
|
||||
((type*)((char*)(ptr) + (offset)))
|
||||
#define structmember(ptr, type, offset) \
|
||||
(*(type*)((char*)(ptr) + (offset)))
|
||||
(*structptr(ptr, type, offset))
|
||||
|
||||
#undef uchar
|
||||
#undef ushort
|
||||
|
@ -157,6 +157,8 @@ key binding quick-reference.
|
||||
| Mod-k | Move to a window _above_ the one currently focused
|
||||
| Mod-space | Toggle between the managed and floating layers
|
||||
| Mod-t <tag> | Move to the view of the given <tag>
|
||||
| Mod-n | Move to the next view
|
||||
| Mod-b | Move to the previous view
|
||||
| Mod-//[0-9]// | Move to the view with the given number
|
||||
|
||||
=== Moving Things Around ===
|
||||
@ -473,12 +475,9 @@ under '/rbar/' appear on the right, with the leftmost item
|
||||
occupying all extra available space. The items are sorted
|
||||
lexicographically.
|
||||
|
||||
The files may be read to obtain the colors and text of the bars.
|
||||
The colors are at the beginning of the string, represented as a
|
||||
tuple of 3 hex color codes for the foreground, background, and
|
||||
border, respectively. When writing the bar files, the colors may
|
||||
be omitted if the text would not otherwise appear to contain
|
||||
them.
|
||||
The files may be read or written to obtain or alter the colors
|
||||
and text of the bars. The format is similar to the various _ctl_
|
||||
files and should be self explanitory.
|
||||
|
||||
= FILES =
|
||||
|
||||
|
43
rc/wmiirc.sh
43
rc/wmiirc.sh
@ -65,7 +65,7 @@ wmiir write /rules <<!
|
||||
|
||||
# Status Bar Info
|
||||
status() {
|
||||
echo -n $(uptime | sed 's/.*://; s/,//g') '|' $(date)
|
||||
echo -n label $(uptime | sed 's/.*://; s/,//g') '|' $(date)
|
||||
}
|
||||
|
||||
# Generic overridable startup details
|
||||
@ -75,26 +75,26 @@ local_events() { true;}
|
||||
wi_runconf -s wmiirc_local
|
||||
startup
|
||||
|
||||
echo $WMII_NORMCOLORS | wmiir create $noticebar
|
||||
echo colors $WMII_NORMCOLORS | wmiir create $noticebar
|
||||
|
||||
# Event processing
|
||||
events() {
|
||||
cat <<'!'
|
||||
# Events
|
||||
Event CreateTag
|
||||
echo "$WMII_NORMCOLORS" "$@" | wmiir create "/lbar/$@"
|
||||
echo colors "$WMII_NORMCOLORS$wi_newline" label "$@" | wmiir create "/lbar/$@"
|
||||
Event DestroyTag
|
||||
wmiir remove "/lbar/$@"
|
||||
Event FocusTag
|
||||
wmiir xwrite "/lbar/$@" "$WMII_FOCUSCOLORS" "$@"
|
||||
wmiir xwrite "/lbar/$@" colors "$WMII_FOCUSCOLORS"
|
||||
Event UnfocusTag
|
||||
wmiir xwrite "/lbar/$@" "$WMII_NORMCOLORS" "$@"
|
||||
wmiir xwrite "/lbar/$@" colors "$WMII_NORMCOLORS"
|
||||
Event UrgentTag
|
||||
shift
|
||||
wmiir xwrite "/lbar/$@" "*$@"
|
||||
wmiir xwrite "/lbar/$@" label "*$@"
|
||||
Event NotUrgentTag
|
||||
shift
|
||||
wmiir xwrite "/lbar/$@" "$@"
|
||||
wmiir xwrite "/lbar/$@" label "$@"
|
||||
Event LeftBarClick LeftBarDND
|
||||
shift
|
||||
wmiir xwrite /ctl view "$@"
|
||||
@ -129,19 +129,12 @@ Event ClientMouseDown
|
||||
Menu LBar-3-Delete
|
||||
tag=$1; clients=$(wmiir read "/tag/$tag/index" | awk '/[^#]/{print $2}')
|
||||
for c in $clients; do
|
||||
if [ "$tag" = "$(wmiir read /client/$c/tags)" ]; then
|
||||
wmiir xwrite /client/$c/ctl kill
|
||||
else
|
||||
wmiir xwrite /client/$c/tags -$tag
|
||||
fi
|
||||
if [ "$tag" = "$(wi_seltag)" ]; then
|
||||
newtag=$(wi_tags | awk -v't='$tag '
|
||||
$1 == t { if(!l) getline l
|
||||
print l
|
||||
exit }
|
||||
{ l = $0 }')
|
||||
wmiir xwrite /ctl view $newtag
|
||||
if [ "$tag" = "$(wmiir read /client/$c/tags)" ]
|
||||
then wmiir xwrite /client/$c/ctl kill
|
||||
else wmiir xwrite /client/$c/tags -$tag
|
||||
fi
|
||||
[ "$tag" = "$(wi_seltag)" ] &&
|
||||
wmiir xwrite /ctl view $(wi_tags | wi_nexttag)
|
||||
done
|
||||
Event LeftBarMouseDown
|
||||
wi_fnmenu LBar "$@" &
|
||||
@ -160,7 +153,7 @@ Action status
|
||||
if wmiir remove /rbar/status 2>/dev/null; then
|
||||
sleep 2
|
||||
fi
|
||||
echo "$WMII_NORMCOLORS" | wmiir create /rbar/status
|
||||
echo colors "$WMII_NORMCOLORS" | wmiir create /rbar/status
|
||||
while status | wmiir write /rbar/status; do
|
||||
sleep 1
|
||||
done
|
||||
@ -238,6 +231,10 @@ Key $MODKEY-t # Change to another tag
|
||||
Key $MODKEY-Shift-t # Retag the selected client
|
||||
# Assumes left-to-right order of evaluation
|
||||
wmiir xwrite /client/$(wi_selclient)/tags $(wi_tags | wimenu -h "${hist}.tags" -n 50) &
|
||||
Key $MODKEY-n # Move to the next tag
|
||||
wmiir xwrite /ctl view $(wi_tags | wi_nexttag)
|
||||
Key $MODKEY-b # Move to the previous tag
|
||||
wmiir xwrite /ctl view $(wi_tags | sort -r | wi_nexttag)
|
||||
!
|
||||
for i in 0 1 2 3 4 5 6 7 8 9; do
|
||||
cat <<!
|
||||
@ -273,9 +270,11 @@ unset IFS
|
||||
wi_tags | while read tag
|
||||
do
|
||||
if [ "$tag" = "$seltag" ]; then
|
||||
echo "$WMII_FOCUSCOLORS" "$tag"
|
||||
echo colors "$WMII_FOCUSCOLORS"
|
||||
echo label $tag
|
||||
else
|
||||
echo "$WMII_NORMCOLORS" "$tag"
|
||||
echo colors "$WMII_NORMCOLORS"
|
||||
echo label $tag
|
||||
fi | wmiir create "/lbar/$tag"
|
||||
done
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user