Fix last commit.

This commit is contained in:
Kris Maglione 2010-06-11 23:48:29 -04:00
parent f1a6e75d10
commit e5e4ff284d
28 changed files with 358 additions and 67 deletions

113
FAQ Normal file
View File

@ -0,0 +1,113 @@
wmii 3.10
@@ If you're reading this file before it's been installed,
@@ substitute the following directories for their placeholders.
@@ @DOCDIR@ doc/
@@ @EXAMPLES@ examples/
@@ @LOCALCONF@ ~/.wmii or ~/.wmii-hg (if this is a snapshot)
@@ @ALTDOC@ alternative_wmiircs/
@@
Frequently Asked Questions
==========================
1. I've just upgraded and something doesn't work.
-------------------------------------------------
If you compiled wmii yourself, please try again from a clean source
tree. If wmii still fails, try deleting or renaming your old
configuration files. If this fails, see questions #2.
2. I've read all of the docs, but I still need help.
----------------------------------------------------
You can get support[1] in the #suckless irc channel on irc.oftc.net, or
you can subscribe to the mailing list by sending an email to
dev+subscribe@suckless.org. You can also browse or search the
mailing list archives[2] at Gmane.
3. I think I've found a bug.
----------------------------
You can report bugs at the issue tracker at the Google Code
project[3]. Please be sure to search for your problem before you
open a new issue.
4. How do I get a list of keyboard shortcuts?
---------------------------------------------
The default keyboard shortcuts are listed in both the wmii(1)
manpage and in the user guide[4]. You can also get a list of all
current keyboard shortcuts at any time by selecting 'showkeys' from
the actions menu (M-a).
5. How do I customize wmii? How do I change my keyboard shortcuts?
------------------------------------------------------------------
You can customize wmii by editing its configuration script. If
you're using the stock wmiirc configuration script, you can add key
bindings and change your theme by editing @LOCALCONF@/wmiirc_local.
See @EXAMPLES@/wmiirc_local for more information. You should also be
sure to read wmii(1) and the user guide[4].
6. I've heard I can do my configuration in any language?
--------------------------------------------------------
While wmii is driven by a sh(1) script by default, it ships with
configuration scripts in several other languages, and more still are
available elsewhere on the web. See @ALTDOC@/README for more
information.
7. I've made some changes to my configuration. How do I reload it?
------------------------------------------------------------------
You can rerun your wmiirc script from the actions menu at any time.
If you're running the stock wmiirc, just select wmiirc. If you're
running the python wmiirc (and haven't moved it to
@LOCALCONF@/wmiirc), type python/wmiirc, and so on.
8. How do I restart wmii without killing X?
-------------------------------------------
You can either run 'exec wmii' from the actions menu or write
'exec wmii' to the /ctl virtual file.
9. Why is there space around my terminal windows?
-------------------------------------------------
Your terminal has asked to only be resized in certain increments,
and there's not enough space for another row. `wmii` is forced to
compromise and leave blank space around it. If you'd rather wmii to
ignore the terminal's request, write 'incmode ignore'[5] to the /ctl
virtual file.
10. On FreeBSD, using p9p[6], I get an error about not being able to open /dev/fd/7.
------------------------------------------------------------------------------------
You need to mount fdescfs on /dev/fd. See the BUGS section of rc(1)
for details.
11. How do I set a background image?
------------------------------------
This isn't the job of a window manager. You can set the background
with a third party tool, such as wmsetbg, Esetbg, feh, qiv,
xsetroot, etc.
12. How do I enable sequential shortcuts (like in ratpoison)?
or How do I use wmii with emacs? The shortcuts collide!
-------------------------------------------------------------
Some applications make extensive use of the Alt key. The preferred
solution is to use the Windows, Apple, or Penguin key in its place.
It's assigned the identifier Mod4 on most systems. Set the
following in wmiirc_local:
MODKEY=Mod4
Alternatively, you can use key chains, so you're required to press a
certain key combination before wmii accepts its shortcuts:
MODKEY=Control-i,
13. How do I find out the names of keys to define keyboard shorcuts?
--------------------------------------------------------------------
The easiest way is to run wikeyname(1) and type the key you want to
bind.
[1] http://suckless.org/community
[2] http://dir.gmane.org/gmane.comp.misc.suckless
[3] http://wmii.googlecode.com/
[4] @DOCDIR@/wmii.pdf
[5] For more information, see wmii(1).
[6] http://plan9.us

View File

@ -10,8 +10,9 @@ DIRS = \
rc \
alternative_wmiircs
DOCS = README \
LICENSE
DOCS = FAQ \
LICENSE \
README
deb-dep:
IFS=', '; \

4
README
View File

@ -47,8 +47,8 @@ Configuration
-------------
The configuration of wmii is done by customizing the rc script wmiirc,
which remotely controls the window manager and handles various events.
The main wmiirc script lives in @CONFPREFIX@/wmii@CONFVERSION@/, while
wmiirc_local goes in $HOME/.wmii@CONFVERSION@/.
The main wmiirc script lives in @GLOBALCONF@ while wmiirc_local goes
in @LOCALCONF@.
More advanced versions of wmiirc are provided in python and ruby.
For more information on them, see alternative_wmiircs/README.

View File

@ -11,7 +11,7 @@ It usually suffices to start the included `wmiirc` script at
wmii startup. Invoking wmii with the flag '-r python/wmiirc',
for instance, will start the python implementation.
Alternatively, if you use a session manager, you can add this
line to ~/.wmii/wmiirc (which must be executable):
line to @LOCALCONF@/wmiirc (which must be executable):
wmiir xwrite /ctl spawn python/wmiirc

View File

@ -5,6 +5,6 @@ This directory contains a Plan 9 based wmiirc script. This script was
traditionally the default wmiirc for wmii, but has been moved for
portability reasons. To run this script, either Plan 9 from User
Space[1] (plan9port for short) or 9base[2] is required. Modifications
can be placed in $home/.wmii@CONFVERSION@/wmiirc_local.rc, which must
can be placed in @LOCALCONF@/wmiirc_local.rc, which must
be executable.

View File

@ -5,7 +5,7 @@ This directory contains a pure Python implementation of
wmiirc. The two included libraries, pyxp and pygmi, are a 9P
client and wmii filesystem utility module, respectively. To
use this library, simply copy the contents of this direcctory
to ~/.wmii/. To customize it, either modify wmiirc.py
to @LOCALCONF@. To customize it, either modify wmiirc.py
directly, or create wmii_local.py and store your modifications
there. The latter approach is preferable in that future
modifications to wmiirc.py can usually be painlessly

View File

@ -81,6 +81,8 @@ class Ctl(object):
assert '\n' not in key
self.cache[key] = val
if key in self.ctl_types:
if self.ctl_types[key][1] is None:
raise NotImplementedError('%s: %s is not writable' % (self.ctl_path, key))
val = self.ctl_types[key][1](val)
self.ctl(key, val)
@ -91,7 +93,7 @@ class Ctl(object):
doesn't exist, a KeyError is raised.
"""
try:
val = self[key]
return self[key]
except KeyError, e:
if default is not self.sentinel:
return default
@ -165,7 +167,7 @@ class Dir(Ctl):
def __init__(self, key):
self.key = key
def __get__(self, dir, cls):
return dir[self.key]
return dir.get(self.key, None)
def __set__(self, dir, val):
dir[self.key] = val
@ -178,6 +180,9 @@ class Dir(Ctl):
props = {
'on': True,
'off': False,
'toggle': Toggle,
'always': Always,
'never': Never
}
def __get__(self, dir, cls):
val = dir[self.key]
@ -234,12 +239,19 @@ class Client(Dir):
below /client.
"""
base_path = '/client'
ctl_types = {
'group': (lambda s: int(s, 16), str),
'pid': (int, None),
}
allow = Dir.ctl_property('allow')
fullscreen = Dir.toggle_property('fullscreen')
group = Dir.ctl_property('group')
pid = Dir.ctl_property('pid')
tags = Dir.ctl_property('tags')
urgent = Dir.toggle_property('urgent')
label = Dir.file_property('label', writable=True)
tags = Dir.file_property('tags', writable=True)
props = Dir.file_property('props')
def kill(self):
@ -615,6 +627,8 @@ class Rule(collections.MutableMapping, utf8):
@classmethod
def quotekey(cls, key):
if key.endswith('_'):
key = key[:-1]
return key.replace('_', '-')
@classmethod
def quotevalue(cls, val):
@ -752,11 +766,16 @@ class Tags(object):
def select(self, tag, take_client=None):
def goto(tag):
if take_client:
# Make a new instance in case this is Client('sel'),
# which would cause problems given 'sel' changes in the
# process.
client = Client(take_client.id)
sel = Tag('sel').id
take_client.tags = '+%s' % tag
client.tags = '+%s' % tag
wmii['view'] = tag
if tag != sel:
take_client.tags = '-%s' % sel
client.tags = '-%s' % sel
else:
wmii['view'] = tag

View File

@ -62,7 +62,7 @@ def time(self):
wmii.rules = (
# Apps with system tray icons like to their main windows
# Give them permission.
(ur'^Pidgin:' dict(allow='+activate')),
(ur'^Pidgin:', dict(allow='+activate')),
# MPlayer and VLC don't float by default, but should.
(ur'MPlayer|VLC', dict(floating=True)),

View File

@ -8,10 +8,9 @@ string interpolation in key bindings, as should be apparent in
the included config.yaml.
In particular, not that there is no need to copy any files to
~/.wmii-hg or ~/.wmii other than config.yaml. The script will
happily load the requisite files from their default install
location. They can be loaded either by involing wmii as
follows:
@LOCALCONF@ other than config.yaml. The script will happily load
the requisite files from their default install location. They
can be loaded either by involing wmii as follows:
wmiir -r ruby/wmiirc
@ -51,11 +50,11 @@ Installation:
gem install librmpd # optional
# install
mv ~/.wmii-hg ~/.wmii-hg.backup
git clone git://github.com/sunaku/wmiirc.git ~/.wmii-hg
mv @LOCALCONF@ @LOCALCONF@.backup
git clone git://github.com/sunaku/wmiirc.git @LOCALCONF@
# choose
cd ~/.wmii-hg
cd @LOCALCONF@
git checkout --track -b CHOICE origin/CHOICE # choices are:
+--------+------------------------------------------------+
@ -68,21 +67,21 @@ Installation:
+--------+------------------------------------------------+
# run
~/.wmii-hg/wmiirc
@LOCALCONF@/wmiirc
Documentation:
# see list of all key bindings
egrep '^ +\$\{\w+\}' ~/.wmii-hg/config.yaml
egrep '^ +\$\{\w+\}' @LOCALCONF@/config.yaml
# read the configuration file
less ~/.wmii-hg/config.yaml
less @LOCALCONF@/config.yaml
Configuration:
Edit ~/.wmii-hg/config.yaml to your liking.
Edit @LOCALCONF@/config.yaml to your liking.
Run ~/.wmii-hg/wmiirc to apply your changes.
Run @LOCALCONF@/wmiirc to apply your changes.
Contribution:

View File

@ -5,6 +5,7 @@ include $(ROOT)/mk/wmii.mk
wmiir.c: $(ROOT)/mk/wmii.mk
DIRS = wmii \
keyname \
menu \
strut \
tray

15
cmd/keyname/Makefile Normal file
View File

@ -0,0 +1,15 @@
ROOT= ../..
include $(ROOT)/mk/hdr.mk
include $(ROOT)/mk/wmii.mk
main.c: $(ROOT)/mk/wmii.mk
TARG = wikeyname
PACKAGES += $(X11PACKAGES)
LIB = $(LIBS9)
OBJ = main
include $(ROOT)/mk/one.mk

85
cmd/keyname/main.c Normal file
View File

@ -0,0 +1,85 @@
/* Copyright ©2010 Kris Maglione <maglione.k at Gmail>
* See LICENSE file for license details.
*/
#include <stuff/util.h>
#include <stuff/x.h>
#include <fmt.h>
#include <locale.h>
static const char version[] = "wikeyname-"VERSION", "COPYRIGHT"\n";
static Handlers handlers;
static char* keyname;
static int nkeys;
static void
usage(void) {
fprint(2, "usage: wikeyname\n");
exit(1);
}
int
main(int argc, char *argv[]) {
setlocale(LC_CTYPE, "");
ARGBEGIN{
default: usage();
}ARGEND;
if(argc)
usage();
initdisplay();
selectinput(&scr.root, KeyPressMask|KeyReleaseMask);
sethandler(&scr.root, &handlers);
if(!grabkeyboard(&scr.root))
fatal("can't grab keyboard\n");
event_loop();
print("%s\n", keyname);
XCloseDisplay(display);
return 0;
}
static bool
kdown_event(Window *w, void *aux, XKeyEvent *ev) {
Fmt f;
char buf[32];
char *key;
KeySym ksym;
int num;
USED(aux);
nkeys++;
num = XLookupString(ev, buf, sizeof buf, &ksym, 0);
key = XKeysymToString(ksym);
fmtstrinit(&f);
unmask(&f, ev->state, modkey_names, '-');
if(f.nfmt)
fmtrune(&f, '-');
fmtstrcpy(&f, key);
free(keyname);
keyname = fmtstrflush(&f);
return false;
}
static bool
kup_event(Window *w, void *aux, XKeyEvent *ev) {
USED(w, aux, ev);
if(keyname != nil && --nkeys <= 0)
event_looprunning = false;
return false;
}
static Handlers handlers = {
.kup = kup_event,
.kdown = kdown_event,
};

View File

@ -164,8 +164,8 @@ main(int argc, char *argv[]) {
changeprop_ulong(testwin, "_WMII_STRUT", "WINDOW", testtime, nelem(testtime));
event_looprunning = windowmap.nmemb > 0;
event_loop();
if(windowmap.nmemb > 0)
event_loop();
XCloseDisplay(display);
return 0;

View File

@ -288,17 +288,9 @@ struct Mask {
static int
Mfmt(Fmt *f) {
Mask m;
int i;
m = va_arg(f->args, Mask);
for(i=0; m.table[i]; i++)
if(*m.mask & (1<<i)) {
if(*m.mask & ((1<<i)-1))
fmtstrcpy(f, "+");
if(fmtstrcpy(f, m.table[i]))
return -1;
}
return 0;
return unmask(f, *m.mask, m.table, '+');
}
char*
@ -338,7 +330,7 @@ fail:
}
static void
unmask(Mask m, char *s) {
setmask(Mask m, char *s) {
char *opt;
int add, old, i, n;
long newmask;
@ -366,7 +358,7 @@ unmask(Mask m, char *s) {
void
msg_debug(char *s) {
unmask((Mask){&debugflag, debugtab}, s);
setmask((Mask){&debugflag, debugtab}, s);
}
static Client*
@ -519,7 +511,7 @@ message_client(Client *c, IxpMsg *m) {
switch(getsym(s)) {
case LALLOW:
unmask((Mask){&c->permission, permtab}, msg_getword(m, 0));
setmask((Mask){&c->permission, permtab}, msg_getword(m, 0));
break;
case LFLOATING:
c->floating = -1 + _lsearch(msg_getword(m, Ebadvalue), floatingtab, nelem(floatingtab));

View File

@ -204,8 +204,8 @@ readmouse(Point *p, uint *button) {
p->y = ev.xmotion.y_root;
if(p->x == scr.rect.max.x - 1)
p->x = scr.rect.max.x;
if(p->y == scr.rect.max.x - 1)
p->y = scr.rect.max.x;
if(p->y == scr.rect.max.y - 1)
p->y = scr.rect.max.y;
break;
}
return ev.type;

View File

@ -43,12 +43,16 @@ enum {
#define strlcat stuff_strlcat
#define strcasestr stuff_strcasestr
int Blprint(Biobuf*, const char*, ...);
int Bvlprint(Biobuf*, const char*, va_list);
extern char* _buffer;
void _die(char*, int, char*, ...);
void backtrace(char*);
extern char buffer[8092];
void closeexec(int);
char** comm(int, char**, char**);
extern char* const _buf_end;
int doublefork(void);
void* emalloc(uint);
void* emallocz(uint);
@ -85,14 +89,11 @@ char* sxprint(const char*, ...);
uint tokenize(char**, uint, char*, char);
void trim(char *str, const char *chars);
void uniq(char**);
int unmask(Fmt*, long, char**, long);
int unquote(char*, char*[], int);
int utflcpy(char*, const char*, int);
int vlprint(int, const char*, va_list);
char* vsxprint(const char*, va_list);
extern char buffer[8092];
extern char* _buffer;
extern char* const _buf_end;
#define bufclear() \
BLOCK( _buffer = buffer; _buffer[0] = '\0' )
#define bufprint(...) \

View File

@ -55,6 +55,7 @@ void event_expose(XExposeEvent*);
void event_focusin(XFocusChangeEvent*);
void event_focusout(XFocusChangeEvent*);
void event_keypress(XKeyEvent*);
void event_keyrelease(XKeyEvent*);
void event_leavenotify(XCrossingEvent*);
void event_mapnotify(XMapEvent*);
void event_mappingnotify(XMappingEvent*);

View File

@ -207,6 +207,7 @@ struct Screen {
Display *display;
Screen scr;
extern char* modkey_names[];
extern struct Map windowmap;
extern struct Map atommap;
extern struct Map atomnamemap;

View File

@ -22,6 +22,7 @@ OBJ=\
event/focusout \
event/ixp \
event/keypress \
event/keyrelease \
event/leavenotify \
event/mapnotify \
event/maprequest \
@ -85,6 +86,7 @@ OBJ=\
util/tokenize \
util/trim \
util/uniq \
util/unmask \
util/unquote \
util/utflcpy \
util/vector \

View File

@ -20,6 +20,7 @@ EventHandler event_handler[LASTEvent] = {
[FocusIn] = (EventHandler)event_focusin,
[FocusOut] = (EventHandler)event_focusout,
[KeyPress] = (EventHandler)event_keypress,
[KeyRelease] = (EventHandler)event_keyrelease,
[LeaveNotify] = (EventHandler)event_leavenotify,
[MapNotify] = (EventHandler)event_mapnotify,
[MapRequest] = (EventHandler)event_maprequest,
@ -73,6 +74,7 @@ void
event_loop(void) {
XEvent ev;
event_looprunning = true;
while(event_looprunning) {
XNextEvent(display, &ev);
event_dispatch(&ev);

View File

@ -0,0 +1,14 @@
/* Copyright ©2006-2010 Kris Maglione <maglione.k at Gmail>
* See LICENSE file for license details.
*/
#include "event.h"
void
event_keyrelease(XKeyEvent *ev) {
Window *w;
if(!ev->send_event)
event_xtime = ev->time;
if((w = findwin(ev->window)))
event_handle(w, kup, ev);
}

View File

@ -0,0 +1,21 @@
#include "fmtdef.h"
void
vseprint(Fmt *f, char *buf, char *e) {
Fmt f;
if(e <= buf)
return nil;
f.runes = 0;
f.start = buf;
f.to = buf;
f.stop = e - 1;
f.flush = 0;
f.farg = nil;
f.nfmt = 0;
va_copy(f.args,args);
dofmt(&f, fmt);
va_end(f.args);
*(char*)f.to = '\0';
return (char*)f.to;
}

View File

@ -45,6 +45,7 @@
#include <stuff/util.h>
#include "printevent.h"
#define Window XWindow
#define unmask _unmask
#define nil ((void*)0)

View File

@ -0,0 +1,21 @@
/* Copyright ©2008-2010 Kris Maglione <maglione.k at Gmail>
* See LICENSE file for license details.
*/
#include <fmt.h>
#include "util.h"
int
unmask(Fmt *f, long mask, char **table, long sep) {
int i, nfmt;
nfmt = f->nfmt;
for(i=0; table[i]; i++)
if(*table[i] && (mask & (1<<i))) {
if(f->nfmt > nfmt)
fmtrune(f, sep);
if(fmtstrcpy(f, table[i]))
return -1;
}
return 0;
}

View File

@ -5,32 +5,29 @@
typedef struct KMask KMask;
static struct KMask {
int mask;
const char* name;
} masks[] = {
{ShiftMask, "Shift"},
{ControlMask, "Control"},
{Mod1Mask, "Mod1"},
{Mod2Mask, "Mod2"},
{Mod3Mask, "Mod3"},
{Mod4Mask, "Mod4"},
{Mod5Mask, "Mod5"},
{0,}
char *modkey_names[] = {
"Shift",
"",
"Control",
"Mod1",
"Mod2",
"Mod3",
"Mod4",
"Mod5",
nil
};
bool
parsekey(char *str, int *mask, char **key) {
static char *keys[16];
KMask *m;
int i, nkeys;
int i, j, nkeys;
*mask = 0;
nkeys = tokenize(keys, nelem(keys), str, '-');
for(i=0; i < nkeys; i++) {
for(m=masks; m->mask; m++)
if(!strcasecmp(m->name, keys[i])) {
*mask |= m->mask;
for(j=0; modkey_names[j]; j++)
if(!strcasecmp(modkey_names[j], keys[i])) {
*mask |= 1 << j;
goto next;
}
break;

View File

@ -592,10 +592,10 @@ them.
/tmp/ns.\fB$USER\fR.\fB${DISPLAY\fR%.0\fB}\fR/wmii
The wmii socket file which provides a 9P service.
.TP
@CONFPREFIX@/wmii@CONFVERSION@
@GLOBALCONF@
Global action directory.
.TP
\fB$HOME\fR/.wmii@CONFVERSION@
@LOCALCONF@
User\-specific action directory. Actions are first searched here.

View File

@ -492,9 +492,9 @@ them.
: /tmp/ns.$USER.${DISPLAY%.0}/wmii
The wmii socket file which provides a 9P service.
: @CONFPREFIX@/wmii@CONFVERSION@
: @GLOBALCONF@
Global action directory.
: $HOME/.wmii@CONFVERSION@
: @LOCALCONF@
User-specific action directory. Actions are first searched here.
:

View File

@ -18,10 +18,15 @@ LIBS9 = $(ROOT)/lib/libstuff.a $(ROOT)/lib/libregexp9.a $(ROOT)/lib/libbio.a $(R
CFLAGS += '-DVERSION=\"$(VERSION)\"' '-DCOPYRIGHT=\"$(COPYRIGHT)\"' \
'-DCONFVERSION=\"$(CONFVERSION)\"' '-DCONFPREFIX=\"$(ETC)\"'
FILTER = sed "s|@CONFPREFIX@|$(ETC)|g; \
s|@GLOBALCONF@|$(ETC)/wmii$(CONFVERSION)|g; \
s|@LOCALCONF@|~/.wmii$(CONFVERSION)|g; \
s|@CONFVERSION@|$(CONFVERSION)|g; \
s|@DOCDIR@|$(DOC)|g; \
s|@ALTDOC@|$(DOC)/alternative_wmiircs|g; \
s|@EXAMPLES@|$(DOC)/examples|g; \
s|@VERSION@|$(VERSION)|g; \
s|@LIBDIR@|$(LIBDIR)|g; \
s|@BINSH@|$(BINSH)|g; \
s|@TERMINAL@|$(TERMINAL)|g;"
s|@TERMINAL@|$(TERMINAL)|g; \
/^@@/d;"