@ -3,7 +3,7 @@
* dynamic window manager is designed like any other X client as well . It is
* dynamic window manager is designed like any other X client as well . It is
* driven through handling X events . In contrast to other X clients , a window
* driven through handling X events . In contrast to other X clients , a window
* manager selects for SubstructureRedirectMask on the root window , to receive
* manager selects for SubstructureRedirectMask on the root window , to receive
* events about window ( dis - ) appearance . Only one X connection at a time is
* events about window ( dis - ) appearance . Only one X connection at a time is
* allowed to select for this event mask .
* allowed to select for this event mask .
*
*
* The event handlers of dwm are organized in an array which is accessed
* The event handlers of dwm are organized in an array which is accessed
@ -11,7 +11,7 @@
* in O ( 1 ) time .
* in O ( 1 ) time .
*
*
* Each child of the root window is called a client , except windows which have
* Each child of the root window is called a client , except windows which have
* set the override_redirect flag . Clients are organized in a linked client
* set the override_redirect flag . Clients are organized in a linked client
* list on each monitor , the focus history is remembered through a stack list
* list on each monitor , the focus history is remembered through a stack list
* on each monitor . Each client contains a bit array to indicate the tags of a
* on each monitor . Each client contains a bit array to indicate the tags of a
* client .
* client .
@ -517,7 +517,8 @@ clientmessage(XEvent *e)
if ( ! c )
if ( ! c )
return ;
return ;
if ( cme - > message_type = = netatom [ NetWMState ] ) {
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 */
setfullscreen ( c , ( cme - > data . l [ 0 ] = = 1 /* _NET_WM_STATE_ADD */
| | ( cme - > data . l [ 0 ] = = 2 /* _NET_WM_STATE_TOGGLE */ & & ! c - > isfullscreen ) ) ) ;
| | ( cme - > data . l [ 0 ] = = 2 /* _NET_WM_STATE_TOGGLE */ & & ! c - > isfullscreen ) ) ) ;
} else if ( cme - > message_type = = netatom [ NetActiveWindow ] ) {
} else if ( cme - > message_type = = netatom [ NetActiveWindow ] ) {
@ -783,7 +784,6 @@ focus(Client *c)
{
{
if ( ! c | | ! ISVISIBLE ( c ) )
if ( ! c | | ! ISVISIBLE ( c ) )
for ( c = selmon - > stack ; c & & ! ISVISIBLE ( c ) ; c = c - > snext ) ;
for ( c = selmon - > stack ; c & & ! ISVISIBLE ( c ) ; c = c - > snext ) ;
/* was if (selmon->sel) */
if ( selmon - > sel & & selmon - > sel ! = c )
if ( selmon - > sel & & selmon - > sel ! = c )
unfocus ( selmon - > sel , 0 ) ;
unfocus ( selmon - > sel , 0 ) ;
if ( c ) {
if ( c ) {
@ -804,7 +804,7 @@ focus(Client *c)
drawbars ( ) ;
drawbars ( ) ;
}
}
/* there are some broken focus acquiring clients */
/* there are some broken focus acquiring clients needing extra handling */
void
void
focusin ( XEvent * e )
focusin ( XEvent * e )
{
{
@ -823,8 +823,7 @@ focusmon(const Arg *arg)
return ;
return ;
if ( ( m = dirtomon ( arg - > i ) ) = = selmon )
if ( ( m = dirtomon ( arg - > i ) ) = = selmon )
return ;
return ;
unfocus ( selmon - > sel , 0 ) ; /* s/1/0/ fixes input focus issues
unfocus ( selmon - > sel , 0 ) ;
in gedit and anjuta */
selmon = m ;
selmon = m ;
focus ( NULL ) ;
focus ( NULL ) ;
}
}
@ -961,7 +960,7 @@ grabkeys(void)
if ( ( code = XKeysymToKeycode ( dpy , keys [ i ] . keysym ) ) )
if ( ( code = XKeysymToKeycode ( dpy , keys [ i ] . keysym ) ) )
for ( j = 0 ; j < LENGTH ( modifiers ) ; j + + )
for ( j = 0 ; j < LENGTH ( modifiers ) ; j + + )
XGrabKey ( dpy , code , keys [ i ] . mod | modifiers [ j ] , root ,
XGrabKey ( dpy , code , keys [ i ] . mod | modifiers [ j ] , root ,
True , GrabModeAsync , GrabModeAsync ) ;
True , GrabModeAsync , GrabModeAsync ) ;
}
}
}
}
@ -1151,7 +1150,7 @@ movemouse(const Arg *arg)
ocx = c - > x ;
ocx = c - > x ;
ocy = c - > y ;
ocy = c - > y ;
if ( XGrabPointer ( dpy , root , False , MOUSEMASK , GrabModeAsync , GrabModeAsync ,
if ( XGrabPointer ( dpy , root , False , MOUSEMASK , GrabModeAsync , GrabModeAsync ,
None , cursor [ CurMove ] - > cursor , CurrentTime ) ! = GrabSuccess )
None , cursor [ CurMove ] - > cursor , CurrentTime ) ! = GrabSuccess )
return ;
return ;
if ( ! getrootptr ( & x , & y ) )
if ( ! getrootptr ( & x , & y ) )
return ;
return ;
@ -1434,7 +1433,7 @@ setclientstate(Client *c, long state)
long data [ ] = { state , None } ;
long data [ ] = { state , None } ;
XChangeProperty ( dpy , c - > win , wmatom [ WMState ] , wmatom [ WMState ] , 32 ,
XChangeProperty ( dpy , c - > win , wmatom [ WMState ] , wmatom [ WMState ] , 32 ,
PropModeReplace , ( unsigned char * ) data , 2 ) ;
PropModeReplace , ( unsigned char * ) data , 2 ) ;
}
}
int
int
@ -1516,7 +1515,7 @@ setlayout(const Arg *arg)
drawbar ( selmon ) ;
drawbar ( selmon ) ;
}
}
/* arg > 1.0 will set mfact absolutly */
/* arg > 1.0 will set mfact absolute ly */
void
void
setmfact ( const Arg * arg )
setmfact ( const Arg * arg )
{
{
@ -1581,19 +1580,20 @@ setup(void)
/* supporting window for NetWMCheck */
/* supporting window for NetWMCheck */
wmcheckwin = XCreateSimpleWindow ( dpy , root , 0 , 0 , 1 , 1 , 0 , 0 , 0 ) ;
wmcheckwin = XCreateSimpleWindow ( dpy , root , 0 , 0 , 1 , 1 , 0 , 0 , 0 ) ;
XChangeProperty ( dpy , wmcheckwin , netatom [ NetWMCheck ] , XA_WINDOW , 32 ,
XChangeProperty ( dpy , wmcheckwin , netatom [ NetWMCheck ] , XA_WINDOW , 32 ,
PropModeReplace , ( unsigned char * ) & wmcheckwin , 1 ) ;
PropModeReplace , ( unsigned char * ) & wmcheckwin , 1 ) ;
XChangeProperty ( dpy , wmcheckwin , netatom [ NetWMName ] , utf8string , 8 ,
XChangeProperty ( dpy , wmcheckwin , netatom [ NetWMName ] , utf8string , 8 ,
PropModeReplace , ( unsigned char * ) " dwm " , 4 ) ;
PropModeReplace , ( unsigned char * ) " dwm " , 4 ) ;
XChangeProperty ( dpy , root , netatom [ NetWMCheck ] , XA_WINDOW , 32 ,
XChangeProperty ( dpy , root , netatom [ NetWMCheck ] , XA_WINDOW , 32 ,
PropModeReplace , ( unsigned char * ) & wmcheckwin , 1 ) ;
PropModeReplace , ( unsigned char * ) & wmcheckwin , 1 ) ;
/* EWMH support per view */
/* EWMH support per view */
XChangeProperty ( dpy , root , netatom [ NetSupported ] , XA_ATOM , 32 ,
XChangeProperty ( dpy , root , netatom [ NetSupported ] , XA_ATOM , 32 ,
PropModeReplace , ( unsigned char * ) netatom , NetLast ) ;
PropModeReplace , ( unsigned char * ) netatom , NetLast ) ;
XDeleteProperty ( dpy , root , netatom [ NetClientList ] ) ;
XDeleteProperty ( dpy , root , netatom [ NetClientList ] ) ;
/* select for events */
/* select events */
wa . cursor = cursor [ CurNormal ] - > cursor ;
wa . cursor = cursor [ CurNormal ] - > cursor ;
wa . event_mask = SubstructureRedirectMask | SubstructureNotifyMask | ButtonPressMask | PointerMotionMask
wa . event_mask = SubstructureRedirectMask | SubstructureNotifyMask
| EnterWindowMask | LeaveWindowMask | StructureNotifyMask | PropertyChangeMask ;
| ButtonPressMask | PointerMotionMask | EnterWindowMask
| LeaveWindowMask | StructureNotifyMask | PropertyChangeMask ;
XChangeWindowAttributes ( dpy , root , CWEventMask | CWCursor , & wa ) ;
XChangeWindowAttributes ( dpy , root , CWEventMask | CWCursor , & wa ) ;
XSelectInput ( dpy , root , wa . event_mask ) ;
XSelectInput ( dpy , root , wa . event_mask ) ;
grabkeys ( ) ;
grabkeys ( ) ;
@ -1769,12 +1769,11 @@ unmanage(Client *c, int destroyed)
Monitor * m = c - > mon ;
Monitor * m = c - > mon ;
XWindowChanges wc ;
XWindowChanges wc ;
/* The server grab construct avoids race conditions. */
detach ( c ) ;
detach ( c ) ;
detachstack ( c ) ;
detachstack ( c ) ;
if ( ! destroyed ) {
if ( ! destroyed ) {
wc . border_width = c - > oldbw ;
wc . border_width = c - > oldbw ;
XGrabServer ( dpy ) ;
XGrabServer ( dpy ) ; /* avoid race conditions */
XSetErrorHandler ( xerrordummy ) ;
XSetErrorHandler ( xerrordummy ) ;
XConfigureWindow ( dpy , c - > win , CWBorderWidth , & wc ) ; /* restore border */
XConfigureWindow ( dpy , c - > win , CWBorderWidth , & wc ) ; /* restore border */
XUngrabButton ( dpy , AnyButton , AnyModifier , c - > win ) ;
XUngrabButton ( dpy , AnyButton , AnyModifier , c - > win ) ;
@ -1871,8 +1870,8 @@ updategeom(void)
memcpy ( & unique [ j + + ] , & info [ i ] , sizeof ( XineramaScreenInfo ) ) ;
memcpy ( & unique [ j + + ] , & info [ i ] , sizeof ( XineramaScreenInfo ) ) ;
XFree ( info ) ;
XFree ( info ) ;
nn = j ;
nn = j ;
if ( n < = nn ) {
if ( n < = nn ) { /* new monitors available */
for ( i = 0 ; i < ( nn - n ) ; i + + ) { /* new monitors available */
for ( i = 0 ; i < ( nn - n ) ; i + + ) {
for ( m = mons ; m & & m - > next ; m = m - > next ) ;
for ( m = mons ; m & & m - > next ; m = m - > next ) ;
if ( m )
if ( m )
m - > next = createmon ( ) ;
m - > next = createmon ( ) ;
@ -1881,8 +1880,8 @@ updategeom(void)
}
}
for ( i = 0 , m = mons ; i < nn & & m ; m = m - > next , i + + )
for ( i = 0 , m = mons ; i < nn & & m ; m = m - > next , i + + )
if ( i > = n
if ( i > = n
| | ( unique [ i ] . x_org ! = m - > mx | | unique [ i ] . y_org ! = m - > my
| | unique [ i ] . x_org ! = m - > mx | | unique [ i ] . y_org ! = m - > my
| | unique [ i ] . width ! = m - > mw | | unique [ i ] . height ! = m - > mh ) )
| | unique [ i ] . width ! = m - > mw | | unique [ i ] . height ! = m - > mh )
{
{
dirty = 1 ;
dirty = 1 ;
m - > num = i ;
m - > num = i ;
@ -1892,13 +1891,11 @@ updategeom(void)
m - > mh = m - > wh = unique [ i ] . height ;
m - > mh = m - > wh = unique [ i ] . height ;
updatebarpos ( m ) ;
updatebarpos ( m ) ;
}
}
} else {
} else { /* less monitors available nn < n */
/* less monitors available nn < n */
for ( i = nn ; i < n ; i + + ) {
for ( i = nn ; i < n ; i + + ) {
for ( m = mons ; m & & m - > next ; m = m - > next ) ;
for ( m = mons ; m & & m - > next ; m = m - > next ) ;
while ( m - > clients ) {
while ( ( c = m - > clients ) ) {
dirty = 1 ;
dirty = 1 ;
c = m - > clients ;
m - > clients = c - > next ;
m - > clients = c - > next ;
detachstack ( c ) ;
detachstack ( c ) ;
c - > mon = mons ;
c - > mon = mons ;
@ -1913,8 +1910,7 @@ updategeom(void)
free ( unique ) ;
free ( unique ) ;
} else
} else
# endif /* XINERAMA */
# endif /* XINERAMA */
/* default monitor setup */
{ /* default monitor setup */
{
if ( ! mons )
if ( ! mons )
mons = createmon ( ) ;
mons = createmon ( ) ;
if ( mons - > mw ! = sw | | mons - > mh ! = sh ) {
if ( mons - > mw ! = sw | | mons - > mh ! = sh ) {
@ -1988,7 +1984,7 @@ updatesizehints(Client *c)
} else
} else
c - > maxa = c - > mina = 0.0 ;
c - > maxa = c - > mina = 0.0 ;
c - > isfixed = ( c - > maxw & & c - > minw & & c - > maxh & & c - > minh
c - > isfixed = ( c - > maxw & & c - > minw & & c - > maxh & & c - > minh
& & c - > maxw = = c - > minw & & c - > maxh = = c - > minh ) ;
& & c - > maxw = = c - > minw & & c - > maxh = = c - > minh ) ;
}
}
void
void
@ -2082,8 +2078,8 @@ wintomon(Window w)
}
}
/* There's no way to check accesses to destroyed windows, thus those cases are
/* There's no way to check accesses to destroyed windows, thus those cases are
* ignored ( especially on UnmapNotify ' s ) . Other types of errors call Xlibs
* ignored ( especially on UnmapNotify ' s ) . Other types of errors call Xlibs
* default error handler , which may call exit . */
* default error handler , which may call exit . */
int
int
xerror ( Display * dpy , XErrorEvent * ee )
xerror ( Display * dpy , XErrorEvent * ee )
{
{
@ -2098,7 +2094,7 @@ xerror(Display *dpy, XErrorEvent *ee)
| | ( ee - > request_code = = X_CopyArea & & ee - > error_code = = BadDrawable ) )
| | ( ee - > request_code = = X_CopyArea & & ee - > error_code = = BadDrawable ) )
return 0 ;
return 0 ;
fprintf ( stderr , " dwm: fatal error: request code=%d, error code=%d \n " ,
fprintf ( stderr , " dwm: fatal error: request code=%d, error code=%d \n " ,
ee - > request_code , ee - > error_code ) ;
ee - > request_code , ee - > error_code ) ;
return xerrorxlib ( dpy , ee ) ; /* may call exit */
return xerrorxlib ( dpy , ee ) ; /* may call exit */
}
}