static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact);
static void arrange(Monitor *m);
static void arrangemon(Monitor *m);
+static void attach_as_master(Client *c);
static void attach(Client *c);
static void attachstack(Client *c);
static void buttonpress(XEvent *e);
static void motionnotify(XEvent *e);
static void movemouse(const Arg *arg);
static Client *nexttiled(Client *c);
+static Client *nextvisible(Client *c);
static void pop(Client *);
static void propertynotify(XEvent *e);
static void quit(const Arg *arg);
for(i = 0; i < LENGTH(rules); i++) {
r = &rules[i];
- if((!r->title || strstr(c->name, r->title))
+ if((!r->title || c->name == strstr(c->name, r->title))
&& (!r->class || strstr(class, r->class))
&& (!r->instance || strstr(instance, r->instance)))
{
}
void
-attach(Client *c) {
+attach_as_master(Client *c) {
c->next = c->mon->clients;
c->mon->clients = c;
}
+void
+attach(Client *c) {
+ if (c->mon->sel) {
+ c->next = c->mon->sel->next;
+ c->mon->sel->next = c;
+ } else {
+ attach_as_master(c);
+ }
+}
void
attachstack(Client *c) {
|| (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen)));
}
else if(cme->message_type == netatom[NetActiveWindow]) {
+ return;
if(!ISVISIBLE(c)) {
c->mon->seltags ^= 1;
c->mon->tagset[c->mon->seltags] = c->tags;
*tc = c->next;
}
+// NOTE: the stack is for z-order and most-recently-focused
+// only mon->clients determines position in visible layout
void
detachstack(Client *c) {
- Client **tc, *t;
-
- for(tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext);
- *tc = c->snext;
-
+ Client *prev = NULL, *next_sel = NULL, *i;
+ for(i = c->mon->stack; i && i != c; i = i->snext) {
+ prev = i;
+ }
if(c == c->mon->sel) {
- for(t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext);
- c->mon->sel = t;
+ // find last visible window before c
+ // WARNING if you detach() before detachstack() this will select last visible window
+ for(i = nextvisible(c->mon->clients); i && i != c; i = nextvisible(i->next))
+ next_sel = i;
+ // failing that, find first visible window (besides c)
+ if (!next_sel)
+ for(i = nextvisible(c->mon->clients); i && i == c; i = nextvisible(i->next));
+ if (i != c)
+ next_sel = i;
+ c->mon->sel = next_sel;
+ }
+ if (prev) {
+ prev->snext = c->snext;
+ } else {
+ c->mon->stack = c->snext;
}
}
c->mon->sel = c;
arrange(c->mon);
XMapWindow(dpy, c->win);
- focus(NULL);
+ focus(c);
}
void
return c;
}
+Client *
+nextvisible(Client *c) {
+ for(; c && !ISVISIBLE(c); c = c->next);
+ return c;
+}
+
void
pop(Client *c) {
detach(c);
- attach(c);
+ attach_as_master(c);
focus(c);
arrange(c->mon);
}
if(c->mon == m)
return;
unfocus(c, True);
- detach(c);
detachstack(c);
+ detach(c);
c->mon = m;
c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
attach(c);
void
spawn(const Arg *arg) {
+ int tag = 0, i;
+ if(arg->v == termcmd) {
+ for(i = 0; i < 32; ++i) {
+ if(selmon->tagset[selmon->seltags] & (1 << i)) {
+ tag = i;
+ break;
+ }
+ }
+ _SWM_WS[8] = swm_tags[tag][0];
+ _SWM_WS[9] = swm_tags[tag][1];
+ }
if(arg->v == dmenucmd)
dmenumon[0] = '0' + selmon->num;
if(fork() == 0) {
XWindowChanges wc;
/* The server grab construct avoids race conditions. */
- detach(c);
detachstack(c);
+ detach(c);
if(!destroyed) {
wc.border_width = c->oldbw;
XGrabServer(dpy);
XUngrabServer(dpy);
}
free(c);
- focus(NULL);
+ focus(selmon ? selmon->sel : NULL);
updateclientlist();
arrange(m);
}