fix floatrules and scratchpad resizing on togglebar
This commit is contained in:
parent
fa9ff0ad64
commit
17bc5dfdee
1 changed files with 2001 additions and 1954 deletions
183
dwm.c
183
dwm.c
|
@ -111,10 +111,8 @@ struct Client {
|
|||
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
|
||||
int bw, oldbw;
|
||||
unsigned int tags;
|
||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow;
|
||||
int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow, hasfloatrule;
|
||||
pid_t pid;
|
||||
int floatborderpx;
|
||||
int hasfloatbw;
|
||||
char scratchkey;
|
||||
Client *next;
|
||||
Client *snext;
|
||||
|
@ -172,8 +170,7 @@ typedef struct {
|
|||
int isterminal;
|
||||
int noswallow;
|
||||
float floatx, floaty, floatw, floath;
|
||||
int floatborderpx;
|
||||
int monitor;
|
||||
int borderpx;
|
||||
} Rule;
|
||||
|
||||
/* Xresources preferences */
|
||||
|
@ -190,7 +187,9 @@ typedef struct {
|
|||
} ResourcePref;
|
||||
|
||||
/* function declarations */
|
||||
static void applyrules(Client *c);
|
||||
static int matchrules(Client *c);
|
||||
static void applyfloatrules(Client *c, int ri);
|
||||
static void applyrules(Client *c, int ri);
|
||||
static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
|
||||
static void arrange(Monitor *m);
|
||||
static void arrangemon(Monitor *m);
|
||||
|
@ -356,70 +355,110 @@ struct Pertag {
|
|||
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; };
|
||||
|
||||
/* function implementations */
|
||||
void
|
||||
applyrules(Client *c)
|
||||
|
||||
int
|
||||
matchrules(Client *c)
|
||||
{
|
||||
const char *class, *instance;
|
||||
unsigned int i;
|
||||
unsigned int ri;
|
||||
const Rule *r;
|
||||
Monitor *m;
|
||||
XClassHint ch = { NULL, NULL };
|
||||
|
||||
/* rule matching */
|
||||
c->isfloating = 0;
|
||||
c->tags = 0;
|
||||
c->scratchkey = 0;
|
||||
XGetClassHint(dpy, c->win, &ch);
|
||||
class = ch.res_class ? ch.res_class : broken;
|
||||
instance = ch.res_name ? ch.res_name : broken;
|
||||
|
||||
for (i = 0; i < LENGTH(rules); i++) {
|
||||
r = &rules[i];
|
||||
for (ri = 0; ri < LENGTH(rules); ri++) {
|
||||
r = &rules[ri];
|
||||
if ((!r->title || strstr(c->name, r->title))
|
||||
&& (!r->class || strstr(class, r->class))
|
||||
&& (!r->instance || strstr(instance, r->instance)))
|
||||
{
|
||||
for (m = mons; m && m->num != r->monitor; m = m->next);
|
||||
if (m)
|
||||
c->mon = m;
|
||||
c->isterminal = r->isterminal;
|
||||
c->noswallow = r->noswallow;
|
||||
c->isfloating = r->isfloating;
|
||||
c->tags |= r->tags;
|
||||
c->scratchkey = r->scratchkey;
|
||||
if (r->floatborderpx >= 0) {
|
||||
c->floatborderpx = r->floatborderpx;
|
||||
c->hasfloatbw = 1;
|
||||
}
|
||||
|
||||
- (bh + m->by);
|
||||
if (r->isfloating) {
|
||||
if (r->floatw > 1) c->w = r->floatw - c->floatborderpx * 2;
|
||||
else if (r->floatw > 0) c->w = (int)((float)c->mon->mw * r->floatw - c->floatborderpx * 2);
|
||||
|
||||
if (r->floath > 1) c->h = r->floath - c->floatborderpx * 2 - (bh + m->by);
|
||||
else if (r->floath > 0) c->h = (int)((float)c->mon->mh * r->floath - c->floatborderpx * 2) - (bh + m->by);
|
||||
|
||||
|
||||
if (r->floatx > 1) c->x = c->mon->mx + r->floatx;
|
||||
else if (r->floatx > 0) c->x = c->mon->mx + (int)((float)c->mon->mw * r->floatx - (float)c->w / 2);
|
||||
else if (r->floatx == 0);
|
||||
else if (r->floatx > -1) c->x = c->mon->mx + c->mon->mw + (int)((float)c->mon->mw * r->floatx - (float)c->w / 2);
|
||||
else c->x = c->mon->mx + c->mon->mw + r->floatx - c->w;
|
||||
|
||||
if (r->floaty > 1) c->y = c->mon->my + r->floaty;
|
||||
else if (r->floaty > 0) c->y = c->mon->my + (int)((float)c->mon->mh * r->floaty - (float)c->h / 2);
|
||||
else if (r->floaty == 0);
|
||||
else if (r->floaty > -1) c->y = c->mon->my + c->mon->mh + (int)((float)c->mon->mh * r->floaty - (float)c->h / 2);
|
||||
else c->y = c->mon->my + c->mon->mh + r->floaty - c->h;
|
||||
}
|
||||
&& (!r->instance || strstr(instance, r->instance))) {
|
||||
if (ch.res_class)
|
||||
XFree(ch.res_class);
|
||||
if (ch.res_name)
|
||||
XFree(ch.res_name);
|
||||
return ri;
|
||||
}
|
||||
}
|
||||
if (ch.res_class)
|
||||
XFree(ch.res_class);
|
||||
if (ch.res_name)
|
||||
XFree(ch.res_name);
|
||||
return False;
|
||||
}
|
||||
|
||||
void
|
||||
applyfloatrules(Client *c, int ri)
|
||||
{
|
||||
const Rule *r;
|
||||
ri = (ri) ? ri : matchrules(c);
|
||||
if (ri) {
|
||||
r = &rules[ri];
|
||||
|
||||
if (r->floatw > 1)
|
||||
c->w = r->floatw;
|
||||
else if (r->floatw > 0)
|
||||
c->w = (int)((float)c->mon->ww * r->floatw);
|
||||
c->w = MIN(c->w, c->mon->ww) - c->bw * 2;
|
||||
|
||||
if (r->floath > 1)
|
||||
c->h = r->floath;
|
||||
else if (r->floath > 0)
|
||||
c->h = (int)((float)c->mon->wh * r->floath);
|
||||
c->h = MIN(c->h, c->mon->wh) - c->bw * 2;
|
||||
|
||||
if (r->floatx > 1)
|
||||
c->x = r->floatx;
|
||||
else if (r->floatx > 0)
|
||||
c->x = (int)((float)c->mon->ww * r->floatx - (float)WIDTH(c) / 2);
|
||||
else if (r->floatx == 0)
|
||||
;
|
||||
else if (r->floatx > -1)
|
||||
c->x = c->mon->ww + (int)((float)c->mon->ww * r->floatx - (float)WIDTH(c) / 2);
|
||||
else
|
||||
c->x = c->mon->ww + r->floatx - WIDTH(c);
|
||||
if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
|
||||
c->x = c->mon->ww - WIDTH(c);
|
||||
c->x = MAX(c->x + c->mon->wx, c->mon->wx);
|
||||
|
||||
if (r->floaty > 1)
|
||||
c->y = r->floaty;
|
||||
else if (r->floaty > 0)
|
||||
c->y = (int)((float)c->mon->wh * r->floaty - (float)HEIGHT(c) / 2);
|
||||
else if (r->floaty == 0)
|
||||
;
|
||||
else if (r->floaty > -1)
|
||||
c->y = c->mon->wh + (int)((float)c->mon->wh * r->floaty - (float)HEIGHT(c) / 2);
|
||||
else
|
||||
c->y = c->mon->wh + r->floaty - HEIGHT(c);
|
||||
if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh)
|
||||
c->y = c->mon->wh - HEIGHT(c);
|
||||
c->y = MAX(c->y + c->mon->wy, c->mon->wy);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
applyrules(Client *c, int ri)
|
||||
{
|
||||
const Rule *r;
|
||||
ri = (ri) ? ri : matchrules(c);
|
||||
|
||||
c->isfloating = 0;
|
||||
c->tags = 0;
|
||||
c->scratchkey = 0;
|
||||
c->bw = borderpx;
|
||||
if (ri) {
|
||||
c->hasfloatrule = True;
|
||||
r = &rules[ri];
|
||||
c->isterminal = r->isterminal;
|
||||
c->noswallow = r->noswallow;
|
||||
c->isfloating = r->isfloating;
|
||||
c->tags |= r->tags;
|
||||
c->scratchkey = r->scratchkey;
|
||||
if (r->borderpx >= 0)
|
||||
c->bw = r->borderpx;
|
||||
if (c->isfloating) {
|
||||
applyfloatrules(c, ri);
|
||||
}
|
||||
}
|
||||
c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags];
|
||||
}
|
||||
|
||||
|
@ -1457,6 +1496,8 @@ manage(Window w, XWindowAttributes *wa)
|
|||
Client *c, *t = NULL, *term = NULL;
|
||||
Window trans = None;
|
||||
XWindowChanges wc;
|
||||
int ri;
|
||||
|
||||
|
||||
c = ecalloc(1, sizeof(Client));
|
||||
c->win = w;
|
||||
|
@ -1468,16 +1509,20 @@ manage(Window w, XWindowAttributes *wa)
|
|||
c->h = c->oldh = wa->height;
|
||||
c->oldbw = wa->border_width;
|
||||
|
||||
ri = False;
|
||||
|
||||
updatetitle(c);
|
||||
if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) {
|
||||
c->mon = t->mon;
|
||||
c->tags = t->tags;
|
||||
} else {
|
||||
c->mon = selmon;
|
||||
applyrules(c);
|
||||
ri = matchrules(c);
|
||||
applyrules(c, ri);
|
||||
term = termforwin(c);
|
||||
}
|
||||
|
||||
/* We can't repeat this code if a window has a floating rule, because that is handled by applyfloatrules() */
|
||||
if (!c->isfloating) {
|
||||
if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
|
||||
c->x = c->mon->mx + c->mon->mw - WIDTH(c);
|
||||
if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh)
|
||||
|
@ -1486,10 +1531,7 @@ manage(Window w, XWindowAttributes *wa)
|
|||
/* only fix client y-offset, if the client center might cover the bar */
|
||||
c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx)
|
||||
&& (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my);
|
||||
if (c->hasfloatbw)
|
||||
c->bw = c->floatborderpx;
|
||||
else
|
||||
c->bw = borderpx;
|
||||
}
|
||||
|
||||
wc.border_width = c->bw;
|
||||
XConfigureWindow(dpy, w, CWBorderWidth, &wc);
|
||||
|
@ -1500,10 +1542,10 @@ manage(Window w, XWindowAttributes *wa)
|
|||
updatewmhints(c);
|
||||
XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
|
||||
grabbuttons(c, 0);
|
||||
if (!c->isfloating)
|
||||
c->isfloating = c->oldstate = trans != None || c->isfixed;
|
||||
if (c->isfloating)
|
||||
XRaiseWindow(dpy, c->win);
|
||||
else
|
||||
c->isfloating = c->oldstate = trans != None || c->isfixed;
|
||||
attachtop(c);
|
||||
attachstack(c);
|
||||
XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
|
||||
|
@ -1736,7 +1778,7 @@ recttomon(int x, int y, int w, int h)
|
|||
void
|
||||
resize(Client *c, int x, int y, int w, int h, int interact)
|
||||
{
|
||||
if (applysizehints(c, &x, &y, &w, &h, interact))
|
||||
if (applysizehints(c, &x, &y, &w, &h, interact) || c->hasfloatrule)
|
||||
resizeclient(c, x, y, w, h);
|
||||
}
|
||||
|
||||
|
@ -1749,9 +1791,6 @@ resizeclient(Client *c, int x, int y, int w, int h)
|
|||
c->oldy = c->y; c->y = wc.y = y;
|
||||
c->oldw = c->w; c->w = wc.width = w;
|
||||
c->oldh = c->h; c->h = wc.height = h;
|
||||
if (c->isfloating && c->hasfloatbw && !c->isfullscreen)
|
||||
wc.border_width = c->floatborderpx;
|
||||
else
|
||||
wc.border_width = c->bw;
|
||||
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
|
||||
configure(c);
|
||||
|
@ -2112,11 +2151,15 @@ showhide(Client *c)
|
|||
{
|
||||
if (!c)
|
||||
return;
|
||||
if (c->isfloating) {
|
||||
applyfloatrules(c, False);
|
||||
}
|
||||
if (ISVISIBLE(c)) {
|
||||
/* show clients top down */
|
||||
XMoveWindow(dpy, c->win, c->x, c->y);
|
||||
if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen)
|
||||
if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) {
|
||||
resize(c, c->x, c->y, c->w, c->h, 0);
|
||||
}
|
||||
showhide(c->snext);
|
||||
} else {
|
||||
/* hide clients bottom up */
|
||||
|
@ -2257,6 +2300,7 @@ tagmon(const Arg *arg)
|
|||
void
|
||||
togglebar(const Arg *arg)
|
||||
{
|
||||
printf("toggling bar\n");
|
||||
selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
|
||||
updatebarpos(selmon);
|
||||
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
|
||||
|
@ -2296,7 +2340,10 @@ togglescratch(const Arg *arg)
|
|||
break;
|
||||
}
|
||||
if (found) {
|
||||
if(m != selmon);
|
||||
applyfloatrules(c, False);
|
||||
if(m != selmon){
|
||||
sendmon(c, selmon);
|
||||
}
|
||||
else {
|
||||
c->tags = ISVISIBLE(c) ? 0 : selmon->tagset[selmon->seltags];
|
||||
focus(NULL);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue