mirror of https://github.com/0intro/wmii
Fix gravity.
This commit is contained in:
parent
e1e28cdb9b
commit
87f632b067
30
README
30
README
|
@ -9,21 +9,21 @@ the remote access utility.
|
|||
|
||||
Requirements
|
||||
------------
|
||||
In order to build wmii you need the Xlib header files and libixp. Further
|
||||
dependencies are xmessage and dmenu. libixp and dmenu can be obtained from
|
||||
[1]. One of plan9port or 9base is also recommended.
|
||||
In order to build wmii you need the Xlib header files and libixp. xmessage
|
||||
and dmenu are used by the default scripts. libixp and dmenu can be obtained
|
||||
from http://suckless.org/. Either plan9port or 9base is recommended.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
Edit config.mk to match your local setup. wmii is installed into
|
||||
the /usr/local hierarchy by default.
|
||||
First, edit config.mk to match your local setup, or to let us guess it, run:
|
||||
make config
|
||||
|
||||
Afterwards enter the following command to build and install wmii (if
|
||||
necessary as root):
|
||||
|
||||
make clean install
|
||||
To build, simply run:
|
||||
make
|
||||
|
||||
To install, run the following, as root, if necessary:
|
||||
make install
|
||||
|
||||
Running wmii
|
||||
------------
|
||||
|
@ -33,12 +33,12 @@ Add the following line to your .xinitrc to start wmii using startx:
|
|||
true
|
||||
done
|
||||
|
||||
In order to connect wmii or wmiir to a specific display, make sure that
|
||||
the DISPLAY environment variable is set correctly, e.g.:
|
||||
In order to connect wmii to a specific display, make sure that
|
||||
the DISPLAY environment variable is set correctly. For example:
|
||||
|
||||
DISPLAY=foo.bar:1 wmii
|
||||
DISPLAY=:1 wmii
|
||||
|
||||
This will start wmii on display :1 of the host foo.bar.
|
||||
This will start wmii on display :1.
|
||||
|
||||
|
||||
Configuration
|
||||
|
@ -49,8 +49,8 @@ The main rc.wmii script lives in PREFIX/etc/wmii-3.5/, while rc.wmii.local
|
|||
goes in $HOME/.wmii-3.5/.
|
||||
|
||||
rc.wmii.local should contain a line containing just: '# Overrides'. You must
|
||||
set your MODKEY before this line, if you wish to change it, and define most
|
||||
functions after it.
|
||||
set your MODKEY and other configuration variables before this line, if you
|
||||
wish to change then, and define most functions after it.
|
||||
|
||||
Credits
|
||||
-------
|
||||
|
|
|
@ -14,7 +14,9 @@ static void update_client_name(Client *c);
|
|||
static Handlers handlers;
|
||||
|
||||
static char Ebadcmd[] = "bad command",
|
||||
Ebadvalue[] = "bad value";
|
||||
Ebadvalue[] = "bad value";
|
||||
|
||||
Rectangle gravclient(Client*, Rectangle);
|
||||
|
||||
enum {
|
||||
ClientMask =
|
||||
|
@ -39,6 +41,7 @@ create_client(XWindow w, XWindowAttributes *wa) {
|
|||
|
||||
c->w.type = WWindow;
|
||||
c->w.w = w;
|
||||
c->w.r = c->r;
|
||||
|
||||
c->proto = winprotocols(&c->w);
|
||||
prop_client(c, XA_WM_TRANSIENT_FOR);
|
||||
|
@ -48,6 +51,7 @@ create_client(XWindow w, XWindowAttributes *wa) {
|
|||
|
||||
XSetWindowBorderWidth(display, w, 0);
|
||||
XAddToSaveSet(display, w);
|
||||
XSelectInput(display, c->w.w, ClientMask);
|
||||
|
||||
fwa.override_redirect = True;
|
||||
fwa.event_mask =
|
||||
|
@ -85,24 +89,29 @@ ignoreerrors(Display *d, XErrorEvent *e) {
|
|||
}
|
||||
|
||||
Rectangle
|
||||
gravclient(Client *c, Rectangle *rp) {
|
||||
gravclient(Client *c, Rectangle rd) {
|
||||
Rectangle r;
|
||||
Point p;
|
||||
|
||||
p = c->w.hints->grav;
|
||||
Point sp;
|
||||
WinHints *h;
|
||||
|
||||
if(rp)
|
||||
return gravitate(*rp, c->w.r, p);
|
||||
h = c->w.hints;
|
||||
r = client2frame(nil, c->w.r);
|
||||
sp = Pt(def.border, labelh(def.font));
|
||||
|
||||
if(c->sel) {
|
||||
if(eqrect(rd, ZR)) {
|
||||
if(c->sel->area->floating)
|
||||
r = c->sel->r;
|
||||
else
|
||||
r = c->sel->revert;
|
||||
}else
|
||||
r = client2frame(nil, c->w.r);
|
||||
p = addpt(p, Pt(2,2));
|
||||
return gravitate(c->w.r, r, p);
|
||||
r = gravitate(r, c->w.r, h->grav);
|
||||
if(h->gravstatic)
|
||||
r = rectaddpt(r, sp);
|
||||
}else {
|
||||
r = gravitate(rd, r, h->grav);
|
||||
if(h->gravstatic)
|
||||
r = rectsubpt(r, sp);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -126,12 +135,13 @@ destroy_client(Client *c) {
|
|||
/* In case the client is already unmapped */
|
||||
handler = XSetErrorHandler(ignoreerrors);
|
||||
|
||||
r = gravclient(c, ZR);
|
||||
r = frame2client(nil, r);
|
||||
|
||||
dummy = nil;
|
||||
update_client_views(c, &dummy);
|
||||
|
||||
unmap_client(c, WithdrawnState);
|
||||
|
||||
r = gravclient(c, nil);
|
||||
reparent_client(c, &scr.root, r.min);
|
||||
|
||||
write_event("DestroyClient 0x%x\n", (uint)c->w.w);
|
||||
|
@ -165,7 +175,7 @@ manage_client(Client *c) {
|
|||
strncpy(c->tags, (char *)tags.value, sizeof(c->tags));
|
||||
XFree(tags.value);
|
||||
|
||||
//gravclient(c, nil);
|
||||
gravclient(c, c->w.r);
|
||||
reparent_client(c, c->framewin, Pt(def.border, labelh(def.font)));
|
||||
|
||||
if(!strlen(c->tags))
|
||||
|
@ -186,25 +196,27 @@ manage_client(Client *c) {
|
|||
static void
|
||||
configreq_event(Window *w, XConfigureRequestEvent *e) {
|
||||
Rectangle r;
|
||||
Rectangle *frect;
|
||||
Point p;
|
||||
Frame *f;
|
||||
Client *c;
|
||||
|
||||
c = w->aux;
|
||||
f = c->sel;
|
||||
|
||||
r = gravclient(c, nil);
|
||||
if(e->value_mask & CWX)
|
||||
r.min.x = e->x;
|
||||
if(e->value_mask & CWY)
|
||||
r.min.y = e->y;
|
||||
if(e->value_mask & CWWidth)
|
||||
p = ZP;
|
||||
r = gravclient(c, ZR);
|
||||
if(e->value_mask&CWX)
|
||||
p.x = e->x - r.min.x;
|
||||
if(e->value_mask&CWY)
|
||||
p.y = e->y - r.min.y;
|
||||
if(e->value_mask&CWWidth)
|
||||
r.max.x = r.min.x + e->width;
|
||||
if(e->value_mask & CWHeight)
|
||||
if(e->value_mask&CWHeight)
|
||||
r.max.y = r.min.y + e->height;
|
||||
if(e->value_mask & CWBorderWidth)
|
||||
if(e->value_mask&CWBorderWidth)
|
||||
c->border = e->border_width;
|
||||
r = gravclient(c, &r);
|
||||
r = rectaddpt(r, p);
|
||||
r = gravclient(c, r);
|
||||
|
||||
if((Dx(r) == Dx(screen->r)) && (Dy(r) == Dy(screen->r))) {
|
||||
c->fullscreen = True;
|
||||
|
@ -216,10 +228,9 @@ configreq_event(Window *w, XConfigureRequestEvent *e) {
|
|||
}
|
||||
}
|
||||
|
||||
if(c->sel->area->floating) {
|
||||
c->sel->r = r;
|
||||
resize_client(c, frect);
|
||||
}else {
|
||||
if(c->sel->area->floating)
|
||||
resize_client(c, &r);
|
||||
else {
|
||||
c->sel->revert = r;
|
||||
configure_client(c);
|
||||
}
|
||||
|
@ -346,30 +357,17 @@ win2client(XWindow w) {
|
|||
|
||||
static void
|
||||
update_client_name(Client *c) {
|
||||
XTextProperty name;
|
||||
XClassHint ch = {0};
|
||||
char **list, *str;
|
||||
int n;
|
||||
char *str;
|
||||
|
||||
c->name[0] = 0;
|
||||
list = nil;
|
||||
c->name[0] = '0';
|
||||
|
||||
name.nitems = 0;
|
||||
XGetTextProperty(display, c->w.w, &name, atom[NetWMName]);
|
||||
if(name.nitems > 0) {
|
||||
if(Xutf8TextPropertyToTextList(display, &name, &list, &n) == Success) {
|
||||
utfecpy(c->name, c->name+sizeof(c->name), list[0]);
|
||||
XFreeStringList(list);
|
||||
}
|
||||
}else {
|
||||
XGetWMName(display, c->w.w, &name);
|
||||
if(name.nitems > 0) {
|
||||
str = toutf8((char*)name.value);
|
||||
utfecpy(c->name, c->name+sizeof(c->name), str);
|
||||
free(str);
|
||||
XFree(name.value);
|
||||
}
|
||||
}
|
||||
str = gettextproperty(&c->w, atom[NetWMName]);
|
||||
if(str == nil)
|
||||
str = gettextproperty(&c->w, XA_WM_NAME);
|
||||
if(str)
|
||||
utfecpy(c->name, c->name+sizeof(c->name), str);
|
||||
free(str);
|
||||
|
||||
XGetClassHint(display, c->w.w, &ch);
|
||||
snprintf(c->props, sizeof(c->props), "%s:%s:%s",
|
||||
|
@ -385,24 +383,13 @@ update_client_name(Client *c) {
|
|||
void
|
||||
set_client_state(Client * c, int state) {
|
||||
long data[] = { state, None };
|
||||
XChangeProperty(
|
||||
/* display */ display,
|
||||
/* parent */ c->w.w,
|
||||
/* property */ atom[WMState],
|
||||
/* type */ atom[WMState],
|
||||
/* format */ 32,
|
||||
/* mode */ PropModeReplace,
|
||||
/* data */ (uchar *) data,
|
||||
/* npositions */2
|
||||
);
|
||||
changeproperty(&c->w, atom[WMState], atom[WMState], 32, (uchar*)data, nelem(data));
|
||||
}
|
||||
|
||||
void
|
||||
map_client(Client *c) {
|
||||
if(!c->w.mapped) {
|
||||
XSelectInput(display, c->w.w, ClientMask & ~StructureNotifyMask);
|
||||
mapwin(&c->w);
|
||||
XSelectInput(display, c->w.w, ClientMask);
|
||||
set_client_state(c, NormalState);
|
||||
}
|
||||
}
|
||||
|
@ -410,10 +397,7 @@ map_client(Client *c) {
|
|||
void
|
||||
unmap_client(Client *c, int state) {
|
||||
if(c->w.mapped) {
|
||||
c->unmapped++;
|
||||
XSelectInput(display, c->w.w, ClientMask & ~StructureNotifyMask);
|
||||
unmapwin(&c->w);
|
||||
XSelectInput(display, c->w.w, ClientMask);
|
||||
set_client_state(c, state);
|
||||
}
|
||||
}
|
||||
|
@ -430,11 +414,7 @@ unmap_frame(Client *c) {
|
|||
|
||||
void
|
||||
reparent_client(Client *c, Window *w, Point pt) {
|
||||
XSelectInput(display, c->w.w, ClientMask & ~StructureNotifyMask);
|
||||
|
||||
reparentwindow(&c->w, w, pt);
|
||||
|
||||
XSelectInput(display, c->w.w, ClientMask);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -471,9 +451,7 @@ configure_client(Client *c) {
|
|||
e.border_width = c->border;
|
||||
e.above = None;
|
||||
e.override_redirect = False;
|
||||
XSendEvent(display, c->w.w, False,
|
||||
StructureNotifyMask, (XEvent *) & e);
|
||||
XSync(display, False);
|
||||
XSendEvent(display, c->w.w, False, StructureNotifyMask, (XEvent*)&e);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -922,8 +900,8 @@ apply_tags(Client *c, const char *tags) {
|
|||
toks[n] = nil;
|
||||
|
||||
update_client_views(c, toks);
|
||||
XChangeProperty(display, c->w.w, atom[TagsAtom], XA_STRING, 8,
|
||||
PropModeReplace, (uchar *)c->tags, strlen(c->tags));
|
||||
|
||||
changeproperty(&c->w, atom[TagsAtom], atom[Utf8String], 8, (uchar*)c->tags, strlen(c->tags));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -37,6 +37,7 @@ struct CTuple {
|
|||
enum {
|
||||
WMState, WMProtocols, WMDelete,
|
||||
NetSupported, NetWMName,
|
||||
Utf8String,
|
||||
TagsAtom,
|
||||
AtomLast
|
||||
};
|
||||
|
|
|
@ -189,6 +189,8 @@ uint textwidth_l(Font*, char*, uint len);
|
|||
uint textwidth(Font*, char*);
|
||||
uint labelh(Font*);
|
||||
Atom xatom(char*);
|
||||
char *gettextproperty(Window*, Atom);
|
||||
void changeproperty(Window*, Atom prop, Atom type, int width, uchar *data, int n);
|
||||
Point querypointer(Window*);
|
||||
void warppointer(Point);
|
||||
Point translate(Window*, Window*, Point);
|
||||
|
|
|
@ -150,6 +150,7 @@ init_atoms() {
|
|||
atom[WMDelete] = xatom("WM_DELETE_WINDOW");
|
||||
atom[NetSupported] = xatom("_NET_SUPPORTED");
|
||||
atom[NetWMName] = xatom("_NET_WM_NAME");
|
||||
atom[Utf8String] = xatom("UTF8_STRING");
|
||||
atom[TagsAtom] = xatom("_WIN_TAGS");
|
||||
|
||||
XChangeProperty(display, scr.root.w, atom[NetSupported], XA_ATOM, 32,
|
||||
|
|
|
@ -119,11 +119,15 @@ static Handlers handlers = {
|
|||
|
||||
static void
|
||||
vplace(Framewin *fw, Point pt) {
|
||||
Rectangle r;
|
||||
Frame *f;
|
||||
Area *a;
|
||||
View *v;
|
||||
int hr;
|
||||
|
||||
v = screen->sel;
|
||||
r = fw->w->r;
|
||||
hr = Dy(r)/2;
|
||||
|
||||
for(a = v->area->next; a->next; a = a->next)
|
||||
if(pt.x < a->r.max.x)
|
||||
|
@ -133,6 +137,16 @@ vplace(Framewin *fw, Point pt) {
|
|||
if(pt.y < f->r.max.y)
|
||||
break;
|
||||
|
||||
#if 0
|
||||
if(!f->collapsed) {
|
||||
if(pt.y + Dy(r) + hr > f->r.max)
|
||||
pt.y = f->r.max - hr
|
||||
else if(f == fw->r && abs(pt.y - f->r.min + hr) < Dy(r))
|
||||
pt.y = f->r.min + hr;
|
||||
else if(
|
||||
}
|
||||
#endif
|
||||
|
||||
if(abs(pt.y - f->r.min.y) < labelh(def.font)) {
|
||||
pt.y = f->r.min.y;
|
||||
if(f == fw->f)
|
||||
|
|
|
@ -553,6 +553,34 @@ xatom(char *name) {
|
|||
return XInternAtom(display, name, False);
|
||||
}
|
||||
|
||||
void
|
||||
changeproperty(Window *w, Atom prop, Atom type, int width, uchar *data, int n) {
|
||||
XChangeProperty(display, w->w, prop, type, width, PropModeReplace, data, n);
|
||||
}
|
||||
|
||||
char *
|
||||
gettextproperty(Window *w, Atom name) {
|
||||
XTextProperty prop;
|
||||
char **list, *str;
|
||||
int n;
|
||||
|
||||
str = nil;
|
||||
|
||||
XGetTextProperty(display, w->w, &prop, name);
|
||||
if(prop.nitems > 0) {
|
||||
if(Xutf8TextPropertyToTextList(display, &prop, &list, &n) == Success) {
|
||||
if(n > 0) {
|
||||
n = strlen(*list)+1;
|
||||
str = emalloc(n);
|
||||
memcpy(str, *list, n);
|
||||
}
|
||||
XFreeStringList(list);
|
||||
}
|
||||
XFree(prop.value);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Mouse */
|
||||
Point
|
||||
querypointer(Window *w) {
|
||||
|
@ -660,21 +688,22 @@ sethints(Window *w) {
|
|||
|
||||
switch (xs.win_gravity) {
|
||||
case EastGravity:case CenterGravity:case WestGravity:
|
||||
p.y = -1;
|
||||
p.y = 1;
|
||||
break;
|
||||
case SouthEastGravity:case SouthGravity:case SouthWestGravity:
|
||||
p.y = -2;
|
||||
p.y = 2;
|
||||
break;
|
||||
}
|
||||
switch (xs.win_gravity) {
|
||||
case NorthGravity:case CenterGravity:case SouthGravity:
|
||||
p.x = -1;
|
||||
p.x = 1;
|
||||
break;
|
||||
case NorthEastGravity:case EastGravity:case SouthEastGravity:
|
||||
p.x = -2;
|
||||
p.x = 2;
|
||||
break;
|
||||
}
|
||||
h->grav = p;
|
||||
h->gravstatic = (xs.win_gravity&StaticGravity) == 0;
|
||||
}
|
||||
|
||||
Rectangle
|
||||
|
@ -709,16 +738,16 @@ sizehint(WinHints *h, Rectangle r) {
|
|||
}
|
||||
|
||||
Rectangle
|
||||
gravitate(Rectangle rd, Rectangle rs, Point grav) {
|
||||
gravitate(Rectangle rc, Rectangle rf, Point grav) {
|
||||
Point d;
|
||||
|
||||
rd = rectsubpt(rd, rd.min);
|
||||
d = subpt(rs.max, rs.min);
|
||||
d = subpt(rd.max, d);
|
||||
rf = rectsubpt(rf, rf.min);
|
||||
|
||||
d = subpt(rc.max, rc.min);
|
||||
d = subpt(rf.max, d);
|
||||
|
||||
d = divpt(d, Pt(2, 2));
|
||||
d = mulpt(d, grav);
|
||||
|
||||
d = addpt(d, rs.min);
|
||||
return rectaddpt(rd, d);
|
||||
return rectaddpt(rc, d);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ struct WinHints {
|
|||
Point inc;
|
||||
Rectangle aspect;
|
||||
Point grav;
|
||||
Bool gravstatic;
|
||||
};
|
||||
|
||||
struct Handlers {
|
||||
|
|
Loading…
Reference in New Issue