@ -51,7 +51,7 @@
# define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
# define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
* MAX ( 0 , MIN ( ( y ) + ( h ) , ( m ) - > wy + ( m ) - > wh ) - MAX ( ( y ) , ( m ) - > wy ) ) )
# define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
# define ISVISIBLE(C) ((( C->tags & C->mon->tagset[C->mon->seltags])) || (C->iskeyboard ))
# define LENGTH(X) (sizeof X / sizeof X[0])
# define MOUSEMASK (BUTTONMASK|PointerMotionMask)
# define WIDTH(X) ((X)->w + 2 * (X)->bw + gappx)
@ -94,7 +94,7 @@ 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 , nofakefullscreen ;
int isfixed , isfloating , isurgent , neverfocus , oldstate , isfullscreen , isterminal , noswallow , nofakefullscreen , iskeyboard ;
pid_t pid ;
Client * next ;
Client * snext ;
@ -145,6 +145,7 @@ typedef struct {
int isterminal ;
int noswallow ;
int nofakefullscreen ;
int iskeyboard ;
int monitor ;
} Rule ;
@ -244,6 +245,7 @@ static int xerror(Display *dpy, XErrorEvent *ee);
static int xerrordummy ( Display * dpy , XErrorEvent * ee ) ;
static int xerrorstart ( Display * dpy , XErrorEvent * ee ) ;
static void zoom ( const Arg * arg ) ;
static void adjustborders ( Monitor * m ) ;
static pid_t getparentprocess ( pid_t p ) ;
static int isdescprocess ( pid_t p , pid_t c ) ;
@ -321,6 +323,7 @@ applyrules(Client *c)
c - > noswallow = r - > noswallow ;
c - > isfloating = r - > isfloating ;
c - > nofakefullscreen = r - > nofakefullscreen ;
c - > iskeyboard = r - > iskeyboard ;
c - > tags | = r - > tags ;
for ( m = mons ; m & & m - > num ! = r - > monitor ; m = m - > next ) ;
if ( m )
@ -340,6 +343,10 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
int baseismin ;
Monitor * m = c - > mon ;
if ( c - > iskeyboard ) {
return ( False ) ;
}
/* set minimum possible */
* w = MAX ( 1 , * w ) ;
* h = MAX ( 1 , * h ) ;
@ -401,12 +408,14 @@ applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact)
}
void
arrange ( Monitor * m )
{
if ( m )
arrange ( Monitor * m ) {
if ( m ) {
adjustborders ( m ) ;
showhide ( m - > stack ) ;
else for ( m = mons ; m ; m = m - > next )
} else for ( m = mons ; m ; m = m - > next ) {
adjustborders ( m ) ;
showhide ( m - > stack ) ;
}
if ( m ) {
arrangemon ( m ) ;
restack ( m ) ;
@ -459,7 +468,7 @@ attachstack(Client *c)
void
swallow ( Client * p , Client * c )
{
if ( c - > noswallow | | c - > isterminal )
if ( c - > noswallow | | c - > isterminal | | c - > isfloating )
return ;
detach ( c ) ;
@ -498,8 +507,7 @@ unswallow(Client *c)
}
void
buttonpress ( XEvent * e )
{
buttonpress ( XEvent * e ) {
unsigned int i , x , click ;
Arg arg = { 0 } ;
Client * c ;
@ -540,8 +548,7 @@ buttonpress(XEvent *e)
}
void
checkotherwm ( void )
{
checkotherwm ( void ) {
xerrorxlib = XSetErrorHandler ( xerrorstart ) ;
/* this causes an error if some other window manager is running */
XSelectInput ( dpy , DefaultRootWindow ( dpy ) , SubstructureRedirectMask ) ;
@ -551,8 +558,7 @@ checkotherwm(void)
}
void
cleanup ( void )
{
cleanup ( void ) {
Arg a = { . ui = ~ 0 } ;
Layout foo = { " " , NULL } ;
Monitor * m ;
@ -578,8 +584,7 @@ cleanup(void)
}
void
cleanupmon ( Monitor * mon )
{
cleanupmon ( Monitor * mon ) {
Monitor * m ;
if ( mon = = mons )
@ -613,8 +618,7 @@ clientmessage(XEvent *e)
}
void
configure ( Client * c )
{
configure ( Client * c ) {
XConfigureEvent ce ;
ce . type = ConfigureNotify ;
@ -632,8 +636,7 @@ configure(Client *c)
}
void
configurenotify ( XEvent * e )
{
configurenotify ( XEvent * e ) {
Monitor * m ;
XConfigureEvent * ev = & e - > xconfigure ;
int dirty ;
@ -656,14 +659,13 @@ configurenotify(XEvent *e)
}
void
configurerequest ( XEvent * e )
{
configurerequest ( XEvent * e ) {
Client * c ;
Monitor * m ;
XConfigureRequestEvent * ev = & e - > xconfigurerequest ;
XWindowChanges wc ;
if ( ( c = wintoclient ( ev - > window ) ) ) {
if ( ( c = wintoclient ( ev - > window ) ) & & ! c - > iskeyboard ) {
if ( ev - > value_mask & CWBorderWidth )
c - > bw = ev - > border_width ;
else if ( c - > isfloating | | ! selmon - > lt [ selmon - > sellt ] - > arrange ) {
@ -708,8 +710,7 @@ configurerequest(XEvent *e)
}
Monitor *
createmon ( void )
{
createmon ( void ) {
Monitor * m ;
m = ecalloc ( 1 , sizeof ( Monitor ) ) ;
@ -725,8 +726,7 @@ createmon(void)
}
void
destroynotify ( XEvent * e )
{
destroynotify ( XEvent * e ) {
Client * c ;
XDestroyWindowEvent * ev = & e - > xdestroywindow ;
@ -738,8 +738,7 @@ destroynotify(XEvent *e)
}
void
detach ( Client * c )
{
detach ( Client * c ) {
Client * * tc ;
for ( tc = & c - > mon - > clients ; * tc & & * tc ! = c ; tc = & ( * tc ) - > next ) ;
@ -747,8 +746,7 @@ detach(Client *c)
}
void
detachstack ( Client * c )
{
detachstack ( Client * c ) {
Client * * tc , * t ;
for ( tc = & c - > mon - > stack ; * tc & & * tc ! = c ; tc = & ( * tc ) - > snext ) ;
@ -761,8 +759,7 @@ detachstack(Client *c)
}
Monitor *
dirtomon ( int dir )
{
dirtomon ( int dir ) {
Monitor * m = NULL ;
if ( dir > 0 ) {
@ -775,8 +772,7 @@ dirtomon(int dir)
return m ;
}
void
drawbar ( Monitor * m )
void drawbar ( Monitor * m )
{
int x , w , tw = 0 ;
int boxs = drw - > fonts - > h / 9 ;
@ -844,6 +840,11 @@ enternotify(XEvent *e)
if ( ( ev - > mode ! = NotifyNormal | | ev - > detail = = NotifyInferior ) & & ev - > window ! = root )
return ;
c = wintoclient ( ev - > window ) ;
if ( c & & c - > iskeyboard ) {
return ;
}
m = c ? c - > mon : wintomon ( ev - > window ) ;
if ( m ! = selmon ) {
unfocus ( selmon - > sel , 1 ) ;
@ -854,8 +855,7 @@ enternotify(XEvent *e)
}
void
expose ( XEvent * e )
{
expose ( XEvent * e ) {
Monitor * m ;
XExposeEvent * ev = & e - > xexpose ;
@ -864,8 +864,10 @@ expose(XEvent *e)
}
void
focus ( Client * c )
{
focus ( Client * c ) {
if ( c & & c - > iskeyboard ) {
return ;
}
if ( ! c | | ! ISVISIBLE ( c ) )
for ( c = selmon - > stack ; c & & ! ISVISIBLE ( c ) ; c = c - > snext ) ;
if ( selmon - > sel & & selmon - > sel ! = c )
@ -899,8 +901,7 @@ focusin(XEvent *e)
}
void
focusmon ( const Arg * arg )
{
focusmon ( const Arg * arg ) {
Monitor * m ;
if ( ! mons - > next )
@ -914,23 +915,23 @@ focusmon(const Arg *arg)
}
void
focusstack ( const Arg * arg )
{
focusstack ( const Arg * arg ) {
Client * c = NULL , * i ;
if ( ! selmon - > sel )
return ;
if ( arg - > i > 0 ) {
for ( c = selmon - > sel - > next ; c & & ! ISVISIBLE ( c ) ; c = c - > next ) ;
for ( c = selmon - > sel - > next ; c & & ( ! ISVISIBLE ( c ) | | c - > iskeyboard ) ; c = c - > next ) ;
if ( ! c )
for ( c = selmon - > clients ; c & & ! ISVISIBLE ( c ) ; c = c - > next ) ;
} else {
for ( c = selmon - > clients ; c & & ( ! ISVISIBLE ( c ) | | c - > iskeyboard ) ; c = c - > next ) ;
}
else {
for ( i = selmon - > clients ; i ! = selmon - > sel ; i = i - > next )
if ( ISVISIBLE ( i ) )
if ( ISVISIBLE ( i ) & & ! i - > iskeyboard )
c = i ;
if ( ! c )
for ( ; i ; i = i - > next )
if ( ISVISIBLE ( i ) )
if ( ISVISIBLE ( i ) & & ! i - > iskeyboard )
c = i ;
}
if ( c ) {
@ -940,8 +941,7 @@ focusstack(const Arg *arg)
}
Atom
getatomprop ( Client * c , Atom prop )
{
getatomprop ( Client * c , Atom prop ) {
int di ;
unsigned long dl ;
unsigned char * p = NULL ;
@ -956,8 +956,7 @@ getatomprop(Client *c, Atom prop)
}
int
getrootptr ( int * x , int * y )
{
getrootptr ( int * x , int * y ) {
int di ;
unsigned int dui ;
Window dummy ;
@ -966,8 +965,7 @@ getrootptr(int *x, int *y)
}
long
getstate ( Window w )
{
getstate ( Window w ) {
int format ;
long result = - 1 ;
unsigned char * p = NULL ;
@ -1030,8 +1028,7 @@ grabbuttons(Client *c, int focused)
}
void
grabkeys ( void )
{
grabkeys ( void ) {
updatenumlockmask ( ) ;
{
unsigned int i , j ;
@ -1048,8 +1045,7 @@ grabkeys(void)
}
void
incnmaster ( const Arg * arg )
{
incnmaster ( const Arg * arg ) {
selmon - > nmaster = MAX ( selmon - > nmaster + arg - > i , 0 ) ;
arrange ( selmon ) ;
}
@ -1067,8 +1063,7 @@ isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
# endif /* XINERAMA */
void
keypress ( XEvent * e )
{
keypress ( XEvent * e ) {
unsigned int i ;
KeySym keysym ;
XKeyEvent * ev ;
@ -1099,8 +1094,7 @@ killclient(const Arg *arg)
}
void
manage ( Window w , XWindowAttributes * wa )
{
manage ( Window w , XWindowAttributes * wa ) {
Client * c , * t = NULL , * term = NULL ;
Window trans = None ;
XWindowChanges wc ;
@ -1108,13 +1102,6 @@ manage(Window w, XWindowAttributes *wa)
c = ecalloc ( 1 , sizeof ( Client ) ) ;
c - > win = w ;
c - > pid = winpid ( w ) ;
/* geometry */
c - > x = c - > oldx = wa - > x ;
c - > y = c - > oldy = wa - > y ;
c - > w = c - > oldw = wa - > width ;
c - > h = c - > oldh = wa - > height ;
c - > oldbw = wa - > border_width ;
updatetitle ( c ) ;
if ( XGetTransientForHint ( dpy , w , & trans ) & & ( t = wintoclient ( trans ) ) ) {
c - > mon = t - > mon ;
@ -1125,15 +1112,43 @@ manage(Window w, XWindowAttributes *wa)
term = termforwin ( c ) ;
}
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 )
c - > y = c - > mon - > my + c - > mon - > mh - HEIGHT ( c ) ;
c - > x = MAX ( c - > x , c - > mon - > mx ) ;
/* 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 ) ;
c - > bw = borderpx ;
/* geometry */
c - > x = c - > oldx = wa - > x ;
c - > y = c - > oldy = wa - > y ;
c - > w = c - > oldw = wa - > width ;
c - > h = c - > oldh = wa - > height ;
c - > oldbw = wa - > border_width ;
/* If Keyboard */
if ( c - > iskeyboard ) {
c - > y = c - > mon - > my + c - > mon - > mh - c - > h ;
c - > mon - > mh - = HEIGHT ( c ) ;
} else {
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 )
c - > y = c - > mon - > my + c - > mon - > mh - HEIGHT ( c ) ;
c - > x = MAX ( c - > x , c - > mon - > mx ) ;
/* 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 ) ;
}
updatewindowtype ( c ) ;
if ( c - > isfloating ) {
c - > bw = ( c - > isfullscreen | | c - > iskeyboard ) ? 0 : borderpx ;
} else {
c - > bw = 0 ;
for ( t = c - > mon - > clients ; t ; t = c - > next ) {
if ( ! t - > isfloating & & c ! = t & & c - > tags & t - > tags ) {
c - > bw = borderpx ;
break ;
}
}
adjustborders ( c - > mon ) ;
}
wc . border_width = c - > bw ;
XConfigureWindow ( dpy , w , CWBorderWidth , & wc ) ;
@ -1224,8 +1239,7 @@ motionnotify(XEvent *e)
}
void
movemouse ( const Arg * arg )
{
movemouse ( const Arg * arg ) {
int x , y , ocx , ocy , nx , ny ;
Client * c ;
Monitor * m ;
@ -1282,15 +1296,13 @@ movemouse(const Arg *arg)
}
Client *
nexttiled ( Client * c )
{
nexttiled ( Client * c ) {
for ( ; c & & ( c - > isfloating | | ! ISVISIBLE ( c ) ) ; c = c - > next ) ;
return c ;
}
void
pop ( Client * c )
{
pop ( Client * c ) {
detach ( c ) ;
attach ( c ) ;
focus ( c ) ;
@ -1298,8 +1310,7 @@ pop(Client *c)
}
void
propertynotify ( XEvent * e )
{
propertynotify ( XEvent * e ) {
Client * c ;
Window trans ;
XPropertyEvent * ev = & e - > xproperty ;
@ -1355,15 +1366,67 @@ recttomon(int x, int y, int w, int h)
}
void
resize ( Client * c , int x , int y , int w , int h , int interact )
{
adjustborders ( Monitor * m ) {
Client * c , * l = NULL ;
int visible = 0 ;
for ( c = m - > clients ; c ; c = c - > next ) {
if ( ISVISIBLE ( c ) & & ! c - > isfloating & & m - > lt [ m - > sellt ] - > arrange ) {
if ( m - > lt [ m - > sellt ] - > arrange = = monocle ) {
visible = 1 ;
c - > oldbw = c - > bw ;
c - > bw = 0 ;
} else {
visible + + ;
c - > oldbw = c - > bw ;
c - > bw = borderpx ;
}
l = c ;
}
}
if ( l & & visible = = 1 & & l - > bw ) {
l - > oldbw = l - > bw ;
l - > bw = 0 ;
resizeclient ( l , l - > x , l - > y , l - > w , l - > h ) ;
}
}
void
resize ( Client * c , int x , int y , int w , int h , int interact ) {
int n ;
if ( c & & c - > iskeyboard ) {
return ;
}
n = c - > mon - > mx + c - > mon - > mw ;
if ( x + w + 1 + ( 2 * c - > bw ) > = n ) {
w = n - x - c - > bw ;
}
n = c - > mon - > my + c - > mon - > mh ;
if ( y + h + 1 + ( 2 * c - > bw ) > = n ) {
h = n - y - c - > bw ;
}
if ( x < = c - > mon - > mx ) {
x - = c - > bw ;
w + = c - > bw ;
}
if ( y < = c - > mon - > my ) {
y - = c - > bw ;
y + = c - > bw ;
}
if ( applysizehints ( c , & x , & y , & w , & h , interact ) )
resizeclient ( c , x , y , w , h ) ;
}
void
resizeclient ( Client * c , int x , int y , int w , int h )
{
resizeclient ( Client * c , int x , int y , int w , int h ) {
XWindowChanges wc ;
unsigned int n ;
unsigned int gapoffset ;
@ -1372,6 +1435,10 @@ resizeclient(Client *c, int x, int y, int w, int h)
wc . border_width = c - > bw ;
if ( c - > iskeyboard ) {
return ;
}
/* Get number of clients for the selected monitor */
for ( n = 0 , nbc = nexttiled ( selmon - > clients ) ; nbc ; nbc = nexttiled ( nbc - > next ) , n + + ) ;
@ -1867,6 +1934,10 @@ unmanage(Client *c, int destroyed)
Monitor * m = c - > mon ;
XWindowChanges wc ;
if ( c - > iskeyboard ) {
updategeom ( ) ;
}
if ( c - > swallowing ) {
unswallow ( c ) ;
return ;