1
0
mirror of git://git.suckless.org/dwm synced 2025-07-27 02:02:08 -07:00

Compare commits

...

349 Commits
1.3 ... 3.5

Author SHA1 Message Date
Anselm R. Garbe
2d7f59424c simplifying regexps in config samples 2007-02-14 09:31:23 +01:00
Anselm R. Garbe
e256afe31e made for/if/else constructs more consistent, some code polishing 2007-02-14 09:09:18 +01:00
Anselm R. Garbe
64cfebc5e7 made configurerequest more tidy 2007-02-14 08:14:41 +01:00
Anselm R. Garbe
7a095d0ce2 I didn't knew of c->isfixed, that should fix Jukkas issue with gkrellm ;) 2007-02-13 22:53:58 +01:00
Anselm R. Garbe
5052c538d9 making it more sure that transient checks will work in any case 2007-02-13 22:24:27 +01:00
Anselm R. Garbe
22d8c6fd18 stupid me, one needs to set c->{x,y,w,h} in configurerequest obviously ;) 2007-02-13 14:59:58 +01:00
Anselm R. Garbe
71857b87ee simplified configurerequest 2007-02-13 13:39:33 +01:00
Anselm R. Garbe
6ba400ee0f yet another consistency fix of dwm 2007-02-12 17:20:51 +01:00
Anselm R. Garbe
35e65ea640 I don't see any reason why we should select for input on override-redirect windows? 2007-02-12 16:41:46 +01:00
Anselm R. Garbe
d0d986dd0e bugfix of bugfix (thx to Sander) 2007-02-12 14:20:47 +01:00
Anselm R. Garbe
9685e7dbc2 fixed a bug 2007-02-12 13:04:29 +01:00
Anselm R. Garbe
37f39afb8e during writing 2wm.1 I noticed some bugs in dwm.1 2007-02-12 11:42:32 +01:00
Anselm R. Garbe
dc9f62f393 removing all EnterNotifys after resize 2007-02-12 10:21:26 +01:00
Anselm R. Garbe
7055315725 added pointer warp on drop in resize 2007-02-12 10:19:52 +01:00
Anselm R. Garbe
fd995dac78 pneubeck pointed out an obvious thing, that a second p = stext + strlen(stext) - 1 is unnecessary 2007-02-09 14:56:19 +01:00
Anselm R. Garbe
e5765cdd84 treating acroread and mplayer floating by default 2007-02-09 11:58:37 +01:00
Anselm R. Garbe
8d0e58f80b adapting John Grahor's patch to dwm-3.5 2007-02-09 09:54:08 +01:00
Anselm R. Garbe
8fcd1bfda8 fixed copyright notice in Makefile 2007-02-08 14:09:52 +01:00
Anselm R. Garbe
e39e697998 fixed order of Bool declarations 2007-02-08 13:39:33 +01:00
Anselm R. Garbe
d2dd58eabd added TOPBAR option for making the bar appear what the user likes 2007-02-08 11:48:01 +01:00
Anselm R. Garbe
c6fc6b173d next version is 3.5 2007-02-08 11:11:15 +01:00
Anselm R. Garbe
4590d7877c making the bar appear at bottom 2007-02-08 11:08:40 +01:00
Anselm R. Garbe
f577fe4e27 Added tag 3.4 for changeset 9ede7b2d2450 2007-02-07 12:42:35 +01:00
Anselm R. Garbe
9ed5de00b6 removed debug flags 2007-02-07 12:37:21 +01:00
Anselm R. Garbe
28ffff801b replaced getproto with a saner function, now old-school artifacts of WM times in the early 90s completely disappeared, no punned pointer warning anymore ;) 2007-02-07 12:37:06 +01:00
Anselm R. Garbe
44ef3f5a07 yet another fix 2007-02-06 15:29:19 +01:00
Anselm R. Garbe
dafbd0dcb0 simplification 2007-02-06 15:28:25 +01:00
Anselm R. Garbe
2ddc78720a implemented aspect ratio support of windows 2007-02-06 15:22:13 +01:00
Anselm R. Garbe
7ece30ebc0 made some changes more concistent 2007-02-05 11:19:46 +01:00
Anselm R. Garbe
3d48f33025 got rid of LD (inspired by JGs patch to wmii) 2007-02-05 11:09:53 +01:00
Anselm R. Garbe
19fd903d40 applied apm's patch proposal, getting rid of XDrawLines 2007-02-05 11:05:16 +01:00
Anselm R. Garbe
5732e471ae Added tag 3.3 for changeset 0f91934037b0 2007-02-01 08:23:00 +01:00
Anselm R. Garbe
042297b27b applied Sander's drop_bh patch 2007-01-31 20:08:55 +01:00
Anselm R. Garbe
a5cb80b86c handling WM_STATE seems to make DnD in gtk/qt apps working, well let's handle this in dwm as well 2007-01-28 20:29:41 +01:00
Anselm R. Garbe
7e98db251e regarding to http://plan9.bell-labs.com/sources/contrib/rsc/man.ps the BUGS section should appear after SEE ALSO section. 2007-01-26 12:41:15 +01:00
Anselm R. Garbe
bced9077f9 renamed CAVEATS into BUGS 2007-01-26 12:31:57 +01:00
Anselm R. Garbe
82fed986f9 Added tag 3.2.2 for changeset d3876aa79292 2007-01-25 10:05:02 +01:00
Anselm R. Garbe
2c1db7ed35 prepared yet another hotfix release 2007-01-25 09:59:48 +01:00
Anselm R. Garbe
ea4827a578 Added tag 3.2.1 for changeset f2cabc83a18f 2007-01-24 17:25:37 +01:00
Anselm R. Garbe
55be4d6137 hotfix release 3.2.1 2007-01-24 17:25:30 +01:00
Anselm R. Garbe
1f18466409 applied offscreen appearance hotfix 2007-01-24 17:24:55 +01:00
Anselm R. Garbe
b65a1e3379 Added tag 3.2 for changeset 4ce65f61f01b 2007-01-24 12:12:29 +01:00
Anselm R. Garbe
87836d79ef renamed activescreen into selscreen 2007-01-23 17:12:15 +01:00
Anselm R. Garbe
c8a12a0852 implemented Sanders remarks 2007-01-23 13:10:35 +01:00
Anselm R. Garbe
71b84c2114 small changes 2007-01-23 12:29:17 +01:00
Anselm R. Garbe
edb2660a2e removed a blank line 2007-01-23 12:04:22 +01:00
Anselm R. Garbe
17ec726b49 this version should also work with cornercases (like unmanage during !issel, etc.) 2007-01-23 12:00:49 +01:00
Anselm R. Garbe
373b11de11 I think this is the best solution of multihead support 2007-01-23 11:49:16 +01:00
Anselm R. Garbe
04a2b74529 darker border 2007-01-22 16:02:37 +01:00
Anselm R. Garbe
fcd98308ba this variant is known to work, but focus() is ugly - we need in general a better way to handle multihead, this issel-stuff looks awkward (maybe it might be a good idea to set sel to NULL but to introduce a Client *revert which is set if a screen is unfocused, have to think about it further). 2007-01-22 10:35:58 +01:00
Anselm R. Garbe
b233089815 applied Sanders all5.patch (thanks for your weekend session, Sander!) 2007-01-22 10:22:58 +01:00
Anselm R. Garbe
201c56f6d3 leavenotify also don't needs the check 2007-01-19 15:05:07 +01:00
Anselm R. Garbe
1e051d71f5 deciding for focus(NULL); 2007-01-19 15:01:51 +01:00
Anselm R. Garbe
ddc79603f9 replaced XSetBorder.../focus() 2007-01-19 14:38:09 +01:00
Anselm R. Garbe
dee5ea2335 yet another multihead fix by Christof Musik 2007-01-19 14:36:25 +01:00
Anselm R. Garbe
b1c9f5f144 I prefer BORDERPX=1 2007-01-19 08:05:39 +01:00
Anselm R. Garbe
a542bdf658 personally I prefer 2px borders 2007-01-18 11:46:39 +01:00
Anselm R. Garbe
96e1b25c8c applied a modified version of Christof Musik's multihead patch (though this is not sure if it works in all cases, have to wait for an ACK by Christof) 2007-01-18 11:11:40 +01:00
Anselm R. Garbe
caf5a16271 moved BORDERPX to config.*.h 2007-01-17 12:36:29 +01:00
Anselm R. Garbe
936e11fd54 Added tag 3.1 for changeset e1c8bef05e6e 2007-01-16 11:41:56 +01:00
Anselm R. Garbe
9715ba82aa removed erealloc (not used) 2007-01-16 11:35:56 +01:00
Anselm R. Garbe
3c35b90dd3 removed unnecessary bx, by, bw variables 2007-01-16 11:33:42 +01:00
Anselm R. Garbe
1d63030665 s/444/555/g - enlightened selected background 2007-01-16 11:28:17 +01:00
Anselm R. Garbe
6a5b41203e removed firefox rule from default.h 2007-01-16 11:26:15 +01:00
Anselm R. Garbe
fbd310972d applied new default colors 2007-01-16 11:25:10 +01:00
Anselm R. Garbe
3059c9c507 applied sanders patch of my config 2007-01-16 11:12:34 +01:00
Anselm R. Garbe
3b18f17d4d Jukka, thanks for being faster than me! 2007-01-15 19:01:57 +01:00
Anselm R. Garbe
72faa1919e changed restack, to fix undrawed tag indicators 2007-01-15 12:07:18 +01:00
Anselm R. Garbe
f8181f64e2 removed drawclient and drawall (they performed useless operations/consumed useless cpu cycles) 2007-01-15 12:04:25 +01:00
Anselm R. Garbe
0045ad87df implemented new color scheme accordingly to Sanders proposal 2007-01-14 22:37:34 +01:00
Anselm R. Garbe
ceea528eff removed mode label stuff 2007-01-14 22:32:26 +01:00
Anselm R. Garbe
6c5dc7017c removed client title bar 2007-01-14 22:27:29 +01:00
Anselm R. Garbe
ae0b4fdd92 added missing space 2007-01-12 21:56:01 +01:00
Anselm R. Garbe
b3cea4d388 nah the last change feels bad 2007-01-12 13:06:15 +01:00
Anselm R. Garbe
d296081321 changed incnmaster shortcuts in config.arg.h 2007-01-12 12:48:51 +01:00
Anselm R. Garbe
177ed7e5de Added tag 3.0 for changeset 76b58d21ea98 2007-01-12 12:37:12 +01:00
Anselm R. Garbe
f679125206 removing to allow nmaster=0 2007-01-12 12:15:06 +01:00
Anselm R. Garbe
58beead14d this looks better now ;) 2007-01-11 16:38:45 +01:00
Anselm R. Garbe
e1811c37ca switching to arabic tags 2007-01-11 16:03:06 +01:00
Anselm R. Garbe
a24a6701c8 small fix of initial numlockmask value 2007-01-11 15:51:15 +01:00
Anselm R. Garbe
d108cfa7fc allowing nmaster=0 (I think that's a straight idea) 2007-01-11 13:43:38 +01:00
Anselm R. Garbe
92cb5ebb7c added Button{4,5} description to dwm.1 2007-01-10 12:56:49 +01:00
Anselm R. Garbe
653826572d added comment to %u in config.default.h, added Button{4.5} support on mode label 2007-01-10 12:54:23 +01:00
Anselm R. Garbe
5a5851bac2 reorganized 2007-01-08 17:36:56 +01:00
Anselm R. Garbe
1d4a24dae0 implemented nmaster appearance in mode label (using %u) 2007-01-08 17:33:24 +01:00
Anselm R. Garbe
a768ea93fd Added tag 2.9 for changeset 3a5910fac3cc 2007-01-08 13:01:37 +01:00
Anselm R. Garbe
c95fe6e24b I received Sander's complain just in time ;) 2007-01-08 12:56:35 +01:00
Anselm R. Garbe
c75168186b changed status fg 2007-01-08 12:43:10 +01:00
Anselm R. Garbe
3a96c9a8d5 fofofo 2007-01-08 12:18:49 +01:00
Anselm R. Garbe
1617b95598 extended default tags to 1-9 2007-01-08 12:12:02 +01:00
Anselm R. Garbe
726ae5bf6d small grammar fix of dwm.1 2007-01-07 19:24:21 +01:00
Anselm R. Garbe
3e11b38349 changed a term in dwm.1 2007-01-07 14:38:41 +01:00
Anselm R. Garbe
16ed879524 using shorter tags, using mon instead of cert 2007-01-05 22:27:26 +01:00
Anselm R. Garbe
20d7b5d058 roman numerals suck badly, reverting 2007-01-05 22:22:18 +01:00
Anselm R. Garbe
11a08b9cfc switching to roman tags, I need more tags 2007-01-05 22:13:44 +01:00
Anselm R. Garbe
c2b753d917 I inc/decrease on the fly, feels better 2007-01-05 22:03:09 +01:00
Anselm R. Garbe
6c767072a3 allowing swap() for first master client 2007-01-05 22:00:15 +01:00
Anselm R. Garbe
e9cfae7aba prevent pop() if first sel == nexttiled(clients) 2007-01-05 21:56:57 +01:00
Anselm R. Garbe
7ac0de8350 removed swap(), implemented pop for everything 2007-01-05 21:55:43 +01:00
Anselm R. Garbe
0b7c0f10ee preserving c1->snext and c2->snext in swap() as well. 2007-01-05 21:52:17 +01:00
Anselm R. Garbe
51f6405b0d fixing some minor issues 2007-01-05 16:35:45 +01:00
Anselm R. Garbe
6096f8a113 removed the term clients from dwm.1 2007-01-05 15:37:10 +01:00
Anselm R. Garbe
d939f301fa adding some prevention that master clients get smaller than bh 2007-01-05 15:16:39 +01:00
Anselm R. Garbe
8c4623da80 changed shortcuts to M-i and M-d 2007-01-05 15:11:01 +01:00
Anselm R. Garbe
0faaba04a5 allowing zoom within master area as well 2007-01-05 15:08:25 +01:00
Anselm R. Garbe
ec7a5ffff1 changed plus key to MODKEY-Shift-plus (US-layout restrictions ;) 2007-01-05 15:04:49 +01:00
Anselm R. Garbe
98afb7b9d0 I prefer two master windows by default 2007-01-05 14:49:18 +01:00
Anselm R. Garbe
06bae9dfb7 added MODKEY-{plus,minus} shortcuts (increasing/decreasing master clients) 2007-01-05 14:48:16 +01:00
Anselm R. Garbe
0b80d1842d experimental version which allows master clients being increased/decreased 2007-01-05 12:50:39 +01:00
Anselm R. Garbe
d7ec23a5db fixed comment of drawclient() 2007-01-04 16:45:28 +01:00
Anselm R. Garbe
2cf8ef9520 switching bakc to my previous color favorit 2007-01-04 14:51:43 +01:00
Anselm R. Garbe
184471b4bb renamed drawtitle into drawclient 2007-01-04 14:17:25 +01:00
arg@mig29
21898c6049 using more thinkpad compliant colors 2007-01-02 16:29:01 +01:00
arg@mig29
6a9300e815 changed arg's color scheme 2007-01-02 16:25:01 +01:00
arg@mig29
ac24f132db corrections 2007-01-02 15:44:19 +01:00
arg@mig29
cb4aa5bc35 next version will contain updated copyright notice 2007-01-02 15:37:58 +01:00
arg@mig29
beac539f31 Added tag 2.8 for changeset 107719a9ce3bd0c79f9f1f626596eb338a276561 2007-01-02 14:53:02 +01:00
arg@mig29
b5d297f02f fixed cleanup, using clients instead of sel 2007-01-02 14:40:18 +01:00
arg@mig29
9056d7ea88 changed comment of updatesizehints 2007-01-02 12:28:02 +01:00
arg@mig29
ebd17e4827 renamed updatesize into updatesizehints (thx to Sander for this hint) 2007-01-01 19:10:31 +01:00
arg@mig29
7e59c89250 small simplification to dotile() (thx to Ross for this hint) 2006-12-20 12:07:05 +01:00
arg@mig29
9e4e4d9022 migrated arg's config.h to new dmenu command line options 2006-12-19 11:38:08 +01:00
arg@mig29
71fd06f843 added Solaris hints 2006-12-18 14:39:34 +01:00
arg@mig29
58e6866d86 Added tag 2.7 for changeset 21951c0dfbae5af68ed77821a4d87253ee91803f 2006-12-14 08:50:49 +01:00
arg@mig29
c7da124149 applied Sanders patch 2006-12-13 14:15:38 +01:00
arg@mig29
21bd90d7d3 fixed man page, status bar displays EOF instead of "broken pipe" 2006-12-13 13:53:10 +01:00
arg@mig29
c8f96b5b4c added the java odyssee to CAVEATS section 2006-12-13 13:42:17 +01:00
arg@mig29
ded60365d4 removed Client->grav 2006-12-12 19:14:38 +01:00
arg@mig29
629647dfee removed gravitate for the moment 2006-12-11 16:45:02 +01:00
arg@mig29
4ca3d861f0 disabling configure() during resize 2006-12-11 09:42:16 +01:00
arg@mig29
069e7a6e24 made gravitate effectless, waiting for complains ;) 2006-12-11 08:31:30 +01:00
arg@mig29
ac6e34ea06 fixed diagnostic error message 2006-12-08 11:11:52 +01:00
arg@mig29
a308b7507a removed the hardcoded fixed fallback, it is useless in non-Latin1 environments 2006-12-08 10:40:09 +01:00
arg@mig29
630e7ff26f we don't use the term clients anymore, windows is the better term 2006-12-07 16:38:57 +01:00
arg@mig29
3764ab471b Added tag 2.6 for changeset 5308dd22b6ee8e3218c81d9e7e4125f235bb5778 2006-12-07 14:55:29 +01:00
arg@mig29
a3319c6f8e found compromise for fonts 2006-12-07 14:39:31 +01:00
arg@mig29
66c699a701 nah, people should define 'fixed' to be compatible with their locale 2006-12-07 12:03:15 +01:00
arg@mig29
aaf1e44da9 using a UTF-8 capable fixed font 2006-12-07 11:55:04 +01:00
arg@mig29
1ef2307ec4 switching to uxterm again, I get kretze from this urxvt crap 2006-12-07 10:43:34 +01:00
arg@mig29
d42c3ba2dc with this patch everything works fine for me 2006-12-07 10:02:46 +01:00
arg@mig29
4b06155873 don't use Xlocale crap, let's use locale.h instead 2006-12-07 09:49:45 +01:00
arg@mig29
857d825eeb using the portable Xmb+UTF-8 way of life, will see if this works well... 2006-12-07 09:47:55 +01:00
arg@mig29
6b345353e3 improved the memory leak prevention 2006-12-06 11:19:06 +01:00
arg@mig29
ab3b3a8f61 making terminus more explicit a regular font (otherwise olique font might be used in some setups like mine). 2006-12-05 14:21:18 +01:00
arg@mig29
71b82fb1f6 also setting LC_CTYPE only 2006-12-05 13:31:29 +01:00
arg@mig29
9bd9ea423e enforcing using fontsets even if they are incomplete for some encodings 2006-12-05 10:30:31 +01:00
arg@mig29
99964398e7 Added tag 2.5.1 for changeset c7f84f23ec5aef29988dcdc4ec22a7352ee8f58e 2006-12-04 21:01:14 +01:00
arg@mig29
7009ebfa69 hotfix of a serious crashing bug 2006-12-04 21:00:26 +01:00
arg@mig29
760e23dd3a Added tag 2.5 for changeset dcbbfabc8ecc5f33a6cc950584de87da1a368045 2006-12-04 15:39:43 +01:00
arg@mig29
c53d9d516a applied Manuel's regex patch 2006-12-03 11:21:25 +01:00
arg@mig29
7739e6b466 made squares equally sized, and 1px bigger 2006-12-01 17:55:46 +01:00
arg@mig29
4881857458 if client is focused, the emptysquare don't needs to be drawed 2006-12-01 17:51:05 +01:00
arg@mig29
c73d5cb7b6 and the winner is 2006-12-01 17:45:27 +01:00
arg@mig29
6458803d21 sander1 proposal 2006-12-01 17:36:37 +01:00
arg@mig29
6e72d781f7 dood 2006-12-01 16:55:42 +01:00
arg@mig29
4e926a9ef2 darkening the fg colors somewhat 2006-12-01 15:50:22 +01:00
arg@mig29
4ba3cfaee9 less obtrusive indicator (only a top line) 2006-12-01 15:03:42 +01:00
arg@mig29
e655e8a7d5 final2 indicator 2006-12-01 12:52:16 +01:00
arg@mig29
c34e4e4b39 removing the -1 on final indicators, looks cleaner 2006-12-01 12:39:13 +01:00
arg@mig29
a678ee6365 final indicators 2006-12-01 12:25:23 +01:00
arg@mig29
49f0ee329d changed things like I described in last mail 2006-12-01 10:16:10 +01:00
arg@mig29
0c9d9a3d94 improved tag indicator 2006-12-01 09:52:15 +01:00
arg@mig29
89e1acb0bb removed viewall signature from dwm.h 2006-11-30 17:01:39 +01:00
arg@mig29
c2ed26b711 next version will be 2.5 2006-11-30 15:51:26 +01:00
arg@mig29
42fd392e05 removed viewall(), replaced with view(-1); added tag(-1) to tag a client with all tags (new key combo MODKEY-Shift-0) 2006-11-30 15:27:43 +01:00
arg@mig29
e06447ee88 Added tag 2.4 for changeset 32b246925086910d63147483160281a91a47479f 2006-11-30 09:19:52 +01:00
arg@mig29
683dabe5e6 extended dwm.1 with last change 2006-11-28 17:36:00 +01:00
arg@mig29
3aff96177c togglefloat should only work in dotile mode (thanks to Sander for this hint) 2006-11-28 17:35:31 +01:00
arg@mig29
0a915eba8f applied Alex Elide's tricky patch, thanks! 2006-11-27 17:51:50 +01:00
arg@mig29
19dcbc5717 returning to old Key struct 2006-11-27 17:49:58 +01:00
arg@mig29
d2a4952956 applied Szabolcs Nagy's patch (thank you!) 2006-11-27 17:46:02 +01:00
arg@mig29
0c97b21b61 applied patch by Jukka 2006-11-27 17:30:06 +01:00
arg@mig29
19390b1a91 changing Key.func into Key.func[NFUNCS], this allows sequences execution of functions per keypress (avoids implementing useless masterfunctions which call atomic ones) 2006-11-27 13:21:38 +01:00
arg@mig29
8dc86051df added man page entry 2006-11-27 11:05:47 +01:00
arg@mig29
46d5f9d1bf added togglefloat to hg tip (i consider this useful for some cases), using MODKEY-Shift-space as shortcut 2006-11-27 10:57:37 +01:00
arg@mig29
35e96b8deb applied Jukka's patch preventing some cornercases and making the EOF error message correct 2006-11-27 10:29:47 +01:00
arg@mig29
2210ea7e3b applied yet another proposal of Manuel 2006-11-26 15:43:16 +01:00
arg@mig29
61a1910f91 applied Jukka's sizeof K&R compliance patch, applied Manuels' last-line printage proposal for stdin reading. 2006-11-26 14:26:53 +01:00
arg@mig29
27ef73507b applied Jukka's stdinread patch 2006-11-26 13:31:36 +01:00
arg@mig29
2b35fb643e next version will be 2.4 2006-11-25 19:26:31 +01:00
arg@mig29
478f6f95f1 applied Manuels patch (thanks to Manuel!) 2006-11-25 19:26:16 +01:00
arg@mig29
44411d2d48 small fix of man page 2006-11-24 17:02:41 +01:00
arg@mig29
a2175cf71a Added tag 2.3 for changeset 719b37b37b0df829d7cf017ac70e353088fe5849 2006-11-24 15:46:32 +01:00
arg@mig29
4606d218c3 using the term 'indicated' instead of 'higlighted' 2006-11-23 16:00:16 +01:00
arg@mig29
d37d0f24e6 updated man page with the bottom right corner indicator 2006-11-23 15:59:16 +01:00
arg@mig29
321e8d51ed fififif 2006-11-22 16:17:50 +01:00
arg@mig29
78f4b51757 added a similiar patch to Daves solution to indicate if there are clients with a specific tag 2006-11-22 14:57:09 +01:00
arg@mig29
7d168a2621 returning to old bar colorization behavior, like sander proposed for consistency reasons 2006-11-21 15:03:08 +01:00
arg@mig29
931e712eac applied Gottox patches 2006-11-21 14:49:13 +01:00
arg@mig29
4ec04209e0 using iso10646 explicitely in arg's config.h 2006-11-21 12:17:47 +01:00
arg@mig29
82ddba88a2 Added tag 2.2 for changeset 7e92f58754ae6edb3225f26d754bd89c1ff458cf 2006-11-21 09:41:33 +01:00
arg@mig29
52a8cc8d46 nah reverting to my prev style, that's really the best 2006-11-18 21:33:33 +01:00
arg@mig29
d175df8aa3 applying aluminium style for arg's config.h 2006-11-18 21:26:53 +01:00
arg@mig29
b003a35fde applied Gottox' windowarea patch 2006-11-16 14:40:57 +01:00
arg@mig29
df1a0f9445 using a more blue-ish color... 2006-11-08 17:16:38 +01:00
arg@mig29
5b07b85838 making the selected color more lightning 2006-11-08 17:10:51 +01:00
arg@mig29
f320cd203b next release will be 2.2 2006-11-03 09:22:40 +01:00
arg@mig29
f78c16f8c6 applied Jukkas patch 2006-11-03 08:29:39 +01:00
arg@mig29
0c5f47e720 Added tag 2.1 for changeset a2c465098a3b972bbed00feda9804b6aae1e9531 2006-11-02 10:18:22 +01:00
arg@mig29
4b5b3d90af renamed resizecol into resizemaster 2006-10-31 12:07:32 +01:00
arg@mig29
2cce4b95cd applied Gottox patch to simplify the resizing of col, instead of resizing the current area, it only resizes the master area in the future (seems more predictable) 2006-10-31 12:06:38 +01:00
arg@mig29
8e6eb52196 Added tag 2.0 for changeset 12deea36603da407e3f32640048846a3bd74a9ec 2006-10-31 09:02:42 +01:00
arg@mig29
04b633ddf3 make sure that changing sx has no impact on snapping 2006-10-31 09:02:16 +01:00
arg@mig29
b76561a212 in a 1920x1200 setup 40 pixels of snap value are much better than 20 2006-10-30 12:40:10 +01:00
arg@mig29
51c7589c87 fixed stupid bug of snap-to-screen 2006-10-30 12:26:55 +01:00
arg@mig29
99785382ae changing snap priority 2006-10-30 12:07:00 +01:00
arg@mig29
dc1690ce0f removed useless abs() calls 2006-10-30 12:04:08 +01:00
arg@mig29
b6614261ea added screen-border snapping in floating mode, feels quite well 2006-10-30 11:58:05 +01:00
arg@mig29
91e569ca37 and another fix 2006-10-27 13:29:35 +02:00
arg@mig29
0f395c1b11 applied sanders try2 patch 2006-10-27 13:28:26 +02:00
arg@mig29
2b13e7466f applied sanders max size fix 2006-10-27 12:05:47 +02:00
arg@mig29
0982e47408 stupid urxvt needs bg to highlight selections in a sane way, though that makes sense to some extend 2006-10-27 10:24:15 +02:00
arg@mig29
b93ebcf42f reverting to original 2006-10-26 15:41:40 +02:00
arg@mig29
a08d83ba62 applied sander's config.*h nitpick patch 2006-10-26 15:29:20 +02:00
arg@mig29
2b7c275ce8 some other change 2006-10-26 15:26:17 +02:00
arg@mig29
040d0f48a0 apply small fix to prevent apps like mplayer wandering when toggling fullscreen 2006-10-26 15:05:45 +02:00
arg@mig29
724f35a664 forgot to use -tr, which actually prevents the ugly flicker (using xsetroot -solid black as root window pixmap to make this work nicely) 2006-10-26 12:22:26 +02:00
arg@mig29
6f3872edbd using MASTER 600 again, it is definately better, and using urxvtc for the moment (it doesn't flickers on refreshes, but this is not because of Marc Lehmann, it is because of the original rxvt code) 2006-10-26 12:13:41 +02:00
arg@mig29
87324e680c changing MASTER in config.arg.h from 600 to 550 per thousand 2006-10-26 11:21:45 +02:00
arg@mig29
c2b908f603 my new 1920x1200 Z61p arrived, now I can use terminus in a sane way... 2006-10-26 10:21:27 +02:00
Anselm R. Garbe
d7734f996f moved MOUSEMASK into event.c (not used in other places) 2006-10-16 16:50:03 +02:00
Anselm R. Garbe
8b68890650 now being at v2.0 2006-10-14 18:21:39 +02:00
Anselm R. Garbe
b60406cb9b using lsx instead of Jukka's shell construct 2006-10-13 18:47:24 +02:00
Anselm R. Garbe
ce9a9934ec hotfix 2006-10-06 14:01:53 +02:00
Anselm R. Garbe
720b2abe17 Added tag 1.9 for changeset a5567a0d30112822db2627a04a2e7aa3b6c38148 2006-10-06 13:43:59 +02:00
Anselm R. Garbe
5983c00b95 do* has no Arg arument anymore (never called directly) 2006-10-06 13:06:37 +02:00
Anselm R. Garbe
6651dd7fd9 code polishing, removed unnecessary newlines 2006-10-06 11:50:15 +02:00
Anselm R. Garbe
acdea31916 yet another small fix and simplification of dotile 2006-10-06 11:37:12 +02:00
Anselm R. Garbe
10885d349a removed the stack position stuff 2006-10-05 19:27:28 +02:00
Anselm R. Garbe
1c1d09f3e9 small boundary check fix 2006-10-05 18:23:28 +02:00
Anselm R. Garbe
0384faeee5 changing MASTER value from percent into per mill 2006-10-05 18:18:47 +02:00
Anselm R. Garbe
6cca3999c8 Added tag 1.8 for changeset c71952fa3c7ca848ec38a6923b5c6d0e18fff431 2006-10-05 19:00:58 +02:00
Anselm R. Garbe
69408d384d simplified dotile(), removed misleading line 2006-10-05 13:47:30 +02:00
Anselm R. Garbe
4aea423f06 final fix for man page 2006-10-05 13:44:48 +02:00
Anselm R. Garbe
6fc8a63041 keep master ratio on resizecol -> arrange 2006-10-05 12:59:35 +02:00
Anselm R. Garbe
2583a7c0d1 yet another simplification of dotile() 2006-10-05 12:18:04 +02:00
Anselm R. Garbe
0ef6e3103c simplified dotile() 2006-10-05 12:13:24 +02:00
Anselm R. Garbe
7c052b37c8 applied resizecol fix by Jukka 2006-10-05 11:00:55 +02:00
Anselm R. Garbe
d9c475d7f4 Button3 click on mode label toggles stack position now 2006-10-05 09:37:11 +02:00
Anselm R. Garbe
c8e57332d1 applied dave's highlight patch for big fonts 2006-09-29 19:06:27 +02:00
Anselm R. Garbe
c045459917 using ff tiled again, seems to work perfectly with new bottom stack 2006-09-29 18:40:32 +02:00
Anselm R. Garbe
e0f64e63db applied ality's hardcode-0 patches 2006-09-29 18:21:02 +02:00
Anselm R. Garbe
dddd58a8cd added symbols for different modes 2006-09-29 18:08:20 +02:00
Anselm R. Garbe
010fd21b20 removed useless updatemaster 2006-09-29 17:25:49 +02:00
Anselm R. Garbe
1802fad2f9 documented the new behavior in man page 2006-09-29 17:20:05 +02:00
Anselm R. Garbe
f833d109d1 fixed small offset issue 2006-09-29 17:15:05 +02:00
Anselm R. Garbe
7225c99903 fixed the z-layer issue described on mailinglist 2006-09-29 17:12:57 +02:00
Anselm R. Garbe
36178933ed removed the direction flipping 2006-09-29 17:02:56 +02:00
Anselm R. Garbe
ad0da9a571 small fix of a corner case 2006-09-29 16:54:15 +02:00
Anselm R. Garbe
6646468125 small change 2006-09-29 16:44:02 +02:00
Anselm R. Garbe
fee8df6ccf added the new dotile as described on ml 2006-09-29 16:22:20 +02:00
Anselm R. Garbe
8fa47ac679 prelim of dotile() 2006-09-29 14:39:03 +02:00
Anselm R. Garbe
b427a2c6cb I changed sanders patch to fix the ff issue to be simplier, though it needs testing if this really fixes the issue 2006-09-29 12:56:01 +02:00
Anselm R. Garbe
14d05e7c72 first step to a more flexible dotile() algorithm 2006-09-29 12:38:27 +02:00
Anselm R. Garbe
a118a57fe3 renamed column into area 2006-09-28 21:29:20 +02:00
Anselm R. Garbe
02cea3b47e small change to README 2006-09-28 16:14:48 +02:00
Anselm R. Garbe
1c2d673ded applied Jukkas patch 2006-09-28 14:03:39 +02:00
Anselm R. Garbe
c34df2c1b6 Added tag 1.7.1 for changeset d5ad819f2a66a40fa75dd2e44429f3bfc884d07b 2006-09-27 17:21:25 +02:00
Anselm R. Garbe
6092aa977e fixing the settags issue, preparing 1.7.1 2006-09-27 17:18:46 +02:00
arg@zarathustra
c9cc2b385a removed an unused var 2006-09-26 17:42:14 +02:00
arg@zarathustra
b39d0c521a Added tag 1.7 for changeset 4dbdb61c8b8ce21dee5c7050a6b103855964ed20 2006-09-26 17:39:30 +02:00
arg@mmvi
e87bed6df2 updated README 2006-09-26 14:32:02 +02:00
arg@mmvi
4ee05b3294 small change 2006-09-26 14:08:42 +02:00
arg@mmvi
e81eb46a78 added slight error check to getcolor 2006-09-26 13:49:16 +02:00
arg@mmvi
f315832f75 small fix 2006-09-26 13:30:30 +02:00
arg@mmvi
97ced11e53 changed order of colordefs in config.h's, changed config.arg.h to fit to new dmenu 2006-09-26 13:24:14 +02:00
arg@mmvi
4d6c4d36ce removed useless debug info 2006-09-26 08:17:35 +02:00
arg@mmvi
b4d53bf194 added configure(), but this doesn't really fix those frking broken SDL apps 2006-09-26 07:40:19 +02:00
arg@mmvi
67bc08d1b9 slight change of event handling order 2006-09-25 21:28:00 +02:00
arg@mmvi
bcb07de750 simplified mouse resizals 2006-09-25 21:19:18 +02:00
arg@mmvi
7d7cde0fd6 applied sanders jukka patch 2006-09-25 20:38:30 +02:00
arg@mmvi
6b25d06d7d applied Jukkas patch 2006-09-25 08:21:51 +02:00
arg@mmvi
cff951c650 removed all dotile checks 2006-09-22 18:48:35 +02:00
arg@mmvi
114cc3ec02 applied Jukkas remark (dunno if this is correct though) 2006-09-22 16:35:49 +02:00
arg@mmvi
3c4b7672a8 applied jukkas patch 2006-09-22 15:39:38 +02:00
arg@mmvi
6de149eb22 man page fix 2006-09-22 14:02:41 +02:00
arg@mmvi
da909dd1e8 ismax toggling on mouse based action 2006-09-22 14:00:54 +02:00
arg@mmvi
67986e81ee hotfix 2006-09-22 13:58:21 +02:00
arg@mmvi
346bdea946 small change to achieve Jukka's last proposal 2006-09-22 13:53:28 +02:00
arg@mmvi
05c10c5776 fixed issue pointed out by Jukka 2006-09-22 11:49:24 +02:00
arg@mmvi
b2cb925d99 patched resizemouse according to sanders remark 2006-09-22 11:24:01 +02:00
arg@mmvi
9fb6502b3b small man page fix 2006-09-22 10:01:51 +02:00
arg@mmvi
9eb226ff78 sander check this 2006-09-22 09:43:21 +02:00
arg@mmvi
e34c4eaf61 slight change to config.arg.h (I use ff floating) 2006-09-22 08:22:39 +02:00
arg@mmvi
9e75bcfc75 updated man page 2006-09-22 08:17:42 +02:00
arg@mmvi
d800ec05ff implemented the maximization as I described on the mailinglist, this feels better to me. 2006-09-22 07:37:56 +02:00
arg@mmvi
bda53ac6ad reviewed client.c 2006-09-20 09:53:21 +02:00
arg@mmvi
4230932563 reviewed util.c 2006-09-20 09:49:32 +02:00
arg@mmvi
f17e898bd1 fixed a nuance in dwm.1 2006-09-20 09:45:39 +02:00
arg@mmvi
886b2088f1 improved intro comment in dwm.h, updated config.mk 2006-09-20 09:40:35 +02:00
arg@mmvi
551d6bb23d some simplifications to intro in dwm.h 2006-09-19 16:13:44 +02:00
arg@mmvi
d504005e91 Added tag 1.6 for changeset ad3fa2d185426c51fd5deceae809770363f8d33c 2006-09-16 11:21:01 +02:00
arg@mmvi
2511b5c675 added visibility check to enternotify as well 2006-09-15 14:21:25 +02:00
arg@mmvi
28aba061ec offscreen client appearance fixes 2006-09-15 10:54:32 +02:00
arg@mmvi
8e37c78ce3 focus() enforces visibility of a client if not NULL 2006-09-15 10:49:05 +02:00
Anselm R. Garbe
ca68975ff8 removed useless inclusion 2006-09-14 11:07:44 +02:00
Anselm R. Garbe
529be52fea fixed executing of dmenu output to handle args correctly 2006-09-12 19:09:04 +02:00
Anselm R. Garbe
ca65478c89 removed a bunch of lines through making function signatures more consistent with my style ( { does not belong to a new line, if function args are single-lined) 2006-09-12 10:57:28 +02:00
Anselm R. Garbe
a1e9362d38 some more simplifications of intro comment in dwm.h, this should suffice for comments in dwm 2006-09-12 09:50:06 +02:00
Anselm R. Garbe
cbfc69e310 made introduction comment in dwm.h shorter 2006-09-12 09:46:19 +02:00
Anselm R. Garbe
1d7674bb22 applied Christof Musik's multihead patch for a pathologic cornercase 2006-09-12 08:27:11 +02:00
Anselm R. Garbe
e6cc22396a added a general comment to dwm.h how dwm is basically organized 2006-09-12 08:14:22 +02:00
Anselm R. Garbe
868159fd0a some other simplifications 2006-09-11 17:31:21 +02:00
Anselm R. Garbe
b597fa4637 fixed some other comments, now also the code side seems to be at a level to be reviewed by experienced programmers 2006-09-11 11:28:28 +02:00
Anselm R. Garbe
d2d394eccf small change to comments, renamed two set* functions in client.c into update* 2006-09-11 10:00:56 +02:00
Anselm R. Garbe
438beeabde small fix 2006-09-11 08:58:58 +02:00
Anselm R. Garbe
281f0981a6 added some comments 2006-09-11 07:40:41 +02:00
Anselm R. Garbe
6ff346bed9 Added tag 1.5 for changeset 728c9089b079721b43c3347124639a29baa22a97 2006-09-08 08:32:08 +02:00
Anselm R. Garbe
0925dd588c applied sanders patch of not manipulating sel 2006-09-08 08:19:54 +02:00
Anselm R. Garbe
6f20315dff really small changes to dwm.1 2006-09-08 07:40:16 +02:00
Anselm R. Garbe
2e68f22118 hotfix 2006-09-07 18:13:19 +02:00
Anselm R. Garbe
8aa860d270 simplified unmanage 2006-09-07 18:12:40 +02:00
Anselm R. Garbe
15abade272 using a global stack for focus recovery on arrange() - seems to work great 2006-09-07 17:53:40 +02:00
Anselm R. Garbe
7ab8c87281 made markups in dwm.1 more consistent 2006-09-07 09:26:01 +02:00
Anselm R. Garbe
4ff8f71643 small addition to dwm.1 2006-09-07 07:53:29 +02:00
Anselm R. Garbe
d22abeee86 this patch keeps track of global z-layer order of clients which are floating or if floating mode is enabled 2006-09-06 17:31:52 +02:00
Anselm R. Garbe
a33150eb4b no this is better 2006-09-06 15:36:42 +02:00
Anselm R. Garbe
fd00b3a186 does this preserve z order for anthony? 2006-09-06 15:30:28 +02:00
Anselm R. Garbe
e8389a4cc0 maybe this might work 2006-09-06 13:56:46 +02:00
Anselm R. Garbe
6078d756bc Added tag 1.4 for changeset 3cff9403766bf83a9fc2a0aef230115d68de2a8e 2006-09-06 12:19:07 +02:00
Anselm R. Garbe
57c49fe867 prepared dwm-1.4 update 2006-09-06 12:18:57 +02:00
Anselm R. Garbe
c60de1acd4 drawstatus even if no client exists 2006-09-06 12:10:43 +02:00
Anselm R. Garbe
69b738c097 sanders solution is convincing and elegant 2006-09-06 11:54:16 +02:00
Anselm R. Garbe
da0b2a2f31 seems to preserve floating client z-layer order (even with reorder() calls) 2006-09-06 11:46:35 +02:00
Anselm R. Garbe
2378a558a2 Added tag 1.4 for changeset a6b8994af16491220db0199623bd57d061e06143 2006-09-06 10:54:10 +02:00
Anselm R. Garbe
f18ed615ae small fix 2006-09-06 10:03:21 +02:00
Anselm R. Garbe
f6656fffb4 made args mode symbols the default ones (the default ones look too ugly) 2006-09-06 09:23:34 +02:00
Anselm R. Garbe
aaad7bfd15 moved transient_for tag inheritance to settags 2006-09-06 09:21:17 +02:00
Anselm R. Garbe
0915da8842 no, reodering floating clients definately breaks the manage() policy which attaches all clients zoomed (otherwise higher-weight clients couldn't be attached zoomed, which sucks) 2006-09-06 09:13:31 +02:00
Anselm R. Garbe
0d0e8bde13 no, ordering floating clients at the end seems better 2006-09-05 19:26:34 +02:00
Anselm R. Garbe
838a1ff950 fix 2006-09-05 18:43:15 +02:00
Anselm R. Garbe
e1315fd40c this makes sure the issue mentioned by sander 2006-09-05 18:04:22 +02:00
Anselm R. Garbe
52a3ab1042 fixing zoom 2006-09-05 17:10:48 +02:00
Anselm R. Garbe
a82e7b765e fixing two off-by-ones 2006-09-05 16:11:52 +02:00
Anselm R. Garbe
0ed0fa4d5b ach ich will auch Alt-s 2006-09-05 16:05:09 +02:00
Anselm R. Garbe
ec85fddb9a applied checking existance of >2 tiles patch (proposed by sander) to zoom and resizecol 2006-09-05 16:00:09 +02:00
Anselm R. Garbe
3a1343a245 renamed resizetile into resizecol 2006-09-05 13:52:23 +02:00
Anselm R. Garbe
9066ee2eb4 well ok, added Mod-s to default bindings (however, I don't need it) 2006-09-05 13:27:43 +02:00
Anselm R. Garbe
40bd21ce63 s/growcol/resizetile/g 2006-09-05 13:25:42 +02:00
Anselm R. Garbe
4633fbec61 right, multihead issue is not involved with growcol 2006-09-05 13:21:59 +02:00
Anselm R. Garbe
25060031a5 hotfix 2006-09-05 13:20:29 +02:00
Anselm R. Garbe
c7ae6334b7 applied a fix related to Sanders remark to growcol 2006-09-05 13:19:18 +02:00
Anselm R. Garbe
eac04882b4 sanders toggletag patch is much more elegant 2006-09-05 09:37:45 +02:00
Anselm R. Garbe
6499fc4f93 I really need column growing, now pushing upstream 2006-09-05 09:02:37 +02:00
Anselm R. Garbe
04f27a5438 don't access sel in restack without checking for NULL (multihead crashing bug) 2006-09-05 08:37:34 +02:00
Anselm R. Garbe
1b3903d6e9 fixing c->weight handling 2006-09-05 08:24:00 +02:00
Anselm R. Garbe
cc05093b0d removed some useless tags 2006-09-04 19:19:37 +02:00
Anselm R. Garbe
6436dd4438 after 1.3 2006-09-04 17:52:46 +02:00
Anselm R. Garbe
26c50c780e Added tag 1.3 for changeset f5f5cbf016a94b48a8fe9c47f0736e96d166d5d4 2006-09-04 17:52:16 +02:00
16 changed files with 872 additions and 1019 deletions

28
.hgtags
View File

@@ -10,5 +10,29 @@ fae61afa861755636c4a1070694209ace8efbb6c 0.9
bbc98e77ae89a7c9232a5be0835f60ea00d8036e 1.0
44a55e6e46bf6c231780b09d919977d6f01083de 1.1
e3179ce2b90451d2807cd53b589d768412b8666b 1.2
6413ea66b1c2496cfc2173fe58df67cb965eb1da 1.3
dd44dc937e8b0a46abf1a15a333dba5304e4fe89 1.3
f5f5cbf016a94b48a8fe9c47f0736e96d166d5d4 1.3
3cff9403766bf83a9fc2a0aef230115d68de2a8e 1.4
728c9089b079721b43c3347124639a29baa22a97 1.5
ad3fa2d185426c51fd5deceae809770363f8d33c 1.6
4dbdb61c8b8ce21dee5c7050a6b103855964ed20 1.7
d5ad819f2a66a40fa75dd2e44429f3bfc884d07b 1.7.1
c71952fa3c7ca848ec38a6923b5c6d0e18fff431 1.8
a5567a0d30112822db2627a04a2e7aa3b6c38148 1.9
12deea36603da407e3f32640048846a3bd74a9ec 2.0
a2c465098a3b972bbed00feda9804b6aae1e9531 2.1
7e92f58754ae6edb3225f26d754bd89c1ff458cf 2.2
719b37b37b0df829d7cf017ac70e353088fe5849 2.3
32b246925086910d63147483160281a91a47479f 2.4
dcbbfabc8ecc5f33a6cc950584de87da1a368045 2.5
c7f84f23ec5aef29988dcdc4ec22a7352ee8f58e 2.5.1
5308dd22b6ee8e3218c81d9e7e4125f235bb5778 2.6
21951c0dfbae5af68ed77821a4d87253ee91803f 2.7
107719a9ce3bd0c79f9f1f626596eb338a276561 2.8
3a5910fac3ccb522a98aeeba7af7008530b25092 2.9
76b58d21ea98257c05565a3b9c850b9b26a32968 3.0
e1c8bef05e6e48df4f26471ea0712aa43ab9d949 3.1
4ce65f61f01b055fa6c2901c6d2527ef741aa4bf 3.2
f2cabc83a18f9b5b548159329ddd4dee904fa31f 3.2.1
d3876aa792923f9a95f7ad0c7f0134533404df35 3.2.2
0f91934037b04221ff5d1ba3a6c39c1ff26e3661 3.3
9ede7b2d2450537e750d5505789fbe63960e97e6 3.4

View File

@@ -1,7 +1,7 @@
MIT/X Consortium License
(C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
(C)opyright MMVI Sander van Dijk <a dot h dot vandijk at gmail dot com>
(C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
(C)opyright MMVI-MMVII Sander van Dijk <a dot h dot vandijk at gmail dot com>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),

View File

@@ -1,5 +1,5 @@
# dwm - dynamic window manager
# (C)opyright MMVI Anselm R. Garbe
# (C)opyright MMVI-MMVII Anselm R. Garbe
include config.mk
@@ -13,7 +13,6 @@ options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
@echo "LD = ${LD}"
.c.o:
@echo CC $<
@@ -26,8 +25,8 @@ config.h:
@cp config.default.h $@
dwm: ${OBJ}
@echo LD $@
@${LD} -o $@ ${OBJ} ${LDFLAGS}
@echo CC -o $@
@${CC} -o $@ ${OBJ} ${LDFLAGS}
@strip $@
clean:

4
README
View File

@@ -1,5 +1,5 @@
dwm - dynamic window manager
----------------------------
============================
dwm is an extremely fast, small, and dynamic window manager for X.
@@ -37,7 +37,7 @@ like this in your .xinitrc:
while true
do
echo `date` `uptime | sed 's/.*://; s/,//g'`
echo `date` `uptime | sed 's/.*,//'`
sleep 1
done | dwm

401
client.c
View File

@@ -1,5 +1,4 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
@@ -8,14 +7,20 @@
#include <X11/Xatom.h>
#include <X11/Xutil.h>
/* static functions */
/* static */
static void
grabbuttons(Client *c, Bool focus)
{
detachstack(Client *c) {
Client **tc;
for(tc=&stack; *tc && *tc != c; tc=&(*tc)->snext);
*tc = c->snext;
}
static void
grabbuttons(Client *c, Bool focused) {
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
if(focus) {
if(focused) {
XGrabButton(dpy, Button1, MODKEY, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button1, MODKEY | LockMask, c->win, False, BUTTONMASK,
@@ -46,61 +51,60 @@ grabbuttons(Client *c, Bool focus)
else
XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
}
static void
resizetitle(Client *c)
{
c->tw = textw(c->name);
if(c->tw > c->w)
c->tw = c->w + 2;
c->tx = c->x + c->w - c->tw + 2;
c->ty = c->y;
if(isvisible(c))
XMoveResizeWindow(dpy, c->twin, c->tx, c->ty, c->tw, c->th);
else
XMoveResizeWindow(dpy, c->twin, c->tx + 2 * sw, c->ty, c->tw, c->th);
setclientstate(Client *c, long state) {
long data[] = {state, None};
XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32,
PropModeReplace, (unsigned char *)data, 2);
}
static int
xerrordummy(Display *dsply, XErrorEvent *ee)
{
xerrordummy(Display *dsply, XErrorEvent *ee) {
return 0;
}
/* extern functions */
/* extern */
void
ban(Client *c)
{
XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
XMoveWindow(dpy, c->twin, c->tx + 2 * sw, c->ty);
configure(Client *c) {
XConfigureEvent ce;
ce.type = ConfigureNotify;
ce.display = dpy;
ce.event = c->win;
ce.window = c->win;
ce.x = c->x;
ce.y = c->y;
ce.width = c->w;
ce.height = c->h;
ce.border_width = c->border;
ce.above = None;
ce.override_redirect = False;
XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce);
}
void
focus(Client *c)
{
Client *old;
if(!issel)
focus(Client *c) {
if(c && !isvisible(c))
return;
if(!sel)
sel = c;
else if(sel != c) {
if(maximized)
togglemax(NULL);
old = sel;
sel = c;
if(old) {
grabbuttons(old, False);
drawtitle(old);
}
if(sel && sel != c) {
grabbuttons(sel, False);
XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]);
}
if(c) {
detachstack(c);
c->snext = stack;
stack = c;
grabbuttons(c, True);
drawtitle(c);
}
sel = c;
drawstatus();
if(!selscreen)
return;
if(c) {
XSetWindowBorder(dpy, c->win, dc.sel[ColBorder]);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
}
else
@@ -108,8 +112,7 @@ focus(Client *c)
}
Client *
getclient(Window w)
{
getclient(Window w) {
Client *c;
for(c = clients; c; c = c->next)
@@ -118,162 +121,91 @@ getclient(Window w)
return NULL;
}
Client *
getctitle(Window w)
{
Client *c;
Bool
isprotodel(Client *c) {
int i, n;
Atom *protocols;
Bool ret = False;
for(c = clients; c; c = c->next)
if(c->twin == w)
return c;
return NULL;
if(XGetWMProtocols(dpy, c->win, &protocols, &n)) {
for(i = 0; !ret && i < n; i++)
if(protocols[i] == wmatom[WMDelete])
ret = True;
XFree(protocols);
}
return ret;
}
void
gravitate(Client *c, Bool invert)
{
int dx = 0, dy = 0;
switch(c->grav) {
default:
break;
case StaticGravity:
case NorthWestGravity:
case NorthGravity:
case NorthEastGravity:
dy = c->border;
break;
case EastGravity:
case CenterGravity:
case WestGravity:
dy = -(c->h / 2) + c->border;
break;
case SouthEastGravity:
case SouthGravity:
case SouthWestGravity:
dy = -(c->h);
break;
}
switch (c->grav) {
default:
break;
case StaticGravity:
case NorthWestGravity:
case WestGravity:
case SouthWestGravity:
dx = c->border;
break;
case NorthGravity:
case CenterGravity:
case SouthGravity:
dx = -(c->w / 2) + c->border;
break;
case NorthEastGravity:
case EastGravity:
case SouthEastGravity:
dx = -(c->w + c->border);
break;
}
if(invert) {
dx = -dx;
dy = -dy;
}
c->x += dx;
c->y += dy;
}
void
killclient(Arg *arg)
{
killclient(Arg *arg) {
if(!sel)
return;
if(sel->proto & PROTODELWIN)
if(isprotodel(sel))
sendevent(sel->win, wmatom[WMProtocols], wmatom[WMDelete]);
else
XKillClient(dpy, sel->win);
}
void
manage(Window w, XWindowAttributes *wa)
{
unsigned int i;
Client *c, *tc;
manage(Window w, XWindowAttributes *wa) {
Client *c, *t;
Window trans;
XSetWindowAttributes twa;
c = emallocz(sizeof(Client));
c->tags = emallocz(ntags * sizeof(Bool));
c->win = w;
c->x = c->tx = wa->x;
c->y = c->ty = wa->y;
c->w = c->tw = wa->width;
c->x = wa->x;
c->y = wa->y;
c->w = wa->width;
c->h = wa->height;
c->th = bh;
c->border = 0;
setsize(c);
if(c->x + c->w + 2 > sw)
c->x = sw - c->w - 2;
if(c->x < 0)
c->x = 0;
if(c->y + c->h + 2 > sh)
c->y = sh - c->h - 2;
if(c->h != sh && c->y < bh)
c->y = bh;
c->proto = getproto(c->win);
if(c->w == sw && c->h == sh) {
c->border = 0;
c->x = sx;
c->y = sy;
}
else {
c->border = BORDERPX;
if(c->x + c->w + 2 * c->border > wax + waw)
c->x = wax + waw - c->w - 2 * c->border;
if(c->y + c->h + 2 * c->border > way + wah)
c->y = way + wah - c->h - 2 * c->border;
if(c->x < wax)
c->x = wax;
if(c->y < way)
c->y = way;
}
updatesizehints(c);
XSelectInput(dpy, c->win,
StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
XGetTransientForHint(dpy, c->win, &trans);
twa.override_redirect = 1;
twa.background_pixmap = ParentRelative;
twa.event_mask = ExposureMask | EnterWindowMask;
c->twin = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th,
0, DefaultDepth(dpy, screen), CopyFromParent,
DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
grabbuttons(c, False);
if((tc = getclient(trans))) /* inherit tags */
for(i = 0; i < ntags; i++)
c->tags[i] = tc->tags[i];
else
settags(c);
XSetWindowBorder(dpy, c->win, dc.norm[ColBorder]);
updatetitle(c);
t = getclient(trans);
settags(c, t);
if(!c->isfloat)
c->isfloat = trans
|| (c->maxw && c->minw &&
c->maxw == c->minw && c->maxh == c->minh);
c->isfloat = (t != 0) || c->isfixed;
if(clients)
clients->prev = c;
c->next = clients;
clients = c;
settitle(c);
ban(c);
c->snext = stack;
stack = clients = c;
XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
XMapWindow(dpy, c->win);
XMapWindow(dpy, c->twin);
setclientstate(c, NormalState);
if(isvisible(c))
focus(c);
arrange(NULL);
arrange();
}
void
resize(Client *c, Bool sizehints, Corner sticky)
{
int bottom = c->y + c->h;
int right = c->x + c->w;
resize(Client *c, Bool sizehints) {
float actual, dx, dy, max, min;
XWindowChanges wc;
if(c->w <= 0 || c->h <= 0)
return;
if(sizehints) {
if(c->incw)
c->w -= (c->w - c->basew) % c->incw;
if(c->inch)
c->h -= (c->h - c->baseh) % c->inch;
if(c->minw && c->w < c->minw)
c->w = c->minw;
if(c->minh && c->h < c->minh)
@@ -282,28 +214,58 @@ resize(Client *c, Bool sizehints, Corner sticky)
c->w = c->maxw;
if(c->maxh && c->h > c->maxh)
c->h = c->maxh;
/* inspired by algorithm from fluxbox */
if(c->minay > 0 && c->maxay && (c->h - c->baseh) > 0) {
dx = (float)(c->w - c->basew);
dy = (float)(c->h - c->baseh);
min = (float)(c->minax) / (float)(c->minay);
max = (float)(c->maxax) / (float)(c->maxay);
actual = dx / dy;
if(max > 0 && min > 0 && actual > 0) {
if(actual < min) {
dy = (dx * min + dy) / (min * min + 1);
dx = dy * min;
c->w = (int)dx + c->basew;
c->h = (int)dy + c->baseh;
}
else if(actual > max) {
dy = (dx * min + dy) / (max * max + 1);
dx = dy * min;
c->w = (int)dx + c->basew;
c->h = (int)dy + c->baseh;
}
}
}
if(c->incw)
c->w -= (c->w - c->basew) % c->incw;
if(c->inch)
c->h -= (c->h - c->baseh) % c->inch;
}
if(sticky == TopRight || sticky == BotRight)
c->x = right - c->w;
if(sticky == BotLeft || sticky == BotRight)
c->y = bottom - c->h;
resizetitle(c);
if(c->w == sw && c->h == sh)
c->border = 0;
else
c->border = BORDERPX;
/* offscreen appearance fixes */
if(c->x > sw)
c->x = sw - c->w - 2 * c->border;
if(c->y > sh)
c->y = sh - c->h - 2 * c->border;
if(c->x + c->w + 2 * c->border < sx)
c->x = sx;
if(c->y + c->h + 2 * c->border < sy)
c->y = sy;
wc.x = c->x;
wc.y = c->y;
wc.width = c->w;
wc.height = c->h;
if(c->w == sw && c->h == sh)
wc.border_width = 0;
else
wc.border_width = 1;
XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
wc.border_width = c->border;
XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight | CWBorderWidth, &wc);
configure(c);
XSync(dpy, False);
}
void
setsize(Client *c)
{
updatesizehints(Client *c) {
long msize;
XSizeHints size;
@@ -334,15 +296,20 @@ setsize(Client *c)
}
else
c->minw = c->minh = 0;
if(c->flags & PWinGravity)
c->grav = size.win_gravity;
if(c->flags & PAspect) {
c->minax = size.min_aspect.x;
c->minay = size.min_aspect.y;
c->maxax = size.max_aspect.x;
c->maxay = size.max_aspect.y;
}
else
c->grav = NorthWestGravity;
c->minax = c->minay = c->maxax = c->maxay = 0;
c->isfixed = (c->maxw && c->minw && c->maxh && c->minh
&& c->maxw == c->minw && c->maxh == c->minh);
}
void
settitle(Client *c)
{
updatetitle(Client *c) {
char **list = NULL;
int n;
XTextProperty name;
@@ -355,81 +322,37 @@ settitle(Client *c)
if(!name.nitems)
return;
if(name.encoding == XA_STRING)
strncpy(c->name, (char *)name.value, sizeof(c->name));
strncpy(c->name, (char *)name.value, sizeof c->name);
else {
if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
&& n > 0 && *list)
&& n > 0 && *list)
{
strncpy(c->name, *list, sizeof(c->name));
strncpy(c->name, *list, sizeof c->name);
XFreeStringList(list);
}
}
XFree(name.value);
resizetitle(c);
}
void
togglemax(Arg *arg)
{
int ox, oy, ow, oh;
Client *c;
XEvent ev;
unmanage(Client *c) {
Client *nc;
if(!sel)
return;
if((maximized = !maximized)) {
ox = sel->x;
oy = sel->y;
ow = sel->w;
oh = sel->h;
sel->x = sx;
sel->y = sy + bh;
sel->w = sw - 2;
sel->h = sh - 2 - bh;
restack();
for(c = getnext(clients); c; c = getnext(c->next))
if(c != sel)
ban(c);
resize(sel, arrange == dofloat, TopLeft);
sel->x = ox;
sel->y = oy;
sel->w = ow;
sel->h = oh;
}
else
arrange(NULL);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}
void
unmanage(Client *c)
{
Client *tc, *fc;
Window trans;
/* The server grab construct avoids race conditions. */
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
detach(c);
detachstack(c);
if(sel == c) {
XGetTransientForHint(dpy, c->win, &trans);
if(trans && (tc = getclient(trans)) && isvisible(tc))
fc = tc;
else
fc = getnext(clients);
focus(fc);
for(nc = stack; nc && !isvisible(nc); nc = nc->snext);
focus(nc);
}
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
XDestroyWindow(dpy, c->twin);
setclientstate(c, WithdrawnState);
free(c->tags);
free(c);
XSync(dpy, False);
XSetErrorHandler(xerror);
XUngrabServer(dpy);
arrange(NULL);
arrange();
}

View File

@@ -1,66 +1,94 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#define TAGS \
const char *tags[] = { "dev", "work", "net", "fnord", NULL };
const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
#define DEFMODE dotile /* dofloat */
#define BORDERPX 1
#define DEFMODE dotile /* dofloat */
#define FLOATSYMBOL "><>"
#define TILESYMBOL "[]="
#define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*"
#define SELBGCOLOR "#333366"
#define SELFGCOLOR "#eeeeee"
#define NORMBGCOLOR "#333333"
#define NORMFGCOLOR "#dddddd"
#define STATUSBGCOLOR "#222222"
#define STATUSFGCOLOR "#9999cc"
#define FONT "-*-terminus-medium-r-*-*-14-*-*-*-*-*-*-*"
#define NORMBORDERCOLOR "#333"
#define NORMBGCOLOR "#222"
#define NORMFGCOLOR "#ccc"
#define SELBORDERCOLOR "#69c"
#define SELBGCOLOR "#555"
#define SELFGCOLOR "#fff"
#define MASTER 600 /* per thousand */
#define MODKEY Mod1Mask
#define MASTERW 60 /* percent */
#define NMASTER 1 /* clients in master area */
#define SNAP 40 /* pixel */
#define TOPBAR True /* False */
#define KEYS \
static Key key[] = { \
/* modifier key function arguments */ \
/* modifier key function argument */ \
{ MODKEY|ShiftMask, XK_Return, spawn, \
{ .cmd = "exec uxterm -bg '#111111' -fg '#eeeeee' -cr '#eeeeee' +sb -fn '"FONT"'" } }, \
{ .cmd = "exec uxterm -bg '#222' -fg '#eee' -cr '#eee' +sb -fn '"FONT"'" } }, \
{ MODKEY, XK_p, spawn, \
{ .cmd = "exe=\"$(IFS=:; for dir in $PATH; do " \
"for file in \"$dir\"/*; do [ -x \"$file\" ] && echo \"${file##*/}\"; done; " \
"done | sort -u | dmenu)\" && exec \"$exe\"" } }, \
{ .cmd = "exe=\"$(lsx `echo $PATH | sed 's/:/ /g'` | sort -u " \
" | dmenu -fn '"FONT"' -nb '"NORMBGCOLOR"' -nf '"NORMFGCOLOR"' " \
"-sb '"SELBGCOLOR"' -sf '"SELFGCOLOR"')\" && exec $exe" } }, \
{ MODKEY, XK_j, focusnext, { 0 } }, \
{ MODKEY, XK_k, focusprev, { 0 } }, \
{ MODKEY, XK_Return, zoom, { 0 } }, \
{ MODKEY, XK_m, togglemax, { 0 } }, \
{ MODKEY, XK_g, resizemaster, { .i = 15 } }, \
{ MODKEY, XK_s, resizemaster, { .i = -15 } }, \
{ MODKEY, XK_i, incnmaster, { .i = 1 } }, \
{ MODKEY, XK_d, incnmaster, { .i = -1 } }, \
{ MODKEY|ShiftMask, XK_0, tag, { .i = -1 } }, \
{ MODKEY|ShiftMask, XK_1, tag, { .i = 0 } }, \
{ MODKEY|ShiftMask, XK_2, tag, { .i = 1 } }, \
{ MODKEY|ShiftMask, XK_3, tag, { .i = 2 } }, \
{ MODKEY|ShiftMask, XK_4, tag, { .i = 3 } }, \
{ MODKEY|ShiftMask, XK_5, tag, { .i = 4 } }, \
{ MODKEY|ShiftMask, XK_6, tag, { .i = 5 } }, \
{ MODKEY|ShiftMask, XK_7, tag, { .i = 6 } }, \
{ MODKEY|ShiftMask, XK_8, tag, { .i = 7 } }, \
{ MODKEY|ShiftMask, XK_9, tag, { .i = 8 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_1, toggletag, { .i = 0 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_2, toggletag, { .i = 1 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_3, toggletag, { .i = 2 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_4, toggletag, { .i = 3 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_5, toggletag, { .i = 4 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_6, toggletag, { .i = 5 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_7, toggletag, { .i = 6 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_8, toggletag, { .i = 7 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_9, toggletag, { .i = 8 } }, \
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \
{ MODKEY, XK_space, togglemode, { 0 } }, \
{ MODKEY, XK_0, viewall, { 0 } }, \
{ MODKEY|ShiftMask, XK_space, togglefloat, { 0 } }, \
{ MODKEY, XK_0, view, { .i = -1 } }, \
{ MODKEY, XK_1, view, { .i = 0 } }, \
{ MODKEY, XK_2, view, { .i = 1 } }, \
{ MODKEY, XK_3, view, { .i = 2 } }, \
{ MODKEY, XK_4, view, { .i = 3 } }, \
{ MODKEY, XK_5, view, { .i = 4 } }, \
{ MODKEY, XK_6, view, { .i = 5 } }, \
{ MODKEY, XK_7, view, { .i = 6 } }, \
{ MODKEY, XK_8, view, { .i = 7 } }, \
{ MODKEY, XK_9, view, { .i = 8 } }, \
{ MODKEY|ControlMask, XK_1, toggleview, { .i = 0 } }, \
{ MODKEY|ControlMask, XK_2, toggleview, { .i = 1 } }, \
{ MODKEY|ControlMask, XK_3, toggleview, { .i = 2 } }, \
{ MODKEY|ControlMask, XK_4, toggleview, { .i = 3 } }, \
{ MODKEY|ControlMask, XK_5, toggleview, { .i = 4 } }, \
{ MODKEY|ControlMask, XK_6, toggleview, { .i = 5 } }, \
{ MODKEY|ControlMask, XK_7, toggleview, { .i = 6 } }, \
{ MODKEY|ControlMask, XK_8, toggleview, { .i = 7 } }, \
{ MODKEY|ControlMask, XK_9, toggleview, { .i = 8 } }, \
{ MODKEY|ShiftMask, XK_q, quit, { 0 } }, \
};
#define RULES \
static Rule rule[] = { \
/* class:instance:title regex tags regex isfloat */ \
{ "Firefox.*", "net", False }, \
{ "Gimp.*", NULL, True}, \
{ "MPlayer.*", NULL, True}, \
{ "Acroread.*", NULL, True}, \
{ "Firefox", "3", False }, \
{ "Gimp", NULL, True }, \
{ "MPlayer", NULL, True }, \
{ "Acroread", NULL, True }, \
};

View File

@@ -1,57 +1,81 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#define TAGS \
const char *tags[] = { "1", "2", "3", "4", "5", NULL };
const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
#define DEFMODE dotile /* dofloat */
#define FLOATSYMBOL "~"
#define TILESYMBOL "#"
#define BORDERPX 1
#define DEFMODE dotile /* dofloat */
#define FLOATSYMBOL "><>"
#define TILESYMBOL "[]="
#define FONT "fixed"
#define SELBGCOLOR "#666699"
#define SELFGCOLOR "#eeeeee"
#define NORMBGCOLOR "#333366"
#define NORMFGCOLOR "#cccccc"
#define STATUSBGCOLOR "#dddddd"
#define STATUSFGCOLOR "#222222"
#define FONT "-*-fixed-medium-r-normal-*-13-*-*-*-*-*-*-*"
#define NORMBORDERCOLOR "#dddddd"
#define NORMBGCOLOR "#eeeeee"
#define NORMFGCOLOR "#222222"
#define SELBORDERCOLOR "#ff0000"
#define SELBGCOLOR "#006699"
#define SELFGCOLOR "#ffffff"
#define MASTER 600 /* per thousand */
#define MODKEY Mod1Mask
#define MASTERW 60 /* percent */
#define NMASTER 1 /* clients in master area */
#define SNAP 20 /* pixel */
#define TOPBAR True /* False */
#define KEYS \
static Key key[] = { \
/* modifier key function arguments */ \
/* modifier key function argument */ \
{ MODKEY|ShiftMask, XK_Return, spawn, { .cmd = "exec xterm" } }, \
{ MODKEY, XK_Tab, focusnext, { 0 } }, \
{ MODKEY|ShiftMask, XK_Tab, focusprev, { 0 } }, \
{ MODKEY, XK_Return, zoom, { 0 } }, \
{ MODKEY, XK_m, togglemax, { 0 } }, \
{ MODKEY, XK_g, resizemaster, { .i = 15 } }, \
{ MODKEY, XK_s, resizemaster, { .i = -15 } }, \
{ MODKEY, XK_i, incnmaster, { .i = 1 } }, \
{ MODKEY, XK_d, incnmaster, { .i = -1 } }, \
{ MODKEY|ShiftMask, XK_0, tag, { .i = -1 } }, \
{ MODKEY|ShiftMask, XK_1, tag, { .i = 0 } }, \
{ MODKEY|ShiftMask, XK_2, tag, { .i = 1 } }, \
{ MODKEY|ShiftMask, XK_3, tag, { .i = 2 } }, \
{ MODKEY|ShiftMask, XK_4, tag, { .i = 3 } }, \
{ MODKEY|ShiftMask, XK_5, tag, { .i = 4 } }, \
{ MODKEY|ShiftMask, XK_6, tag, { .i = 5 } }, \
{ MODKEY|ShiftMask, XK_7, tag, { .i = 6 } }, \
{ MODKEY|ShiftMask, XK_8, tag, { .i = 7 } }, \
{ MODKEY|ShiftMask, XK_9, tag, { .i = 8 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_1, toggletag, { .i = 0 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_2, toggletag, { .i = 1 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_3, toggletag, { .i = 2 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_4, toggletag, { .i = 3 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_5, toggletag, { .i = 4 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_6, toggletag, { .i = 5 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_7, toggletag, { .i = 6 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_8, toggletag, { .i = 7 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_9, toggletag, { .i = 8 } }, \
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \
{ MODKEY, XK_space, togglemode, { 0 } }, \
{ MODKEY, XK_0, viewall, { 0 } }, \
{ MODKEY|ShiftMask, XK_space, togglefloat, { 0 } }, \
{ MODKEY, XK_0, view, { .i = -1 } }, \
{ MODKEY, XK_1, view, { .i = 0 } }, \
{ MODKEY, XK_2, view, { .i = 1 } }, \
{ MODKEY, XK_3, view, { .i = 2 } }, \
{ MODKEY, XK_4, view, { .i = 3 } }, \
{ MODKEY, XK_5, view, { .i = 4 } }, \
{ MODKEY, XK_6, view, { .i = 5 } }, \
{ MODKEY, XK_7, view, { .i = 6 } }, \
{ MODKEY, XK_8, view, { .i = 7 } }, \
{ MODKEY, XK_9, view, { .i = 8 } }, \
{ MODKEY|ControlMask, XK_1, toggleview, { .i = 0 } }, \
{ MODKEY|ControlMask, XK_2, toggleview, { .i = 1 } }, \
{ MODKEY|ControlMask, XK_3, toggleview, { .i = 2 } }, \
{ MODKEY|ControlMask, XK_4, toggleview, { .i = 3 } }, \
{ MODKEY|ControlMask, XK_5, toggleview, { .i = 4 } }, \
{ MODKEY|ControlMask, XK_6, toggleview, { .i = 5 } }, \
{ MODKEY|ControlMask, XK_7, toggleview, { .i = 6 } }, \
{ MODKEY|ControlMask, XK_8, toggleview, { .i = 7 } }, \
{ MODKEY|ControlMask, XK_9, toggleview, { .i = 8 } }, \
{ MODKEY|ShiftMask, XK_q, quit, { 0 } }, \
};
@@ -60,6 +84,7 @@ static Key key[] = { \
#define RULES \
static Rule rule[] = { \
/* class:instance:title regex tags regex isfloat */ \
{ "Firefox.*", "2", False }, \
{ "Gimp.*", NULL, True}, \
{ "Gimp", NULL, True }, \
{ "MPlayer", NULL, True }, \
{ "Acroread", NULL, True }, \
};

View File

@@ -1,5 +1,5 @@
# dwm version
VERSION = 1.3
VERSION = 3.5
# Customize below to fit your system
@@ -20,6 +20,10 @@ LDFLAGS = ${LIBS}
#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = -g ${LIBS}
# Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = ${LIBS}
#CFLAGS += -xtarget=ultra
# compiler and linker
CC = cc
LD = ${CC}

124
draw.c
View File

@@ -1,17 +1,24 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVII Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
#include <stdio.h>
#include <string.h>
#include <X11/Xlocale.h>
/* static */
static unsigned int
textnw(const char *text, unsigned int len)
static Bool
isoccupied(unsigned int t)
{
Client *c;
for(c = clients; c; c = c->next)
if(c->tags[t])
return True;
return False;
}
static unsigned int
textnw(const char *text, unsigned int len) {
XRectangle r;
if(dc.font.set) {
@@ -22,8 +29,7 @@ textnw(const char *text, unsigned int len)
}
static void
drawtext(const char *text, unsigned long col[ColLast], Bool highlight)
{
drawtext(const char *text, unsigned long col[ColLast], Bool filledsquare, Bool emptysquare) {
int x, y, w, h;
static char buf[256];
unsigned int len, olen;
@@ -32,21 +38,17 @@ drawtext(const char *text, unsigned long col[ColLast], Bool highlight)
XSetForeground(dpy, dc.gc, col[ColBG]);
XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
if(!text)
return;
w = 0;
olen = len = strlen(text);
if(len >= sizeof(buf))
len = sizeof(buf) - 1;
if(len >= sizeof buf)
len = sizeof buf - 1;
memcpy(buf, text, len);
buf[len] = 0;
h = dc.font.ascent + dc.font.descent;
y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
x = dc.x + (h / 2);
/* shorten text if necessary */
while(len && (w = textnw(buf, len)) > dc.w - h)
buf[--len] = 0;
@@ -58,7 +60,6 @@ drawtext(const char *text, unsigned long col[ColLast], Bool highlight)
if(len > 3)
buf[len - 3] = '.';
}
if(w > dc.w)
return; /* too long */
gcv.foreground = col[ColFG];
@@ -71,102 +72,68 @@ drawtext(const char *text, unsigned long col[ColLast], Bool highlight)
XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv);
XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
}
if(highlight) {
r.x = dc.x + 2;
r.y = dc.y + 2;
r.width = r.height = 3;
x = (h + 2) / 4;
r.x = dc.x + 1;
r.y = dc.y + 1;
if(filledsquare) {
r.width = r.height = x + 1;
XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
}
else if(emptysquare) {
r.width = r.height = x;
XDrawRectangles(dpy, dc.drawable, dc.gc, &r, 1);
}
}
/* extern */
void
drawall()
{
Client *c;
for(c = clients; c; c = getnext(c->next))
drawtitle(c);
drawstatus();
}
void
drawstatus()
{
drawstatus(void) {
int i, x;
dc.x = dc.y = 0;
for(i = 0; i < ntags; i++) {
dc.w = textw(tags[i]);
if(seltag[i])
drawtext(tags[i], dc.sel, sel && sel->tags[i]);
drawtext(tags[i], dc.sel, sel && sel->tags[i], isoccupied(i));
else
drawtext(tags[i], dc.norm, sel && sel->tags[i]);
drawtext(tags[i], dc.norm, sel && sel->tags[i], isoccupied(i));
dc.x += dc.w;
}
dc.w = bmw;
drawtext(arrange == dotile ? TILESYMBOL : FLOATSYMBOL, dc.status, False);
drawtext(arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, dc.norm, False, False);
x = dc.x + dc.w;
dc.w = textw(stext);
dc.x = bx + bw - dc.w;
dc.x = sw - dc.w;
if(dc.x < x) {
dc.x = x;
dc.w = bw - x;
dc.w = sw - x;
}
drawtext(stext, dc.status, False);
drawtext(stext, dc.norm, False, False);
if((dc.w = dc.x - x) > bh) {
dc.x = x;
if(sel)
drawtext(sel->name, dc.sel, False);
else
drawtext(NULL, dc.norm, False);
drawtext(sel ? sel->name : NULL, sel ? dc.sel : dc.norm, False, False);
}
XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
XSync(dpy, False);
}
void
drawtitle(Client *c)
{
if(c == sel && issel) {
drawstatus();
XUnmapWindow(dpy, c->twin);
XSetWindowBorder(dpy, c->win, dc.sel[ColBG]);
return;
}
XSetWindowBorder(dpy, c->win, dc.norm[ColBG]);
XMapWindow(dpy, c->twin);
dc.x = dc.y = 0;
dc.w = c->tw;
drawtext(c->name, dc.norm, False);
XCopyArea(dpy, dc.drawable, c->twin, dc.gc, 0, 0, c->tw, c->th, 0, 0);
XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, sw, bh, 0, 0);
XSync(dpy, False);
}
unsigned long
getcolor(const char *colstr)
{
getcolor(const char *colstr) {
Colormap cmap = DefaultColormap(dpy, screen);
XColor color;
XAllocNamedColor(dpy, cmap, colstr, &color, &color);
if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
eprint("error, cannot allocate color '%s'\n", colstr);
return color.pixel;
}
void
setfont(const char *fontstr)
{
char **missing, *def;
setfont(const char *fontstr) {
char *def, **missing;
int i, n;
missing = NULL;
setlocale(LC_ALL, "");
if(dc.font.set)
XFreeFontSet(dpy, dc.font.set);
dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
@@ -174,16 +141,11 @@ setfont(const char *fontstr)
while(n--)
fprintf(stderr, "missing fontset: %s\n", missing[n]);
XFreeStringList(missing);
if(dc.font.set) {
XFreeFontSet(dpy, dc.font.set);
dc.font.set = NULL;
}
}
if(dc.font.set) {
XFontSetExtents *font_extents;
XFontStruct **xfonts;
char **font_names;
dc.font.ascent = dc.font.descent = 0;
font_extents = XExtentsOfFontSet(dc.font.set);
n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
@@ -199,11 +161,8 @@ setfont(const char *fontstr)
if(dc.font.xfont)
XFreeFont(dpy, dc.font.xfont);
dc.font.xfont = NULL;
dc.font.xfont = XLoadQueryFont(dpy, fontstr);
if (!dc.font.xfont)
dc.font.xfont = XLoadQueryFont(dpy, "fixed");
if (!dc.font.xfont)
eprint("error, cannot init 'fixed' font\n");
if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)))
eprint("error, cannot load font: '%s'\n", fontstr);
dc.font.ascent = dc.font.xfont->ascent;
dc.font.descent = dc.font.xfont->descent;
}
@@ -211,7 +170,6 @@ setfont(const char *fontstr)
}
unsigned int
textw(const char *text)
{
textw(const char *text) {
return textnw(text, strlen(text)) + dc.font.height;
}

174
dwm.1
View File

@@ -5,29 +5,27 @@ dwm \- dynamic window manager
.B dwm
.RB [ \-v ]
.SH DESCRIPTION
.B dwm
is a dynamic window manager for X. It manages windows in tiling and floating
modes. Either mode can be applied dynamically, optimizing the environment for
the application in use and the task performed.
dwm is a dynamic window manager for X. It manages windows in tiling and
floating modes. Either mode can be applied dynamically, optimizing the
environment for the application in use and the task performed.
.P
In tiling mode windows are managed in a master and stacking column. The master
column contains the window which currently needs most attention, whereas the
stacking column contains all other windows. In floating mode windows can be
In tiling mode windows are managed in a master and stacking area. The master
area contains the windows which currently need most attention, whereas the
stacking area contains all other windows. In floating mode windows can be
resized and moved freely. Dialog windows are always managed floating,
regardless of the mode selected.
regardless of the mode applied.
.P
Windows are grouped by tags. Each window can be tagged with one or multiple
tags. Selecting a certain tag for viewing will display all windows with that
tag.
tags. Selecting certain tags displays all windows with these tags.
.P
.B dwm
contains a small status bar which displays all available tags, the mode, the
title of the focused window, and the text read from standard input. The tags of
the focused window are highlighted with a small point.
dwm contains a small status bar which displays all available tags, the mode,
the title of the focused window, and the text read from standard input. The
selected tags are indicated with a different color. The tags of the focused
window are indicated with a filled square in the top left corner. The tags
which are applied to one or more windows are indicated with an empty square in
the top left corner.
.P
.B dwm
draws a 1-pixel border around windows to indicate the focus state.
Unfocused windows contain a small bar in front of them displaying their title.
dwm draws a small border around windows to indicate the focus state.
.SH OPTIONS
.TP
.B \-v
@@ -39,30 +37,23 @@ prints version information to standard output, then exits.
is read and displayed in the status text area.
.TP
.B Button1
click on a tag label views all windows with that
.BR tag ,
click on the mode label toggles between
.B tiled
and
.B floating
mode.
click on a tag label to display all windows with that tag, click on the mode
label toggles between tiling and floating mode.
.TP
.B Button3
click on a tag label adds/removes all windows with that
.B tag
to/from the view.
click on a tag label adds/removes all windows with that tag to/from the view.
.TP
.B Button4
click on the mode label increases the number of windows in the master area (tiling mode only).
.TP
.B Button5
click on the mode label decreases the number of windows in the master area (tiling mode only).
.TP
.B Mod1-Button1
click on a tag label applies that
.B tag
to the focused
.BR window .
click on a tag label applies that tag to the focused window.
.TP
.B Mod1-Button3
click on a tag label adds/removes that
.B tag
to/from the focused
.BR window .
click on a tag label adds/removes that tag to/from the focused window.
.SS Keyboard commands
.TP
.B Mod1-Shift-Return
@@ -70,102 +61,89 @@ Start
.BR xterm (1).
.TP
.B Mod1-Tab
Focus next
.BR window .
Focus next window.
.TP
.B Mod1-Shift-Tab
Focus previous
.BR window .
Focus previous window.
.TP
.B Mod1-Return
Zoom current
.B window
to the
.B master
column
.RB ( tiling
mode only).
Zooms/cycles current window to/from master area (tiling mode), toggles maximization of current window (floating mode).
.TP
.B Mod1-m
Maximize current
.BR window .
.B Mod1-g
Grow master area (tiling mode only).
.TP
.B Mod1-s
Shrink master area (tiling mode only).
.TP
.B Mod1-i
Increase the number of windows in the master area (tiling mode only).
.TP
.B Mod1-d
Decrease the number of windows in the master area (tiling mode only).
.TP
.B Mod1-Shift-[1..n]
Apply
.B nth tag
to current
.BR window .
.RB nth
tag to current window.
.TP
.B Mod1-Shift-0
Apply all tags to current window.
.TP
.B Mod1-Control-Shift-[1..n]
Add/remove
.B nth tag
to/from current
.BR window .
.B nth
tag to/from current window.
.TP
.B Mod1-Shift-c
Close focused
.B window.
Close focused window.
.TP
.B Mod1-space
Toggle between
.B tiled
and
.B floating
mode (affects
.BR "all windows" ).
Toggle between tiling and floating mode (affects all windows).
.TP
.B Mod1-Shift-space
Toggle focused window between floating and non-floating state (tiling mode only).
.TP
.B Mod1-[1..n]
View all windows with
.BR "tag n" .
.BR nth
tag.
.TP
.B Mod1-0
View all windows with any
.BR "tag" .
View all windows with any tag.
.TP
.B Mod1-Control-[1..n]
Add/remove all windows with
.B tag n
to/from the view.
.BR nth
tag to/from the view.
.TP
.B Mod1-Shift-q
Quit
.B dwm.
Quit dwm.
.SS Mouse commands
.TP
.B Mod1-Button1
Move current
.B window
while dragging
.RB ( floating
mode only).
Move current window while dragging (floating mode only).
.TP
.B Mod1-Button2
Zoom current
.B window
to the
.B master
column
.RB ( tiling
mode only).
Zooms/cycles current window to/from master area (tiling mode), toggles maximization of current window (floating mode).
.TP
.B Mod1-Button3
Resize current
.B window
while dragging
.RB ( floating
mode only).
Resize current window while dragging (floating mode only).
.SH CUSTOMIZATION
.B dwm
is customized by creating a custom config.h and (re)compiling the source
dwm is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple.
.SH CAVEATS
The status bar may display
.B broken pipe
when
.B dwm
has been started by
.BR xdm (1),
because it closes standard output before executing
.BR dwm .
.SH SEE ALSO
.BR dmenu (1)
.SH BUGS
The status bar may display
.BR "EOF"
when dwm has been started by an X session manager like
.BR xdm (1),
because those close standard output before executing dwm.
.P
Java applications which use the XToolkit/XAWT backend may draw grey windows
only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early
JDK 1.6 versions, because it assumes a reparenting window manager. As a workaround
you can use JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or you
can set the following environment variable (to use the older Motif
backend instead):
.BR AWT_TOOLKIT=MToolkit .

179
dwm.h
View File

@@ -1,6 +1,34 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*
* 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
* manager selects for SubstructureRedirectMask on the root window, to receive
* events about window (dis-)appearance. Only one X connection at a time is
* allowed to select for this event mask.
*
* Calls to fetch an X event from the event queue are blocking. Due reading
* status text from standard input, a select()-driven main loop has been
* implemented which selects for reads on the X connection and STDIN_FILENO to
* handle all data smoothly. The event handlers of dwm are organized in an
* array which is accessed whenever a new event has been fetched. This allows
* event dispatching in O(1) time.
*
* Each child of the root window is called a client, except windows which have
* set the override_redirect flag. Clients are organized in a global
* doubly-linked client list, the focus history is remembered through a global
* stack list. Each client contains an array of Bools of the same size as the
* global tags array to indicate the tags of a client. For each client dwm
* creates a small title window, which is resized whenever the (_NET_)WM_NAME
* properties are updated or the client is moved/resized.
*
* Keys and tagging rules are organized as arrays and defined in the config.h
* file. These arrays are kept static in event.o and tag.o respectively,
* because no other part of dwm needs access to them. The current mode is
* represented by the arrange() function pointer, which wether points to
* dofloat() or dotile().
*
* To understand everything else, start reading main.c:main().
*/
#include "config.h"
@@ -8,26 +36,16 @@
/* mask shorthands, used in event.c and client.c */
#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask)
#define MOUSEMASK (BUTTONMASK | PointerMotionMask)
#define PROTODELWIN 1
enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMState, WMLast }; /* default atoms */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { ColBorder, ColFG, ColBG, ColLast }; /* color */
typedef union {
const char *cmd;
int i;
} Arg;
/* atoms */
enum { NetSupported, NetWMName, NetLast };
enum { WMProtocols, WMDelete, WMLast };
/* cursor */
enum { CurNormal, CurResize, CurMove, CurLast };
/* color */
enum { ColFG, ColBG, ColLast };
/* window corners */
typedef enum { TopLeft, TopRight, BotLeft, BotRight } Corner;
} Arg; /* argument type */
typedef struct {
int ascent;
@@ -37,104 +55,101 @@ typedef struct {
XFontStruct *xfont;
} Fnt;
typedef struct { /* draw context */
typedef struct {
int x, y, w, h;
unsigned long norm[ColLast];
unsigned long sel[ColLast];
unsigned long status[ColLast];
Drawable drawable;
Fnt font;
GC gc;
} DC;
} DC; /* draw context */
typedef struct Client Client;
struct Client {
char name[256];
int proto;
int x, y, w, h;
int tx, ty, tw, th; /* title */
int rx, ry, rw, rh; /* revert geometry */
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int grav;
int minax, minay, maxax, maxay;
long flags;
unsigned int border, weight;
Bool isfloat;
unsigned int border;
Bool isfixed, isfloat, ismax;
Bool *tags;
Client *next;
Client *prev;
Client *snext;
Window win;
Window twin;
};
extern const char *tags[];
extern char stext[1024];
extern int bx, by, bw, bh, bmw, mw, screen, sx, sy, sw, sh;
extern unsigned int ntags, numlockmask;
extern void (*handler[LASTEvent])(XEvent *);
extern void (*arrange)(Arg *);
extern const char *tags[]; /* all tags */
extern char stext[256]; /* status text */
extern int bh, bmw; /* bar height, bar mode label width */
extern int screen, sx, sy, sw, sh; /* screen geometry */
extern int wax, way, wah, waw; /* windowarea geometry */
extern unsigned int master, nmaster; /* master percent, number of master clients */
extern unsigned int ntags, numlockmask; /* number of tags, dynamic lock mask */
extern void (*handler[LASTEvent])(XEvent *); /* event handler */
extern void (*arrange)(void); /* arrange function, indicates mode */
extern Atom wmatom[WMLast], netatom[NetLast];
extern Bool running, issel, maximized, *seltag;
extern Client *clients, *sel;
extern Bool running, selscreen, *seltag; /* seltag is array of Bool */
extern Client *clients, *sel, *stack; /* global client list and stack */
extern Cursor cursor[CurLast];
extern DC dc;
extern DC dc; /* global draw context */
extern Display *dpy;
extern Window root, barwin;
/* client.c */
extern void ban(Client *c);
extern void focus(Client *c);
extern Client *getclient(Window w);
extern Client *getctitle(Window w);
extern void gravitate(Client *c, Bool invert);
extern void killclient(Arg *arg);
extern void manage(Window w, XWindowAttributes *wa);
extern void resize(Client *c, Bool sizehints, Corner sticky);
extern void setsize(Client *c);
extern void settitle(Client *c);
extern void togglemax(Arg *arg);
extern void unmanage(Client *c);
extern void configure(Client *c); /* send synthetic configure event */
extern void focus(Client *c); /* focus c, c may be NULL */
extern Client *getclient(Window w); /* return client of w */
extern Bool isprotodel(Client *c); /* returns True if c->win supports wmatom[WMDelete] */
extern void killclient(Arg *arg); /* kill c nicely */
extern void manage(Window w, XWindowAttributes *wa); /* manage new client */
extern void resize(Client *c, Bool sizehints); /* resize c*/
extern void updatesizehints(Client *c); /* update the size hint variables of c */
extern void updatetitle(Client *c); /* update the name of c */
extern void unmanage(Client *c); /* destroy c */
/* draw.c */
extern void drawall();
extern void drawstatus();
extern void drawtitle(Client *c);
extern unsigned long getcolor(const char *colstr);
extern void setfont(const char *fontstr);
extern unsigned int textw(const char *text);
extern void drawstatus(void); /* draw the bar */
extern unsigned long getcolor(const char *colstr); /* return color of colstr */
extern void setfont(const char *fontstr); /* set the font for DC */
extern unsigned int textw(const char *text); /* return the width of text in px*/
/* event.c */
extern void grabkeys();
extern void procevent();
extern void grabkeys(void); /* grab all keys defined in config.h */
extern void procevent(void); /* process pending X events */
/* main.c */
extern int getproto(Window w);
extern void quit(Arg *arg);
extern void sendevent(Window w, Atom a, long value);
extern int xerror(Display *dsply, XErrorEvent *ee);
extern void quit(Arg *arg); /* quit dwm nicely */
extern void sendevent(Window w, Atom a, long value); /* send synthetic event to w */
extern int xerror(Display *dsply, XErrorEvent *ee); /* dwm's X error handler */
/* tag.c */
extern void initrregs();
extern Client *getnext(Client *c);
extern Client *getprev(Client *c);
extern void settags(Client *c);
extern void tag(Arg *arg);
extern void toggletag(Arg *arg);
extern void initrregs(void); /* initialize regexps of rules defined in config.h */
extern Client *getnext(Client *c); /* returns next visible client */
extern Client *getprev(Client *c); /* returns previous visible client */
extern void settags(Client *c, Client *trans); /* sets tags of c */
extern void tag(Arg *arg); /* tags c with arg's index */
extern void toggletag(Arg *arg); /* toggles c tags with arg's index */
/* util.c */
extern void *emallocz(unsigned int size);
extern void eprint(const char *errstr, ...);
extern void *erealloc(void *ptr, unsigned int size);
extern void spawn(Arg *arg);
extern void *emallocz(unsigned int size); /* allocates zero-initialized memory, exits on error */
extern void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */
extern void spawn(Arg *arg); /* forks a new subprocess with to arg's cmd */
/* view.c */
extern void detach(Client *c);
extern void dofloat(Arg *arg);
extern void dotile(Arg *arg);
extern void focusnext(Arg *arg);
extern void focusprev(Arg *arg);
extern Bool isvisible(Client *c);
extern void restack();
extern void togglemode(Arg *arg);
extern void toggleview(Arg *arg);
extern void view(Arg *arg);
extern void viewall(Arg *arg);
extern void zoom(Arg *arg);
extern void detach(Client *c); /* detaches c from global client list */
extern void dofloat(void); /* arranges all windows floating */
extern void dotile(void); /* arranges all windows tiled */
extern void focusnext(Arg *arg); /* focuses next visible client, arg is ignored */
extern void focusprev(Arg *arg); /* focuses previous visible client, arg is ignored */
extern void incnmaster(Arg *arg); /* increments nmaster with arg's index value */
extern Bool isvisible(Client *c); /* returns True if client is visible */
extern void resizemaster(Arg *arg); /* resizes the master percent with arg's index value */
extern void restack(void); /* restores z layers of all clients */
extern void togglefloat(Arg *arg); /* toggles focusesd client between floating/non-floating state */
extern void togglemode(Arg *arg); /* toggles global arrange function (dotile/dofloat) */
extern void toggleview(Arg *arg); /* toggles the tag with arg's index (in)visible */
extern void view(Arg *arg); /* views the tag with arg's index */
extern void zoom(Arg *arg); /* zooms the focused client to master area, arg is ignored */

256
event.c
View File

@@ -1,5 +1,4 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
@@ -19,10 +18,10 @@ typedef struct {
KEYS
#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask))
#define MOUSEMASK (BUTTONMASK | PointerMotionMask)
static void
movemouse(Client *c)
{
movemouse(Client *c) {
int x1, y1, ocx, ocy, di;
unsigned int dui;
Window dummy;
@@ -33,72 +32,80 @@ movemouse(Client *c)
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurMove], CurrentTime) != GrabSuccess)
return;
c->ismax = False;
XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
for(;;) {
XMaskEvent(dpy, MOUSEMASK | ExposureMask, &ev);
XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev);
switch (ev.type) {
default: break;
case ButtonRelease:
resize(c, True);
XUngrabPointer(dpy, CurrentTime);
return;
case ConfigureRequest:
case Expose:
handler[Expose](&ev);
case MapRequest:
handler[ev.type](&ev);
break;
case MotionNotify:
XSync(dpy, False);
c->x = ocx + (ev.xmotion.x - x1);
c->y = ocy + (ev.xmotion.y - y1);
resize(c, False, TopLeft);
if(abs(wax + c->x) < SNAP)
c->x = wax;
else if(abs((wax + waw) - (c->x + c->w + 2 * c->border)) < SNAP)
c->x = wax + waw - c->w - 2 * c->border;
if(abs(way - c->y) < SNAP)
c->y = way;
else if(abs((way + wah) - (c->y + c->h + 2 * c->border)) < SNAP)
c->y = way + wah - c->h - 2 * c->border;
resize(c, False);
break;
case ButtonRelease:
XUngrabPointer(dpy, CurrentTime);
return;
}
}
}
static void
resizemouse(Client *c)
{
resizemouse(Client *c) {
int ocx, ocy;
int nw, nh;
Corner sticky;
XEvent ev;
ocx = c->x;
ocy = c->y;
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurResize], CurrentTime) != GrabSuccess)
None, cursor[CurResize], CurrentTime) != GrabSuccess)
return;
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
c->ismax = False;
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1);
for(;;) {
XMaskEvent(dpy, MOUSEMASK | ExposureMask, &ev);
XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask , &ev);
switch(ev.type) {
default: break;
case ButtonRelease:
resize(c, True);
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
c->w + c->border - 1, c->h + c->border - 1);
XUngrabPointer(dpy, CurrentTime);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
return;
case ConfigureRequest:
case Expose:
handler[Expose](&ev);
case MapRequest:
handler[ev.type](&ev);
break;
case MotionNotify:
XSync(dpy, False);
if((nw = abs(ocx - ev.xmotion.x)))
c->w = abs(ocx - ev.xmotion.x);
if((nh = abs(ocy - ev.xmotion.y)))
c->h = abs(ocy - ev.xmotion.y);
c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
if(ocx <= ev.xmotion.x)
sticky = (ocy <= ev.xmotion.y) ? TopLeft : BotLeft;
else
sticky = (ocy <= ev.xmotion.y) ? TopRight : BotRight;
resize(c, True, sticky);
nw = ev.xmotion.x - ocx - 2 * c->border + 1;
c->w = nw > 0 ? nw : 1;
nh = ev.xmotion.y - ocy - 2 * c->border + 1;
c->h = nh > 0 ? nh : 1;
resize(c, True);
break;
case ButtonRelease:
XUngrabPointer(dpy, CurrentTime);
return;
}
}
}
static void
buttonpress(XEvent *e)
{
buttonpress(XEvent *e) {
int x;
Arg a;
Client *c;
@@ -124,86 +131,68 @@ buttonpress(XEvent *e)
return;
}
}
if(ev->x < x + bmw) {
if(ev->button == Button1)
if(ev->x < x + bmw)
switch(ev->button) {
case Button1:
togglemode(NULL);
}
break;
case Button4:
a.i = 1;
incnmaster(&a);
break;
case Button5:
a.i = -1;
incnmaster(&a);
break;
}
}
else if((c = getclient(ev->window))) {
focus(c);
if(maximized || CLEANMASK(ev->state) != MODKEY)
if(CLEANMASK(ev->state) != MODKEY)
return;
if(ev->button == Button1 && (arrange == dofloat || c->isfloat)) {
restack(c);
restack();
movemouse(c);
}
else if(ev->button == Button2)
zoom(NULL);
else if(ev->button == Button3 && (arrange == dofloat || c->isfloat)) {
restack(c);
else if(ev->button == Button3
&& (arrange == dofloat || c->isfloat) && !c->isfixed)
{
restack();
resizemouse(c);
}
}
}
static void
synconfig(Client *c, int x, int y, int w, int h, unsigned int border)
{
XEvent synev;
synev.type = ConfigureNotify;
synev.xconfigure.display = dpy;
synev.xconfigure.event = c->win;
synev.xconfigure.window = c->win;
synev.xconfigure.x = x;
synev.xconfigure.y = y;
synev.xconfigure.width = w;
synev.xconfigure.height = h;
synev.xconfigure.border_width = border;
synev.xconfigure.above = None;
XSendEvent(dpy, c->win, True, NoEventMask, &synev);
}
static void
configurerequest(XEvent *e)
{
unsigned long newmask;
configurerequest(XEvent *e) {
Client *c;
XConfigureRequestEvent *ev = &e->xconfigurerequest;
XWindowChanges wc;
if((c = getclient(ev->window))) {
if((c == sel) && !c->isfloat && (arrange != dofloat) && maximized) {
synconfig(c, sx, sy + bh, sw - 2, sh - 2 - bh, ev->border_width);
XSync(dpy, False);
return;
}
gravitate(c, True);
if(ev->value_mask & CWX)
c->x = ev->x;
if(ev->value_mask & CWY)
c->y = ev->y;
if(ev->value_mask & CWWidth)
c->w = ev->width;
if(ev->value_mask & CWHeight)
c->h = ev->height;
c->ismax = False;
if(ev->value_mask & CWBorderWidth)
c->border = ev->border_width;
gravitate(c, False);
wc.x = c->x;
wc.y = c->y;
wc.width = c->w;
wc.height = c->h;
newmask = ev->value_mask & (~(CWSibling | CWStackMode | CWBorderWidth));
if(newmask)
XConfigureWindow(dpy, c->win, newmask, &wc);
if(c->isfixed || c->isfloat || (arrange == dofloat)) {
if(ev->value_mask & CWX)
c->x = ev->x;
if(ev->value_mask & CWY)
c->y = ev->y;
if(ev->value_mask & CWWidth)
c->w = ev->width;
if(ev->value_mask & CWHeight)
c->h = ev->height;
if((ev->value_mask & (CWX | CWY))
&& !(ev->value_mask & (CWWidth | CWHeight)))
configure(c);
resize(c, False);
if(!isvisible(c))
XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
}
else
synconfig(c, c->x, c->y, c->w, c->h, c->border);
XSync(dpy, False);
if(c->isfloat)
resize(c, False, TopLeft);
else
arrange(NULL);
configure(c);
}
else {
wc.x = ev->x;
@@ -214,13 +203,12 @@ configurerequest(XEvent *e)
wc.sibling = ev->above;
wc.stack_mode = ev->detail;
XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
XSync(dpy, False);
}
XSync(dpy, False);
}
static void
destroynotify(XEvent *e)
{
destroynotify(XEvent *e) {
Client *c;
XDestroyWindowEvent *ev = &e->xdestroywindow;
@@ -229,71 +217,60 @@ destroynotify(XEvent *e)
}
static void
enternotify(XEvent *e)
{
enternotify(XEvent *e) {
Client *c;
XCrossingEvent *ev = &e->xcrossing;
if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
return;
if((c = getclient(ev->window)) || (c = getctitle(ev->window)))
if((c = getclient(ev->window)) && isvisible(c))
focus(c);
else if(ev->window == root) {
issel = True;
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
drawall();
selscreen = True;
for(c = stack; c && !isvisible(c); c = c->snext);
focus(c);
}
}
static void
expose(XEvent *e)
{
Client *c;
expose(XEvent *e) {
XExposeEvent *ev = &e->xexpose;
if(ev->count == 0) {
if(barwin == ev->window)
drawstatus();
else if((c = getctitle(ev->window)))
drawtitle(c);
}
}
static void
keypress(XEvent *e)
{
static unsigned int len = sizeof(key) / sizeof(key[0]);
keypress(XEvent *e) {
static unsigned int len = sizeof key / sizeof key[0];
unsigned int i;
KeySym keysym;
XKeyEvent *ev = &e->xkey;
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
for(i = 0; i < len; i++) {
if(keysym == key[i].keysym &&
CLEANMASK(key[i].mod) == CLEANMASK(ev->state))
for(i = 0; i < len; i++)
if(keysym == key[i].keysym
&& CLEANMASK(key[i].mod) == CLEANMASK(ev->state))
{
if(key[i].func)
key[i].func(&key[i].arg);
return;
}
}
}
static void
leavenotify(XEvent *e)
{
leavenotify(XEvent *e) {
XCrossingEvent *ev = &e->xcrossing;
if((ev->window == root) && !ev->same_screen) {
issel = False;
drawall();
selscreen = False;
focus(NULL);
}
}
static void
mappingnotify(XEvent *e)
{
mappingnotify(XEvent *e) {
XMappingEvent *ev = &e->xmapping;
XRefreshKeyboardMapping(ev);
@@ -302,60 +279,48 @@ mappingnotify(XEvent *e)
}
static void
maprequest(XEvent *e)
{
maprequest(XEvent *e) {
static XWindowAttributes wa;
XMapRequestEvent *ev = &e->xmaprequest;
if(!XGetWindowAttributes(dpy, ev->window, &wa))
return;
if(wa.override_redirect) {
XSelectInput(dpy, ev->window,
(StructureNotifyMask | PropertyChangeMask));
if(wa.override_redirect)
return;
}
if(!getclient(ev->window))
manage(ev->window, &wa);
}
static void
propertynotify(XEvent *e)
{
propertynotify(XEvent *e) {
Client *c;
Window trans;
XPropertyEvent *ev = &e->xproperty;
if(ev->state == PropertyDelete)
return; /* ignore */
if((c = getclient(ev->window))) {
if(ev->atom == wmatom[WMProtocols]) {
c->proto = getproto(c->win);
return;
}
switch (ev->atom) {
default: break;
case XA_WM_TRANSIENT_FOR:
XGetTransientForHint(dpy, c->win, &trans);
if(!c->isfloat && (c->isfloat = (trans != 0)))
arrange(NULL);
arrange();
break;
case XA_WM_NORMAL_HINTS:
setsize(c);
updatesizehints(c);
break;
}
if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
settitle(c);
drawtitle(c);
updatetitle(c);
if(c == sel)
drawstatus();
}
}
}
static void
unmapnotify(XEvent *e)
{
unmapnotify(XEvent *e) {
Client *c;
XUnmapEvent *ev = &e->xunmap;
@@ -380,9 +345,8 @@ void (*handler[LASTEvent]) (XEvent *) = {
};
void
grabkeys()
{
static unsigned int len = sizeof(key) / sizeof(key[0]);
grabkeys(void) {
static unsigned int len = sizeof key / sizeof key[0];
unsigned int i;
KeyCode code;
@@ -401,8 +365,7 @@ grabkeys()
}
void
procevent()
{
procevent(void) {
XEvent ev;
while(XPending(dpy)) {
@@ -411,4 +374,3 @@ procevent()
(handler[ev.type])(&ev); /* call handler */
}
}

187
main.c
View File

@@ -1,10 +1,10 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -17,16 +17,16 @@
/* extern */
char stext[1024];
Bool *seltag;
int bx, by, bw, bh, bmw, mw, screen, sx, sy, sw, sh;
unsigned int ntags, numlockmask;
char stext[256];
int bh, bmw, screen, sx, sy, sw, sh, wax, way, waw, wah;
unsigned int master, nmaster, ntags, numlockmask;
Atom wmatom[WMLast], netatom[NetLast];
Bool running = True;
Bool issel = True;
Bool maximized = False;
Bool *seltag;
Bool selscreen = True;
Client *clients = NULL;
Client *sel = NULL;
Client *stack = NULL;
Cursor cursor[CurLast];
Display *dpy;
DC dc = {0};
@@ -38,12 +38,11 @@ static int (*xerrorxlib)(Display *, XErrorEvent *);
static Bool otherwm, readin;
static void
cleanup()
{
cleanup(void) {
close(STDIN_FILENO);
while(sel) {
resize(sel, True, TopLeft);
unmanage(sel);
while(stack) {
resize(stack, True);
unmanage(stack);
}
if(dc.font.set)
XFreeFontSet(dpy, dc.font.set);
@@ -53,13 +52,16 @@ cleanup()
XFreePixmap(dpy, dc.drawable);
XFreeGC(dpy, dc.gc);
XDestroyWindow(dpy, barwin);
XFreeCursor(dpy, cursor[CurNormal]);
XFreeCursor(dpy, cursor[CurResize]);
XFreeCursor(dpy, cursor[CurMove]);
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
XSync(dpy, False);
free(seltag);
}
static void
scan()
{
scan(void) {
unsigned int i, num;
Window *wins, d1, d2;
XWindowAttributes wa;
@@ -67,9 +69,8 @@ scan()
wins = NULL;
if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
for(i = 0; i < num; i++) {
if(!XGetWindowAttributes(dpy, wins[i], &wa))
continue;
if(wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
if(!XGetWindowAttributes(dpy, wins[i], &wa)
|| wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1))
continue;
if(wa.map_state == IsViewable)
manage(wins[i], &wa);
@@ -80,8 +81,7 @@ scan()
}
static void
setup()
{
setup(void) {
int i, j;
unsigned int mask;
Window w;
@@ -91,69 +91,72 @@ setup()
/* init atoms */
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
PropModeReplace, (unsigned char *) netatom, NetLast);
/* init cursors */
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
/* init modifier map */
numlockmask = 0;
modmap = XGetModifierMapping(dpy);
for (i = 0; i < 8; i++) {
for (i = 0; i < 8; i++)
for (j = 0; j < modmap->max_keypermod; j++) {
if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock))
if(modmap->modifiermap[i * modmap->max_keypermod + j]
== XKeysymToKeycode(dpy, XK_Num_Lock))
numlockmask = (1 << i);
}
}
XFree(modmap);
wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | EnterWindowMask | LeaveWindowMask;
XFreeModifiermap(modmap);
/* select for events */
wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
| EnterWindowMask | LeaveWindowMask;
wa.cursor = cursor[CurNormal];
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
grabkeys();
initrregs();
for(ntags = 0; tags[ntags]; ntags++);
seltag = emallocz(sizeof(Bool) * ntags);
seltag[0] = True;
/* style */
dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR);
dc.norm[ColBG] = getcolor(NORMBGCOLOR);
dc.norm[ColFG] = getcolor(NORMFGCOLOR);
dc.sel[ColBorder] = getcolor(SELBORDERCOLOR);
dc.sel[ColBG] = getcolor(SELBGCOLOR);
dc.sel[ColFG] = getcolor(SELFGCOLOR);
dc.status[ColBG] = getcolor(STATUSBGCOLOR);
dc.status[ColFG] = getcolor(STATUSFGCOLOR);
setfont(FONT);
bmw = textw(FLOATSYMBOL) > textw(TILESYMBOL) ? textw(FLOATSYMBOL) : textw(TILESYMBOL);
/* geometry */
sx = sy = 0;
sw = DisplayWidth(dpy, screen);
sh = DisplayHeight(dpy, screen);
mw = (sw * MASTERW) / 100;
bx = by = 0;
bw = sw;
master = MASTER;
nmaster = NMASTER;
bmw = textw(TILESYMBOL) > textw(FLOATSYMBOL) ? textw(TILESYMBOL) : textw(FLOATSYMBOL);
/* bar */
dc.h = bh = dc.font.height + 2;
wa.override_redirect = 1;
wa.background_pixmap = ParentRelative;
wa.event_mask = ButtonPressMask | ExposureMask;
barwin = XCreateWindow(dpy, root, bx, by, bw, bh, 0, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
barwin = XCreateWindow(dpy, root, sx, sy + (TOPBAR ? 0 : sh - bh), sw, bh, 0,
DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
XDefineCursor(dpy, barwin, cursor[CurNormal]);
XMapRaised(dpy, barwin);
strcpy(stext, "dwm-"VERSION);
/* windowarea */
wax = sx;
way = sy + (TOPBAR ? bh : 0);
wah = sh - bh;
waw = sw;
/* pixmap for everything */
dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
dc.gc = XCreateGC(dpy, root, 0, 0);
XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
strcpy(stext, "dwm-"VERSION);
/* multihead support */
selscreen = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
}
/*
@@ -161,36 +164,15 @@ setup()
* is already running.
*/
static int
xerrorstart(Display *dsply, XErrorEvent *ee)
{
xerrorstart(Display *dsply, XErrorEvent *ee) {
otherwm = True;
return -1;
}
/* extern */
int
getproto(Window w)
{
int i, format, protos, status;
unsigned long extra, res;
Atom *protocols, real;
protos = 0;
status = XGetWindowProperty(dpy, w, wmatom[WMProtocols], 0L, 20L, False,
XA_ATOM, &real, &format, &res, &extra, (unsigned char **)&protocols);
if(status != Success || protocols == 0)
return protos;
for(i = 0; i < res; i++)
if(protocols[i] == wmatom[WMDelete])
protos |= PROTODELWIN;
free(protocols);
return protos;
}
void
sendevent(Window w, Atom a, long value)
{
sendevent(Window w, Atom a, long value) {
XEvent e;
e.type = ClientMessage;
@@ -204,59 +186,54 @@ sendevent(Window w, Atom a, long value)
}
void
quit(Arg *arg)
{
quit(Arg *arg) {
readin = running = False;
}
/*
* 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
* default error handler, which calls exit().
* default error handler, which may call exit.
*/
int
xerror(Display *dpy, XErrorEvent *ee)
{
xerror(Display *dpy, XErrorEvent *ee) {
if(ee->error_code == BadWindow
|| (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch)
|| (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable)
|| (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable)
|| (ee->request_code == X_PolySegment && ee->error_code == BadDrawable)
|| (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch)
|| (ee->request_code == X_GrabKey && ee->error_code == BadAccess))
|| (ee->request_code == X_GrabKey && ee->error_code == BadAccess)
|| (ee->request_code == X_CopyArea && ee->error_code == BadDrawable))
return 0;
fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
ee->request_code, ee->error_code);
return xerrorxlib(dpy, ee); /* may call exit() */
return xerrorxlib(dpy, ee); /* may call exit */
}
int
main(int argc, char *argv[])
{
main(int argc, char *argv[]) {
char *p;
int r, xfd;
fd_set rd;
if(argc == 2 && !strncmp("-v", argv[1], 3)) {
fputs("dwm-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout);
fputs("dwm-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n", stdout);
exit(EXIT_SUCCESS);
}
else if(argc != 1)
eprint("usage: dwm [-v]\n");
setlocale(LC_CTYPE, "");
dpy = XOpenDisplay(0);
if(!dpy)
eprint("dwm: cannot open display\n");
xfd = ConnectionNumber(dpy);
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
otherwm = False;
XSetErrorHandler(xerrorstart);
/* this causes an error if some other window manager is running */
XSelectInput(dpy, root, SubstructureRedirectMask);
XSync(dpy, False);
if(otherwm)
eprint("dwm: another window manager is already running\n");
@@ -264,7 +241,6 @@ main(int argc, char *argv[])
XSetErrorHandler(NULL);
xerrorxlib = XSetErrorHandler(xerror);
XSync(dpy, False);
setup();
drawstatus();
scan();
@@ -278,25 +254,34 @@ main(int argc, char *argv[])
if(readin)
FD_SET(STDIN_FILENO, &rd);
FD_SET(xfd, &rd);
r = select(xfd + 1, &rd, NULL, NULL, NULL);
if((r == -1) && (errno == EINTR))
continue;
if(r > 0) {
if(readin && FD_ISSET(STDIN_FILENO, &rd)) {
readin = NULL != fgets(stext, sizeof(stext), stdin);
if(readin)
stext[strlen(stext) - 1] = 0;
else
strcpy(stext, "broken pipe");
drawstatus();
}
}
else if(r < 0)
if(select(xfd + 1, &rd, NULL, NULL, NULL) == -1) {
if(errno == EINTR)
continue;
eprint("select failed\n");
procevent();
}
if(FD_ISSET(STDIN_FILENO, &rd)) {
switch(r = read(STDIN_FILENO, stext, sizeof stext - 1)) {
case -1:
strncpy(stext, strerror(errno), sizeof stext - 1);
stext[sizeof stext - 1] = '\0';
readin = False;
break;
case 0:
strncpy(stext, "EOF", 4);
readin = False;
break;
default:
for(stext[r] = '\0', p = stext + strlen(stext) - 1; p >= stext && *p == '\n'; *p-- = '\0');
for(; p >= stext && *p != '\n'; --p);
if(p > stext)
strncpy(stext, p + 1, sizeof stext);
}
drawstatus();
}
if(FD_ISSET(xfd, &rd))
procevent();
}
cleanup();
XCloseDisplay(dpy);
return 0;
}

55
tag.c
View File

@@ -1,5 +1,4 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
@@ -33,41 +32,37 @@ static unsigned int len = 0;
/* extern */
Client *
getnext(Client *c)
{
getnext(Client *c) {
for(; c && !isvisible(c); c = c->next);
return c;
}
Client *
getprev(Client *c)
{
getprev(Client *c) {
for(; c && !isvisible(c); c = c->prev);
return c;
}
void
initrregs()
{
initrregs(void) {
unsigned int i;
regex_t *reg;
if(rreg)
return;
len = sizeof(rule) / sizeof(rule[0]);
len = sizeof rule / sizeof rule[0];
rreg = emallocz(len * sizeof(RReg));
for(i = 0; i < len; i++) {
if(rule[i].clpattern) {
reg = emallocz(sizeof(regex_t));
if(regcomp(reg, rule[i].clpattern, 0))
if(regcomp(reg, rule[i].clpattern, REG_EXTENDED))
free(reg);
else
rreg[i].clregex = reg;
}
if(rule[i].tpattern) {
reg = emallocz(sizeof(regex_t));
if(regcomp(reg, rule[i].tpattern, 0))
if(regcomp(reg, rule[i].tpattern, REG_EXTENDED))
free(reg);
else
rreg[i].tregex = reg;
@@ -76,19 +71,22 @@ initrregs()
}
void
settags(Client *c)
{
settags(Client *c, Client *trans) {
char prop[512];
unsigned int i, j;
regmatch_t tmp;
Bool matched = False;
XClassHint ch;
Bool matched = trans != NULL;
XClassHint ch = { 0 };
if(XGetClassHint(dpy, c->win, &ch)) {
snprintf(prop, sizeof(prop), "%s:%s:%s",
if(matched)
for(i = 0; i < ntags; i++)
c->tags[i] = trans->tags[i];
else {
XGetClassHint(dpy, c->win, &ch);
snprintf(prop, sizeof prop, "%s:%s:%s",
ch.res_class ? ch.res_class : "",
ch.res_name ? ch.res_name : "", c->name);
for(i = 0; !matched && i < len; i++)
for(i = 0; i < len; i++)
if(rreg[i].clregex && !regexec(rreg[i].clregex, prop, 1, &tmp, 0)) {
c->isfloat = rule[i].isfloat;
for(j = 0; rreg[i].tregex && j < ntags; j++) {
@@ -106,35 +104,30 @@ settags(Client *c)
if(!matched)
for(i = 0; i < ntags; i++)
c->tags[i] = seltag[i];
for(i = 0; i < ntags && !c->tags[i]; i++);
c->weight = i;
}
void
tag(Arg *arg)
{
tag(Arg *arg) {
unsigned int i;
if(!sel)
return;
for(i = 0; i < ntags; i++)
sel->tags[i] = False;
sel->tags[arg->i] = True;
arrange(NULL);
sel->tags[i] = (arg->i == -1) ? True : False;
if(arg->i >= 0 && arg->i < ntags)
sel->tags[arg->i] = True;
arrange();
}
void
toggletag(Arg *arg)
{
toggletag(Arg *arg) {
unsigned int i;
if(!sel)
return;
sel->tags[arg->i] = !sel->tags[arg->i];
for(i = 0; i < ntags && !sel->tags[i]; i++);
if(i == ntags)
sel->tags[arg->i] = True;
arrange(NULL);
arrange();
}

25
util.c
View File

@@ -1,5 +1,4 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
@@ -12,8 +11,7 @@
/* extern */
void *
emallocz(unsigned int size)
{
emallocz(unsigned int size) {
void *res = calloc(1, size);
if(!res)
@@ -22,8 +20,7 @@ emallocz(unsigned int size)
}
void
eprint(const char *errstr, ...)
{
eprint(const char *errstr, ...) {
va_list ap;
va_start(ap, errstr);
@@ -32,26 +29,16 @@ eprint(const char *errstr, ...)
exit(EXIT_FAILURE);
}
void *
erealloc(void *ptr, unsigned int size)
{
void *res = realloc(ptr, size);
if(!res)
eprint("fatal: could not malloc() %u bytes\n", size);
return res;
}
void
spawn(Arg *arg)
{
spawn(Arg *arg) {
static char *shell = NULL;
if(!shell && !(shell = getenv("SHELL")))
shell = "/bin/sh";
if(!arg->cmd)
return;
/* the double-fork construct avoids zombie processes */
/* The double-fork construct avoids zombie processes and keeps the code
* clean from stupid signal handlers. */
if(fork() == 0) {
if(fork() == 0) {
if(dpy)

302
view.c
View File

@@ -1,5 +1,4 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
@@ -8,43 +7,40 @@
/* static */
static Client *
minclient()
{
Client *c, *min;
for(min = c = clients; c; c = c->next)
if(c->weight < min->weight)
min = c;
return min;
nexttiled(Client *c) {
for(c = getnext(c); c && c->isfloat; c = getnext(c->next));
return c;
}
static void
reorder()
{
Client *c, *newclients, *tail;
togglemax(Client *c) {
XEvent ev;
if(c->isfixed)
return;
newclients = tail = NULL;
while((c = minclient())) {
detach(c);
if(tail) {
c->prev = tail;
tail->next = c;
tail = c;
}
else
tail = newclients = c;
if((c->ismax = !c->ismax)) {
c->rx = c->x; c->x = wax;
c->ry = c->y; c->y = way;
c->rw = c->w; c->w = waw - 2 * BORDERPX;
c->rh = c->h; c->h = wah - 2 * BORDERPX;
}
clients = newclients;
else {
c->x = c->rx;
c->y = c->ry;
c->w = c->rw;
c->h = c->rh;
}
resize(c, True);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}
/* extern */
void (*arrange)(Arg *) = DEFMODE;
void (*arrange)(void) = DEFMODE;
void
detach(Client *c)
{
detach(Client *c) {
if(c->prev)
c->prev->next = c->next;
if(c->next)
@@ -55,94 +51,77 @@ detach(Client *c)
}
void
dofloat(Arg *arg)
{
dofloat(void) {
Client *c;
maximized = False;
for(c = clients; c; c = c->next) {
if(isvisible(c)) {
resize(c, True, TopLeft);
}
if(isvisible(c))
resize(c, True);
else
ban(c);
XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
}
if(!sel || !isvisible(sel)) {
for(c = stack; c && !isvisible(c); c = c->snext);
focus(c);
}
if(!sel || !isvisible(sel))
focus(getnext(clients));
restack();
}
void
dotile(Arg *arg)
{
int h, i, n, w;
dotile(void) {
unsigned int i, n, mw, mh, tw, th;
Client *c;
maximized = False;
for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
n++;
/* window geoms */
mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
mw = (n > nmaster) ? (waw * master) / 1000 : waw;
th = (n > nmaster) ? wah / (n - nmaster) : 0;
tw = waw - mw;
w = sw - mw;
for(n = 0, c = clients; c; c = c->next)
if(isvisible(c) && !c->isfloat)
n++;
if(n > 1)
h = (sh - bh) / (n - 1);
else
h = sh - bh;
for(i = 0, c = clients; c; c = c->next) {
for(i = 0, c = clients; c; c = c->next)
if(isvisible(c)) {
if(c->isfloat) {
resize(c, True, TopLeft);
resize(c, True);
continue;
}
if(n == 1) {
c->x = sx;
c->y = sy + bh;
c->w = sw - 2;
c->h = sh - 2 - bh;
c->ismax = False;
c->x = wax;
c->y = way;
if(i < nmaster) {
c->y += i * mh;
c->w = mw - 2 * BORDERPX;
c->h = mh - 2 * BORDERPX;
}
else if(i == 0) {
c->x = sx;
c->y = sy + bh;
c->w = mw - 2;
c->h = sh - 2 - bh;
else { /* tile window */
c->x += mw;
c->w = tw - 2 * BORDERPX;
if(th > 2 * BORDERPX) {
c->y += (i - nmaster) * th;
c->h = th - 2 * BORDERPX;
}
else /* fallback if th <= 2 * BORDERPX */
c->h = wah - 2 * BORDERPX;
}
else if(h > bh) {
c->x = sx + mw;
c->y = sy + (i - 1) * h + bh;
c->w = w - 2;
if(i + 1 == n)
c->h = sh - c->y - 2;
else
c->h = h - 2;
}
else { /* fallback if h < bh */
c->x = sx + mw;
c->y = sy + bh;
c->w = w - 2;
c->h = sh - 2 - bh;
}
resize(c, False, TopLeft);
resize(c, False);
i++;
}
else
ban(c);
XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
if(!sel || !isvisible(sel)) {
for(c = stack; c && !isvisible(c); c = c->snext);
focus(c);
}
if(!sel || !isvisible(sel))
focus(getnext(clients));
restack();
}
void
focusnext(Arg *arg)
{
focusnext(Arg *arg) {
Client *c;
if(!sel)
return;
if(!(c = getnext(sel->next)))
c = getnext(clients);
if(c) {
@@ -152,13 +131,11 @@ focusnext(Arg *arg)
}
void
focusprev(Arg *arg)
{
focusprev(Arg *arg) {
Client *c;
if(!sel)
return;
if(!(c = getprev(sel->prev))) {
for(c = clients; c && c->next; c = c->next);
c = getprev(c);
@@ -169,9 +146,20 @@ focusprev(Arg *arg)
}
}
void
incnmaster(Arg *arg) {
if((arrange == dofloat) || (nmaster + arg->i < 1)
|| (wah / (nmaster + arg->i) <= 2 * BORDERPX))
return;
nmaster += arg->i;
if(sel)
arrange();
else
drawstatus();
}
Bool
isvisible(Client *c)
{
isvisible(Client *c) {
unsigned int i;
for(i = 0; i < ntags; i++)
@@ -181,118 +169,102 @@ isvisible(Client *c)
}
void
restack()
{
static unsigned int nwins = 0;
static Window *wins = NULL;
unsigned int f, fi, m, mi, n;
resizemaster(Arg *arg) {
if(arg->i == 0)
master = MASTER;
else {
if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX
|| waw * (master + arg->i) / 1000 <= 2 * BORDERPX)
return;
master += arg->i;
}
arrange();
}
void
restack(void) {
Client *c;
XEvent ev;
for(f = 0, m = 0, c = clients; c; c = c->next)
if(isvisible(c)) {
if(c->isfloat || arrange == dofloat)
f++;
else
m++;
}
if(!(n = 2 * (f + m))) {
drawstatus();
drawstatus();
if(!sel)
return;
}
if(nwins < n) {
nwins = n;
wins = erealloc(wins, nwins * sizeof(Window));
}
fi = 0;
mi = 2 * f;
if(sel->isfloat || arrange == dofloat) {
wins[fi++] = sel->twin;
wins[fi++] = sel->win;
}
else {
wins[mi++] = sel->twin;
wins[mi++] = sel->win;
}
for(c = clients; c; c = c->next)
if(isvisible(c) && c != sel) {
if(c->isfloat || arrange == dofloat) {
wins[fi++] = c->twin;
wins[fi++] = c->win;
}
else {
wins[mi++] = c->twin;
wins[mi++] = c->win;
}
if(sel->isfloat || arrange == dofloat)
XRaiseWindow(dpy, sel->win);
if(arrange != dofloat) {
if(!sel->isfloat)
XLowerWindow(dpy, sel->win);
for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
if(c == sel)
continue;
XLowerWindow(dpy, c->win);
}
XRestackWindows(dpy, wins, n);
drawall();
}
XSync(dpy, False);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}
void
togglemode(Arg *arg)
{
togglefloat(Arg *arg) {
if(!sel || arrange == dofloat)
return;
sel->isfloat = !sel->isfloat;
arrange();
}
void
togglemode(Arg *arg) {
arrange = (arrange == dofloat) ? dotile : dofloat;
if(sel)
arrange(NULL);
arrange();
else
drawstatus();
}
void
toggleview(Arg *arg)
{
toggleview(Arg *arg) {
unsigned int i;
seltag[arg->i] = !seltag[arg->i];
for(i = 0; i < ntags && !seltag[i]; i++);
if(i == ntags)
seltag[arg->i] = True; /* cannot toggle last view */
reorder();
arrange(NULL);
arrange();
}
void
view(Arg *arg)
{
view(Arg *arg) {
unsigned int i;
for(i = 0; i < ntags; i++)
seltag[i] = False;
seltag[arg->i] = True;
reorder();
arrange(NULL);
seltag[i] = (arg->i == -1) ? True : False;
if(arg->i >= 0 && arg->i < ntags)
seltag[arg->i] = True;
arrange();
}
void
viewall(Arg *arg)
{
unsigned int i;
zoom(Arg *arg) {
unsigned int n;
Client *c;
for(i = 0; i < ntags; i++)
seltag[i] = True;
reorder();
arrange(NULL);
}
void
zoom(Arg *arg)
{
Client *c = sel;
if(!c || (arrange != dotile) || c->isfloat || maximized)
if(!sel)
return;
if(sel->isfloat || (arrange == dofloat)) {
togglemax(sel);
return;
}
for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
n++;
if(c == getnext(clients))
if(!(c = getnext(c->next)))
if((c = sel) == nexttiled(clients))
if(!(c = nexttiled(c->next)))
return;
detach(c);
if(clients)
clients->prev = c;
c->next = clients;
clients->prev = c;
clients = c;
focus(c);
arrange(NULL);
arrange();
}