Fix gravity.

This commit is contained in:
Kris Maglione 2007-04-20 02:52:33 -04:00
parent e1e28cdb9b
commit 87f632b067
8 changed files with 125 additions and 99 deletions

30
README
View File

@ -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
-------

View File

@ -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;
Point sp;
WinHints *h;
p = c->w.hints->grav;
h = c->w.hints;
r = client2frame(nil, c->w.r);
sp = Pt(def.border, labelh(def.font));
if(rp)
return gravitate(*rp, c->w.r, p);
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

View File

@ -37,6 +37,7 @@ struct CTuple {
enum {
WMState, WMProtocols, WMDelete,
NetSupported, NetWMName,
Utf8String,
TagsAtom,
AtomLast
};

View File

@ -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);

View File

@ -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,

View File

@ -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)

View File

@ -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);
}

View File

@ -49,6 +49,7 @@ struct WinHints {
Point inc;
Rectangle aspect;
Point grav;
Bool gravstatic;
};
struct Handlers {