Improve wistrut and build it by default. Add wistrut and wihack man pages.

This commit is contained in:
Kris Maglione 2010-05-24 15:17:09 -04:00
parent 9adfeea6c2
commit e3fdbdb548
24 changed files with 421 additions and 69 deletions

View File

@ -5,7 +5,8 @@ include $(ROOT)/mk/wmii.mk
wmiir.c: $(ROOT)/mk/wmii.mk wmiir.c: $(ROOT)/mk/wmii.mk
DIRS = wmii \ DIRS = wmii \
menu menu \
strut
TARG = wihack \ TARG = wihack \
wmii.rc \ wmii.rc \
wmii.sh \ wmii.sh \

View File

@ -11,8 +11,8 @@
# define EXTERN extern # define EXTERN extern
#endif #endif
enum { DAuto, DHorizontal, DVertical };
EXTERN Handlers handlers; EXTERN Handlers handlers;
EXTERN int direction;
EXTERN Window win;
EXTERN Window frame;

View File

@ -6,7 +6,7 @@ uint flushenterevents(void);
void xevent_loop(void); void xevent_loop(void);
void xtime_kludge(void); void xtime_kludge(void);
void restrut(void); void restrut(Window*);
void ewmh_getstrut(Window*, Rectangle[4]); void ewmh_getstrut(Window*, Rectangle[4]);
void ewmh_setstrut(Window*, Rectangle[4]); void ewmh_setstrut(Window*, Rectangle[4]);

View File

@ -6,13 +6,19 @@
#include <X11/Xproto.h> #include <X11/Xproto.h>
#include <locale.h> #include <locale.h>
#include <string.h> #include <string.h>
#include <time.h>
#include "fns.h" #include "fns.h"
static const char version[] = "witray-"VERSION", "COPYRIGHT"\n"; static Window* testwin;
static ulong testtime[2];
static const char version[] = "wistrut-"VERSION", "COPYRIGHT"\n";
static void manage(ulong);
static void static void
usage(void) { usage(void) {
fatal("usage: %s <window>\n", argv0); fatal("usage: %s [-HV] <window|class>...\n", argv0);
} }
static int static int
@ -20,14 +26,32 @@ errfmt(Fmt *f) {
return fmtstrcpy(f, ixp_errbuf()); return fmtstrcpy(f, ixp_errbuf());
} }
void static void
debug(int flag, const char *fmt, ...) { search_wins(char *pattern) {
va_list ap; ulong *wins;
ulong n, num;
int i;
char **class;
Reprog *regexp;
Window *win;
USED(flag); regexp = regcomp(pattern);
va_start(ap, fmt);
vfprint(2, fmt, ap); num = getprop_ulong(&scr.root, "_NET_CLIENT_LIST", "WINDOW", 0L, &wins, 1024L);
va_end(ap); for(i = 0; i < num; i++) {
win = window(wins[i]);
n = getprop_textlist(win, "WM_CLASS", &class);
bufclear();
bufprint("%s:%s:%s",
(n > 0 ? class[0] : "<nil>"),
(n > 1 ? class[1] : "<nil>"),
freelater(windowname(win)));
freestringlist(class);
if(regexec(regexp, buffer, nil, 0))
manage(wins[i]);
}
free(wins);
} }
static Window static Window
@ -43,6 +67,7 @@ findframe(Window *w) {
XQueryTree(display, xw, &root, &par, &children, &n); XQueryTree(display, xw, &root, &par, &children, &n);
XFree(children); XFree(children);
} }
ret.type = WWindow;
ret.xid = xw; ret.xid = xw;
ret.parent = &scr.root; ret.parent = &scr.root;
return ret; return ret;
@ -62,37 +87,91 @@ getwinsize(Window *win) {
Pt(x+border, y+border)); Pt(x+border, y+border));
} }
static bool
managable(ulong xid) {
ulong *ret;
ulong n;
bool retval;
n = getprop_ulong(window(xid), "_WMII_STRUT", "WINDOW", 0L, &ret, 1L);
if(n < 0)
retval = true;
else {
if(ret[0] == xid)
retval = ret[0] != testtime[0] || ret[1] != testtime[1];
else
retval = managable(ret[0]);
}
free(ret);
return retval;
}
static void
manage(ulong xid) {
Window *frame;
Window *win;
if(!managable(xid))
return;
win = emallocz(sizeof *win);
frame = emalloc(sizeof *frame);
win->type = WWindow;
win->xid = xid;
*frame = findframe(win);
frame->aux = win;
getwinsize(frame);
restrut(frame);
sethandler(frame, &handlers);
selectinput(frame, StructureNotifyMask);
changeprop_ulong(frame, "_WMII_STRUT", "WINDOW", testtime, nelem(testtime));
}
int int
main(int argc, char *argv[]) { main(int argc, char *argv[]) {
ulong win;
char *s; char *s;
fmtinstall('r', errfmt); fmtinstall('r', errfmt);
extern int fmtevent(Fmt*);
fmtinstall('E', fmtevent); fmtinstall('E', fmtevent);
ARGBEGIN{ ARGBEGIN{
case 'H':
direction = DHorizontal;
break;
case 'V':
direction = DVertical;
break;
case 'v':
print("%s", version);
return 0;
default: default:
usage(); usage();
}ARGEND; }ARGEND;
s = EARGF(usage());
if(!getulong(s, &win.xid))
usage();
if(argc)
usage();
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
initdisplay(); initdisplay();
frame = findframe(&win); testwin = createwindow(&scr.root, Rect(0, 0, 1, 1), 0,
getwinsize(&frame); InputOnly, nil, 0);
restrut(); testtime[0] = testwin->xid;
sethandler(&frame, &handlers); testtime[1] = time(nil);
selectinput(&frame, StructureNotifyMask);
event_looprunning = true; while(argc) {
s = ARGF();
if(getulong(s, &win))
manage(win);
else
search_wins(s);
}
changeprop_ulong(testwin, "_WMII_STRUT", "WINDOW", testtime, nelem(testtime));
event_looprunning = windowmap.nmemb > 0;
event_loop(); event_loop();
XCloseDisplay(display); XCloseDisplay(display);

View File

@ -6,14 +6,14 @@
#include "fns.h" #include "fns.h"
void void
restrut(void) { restrut(Window *frame) {
enum { Left, Right, Top, Bottom }; enum { Left, Right, Top, Bottom };
Rectangle strut[4]; Rectangle strut[4];
Rectangle r; Rectangle r;
r = frame.r; r = frame->r;
memset(strut, 0, sizeof strut); memset(strut, 0, sizeof strut);
if(Dx(r) < Dx(scr.rect)/2) { if(Dx(r) < Dx(scr.rect)/2 && direction != DVertical) {
if(r.min.x <= scr.rect.min.x) { if(r.min.x <= scr.rect.min.x) {
strut[Left] = r; strut[Left] = r;
strut[Left].min.x = 0; strut[Left].min.x = 0;
@ -25,7 +25,7 @@ restrut(void) {
strut[Right].max.x = 0; strut[Right].max.x = 0;
} }
} }
if(Dy(r) < Dy(scr.rect)/2) { if(Dy(r) < Dy(scr.rect)/2 && direction != DHorizontal) {
if(r.min.y <= scr.rect.min.y) { if(r.min.y <= scr.rect.min.y) {
strut[Top] = r; strut[Top] = r;
strut[Top].min.y = 0; strut[Top].min.y = 0;
@ -38,9 +38,6 @@ restrut(void) {
} }
} }
#define pstrut(name) \
if(!eqrect(strut[name], ZR)) \
fprint(2, "strut["#name"] = %R\n", strut[name])
/* Choose the struts which take up the least space. /* Choose the struts which take up the least space.
* Not ideal. * Not ideal.
*/ */
@ -70,29 +67,31 @@ restrut(void) {
} }
#if 0 #if 0
#define pstrut(name) \
if(!eqrect(strut[name], ZR)) \
fprint(2, "strut["#name"] = %R\n", strut[name])
pstrut(Left); pstrut(Left);
pstrut(Right); pstrut(Right);
pstrut(Top); pstrut(Top);
pstrut(Bottom); pstrut(Bottom);
#endif #endif
ewmh_setstrut(&win, strut); ewmh_setstrut(frame->aux, strut);
} }
static void static void
config(Window *w, XConfigureEvent *ev) { config(Window *frame, XConfigureEvent *ev) {
USED(w); frame->r = rectaddpt(Rect(0, 0, ev->width, ev->height),
Pt(ev->x+ev->border_width, ev->y+ev->border_width));
frame.r = rectaddpt(Rect(0, 0, ev->width, ev->height), restrut(frame);
Pt(ev->x+ev->border_width, ev->y+ev->border_width));
restrut();
} }
static void static void
destroy(Window *w, XDestroyWindowEvent *ev) { destroy(Window *w, XDestroyWindowEvent *ev) {
USED(w, ev); USED(w, ev);
event_looprunning = false; sethandler(w, nil);
event_looprunning = windowmap.nmemb > 0;
} }
Handlers handlers = { Handlers handlers = {

View File

@ -1,4 +1,5 @@
#!/bin/sh -f #!/bin/sh -f
unset WMII_HACK_TRANSIENT WMII_HACK_TYPE WMII_HACK_TAGS
usage() { usage() {
echo 1>&2 Usage: \ echo 1>&2 Usage: \

View File

@ -718,9 +718,7 @@ client_updatename(Client *c) {
c->name[0] = '\0'; c->name[0] = '\0';
str = getprop_string(&c->w, "_NET_WM_NAME"); str = windowname(&c->w);
if(str == nil)
str = getprop_string(&c->w, "WM_NAME");
if(str) if(str)
utflcpy(c->name, str, sizeof c->name); utflcpy(c->name, str, sizeof c->name);
free(str); free(str);

View File

@ -21,13 +21,12 @@ static void ewmh_setstate(Client*, Atom, int);
void void
ewmh_init(void) { ewmh_init(void) {
WinAttr wa;
char myname[] = "wmii"; char myname[] = "wmii";
long win; long win;
ewmhwin = createwindow(&scr.root, ewmhwin = createwindow(&scr.root,
Rect(0, 0, 1, 1), 0 /*depth*/, Rect(0, 0, 1, 1), 0 /*depth*/,
InputOnly, &wa, 0); InputOnly, nil, 0);
win = ewmhwin->xid; win = ewmhwin->xid;
changeprop_long(&scr.root, Net("SUPPORTING_WM_CHECK"), "WINDOW", &win, 1); changeprop_long(&scr.root, Net("SUPPORTING_WM_CHECK"), "WINDOW", &win, 1);

View File

@ -484,7 +484,6 @@ static int
tvcol(Frame *f) { tvcol(Frame *f) {
Framewin *fw; Framewin *fw;
Window *cwin; Window *cwin;
WinAttr wa;
Rectangle r; Rectangle r;
Point pt, pt2; Point pt, pt2;
uint button; uint button;
@ -502,7 +501,7 @@ tvcol(Frame *f) {
r.min.y += fw->grabbox.min.y + Dy(fw->grabbox)/2; r.min.y += fw->grabbox.min.y + Dy(fw->grabbox)/2;
r.max.y = r.min.y + 1; r.max.y = r.min.y + 1;
cwin = createwindow(&scr.root, r, 0, InputOnly, &wa, 0); cwin = createwindow(&scr.root, r, 0, InputOnly, nil, 0);
mapwin(cwin); mapwin(cwin);
ret = TDone; ret = TDone;

View File

@ -43,24 +43,22 @@ scan_wins(void) {
uint num; uint num;
XWindow *wins; XWindow *wins;
XWindowAttributes wa; XWindowAttributes wa;
XWindow d1, d2; XWindow root, parent;
if(XQueryTree(display, scr.root.xid, &d1, &d2, &wins, &num)) { if(XQueryTree(display, scr.root.xid, &root, &parent, &wins, &num)) {
for(i = 0; i < num; i++) { for(i = 0; i < num; i++) {
if(!XGetWindowAttributes(display, wins[i], &wa)) if(!XGetWindowAttributes(display, wins[i], &wa) || wa.override_redirect)
continue;
/* Skip transients. */
if(wa.override_redirect || XGetTransientForHint(display, wins[i], &d1))
continue; continue;
if(!XGetTransientForHint(display, wins[i], &parent))
if(wa.map_state == IsViewable) if(wa.map_state == IsViewable)
client_create(wins[i], &wa); client_create(wins[i], &wa);
} }
/* Manage transients. */ /* Manage transients. */
for(i = 0; i < num; i++) { for(i = 0; i < num; i++) {
if(!XGetWindowAttributes(display, wins[i], &wa)) if(!XGetWindowAttributes(display, wins[i], &wa) || wa.override_redirect)
continue; continue;
if((XGetTransientForHint(display, wins[i], &d1)) if(XGetTransientForHint(display, wins[i], &parent))
&& (wa.map_state == IsViewable)) if(wa.map_state == IsViewable)
client_create(wins[i], &wa); client_create(wins[i], &wa);
} }
} }

View File

@ -42,13 +42,12 @@ static Handlers chandler = {
Window* Window*
constraintwin(Rectangle r) { constraintwin(Rectangle r) {
Window *w; Window *w;
WinAttr wa;
w = createwindow(&scr.root, r, 0, InputOnly, &wa, 0); w = createwindow(&scr.root, r, 0, InputOnly, nil, 0);
if(0) { if(0) {
Window *w2; Window *w2;
w2 = createwindow(&scr.root, r, 0, InputOutput, &wa, 0); w2 = createwindow(&scr.root, r, 0, InputOutput, nil, 0);
selectinput(w2, ExposureMask); selectinput(w2, ExposureMask);
w->aux = w2; w->aux = w2;

View File

@ -124,6 +124,7 @@ typedef struct MapEnt MapEnt;
struct Map { struct Map {
MapEnt**bucket; MapEnt**bucket;
uint nhash; uint nhash;
uint nmemb;
}; };
void** hash_get(Map*, const char*, bool create); void** hash_get(Map*, const char*, bool create);

View File

@ -189,6 +189,8 @@ struct Screen {
Display *display; Display *display;
Screen scr; Screen scr;
extern struct Map windowmap;
extern struct Map atommap;
extern const Point ZP; extern const Point ZP;
extern const Rectangle ZR; extern const Rectangle ZR;
extern Window* pointerwin; extern Window* pointerwin;
@ -268,6 +270,7 @@ void ungrabpointer(void);
int unmapwin(Window*); int unmapwin(Window*);
void warppointer(Point); void warppointer(Point);
Window* window(XWindow); Window* window(XWindow);
char* windowname(Window*);
long winprotocols(Window*); long winprotocols(Window*);
Atom xatom(char*); Atom xatom(char*);
void sendmessage(Window*, char*, long, long, long, long, long); void sendmessage(Window*, char*, long, long, long, long, long);

View File

@ -141,6 +141,7 @@ OBJ=\
x11/properties/getprop_ulong \ x11/properties/getprop_ulong \
x11/properties/getproperty \ x11/properties/getproperty \
x11/properties/strlistdup \ x11/properties/strlistdup \
x11/properties/windowname \
x11/shape/setshapemask \ x11/shape/setshapemask \
x11/text/freefont \ x11/text/freefont \
x11/text/labelh \ x11/text/labelh \

View File

@ -1,5 +1,6 @@
/* Written by Kris Maglione */ /* Written by Kris Maglione */
/* Public domain */ /* Public domain */
#include <assert.h>
#include <string.h> #include <string.h>
#include <stuff/util.h> #include <stuff/util.h>
@ -28,9 +29,10 @@ hash(const char *str) {
} }
static void static void
insert(MapEnt **e, ulong val, const char *key) { insert(Map *m, MapEnt **e, ulong val, const char *key) {
MapEnt *te; MapEnt *te;
m->nmemb++;
te = emallocz(sizeof *te); te = emallocz(sizeof *te);
te->hash = val; te->hash = val;
te->key = key; te->key = key;
@ -47,7 +49,7 @@ map_getp(Map *map, ulong val, int create) {
if((*e)->hash >= val) break; if((*e)->hash >= val) break;
if(*e == nil || (*e)->hash != val) { if(*e == nil || (*e)->hash != val) {
if(create) if(create)
insert(e, val, nil); insert(map, e, val, nil);
else else
e = &NM; e = &NM;
} }
@ -71,7 +73,7 @@ hash_getp(Map *map, const char *str, int create) {
break; break;
if(*e == nil || (*e)->hash > h || cmp > 0) if(*e == nil || (*e)->hash > h || cmp > 0)
if(create) if(create)
insert(e, h, str); insert(map, e, h, str);
} }
return e; return e;
} }
@ -103,6 +105,7 @@ map_rm(Map *map, ulong val) {
te = *e; te = *e;
ret = te->val; ret = te->val;
*e = te->next; *e = te->next;
assert(map->nmemb-- > 0);
free(te); free(te);
} }
return ret; return ret;
@ -119,6 +122,7 @@ hash_rm(Map *map, const char *str) {
te = *e; te = *e;
ret = te->val; ret = te->val;
*e = te->next; *e = te->next;
assert(map->nmemb-- > 0);
free(te); free(te);
} }
return ret; return ret;

View File

@ -0,0 +1,17 @@
/* Copyright ©2007-2010 Kris Maglione <maglione.k at Gmail>
* See LICENSE file for license details.
*/
#include "../x11.h"
char*
windowname(Window *w) {
char *str;
str = getprop_string(w, "_NET_WM_NAME");
if(str == nil)
str = getprop_string(w, "WM_NAME");
if(str == nil)
str = estrdup("");
return str;
}

View File

@ -8,9 +8,13 @@ createwindow_visual(Window *parent, Rectangle r,
int depth, Visual *vis, uint class, int depth, Visual *vis, uint class,
WinAttr *wa, int valmask) { WinAttr *wa, int valmask) {
Window *w; Window *w;
WinAttr wa_empty;
assert(parent->type == WWindow); assert(parent->type == WWindow);
if(wa == nil)
wa = &wa_empty;
w = emallocz(sizeof *w); w = emallocz(sizeof *w);
w->visual = vis; w->visual = vis;
w->type = WWindow; w->type = WWindow;

View File

@ -14,8 +14,6 @@
#include <stuff/util.h> #include <stuff/util.h>
#undef pointerwin #undef pointerwin
extern Map windowmap;
extern Map atommap;
extern MapEnt* wbucket[137]; extern MapEnt* wbucket[137];
extern MapEnt* abucket[137]; extern MapEnt* abucket[137];

View File

@ -5,7 +5,9 @@ include $(ROOT)/mk/wmii.mk
TARG = wmii.1 \ TARG = wmii.1 \
wmiir.1 \ wmiir.1 \
wmii9menu.1\ wmii9menu.1\
wimenu.1 wihack.1 \
wimenu.1 \
wistrut.1
$(TARG): Makefile $(ROOT)/mk/wmii.mk header.t2t $(TARG): Makefile $(ROOT)/mk/wmii.mk header.t2t

67
man/wihack.1 Normal file
View File

@ -0,0 +1,67 @@
.TH "WIMENU" 1 "May, 2010" "wmii-@VERSION@"
.SH NAME
.P
wihack \- The wmii window hack
.SH SYNOPSIS
.P
wihack \fI[\-transient \fI<window>\fR]\fR \fI[\-type \fI<ewmh window type>\fR]\fR \fI[\-tags \fI<tags>\fR]\fR \fI<program>\fR
.SH DESCRIPTION
.P
\fBwihack\fR is a program which alters the windows created by an
arbitrary program. It has the name \fBwihack\fR because it is just that:
a hack. It uses LD_PRELOAD to override certain Xlib calls and add
properties to newly created windows.
.SH ARGUMENTS
.TP
\-transient \fI<window>\fR
Marks created windows as transient for a given \fI<window>\fR.
This causes the new window to open in the floating layer of
the same tags as \fI<window>\fR.
.TP
\-type \fI<ewmh window type>\fR
Sets the EWMH window type of the created window to the type
given. \fBwmii\fR understands the following types:
.RS 8
.TP
dialog
Opens in the floating layer.
.TP
dock
.TP
menu
.TP
toolbar
Automatically opens in the floating layer. Does not
have a window border or titlebar.
.TP
splash
Automatically floats and does not automatically
receive focus.
.RS -8
.TP
\-tags \fI<tags>\fR
The created window opens on the given tags.
.SH BUGS
.P
It is a hack.
.P
It doesn't work for setuid programs.
.P
It doesn't work for non\-Xlib programs.
.SH SEE ALSO
.P
wmii(1)
.\" man code generated by txt2tags 2.5 (http://txt2tags.sf.net)
.\" cmdline: txt2tags -o- wihack.man1

58
man/wihack.man1 Normal file
View File

@ -0,0 +1,58 @@
WIMENU
wmii-@VERSION@
May, 2010
%!includeconf: header.t2t
= NAME =
wihack - The wmii window hack
= SYNOPSIS =
wihack [-transient <window>] [-type <ewmh window type>] [-tags <tags>] <program>
= DESCRIPTION =
`wihack` is a program which alters the windows created by an
arbitrary program. It has the name `wihack` because it is just that:
a hack. It uses LD_PRELOAD to override certain Xlib calls and add
properties to newly created windows.
= ARGUMENTS =
: -transient <window>
Marks created windows as transient for a given <window>.
This causes the new window to open in the floating layer of
the same tags as <window>.
: -type <ewmh window type>
Sets the EWMH window type of the created window to the type
given. `wmii` understands the following types:
>>
: dialog
Opens in the floating layer.
: dock
: menu
: toolbar
Automatically opens in the floating layer. Does not
have a window border or titlebar.
: splash
Automatically floats and does not automatically
receive focus.
<<
: -tags <tags>
The created window opens on the given tags.
:
= BUGS =
It is a hack.
It doesn't work for setuid programs.
It doesn't work for non-Xlib programs.
= SEE ALSO =
wmii(1)

69
man/wistrut.1 Normal file
View File

@ -0,0 +1,69 @@
.TH "WIMENU" 1 "May, 2010" "wmii-@VERSION@"
.SH NAME
.P
wistrut \- The wmii EWMH strut manager
.SH SYNOPSIS
.P
wistrut \fI[\-HV]\fR \fI<window|class>\fR...
.P
wistrut \-v
.SH DESCRIPTION
.P
\fBwistrut\fR automatically sets EWMH struts on windows for programs
which don't provide such functionality. This allows you to leave
utility windows onscreen without obscuring managed clients. Instead,
whatever part of the screen is occupied by the window will be left
free by wmii, provided it is less than half of the screen width or
height. Struts are automatically updated when the managed windows
are moved or resized, and are only applied if the window is touching
an edge of the screen.
.P
\fBwistrut\fR may be used with any EWMH compatible window manager.
.SH ARGUMENTS
.P
All non\-option arguments constitute window IDs or regular
expressions. In the latter case, the any window whose
\fI<name>\fR:\fI<class>\fR:\fI<title>\fR (as used in wmii's colrules and tagrules)
will be managed.
.TP
\-H
.RS
Only set horizontal struts. Normally, \fBwistrut\fR locates
struts in the direction of the narrowest dimension of the
window, provided it is touching a screen edge. With this
option set, they will always be allocated on either the left
or right of the screen. Never the top or bottom.
.RE
.TP
\-V
.RS
Only set vertical struts. See \-H.
.RE
.TP
\-v
.RS
Display version information.
.RE
.SH BUGS
.P
There is no way to remove struts from a window other than to move it
away from the edge of the screen and kill \fBwistrut\fR.
.SH SEE ALSO
.P
wmii(1)
.\" man code generated by txt2tags 2.5 (http://txt2tags.sf.net)
.\" cmdline: txt2tags -o- wistrut.man1

55
man/wistrut.man1 Normal file
View File

@ -0,0 +1,55 @@
WIMENU
wmii-@VERSION@
May, 2010
%!includeconf: header.t2t
= NAME =
wistrut - The wmii EWMH strut manager
= SYNOPSIS =
wistrut [-HV] <window|class>... +
wistrut -v
= DESCRIPTION =
`wistrut` automatically sets EWMH struts on windows for programs
which don't provide such functionality. This allows you to leave
utility windows onscreen without obscuring managed clients. Instead,
whatever part of the screen is occupied by the window will be left
free by wmii, provided it is less than half of the screen width or
height. Struts are automatically updated when the managed windows
are moved or resized, and are only applied if the window is touching
an edge of the screen.
`wistrut` may be used with any EWMH compatible window manager.
= ARGUMENTS =
All non-option arguments constitute window IDs or regular
expressions. In the latter case, the any window whose
<name>:<class>:<title> (as used in wmii's colrules and tagrules)
will be managed.
: -H
Only set horizontal struts. Normally, `wistrut` locates
struts in the direction of the narrowest dimension of the
window, provided it is touching a screen edge. With this
option set, they will always be allocated on either the left
or right of the screen. Never the top or bottom.
: -V
Only set vertical struts. See -H.
: -v
Display version information.
= BUGS =
There is no way to remove struts from a window other than to move it
away from the edge of the screen and kill `wistrut`.
= SEE ALSO =
wmii(1)

View File

@ -59,7 +59,7 @@ undup() { # GCC is crap.
} }
cat $xtmp | sed "s,^$re,$base&,g; s,\([[:space:]]\)$re,\1$base\2,g" | cat $xtmp | sed "s,^$re,$base&,g; s,\([[:space:]]\)$re,\1$base\2,g" |
egrep -v ': error: .Each undeclared identifier|: error: for each function it appears|is dangerous, better use|is almost always misused|: In function |: At top level:|support .long long.|use of C99 long long|ISO C forbids conversion|warning:.*warn_unused_result' | egrep -iv ': (error|note): .?Each undeclared identifier|: error: for each function it appears|is dangerous, better use|is almost always misused|: In function |: At top level:|support .long long.|use of C99 long long|ISO C forbids conversion|warning:.*warn_unused_result' |
sed 's/ .first use in this function.$//; s/\"\([^\"][^\"]*\)\", line \([0-9][0-9]*\)/\1:\2/g' | sed 's/ .first use in this function.$//; s/\"\([^\"][^\"]*\)\", line \([0-9][0-9]*\)/\1:\2/g' |
awk '$1 == "warning:"{t=$2" "$1; sub(/^[^ ]+ [^ ]+ /, ""); $0 = t" "$0}; //' | awk '$1 == "warning:"{t=$2" "$1; sub(/^[^ ]+ [^ ]+ /, ""); $0 = t" "$0}; //' |
awk '{sub(/\[/, ": [", $1); print}' | awk '{sub(/\[/, ": [", $1); print}' |