Xinqi Bao's Git
   2  * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> 
   3  * See LICENSE file for license details. 
   8 #include <X11/keysym.h> 
  11 #define ButtonMask      (ButtonPressMask | ButtonReleaseMask) 
  12 #define MouseMask       (ButtonMask | PointerMotionMask) 
  15 const char *browse
[] = { "firefox", NULL 
}; 
  16 const char *gimp
[] = { "gimp", NULL 
}; 
  17 const char *term
[] = {  
  18         "urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-cr", "white", 
  19         "-fn", "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*", NULL
 
  21 const char *xlock
[] = { "xlock", NULL 
}; 
  24         /* modifier                             key                     function        arguments */ 
  25         { ControlMask
,                  XK_0
,           appendtag
,      { .i 
= Tscratch 
} },  
  26         { ControlMask
,                  XK_1
,           appendtag
,      { .i 
= Tdev 
} },  
  27         { ControlMask
,                  XK_2
,           appendtag
,      { .i 
= Twww 
} },  
  28         { ControlMask
,                  XK_3
,           appendtag
,      { .i 
= Twork 
} },  
  29         { Mod1Mask
,                             XK_0
,           view
,           { .i 
= Tscratch 
} },  
  30         { Mod1Mask
,                             XK_1
,           view
,           { .i 
= Tdev 
} },  
  31         { Mod1Mask
,                             XK_2
,           view
,           { .i 
= Twww 
} },  
  32         { Mod1Mask
,                             XK_3
,           view
,           { .i 
= Twork 
} },  
  33         { Mod1Mask
,                             XK_j
,           focusnext
,              { 0 } },  
  34         { Mod1Mask
,                             XK_k
,           focusprev
,              { 0 } }, 
  35         { Mod1Mask
,                             XK_m
,           maximize
,               { 0 } },  
  36         { Mod1Mask
,                             XK_space
,       dotile
,         { 0 } },  
  37         { Mod1Mask
,                             XK_Return
,      zoom
,           { 0 } }, 
  38         { ControlMask
|ShiftMask
,XK_0
,           heretag
,        { .i 
= Tscratch 
} },  
  39         { ControlMask
|ShiftMask
,XK_1
,           heretag
,        { .i 
= Tdev 
} },  
  40         { ControlMask
|ShiftMask
,XK_2
,           heretag
,        { .i 
= Twww 
} },  
  41         { ControlMask
|ShiftMask
,XK_3
,           heretag
,        { .i 
= Twork 
} },  
  42         { Mod1Mask
|ShiftMask
,   XK_0
,           replacetag
,             { .i 
= Tscratch 
} },  
  43         { Mod1Mask
|ShiftMask
,   XK_1
,           replacetag
,             { .i 
= Tdev 
} },  
  44         { Mod1Mask
|ShiftMask
,   XK_2
,           replacetag
,             { .i 
= Twww 
} },  
  45         { Mod1Mask
|ShiftMask
,   XK_3
,           replacetag
,             { .i 
= Twork 
} },  
  46         { Mod1Mask
|ShiftMask
,   XK_c
,           killclient
,             { 0 } },  
  47         { Mod1Mask
|ShiftMask
,   XK_g
,           spawn
,          { .argv 
= gimp 
} }, 
  48         { Mod1Mask
|ShiftMask
,   XK_l
,           spawn
,          { .argv 
= xlock 
} }, 
  49         { Mod1Mask
|ShiftMask
,   XK_q
,           quit
,           { 0 } }, 
  50         { Mod1Mask
|ShiftMask
,   XK_space
,       dofloat
,        { 0 } },  
  51         { Mod1Mask
|ShiftMask
,   XK_w
,           spawn
,          { .argv 
= browse 
} }, 
  52         { Mod1Mask
|ShiftMask
,   XK_Return
,      spawn
,          { .argv 
= term 
} }, 
  61         int x1
, y1
, ocx
, ocy
, di
; 
  67         if(XGrabPointer(dpy
, root
, False
, MouseMask
, GrabModeAsync
, GrabModeAsync
, 
  68                                 None
, cursor
[CurMove
], CurrentTime
) != GrabSuccess
) 
  70         XQueryPointer(dpy
, root
, &dummy
, &dummy
, &x1
, &y1
, &di
, &di
, &dui
); 
  72                 XMaskEvent(dpy
, MouseMask 
| ExposureMask
, &ev
); 
  80                         *c
->x 
= ocx 
+ (ev
.xmotion
.x 
- x1
); 
  81                         *c
->y 
= ocy 
+ (ev
.xmotion
.y 
- y1
); 
  85                         XUngrabPointer(dpy
, CurrentTime
); 
  92 resizemouse(Client 
*c
) 
  99         if(XGrabPointer(dpy
, root
, False
, MouseMask
, GrabModeAsync
, GrabModeAsync
, 
 100                                 None
, cursor
[CurResize
], CurrentTime
) != GrabSuccess
) 
 102         XWarpPointer(dpy
, None
, c
->win
, 0, 0, 0, 0, *c
->w
, *c
->h
); 
 104                 XMaskEvent(dpy
, MouseMask 
| ExposureMask
, &ev
); 
 108                         handler
[Expose
](&ev
); 
 112                         *c
->w 
= abs(ocx 
- ev
.xmotion
.x
); 
 113                         *c
->h 
= abs(ocy 
- ev
.xmotion
.y
); 
 114                         *c
->x 
= (ocx 
<= ev
.xmotion
.x
) ? ocx 
: ocx 
- *c
->w
; 
 115                         *c
->y 
= (ocy 
<= ev
.xmotion
.y
) ? ocy 
: ocy 
- *c
->h
; 
 119                         XUngrabPointer(dpy
, CurrentTime
); 
 126 buttonpress(XEvent 
*e
) 
 130         XButtonPressedEvent 
*ev 
= &e
->xbutton
; 
 133         if(barwin 
== ev
->window
) { 
 137                         for(a
.i 
= 0; a
.i 
< TLast
; a
.i
++) { 
 138                                 x 
+= textw(tags
[a
.i
]); 
 146                         a
.i 
= (tsel 
+ 1 < TLast
) ? tsel 
+ 1 : 0; 
 150                         a
.i 
= (tsel 
- 1 >= 0) ? tsel 
- 1 : TLast 
- 1; 
 155         else if((c 
= getclient(ev
->window
))) { 
 156                 if(arrange 
== dotile 
&& !c
->isfloat
) { 
 157                         if((ev
->state 
& ControlMask
) && (ev
->button 
== Button1
)) 
 161                 /* floating windows */ 
 180 configurerequest(XEvent 
*e
) 
 182         XConfigureRequestEvent 
*ev 
= &e
->xconfigurerequest
; 
 186         ev
->value_mask 
&= ~CWSibling
; 
 187         if((c 
= getclient(ev
->window
))) { 
 189                 if(ev
->value_mask 
& CWX
) 
 191                 if(ev
->value_mask 
& CWY
) 
 193                 if(ev
->value_mask 
& CWWidth
) 
 195                 if(ev
->value_mask 
& CWHeight
) 
 197                 if(ev
->value_mask 
& CWBorderWidth
) 
 205         wc
.width 
= ev
->width
; 
 206         wc
.height 
= ev
->height
; 
 209         wc
.stack_mode 
= Above
; 
 210         ev
->value_mask 
&= ~CWStackMode
; 
 211         ev
->value_mask 
|= CWBorderWidth
; 
 212         XConfigureWindow(dpy
, ev
->window
, ev
->value_mask
, &wc
); 
 217 destroynotify(XEvent 
*e
) 
 220         XDestroyWindowEvent 
*ev 
= &e
->xdestroywindow
; 
 222         if((c 
= getclient(ev
->window
))) 
 227 enternotify(XEvent 
*e
) 
 229         XCrossingEvent 
*ev 
= &e
->xcrossing
; 
 232         if(ev
->mode 
!= NotifyNormal 
|| ev
->detail 
== NotifyInferior
) 
 235         if((c 
= getclient(ev
->window
))) 
 237         else if(ev
->window 
== root
) 
 244         XExposeEvent 
*ev 
= &e
->xexpose
; 
 248                 if(barwin 
== ev
->window
) 
 250                 else if((c 
= getctitle(ev
->window
))) 
 258         XKeyEvent 
*ev 
= &e
->xkey
; 
 259         static unsigned int len 
= key 
? sizeof(key
) / sizeof(key
[0]) : 0; 
 263         keysym 
= XKeycodeToKeysym(dpy
, (KeyCode
)ev
->keycode
, 0); 
 264         for(i 
= 0; i 
< len
; i
++) 
 265                 if((keysym 
== key
[i
].keysym
) && (key
[i
].mod 
== ev
->state
)) { 
 267                                 key
[i
].func(&key
[i
].arg
); 
 273 leavenotify(XEvent 
*e
) 
 275         XCrossingEvent 
*ev 
= &e
->xcrossing
; 
 277         if((ev
->window 
== root
) && !ev
->same_screen
) 
 282 maprequest(XEvent 
*e
) 
 284         XMapRequestEvent 
*ev 
= &e
->xmaprequest
; 
 285         static XWindowAttributes wa
; 
 287         if(!XGetWindowAttributes(dpy
, ev
->window
, &wa
)) 
 290         if(wa
.override_redirect
) { 
 291                 XSelectInput(dpy
, ev
->window
, 
 292                                 (StructureNotifyMask 
| PropertyChangeMask
)); 
 296         if(!getclient(ev
->window
)) 
 297                 manage(ev
->window
, &wa
); 
 301 propertynotify(XEvent 
*e
) 
 303         XPropertyEvent 
*ev 
= &e
->xproperty
; 
 307         if(ev
->state 
== PropertyDelete
) 
 310         if((c 
= getclient(ev
->window
))) { 
 311                 if(ev
->atom 
== wmatom
[WMProtocols
]) { 
 312                         c
->proto 
= getproto(c
->win
); 
 317                         case XA_WM_TRANSIENT_FOR
: 
 318                                 XGetTransientForHint(dpy
, c
->win
, &trans
); 
 319                                 if(!c
->isfloat 
&& (c
->isfloat 
= (trans 
!= 0))) 
 322                         case XA_WM_NORMAL_HINTS
: 
 326                 if(ev
->atom 
== XA_WM_NAME 
|| ev
->atom 
== netatom
[NetWMName
]) { 
 334 unmapnotify(XEvent 
*e
) 
 337         XUnmapEvent 
*ev 
= &e
->xunmap
; 
 339         if((c 
= getclient(ev
->window
))) 
 345 void (*handler
[LASTEvent
]) (XEvent 
*) = { 
 346         [ButtonPress
] = buttonpress
, 
 347         [ConfigureRequest
] = configurerequest
, 
 348         [DestroyNotify
] = destroynotify
, 
 349         [EnterNotify
] = enternotify
, 
 350         [LeaveNotify
] = leavenotify
, 
 352         [KeyPress
] = keypress
, 
 353         [MapRequest
] = maprequest
, 
 354         [PropertyNotify
] = propertynotify
, 
 355         [UnmapNotify
] = unmapnotify
 
 361         static unsigned int len 
= key 
? sizeof(key
) / sizeof(key
[0]) : 0; 
 365         for(i 
= 0; i 
< len
; i
++) { 
 366                 code 
= XKeysymToKeycode(dpy
, key
[i
].keysym
); 
 367                 XUngrabKey(dpy
, code
, key
[i
].mod
, root
); 
 368                 XGrabKey(dpy
, code
, key
[i
].mod
, root
, True
, 
 369                                 GrabModeAsync
, GrabModeAsync
);