wmii

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

commit 089bf7bba73d942a750de55a5be8569be9fd6710
parent a6df12242456734d736730960dc310905af779ab
Author: Kris Maglione <kris@suckless.org>
Date:   Thu,  7 Oct 2010 16:31:42 -0400

[wimenu] Add paste key binding.

Diffstat:
cmd/menu/Makefile | 2+-
cmd/menu/dat.h | 1+
cmd/menu/keys.c | 1+
cmd/menu/keys.txt | 90++++++++++++++++++++++++++++++++++++++++---------------------------------------
cmd/menu/main.c | 5+++++
cmd/menu/menu.c | 10++++++++++
include/stuff/x11.h | 1+
lib/libstuff/Makefile | 1+
lib/libstuff/x11/selection.c | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/libstuff/x11/xatom.c | 2+-
man/wimenu.1 | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
man/wimenu.man1 | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mk/common.mk | 2+-
mk/dir.mk | 3+++
mk/hdr.mk | 2+-
15 files changed, 270 insertions(+), 48 deletions(-)

diff --git a/cmd/menu/Makefile b/cmd/menu/Makefile @@ -11,7 +11,7 @@ bindings.c: keys.txt Makefile TARG = wimenu HFILES= dat.h fns.h -TAGFILES= dat.h +TAGFILES= dat.h $(ROOT)/include/*.h $(ROOT)/include/stuff/*.h PACKAGES += $(X11PACKAGES) diff --git a/cmd/menu/dat.h b/cmd/menu/dat.h @@ -38,6 +38,7 @@ enum { LLITERAL, LNEXT, LNEXTPAGE, + LPASTE, LPREV, LPREVPAGE, LREJECT, diff --git a/cmd/menu/keys.c b/cmd/menu/keys.c @@ -84,6 +84,7 @@ char *symtab[] = { "literal", "next", "nextpage", + "paste", "prev", "prevpage", "reject", diff --git a/cmd/menu/keys.txt b/cmd/menu/keys.txt @@ -1,49 +1,51 @@ -Control-j Accept -Control-m Accept -Return Accept -Control-Shift-j Accept literal -Control-Shift-m Accept literal -Shift-Return Accept literal +Control-j Accept +Control-m Accept +Return Accept +Control-Shift-j Accept literal +Control-Shift-m Accept literal +Shift-Return Accept literal Escape Reject Control-Bracketleft Reject -Left Backward char -Control-b Backward char -Right Forward char -Control-f Forward char - -Mod1-b Backward word -Mod1-f Forward word - -Control-a Backward line -Control-e Forward line - -Control-p History backward -Up History backward -Control-n History forward -Down History forward - -Backspace Kill char -Control-h Kill char -Control-Backspace Kill word -Control-w Kill word -Control-u Kill line - -Tab Complete next -Control-i Complete next -Mod1-l Complete next - -Shift-Tab Complete prev -Control-Shift-i Complete prev -Mod1-h Complete prev - -Prior Complete prevpage -Mod1-k Complete prevpage -Next Complete nextpage -Mod1-j Complete nextpage -Home Complete first -Mod1-g Complete first -End Complete last -Mod1-Shift-g Complete last +Left Backward char +Control-b Backward char +Right Forward char +Control-f Forward char + +Mod1-b Backward word +Mod1-f Forward word + +Control-a Backward line +Control-e Forward line + +Control-p History backward +Up History backward +Control-n History forward +Down History forward + +Backspace Kill char +Control-h Kill char +Control-Backspace Kill word +Control-w Kill word +Control-u Kill line + +Tab Complete next +Control-i Complete next +Mod1-l Complete next + +Mod1-p Paste PRIMARY + +Shift-Tab Complete prev +Control-Shift-i Complete prev +Mod1-h Complete prev + +Prior Complete prevpage +Mod1-k Complete prevpage +Next Complete nextpage +Mod1-j Complete nextpage +Home Complete first +Mod1-g Complete first +End Complete last +Mod1-Shift-g Complete last diff --git a/cmd/menu/main.c b/cmd/menu/main.c @@ -172,6 +172,11 @@ init_screens(void) { menu_show(); } +ErrorCode ignored_xerrors[] = { + { 0, BadWindow }, + { X_GetAtomName, BadAtom }, +}; + int main(int argc, char *argv[]) { static char *address; diff --git a/cmd/menu/menu.c b/cmd/menu/menu.c @@ -213,6 +213,13 @@ selectitem(Item *i) { } } +static void +paste(void *aux, char *str) { + if(str) + caret_insert(str, false); + menu_draw(); +} + static bool kdown_event(Window *w, void *aux, XKeyEvent *e) { char **action, **p; @@ -321,6 +328,9 @@ kdown_event(Window *w, void *aux, XKeyEvent *e) { caret_move(FORWARD, amount); update_input(); break; + case LPASTE: + getselection(action[1] ? action[1] : "PRIMARY", paste, nil); + break; case LREJECT: srv.running = false; result = 1; diff --git a/include/stuff/x11.h b/include/stuff/x11.h @@ -277,6 +277,7 @@ ulong getproperty(Window*, char *prop, char *type, Atom *actual, ulong offset, u Rectangle getwinrect(Window*); int grabkeyboard(Window*); int grabpointer(Window*, Window *confine, Cursor, int mask); +void getselection(char*, void (*)(void*, char*), void*); bool havexft(void); void initdisplay(void); KeyCode keycode(const char*); diff --git a/lib/libstuff/Makefile b/lib/libstuff/Makefile @@ -96,6 +96,7 @@ OBJ=\ x11/ignored_xerrors \ x11/freestringlist \ x11/initdisplay \ + x11/selection \ x11/sendevent \ x11/sendmessage \ x11/sync \ diff --git a/lib/libstuff/x11/selection.c b/lib/libstuff/x11/selection.c @@ -0,0 +1,63 @@ +/* Copyright ©2010 Kris Maglione <maglione.k at Gmail> + * See LICENSE file for license details. + */ +#include "x11.h" + +static Handlers handlers; + +typedef struct Data Data; + +struct Data { + long selection; + void (*callback)(void*, char*); + void* aux; +}; + +static bool +_getselection(Window *w, long selection, char *type) { + XConvertSelection(display, selection, xatom(type), + selection, w->xid, CurrentTime); + return true; +} + +void +getselection(char *selection, void (*callback)(void*, char*), void *aux) { + Window *w; + Data *d; + + d = emallocz(sizeof *d); + d->selection = xatom(selection); + d->callback = callback; + d->aux = aux; + + w = createwindow(&scr.root, Rect(0, 0, 1, 1), 0, InputOnly, nil, 0); + w->aux = d; + sethandler(w, &handlers); + + _getselection(w, d->selection, "UTF8_STRING"); +} + +static bool +selection_event(Window *w, void *aux, XSelectionEvent *ev) { + Data *d; + char **ret; + + d = aux; + if(ev->property == None && ev->target != xatom("STRING")) + return _getselection(w, d->selection, "STRING"); + else if(ev->property == None) + d->callback(d->aux, nil); + else { + getprop_textlist(w, atomname(ev->property), &ret); + delproperty(w, atomname(ev->property)); + d->callback(d->aux, ret ? *ret : nil); + free(ret); + } + destroywindow(w); + return false; +} + +static Handlers handlers = { + .selection = selection_event, +}; + diff --git a/lib/libstuff/x11/xatom.c b/lib/libstuff/x11/xatom.c @@ -24,7 +24,7 @@ atomname(ulong atom) { e = map_get(&atomnamemap, atom, true); if(*e == nil) { *e = XGetAtomName(display, atom); - if(&e == nil) { + if(*e == nil) { map_rm(&atomnamemap, atom); return nil; } diff --git a/man/wimenu.1 b/man/wimenu.1 @@ -85,6 +85,84 @@ as a menu option, and the text to the right is displayed when a selection is made. .RE +.SH KEY BINDINGS +.P +\fBwimenu\fR's default key bindings are based largely on the +movement keys of vi and the standard UNIX shell input bindings. + +.TP +Return, C\-j, C\-m +Accept the input, and select the first matching +completion if the cursor is at the end of the input. +.TP +S\-Return, C\-S\-j, C\-S\-m +Accept the input literally. +.TP +Esc, C\-[ +Quit without returning any output, and exit with +non\-zero status. + +.TP +A\-p +Paste the PRIMARY selection. + +.TP +Left, C\-b +Move backward one character. +.TP +Right, C\-f +Move forward one character. + +.TP +A\-b +Move backward one word. +.TP +A\-f +Move forward one word. + +.TP +C\-a +Move to the begining of the line. +.TP +C\-e +Move to the end of the line. + +.TP +C\-p, up +Move backward through the input history. +.TP +C\-n, up +Move forward through the input history. + +.TP +Backspace, C\-h +Delete the previous character. +.TP +C\-Backspace, C\-w +Delete the previous word. +.TP +C\-u +Delete the previous portion of the line. + +.TP +Tab, C\-i¸ A\-l +Select the next completion. +.TP +S\-Tab, C\-S\-i, A\-h +Select the previous completion. +.TP +PageUp, A\-k +Select the previous completion page. +.TP +PageDown, A\-j +Select the next completion page. +.TP +Home, A\-g +Select the first completion page. +.TP +End, A\-S\-g +Select the last completion page. + .SH CUSTOM COMPLETION .P Custom, multipart completion data may be proveded by an diff --git a/man/wimenu.man1 b/man/wimenu.man1 @@ -76,6 +76,63 @@ following. More advanced options are documented below. as a menu option, and the text to the right is displayed when a selection is made. += KEY BINDINGS = + +`wimenu`'s default key bindings are based largely on the +movement keys of vi and the standard UNIX shell input bindings. + +: Return, C-j, C-m + Accept the input, and select the first matching + completion if the cursor is at the end of the input. +: S-Return, C-S-j, C-S-m + Accept the input literally. +: Esc, C-[ + Quit without returning any output, and exit with + non-zero status. + +: A-p + Paste the PRIMARY selection. + +: Left, C-b + Move backward one character. +: Right, C-f + Move forward one character. + +: A-b + Move backward one word. +: A-f + Move forward one word. + +: C-a + Move to the begining of the line. +: C-e + Move to the end of the line. + +: C-p, Up + Move backward through the input history. +: C-n, Down + Move forward through the input history. + +: Backspace, C-h + Delete the previous character. +: C-Backspace, C-w + Delete the previous word. +: C-u + Delete the previous portion of the line. + +: Tab, C-i¸ A-l + Select the next completion. +: S-Tab, C-S-i, A-h + Select the previous completion. +: PageUp, A-k + Select the previous completion page. +: PageDown, A-j + Select the next completion page. +: Home, A-g + Select the first completion page. +: End, A-S-g + Select the last completion page. +: = CUSTOM COMPLETION = Custom, multipart completion data may be proveded by an diff --git a/mk/common.mk b/mk/common.mk @@ -42,7 +42,7 @@ tags: [ -f "$$f.c" ] && files="$$files $$f.c"; \ done; \ echo CTAGS $$files $(TAGFILES); \ - $(DEBUG) $(CTAGS) $$files $(TAGFILES) + if [ -n "$$files" ]; then $(DEBUG) $(CTAGS) $$files $(TAGFILES); fi .PHONY: all options clean dist install uninstall depend cleandep tags .PHONY: simpleuninstall simpleinstall diff --git a/mk/dir.mk b/mk/dir.mk @@ -21,12 +21,15 @@ duninstall: +dirs="$(INSTDIRS)"; $(MKSUBDIR) ddepend: +dirs="$(DIRS)"; $(MKSUBDIR) +dtags: + +dirs="$(DIRS)"; $(MKSUBDIR) all: dall clean: dclean install: dinstall uninstall: duninstall depend: ddepend +tags: dtags INSTDIRS = $(DIRS) diff --git a/mk/hdr.mk b/mk/hdr.mk @@ -34,7 +34,7 @@ CLEANNAME=$(SHELL) $(ROOT)/util/cleanname SOEXT=so TAGFILES= -CTAGS=ctags +CTAGS=ctags --fields=+S --c-kinds=+px PACKAGES =