@ -55,12 +55,12 @@
# define WIDTH(X) ((X)->w + 2 * (X)->bw)
# define HEIGHT(X) ((X)->h + 2 * (X)->bw)
# define TAGMASK ((1 << LENGTH(tags)) - 1)
# define TEXTW(X) (drw_ fontset_getwidth(drw, (X)) + lrpad )
# define TEXTW(X) (drw_ text(drw, 0, 0, 0, 0, (X), 0) + drw->fonts[0]->h )
/* enums */
enum { CurNormal , CurResize , CurMove , CurLast } ; /* cursor */
enum { SchemeNorm , SchemeSel } ; /* color schemes */
enum { NetSupported , NetWMName , NetWMState , NetWMCheck ,
enum { SchemeNorm , SchemeSel , SchemeLast } ; /* color schemes */
enum { NetSupported , NetWMName , NetWMState ,
NetWMFullscreen , NetActiveWindow , NetWMWindowType ,
NetWMWindowTypeDialog , NetClientList , NetLast } ; /* EWMH atoms */
enum { WMProtocols , WMDelete , WMState , WMTakeFocus , WMLast } ; /* default atoms */
@ -152,6 +152,7 @@ static void buttonpress(XEvent *e);
static void checkotherwm ( void ) ;
static void cleanup ( void ) ;
static void cleanupmon ( Monitor * mon ) ;
static void clearurgent ( Client * c ) ;
static void clientmessage ( XEvent * e ) ;
static void configure ( Client * c ) ;
static void configurenotify ( XEvent * e ) ;
@ -169,7 +170,6 @@ static void focus(Client *c);
static void focusin ( XEvent * e ) ;
static void focusmon ( const Arg * arg ) ;
static void focusstack ( const Arg * arg ) ;
static Atom getatomprop ( Client * c , Atom prop ) ;
static int getrootptr ( int * x , int * y ) ;
static long getstate ( Window w ) ;
static int gettextprop ( Window w , Atom atom , char * text , unsigned int size ) ;
@ -203,7 +203,6 @@ static void setfullscreen(Client *c, int fullscreen);
static void setlayout ( const Arg * arg ) ;
static void setmfact ( const Arg * arg ) ;
static void setup ( void ) ;
static void seturgent ( Client * c , int urg ) ;
static void showhide ( Client * c ) ;
static void sigchld ( int unused ) ;
static void spawn ( const Arg * arg ) ;
@ -217,15 +216,15 @@ static void toggleview(const Arg *arg);
static void unfocus ( Client * c , int setfocus ) ;
static void unmanage ( Client * c , int destroyed ) ;
static void unmapnotify ( XEvent * e ) ;
static int updategeom ( void ) ;
static void updatebarpos ( Monitor * m ) ;
static void updatebars ( void ) ;
static void updateclientlist ( void ) ;
static int updategeom ( void ) ;
static void updatenumlockmask ( void ) ;
static void updatesizehints ( Client * c ) ;
static void updatestatus ( void ) ;
static void updatetitle ( Client * c ) ;
static void updatewindowtype ( Client * c ) ;
static void updatetitle ( Client * c ) ;
static void updatewmhints ( Client * c ) ;
static void view ( const Arg * arg ) ;
static Client * wintoclient ( Window w ) ;
@ -241,7 +240,6 @@ static char stext[256];
static int screen ;
static int sw , sh ; /* X display screen geometry width, height */
static int bh , blw = 0 ; /* bar geometry */
static int lrpad ; /* sum of left and right padding for text */
static int ( * xerrorxlib ) ( Display * , XErrorEvent * ) ;
static unsigned int numlockmask = 0 ;
static void ( * handler [ LASTEvent ] ) ( XEvent * ) = {
@ -263,11 +261,11 @@ static void (*handler[LASTEvent]) (XEvent *) = {
static Atom wmatom [ WMLast ] , netatom [ NetLast ] ;
static int running = 1 ;
static Cur * cursor [ CurLast ] ;
static Clr * * scheme ;
static Clr Scheme scheme [ SchemeLast ] ;
static Display * dpy ;
static Drw * drw ;
static Monitor * mons , * selmon ;
static Window root , wmcheckwin ;
static Window root ;
/* configuration, allows nested code to access above variables */
# include "config.h"
@ -440,14 +438,12 @@ buttonpress(XEvent *e)
arg . ui = 1 < < i ;
} else if ( ev - > x < x + blw )
click = ClkLtSymbol ;
else if ( ev - > x > selmon - > ww - ( int ) TEXTW ( stext ) )
else if ( ev - > x > selmon - > ww - TEXTW ( stext ) )
click = ClkStatusText ;
else
click = ClkWinTitle ;
} else if ( ( c = wintoclient ( ev - > window ) ) ) {
focus ( c ) ;
restack ( selmon ) ;
XAllowEvents ( dpy , ReplayPointer , CurrentTime ) ;
click = ClkClientWin ;
}
for ( i = 0 ; i < LENGTH ( buttons ) ; i + + )
@ -485,9 +481,11 @@ cleanup(void)
cleanupmon ( mons ) ;
for ( i = 0 ; i < CurLast ; i + + )
drw_cur_free ( drw , cursor [ i ] ) ;
for ( i = 0 ; i < LENGTH ( colors ) ; i + + )
free ( scheme [ i ] ) ;
XDestroyWindow ( dpy , wmcheckwin ) ;
for ( i = 0 ; i < SchemeLast ; i + + ) {
drw_clr_free ( scheme [ i ] . border ) ;
drw_clr_free ( scheme [ i ] . bg ) ;
drw_clr_free ( scheme [ i ] . fg ) ;
}
drw_free ( drw ) ;
XSync ( dpy , False ) ;
XSetInputFocus ( dpy , PointerRoot , RevertToPointerRoot , CurrentTime ) ;
@ -510,6 +508,19 @@ cleanupmon(Monitor *mon)
free ( mon ) ;
}
void
clearurgent ( Client * c )
{
XWMHints * wmh ;
c - > isurgent = 0 ;
if ( ! ( wmh = XGetWMHints ( dpy , c - > win ) ) )
return ;
wmh - > flags & = ~ XUrgencyHint ;
XSetWMHints ( dpy , c - > win , wmh ) ;
XFree ( wmh ) ;
}
void
clientmessage ( XEvent * e )
{
@ -519,13 +530,15 @@ clientmessage(XEvent *e)
if ( ! c )
return ;
if ( cme - > message_type = = netatom [ NetWMState ] ) {
if ( cme - > data . l [ 1 ] = = netatom [ NetWMFullscreen ]
| | cme - > data . l [ 2 ] = = netatom [ NetWMFullscreen ] )
if ( cme - > data . l [ 1 ] = = netatom [ NetWMFullscreen ] | | cme - > data . l [ 2 ] = = netatom [ NetWMFullscreen ] )
setfullscreen ( c , ( cme - > data . l [ 0 ] = = 1 /* _NET_WM_STATE_ADD */
| | ( cme - > data . l [ 0 ] = = 2 /* _NET_WM_STATE_TOGGLE */ & & ! c - > isfullscreen ) ) ) ;
} else if ( cme - > message_type = = netatom [ NetActiveWindow ] ) {
if ( c ! = selmon - > sel & & ! c - > isurgent )
seturgent ( c , 1 ) ;
if ( ! ISVISIBLE ( c ) ) {
c - > mon - > seltags ^ = 1 ;
c - > mon - > tagset [ c - > mon - > seltags ] = c - > tags ;
}
pop ( c ) ;
}
}
@ -552,7 +565,6 @@ void
configurenotify ( XEvent * e )
{
Monitor * m ;
Client * c ;
XConfigureEvent * ev = & e - > xconfigure ;
int dirty ;
@ -564,12 +576,8 @@ configurenotify(XEvent *e)
if ( updategeom ( ) | | dirty ) {
drw_resize ( drw , sw , bh ) ;
updatebars ( ) ;
for ( m = mons ; m ; m = m - > next ) {
for ( c = m - > clients ; c ; c = c - > next )
if ( c - > isfullscreen )
resizeclient ( c , m - > mx , m - > my , m - > mw , m - > mh ) ;
for ( m = mons ; m ; m = m - > next )
XMoveResizeWindow ( dpy , m - > barwin , m - > wx , m - > by , m - > ww , bh ) ;
}
focus ( NULL ) ;
arrange ( NULL ) ;
}
@ -696,18 +704,11 @@ dirtomon(int dir)
void
drawbar ( Monitor * m )
{
int x , w , tw = 0 ;
int boxs = drw - > fonts - > h / 9 ;
int boxw = drw - > fonts - > h / 6 + 2 ;
int x , xx , w , dx ;
unsigned int i , occ = 0 , urg = 0 ;
Client * c ;
/* draw status first so it can be overdrawn by tags later */
if ( m = = selmon ) { /* status is only drawn on selected monitor */
drw_setscheme ( drw , scheme [ SchemeNorm ] ) ;
tw = TEXTW ( stext ) - lrpad + 2 ; /* 2px right padding */
drw_text ( drw , m - > ww - tw , 0 , tw , bh , 0 , stext , 0 ) ;
}
dx = ( drw - > fonts [ 0 ] - > ascent + drw - > fonts [ 0 ] - > descent + 2 ) / 4 ;
for ( c = m - > clients ; c ; c = c - > next ) {
occ | = c - > tags ;
@ -717,27 +718,36 @@ drawbar(Monitor *m)
x = 0 ;
for ( i = 0 ; i < LENGTH ( tags ) ; i + + ) {
w = TEXTW ( tags [ i ] ) ;
drw_setscheme ( drw , scheme [ m - > tagset [ m - > seltags ] & 1 < < i ? SchemeSel : SchemeNorm ] ) ;
drw_text ( drw , x , 0 , w , bh , lrpad / 2 , tags [ i ] , urg & 1 < < i ) ;
if ( occ & 1 < < i )
drw_rect ( drw , x + boxs , boxs , boxw , boxw ,
m = = selmon & & selmon - > sel & & selmon - > sel - > tags & 1 < < i ,
urg & 1 < < i ) ;
drw_setscheme ( drw , m - > tagset [ m - > seltags ] & 1 < < i ? & scheme [ SchemeSel ] : & scheme [ SchemeNorm ] ) ;
drw_text ( drw , x , 0 , w , bh , tags [ i ] , urg & 1 < < i ) ;
drw_rect ( drw , x + 1 , 1 , dx , dx , m = = selmon & & selmon - > sel & & selmon - > sel - > tags & 1 < < i ,
occ & 1 < < i , urg & 1 < < i ) ;
x + = w ;
}
w = blw = TEXTW ( m - > ltsymbol ) ;
drw_setscheme ( drw , scheme [ SchemeNorm ] ) ;
x = drw_text ( drw , x , 0 , w , bh , lrpad / 2 , m - > ltsymbol , 0 ) ;
if ( ( w = m - > ww - tw - x ) > bh ) {
drw_setscheme ( drw , & scheme [ SchemeNorm ] ) ;
drw_text ( drw , x , 0 , w , bh , m - > ltsymbol , 0 ) ;
x + = w ;
xx = x ;
if ( m = = selmon ) { /* status is only drawn on selected monitor */
w = TEXTW ( stext ) ;
x = m - > ww - w ;
if ( x < xx ) {
x = xx ;
w = m - > ww - xx ;
}
drw_text ( drw , x , 0 , w , bh , stext , 0 ) ;
} else
x = m - > ww ;
if ( ( w = x - xx ) > bh ) {
x = xx ;
if ( m - > sel ) {
drw_setscheme ( drw , scheme [ m = = selmon ? SchemeSel : SchemeNorm ] ) ;
drw_text ( drw , x , 0 , w , bh , lrpad / 2 , m - > sel - > name , 0 ) ;
if ( m - > sel - > isfloating )
drw_rect ( drw , x + boxs , boxs , boxw , boxw , m - > sel - > isfixed , 0 ) ;
drw_setscheme ( drw , m = = selmon ? & scheme [ SchemeSel ] : & scheme [ SchemeNorm ] ) ;
drw_text ( drw , x , 0 , w , bh , m - > sel - > name , 0 ) ;
drw_rect ( drw , x + 1 , 1 , dx , dx , m - > sel - > isfixed , m - > sel - > isfloating , 0 ) ;
} else {
drw_setscheme ( drw , scheme [ SchemeNorm ] ) ;
drw_rect ( drw , x , 0 , w , bh , 1 , 1 ) ;
drw_setscheme ( drw , & scheme [ SchemeNorm ] ) ;
drw_rect ( drw , x , 0 , w , bh , 1 , 0, 1) ;
}
}
drw_map ( drw , m - > barwin , 0 , 0 , m - > ww , bh ) ;
@ -786,17 +796,18 @@ focus(Client *c)
{
if ( ! c | | ! ISVISIBLE ( c ) )
for ( c = selmon - > stack ; c & & ! ISVISIBLE ( c ) ; c = c - > snext ) ;
/* was if (selmon->sel) */
if ( selmon - > sel & & selmon - > sel ! = c )
unfocus ( selmon - > sel , 0 ) ;
if ( c ) {
if ( c - > mon ! = selmon )
selmon = c - > mon ;
if ( c - > isurgent )
seturgent( c , 0 ) ;
clearurgent( c ) ;
detachstack ( c ) ;
attachstack ( c ) ;
grabbuttons ( c , 1 ) ;
XSetWindowBorder ( dpy , c - > win , scheme [ SchemeSel ] [ColBorder ] . pixel ) ;
XSetWindowBorder ( dpy , c - > win , scheme [ SchemeSel ] .border - > pix ) ;
setfocus ( c ) ;
} else {
XSetInputFocus ( dpy , root , RevertToPointerRoot , CurrentTime ) ;
@ -806,7 +817,7 @@ focus(Client *c)
drawbars ( ) ;
}
/* there are some broken focus acquiring clients needing extra handling */
/* there are some broken focus acquiring clients */
void
focusin ( XEvent * e )
{
@ -825,7 +836,8 @@ focusmon(const Arg *arg)
return ;
if ( ( m = dirtomon ( arg - > i ) ) = = selmon )
return ;
unfocus ( selmon - > sel , 0 ) ;
unfocus ( selmon - > sel , 0 ) ; /* s/1/0/ fixes input focus issues
in gedit and anjuta */
selmon = m ;
focus ( NULL ) ;
}
@ -835,7 +847,7 @@ focusstack(const Arg *arg)
{
Client * c = NULL , * i ;
if ( ! selmon - > sel | | ( selmon - > sel - > isfullscreen & & lockfullscreen ) )
if ( ! selmon - > sel )
return ;
if ( arg - > i > 0 ) {
for ( c = selmon - > sel - > next ; c & & ! ISVISIBLE ( c ) ; c = c - > next ) ;
@ -910,7 +922,8 @@ gettextprop(Window w, Atom atom, char *text, unsigned int size)
if ( ! text | | size = = 0 )
return 0 ;
text [ 0 ] = ' \0 ' ;
if ( ! XGetTextProperty ( dpy , w , & name , atom ) | | ! name . nitems )
XGetTextProperty ( dpy , w , & name , atom ) ;
if ( ! name . nitems )
return 0 ;
if ( name . encoding = = XA_STRING )
strncpy ( text , ( char * ) name . value , size - 1 ) ;
@ -933,9 +946,7 @@ grabbuttons(Client *c, int focused)
unsigned int i , j ;
unsigned int modifiers [ ] = { 0 , LockMask , numlockmask , numlockmask | LockMask } ;
XUngrabButton ( dpy , AnyButton , AnyModifier , c - > win ) ;
if ( ! focused )
XGrabButton ( dpy , AnyButton , AnyModifier , c - > win , False ,
BUTTONMASK , GrabModeSync , GrabModeSync , None , None ) ;
if ( focused ) {
for ( i = 0 ; i < LENGTH ( buttons ) ; i + + )
if ( buttons [ i ] . click = = ClkClientWin )
for ( j = 0 ; j < LENGTH ( modifiers ) ; j + + )
@ -943,6 +954,9 @@ grabbuttons(Client *c, int focused)
buttons [ i ] . mask | modifiers [ j ] ,
c - > win , False , BUTTONMASK ,
GrabModeAsync , GrabModeSync , None , None ) ;
} else
XGrabButton ( dpy , AnyButton , AnyModifier , c - > win , False ,
BUTTONMASK , GrabModeAsync , GrabModeSync , None , None ) ;
}
}
@ -1024,13 +1038,6 @@ manage(Window w, XWindowAttributes *wa)
c = ecalloc ( 1 , sizeof ( Client ) ) ;
c - > win = 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 ;
@ -1039,6 +1046,12 @@ manage(Window w, XWindowAttributes *wa)
c - > mon = selmon ;
applyrules ( c ) ;
}
/* 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 ( c - > x + WIDTH ( c ) > c - > mon - > mx + c - > mon - > mw )
c - > x = c - > mon - > mx + c - > mon - > mw - WIDTH ( c ) ;
@ -1052,7 +1065,7 @@ manage(Window w, XWindowAttributes *wa)
wc . border_width = c - > bw ;
XConfigureWindow ( dpy , w , CWBorderWidth , & wc ) ;
XSetWindowBorder ( dpy , w , scheme [ SchemeNorm ] [ColBorder ] . pixel ) ;
XSetWindowBorder ( dpy , w , scheme [ SchemeNorm ] .border - > pix ) ;
configure ( c ) ; /* propagates border_width, if size doesn't change */
updatewindowtype ( c ) ;
updatesizehints ( c ) ;
@ -1169,6 +1182,8 @@ movemouse(const Arg *arg)
nx = ocx + ( ev . xmotion . x - x ) ;
ny = ocy + ( ev . xmotion . y - y ) ;
if ( nx > = selmon - > wx & & nx < = selmon - > wx + selmon - > ww
& & ny > = selmon - > wy & & ny < = selmon - > wy + selmon - > wh ) {
if ( abs ( selmon - > wx - nx ) < snap )
nx = selmon - > wx ;
else if ( abs ( ( selmon - > wx + selmon - > ww ) - ( nx + WIDTH ( c ) ) ) < snap )
@ -1180,6 +1195,7 @@ movemouse(const Arg *arg)
if ( ! c - > isfloating & & selmon - > lt [ selmon - > sellt ] - > arrange
& & ( abs ( nx - c - > x ) > snap | | abs ( ny - c - > y ) > snap ) )
togglefloating ( NULL ) ;
}
if ( ! selmon - > lt [ selmon - > sellt ] - > arrange | | c - > isfloating )
resize ( c , nx , ny , c - > w , c - > h , 1 ) ;
break ;
@ -1512,7 +1528,7 @@ setlayout(const Arg *arg)
drawbar ( selmon ) ;
}
/* arg > 1.0 will set mfact absolut e ly */
/* arg > 1.0 will set mfact absolut ly */
void
setmfact ( const Arg * arg )
{
@ -1521,7 +1537,7 @@ setmfact(const Arg *arg)
if ( ! arg | | ! selmon - > lt [ selmon - > sellt ] - > arrange )
return ;
f = arg - > f < 1.0 ? arg - > f + selmon - > mfact : arg - > f - 1.0 ;
if ( f < 0. 05 | | f > 0.9 5 )
if ( f < 0. 1 | | f > 0.9 )
return ;
selmon - > mfact = f ;
arrange ( selmon ) ;
@ -1530,9 +1546,7 @@ setmfact(const Arg *arg)
void
setup ( void )
{
int i ;
XSetWindowAttributes wa ;
Atom utf8string ;
/* clean up any zombies immediately */
sigchld ( 0 ) ;
@ -1543,13 +1557,12 @@ setup(void)
sh = DisplayHeight ( dpy , screen ) ;
root = RootWindow ( dpy , screen ) ;
drw = drw_create ( dpy , screen , root , sw , sh ) ;
if ( ! drw_ fontset_create ( drw , fonts , LENGTH ( fonts ) ) )
die ( " no fonts could be loaded. " ) ;
lrpad = drw - > fonts - > h ;
bh = drw - > fonts - > h + 2 ;
drw_ load_ fonts( drw , fonts , LENGTH ( fonts ) ) ;
if ( ! drw - > fontcount )
die ( " no fonts could be loaded. \n " ) ;
bh = drw - > fonts [ 0 ] - > h + 2 ;
updategeom ( ) ;
/* init atoms */
utf8string = XInternAtom ( dpy , " UTF8_STRING " , False ) ;
wmatom [ WMProtocols ] = XInternAtom ( dpy , " WM_PROTOCOLS " , False ) ;
wmatom [ WMDelete ] = XInternAtom ( dpy , " WM_DELETE_WINDOW " , False ) ;
wmatom [ WMState ] = XInternAtom ( dpy , " WM_STATE " , False ) ;
@ -1558,7 +1571,6 @@ setup(void)
netatom [ NetSupported ] = XInternAtom ( dpy , " _NET_SUPPORTED " , False ) ;
netatom [ NetWMName ] = XInternAtom ( dpy , " _NET_WM_NAME " , False ) ;
netatom [ NetWMState ] = XInternAtom ( dpy , " _NET_WM_STATE " , False ) ;
netatom [ NetWMCheck ] = XInternAtom ( dpy , " _NET_SUPPORTING_WM_CHECK " , False ) ;
netatom [ NetWMFullscreen ] = XInternAtom ( dpy , " _NET_WM_STATE_FULLSCREEN " , False ) ;
netatom [ NetWMWindowType ] = XInternAtom ( dpy , " _NET_WM_WINDOW_TYPE " , False ) ;
netatom [ NetWMWindowTypeDialog ] = XInternAtom ( dpy , " _NET_WM_WINDOW_TYPE_DIALOG " , False ) ;
@ -1568,49 +1580,29 @@ setup(void)
cursor [ CurResize ] = drw_cur_create ( drw , XC_sizing ) ;
cursor [ CurMove ] = drw_cur_create ( drw , XC_fleur ) ;
/* init appearance */
scheme = ecalloc ( LENGTH ( colors ) , sizeof ( Clr * ) ) ;
for ( i = 0 ; i < LENGTH ( colors ) ; i + + )
scheme [ i ] = drw_scm_create ( drw , colors [ i ] , 3 ) ;
scheme [ SchemeNorm ] . border = drw_clr_create ( drw , normbordercolor ) ;
scheme [ SchemeNorm ] . bg = drw_clr_create ( drw , normbgcolor ) ;
scheme [ SchemeNorm ] . fg = drw_clr_create ( drw , normfgcolor ) ;
scheme [ SchemeSel ] . border = drw_clr_create ( drw , selbordercolor ) ;
scheme [ SchemeSel ] . bg = drw_clr_create ( drw , selbgcolor ) ;
scheme [ SchemeSel ] . fg = drw_clr_create ( drw , selfgcolor ) ;
/* init bars */
updatebars ( ) ;
updatestatus ( ) ;
/* supporting window for NetWMCheck */
wmcheckwin = XCreateSimpleWindow ( dpy , root , 0 , 0 , 1 , 1 , 0 , 0 , 0 ) ;
XChangeProperty ( dpy , wmcheckwin , netatom [ NetWMCheck ] , XA_WINDOW , 32 ,
PropModeReplace , ( unsigned char * ) & wmcheckwin , 1 ) ;
XChangeProperty ( dpy , wmcheckwin , netatom [ NetWMName ] , utf8string , 8 ,
PropModeReplace , ( unsigned char * ) " dwm " , 3 ) ;
XChangeProperty ( dpy , root , netatom [ NetWMCheck ] , XA_WINDOW , 32 ,
PropModeReplace , ( unsigned char * ) & wmcheckwin , 1 ) ;
/* EWMH support per view */
XChangeProperty ( dpy , root , netatom [ NetSupported ] , XA_ATOM , 32 ,
PropModeReplace , ( unsigned char * ) netatom , NetLast ) ;
XDeleteProperty ( dpy , root , netatom [ NetClientList ] ) ;
/* select events */
/* select for events */
wa . cursor = cursor [ CurNormal ] - > cursor ;
wa . event_mask = SubstructureRedirectMask | SubstructureNotifyMask
| ButtonPressMask | PointerMotionMask | EnterWindowMask
| LeaveWindowMask | StructureNotifyMask | PropertyChangeMask ;
wa . event_mask = SubstructureRedirectMask | SubstructureNotifyMask | ButtonPressMask | PointerMotionMask
| EnterWindowMask | LeaveWindowMask | StructureNotifyMask | PropertyChangeMask ;
XChangeWindowAttributes ( dpy , root , CWEventMask | CWCursor , & wa ) ;
XSelectInput ( dpy , root , wa . event_mask ) ;
grabkeys ( ) ;
focus ( NULL ) ;
}
void
seturgent ( Client * c , int urg )
{
XWMHints * wmh ;
c - > isurgent = urg ;
if ( ! ( wmh = XGetWMHints ( dpy , c - > win ) ) )
return ;
wmh - > flags = urg ? ( wmh - > flags | XUrgencyHint ) : ( wmh - > flags & ~ XUrgencyHint ) ;
XSetWMHints ( dpy , c - > win , wmh ) ;
XFree ( wmh ) ;
}
void
showhide ( Client * c )
{
@ -1689,12 +1681,10 @@ tile(Monitor *m)
if ( i < m - > nmaster ) {
h = ( m - > wh - my ) / ( MIN ( n , m - > nmaster ) - i ) ;
resize ( c , m - > wx , m - > wy + my , mw - ( 2 * c - > bw ) , h - ( 2 * c - > bw ) , 0 ) ;
if ( my + HEIGHT ( c ) < m - > wh )
my + = HEIGHT ( c ) ;
} else {
h = ( m - > wh - ty ) / ( n - i ) ;
resize ( c , m - > wx + mw , m - > wy + ty , m - > ww - mw - ( 2 * c - > bw ) , h - ( 2 * c - > bw ) , 0 ) ;
if ( ty + HEIGHT ( c ) < m - > wh )
ty + = HEIGHT ( c ) ;
}
}
@ -1755,7 +1745,7 @@ unfocus(Client *c, int setfocus)
if ( ! c )
return ;
grabbuttons ( c , 0 ) ;
XSetWindowBorder ( dpy , c - > win , scheme [ SchemeNorm ] [ColBorder ] . pixel ) ;
XSetWindowBorder ( dpy , c - > win , scheme [ SchemeNorm ] .border - > pix ) ;
if ( setfocus ) {
XSetInputFocus ( dpy , root , RevertToPointerRoot , CurrentTime ) ;
XDeleteProperty ( dpy , root , netatom [ NetActiveWindow ] ) ;
@ -1768,11 +1758,12 @@ unmanage(Client *c, int destroyed)
Monitor * m = c - > mon ;
XWindowChanges wc ;
/* The server grab construct avoids race conditions. */
detach ( c ) ;
detachstack ( c ) ;
if ( ! destroyed ) {
wc . border_width = c - > oldbw ;
XGrabServer ( dpy ) ; /* avoid race conditions */
XGrabServer ( dpy ) ;
XSetErrorHandler ( xerrordummy ) ;
XConfigureWindow ( dpy , c - > win , CWBorderWidth , & wc ) ; /* restore border */
XUngrabButton ( dpy , AnyButton , AnyModifier , c - > win ) ;
@ -1810,7 +1801,6 @@ updatebars(void)
. background_pixmap = ParentRelative ,
. event_mask = ButtonPressMask | ExposureMask
} ;
XClassHint ch = { " dwm " , " dwm " } ;
for ( m = mons ; m ; m = m - > next ) {
if ( m - > barwin )
continue ;
@ -1819,7 +1809,6 @@ updatebars(void)
CWOverrideRedirect | CWBackPixmap | CWEventMask , & wa ) ;
XDefineCursor ( dpy , m - > barwin , cursor [ CurNormal ] - > cursor ) ;
XMapRaised ( dpy , m - > barwin ) ;
XSetClassHint ( dpy , m - > barwin , & ch ) ;
}
}
@ -1871,8 +1860,8 @@ updategeom(void)
memcpy ( & unique [ j + + ] , & info [ i ] , sizeof ( XineramaScreenInfo ) ) ;
XFree ( info ) ;
nn = j ;
if ( n < = nn ) { /* new monitors available */
for ( i = 0 ; i < ( nn - n ) ; i + + ) {
if ( n < = nn ) {
for ( i = 0 ; i < ( nn - n ) ; i + + ) { /* new monitors available */
for ( m = mons ; m & & m - > next ; m = m - > next ) ;
if ( m )
m - > next = createmon ( ) ;
@ -1881,8 +1870,8 @@ updategeom(void)
}
for ( i = 0 , m = mons ; i < nn & & m ; m = m - > next , i + + )
if ( i > = n
| | unique [ i ] . x_org ! = m - > mx | | unique [ i ] . y_org ! = m - > my
| | unique [ i ] . width ! = m - > mw | | unique [ i ] . height ! = m - > mh )
| | ( unique [ i ] . x_org ! = m - > mx | | unique [ i ] . y_org ! = m - > my
| | unique [ i ] . width ! = m - > mw | | unique [ i ] . height ! = m - > mh ) )
{
dirty = 1 ;
m - > num = i ;
@ -1892,11 +1881,13 @@ updategeom(void)
m - > mh = m - > wh = unique [ i ] . height ;
updatebarpos ( m ) ;
}
} else { /* less monitors available nn < n */
} else {
/* less monitors available nn < n */
for ( i = nn ; i < n ; i + + ) {
for ( m = mons ; m & & m - > next ; m = m - > next ) ;
while ( ( c = m - > clients ) ) {
while ( m - > clients ) {
dirty = 1 ;
c = m - > clients ;
m - > clients = c - > next ;
detachstack ( c ) ;
c - > mon = mons ;
@ -1911,7 +1902,8 @@ updategeom(void)
free ( unique ) ;
} else
# endif /* XINERAMA */
{ /* default monitor setup */
/* default monitor setup */
{
if ( ! mons )
mons = createmon ( ) ;
if ( mons - > mw ! = sw | | mons - > mh ! = sh ) {
@ -1984,15 +1976,8 @@ updatesizehints(Client *c)
c - > maxa = ( float ) size . max_aspect . x / size . max_aspect . y ;
} else
c - > maxa = c - > mina = 0.0 ;
c - > isfixed = ( c - > maxw & & c - > maxh & & c - > maxw = = c - > minw & & c - > maxh = = c - > minh ) ;
}
void
updatestatus ( void )
{
if ( ! gettextprop ( root , XA_WM_NAME , stext , sizeof ( stext ) ) )
strcpy ( stext , " dwm- " VERSION ) ;
drawbar ( selmon ) ;
c - > isfixed = ( c - > maxw & & c - > minw & & c - > maxh & & c - > minh
& & c - > maxw = = c - > minw & & c - > maxh = = c - > minh ) ;
}
void
@ -2004,6 +1989,14 @@ updatetitle(Client *c)
strcpy ( c - > name , broken ) ;
}
void
updatestatus ( void )
{
if ( ! gettextprop ( root , XA_WM_NAME , stext , sizeof ( stext ) ) )
strcpy ( stext , " dwm- " VERSION ) ;
drawbar ( selmon ) ;
}
void
updatewindowtype ( Client * c )
{
@ -2109,7 +2102,7 @@ xerrordummy(Display *dpy, XErrorEvent *ee)
int
xerrorstart ( Display * dpy , XErrorEvent * ee )
{
die ( " dwm: another window manager is already running " ) ;
die ( " dwm: another window manager is already running \n " ) ;
return - 1 ;
}
@ -2131,19 +2124,15 @@ int
main ( int argc , char * argv [ ] )
{
if ( argc = = 2 & & ! strcmp ( " -v " , argv [ 1 ] ) )
die ( " dwm- " VERSION ) ;
die ( " dwm- " VERSION " \n " ) ;
else if ( argc ! = 1 )
die ( " usage: dwm [-v] " ) ;
die ( " usage: dwm [-v] \n " ) ;
if ( ! setlocale ( LC_CTYPE , " " ) | | ! XSupportsLocale ( ) )
fputs ( " warning: no locale support \n " , stderr ) ;
if ( ! ( dpy = XOpenDisplay ( NULL ) ) )
die ( " dwm: cannot open display " ) ;
die ( " dwm: cannot open display \n " ) ;
checkotherwm ( ) ;
setup ( ) ;
# ifdef __OpenBSD__
if ( pledge ( " stdio rpath proc exec " , NULL ) = = - 1 )
die ( " pledge " ) ;
# endif /* __OpenBSD__ */
scan ( ) ;
run ( ) ;
cleanup ( ) ;