aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilip Wandzio <contact@philw.dev>2026-01-14 00:21:47 +0100
committerFilip Wandzio <contact@philw.dev>2026-01-14 00:21:47 +0100
commita89a4c9273807320484ebd30075a5f58b71ba2cd (patch)
treee8ec5fb16226505a4fbe221e836d5cae3fbca50c
parent10e09252e99335d4d084f3a92dffb9367da14bea (diff)
downloaddwm-a89a4c9273807320484ebd30075a5f58b71ba2cd.tar.gz
dwm-a89a4c9273807320484ebd30075a5f58b71ba2cd.zip
Switch from c99 to c23 standardHEADmaster
Create sketch for manual testing Disable redundant functions The following functions: movemouse, resizemouse, togglefloating, sendmon, pop, quit and zoom shall be removed. Specific windows (loading screens, notifications) will remain floating but there is no need in a window manager for manually toggling the floating behavior. Killing the session is no longer possible via keybinding. Insted I suggested adding a keybinding for reseting dwm and switching to TTY if it fails after all.
Diffstat (limited to '')
-rw-r--r--Makefile2
-rw-r--r--TESTING.md40
-rw-r--r--src/core/dwm.c359
-rw-r--r--src/core/dwm.h18
4 files changed, 233 insertions, 186 deletions
diff --git a/Makefile b/Makefile
index 84c0b68..77d2a53 100644
--- a/Makefile
+++ b/Makefile
@@ -33,7 +33,7 @@ CPPFLAGS = \
33 ${XINERAMAFLAGS} 33 ${XINERAMAFLAGS}
34 34
35CFLAGS = \ 35CFLAGS = \
36 -std=c99 \ 36 -std=c23 \
37 -pedantic \ 37 -pedantic \
38 -Wall \ 38 -Wall \
39 -Wno-deprecated-declarations \ 39 -Wno-deprecated-declarations \
diff --git a/TESTING.md b/TESTING.md
new file mode 100644
index 0000000..376d43c
--- /dev/null
+++ b/TESTING.md
@@ -0,0 +1,40 @@
1# Manual testing
2
3## Basic
4
5```make clean install``` completes without errors e.g
6
7```
8rm -f dwm src/core/dwm.o src/drw/drw.o src/util/util.o
9clang -c -std=c23 -pedantic -Wall -Wno-deprecated-declarations -Os -I/usr/X11R6/include -I/usr/include/freetype2 -I./src -I./src/drw -I./src/util -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"\" -DXINERAMA -o src/core/dwm.o src/core/dwm.c
10clang -c -std=c23 -pedantic -Wall -Wno-deprecated-declarations -Os -I/usr/X11R6/include -I/usr/include/freetype2 -I./src -I./src/drw -I./src/util -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"\" -DXINERAMA -o src/drw/drw.o src/drw/drw.c
11clang -c -std=c23 -pedantic -Wall -Wno-deprecated-declarations -Os -I/usr/X11R6/include -I/usr/include/freetype2 -I./src -I./src/drw -I./src/util -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"\" -DXINERAMA -o src/util/util.o src/util/util.c
12clang -o dwm src/core/dwm.o src/drw/drw.o src/util/util.o -L/usr/X11R6/lib -lX11 -lXinerama -lfontconfig -lXft -lX11-xcb -lxcb -lxcb-res
13mkdir -p /usr/local/bin
14cp -f dwm /usr/local/bin
15chmod 755 /usr/local/bin/dwm
16mkdir -p /usr/local/share/man/man1
17sed "s/VERSION//g" < assets/dwm.1 > /usr/local/share/man/man1/dwm.1
18chmod 644 /usr/local/share/man/man1/dwm.1
19```
20
21No errors in stdout/stderr on startup
22
23## Keys
24
25Default terminal launches `Super+Enter`
26
27dwm restarts after `Super + r`
28
29## Multi-monitor
30
31xrandr on dsub, hdmi, dp + built-in screen
32
33## GUI Tools
34
35swallowing, floating etc.
36
37polkit permissions
38
39## A/V
40pipewire in the browser, recording audio, matrix calls etc.
diff --git a/src/core/dwm.c b/src/core/dwm.c
index 6d4cdcd..761c22a 100644
--- a/src/core/dwm.c
+++ b/src/core/dwm.c
@@ -1141,71 +1141,72 @@ void motionnotify(XEvent *e)
1141 mon = m; 1141 mon = m;
1142} 1142}
1143 1143
1144void movemouse(const Arg *arg) 1144// @TODO marked for removal
1145{ 1145// void movemouse(const Arg *arg)
1146 int x, y, ocx, ocy, nx, ny; 1146// {
1147 Client *c; 1147// int x, y, ocx, ocy, nx, ny;
1148 Monitor *m; 1148// Client *c;
1149 XEvent ev; 1149// Monitor *m;
1150 Time lasttime = 0; 1150// XEvent ev;
1151 1151// Time lasttime = 0;
1152 if (!(c = selmon->sel)) 1152//
1153 return; 1153// if (!(c = selmon->sel))
1154 if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ 1154// return;
1155 return; 1155// if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
1156 restack(selmon); 1156// return;
1157 ocx = c->x; 1157// restack(selmon);
1158 ocy = c->y; 1158// ocx = c->x;
1159 if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, 1159// ocy = c->y;
1160 GrabModeAsync, None, cursor[CurMove]->cursor, 1160// if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync,
1161 CurrentTime) != GrabSuccess) 1161// GrabModeAsync, None, cursor[CurMove]->cursor,
1162 return; 1162// CurrentTime) != GrabSuccess)
1163 if (!getrootptr(&x, &y)) 1163// return;
1164 return; 1164// if (!getrootptr(&x, &y))
1165 do { 1165// return;
1166 XMaskEvent(dpy, 1166// do {
1167 MOUSEMASK | ExposureMask | SubstructureRedirectMask, 1167// XMaskEvent(dpy,
1168 &ev); 1168// MOUSEMASK | ExposureMask | SubstructureRedirectMask,
1169 switch (ev.type) { 1169// &ev);
1170 case ConfigureRequest: 1170// switch (ev.type) {
1171 case Expose: 1171// case ConfigureRequest:
1172 case MapRequest: 1172// case Expose:
1173 handler[ev.type](&ev); 1173// case MapRequest:
1174 break; 1174// handler[ev.type](&ev);
1175 case MotionNotify: 1175// break;
1176 if ((ev.xmotion.time - lasttime) <= (1000 / 60)) 1176// case MotionNotify:
1177 continue; 1177// if ((ev.xmotion.time - lasttime) <= (1000 / 60))
1178 lasttime = ev.xmotion.time; 1178// continue;
1179 1179// lasttime = ev.xmotion.time;
1180 nx = ocx + (ev.xmotion.x - x); 1180//
1181 ny = ocy + (ev.xmotion.y - y); 1181// nx = ocx + (ev.xmotion.x - x);
1182 if (abs(selmon->wx - nx) < snap) 1182// ny = ocy + (ev.xmotion.y - y);
1183 nx = selmon->wx; 1183// if (abs(selmon->wx - nx) < snap)
1184 else if (abs((selmon->wx + selmon->ww) - 1184// nx = selmon->wx;
1185 (nx + WIDTH(c))) < snap) 1185// else if (abs((selmon->wx + selmon->ww) -
1186 nx = selmon->wx + selmon->ww - WIDTH(c); 1186// (nx + WIDTH(c))) < snap)
1187 if (abs(selmon->wy - ny) < snap) 1187// nx = selmon->wx + selmon->ww - WIDTH(c);
1188 ny = selmon->wy; 1188// if (abs(selmon->wy - ny) < snap)
1189 else if (abs((selmon->wy + selmon->wh) - 1189// ny = selmon->wy;
1190 (ny + HEIGHT(c))) < snap) 1190// else if (abs((selmon->wy + selmon->wh) -
1191 ny = selmon->wy + selmon->wh - HEIGHT(c); 1191// (ny + HEIGHT(c))) < snap)
1192 if (!c->isfloating && 1192// ny = selmon->wy + selmon->wh - HEIGHT(c);
1193 selmon->lt[selmon->sellt]->arrange && 1193// if (!c->isfloating &&
1194 (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) 1194// selmon->lt[selmon->sellt]->arrange &&
1195 togglefloating(NULL); 1195// (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
1196 if (!selmon->lt[selmon->sellt]->arrange || 1196// togglefloating(NULL);
1197 c->isfloating) 1197// if (!selmon->lt[selmon->sellt]->arrange ||
1198 resize(c, nx, ny, c->w, c->h, 1); 1198// c->isfloating)
1199 break; 1199// resize(c, nx, ny, c->w, c->h, 1);
1200 } 1200// break;
1201 } while (ev.type != ButtonRelease); 1201// }
1202 XUngrabPointer(dpy, CurrentTime); 1202// } while (ev.type != ButtonRelease);
1203 if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { 1203// XUngrabPointer(dpy, CurrentTime);
1204 sendmon(c, m); 1204// if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
1205 selmon = m; 1205// sendmon(c, m);
1206 focus(NULL); 1206// selmon = m;
1207 } 1207// focus(NULL);
1208} 1208// }
1209// }
1209 1210
1210Client *nexttiled(Client *c) 1211Client *nexttiled(Client *c)
1211{ 1212{
@@ -1214,13 +1215,13 @@ Client *nexttiled(Client *c)
1214 return c; 1215 return c;
1215} 1216}
1216 1217
1217void pop(Client *c) 1218// void pop(Client *c)
1218{ 1219// {
1219 detach(c); 1220// detach(c);
1220 attach(c); 1221// attach(c);
1221 focus(c); 1222// focus(c);
1222 arrange(c->mon); 1223// arrange(c->mon);
1223} 1224// }
1224 1225
1225void propertynotify(XEvent *e) 1226void propertynotify(XEvent *e)
1226{ 1227{
@@ -1270,8 +1271,9 @@ void propertynotify(XEvent *e)
1270 } 1271 }
1271} 1272}
1272 1273
1273void quit(const Arg *arg) { running = 0; } 1274// @TODO marked for removal
1274 1275// void quit(const Arg *arg) { running = 0; }
1276//
1275Monitor *recttomon(int x, int y, int w, int h) 1277Monitor *recttomon(int x, int y, int w, int h)
1276{ 1278{
1277 Monitor *m, *r = selmon; 1279 Monitor *m, *r = selmon;
@@ -1343,72 +1345,73 @@ void resizerequest(XEvent *e)
1343 } 1345 }
1344} 1346}
1345 1347
1346void resizemouse(const Arg *arg) 1348// @TODO marked for removal
1347{ 1349// void resizemouse(const Arg *arg)
1348 int ocx, ocy, nw, nh; 1350// {
1349 Client *c; 1351// int ocx, ocy, nw, nh;
1350 Monitor *m; 1352// Client *c;
1351 XEvent ev; 1353// Monitor *m;
1352 Time lasttime = 0; 1354// XEvent ev;
1353 1355// Time lasttime = 0;
1354 if (!(c = selmon->sel)) 1356//
1355 return; 1357// if (!(c = selmon->sel))
1356 if (c->isfullscreen) /* no support resizing fullscreen windows by mouse 1358// return;
1357 */ 1359// if (c->isfullscreen) /* no support resizing fullscreen windows by mouse
1358 return; 1360// */
1359 restack(selmon); 1361// return;
1360 ocx = c->x; 1362// restack(selmon);
1361 ocy = c->y; 1363// ocx = c->x;
1362 if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, 1364// ocy = c->y;
1363 GrabModeAsync, None, cursor[CurResize]->cursor, 1365// if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync,
1364 CurrentTime) != GrabSuccess) 1366// GrabModeAsync, None, cursor[CurResize]->cursor,
1365 return; 1367// CurrentTime) != GrabSuccess)
1366 XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, 1368// return;
1367 c->h + c->bw - 1); 1369// XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1,
1368 do { 1370// c->h + c->bw - 1);
1369 XMaskEvent(dpy, 1371// do {
1370 MOUSEMASK | ExposureMask | SubstructureRedirectMask, 1372// XMaskEvent(dpy,
1371 &ev); 1373// MOUSEMASK | ExposureMask | SubstructureRedirectMask,
1372 switch (ev.type) { 1374// &ev);
1373 case ConfigureRequest: 1375// switch (ev.type) {
1374 case Expose: 1376// case ConfigureRequest:
1375 case MapRequest: 1377// case Expose:
1376 handler[ev.type](&ev); 1378// case MapRequest:
1377 break; 1379// handler[ev.type](&ev);
1378 case MotionNotify: 1380// break;
1379 if ((ev.xmotion.time - lasttime) <= (1000 / 60)) 1381// case MotionNotify:
1380 continue; 1382// if ((ev.xmotion.time - lasttime) <= (1000 / 60))
1381 lasttime = ev.xmotion.time; 1383// continue;
1382 1384// lasttime = ev.xmotion.time;
1383 nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); 1385//
1384 nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); 1386// nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
1385 if (c->mon->wx + nw >= selmon->wx && 1387// nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
1386 c->mon->wx + nw <= selmon->wx + selmon->ww && 1388// if (c->mon->wx + nw >= selmon->wx &&
1387 c->mon->wy + nh >= selmon->wy && 1389// c->mon->wx + nw <= selmon->wx + selmon->ww &&
1388 c->mon->wy + nh <= selmon->wy + selmon->wh) { 1390// c->mon->wy + nh >= selmon->wy &&
1389 if (!c->isfloating && 1391// c->mon->wy + nh <= selmon->wy + selmon->wh) {
1390 selmon->lt[selmon->sellt]->arrange && 1392// if (!c->isfloating &&
1391 (abs(nw - c->w) > snap || 1393// selmon->lt[selmon->sellt]->arrange &&
1392 abs(nh - c->h) > snap)) 1394// (abs(nw - c->w) > snap ||
1393 togglefloating(NULL); 1395// abs(nh - c->h) > snap))
1394 } 1396// togglefloating(NULL);
1395 if (!selmon->lt[selmon->sellt]->arrange || 1397// }
1396 c->isfloating) 1398// if (!selmon->lt[selmon->sellt]->arrange ||
1397 resize(c, c->x, c->y, nw, nh, 1); 1399// c->isfloating)
1398 break; 1400// resize(c, c->x, c->y, nw, nh, 1);
1399 } 1401// break;
1400 } while (ev.type != ButtonRelease); 1402// }
1401 XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, 1403// } while (ev.type != ButtonRelease);
1402 c->h + c->bw - 1); 1404// XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1,
1403 XUngrabPointer(dpy, CurrentTime); 1405// c->h + c->bw - 1);
1404 while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)) 1406// XUngrabPointer(dpy, CurrentTime);
1405 ; 1407// while (XCheckMaskEvent(dpy, EnterWindowMask, &ev))
1406 if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { 1408// ;
1407 sendmon(c, m); 1409// if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
1408 selmon = m; 1410// sendmon(c, m);
1409 focus(NULL); 1411// selmon = m;
1410 } 1412// focus(NULL);
1411} 1413// }
1414// }
1412 1415
1413void restack(Monitor *m) 1416void restack(Monitor *m)
1414{ 1417{
@@ -1481,20 +1484,20 @@ void scan(void)
1481 } 1484 }
1482} 1485}
1483 1486
1484void sendmon(Client *c, Monitor *m) 1487// void sendmon(Client *c, Monitor *m)
1485{ 1488// {
1486 if (c->mon == m) 1489// if (c->mon == m)
1487 return; 1490// return;
1488 unfocus(c, 1); 1491// unfocus(c, 1);
1489 detach(c); 1492// detach(c);
1490 detachstack(c); 1493// detachstack(c);
1491 c->mon = m; 1494// c->mon = m;
1492 c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ 1495// c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
1493 attach(c); 1496// attach(c);
1494 attachstack(c); 1497// attachstack(c);
1495 focus(NULL); 1498// focus(NULL);
1496 arrange(NULL); 1499// arrange(NULL);
1497} 1500// }
1498 1501
1499void setclientstate(Client *c, long state) 1502void setclientstate(Client *c, long state)
1500{ 1503{
@@ -1811,19 +1814,19 @@ void togglebar(const Arg *arg)
1811 arrange(selmon); 1814 arrange(selmon);
1812} 1815}
1813 1816
1814void togglefloating(const Arg *arg) 1817// void togglefloating(const Arg *arg)
1815{ 1818// {
1816 if (!selmon->sel) 1819// if (!selmon->sel)
1817 return; 1820// return;
1818 if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ 1821// if (selmon->sel->isfullscreen) /* no support for fullscreen windows */
1819 return; 1822// return;
1820 selmon->sel->isfloating = 1823// selmon->sel->isfloating =
1821 !selmon->sel->isfloating || selmon->sel->isfixed; 1824// !selmon->sel->isfloating || selmon->sel->isfixed;
1822 if (selmon->sel->isfloating) 1825// if (selmon->sel->isfloating)
1823 resize(selmon->sel, selmon->sel->x, selmon->sel->y, 1826// resize(selmon->sel, selmon->sel->x, selmon->sel->y,
1824 selmon->sel->w, selmon->sel->h, 0); 1827// selmon->sel->w, selmon->sel->h, 0);
1825 arrange(selmon); 1828// arrange(selmon);
1826} 1829// }
1827 1830
1828void togglefullscr(const Arg *arg) 1831void togglefullscr(const Arg *arg)
1829{ 1832{
@@ -2534,17 +2537,17 @@ Monitor *systraytomon(Monitor *m)
2534 return mons; 2537 return mons;
2535 return t; 2538 return t;
2536} 2539}
2537 2540// @TODO marked for removal
2538void zoom(const Arg *arg) 2541// void zoom(const Arg *arg)
2539{ 2542// {
2540 Client *c = selmon->sel; 2543// Client *c = selmon->sel;
2541 2544//
2542 if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating) 2545// if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating)
2543 return; 2546// return;
2544 if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next))) 2547// if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next)))
2545 return; 2548// return;
2546 pop(c); 2549// pop(c);
2547} 2550// }
2548 2551
2549int main(int argc, char *argv[]) 2552int main(int argc, char *argv[])
2550{ 2553{
diff --git a/src/core/dwm.h b/src/core/dwm.h
index d3bdf5a..5e1b2e4 100644
--- a/src/core/dwm.h
+++ b/src/core/dwm.h
@@ -163,17 +163,20 @@ static void manage(Window w, XWindowAttributes *wa);
163static void mappingnotify(XEvent *e); 163static void mappingnotify(XEvent *e);
164static void maprequest(XEvent *e); 164static void maprequest(XEvent *e);
165static void motionnotify(XEvent *e); 165static void motionnotify(XEvent *e);
166static void movemouse(const Arg *arg); 166// @TODO marked for removal
167// static void movemouse(const Arg *arg);
167static Client *nexttiled(Client *c); 168static Client *nexttiled(Client *c);
168static void pop(Client *c); 169// static void pop(Client *c);
169static void propertynotify(XEvent *e); 170static void propertynotify(XEvent *e);
170static void quit(const Arg *arg); 171// @TODO marked for removal
172// static void quit(const Arg *arg);
171static Monitor *recttomon(int x, int y, int w, int h); 173static Monitor *recttomon(int x, int y, int w, int h);
172static void removesystrayicon(Client *i); 174static void removesystrayicon(Client *i);
173static void resize(Client *c, int x, int y, int w, int h, int interact); 175static void resize(Client *c, int x, int y, int w, int h, int interact);
174static void resizebarwin(Monitor *m); 176static void resizebarwin(Monitor *m);
175static void resizeclient(Client *c, int x, int y, int w, int h); 177static void resizeclient(Client *c, int x, int y, int w, int h);
176static void resizemouse(const Arg *arg); 178// @TODO marked for removal
179// static void resizemouse(const Arg *arg);
177static void resizerequest(XEvent *e); 180static void resizerequest(XEvent *e);
178static void restack(Monitor *m); 181static void restack(Monitor *m);
179static void restart(const Arg *arg); 182static void restart(const Arg *arg);
@@ -181,7 +184,7 @@ static void run(void);
181static void scan(void); 184static void scan(void);
182static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, 185static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2,
183 long d3, long d4); 186 long d3, long d4);
184static void sendmon(Client *c, Monitor *m); 187// static void sendmon(Client *c, Monitor *m);
185static void setclientstate(Client *c, long state); 188static void setclientstate(Client *c, long state);
186static void setfocus(Client *c); 189static void setfocus(Client *c);
187static void setfullscreen(Client *c, int fullscreen); 190static void setfullscreen(Client *c, int fullscreen);
@@ -194,7 +197,7 @@ static Monitor *systraytomon(Monitor *m);
194static void tag(const Arg *arg); 197static void tag(const Arg *arg);
195static void tile(Monitor *m); 198static void tile(Monitor *m);
196static void togglebar(const Arg *arg); 199static void togglebar(const Arg *arg);
197static void togglefloating(const Arg *arg); 200// static void togglefloating(const Arg *arg);
198static void togglefullscr(const Arg *arg); 201static void togglefullscr(const Arg *arg);
199static void toggletag(const Arg *arg); 202static void toggletag(const Arg *arg);
200static void toggleview(const Arg *arg); 203static void toggleview(const Arg *arg);
@@ -221,7 +224,8 @@ static Client *wintosystrayicon(Window w);
221static int xerror(Display *dpy, XErrorEvent *ee); 224static int xerror(Display *dpy, XErrorEvent *ee);
222static int xerrordummy(Display *dpy, XErrorEvent *ee); 225static int xerrordummy(Display *dpy, XErrorEvent *ee);
223static int xerrorstart(Display *dpy, XErrorEvent *ee); 226static int xerrorstart(Display *dpy, XErrorEvent *ee);
224static void zoom(const Arg *arg); 227// @TODO marked for removal
228// static void zoom(const Arg *arg);
225 229
226static pid_t getparentprocess(pid_t p); 230static pid_t getparentprocess(pid_t p);
227static int isdescprocess(pid_t p, pid_t c); 231static int isdescprocess(pid_t p, pid_t c);