index.md (3620B)
1 How does a tag-mask work? 2 ========================= 3 There exists extensive documentation in this wiki about tags in dwm. 4 5 This article will concentrate on how to manage bit masks in default rules. 6 7 In order to manage a number of tags efficiently, dwm uses bitmasks. 8 9 Looking at dwm's code, the tags array is defined in the familiar way: 10 11 static const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; 12 13 We have 9 tags, labelled numerically (but the labels are just that, labels; 14 they don't have any intrinsic values). 15 16 Within dwm's code, each client's tag list is managed as a bit mask: given an 17 integer binary representation, tags are associated from the least significant 18 bit (rightmost) to the most significant bit (leftmost). 19 20 For example, tag '1' is 000000001, while tag 9 is 100000000. Tag '3' is 21 000000100 (third from the right) 22 23 The code in dwm.c that uses the rules array matches the current client 24 properties with each rule, and when matched, it bit-ands the tags member of the 25 rules array element with TAGMASK, then bit-ors it with the client's current tag 26 mask. 27 28 /* rule matching */ 29 XGetClassHint(dpy, c->win, &ch); 30 for(i = 0; i < LENGTH(rules); i++) { 31 r = &rules[i]; 32 if((!r->title || strstr(c->name, r->title)) 33 && (!r->class || (ch.res_class && strstr(ch.res_class, r->class))) 34 && (!r->instance || (ch.res_name && strstr(ch.res_name, r->instance)))) { 35 c->isfloating = r->isfloating; 36 c->tags |= r->tags & TAGMASK; 37 } 38 } 39 40 The client's tags value is therefore built sequentially through the rules. If 41 the tagmask in rules is 0, the currently selected tag becomes the client's tags 42 value. 43 44 if(!c->tags) 45 c->tags = tagset[seltags]; 46 47 TAGMASK is the all-one bit mask, setting to 1 all the bits corresponding to a 48 tag in the tags array. TAGMASK is defined in dwm.c as: 49 50 #define TAGMASK ((int)((1LL << LENGTH(tags)) - 1)) 51 52 and would produce, for the standard tags array, the bit configuration 111111111 53 (nine 1's). 54 55 The reason for using TAGMASK is that it disallows the rules array to select a 56 tag for which we do not have a representation in the tags array. 57 58 Now, this method of representing tags allows us to express our preferences 59 regarding tags using bit-wise operators. 60 61 When are tagmasks used? 62 ----------------------- 63 Please note that dwm always uses tagmasks: even when one tag is selected as the 64 visible tag, it is actually internally managed as a tagmask. 65 66 To prove this, use the command combination that allows you to bring more than 67 one tag into view (usually Mod1-Ctrl-tagnumber). If you select tags 1, 2 and 3, 68 and then open a new xterm using Mod1-Shift-Return, the new xterm will be tagged 69 with tags 1, 2 and 3. 70 71 A very powerful feature. 72 73 What does tagmask 0 mean? 74 ------------------------- 75 It means that the current tagmask should be selected for this window: if more 76 than one tag are currently visible, all the currently visible tags are going to 77 be associated to that window. 78 79 What does tagmask 1 << 8 mean? 80 ------------------------------------ 81 1 shifted to the left by eight positions generates mask 100000000, selecting 82 tag '9' (ninth from the right) in the the tags array. 83 84 What does ~0 mean? 85 ------------------ 86 Complement of 0 is all 1's. This indicates all tags should be selected. The tag 87 mask in rules is then filtered using the TAGMASK macro to adapt the mask to 88 just the available tags. 89 90 What does (1 << 8) - 1 mean? 91 ---------------------------------- 92 1 << 8 selects tag '9' only (100000000). Subtracting 1 to that bitmask 93 transforms all the 0's to the right of that tagmask into 1's (011111111), 94 effectively selecting all tags except '9'.