1
0
mirror of git://git.suckless.org/dwm synced 2025-07-27 10:12:09 -07:00

Compare commits

..

305 Commits
0.2 ... 1.2

Author SHA1 Message Date
Anselm R. Garbe
140be1b4b3 prepared 1.2 2006-08-30 12:39:27 +02:00
Anselm R. Garbe
79259acc12 now using Salmi's menu command 2006-08-30 11:21:56 +02:00
Anselm R. Garbe
5a3bea2d69 removed a warning reported by Jukka 2006-08-30 11:15:58 +02:00
Anselm R. Garbe
30d928591d simplified configurerequest 2006-08-29 19:24:28 +02:00
Anselm R. Garbe
70a3e62257 now dwm enforces max screen size also in tiled mode on non-floating clients which are maximized 2006-08-29 18:05:02 +02:00
Anselm R. Garbe
6828fba7a0 fixed 2006-08-29 17:33:27 +02:00
Anselm R. Garbe
aa1bda8164 configurenotify remembers max geom now, and restores this if necessary, however it accepts to touch the max size on configurerequest, this shouldn't break fillscreen apps (tested with mplayer) 2006-08-29 17:31:55 +02:00
Anselm R. Garbe
157ea539a2 applied patch similiar proposed by dave tweed 2006-08-29 17:11:37 +02:00
Anselm R. Garbe
c3c94c0e0a improved selection policy 2006-08-29 15:28:29 +02:00
Anselm R. Garbe
9d73909075 still something wrong with reorder() 2006-08-29 13:40:09 +02:00
Anselm R. Garbe
016c54196e this algorithm seems to keep order for any scenario 2006-08-29 09:57:57 +02:00
Anselm R. Garbe
5056bb952d fix client position in list also on tag and toggletag 2006-08-29 09:25:14 +02:00
Anselm R. Garbe
8a6679b3b4 added attach/detach functions which don't attach at the begin of list, but at the slot of a first match of the tags of a client 2006-08-29 09:23:44 +02:00
Anselm R. Garbe
7b6d5ff298 removed crappy variables 2006-08-28 14:32:51 +02:00
Anselm R. Garbe
846850914d changed config.arg.h - I really need the 4th tag 2006-08-28 12:27:00 +02:00
Anselm R. Garbe
4e6c513ac2 updated html page 2006-08-28 10:21:40 +02:00
Anselm R. Garbe
db9cda6a7d Added tag 1.1 for changeset 44a55e6e46bf6c231780b09d919977d6f01083de 2006-08-28 10:19:55 +02:00
Anselm R. Garbe
a50b15a9e9 added a comment to spawn 2006-08-28 08:17:27 +02:00
Anselm R. Garbe
0a25fe9188 applied sanders focus_ patches 2006-08-28 08:06:50 +02:00
Anselm R. Garbe
2dd5212a79 applied sanders somepatches.patch 2006-08-28 08:02:29 +02:00
Anselm R. Garbe
00e95e1f38 oh frking dear big font... 2006-08-25 18:14:55 +02:00
Anselm R. Garbe
0a0759132c term enlightened 2006-08-25 18:05:18 +02:00
Anselm R. Garbe
5cf362c7d0 switching to darker colorscheme with larger font 2006-08-25 18:03:56 +02:00
Anselm R. Garbe
413be1112a patched arg.h 2006-08-25 17:42:58 +02:00
Anselm R. Garbe
8233dc8568 new stuff 2006-08-25 17:34:03 +02:00
Anselm R. Garbe
afa8b3bcd9 switching to dark colors again 2006-08-25 17:31:57 +02:00
Anselm R. Garbe
c518345f40 updated man page of dwm 2006-08-25 16:21:45 +02:00
Anselm R. Garbe
afe6ac9923 changed order of options 2006-08-25 16:15:13 +02:00
Anselm R. Garbe
e995c1b532 trying a different configuration 2006-08-25 15:48:44 +02:00
Anselm R. Garbe
e36929292e removed small 1px gap, somehow without it things feel better 2006-08-25 15:37:00 +02:00
Anselm R. Garbe
03128f78df oops 2006-08-25 15:24:18 +02:00
Anselm R. Garbe
7d4a5e654c fixed typo 2006-08-25 15:21:49 +02:00
Anselm R. Garbe
41ba7a7984 s/TILED/TILE/g 2006-08-25 15:16:20 +02:00
Anselm R. Garbe
aa471f2d65 removed a bunch of lines, made mode symbols configurable 2006-08-25 15:12:32 +02:00
Anselm R. Garbe
d37dfa1bed changed symbols for float/tiled mode, added mouse-driven mode toggle to buttonpress() 2006-08-25 15:06:38 +02:00
Anselm R. Garbe
9f35cc52fe small fix to separate client title from right-most tag 2006-08-25 14:46:01 +02:00
Anselm R. Garbe
f1fe19bc2b restored config.arg.h 2006-08-25 13:02:07 +02:00
Anselm R. Garbe
b55bd709ee new color stuff/new rendering stuff 2006-08-25 12:59:45 +02:00
Anselm R. Garbe
9833610356 back to 3 colors 2006-08-25 07:54:49 +02:00
Anselm R. Garbe
de7fc0011e fixed 2006-08-24 12:07:10 +02:00
Anselm R. Garbe
2e0c767d74 3->4 colors 2006-08-24 12:04:56 +02:00
Anselm R. Garbe
a5379e901c Added tag 1.0 for changeset bbc98e77ae89a7c9232a5be0835f60ea00d8036e 2006-08-24 10:28:50 +02:00
Anselm R. Garbe
a039d51d5f prepared dwm-1.0 2006-08-24 10:25:05 +02:00
Anselm R. Garbe
60b3dceccf yet another fix 2006-08-24 10:20:00 +02:00
Anselm R. Garbe
c2ac851b90 small man page fix 2006-08-24 10:18:42 +02:00
Anselm R. Garbe
c976bc6c2c found less intrusive way 2006-08-24 09:41:41 +02:00
Anselm R. Garbe
2e834e941f changing tag indicator through underline 2006-08-24 09:25:10 +02:00
Anselm R. Garbe
77e5f3167c black on light is really better, I notice this after all 2006-08-23 19:05:03 +02:00
Anselm R. Garbe
7e597ae204 updated man page 2006-08-23 18:50:46 +02:00
Anselm R. Garbe
c39df91ab9 applied tag drawing change to man page 2006-08-23 14:40:44 +02:00
Anselm R. Garbe
af1158d105 implemented right tag drawing in the status bar and titlebars 2006-08-23 14:38:25 +02:00
Anselm R. Garbe
b739721d9e removed a blank line 2006-08-23 13:04:43 +02:00
Anselm R. Garbe
7711ab6707 eliminated sentinel warning 2006-08-23 12:28:39 +02:00
Anselm R. Garbe
d370c32f69 small fix of man page 2006-08-23 12:10:55 +02:00
Anselm R. Garbe
d6a6eca71d implemented class:inst:title matching 2006-08-23 12:08:37 +02:00
Anselm R. Garbe
39ffc18635 applied zero_to_five patch 2006-08-23 12:03:25 +02:00
Anselm R. Garbe
3e972ec84d tags appear in the left again 2006-08-23 11:33:50 +02:00
Anselm R. Garbe
b5159dfd2f separated setup stuff into main.c:setup() - this makes main() more readable 2006-08-23 10:21:57 +02:00
Anselm R. Garbe
07c2659806 updated man page 2006-08-22 19:56:29 +02:00
Anselm R. Garbe
dc83b9e988 titlebars contain tags in the right now 2006-08-22 19:55:20 +02:00
Anselm R. Garbe
8b4bc8270a fixed default key bindings (indexes of tags were screwed up) 2006-08-22 18:08:25 +02:00
Anselm R. Garbe
0ff80653d3 rearranged getproto 2006-08-22 17:40:21 +02:00
Anselm R. Garbe
352e1b4c81 removed winprop (merged into getproto) 2006-08-22 17:38:59 +02:00
Anselm R. Garbe
aa13727067 separated several functions into view.c 2006-08-22 16:50:21 +02:00
Anselm R. Garbe
595028614b removed DEFTAG 2006-08-22 16:42:29 +02:00
Anselm R. Garbe
6a3ae5e26a removed badmalloc (thx for the pointer to Uriel) 2006-08-22 16:06:11 +02:00
Anselm R. Garbe
8c334ee078 rxvt is quite slow under OpenBSD 2006-08-22 10:06:11 +02:00
Anselm R. Garbe
f60fe2a4f9 font fix 2006-08-22 10:01:32 +02:00
Anselm R. Garbe
b112257bf2 slight change of my config.h 2006-08-22 09:57:32 +02:00
Anselm R. Garbe
eb88adcd8a fixed 2006-08-22 09:49:48 +02:00
arg@localhost.10kloc.org
950a1ab5af windows which have set transient_for hint inherit the transient_for window tags now 2006-08-21 17:35:37 +02:00
arg@localhost.10kloc.org
1b9fe55025 after switching to OpenBSD again, I switched back to a saner color scheme 2006-08-21 17:41:09 +02:00
Anselm R.Garbe
2272df9d31 applied Sanders focus_* patches, removed the unnecessary clean-prefix from the new function names 2006-08-21 09:03:14 +02:00
Anselm R.Garbe
08d85d6d66 small renamings of two static functions 2006-08-21 07:33:18 +02:00
Anselm R.Garbe
b43989207a small changes to dwm.1, rearranged order within main event loop 2006-08-21 07:31:15 +02:00
Anselm R.Garbe
2eebebf262 applied Sanders patch 2006-08-18 13:40:34 +02:00
Anselm R.Garbe
8c1fffe106 made a new client position strategy similiar to that one proposed by Sander, but which takes top bar into account 2006-08-18 08:39:33 +02:00
Anselm R.Garbe
5e9acbc952 fixed a bug reported by sander 2006-08-17 10:06:36 +02:00
Anselm R.Garbe
a420ceab50 applied the shorter xprop command 2006-08-17 09:44:17 +02:00
Anselm R.Garbe
0e1c649dca centering apps only if transient_for is not(!) set 2006-08-17 09:37:43 +02:00
Anselm R.Garbe
67c2124fa9 fixed issue Sander reported 2006-08-17 09:35:44 +02:00
Anselm R.Garbe
a635743c6d corrected order of cleanup code 2006-08-16 19:25:29 +02:00
Anselm R.Garbe
b5c2412d84 condition was insufficient 2006-08-16 17:58:18 +02:00
Anselm R.Garbe
ad2e77d635 fixed issue reported by sander 2006-08-16 17:56:04 +02:00
Anselm R.Garbe
a20b10d01f added general centralization rule for new clients (works around various borken apps) 2006-08-16 15:57:36 +02:00
Anselm R.Garbe
4cc0551948 removed leading ; 2006-08-16 15:31:24 +02:00
Anselm R.Garbe
56130c3689 added sample command to config.default.h to highlight how to query class:instance info with a one-liner of shell commands 2006-08-16 15:00:14 +02:00
Anselm R.Garbe
14f7380308 applied another config.mk patch made by sander 2006-08-16 12:36:32 +02:00
Anselm R.Garbe
727449d1e7 we close stdin as well 2006-08-16 09:31:41 +02:00
Anselm R.Garbe
80bf2aa559 simplified sort | uniq into sort -u (on my boxes all sort support -u) 2006-08-16 09:05:58 +02:00
Anselm R.Garbe
b9cd0c4331 fixing small bug in config.mk 2006-08-15 16:54:54 +02:00
Anselm R.Garbe
f77a87137c adding forgetten whitespace 2006-08-15 10:45:14 +02:00
Anselm R.Garbe
65dfe8fdce added gmane archive to dwm.html 2006-08-15 10:44:15 +02:00
Anselm R.Garbe
e3bb595d77 Added tag 0.9 for changeset fae61afa861755636c4a1070694209ace8efbb6c 2006-08-15 10:25:30 +02:00
Anselm R.Garbe
a1682b8927 prepared dwm-0.9 2006-08-15 10:11:29 +02:00
Anselm R.Garbe
24d91e3b8a extended cleanup 2006-08-15 09:37:12 +02:00
Anselm R.Garbe
ce04a66528 applied Sanders changes to config.arg.h 2006-08-15 08:38:19 +02:00
Anselm R.Garbe
df74b26e5d applied jk_to_tab patch 2006-08-15 08:25:11 +02:00
Anselm R.Garbe
b6ad663f87 changed main event loop 2006-08-15 07:31:42 +02:00
Anselm R.Garbe
ee31e38dc7 removed NUMLOCKMASK, added dynamically calculated numlockmask instead 2006-08-14 19:18:02 +02:00
Anselm R.Garbe
442334641e added Sander to LICENSE (since he has contributed/revised big portions) 2006-08-14 18:47:13 +02:00
Anselm R.Garbe
dfa5ea6360 applied viewsel.patch 2006-08-14 18:46:07 +02:00
Anselm R.Garbe
3e06edeb5d applied sanders man page patch, removed button2 from bar click 2006-08-14 18:14:08 +02:00
Anselm R.Garbe
78b050c13c applied sanders tag()/toggletag() fixes 2006-08-14 17:50:48 +02:00
Anselm R.Garbe
4ad20ffc2c fixed 2006-08-14 17:48:54 +02:00
Anselm R.Garbe
57e6e3bb80 added missing arrange 2006-08-14 17:14:22 +02:00
Anselm R.Garbe
19da197f58 changed replacetag into toggletag 2006-08-14 16:59:18 +02:00
Anselm R.Garbe
666fae97e6 added some flicker prevention 2006-08-14 16:37:55 +02:00
Anselm R.Garbe
823fb1118a remove unnecessary XSync 2006-08-14 16:26:06 +02:00
Anselm R.Garbe
db1d62e184 changed order of selecting input at root window 2006-08-14 16:21:16 +02:00
Anselm R.Garbe
d26ffc7fa3 removed finished message 2006-08-14 16:11:54 +02:00
Anselm R.Garbe
0f3acce042 added mappingnotify event for kb refreshes 2006-08-14 16:08:52 +02:00
Anselm R.Garbe
9eef9f7b02 removed unneecessary crap 2006-08-14 15:43:04 +02:00
Anselm R.Garbe
aff4c787f4 applied the saner patch (removed the pathetic one) 2006-08-14 15:33:23 +02:00
Anselm R.Garbe
fe3dfbbe90 pplied Sanders appendtag patch 2006-08-14 15:31:58 +02:00
Anselm R.Garbe
2ffdc1936c some other small fixes 2006-08-14 15:11:02 +02:00
Anselm R.Garbe
0fe52c63ea removed ungrabkeys again (because of sander's mail) 2006-08-14 11:38:43 +02:00
Anselm R.Garbe
28a52197c4 fixed string cutting 2006-08-14 10:58:03 +02:00
Anselm R.Garbe
2c0d1cc87b fixed a core dump 2006-08-14 10:49:22 +02:00
Anselm R.Garbe
375a251d16 implemented ungrabkeys() which is called in cleanup() 2006-08-14 10:24:38 +02:00
Anselm R.Garbe
d4b7a9a373 implemented restack behavior (floats are on top in tiled mode) 2006-08-14 10:18:24 +02:00
Anselm R.Garbe
4d67199a4b fixed string cutting in draw.c 2006-08-14 08:52:15 +02:00
Anselm R.Garbe
95766d6241 applied Sanders LD and resize patches 2006-08-14 08:43:19 +02:00
Anselm R.Garbe
4cb78a170c removed viewnext/viewprev 2006-08-14 08:38:26 +02:00
Anselm R.Garbe
2c66b422e7 supplying NULL args in select 2006-08-14 07:40:20 +02:00
Anselm R.Garbe
e571de83e9 reducing ConnectionNumber calls to a bare minimum 2006-08-14 07:23:46 +02:00
Anselm R.Garbe
4bb89e2cb1 updated man page, added CAVEATS section 2006-08-13 18:04:42 +02:00
Anselm R.Garbe
349cadacf6 made shortcuts like proposed by Sander, renamed viewextend to toggleview (more clear) 2006-08-13 17:58:06 +02:00
Anselm R.Garbe
292ccc4c43 implemented viewextend and added M-S-C-n shortcuts for extending the current view... updated man page (works great!) nice feature 2006-08-11 19:26:12 +02:00
Anselm R.Garbe
d7413ffd2d implement multi-tag selection through button3 click on the specific tag 2006-08-11 18:37:41 +02:00
Anselm R.Garbe
50729a2e73 after some days of experimenting with grey background, I finally give up and switch to white on black ;) 2006-08-11 18:11:39 +02:00
Anselm R.Garbe
a3e3f0b9ed applied Sanders fixes to dwm.1 2006-08-11 17:12:48 +02:00
Anselm R.Garbe
45aea23355 fixed dwm.1, added Mod1-Shift-c (was missing for an odd reason) 2006-08-11 12:32:34 +02:00
Anselm R.Garbe
975b459c17 simplified drawtext 2006-08-11 11:52:55 +02:00
Anselm R.Garbe
2b35faee06 updated dwm(1) 2006-08-11 10:54:29 +02:00
Anselm R.Garbe
84818bdbb5 upgraded version info 2006-08-11 10:28:51 +02:00
Anselm R.Garbe
895902b57a applied Sander's patch as well 2006-08-11 10:05:53 +02:00
Anselm R.Garbe
7d4184dc5c realized that client focussing through the bar is pretty useless, better is sloppy view focussing for B1/B3 as well instead 2006-08-11 10:00:47 +02:00
Anselm R.Garbe
8278f0a6be implemented focusprev on button1 press in the bar, and focusnext on button3 press in the bar 2006-08-11 09:16:40 +02:00
Anselm R.Garbe
d3969634ac simplified unmanage 2006-08-11 08:47:55 +02:00
Anselm R.Garbe
735ca9ccd6 removed the if(clients) check from popping code 2006-08-11 08:34:42 +02:00
Anselm R.Garbe
4ee661d908 added dwm favicon 2006-08-10 18:44:19 +02:00
Anselm R.Garbe
9fce8215b7 applied Sanders zoom_update patch 2006-08-10 17:48:50 +02:00
Anselm R.Garbe
6521c2dd41 respecting inc hints in floating mode on togglemax 2006-08-10 17:33:11 +02:00
Anselm R.Garbe
9ee9ce7e14 reverting last patch, that sucks, I don't care about retarded apps like gvim 2006-08-10 16:37:13 +02:00
Anselm R.Garbe
9d39da6452 togglemax repects inc-hints (this way gvim can be toggle'maxed as well) 2006-08-10 16:35:36 +02:00
Anselm R.Garbe
0228dcd58f applied grammar correction by ILF 2006-08-10 15:35:02 +02:00
Anselm R.Garbe
3d35ea99bb Added tag 0.8 for changeset cd15de32e173f8ce97bfe1c9b6607937b59056b4 2006-08-10 15:19:31 +02:00
Anselm R.Garbe
0680c76a6f prepared 0.8 2006-08-10 15:19:25 +02:00
Anselm R.Garbe
c3e5f5cc9a updated html 2006-08-10 13:30:39 +02:00
Anselm R.Garbe
1c620d27d8 fixed the issue reported by sander (gaps at left columns button due to round-offs) 2006-08-10 12:33:44 +02:00
Anselm R.Garbe
fde45ebed8 applied sumik's multihead patch 2006-08-10 11:26:32 +02:00
Anselm R.Garbe
4bd0d33f57 applied sander's patch 2006-08-10 11:19:25 +02:00
Anselm R.Garbe
00255728aa readded border color, this sucks least 2006-08-10 11:12:15 +02:00
Anselm R.Garbe
4b0328f209 drawing border with fg color 2006-08-10 11:07:27 +02:00
Anselm R.Garbe
30561a0161 removed unnecessary border color 2006-08-10 10:27:08 +02:00
Anselm R.Garbe
a4c4998c8b swapping my default colors (bg with fg) 2006-08-10 10:22:15 +02:00
Anselm R.Garbe
8e053b6476 made terminals darker, that is better indeed 2006-08-10 10:20:26 +02:00
Anselm R.Garbe
b79b5facb1 disallow zoom on maximized clients 2006-08-10 10:16:12 +02:00
Anselm R.Garbe
c53f0fca91 added zoom on Mod1-Button1 on managed clients only (there is no moving possible) 2006-08-09 18:37:33 +02:00
Anselm R.Garbe
c225e1afc2 removed NET_ACTIVE_WINDOW handling 2006-08-08 18:12:18 +02:00
Anselm R.Garbe
92e55c7c53 implemented NET_ACTIVE_WINDOW support 2006-08-08 17:08:45 +02:00
Anselm R.Garbe
c86f131681 fixed typo 2006-08-08 12:58:05 +02:00
Anselm R.Garbe
e943234d09 it always takes a while until one sticks to a colorscheme, but this one feels well 2006-08-08 12:50:11 +02:00
Anselm R.Garbe
9fc24e371b default colors are best 2006-08-08 12:47:45 +02:00
Anselm R.Garbe
cac467d52c without borders it looks cleaner 2006-08-08 11:47:29 +02:00
Anselm R.Garbe
04f17d2669 red is easier to my eyes with ffffaa bg 2006-08-08 11:18:05 +02:00
Anselm R.Garbe
dff15a02f7 using a better colorscheme (ffffaa is the best background for black) 2006-08-08 11:06:56 +02:00
Anselm R.Garbe
42277b1110 applied Sanders tiny patches 2006-08-08 09:30:45 +02:00
arg@10ksloc.org
095f9e143e removed some " 2006-08-07 17:38:14 +02:00
arg@10ksloc.org
9fbb2ebb90 I really only need 3 tags 2006-08-07 14:12:28 +02:00
arg@10ksloc.org
dbcf87ce76 added a trailing '.' to shortcut descriptions in dwm(1) 2006-08-07 14:10:22 +02:00
arg@10ksloc.org
4250c26e9b changed signature of drawtext 2006-08-07 13:54:59 +02:00
arg@10ksloc.org
e48de30516 applied grabbing-- and shell_minimal 2006-08-07 13:40:31 +02:00
arg@10ksloc.org
1f0060caa3 updated screenshot section 2006-08-07 12:26:28 +02:00
arg@10ksloc.org
c732cc90ab changed font size, I'm not blind... 2006-08-07 12:21:17 +02:00
arg@10ksloc.org
4e2c5b5f25 small fix of a comment 2006-08-07 12:12:56 +02:00
arg@10ksloc.org
d9386a0c07 typo fix 2006-08-07 11:58:46 +02:00
arg@10ksloc.org
66e16c92d3 applied Sanders man page/Makefile patch 2006-08-07 11:57:05 +02:00
arg@10ksloc.org
6a8e176df1 settle with grey 2006-08-07 11:10:19 +02:00
arg@10ksloc.org
632c7f3410 next version is 0.8 2006-08-07 10:32:36 +02:00
arg@10ksloc.org
045f1840e0 made my colors tasting better with the background 2006-08-07 10:28:21 +02:00
arg@10ksloc.org
45d16d090b status box should have a border in my eyes 2006-08-07 09:47:13 +02:00
arg@10ksloc.org
525c5ff4d8 next attempt for w on black switch 2006-08-07 09:41:43 +02:00
arg@10ksloc.org
5952157c3b Added tag 0.7 for changeset 3fb41412e2492f66476d92ce8f007a8b48fb1d2a 2006-08-07 08:55:39 +02:00
arg@10ksloc.org
f777d21899 prepared dwm.html 2006-08-07 08:51:43 +02:00
arg@10ksloc.org
82064af2d7 added stripping to dwm target in Makefile 2006-08-07 08:46:11 +02:00
arg@10ksloc.org
d54444cfd7 changed getproto, maybe that might fix the killclient issue reported on the list 2006-08-07 08:19:58 +02:00
arg@10ksloc.org
525ef3c178 applied endless loop prevention on zoom() 2006-08-07 08:05:04 +02:00
arg@10ksloc.org
5ef6ef1bac updated man page 2006-08-07 07:36:36 +02:00
arg@10ksloc.org
f4208e7cac small fix of the last commit 2006-08-05 14:57:26 +02:00
arg@10ksloc.org
ecc95c903b using -Os again, zoom is ignored in floating mode or on floating clients 2006-08-05 14:56:32 +02:00
arg@10ksloc.org
a207949b65 mouse grab needs also to grab for combinations of numlock/lockmask 2006-08-05 14:02:25 +02:00
arg@10ksloc.org
86d12249dd slight fix 2006-08-05 13:10:09 +02:00
arg@10ksloc.org
b098c94ed4 small performance tweak ;) 2006-08-04 18:34:40 +02:00
arg@10ksloc.org
6a39a496d0 fixed xterm font change (all other related apps should work fine with this fix as well) 2006-08-04 18:25:40 +02:00
arg@10ksloc.org
3d73084b5e fixed view-change bug reported on the list 2006-08-04 18:17:02 +02:00
arg@10ksloc.org
12b1d439e4 no need for -g anymore, regexp matching works now 2006-08-04 17:04:50 +02:00
arg@10ksloc.org
1076161bf3 fixed dmenu link (thx to deifl) 2006-08-04 15:47:50 +02:00
arg@10ksloc.org
e21d93b7bd switched to regexp matching for Rules 2006-08-04 14:40:32 +02:00
arg@10ksloc.org
f504aea132 fixed a bug in dmenu call 2006-08-04 13:42:40 +02:00
arg@10ksloc.org
9955ddc978 using execl now, argv changed, using cmd and const char defs directly in the KEYS struct 2006-08-04 12:00:55 +02:00
arg@10ksloc.org
0dfe729f90 added dmenu to dwm.html 2006-08-04 10:36:22 +02:00
arg@10ksloc.org
8f698bd4cc small stylistic fix 2006-08-04 10:27:16 +02:00
arg@10ksloc.org
99b126d0af removed CONFIG 2006-08-03 17:08:43 +02:00
arg@10ksloc.org
a2d56f6dce make config.h not a time dependence 2006-08-03 15:36:13 +02:00
arg@10ksloc.org
db876f9fb0 removed rm config.h from clean 2006-08-03 15:29:28 +02:00
arg@10ksloc.org
05a618b06e added gmake compliance 2006-08-03 15:21:08 +02:00
arg@10ksloc.org
72608f0d5a s/tag2/two/g 2006-08-03 15:09:52 +02:00
arg@10ksloc.org
bba044de4f applied Jukka's diff 2006-08-03 15:05:34 +02:00
arg@10ksloc.org
4d55eee754 applied Sanders Makefile patch 2006-08-03 13:50:37 +02:00
arg@10ksloc.org
d41b232b52 stylistic chnage 2006-08-03 12:21:00 +02:00
arg@10ksloc.org
b35575574b removed TLast tag enum, now tags is simple defined as char *[] array, the rest is calculated correctly, rules take an int array for the tags 2006-08-03 12:12:26 +02:00
arg@10ksloc.org
666b4563a0 hotfix of settags 2006-08-03 11:38:26 +02:00
arg@10ksloc.org
7315bb08ad using SRC instead of *.c 2006-08-03 11:27:29 +02:00
arg@10ksloc.org
f80688f1c7 changed the files included in make dist 2006-08-03 10:59:20 +02:00
arg@10ksloc.org
dc5c070c44 applied Sanders doc changes, added a PHONY line and changed the output of config.h creation somewhat 2006-08-03 10:58:29 +02:00
arg@10ksloc.org
8cc7f3bace changed Client->tags and Rule->tags to be Bool (I'll also try to remove the TLast enum) 2006-08-03 10:55:07 +02:00
arg@10ksloc.org
5d3fd3707b implemented the idea presented by Sander for dwm target 2006-08-02 17:49:21 +02:00
arg@10ksloc.org
1bf0c4a8e7 changing MASTERW value from 52 to 60 (in both, default and arg), I feel this is better now 2006-08-02 17:19:22 +02:00
arg@10ksloc.org
863656d2bc fixed a type in README, and patched config.mk 2006-08-02 17:12:00 +02:00
arg@10ksloc.org
f1a34ae1e4 updated dwm.html 2006-08-02 16:54:58 +02:00
arg@10ksloc.org
3000cad507 Added tag 0.6 for changeset c11f86db4550cac5d0a648a3fe4d6d3b9a4fcf7e 2006-08-02 16:52:21 +02:00
arg@10ksloc.org
0f8249f262 removed config.h (stupid hg) 2006-08-02 16:52:02 +02:00
arg@10ksloc.org
b515765216 removed the CONFIG variable from config.mk, renamed config.h into config.default.h, after first clone/extract one needs to copy config.default.h to config.h, that is easier than always heavy typing make CONFIG=blafasel 2006-08-02 16:46:59 +02:00
arg@10ksloc.org
85e6d59956 added Acroread.* and MPlayer.* to config.arg.h rules 2006-08-02 16:38:21 +02:00
arg@10ksloc.org
95e8d12b71 made fullscreen apps working fine in floating mode (there is no sane way to make them work in tiled mode, thus I switch to floating mode if I run such kind of app), also fixed the xterm issue reported by Sander 2006-08-02 16:32:05 +02:00
arg@10ksloc.org
a55f0e12fe new stuff 2006-08-02 13:05:04 +02:00
arg@10ksloc.org
0cf3ba0eab dwm is now exit, if stdin is closed due broken pipe 2006-08-02 12:33:24 +02:00
arg@10ksloc.org
1d85225952 implemented focus on enterwindow on titlebars 2006-08-02 11:28:27 +02:00
arg@10ksloc.org
3af6434085 applied Sanders patches (numlock2) 2006-08-02 11:13:32 +02:00
arg@10ksloc.org
57871415c1 reverting to old resize policy 2006-08-02 10:48:58 +02:00
arg@10ksloc.org
52021851d1 new resize stuff (using XConfigureWindow instead of XSendEvent) 2006-08-02 10:43:21 +02:00
arg@10ksloc.org
080a38d62d renamed WM_PROTOCOL_DELWIN into PROTODELWIN 2006-08-01 16:44:23 +02:00
arg@10ksloc.org
ab7a11c0c7 renamed ARRANGE into DEFMODE 2006-08-01 16:39:20 +02:00
arg@10ksloc.org
d8675f6f30 small fixes to dwm.html 2006-08-01 16:35:54 +02:00
arg@10ksloc.org
eff4478c2d simplified README 2006-08-01 16:29:25 +02:00
arg@10ksloc.org
81683351f0 removed 1 missing LOC 2006-08-01 16:20:29 +02:00
arg@10ksloc.org
b38905b004 removed 5LOC 2006-08-01 16:20:03 +02:00
arg@10ksloc.org
d9a6a3b5d2 removed artefacts of single-linked list (thanx to Jukka, I must have been mad) 2006-08-01 16:14:17 +02:00
arg@10ksloc.org
7c2e3bb67d cleaned config.*h to prevent some confusion 2006-08-01 15:29:37 +02:00
arg@10ksloc.org
b01a51a844 saved 2LOC 2006-08-01 15:16:29 +02:00
arg@10ksloc.org
77f8c075c4 uppercasing all define'd values (uppercase-prefixed should only be enum field qualifiers) 2006-08-01 14:46:01 +02:00
arg@10ksloc.org
33b4821cd6 fixed config.h files 2006-08-01 14:03:29 +02:00
arg@10ksloc.org
a73a882806 centralized/externalized configuration to config.h 2006-08-01 13:59:13 +02:00
arg@10ksloc.org
57416beefe applied Cedric's NumLock patch 2006-08-01 12:41:38 +02:00
arg@10ksloc.org
1b63f832c5 applied Jukkas prev/next patch with XK_{h,l} 2006-08-01 12:39:14 +02:00
arg@10ksloc.org
7b5638f61d applied Sanders patches 2006-08-01 12:32:33 +02:00
arg@10ksloc.org
937cabfa0a committed a patch which fixes the hints of Jukka 2006-08-01 11:49:19 +02:00
arg@10ksloc.org
deba5069e5 updated html 2006-07-21 21:15:39 +02:00
arg@10ksloc.org
956113b295 Added tag 0.5 for changeset 22213b9a2114167ee8ba019a012e27da0422a61a 2006-07-21 21:15:11 +02:00
arg@10ksloc.org
db98a7d60f prepared 0.5 2006-07-21 21:15:08 +02:00
arg@10ksloc.org
0464e42231 some cleanups/fixes inspired by Jukka Salmi's feedback 2006-07-21 18:34:10 +02:00
arg@10ksloc.org
4970ef938e simplified main.c, switching back to single urxvt usage 2006-07-21 14:11:38 +02:00
arg@10ksloc.org
f85b163899 s/sleep 5/sleep 2/ 2006-07-21 11:54:14 +02:00
arg@10ksloc.org
2b66f7afb1 changed the status info README hint (more simple now, no extra script necessary) 2006-07-21 11:48:28 +02:00
arg@10ksloc.org
67b3083dfd s/0.5/0.6/ - my steps are wider than the reality 2006-07-21 10:18:12 +02:00
arg@10ksloc.org
0c7bcc24cb applied sanders maxfix patch 2006-07-21 10:07:41 +02:00
arg@10ksloc.org
98c6a92eb5 added a note how to achieve status info in the bar 2006-07-21 09:59:11 +02:00
arg@10ksloc.org
ba59bc8b9f preparing 0.6 which will be available in the evening after sanders patch approx. 2006-07-21 09:39:44 +02:00
arg@10ksloc.org
cd8d8e1208 sanitization of several clunky stuff, removed heretag (rarely of use), simplified pop(), changed shortcuts to always contain MODKEY 2006-07-21 07:37:52 +02:00
arg@10ksloc.org
04eb016e78 applied sanders no_sizehints for tiled mode patch (thx!) 2006-07-20 19:09:11 +02:00
arg@10ksloc.org
0a4342098b serious mistake in pop() (forgot to set c->prev to NULL on pop) 2006-07-20 18:23:43 +02:00
arg@10ksloc.org
72707c2fae using double-linked list in order to get correct prev focus handling 2006-07-20 16:54:20 +02:00
arg@10ksloc.org
06dc514bc7 added yet another CUTOMIZE tag 2006-07-20 15:40:41 +02:00
arg@10ksloc.org
2b5553b1eb cleaned the CUSTOMIZE flags 2006-07-20 15:17:52 +02:00
arg@10ksloc.org
4688ad181d made status bar drawing more robust, implemented togglemax and togglemode, works quite well 2006-07-20 15:07:35 +02:00
arg@10ksloc.org
dc5d967ee6 cleaned up code 2006-07-20 12:18:06 +02:00
arg@10ksloc.org
fe3756c8e1 Added tag 0.4 for changeset eb3165734f00fe7f7da8aeebaed00e60a57caac9 2006-07-20 10:48:22 +02:00
arg@10ksloc.org
01b151f5f8 prepared 0.4 2006-07-20 10:48:19 +02:00
arg@10ksloc.org
8bb4a93f2b using O3 instead of Os, binary size still < 40kb 2006-07-20 10:26:36 +02:00
arg@10ksloc.org
5ec04b7726 fixed version in man page 2006-07-20 10:15:05 +02:00
arg@10ksloc.org
3657eaedf3 yet another html patch 2006-07-20 10:12:41 +02:00
arg@10ksloc.org
9291283a18 updated html 2006-07-20 10:10:58 +02:00
arg@10ksloc.org
eccd02def2 makefile now sets permissions for executables and man pages 2006-07-20 09:45:47 +02:00
arg@10ksloc.org
11737233a7 removed c->f{x,y,w,h} and c->t{x,y,w,h} in favor for the new rule handling remembering two kinds of geometries is unnecessary, removed the randomized (x,y) setting on dofloat startup, was kind too random und unpredictable 2006-07-20 07:26:23 +02:00
arg@10ksloc.org
bcaf6a7a0f implemented regexp matching for rules 2006-07-19 17:42:08 +02:00
arg@10ksloc.org
f95eed34b4 applied Jukka's patch with s/ModKeyMask/MODKEY/g 2006-07-19 16:38:39 +02:00
arg@10ksloc.org
1eaffa372f removed TODO, because dwm is nearly finished 2006-07-19 15:03:53 +02:00
arg@10ksloc.org
b1697e8d5f reapplied my default keybindings 2006-07-19 14:54:19 +02:00
arg@10ksloc.org
801d11c7e7 alternate dwm.png 2006-07-19 14:49:19 +02:00
arg@10ksloc.org
1b855fccd7 Added tag 0.3 for changeset 7e66082e5092fb0bccd18a3695a0bec52c80fdb2 2006-07-19 14:44:44 +02:00
arg@10ksloc.org
d34b4c7b9a some changes in the html page 2006-07-19 14:44:24 +02:00
arg@10ksloc.org
1f9614f82e prepared 0.3 2006-07-19 14:43:17 +02:00
arg@10ksloc.org
4491bdda69 fixed the bug mentioned by Sander 2006-07-19 14:11:27 +02:00
arg@10ksloc.org
8af1d97332 refactored Sanders code somewhat 2006-07-19 13:52:31 +02:00
arg@10ksloc.org
79cd408844 implemented fallback for too many clients in stacked mode 2006-07-19 13:36:04 +02:00
arg@10ksloc.org
18be893b66 and another fix... 2006-07-19 13:30:18 +02:00
arg@10ksloc.org
0fb1842fd0 yet another typo fix 2006-07-19 13:29:45 +02:00
arg@10ksloc.org
f522930a99 fixed a typo 2006-07-19 13:24:58 +02:00
arg@10ksloc.org
aebd745f72 floating clients get random (x,y) offsets now 2006-07-19 13:22:49 +02:00
arg@10ksloc.org
c53980cddc applied Sanders resize patch, fixed lower bug 2006-07-19 11:31:04 +02:00
arg@mmvi
95e56ffc0d changed CFLAGs 2006-07-18 17:54:55 +02:00
arg@mmvi
f1294353f2 firefox instance is different now 2006-07-18 15:10:57 +02:00
Anselm R. Garbe
6649dcce6d changed occurrences of wmii.de into 10kloc.org in dwm.html, because 10kloc.org is already working 2006-07-18 13:01:33 +02:00
Anselm R. Garbe
58f2fe3f6a implemened distinguishing float/managed geometries of clients (works quite well) 2006-07-18 12:36:57 +02:00
Anselm R. Garbe
0aaa9a21f3 pop on heretag 2006-07-18 11:45:32 +02:00
Anselm R. Garbe
4f8b08d330 added heretag command which allows to tag a client of a foreign tag with current tag 2006-07-18 11:38:31 +02:00
Anselm R. Garbe
849e631510 using EXIT_stuff in exit() now 2006-07-18 08:18:54 +02:00
Anselm R. Garbe
789717d109 simplified Makefile 2006-07-17 18:49:13 +02:00
Anselm R. Garbe
605630c145 added new stuff 2006-07-17 16:46:42 +02:00
Anselm R. Garbe
1e7e57dad3 updated html 2006-07-17 11:56:27 +02:00
Anselm R. Garbe
eb184e02ea patched dwm 2006-07-17 11:36:07 +02:00
Anselm R. Garbe
ed41473634 updated README 2006-07-17 10:09:57 +02:00
Anselm R. Garbe
ee5ba14431 Added tag 0.2 for changeset 0a6472e2203994bc5738d40a340d26f7ec9d6062 2006-07-17 10:00:59 +02:00
20 changed files with 1401 additions and 922 deletions

10
.hgtags
View File

@@ -1 +1,11 @@
d31b5ad96b0ba7b5b0a30928fcf000428339a577 0.1
0a6472e2203994bc5738d40a340d26f7ec9d6062 0.2
7e66082e5092fb0bccd18a3695a0bec52c80fdb2 0.3
eb3165734f00fe7f7da8aeebaed00e60a57caac9 0.4
22213b9a2114167ee8ba019a012e27da0422a61a 0.5
c11f86db4550cac5d0a648a3fe4d6d3b9a4fcf7e 0.6
3fb41412e2492f66476d92ce8f007a8b48fb1d2a 0.7
cd15de32e173f8ce97bfe1c9b6607937b59056b4 0.8
fae61afa861755636c4a1070694209ace8efbb6c 0.9
bbc98e77ae89a7c9232a5be0835f60ea00d8036e 1.0
44a55e6e46bf6c231780b09d919977d6f01083de 1.1

View File

@@ -1,6 +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>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),

View File

@@ -3,53 +3,60 @@
include config.mk
SRC = client.c draw.c event.c main.c tag.c util.c
SRC = client.c draw.c event.c main.c tag.c util.c view.c
OBJ = ${SRC:.c=.o}
MAN1 = dwm.1
BIN = dwm
all: config dwm
@echo finished
all: options dwm
config:
options:
@echo dwm build options:
@echo "LIBS = ${LIBS}"
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
@echo "LD = ${LD}"
.c.o:
@echo CC $<
@${CC} -c ${CFLAGS} $<
${OBJ}: dwm.h
${OBJ}: dwm.h config.h config.mk
config.h:
@echo creating $@ from config.default.h
@cp config.default.h $@
dwm: ${OBJ}
@echo LD $@
@${CC} -o $@ ${OBJ} ${LDFLAGS}
@${LD} -o $@ ${OBJ} ${LDFLAGS}
@strip $@
clean:
rm -f dwm *.o core dwm-${VERSION}.tar.gz
@echo cleaning
@rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
dist: clean
mkdir -p dwm-${VERSION}
cp -R Makefile README LICENSE config.mk *.h *.c ${MAN1} dwm-${VERSION}
tar -cf dwm-${VERSION}.tar dwm-${VERSION}
gzip dwm-${VERSION}.tar
rm -rf dwm-${VERSION}
@echo creating dist tarball
@mkdir -p dwm-${VERSION}
@cp -R LICENSE Makefile README config.*.h config.mk \
dwm.1 dwm.h ${SRC} dwm-${VERSION}
@tar -cf dwm-${VERSION}.tar dwm-${VERSION}
@gzip dwm-${VERSION}.tar
@rm -rf dwm-${VERSION}
install: all
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
@mkdir -p ${DESTDIR}${PREFIX}/bin
@cp -f ${BIN} ${DESTDIR}${PREFIX}/bin
@echo installed executable files to ${DESTDIR}${PREFIX}/bin
@cp -f dwm ${DESTDIR}${PREFIX}/bin
@chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
@mkdir -p ${DESTDIR}${MANPREFIX}/man1
@cp -f ${MAN1} ${DESTDIR}${MANPREFIX}/man1
@echo installed manual pages to ${DESTDIR}${MANPREFIX}/man1
@sed 's/VERSION/${VERSION}/g' < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
uninstall:
for i in ${BIN}; do \
rm -f ${DESTDIR}${PREFIX}/bin/`basename $$i`; \
done
for i in ${MAN1}; do \
rm -f ${DESTDIR}${MANPREFIX}/man1/`basename $$i`; \
done
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
@rm -f ${DESTDIR}${PREFIX}/bin/dwm
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
@rm -f ${DESTDIR}${MANPREFIX}/man1/dwm.1
.PHONY: all options clean dist install uninstall

22
README
View File

@@ -1,7 +1,6 @@
dwm - dynamic window manager
----------------------------
dwm is an extremly fast, small, and dynamic X11 window manager.
dwm is an extremely fast, small, and dynamic window manager for X.
Requirements
@@ -11,8 +10,8 @@ In order to build dwm you need the Xlib header files.
Installation
------------
Edit config.mk to match your local setup. dwm is installed into
the /usr/local namespace by default.
Edit config.mk to match your local setup (dwm is installed into
the /usr/local namespace by default).
Afterwards enter the following command to build and install dwm (if
necessary as root):
@@ -31,10 +30,19 @@ the DISPLAY environment variable is set correctly, e.g.:
DISPLAY=foo.bar:1 exec dwm
This will start dwm on display :1 of the host foo.bar.
(This will start dwm on display :1 of the host foo.bar.)
In order to display status info in the bar, you can do something
like this in your .xinitrc:
while true
do
echo `date` `uptime | sed 's/.*://; s/,//g'`
sleep 1
done | dwm
Configuration
-------------
The configuration of dwm is done by customizing the wm.h source file. To
customize the key bindings edit dev.c.
The configuration of dwm is done by creating a custom config.h
and (re)compiling the source code.

1
TODO
View File

@@ -1 +0,0 @@
- improve mouse based resizals with quadrant approach (then I think we have feature completeness already)

365
client.c
View File

@@ -3,7 +3,6 @@
* See LICENSE file for license details.
*/
#include "dwm.h"
#include <stdlib.h>
#include <string.h>
#include <X11/Xatom.h>
@@ -11,21 +10,58 @@
/* static functions */
static void
grabbuttons(Client *c, Bool focus)
{
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
if(focus) {
XGrabButton(dpy, Button1, MODKEY, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button1, MODKEY | LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button1, MODKEY | numlockmask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button1, MODKEY | numlockmask | LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, MODKEY, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, MODKEY | LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, MODKEY | numlockmask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, MODKEY | numlockmask | LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, MODKEY, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, MODKEY | LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, MODKEY | numlockmask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, MODKEY | numlockmask | LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
}
else
XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
}
static void
resizetitle(Client *c)
{
int i;
c->tw = 0;
for(i = 0; i < TLast; i++)
if(c->tags[i])
c->tw += textw(c->tags[i]);
c->tw += textw(c->name);
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;
XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
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);
}
static int
@@ -40,59 +76,35 @@ void
ban(Client *c)
{
XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
XMoveWindow(dpy, c->title, c->tx + 2 * sw, c->ty);
XMoveWindow(dpy, c->twin, c->tx + 2 * sw, c->ty);
}
void
focus(Client *c)
{
Client *old = sel;
XEvent ev;
sel = c;
if(old && old != c)
if(!issel)
return;
if(!sel)
sel = c;
else if(sel != c) {
if(sel->ismax)
togglemax(NULL);
sel = c;
grabbuttons(old, False);
drawtitle(old);
}
grabbuttons(c, True);
drawtitle(c);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
XSync(dpy, False);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}
void
focusnext(Arg *arg)
{
Client *c;
if(!sel)
return;
if(!(c = getnext(sel->next)))
c = getnext(clients);
if(c) {
higher(c);
c->revert = sel;
focus(c);
}
}
void
focusprev(Arg *arg)
{
Client *c;
if(!sel)
return;
if((c = sel->revert && sel->revert->tags[tsel] ? sel->revert : NULL)) {
higher(c);
focus(c);
}
}
Client *
getclient(Window w)
{
Client *c;
for(c = clients; c; c = c->next)
if(c->win == w)
return c;
@@ -103,8 +115,9 @@ Client *
getctitle(Window w)
{
Client *c;
for(c = clients; c; c = c->next)
if(c->title == w)
if(c->twin == w)
return c;
return NULL;
}
@@ -115,6 +128,8 @@ gravitate(Client *c, Bool invert)
int dx = 0, dy = 0;
switch(c->grav) {
default:
break;
case StaticGravity:
case NorthWestGravity:
case NorthGravity:
@@ -129,13 +144,13 @@ gravitate(Client *c, Bool invert)
case SouthEastGravity:
case SouthGravity:
case SouthWestGravity:
dy = -c->h;
break;
default:
dy = -(c->h);
break;
}
switch (c->grav) {
default:
break;
case StaticGravity:
case NorthWestGravity:
case WestGravity:
@@ -152,8 +167,6 @@ gravitate(Client *c, Bool invert)
case SouthEastGravity:
dx = -(c->w + c->border);
break;
default:
break;
}
if(invert) {
@@ -164,154 +177,130 @@ gravitate(Client *c, Bool invert)
c->y += dy;
}
void
higher(Client *c)
{
XRaiseWindow(dpy, c->win);
XRaiseWindow(dpy, c->title);
}
void
killclient(Arg *arg)
{
if(!sel)
return;
if(sel->proto & WM_PROTOCOL_DELWIN)
if(sel->proto & PROTODELWIN)
sendevent(sel->win, wmatom[WMProtocols], wmatom[WMDelete]);
else
XKillClient(dpy, sel->win);
}
void
lower(Client *c)
{
XLowerWindow(dpy, c->title);
XLowerWindow(dpy, c->win);
}
void
manage(Window w, XWindowAttributes *wa)
{
Client *c;
XSetWindowAttributes twa;
unsigned int i;
Client *c, *tc;
Window trans;
XSetWindowAttributes twa;
c = emallocz(sizeof(Client));
c->tags = emallocz(ntags * sizeof(Bool));
c->win = w;
c->tx = c->x = wa->x;
c->ty = c->y = wa->y;
if(c->y < bh)
c->ty = c->y += bh;
c->tw = c->w = wa->width;
c->x = c->tx = wa->x;
c->y = c->ty = wa->y;
c->w = c->tw = wa->width;
c->h = wa->height;
c->th = bh;
c->border = 1;
c->proto = getproto(c->win);
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);
XSelectInput(dpy, c->win,
StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
XGetTransientForHint(dpy, c->win, &trans);
twa.override_redirect = 1;
twa.background_pixmap = ParentRelative;
twa.event_mask = ExposureMask;
twa.event_mask = ExposureMask | EnterWindowMask;
c->title = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th,
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);
settitle(c);
settags(c);
grabbuttons(c, False);
if((tc = getclient(trans))) /* inherit tags */
for(i = 0; i < ntags; i++)
c->tags[i] = tc->tags[i];
else
settags(c);
if(!c->isfloat)
c->isfloat = trans
|| (c->maxw && c->minw &&
c->maxw == c->minw && c->maxh == c->minh);
if(clients)
clients->prev = c;
c->next = clients;
clients = c;
XGrabButton(dpy, Button1, ControlMask, c->win, False, ButtonPressMask,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button1, Mod1Mask, c->win, False, ButtonPressMask,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, Mod1Mask, c->win, False, ButtonPressMask,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, Mod1Mask, c->win, False, ButtonPressMask,
GrabModeAsync, GrabModeSync, None, None);
if(!c->isfloat)
c->isfloat = trans
|| ((c->maxw == c->minw) && (c->maxh == c->minh));
settitle(c);
if(isvisible(c))
sel = c;
arrange(NULL);
/* mapping the window now prevents flicker */
if(c->tags[tsel]) {
XMapRaised(dpy, c->win);
XMapRaised(dpy, c->title);
XMapWindow(dpy, c->win);
XMapWindow(dpy, c->twin);
if(isvisible(c))
focus(c);
}
else {
ban(c);
XMapRaised(dpy, c->win);
XMapRaised(dpy, c->title);
XSync(dpy, False);
}
}
void
maximize(Arg *arg)
resize(Client *c, Bool sizehints, Corner sticky)
{
if(!sel)
return;
sel->x = sx;
sel->y = sy + bh;
sel->w = sw - 2 * sel->border;
sel->h = sh - 2 * sel->border - bh;
higher(sel);
resize(sel, False);
}
int bottom = c->y + c->h;
int right = c->x + c->w;
XWindowChanges wc;
void
resize(Client *c, Bool inc)
{
XConfigureEvent e;
if(inc) {
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)
c->h = c->minh;
if(c->maxw && c->w > c->maxw)
c->w = c->maxw;
if(c->maxh && c->h > c->maxh)
c->h = c->maxh;
}
if(c->x > sw) /* might happen on restart */
c->x = sw - c->w;
if(c->y > sh)
c->ty = c->y = sh - c->h;
if(c->minw && c->w < c->minw)
c->w = c->minw;
if(c->minh && c->h < c->minh)
c->h = c->minh;
if(c->maxw && c->w > c->maxw)
c->w = c->maxw;
if(c->maxh && c->h > c->maxh)
c->h = c->maxh;
if(sticky == TopRight || sticky == BotRight)
c->x = right - c->w;
if(sticky == BotLeft || sticky == BotRight)
c->y = bottom - c->h;
resizetitle(c);
XSetWindowBorderWidth(dpy, c->win, 1);
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
e.type = ConfigureNotify;
e.event = c->win;
e.window = c->win;
e.x = c->x;
e.y = c->y;
e.width = c->w;
e.height = c->h;
e.border_width = c->border;
e.above = None;
e.override_redirect = False;
XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&e);
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);
XSync(dpy, False);
}
void
setsize(Client *c)
{
XSizeHints size;
long msize;
XSizeHints size;
if(!XGetWMNormalHints(dpy, c->win, &size, &msize) || !size.flags)
size.flags = PSize;
c->flags = size.flags;
@@ -348,9 +337,9 @@ setsize(Client *c)
void
settitle(Client *c)
{
XTextProperty name;
int n;
char **list = NULL;
int n;
XTextProperty name;
name.nitems = 0;
c->name[0] = 0;
@@ -373,53 +362,65 @@ settitle(Client *c)
resizetitle(c);
}
void
togglemax(Arg *arg)
{
int ox, oy, ow, oh;
XEvent ev;
if(!sel)
return;
if((sel->ismax = !sel->ismax)) {
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();
resize(sel, arrange == dofloat, TopLeft);
sel->x = ox;
sel->y = oy;
sel->w = ow;
sel->h = oh;
}
else
resize(sel, False, TopLeft);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}
void
unmanage(Client *c)
{
Client **l;
Client *tc;
Window trans;
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
XGetTransientForHint(dpy, c->win, &trans);
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
XDestroyWindow(dpy, c->title);
for(l = &clients; *l && *l != c; l = &(*l)->next);
*l = c->next;
for(l = &clients; *l; l = &(*l)->next)
if((*l)->revert == c)
(*l)->revert = NULL;
if(sel == c)
sel = sel->revert ? sel->revert : clients;
XDestroyWindow(dpy, c->twin);
detach(c);
if(sel == c) {
if(trans && (tc = getclient(trans)) && isvisible(tc))
sel = tc;
else
sel = getnext(clients);
}
free(c->tags);
free(c);
XSync(dpy, False);
XSetErrorHandler(xerror);
XUngrabServer(dpy);
arrange(NULL);
if(sel)
focus(sel);
}
void
zoom(Arg *arg)
{
Client **l, *c;
if(!sel)
return;
if(sel == getnext(clients) && sel->next) {
if((c = getnext(sel->next)))
sel = c;
}
for(l = &clients; *l && *l != sel; l = &(*l)->next);
*l = sel->next;
sel->next = clients; /* pop */
clients = sel;
arrange(NULL);
focus(sel);
}

65
config.arg.h Normal file
View File

@@ -0,0 +1,65 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#define TAGS \
const char *tags[] = { "dev", "work", "net", "fnord", NULL };
#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 MODKEY Mod1Mask
#define MASTERW 60 /* percent */
#define KEYS \
static Key key[] = { \
/* modifier key function arguments */ \
{ MODKEY|ShiftMask, XK_Return, spawn, \
{ .cmd = "exec uxterm -bg '#111111' -fg '#eeeeee' -cr '#eeeeee' +sb -fn '"FONT"'" } }, \
{ MODKEY, XK_p, spawn, \
{ .cmd = "exec \"$(IFS=:; for dir in $PATH; do " \
"for file in \"$dir\"/*; do [ -x \"$file\" ] && echo \"${file##*/}\"; done; " \
"done | sort -u | dmenu)\"" } }, \
{ MODKEY, XK_j, focusnext, { 0 } }, \
{ MODKEY, XK_k, focusprev, { 0 } }, \
{ MODKEY, XK_Return, zoom, { 0 } }, \
{ MODKEY, XK_m, togglemax, { 0 } }, \
{ 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|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|ShiftMask, XK_c, killclient, { 0 } }, \
{ MODKEY, XK_space, togglemode, { 0 } }, \
{ 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|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|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}, \
};

64
config.default.h Normal file
View File

@@ -0,0 +1,64 @@
/*
* (C)opyright MMVI 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 };
#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 MODKEY Mod1Mask
#define MASTERW 60 /* percent */
#define KEYS \
static Key key[] = { \
/* modifier key function arguments */ \
{ 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|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|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|ShiftMask, XK_c, killclient, { 0 } }, \
{ MODKEY, XK_space, togglemode, { 0 } }, \
{ 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|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|ShiftMask, XK_q, quit, { 0 } }, \
};
/* Query class:instance:title for regex matching info with following command:
* xprop | awk -F '"' '/^WM_CLASS/ { printf("%s:%s:",$4,$2) }; /^WM_NAME/ { printf("%s\n",$2) }' */
#define RULES \
static Rule rule[] = { \
/* class:instance:title regex tags regex isfloat */ \
{ "Firefox.*", "2", False }, \
{ "Gimp.*", NULL, True}, \
};

View File

@@ -1,31 +1,25 @@
# Customize to fit your system
# dwm version
VERSION = 1.2
# Customize below to fit your system
# paths
PREFIX = /usr/local
CONFPREFIX = ${PREFIX}/etc
MANPREFIX = ${PREFIX}/share/man
X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib
VERSION = 0.2
# includes and libs
LIBS = -L${PREFIX}/lib -L/usr/lib -lc -L${X11LIB} -lX11
INCS = -I. -I/usr/include -I${X11INC}
LIBS = -L/usr/lib -lc -L${X11LIB} -lX11
# Linux/BSD
#CFLAGS = -Os -I. -I${PREFIX}/include -I/usr/include -I${X11INC} \
# -DVERSION=\"${VERSION}\"
#LDFLAGS = ${LIBS}
CFLAGS = -g -Wall -O2 -I. -I${PREFIX}/include -I/usr/include -I${X11INC} \
-DVERSION=\"${VERSION}\"
LDFLAGS = -g ${LIBS}
# flags
CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\"
LDFLAGS = ${LIBS}
#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = -g ${LIBS}
# Solaris
#CFLAGS = -fast -xtarget=ultra ${INCLUDES} -DVERSION=\"${VERSION}\"
#LIBS += -lnsl -lsocket
AR = ar cr
# compiler and linker
CC = cc
RANLIB = ranlib
LD = ${CC}

134
draw.c
View File

@@ -3,36 +3,17 @@
* See LICENSE file for license details.
*/
#include "dwm.h"
#include <stdio.h>
#include <string.h>
#include <X11/Xlocale.h>
/* static */
static void
drawborder(void)
{
XPoint points[5];
XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
XSetForeground(dpy, dc.gc, dc.border);
points[0].x = dc.x;
points[0].y = dc.y;
points[1].x = dc.w - 1;
points[1].y = 0;
points[2].x = 0;
points[2].y = dc.h - 1;
points[3].x = -(dc.w - 1);
points[3].y = 0;
points[4].x = 0;
points[4].y = -(dc.h - 1);
XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious);
}
static unsigned int
textnw(char *text, unsigned int len)
textnw(const char *text, unsigned int len)
{
XRectangle r;
if(dc.font.set) {
XmbTextExtents(dc.font.set, text, len, NULL, &r);
return r.width;
@@ -41,25 +22,22 @@ textnw(char *text, unsigned int len)
}
static void
drawtext(const char *text, Bool invert, Bool border)
drawtext(const char *text, unsigned long col[ColLast], Bool highlight)
{
int x, y, w, h;
unsigned int len;
static char buf[256];
unsigned int len, olen;
XGCValues gcv;
XRectangle r = { dc.x, dc.y, dc.w, dc.h };
XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg);
XSetForeground(dpy, dc.gc, col[ColBG]);
XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
w = 0;
if(border)
drawborder();
if(!text)
return;
len = strlen(text);
w = 0;
olen = len = strlen(text);
if(len >= sizeof(buf))
len = sizeof(buf) - 1;
memcpy(buf, text, len);
@@ -72,21 +50,32 @@ drawtext(const char *text, Bool invert, Bool border)
/* shorten text if necessary */
while(len && (w = textnw(buf, len)) > dc.w - h)
buf[--len] = 0;
if(len < olen) {
if(len > 1)
buf[len - 1] = '.';
if(len > 2)
buf[len - 2] = '.';
if(len > 3)
buf[len - 3] = '.';
}
if(w > dc.w)
return; /* too long */
gcv.foreground = invert ? dc.bg : dc.fg;
gcv.background = invert ? dc.fg : dc.bg;
gcv.foreground = col[ColFG];
if(dc.font.set) {
XChangeGC(dpy, dc.gc, GCForeground | GCBackground, &gcv);
XmbDrawImageString(dpy, dc.drawable, dc.font.set, dc.gc,
x, y, buf, len);
XChangeGC(dpy, dc.gc, GCForeground, &gcv);
XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
}
else {
gcv.font = dc.font.xfont->fid;
XChangeGC(dpy, dc.gc, GCForeground | GCBackground | GCFont, &gcv);
XDrawImageString(dpy, dc.drawable, dc.gc, x, y, buf, len);
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;
XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
}
}
@@ -105,31 +94,38 @@ drawall()
void
drawstatus()
{
int i;
Bool istile = arrange == dotile;
int i, x;
dc.x = dc.y = 0;
dc.w = bw;
drawtext(NULL, !istile, False);
dc.w = 0;
for(i = 0; i < TLast; i++) {
dc.x += dc.w;
for(i = 0; i < ntags; i++) {
dc.w = textw(tags[i]);
if(istile)
drawtext(tags[i], (i == tsel), True);
if(seltag[i])
drawtext(tags[i], dc.sel, sel && sel->tags[i]);
else
drawtext(tags[i], (i != tsel), True);
}
if(sel) {
drawtext(tags[i], dc.norm, sel && sel->tags[i]);
dc.x += dc.w;
dc.w = textw(sel->name);
drawtext(sel->name, istile, True);
}
dc.w = bmw;
drawtext(arrange == dotile ? TILESYMBOL : FLOATSYMBOL, dc.status, False);
x = dc.x + dc.w;
dc.w = textw(stext);
dc.x = bx + bw - dc.w;
drawtext(stext, !istile, False);
if(dc.x < x) {
dc.x = x;
dc.w = bw - x;
}
drawtext(stext, dc.status, 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);
}
XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
XSync(dpy, False);
}
@@ -137,41 +133,27 @@ drawstatus()
void
drawtitle(Client *c)
{
int i;
Bool istile = arrange == dotile;
if(c == sel) {
if(c == sel && issel) {
drawstatus();
XUnmapWindow(dpy, c->title);
XSetWindowBorder(dpy, c->win, dc.fg);
XUnmapWindow(dpy, c->twin);
XSetWindowBorder(dpy, c->win, dc.sel[ColBG]);
return;
}
XSetWindowBorder(dpy, c->win, dc.bg);
XMapWindow(dpy, c->title);
XSetWindowBorder(dpy, c->win, dc.norm[ColBG]);
XMapWindow(dpy, c->twin);
dc.x = dc.y = 0;
dc.w = 0;
for(i = 0; i < TLast; i++) {
if(c->tags[i]) {
dc.x += dc.w;
dc.w = textw(c->tags[i]);
drawtext(c->tags[i], !istile, True);
}
}
dc.x += dc.w;
dc.w = textw(c->name);
drawtext(c->name, !istile, True);
XCopyArea(dpy, dc.drawable, c->title, dc.gc, 0, 0, c->tw, c->th, 0, 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);
XSync(dpy, False);
}
unsigned long
getcolor(const char *colstr)
{
XColor color;
Colormap cmap = DefaultColormap(dpy, screen);
XColor color;
XAllocNamedColor(dpy, cmap, colstr, &color, &color);
return color.pixel;
@@ -229,7 +211,7 @@ setfont(const char *fontstr)
}
unsigned int
textw(char *text)
textw(const char *text)
{
return textnw(text, strlen(text)) + dc.font.height;
}

184
dwm.1
View File

@@ -1,4 +1,4 @@
.TH DWM 1 dwm-0.2
.TH DWM 1 dwm-VERSION
.SH NAME
dwm \- dynamic window manager
.SH SYNOPSIS
@@ -6,114 +6,150 @@ dwm \- dynamic window manager
.RB [ \-v ]
.SH DESCRIPTION
.B dwm
is a dynamic window manager for X11. It manages windows in tiling and floating
modes. Either mode can be applied dynamically, depending on the application in
use and the task performed.
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 needs most attention at a time, whereas the
stacking column contains all other windows in a stack. Dialog windows are
managed floating, however. In floating mode windows can be resized and moved
freely.
column contains the window which currently needs most attention, whereas the
stacking column 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.
.P
Windows are grouped by tags. All windows with a specific tag can be viewed at a
time. But each window may contain more than one tag, which makes it visible in
several views.
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.
.P
.B dwm
consists of a small status bar which reads the text displayed from standard
input, if written. It draws 1-pixel borders around windows to indicate the
focus state. Unfocused windows contain a small bar in front of the window
displaying the tags and the window title.
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.
.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.
.SH OPTIONS
.TP
.B \-v
prints version information to standard output, then exits.
.SH USAGE
.SS Status bar
.TP
.B Standard input
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.
.TP
.B Button3
click on a tag label adds/removes all windows with that
.B tag
to/from the view.
.SS Keyboard commands
.TP
.B Mod1-Shift-Return
Start
.BR xterm (1).
.TP
.B Mod1-Tab
Focus next
.BR window .
.TP
.B Mod1-Shift-Tab
Focus previous
.BR window .
.TP
.B Mod1-Return
Zoom
Zoom current
.B window
to the
.B master
column
.TP
.B Mod1-k
Focus previous
.B window
.TP
.B Mod1-j
Focus next
.B window
.RB ( tiling
mode only).
.TP
.B Mod1-m
Maximize current
.B window
.TP
.B Mod1-[0..n]
Focus
.B nth
tag
.TP
.B Mod1-space
(Re-)arrange
.B all
windows tiled
.TP
.B Mod1-Shift-space
(Re-)arrange
.B all
windows floating
.BR window .
.TP
.B Mod1-Shift-[0..n]
Apply
.B nth
tag to current
.B window
.B nth tag
to current
.BR window .
.TP
.B Mod1-Control-Shift-[0..n]
Add/remove
.B nth tag
to/from current
.BR window .
.TP
.B Mod1-Shift-c
Close focused
.B window.
.TP
.B Mod1-space
Toggle between
.B tiled
and
.B floating
mode (affects
.BR "all windows" ).
.TP
.B Mod1-[0..n]
View all windows with
.BR "tag n" .
.TP
.B Mod1-Control-[0..n]
Add/remove all windows with
.B tag n
to/from the view.
.TP
.B Mod1-Shift-q
Quit
.B dwm
.TP
.B Mod1-Shift-Return
Start
.B terminal
.TP
.B Mod1-Shift-w
Start
.B web browser
.TP
.B Mod1-Shift-l
Lock
.B screen
.TP
.B Control-[0..n]
Append
.B nth
tag to cureent
.B window
.TP
.B Control-Button1
Zooms the clicked
.B window
to master column
.B dwm.
.SS Mouse commands
.TP
.B Mod1-Button1
Moves current
Move current
.B window
while dragging
.RB ( floating
mode only).
.TP
.B Mod1-Button2
Lowers current
Zoom current
.B window
to the
.B master
column
.RB ( tiling
mode only).
.TP
.B Mod1-Button3
Resizes current
Resize current
.B window
while dragging
.RB ( floating
mode only).
.SH CUSTOMIZATION
.B dwm
is customized through editing its source code. This keeps it fast, secure and
simple. The source code contains the
.I CUSTOMIZE
keyword to highlight relevant portions for customization.
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)

126
dwm.h
View File

@@ -3,38 +3,18 @@
* See LICENSE file for license details.
*/
#include "config.h"
#include <X11/Xlib.h>
/********** CUSTOMIZE **********/
/* mask shorthands, used in event.c and client.c */
#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask)
#define MOUSEMASK (BUTTONMASK | PointerMotionMask)
#define PROTODELWIN 1
#define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*"
#define BGCOLOR "#0a2c2d"
#define FGCOLOR "#ddeeee"
#define BORDERCOLOR "#176164"
/*
#define BGCOLOR "#666699"
#define FGCOLOR "#eeeeee"
#define BORDERCOLOR "#9999CC"
*/
#define MASTERW 52 /* percent */
#define WM_PROTOCOL_DELWIN 1
/* tags */
enum { Tscratch, Tdev, Twww, Twork, TLast };
/********** CUSTOMIZE **********/
typedef union Arg Arg;
typedef struct DC DC;
typedef struct Client Client;
typedef struct Fnt Fnt;
typedef struct Key Key;
typedef struct Rule Rule;
union Arg {
const char **argv;
typedef union {
const char *cmd;
int i;
};
} Arg;
/* atoms */
enum { NetSupported, NetWMName, NetLast };
@@ -43,86 +23,76 @@ enum { WMProtocols, WMDelete, WMLast };
/* cursor */
enum { CurNormal, CurResize, CurMove, CurLast };
struct Fnt {
/* color */
enum { ColFG, ColBG, ColLast };
/* window corners */
typedef enum { TopLeft, TopRight, BotLeft, BotRight } Corner;
typedef struct {
int ascent;
int descent;
int height;
XFontSet set;
XFontStruct *xfont;
};
} Fnt;
struct DC { /* draw context */
typedef struct { /* draw context */
int x, y, w, h;
unsigned long bg;
unsigned long fg;
unsigned long border;
unsigned long norm[ColLast];
unsigned long sel[ColLast];
unsigned long status[ColLast];
Drawable drawable;
Fnt font;
GC gc;
};
} DC;
typedef struct Client Client;
struct Client {
char name[256];
char *tags[TLast];
int proto;
int x, y, w, h;
int tx, ty, tw, th;
int tx, ty, tw, th; /* title */
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int grav;
unsigned int border;
long flags;
unsigned int border, weight;
Bool isfloat;
Bool ismax;
Bool *tags;
Client *next;
Client *revert;
Client *prev;
Window win;
Window title;
Window twin;
};
struct Rule {
const char *class;
const char *instance;
char *tags[TLast];
Bool isfloat;
};
struct Key {
unsigned long mod;
KeySym keysym;
void (*func)(Arg *arg);
Arg arg;
};
extern char *tags[TLast], stext[1024];
extern int tsel, screen, sx, sy, sw, sh, bx, by, bw, bh, mw;
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 Atom wmatom[WMLast], netatom[NetLast];
extern Bool running, issel;
extern Bool running, issel, *seltag;
extern Client *clients, *sel;
extern Cursor cursor[CurLast];
extern DC dc;
extern Display *dpy;
extern Key key[];
extern Window root, barwin;
/* client.c */
extern void ban(Client *c);
extern void focus(Client *c);
extern void focusnext(Arg *arg);
extern void focusprev(Arg *arg);
extern Client *getclient(Window w);
extern Client *getctitle(Window w);
extern void gravitate(Client *c, Bool invert);
extern void higher(Client *c);
extern void killclient(Arg *arg);
extern void lower(Client *c);
extern void manage(Window w, XWindowAttributes *wa);
extern void maximize(Arg *arg);
extern void resize(Client *c, Bool inc);
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 zoom(Arg *arg);
/* draw.c */
extern void drawall();
@@ -130,10 +100,11 @@ 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(char *text);
extern unsigned int textw(const char *text);
/* event.c */
extern void grabkeys();
extern void procevent();
/* main.c */
extern int getproto(Window w);
@@ -142,15 +113,28 @@ extern void sendevent(Window w, Atom a, long value);
extern int xerror(Display *dsply, XErrorEvent *ee);
/* tag.c */
extern void appendtag(Arg *arg);
extern void dofloat(Arg *arg);
extern void dotile(Arg *arg);
extern void initrregs();
extern Client *getnext(Client *c);
extern void replacetag(Arg *arg);
extern Client *getprev(Client *c);
extern void settags(Client *c);
extern void view(Arg *arg);
extern void tag(Arg *arg);
extern void toggletag(Arg *arg);
/* 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);
/* 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 zoom(Arg *arg);

108
dwm.html
View File

@@ -4,6 +4,7 @@
<meta name="author" content="Anselm R. Garbe">
<meta name="generator" content="ed">
<meta name="copyright" content="(C)opyright 2006 by Anselm R. Garbe">
<link rel="dwm icon" href="favicon.ico" type="image/x-icon" />
<style type="text/css">
body {
color: #000000;
@@ -21,85 +22,106 @@
<p>
dwm is a dynamic window manager for X11.
</p>
<h3>Philosophy</h3>
<h4>Background</h4>
<p>
As founder and main developer of wmii I came to the conclusion that
wmii is too clunky for my needs. I don't need so many funky features
and all this hype about remote control through a 9P service, I only
want to manage my windows in a simple, but dynamic way. wmii never got
finished because I listened to users, who proposed arbitrary ideas I
considered useful. This resulted in an extreme <a href="http://www.jwz.org/doc/cadt.html">CADT</a>
development model, which was a mistake. Thus the philosophy of
dwm is simply <i>to fit my needs</i> (maybe yours as well). That's it.
considered useful. This resulted in an extreme <a
href="http://www.jwz.org/doc/cadt.html">CADT</a> development model,
which was a mistake. Thus the philosophy of dwm is simply <i>to fit my
needs</i> (maybe yours as well). That's it.
</p>
<h3>Differences to wmii</h3
<h4>Differences to ion, larswm, and wmii</h4>
<p>
In contrast to wmii, dwm is only a window manager, and nothing else.
Hence, it is much smaller, faster and simpler.
In contrast to ion, larswm, and wmii, dwm is much smaller, faster and simpler.
</p>
<ul>
<li>
dwm has no 9P support, no editable tagbars, no shell-based
configuration and remote control and comes without any additional
tools like printing the selection or warping the mouse.
dwm has no Lua integration, no 9P support, no editable
tagbars, no shell-based configuration, no remote control, and comes
without any additional tools like printing the selection or warping
the mouse.
</li>
<li>
dwm is only a single binary, it's source code is intended to never
exceed 2000 SLOC.
</li>
<li>
dwm is based on tagging and dynamic window management (however
simpler than ion, wmii or larswm). It manages windows in
tiling and floating modes. Either mode can be applied dynamically,
depending on the application in use and the task performed.
</li>
<li>
dwm doesn't distinguishes between layers, there is no floating or
tiled layer. Wether the clients of currently selected tag are in
tiled mode or not, you can re-arrange all clients on the fly.
Popup- and fixed-size windows are treated floating, however.
</li>
<li>
dwm is customized through editing its source code, that makes it
extremely fast and secure - it does not process any input data which
hasn't been known at compile time, except window title names.
extremely fast and secure - it does not process any input data
which hasn't been known at compile time, except window title names
and status text read from standard input. You don't have to learn
Lua/sh/ruby or some weird configuration file format (like X
resource files), beside C to customize it for your needs,
you <b>only</b> have to learn C (at least editing header files).
</li>
<li>
dwm is based on tagging and dynamic window management (however simpler
than wmii or larswm).
</li>
<li>
dwm don't distinguishes between layers, there is no floating or
managed layer. Wether the clients of currently selected tag are
managed or not, you can re-arrange all clients on the fly. Popup-
and fixed-size windows are treated unmanaged.
Because dwm is customized through editing its source code, it's
pointless to make binary packages of it. This keeps its userbase
small and elitist. No novices asking stupid questions.
</li>
<li>
dwm uses 1-pixel borders to provide the maximum of screen real
estate to clients. Small titlebars are only drawn in front of unfocused
clients.
estate to clients. Small titlebars are only drawn in front of
unfocused clients.
</li>
<li>
dwm reads from <b>stdin</b> to print arbitrary status text (like the
date, load, battery charge). That's much simpler than larsremote,
wmiir and what not...
dwm reads from standard input to print arbitrary status text (like
the date, load, battery charge). That's much simpler than
larsremote, wmiir and what not...
</li>
<li>
Anselm <b>does not</b> want any feedback to dwm. If you ask for support,
feature requests, or if you report bugs, they will be <b>ignored</b>
with a high chance. dwm is only intended to fit Anselms needs.
However you are free to download and distribute/relicense it, with the
conditions of the <a href="http://wmii.de/cgi-bin/hgwebdir.cgi/dwm?f=f10eb1139362;file=LICENSE;style=raw">MIT/X Consortium license</a>.
It can be downloaded and distributed under the conditions
of the <a href="http://10kloc.org/cgi-bin/hgwebdir.cgi/dwm?f=f10eb1139362;file=LICENSE;style=raw">MIT/X Consortium license</a>.
</li>
<li>
Optionally you can install <b>dmenu</b> to extend dwm with a wmii-alike menu.
</li>
</ul>
<h3>Screenshot</h3>
<p>
<a href="http://wmii.de/shots/dwm-20060714.png">Click here for a screenshot</a> (20060714)
</p>
<h3>Development</h3>
<p>
dwm is actively developed in parallel to wmii. You can <a href="http://wmii.de/cgi-bin/hgwebdir.cgi/dwm">browse</a> its source code repository or get a copy using <a href="http://www.selenic.com/mercurial/">Mercurial</a> with following command:
</p>
<p>
<code>hg clone http://wmii.de/cgi-bin/hgwebdir.cgi/dwm</code>
</p>
<h4>Links</h4>
<ul>
<li><a href="http://10kloc.org/cgi-bin/man/man2html?query=dwm">Man page</a></li>
<li><a href="http://10kloc.org/shots/dwm-20060810a.png">Screenshot of tiled mode</a> (20060810)</li>
<li><a href="http://10kloc.org/shots/dwm-20060810b.png">Screenshotof floating mode</a> (20060810)</li>
<li><a href="http://10kloc.org/download/poster.ps">A4 poster (PostScript)</a></li>
<li>Mailing List: <a href="http://10kloc.org/cgi-bin/mailman/listinfo/dwm">dwm at wmii dot de</a> <a href="http://10kloc.org/pipermail/dwm/">(Archives)</a>&nbsp;<a href="http://dir.gmane.org/gmane.comp.window-managers.dwm">(GMANE Archive)</a></li>
<li>IRC channel: <code>#dwm</code> at <code>irc.oftc.net</code></li>
</ul>
<h3>Download</h3>
<ul>
<li><a href="http://wmii.de/download/dwm-0.2.tar.gz">dwm 0.2</a> (13kb) (20060717)</li>
<li><a href="http://10kloc.org/download/dwm-1.2.tar.gz">dwm 1.2</a> (15kb) (20060830)</li>
<li><a href="http://10kloc.org/download/dmenu-0.6.tar.gz">dmenu 0.6</a> (7kb) (20060828)</li>
</ul>
<h3>Development</h3>
<p>
dwm is actively developed in parallel to wmii. You can <a href="http://10kloc.org/cgi-bin/hgwebdir.cgi/dwm">browse</a> its source code repository or get a copy using <a href="http://www.selenic.com/mercurial/">Mercurial</a> with following command:
</p>
<p>
<code>hg clone http://10kloc.org/cgi-bin/hgwebdir.cgi/dwm</code>
</p>
<p>
<code>hg clone http://10kloc.org/cgi-bin/hgwebdir.cgi/dmenu</code>
</p>
<h3>Miscellaneous</h3>
<p>
You can purchase this <a href="https://www.spreadshirt.net/shop.php?op=article&article_id=3298632&view=403">tricot</a>
if you like dwm and the dwm logo, which has been designed by Anselm.
</p>
<p><small>--Anselm (20060714)</small></p>
<p><small>--Anselm</small></p>
</body>
</html>

BIN
dwm.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 387 B

After

Width:  |  Height:  |  Size: 373 B

268
event.c
View File

@@ -3,69 +3,39 @@
* See LICENSE file for license details.
*/
#include "dwm.h"
#include <stdlib.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#define ButtonMask (ButtonPressMask | ButtonReleaseMask)
#define MouseMask (ButtonMask | PointerMotionMask)
/* CUSTOMIZE */
const char *browse[] = { "firefox", NULL };
const char *gimp[] = { "gimp", NULL };
const char *term[] = {
"urxvtc", "-tr", "+sb", "-bg", "black", "-fg", "white", "-cr", "white",
"-fn", "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*", NULL
};
const char *xlock[] = { "xlock", NULL };
Key key[] = {
/* modifier key function arguments */
{ ControlMask, XK_0, appendtag, { .i = Tscratch } },
{ ControlMask, XK_1, appendtag, { .i = Tdev } },
{ ControlMask, XK_2, appendtag, { .i = Twww } },
{ ControlMask, XK_3, appendtag, { .i = Twork } },
{ Mod1Mask, XK_0, view, { .i = Tscratch } },
{ Mod1Mask, XK_1, view, { .i = Tdev } },
{ Mod1Mask, XK_2, view, { .i = Twww } },
{ Mod1Mask, XK_3, view, { .i = Twork } },
{ Mod1Mask, XK_j, focusnext, { 0 } },
{ Mod1Mask, XK_k, focusprev, { 0 } },
{ Mod1Mask, XK_m, maximize, { 0 } },
{ Mod1Mask, XK_space, dotile, { 0 } },
{ Mod1Mask, XK_Return, zoom, { 0 } },
{ Mod1Mask|ShiftMask, XK_0, replacetag, { .i = Tscratch } },
{ Mod1Mask|ShiftMask, XK_1, replacetag, { .i = Tdev } },
{ Mod1Mask|ShiftMask, XK_2, replacetag, { .i = Twww } },
{ Mod1Mask|ShiftMask, XK_3, replacetag, { .i = Twork } },
{ Mod1Mask|ShiftMask, XK_c, killclient, { 0 } },
{ Mod1Mask|ShiftMask, XK_g, spawn, { .argv = gimp } },
{ Mod1Mask|ShiftMask, XK_l, spawn, { .argv = xlock } },
{ Mod1Mask|ShiftMask, XK_q, quit, { 0 } },
{ Mod1Mask|ShiftMask, XK_space, dofloat, { 0 } },
{ Mod1Mask|ShiftMask, XK_w, spawn, { .argv = browse } },
{ Mod1Mask|ShiftMask, XK_Return, spawn, { .argv = term } },
};
/* static */
typedef struct {
unsigned long mod;
KeySym keysym;
void (*func)(Arg *arg);
Arg arg;
} Key;
KEYS
#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask))
static void
movemouse(Client *c)
{
XEvent ev;
int x1, y1, ocx, ocy, di;
unsigned int dui;
Window dummy;
XEvent ev;
ocx = c->x;
ocy = c->y;
if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
None, cursor[CurMove], CurrentTime) != GrabSuccess)
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurMove], CurrentTime) != GrabSuccess)
return;
XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui);
for(;;) {
XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
XMaskEvent(dpy, MOUSEMASK | ExposureMask, &ev);
switch (ev.type) {
default: break;
case Expose:
@@ -75,7 +45,7 @@ movemouse(Client *c)
XSync(dpy, False);
c->x = ocx + (ev.xmotion.x - x1);
c->y = ocy + (ev.xmotion.y - y1);
resize(c, False);
resize(c, False, TopLeft);
break;
case ButtonRelease:
XUngrabPointer(dpy, CurrentTime);
@@ -87,17 +57,19 @@ movemouse(Client *c)
static void
resizemouse(Client *c)
{
XEvent ev;
int ocx, ocy;
int nw, nh;
Corner sticky;
XEvent ev;
ocx = c->x;
ocy = c->y;
if(XGrabPointer(dpy, root, False, MouseMask, GrabModeAsync, GrabModeAsync,
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurResize], CurrentTime) != GrabSuccess)
return;
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
for(;;) {
XMaskEvent(dpy, MouseMask | ExposureMask, &ev);
XMaskEvent(dpy, MOUSEMASK | ExposureMask, &ev);
switch(ev.type) {
default: break;
case Expose:
@@ -105,11 +77,17 @@ resizemouse(Client *c)
break;
case MotionNotify:
XSync(dpy, False);
c->w = abs(ocx - ev.xmotion.x);
c->h = abs(ocy - ev.xmotion.y);
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;
resize(c, True);
if(ocx <= ev.xmotion.x)
sticky = (ocy <= ev.xmotion.y) ? TopLeft : BotLeft;
else
sticky = (ocy <= ev.xmotion.y) ? TopRight : BotRight;
resize(c, True, sticky);
break;
case ButtonRelease:
XUngrabPointer(dpy, CurrentTime);
@@ -123,64 +101,84 @@ buttonpress(XEvent *e)
{
int x;
Arg a;
XButtonPressedEvent *ev = &e->xbutton;
Client *c;
XButtonPressedEvent *ev = &e->xbutton;
if(barwin == ev->window) {
switch(ev->button) {
default:
x = 0;
for(a.i = 0; a.i < TLast; a.i++) {
x += textw(tags[a.i]);
if(ev->x < x) {
x = 0;
for(a.i = 0; a.i < ntags; a.i++) {
x += textw(tags[a.i]);
if(ev->x < x) {
if(ev->button == Button1)
view(&a);
break;
}
else if(ev->button == Button3)
toggleview(&a);
return;
}
break;
case Button4:
a.i = (tsel + 1 < TLast) ? tsel + 1 : 0;
view(&a);
break;
case Button5:
a.i = (tsel - 1 >= 0) ? tsel - 1 : TLast - 1;
view(&a);
break;
}
if(ev->x < x + bmw) {
if(ev->button == Button1)
togglemode(NULL);
}
}
else if((c = getclient(ev->window))) {
if(arrange == dotile && !c->isfloat) {
if((ev->state & ControlMask) && (ev->button == Button1))
zoom(NULL);
focus(c);
if(CLEANMASK(ev->state) != MODKEY)
return;
}
/* floating windows */
higher(c);
switch(ev->button) {
default:
break;
case Button1:
movemouse(c);
if(!c->ismax && (arrange == dofloat || c->isfloat)) {
restack(c);
movemouse(c);
}
break;
case Button2:
lower(c);
zoom(NULL);
break;
case Button3:
resizemouse(c);
if(!c->ismax && (arrange == dofloat || c->isfloat)) {
restack(c);
resizemouse(c);
}
break;
}
}
}
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;
Client *c;
XConfigureRequestEvent *ev = &e->xconfigurerequest;
XWindowChanges wc;
Client *c;
ev->value_mask &= ~CWSibling;
if((c = getclient(ev->window))) {
if(!c->isfloat && (arrange != dofloat) && c->ismax) {
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;
@@ -191,22 +189,34 @@ configurerequest(XEvent *e)
if(ev->value_mask & CWHeight)
c->h = ev->height;
if(ev->value_mask & CWBorderWidth)
c->border = 1;
c->border = ev->border_width;
gravitate(c, False);
resize(c, True);
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);
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);
}
else {
wc.x = ev->x;
wc.y = ev->y;
wc.width = ev->width;
wc.height = ev->height;
wc.border_width = ev->border_width;
wc.sibling = ev->above;
wc.stack_mode = ev->detail;
XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
XSync(dpy, False);
}
wc.x = ev->x;
wc.y = ev->y;
wc.width = ev->width;
wc.height = ev->height;
wc.border_width = 1;
wc.sibling = None;
wc.stack_mode = Above;
ev->value_mask &= ~CWStackMode;
ev->value_mask |= CWBorderWidth;
XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
XSync(dpy, False);
}
static void
@@ -222,23 +232,26 @@ destroynotify(XEvent *e)
static void
enternotify(XEvent *e)
{
XCrossingEvent *ev = &e->xcrossing;
Client *c;
XCrossingEvent *ev = &e->xcrossing;
if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
return;
if((c = getclient(ev->window)))
if((c = getclient(ev->window)) || (c = getctitle(ev->window)))
focus(c);
else if(ev->window == root)
else if(ev->window == root) {
issel = True;
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
drawall();
}
}
static void
expose(XEvent *e)
{
XExposeEvent *ev = &e->xexpose;
Client *c;
XExposeEvent *ev = &e->xexpose;
if(ev->count == 0) {
if(barwin == ev->window)
@@ -251,18 +264,21 @@ expose(XEvent *e)
static void
keypress(XEvent *e)
{
XKeyEvent *ev = &e->xkey;
static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
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) && (key[i].mod == 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
@@ -270,15 +286,27 @@ leavenotify(XEvent *e)
{
XCrossingEvent *ev = &e->xcrossing;
if((ev->window == root) && !ev->same_screen)
issel = True;
if((ev->window == root) && !ev->same_screen) {
issel = False;
drawall();
}
}
static void
mappingnotify(XEvent *e)
{
XMappingEvent *ev = &e->xmapping;
XRefreshKeyboardMapping(ev);
if(ev->request == MappingKeyboard)
grabkeys();
}
static void
maprequest(XEvent *e)
{
XMapRequestEvent *ev = &e->xmaprequest;
static XWindowAttributes wa;
XMapRequestEvent *ev = &e->xmaprequest;
if(!XGetWindowAttributes(dpy, ev->window, &wa))
return;
@@ -296,9 +324,9 @@ maprequest(XEvent *e)
static void
propertynotify(XEvent *e)
{
XPropertyEvent *ev = &e->xproperty;
Window trans;
Client *c;
Window trans;
XPropertyEvent *ev = &e->xproperty;
if(ev->state == PropertyDelete)
return; /* ignore */
@@ -346,6 +374,7 @@ void (*handler[LASTEvent]) (XEvent *) = {
[LeaveNotify] = leavenotify,
[Expose] = expose,
[KeyPress] = keypress,
[MappingNotify] = mappingnotify,
[MapRequest] = maprequest,
[PropertyNotify] = propertynotify,
[UnmapNotify] = unmapnotify
@@ -354,14 +383,33 @@ void (*handler[LASTEvent]) (XEvent *) = {
void
grabkeys()
{
static unsigned int len = key ? sizeof(key) / sizeof(key[0]) : 0;
static unsigned int len = sizeof(key) / sizeof(key[0]);
unsigned int i;
KeyCode code;
XUngrabKey(dpy, AnyKey, AnyModifier, root);
for(i = 0; i < len; i++) {
code = XKeysymToKeycode(dpy, key[i].keysym);
XUngrabKey(dpy, code, key[i].mod, root);
XGrabKey(dpy, code, key[i].mod, root, True,
GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, key[i].mod | LockMask, root, True,
GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, key[i].mod | numlockmask, root, True,
GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, key[i].mod | numlockmask | LockMask, root, True,
GrabModeAsync, GrabModeAsync);
}
}
void
procevent()
{
XEvent ev;
while(XPending(dpy)) {
XNextEvent(dpy, &ev);
if(handler[ev.type])
(handler[ev.type])(&ev); /* call handler */
}
}

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

310
main.c
View File

@@ -4,40 +4,66 @@
*/
#include "dwm.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xproto.h>
/* extern */
char stext[1024];
Bool *seltag;
int bx, by, bw, bh, bmw, mw, screen, sx, sy, sw, sh;
unsigned int ntags, numlockmask;
Atom wmatom[WMLast], netatom[NetLast];
Bool running = True;
Bool issel = True;
Client *clients = NULL;
Client *sel = NULL;
Cursor cursor[CurLast];
Display *dpy;
DC dc = {0};
Window root, barwin;
/* static */
static Bool otherwm;
static int (*xerrorxlib)(Display *, XErrorEvent *);
static Bool otherwm, readin;
static void
cleanup()
{
close(STDIN_FILENO);
while(sel) {
resize(sel, True);
resize(sel, True, TopLeft);
unmanage(sel);
}
if(dc.font.set)
XFreeFontSet(dpy, dc.font.set);
else
XFreeFont(dpy, dc.font.xfont);
XUngrabKey(dpy, AnyKey, AnyModifier, root);
XFreePixmap(dpy, dc.drawable);
XFreeGC(dpy, dc.gc);
XDestroyWindow(dpy, barwin);
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
XSync(dpy, False);
}
static void
scan()
{
unsigned int i, num;
Window *wins;
Window *wins, d1, d2;
XWindowAttributes wa;
Window d1, d2;
wins = NULL;
if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
for(i = 0; i < num; i++) {
if(!XGetWindowAttributes(dpy, wins[i], &wa))
@@ -52,24 +78,81 @@ scan()
XFree(wins);
}
static int
win_property(Window w, Atom a, Atom t, long l, unsigned char **prop)
static void
setup()
{
Atom real;
int format;
unsigned long res, extra;
int status;
int i, j;
unsigned int mask;
Window w;
XModifierKeymap *modmap;
XSetWindowAttributes wa;
status = XGetWindowProperty(dpy, w, a, 0L, l, False, t, &real, &format,
&res, &extra, prop);
/* init atoms */
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", 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);
if(status != Success || *prop == 0) {
return 0;
/* init cursors */
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
modmap = XGetModifierMapping(dpy);
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))
numlockmask = (1 << i);
}
}
if(res == 0) {
free((void *) *prop);
}
return res;
XFree(modmap);
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[ColBG] = getcolor(NORMBGCOLOR);
dc.norm[ColFG] = getcolor(NORMFGCOLOR);
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);
sx = sy = 0;
sw = DisplayWidth(dpy, screen);
sh = DisplayHeight(dpy, screen);
mw = (sw * MASTERW) / 100;
bx = by = 0;
bw = sw;
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),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
XDefineCursor(dpy, barwin, cursor[CurNormal]);
XMapRaised(dpy, barwin);
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);
}
/*
@@ -85,36 +168,22 @@ xerrorstart(Display *dsply, XErrorEvent *ee)
/* extern */
char stext[1024];
int tsel = Tdev; /* default tag */
int screen, sx, sy, sw, sh, bx, by, bw, bh, mw;
Atom wmatom[WMLast], netatom[NetLast];
Bool running = True;
Bool issel = True;
Client *clients = NULL;
Client *sel = NULL;
Cursor cursor[CurLast];
Display *dpy;
DC dc = {0};
Window root, barwin;
int
getproto(Window w)
{
unsigned char *protocols;
long res;
int protos = 0;
int i;
int i, format, protos, status;
unsigned long extra, res;
Atom *protocols, real;
res = win_property(w, wmatom[WMProtocols], XA_ATOM, 20L, &protocols);
if(res <= 0) {
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++) {
for(i = 0; i < res; i++)
if(protocols[i] == wmatom[WMDelete])
protos |= WM_PROTOCOL_DELWIN;
}
free((char *) protocols);
protos |= PROTODELWIN;
free(protocols);
return protos;
}
@@ -136,7 +205,7 @@ sendevent(Window w, Atom a, long value)
void
quit(Arg *arg)
{
running = False;
readin = running = False;
}
/*
@@ -148,162 +217,83 @@ int
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_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))
return 0;
fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n",
ee->request_code, ee->error_code);
ee->request_code, ee->error_code);
return xerrorxlib(dpy, ee); /* may call exit() */
}
int
main(int argc, char *argv[])
{
int i, n;
int r, xfd;
fd_set rd;
XSetWindowAttributes wa;
unsigned int mask;
Bool readstdin = True;
Window w;
XEvent ev;
for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
switch (argv[i][1]) {
case 'v':
fprintf(stdout, "%s",
"dwm-"VERSION", (C)opyright MMVI Anselm R. Garbe\n");
exit(0);
break;
default:
eprint("usage: dwm [-v]\n");
break;
}
if(argc == 2 && !strncmp("-v", argv[1], 3)) {
fputs("dwm-"VERSION", (C)opyright MMVI Anselm R. Garbe\n", stdout);
exit(EXIT_SUCCESS);
}
else if(argc != 1)
eprint("usage: dwm [-v]\n");
dpy = XOpenDisplay(0);
if(!dpy)
eprint("dwm: cannot connect X server\n");
eprint("dwm: cannot open display\n");
xfd = ConnectionNumber(dpy);
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
/* check if another WM is already running */
otherwm = False;
XSetErrorHandler(xerrorstart);
/* this causes an error if some other WM is running */
/* 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");
XSync(dpy, False);
XSetErrorHandler(NULL);
xerrorxlib = XSetErrorHandler(xerror);
XSync(dpy, False);
/* init atoms */
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", 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);
grabkeys();
/* style */
dc.bg = getcolor(BGCOLOR);
dc.fg = getcolor(FGCOLOR);
dc.border = getcolor(BORDERCOLOR);
setfont(FONT);
sx = sy = 0;
sw = DisplayWidth(dpy, screen);
sh = DisplayHeight(dpy, screen);
mw = (sw * MASTERW) / 100;
wa.override_redirect = 1;
wa.background_pixmap = ParentRelative;
wa.event_mask = ButtonPressMask | ExposureMask;
bx = by = 0;
bw = sw;
dc.h = bh = dc.font.height + 4;
barwin = XCreateWindow(dpy, root, bx, by, bw, bh, 0, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
XDefineCursor(dpy, barwin, cursor[CurNormal]);
XMapRaised(dpy, barwin);
dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
dc.gc = XCreateGC(dpy, root, 0, 0);
setup();
drawstatus();
issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
wa.event_mask = SubstructureRedirectMask | EnterWindowMask \
| LeaveWindowMask;
wa.cursor = cursor[CurNormal];
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
strcpy(stext, "dwm-"VERSION);
scan();
/* main event loop, reads status text from stdin as well */
Mainloop:
/* main event loop, also reads status text from stdin */
XSync(dpy, False);
procevent();
readin = True;
while(running) {
FD_ZERO(&rd);
if(readstdin)
if(readin)
FD_SET(STDIN_FILENO, &rd);
FD_SET(ConnectionNumber(dpy), &rd);
i = select(ConnectionNumber(dpy) + 1, &rd, 0, 0, 0);
if(i == -1 && errno == EINTR)
FD_SET(xfd, &rd);
r = select(xfd + 1, &rd, NULL, NULL, NULL);
if((r == -1) && (errno == EINTR))
continue;
if(i < 0)
eprint("select failed\n");
else if(i > 0) {
if(FD_ISSET(ConnectionNumber(dpy), &rd)) {
while(XPending(dpy)) {
XNextEvent(dpy, &ev);
if(handler[ev.type])
(handler[ev.type])(&ev); /* call handler */
}
}
if(readstdin && FD_ISSET(STDIN_FILENO, &rd)) {
i = n = 0;
for(;;) {
if((i = getchar()) == EOF) {
/* broken pipe/end of producer */
readstdin = False;
strcpy(stext, "broken pipe");
goto Mainloop;
}
if(i == '\n' || n >= sizeof(stext) - 1)
break;
stext[n++] = i;
}
stext[n] = 0;
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)
eprint("select failed\n");
procevent();
}
cleanup();
XCloseDisplay(dpy);

243
tag.c
View File

@@ -3,176 +3,149 @@
* See LICENSE file for license details.
*/
#include "dwm.h"
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <X11/Xutil.h>
typedef struct {
const char *clpattern;
const char *tpattern;
Bool isfloat;
} Rule;
typedef struct {
regex_t *clregex;
regex_t *tregex;
} RReg;
/* static */
/* CUSTOMIZE */
static Rule rule[] = {
/* class instance tags isfloat */
{ "Firefox-bin", "Gecko", { [Twww] = "www" }, False },
};
TAGS
RULES
static RReg *rreg = NULL;
static unsigned int len = 0;
static void
commit()
{
/* asserts sel != NULL */
settitle(sel);
if(!isvisible(sel))
arrange(NULL);
else
drawstatus();
}
/* extern */
/* CUSTOMIZE */
char *tags[TLast] = {
[Tscratch] = "scratch",
[Tdev] = "dev",
[Twww] = "www",
[Twork] = "work",
};
void (*arrange)(Arg *) = dotile;
void
appendtag(Arg *arg)
{
if(!sel)
return;
sel->tags[arg->i] = tags[arg->i];
arrange(NULL);
}
void
dofloat(Arg *arg)
{
Client *c;
arrange = dofloat;
for(c = clients; c; c = c->next) {
if(c->tags[tsel])
resize(c, True);
else
ban(c);
}
if(sel && !sel->tags[tsel]) {
if((sel = getnext(clients))) {
higher(sel);
focus(sel);
}
}
drawall();
}
void
dotile(Arg *arg)
{
Client *c;
int n, i, w, h;
w = sw - mw;
arrange = dotile;
for(n = 0, c = clients; c; c = c->next)
if(c->tags[tsel] && !c->isfloat)
n++;
if(n > 1)
h = (sh - bh) / (n - 1);
else
h = sh - bh;
for(i = 0, c = clients; c; c = c->next) {
if(c->tags[tsel]) {
if(c->isfloat) {
higher(c);
resize(c, True);
continue;
}
if(n == 1) {
c->x = sx;
c->y = sy + bh;
c->w = sw - 2 * c->border;
c->h = sh - 2 * c->border - bh;
}
else if(i == 0) {
c->x = sx;
c->y = sy + bh;
c->w = mw - 2 * c->border;
c->h = sh - 2 * c->border - bh;
}
else {
c->x = sx + mw;
c->y = sy + (i - 1) * h + bh;
c->w = w - 2 * c->border;
c->h = h - 2 * c->border;
}
resize(c, False);
i++;
}
else
ban(c);
}
if(!sel || (sel && !sel->tags[tsel])) {
if((sel = getnext(clients))) {
higher(sel);
focus(sel);
}
}
drawall();
}
Client *
getnext(Client *c)
{
for(; c && !c->tags[tsel]; c = c->next);
for(; c && !isvisible(c); c = c->next);
return c;
}
Client *
getprev(Client *c)
{
for(; c && !isvisible(c); c = c->prev);
return c;
}
void
replacetag(Arg *arg)
initrregs()
{
int i;
if(!sel)
return;
unsigned int i;
regex_t *reg;
for(i = 0; i < TLast; i++)
sel->tags[i] = NULL;
appendtag(arg);
if(rreg)
return;
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))
free(reg);
else
rreg[i].clregex = reg;
}
if(rule[i].tpattern) {
reg = emallocz(sizeof(regex_t));
if(regcomp(reg, rule[i].tpattern, 0))
free(reg);
else
rreg[i].tregex = reg;
}
}
}
void
settags(Client *c)
{
XClassHint ch;
static unsigned int len = rule ? sizeof(rule) / sizeof(rule[0]) : 0;
char prop[512];
unsigned int i, j;
regmatch_t tmp;
Bool matched = False;
if(!len) {
c->tags[tsel] = tags[tsel];
return;
}
XClassHint ch;
if(XGetClassHint(dpy, c->win, &ch)) {
if(ch.res_class && ch.res_name) {
for(i = 0; i < len; i++)
if(!strncmp(rule[i].class, ch.res_class, sizeof(rule[i].class))
&& !strncmp(rule[i].instance, ch.res_name, sizeof(rule[i].instance)))
{
for(j = 0; j < TLast; j++)
c->tags[j] = rule[i].tags[j];
c->isfloat = rule[i].isfloat;
matched = True;
break;
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++)
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++) {
if(!regexec(rreg[i].tregex, tags[j], 1, &tmp, 0)) {
matched = True;
c->tags[j] = True;
}
}
}
}
if(ch.res_class)
XFree(ch.res_class);
if(ch.res_name)
XFree(ch.res_name);
}
if(!matched)
c->tags[tsel] = tags[tsel];
for(i = 0; i < ntags; i++)
c->tags[i] = seltag[i];
for(i = 0; i < ntags && !c->tags[i]; i++);
c->weight = i;
}
void
view(Arg *arg)
tag(Arg *arg)
{
tsel = arg->i;
arrange(NULL);
drawall();
unsigned int i;
if(!sel)
return;
for(i = 0; i < ntags; i++)
sel->tags[i] = False;
sel->tags[arg->i] = True;
commit();
}
void
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;
commit();
}

44
util.c
View File

@@ -3,59 +3,65 @@
* See LICENSE file for license details.
*/
#include "dwm.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
/* static */
static void
bad_malloc(unsigned int size)
{
fprintf(stderr, "fatal: could not malloc() %d bytes\n",
(int) size);
exit(1);
}
/* extern */
void *
emallocz(unsigned int size)
{
void *res = calloc(1, size);
if(!res)
bad_malloc(size);
eprint("fatal: could not malloc() %u bytes\n", size);
return res;
}
void
eprint(const char *errstr, ...) {
eprint(const char *errstr, ...)
{
va_list ap;
va_start(ap, errstr);
vfprintf(stderr, errstr, ap);
va_end(ap);
exit(1);
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)
{
char **argv = (char **)arg->argv;
if(!argv || !argv[0])
static char *shell = NULL;
if(!shell && !(shell = getenv("SHELL")))
shell = "/bin/sh";
if(!arg->cmd)
return;
/* the double-fork construct avoids zombie processes */
if(fork() == 0) {
if(fork() == 0) {
if(dpy)
close(ConnectionNumber(dpy));
setsid();
execvp(argv[0], argv);
fprintf(stderr, "dwm: execvp %s", argv[0]);
execl(shell, shell, "-c", arg->cmd, (char *)NULL);
fprintf(stderr, "dwm: execl '%s -c %s'", shell, arg->cmd);
perror(" failed");
}
exit (0);
exit(0);
}
wait(0);
}

289
view.c Normal file
View File

@@ -0,0 +1,289 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
#include <stdio.h>
/* static */
static Client *
minclient()
{
Client *c, *min;
for(min = c = clients; c; c = c->next)
if(c->weight < min->weight)
min = c;
return min;
}
static void
reorder()
{
Client *c, *newclients, *tail;
newclients = tail = NULL;
while((c = minclient())) {
detach(c);
if(tail) {
c->prev = tail;
tail->next = c;
tail = c;
}
else
tail = newclients = c;
}
clients = newclients;
}
/* extern */
void (*arrange)(Arg *) = DEFMODE;
void
detach(Client *c)
{
if(c->prev)
c->prev->next = c->next;
if(c->next)
c->next->prev = c->prev;
if(c == clients)
clients = c->next;
c->next = c->prev = NULL;
}
void
dofloat(Arg *arg)
{
Client *c;
for(c = clients; c; c = c->next) {
c->ismax = False;
if(isvisible(c)) {
resize(c, True, TopLeft);
}
else
ban(c);
}
if((sel = getnext(clients)))
focus(sel);
else
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
restack();
}
void
dotile(Arg *arg)
{
int h, i, n, w;
Client *c;
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) {
c->ismax = False;
if(isvisible(c)) {
if(c->isfloat) {
resize(c, True, TopLeft);
continue;
}
if(n == 1) {
c->x = sx;
c->y = sy + bh;
c->w = sw - 2;
c->h = sh - 2 - bh;
}
else if(i == 0) {
c->x = sx;
c->y = sy + bh;
c->w = mw - 2;
c->h = sh - 2 - bh;
}
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);
i++;
}
else
ban(c);
}
if((sel = getnext(clients)))
focus(sel);
else
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
restack();
}
void
focusnext(Arg *arg)
{
Client *c;
if(!sel)
return;
if(!(c = getnext(sel->next)))
c = getnext(clients);
if(c) {
focus(c);
restack();
}
}
void
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);
}
if(c) {
focus(c);
restack();
}
}
Bool
isvisible(Client *c)
{
unsigned int i;
for(i = 0; i < ntags; i++)
if(c->tags[i] && seltag[i])
return True;
return False;
}
void
restack()
{
static unsigned int nwins = 0;
static Window *wins = NULL;
unsigned int f, fi, m, mi, n;
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();
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;
}
}
XRestackWindows(dpy, wins, n);
drawall();
XSync(dpy, False);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}
void
togglemode(Arg *arg)
{
arrange = (arrange == dofloat) ? dotile : dofloat;
if(sel)
arrange(NULL);
else
drawstatus();
}
void
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);
}
void
view(Arg *arg)
{
unsigned int i;
for(i = 0; i < ntags; i++)
seltag[i] = False;
seltag[arg->i] = True;
reorder();
arrange(NULL);
}
void
zoom(Arg *arg)
{
Client *c = sel;
if(!c || (arrange != dotile) || c->isfloat || c->ismax)
return;
if(c == getnext(clients))
if(!(c = getnext(c->next)))
return;
detach(c);
c->next = clients;
clients->prev = c;
clients = c;
focus(c);
arrange(NULL);
}