Xinqi Bao's Git
029a59ca2626e900172dbf2990bd78eff5dcd42b
   2  * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com> 
   3  * See LICENSE file for license details. 
  10 #include <X11/Xutil.h> 
  14 void (*arrange
)(Arg 
*) = tiling
; 
  16 static Rule rule
[] = { 
  17         /* class                        instance        tags                                            floating */ 
  18         { "Firefox-bin",        "Gecko",        { [Twww
] = "www" },                     False 
}, 
  24         for(; c 
&& !c
->tags
[tsel
]; c 
= c
->next
); 
  36         for(l 
= &clients
; *l 
&& *l 
!= sel
; l 
= &(*l
)->next
); 
  39         old
->next 
= clients
; /* pop */ 
  53         sel
->w 
= sw 
- 2 * sel
->border
; 
  54         sel
->h 
= sh 
- 2 * sel
->border 
- bh
; 
  57         discard_events(EnterWindowMask
); 
  68         if((c 
= next(clients
))) 
  71         for(c 
= clients
; c
; c 
= next(c
->next
)) 
  82         sel
->tags
[arg
->i
] = tags
[arg
->i
]; 
  93         for(i 
= 0; i 
< TLast
; i
++) 
 101         XMoveWindow(dpy
, c
->win
, c
->x 
+ 2 * sw
, c
->y
); 
 102         XMoveWindow(dpy
, c
->title
, c
->tx 
+ 2 * sw
, c
->ty
); 
 111         for(c 
= clients
; c
; c 
= c
->next
) { 
 117         if(sel 
&& !sel
->tags
[tsel
]) { 
 118                 if((sel 
= next(clients
))) { 
 123         discard_events(EnterWindowMask
); 
 134         for(n 
= 0, c 
= clients
; c
; c 
= c
->next
) 
 135                 if(c
->tags
[tsel
] && !c
->floating
) 
 139                 h 
= (sh 
- bh
) / (n 
- 1); 
 143         for(i 
= 0, c 
= clients
; c
; c 
= c
->next
) { 
 153                                 c
->w 
= sw 
- 2 * c
->border
; 
 154                                 c
->h 
= sh 
- 2 * c
->border 
- bh
; 
 159                                 c
->w 
= mw 
- 2 * c
->border
; 
 160                                 c
->h 
= sh 
- 2 * c
->border 
- bh
; 
 164                                 c
->y 
= sy 
+ (i 
- 1) * h 
+ bh
; 
 165                                 c
->w 
= w 
- 2 * c
->border
; 
 166                                 c
->h 
= h 
- 2 * c
->border
; 
 174         if(sel 
&& !sel
->tags
[tsel
]) { 
 175                 if((sel 
= next(clients
))) { 
 180         discard_events(EnterWindowMask
); 
 191         if((c 
= sel
->revert 
&& sel
->revert
->tags
[tsel
] ? sel
->revert 
: NULL
)) { 
 205         if(!(c 
= next(sel
->next
))) 
 219         if(sel
->proto 
& WM_PROTOCOL_DELWIN
) 
 220                 send_message(sel
->win
, wm_atom
[WMProtocols
], wm_atom
[WMDelete
]); 
 222                 XKillClient(dpy
, sel
->win
); 
 226 resize_title(Client 
*c
) 
 231         for(i 
= 0; i 
< TLast
; i
++) 
 233                         c
->tw 
+= textw(c
->tags
[i
]) + dc
.font
.height
; 
 234         c
->tw 
+= textw(c
->name
) + dc
.font
.height
; 
 237         c
->tx 
= c
->x 
+ c
->w 
- c
->tw 
+ 2; 
 239         XMoveResizeWindow(dpy
, c
->title
, c
->tx
, c
->ty
, c
->tw
, c
->th
); 
 243 update_name(Client 
*c
) 
 251         XGetTextProperty(dpy
, c
->win
, &name
, net_atom
[NetWMName
]); 
 253                 XGetWMName(dpy
, c
->win
, &name
); 
 256         if(name
.encoding 
== XA_STRING
) 
 257                 strncpy(c
->name
, (char *)name
.value
, sizeof(c
->name
)); 
 259                 if(XmbTextPropertyToTextList(dpy
, &name
, &list
, &n
) >= Success
 
 262                         strncpy(c
->name
, *list
, sizeof(c
->name
)); 
 263                         XFreeStringList(list
); 
 271 update_size(Client 
*c
) 
 275         if(!XGetWMNormalHints(dpy
, c
->win
, &size
, &msize
) || !size
.flags
) 
 277         c
->flags 
= size
.flags
; 
 278         if(c
->flags 
& PBaseSize
) { 
 279                 c
->basew 
= size
.base_width
; 
 280                 c
->baseh 
= size
.base_height
; 
 283                 c
->basew 
= c
->baseh 
= 0; 
 284         if(c
->flags 
& PResizeInc
) { 
 285                 c
->incw 
= size
.width_inc
; 
 286                 c
->inch 
= size
.height_inc
; 
 289                 c
->incw 
= c
->inch 
= 0; 
 290         if(c
->flags 
& PMaxSize
) { 
 291                 c
->maxw 
= size
.max_width
; 
 292                 c
->maxh 
= size
.max_height
; 
 295                 c
->maxw 
= c
->maxh 
= 0; 
 296         if(c
->flags 
& PMinSize
) { 
 297                 c
->minw 
= size
.min_width
; 
 298                 c
->minh 
= size
.min_height
; 
 301                 c
->minw 
= c
->minh 
= 0; 
 302         if(c
->flags 
& PWinGravity
) 
 303                 c
->grav 
= size
.win_gravity
; 
 305                 c
->grav 
= NorthWestGravity
; 
 311         XRaiseWindow(dpy
, c
->win
); 
 312         XRaiseWindow(dpy
, c
->title
); 
 318         XLowerWindow(dpy
, c
->title
); 
 319         XLowerWindow(dpy
, c
->win
); 
 331         XSetInputFocus(dpy
, c
->win
, RevertToPointerRoot
, CurrentTime
); 
 333         discard_events(EnterWindowMask
); 
 340         static unsigned int len 
= rule 
? sizeof(rule
) / sizeof(rule
[0]) : 0; 
 342         Bool matched 
= False
; 
 345                 c
->tags
[tsel
] = tags
[tsel
]; 
 349         if(XGetClassHint(dpy
, c
->win
, &ch
)) { 
 350                 if(ch
.res_class 
&& ch
.res_name
) { 
 351                         for(i 
= 0; i 
< len
; i
++) 
 352                                 if(!strncmp(rule
[i
].class, ch
.res_class
, sizeof(rule
[i
].class)) 
 353                                         && !strncmp(rule
[i
].instance
, ch
.res_name
, sizeof(rule
[i
].instance
))) 
 355                                         for(j 
= 0; j 
< TLast
; j
++) 
 356                                                 c
->tags
[j
] = rule
[i
].tags
[j
]; 
 357                                         c
->floating 
= rule
[i
].floating
; 
 369                 c
->tags
[tsel
] = tags
[tsel
]; 
 373 manage(Window w
, XWindowAttributes 
*wa
) 
 376         XSetWindowAttributes twa
; 
 379         c 
= emallocz(sizeof(Client
)); 
 381         c
->tx 
= c
->x 
= wa
->x
; 
 382         c
->ty 
= c
->y 
= wa
->y
; 
 385         c
->tw 
= c
->w 
= wa
->width
; 
 389         c
->proto 
= win_proto(c
->win
); 
 391         XSelectInput(dpy
, c
->win
, 
 392                         StructureNotifyMask 
| PropertyChangeMask 
| EnterWindowMask
); 
 393         XGetTransientForHint(dpy
, c
->win
, &trans
); 
 394         twa
.override_redirect 
= 1; 
 395         twa
.background_pixmap 
= ParentRelative
; 
 396         twa
.event_mask 
= ExposureMask
; 
 398         c
->title 
= XCreateWindow(dpy
, root
, c
->tx
, c
->ty
, c
->tw
, c
->th
, 
 399                         0, DefaultDepth(dpy
, screen
), CopyFromParent
, 
 400                         DefaultVisual(dpy
, screen
), 
 401                         CWOverrideRedirect 
| CWBackPixmap 
| CWEventMask
, &twa
); 
 406         for(l 
= &clients
; *l
; l 
= &(*l
)->next
); 
 407         c
->next 
= *l
; /* *l == nil */ 
 410         XGrabButton(dpy
, Button1
, Mod1Mask
, c
->win
, False
, ButtonPressMask
, 
 411                         GrabModeAsync
, GrabModeSync
, None
, None
); 
 412         XGrabButton(dpy
, Button2
, Mod1Mask
, c
->win
, False
, ButtonPressMask
, 
 413                         GrabModeAsync
, GrabModeSync
, None
, None
); 
 414         XGrabButton(dpy
, Button3
, Mod1Mask
, c
->win
, False
, ButtonPressMask
, 
 415                         GrabModeAsync
, GrabModeSync
, None
, None
); 
 419                         || ((c
->maxw 
== c
->minw
) && (c
->maxh 
== c
->minh
)); 
 422         /* mapping the window now prevents flicker */ 
 424                 XMapRaised(dpy
, c
->win
); 
 425                 XMapRaised(dpy
, c
->title
); 
 430                 XMapRaised(dpy
, c
->win
); 
 431                 XMapRaised(dpy
, c
->title
); 
 436 gravitate(Client 
*c
, Bool invert
) 
 442         case NorthWestGravity
: 
 444         case NorthEastGravity
: 
 450                 dy 
= -(c
->h 
/ 2) + c
->border
; 
 452         case SouthEastGravity
: 
 454         case SouthWestGravity
: 
 463         case NorthWestGravity
: 
 465         case SouthWestGravity
: 
 471                 dx 
= -(c
->w 
/ 2) + c
->border
; 
 473         case NorthEastGravity
: 
 475         case SouthEastGravity
: 
 476                 dx 
= -(c
->w 
+ c
->border
); 
 492 resize(Client 
*c
, Bool inc
) 
 498                         c
->w 
-= (c
->w 
- c
->basew
) % c
->incw
; 
 500                         c
->h 
-= (c
->h 
- c
->baseh
) % c
->inch
; 
 502         if(c
->minw 
&& c
->w 
< c
->minw
) 
 504         if(c
->minh 
&& c
->h 
< c
->minh
) 
 506         if(c
->maxw 
&& c
->w 
> c
->maxw
) 
 508         if(c
->maxh 
&& c
->h 
> c
->maxh
) 
 511         XSetWindowBorderWidth(dpy
, c
->win
, 1); 
 512         XMoveResizeWindow(dpy
, c
->win
, c
->x
, c
->y
, c
->w
, c
->h
); 
 513         e
.type 
= ConfigureNotify
; 
 520         e
.border_width 
= c
->border
; 
 522         e
.override_redirect 
= False
; 
 523         XSendEvent(dpy
, c
->win
, False
, StructureNotifyMask
, (XEvent 
*)&e
); 
 528 dummy_error_handler(Display 
*dsply
, XErrorEvent 
*err
) 
 539         XSetErrorHandler(dummy_error_handler
); 
 541         XUngrabButton(dpy
, AnyButton
, AnyModifier
, c
->win
); 
 542         XDestroyWindow(dpy
, c
->title
); 
 544         for(l 
= &clients
; *l 
&& *l 
!= c
; l 
= &(*l
)->next
); 
 546         for(l 
= &clients
; *l
; l 
= &(*l
)->next
) 
 547                 if((*l
)->revert 
== c
) 
 550                 sel 
= sel
->revert 
? sel
->revert 
: clients
; 
 555         XSetErrorHandler(error_handler
); 
 566         for(c 
= clients
; c
; c 
= c
->next
) 
 576         for(c 
= clients
; c
; c 
= c
->next
) 
 583 draw_client(Client 
*c
) 
 588                 XUnmapWindow(dpy
, c
->title
); 
 589                 XSetWindowBorder(dpy
, c
->win
, dc
.fg
); 
 593         XSetWindowBorder(dpy
, c
->win
, dc
.bg
); 
 594         XMapWindow(dpy
, c
->title
); 
 599         for(i 
= 0; i 
< TLast
; i
++) { 
 602                         dc
.w 
= textw(c
->tags
[i
]) + dc
.font
.height
; 
 603                         drawtext(c
->tags
[i
], True
); 
 607         dc
.w 
= textw(c
->name
) + dc
.font
.height
; 
 608         drawtext(c
->name
, True
); 
 609         XCopyArea(dpy
, dc
.drawable
, c
->title
, dc
.gc
, 
 610                         0, 0, c
->tw
, c
->th
, 0, 0);