commit f98b253

wf  ·  2026-04-04 19:14:52 +0000 UTC
parent 385193b
Extra eyecandy, versioning, small fixes
9 files changed,  +95, -70
M howl.c
M ipc.c
+12, -7
 1@@ -4,12 +4,19 @@ LDFLAGS   := `pkg-config --cflags --libs swc` -Iinclude
 2 LDLIBS    := `pkg-config --libs swc`
 3 PREFIX    ?= /usr/local
 4 
 5+###############
 6+
 7 howl      := howl
 8 howl_src  := ipc.c log.c howl.c
 9 
10 howlc     := howlc
11 howlc_src := client.c
12 
13+version   := 0.1.0
14+CFLAGS    += -DVERSION=\"$(version)\"
15+
16+###############
17+
18 .PHONY: all install uninstall clean
19 
20 all: $(howl) $(howlc)
21@@ -22,18 +29,16 @@ $(howlc): $(howlc_src)
22 	@echo "Building howlc..."
23 	$(CC) $(CFLAGS) $(LDFLAGS) -o $(howlc) $(howlc_src) $(LDLIBS)
24 
25-install: $(howl) $(howlc) install-man
26+install: $(howl) $(howlc)
27 	install -Dm755 $(howl)  $(DESTDIR)$(PREFIX)/bin/$(howl)
28 	install -Dm755 $(howlc) $(DESTDIR)$(PREFIX)/bin/$(howlc)
29+	install -Dm644 doc/howl.1 $(DESTDIR)$(PREFIX)/share/man/man1/howl.1
30+	install -Dm644 doc/howlc.1 $(DESTDIR)$(PREFIX)/share/man/man1/howlc.1
31 
32-uninstall: uninstall-man
33+uninstall:
34 	rm -f $(DESTDIR)$(PREFIX)/bin/$(howl)
35 	rm -f $(DESTDIR)$(PREFIX)/bin/$(howlc)
36-
37-install-man:
38-	install -Dm644 doc/howlc.1 $(DESTDIR)$(PREFIX)/share/man/man1/howlc.1
39-
40-uninstall-man:
41+	rm -f $(DESTDIR)$(PREFIX)/share/man/man1/howl.1
42 	rm -f $(DESTDIR)$(PREFIX)/share/man/man1/howlc.1
43 
44 clean:
+1, -1
1@@ -5,7 +5,7 @@ howl is a small wayland compositor written with the neuswc library.
2 
3 It is controlled through an external client, which allows for scriptability.
4 
5-See the `howlc` manual page for more information on usage.
6+See the `howl` and `howlc` manual pages for more information on usage.
7 
8 To do
9 -----
+25, -22
 1@@ -17,27 +17,30 @@ struct command {
 2 };
 3 
 4 static const struct command commands[] = {
 5-	{ "move",            cmd_move,           2, false },
 6-	{ "move_absolute",   cmd_move_absolute,  2, false },
 7-	{ "resize",          cmd_resize,         2, false },
 8-	{ "resize_absolute", cmd_resize,         2, false },
 9-	{ "teleport",        cmd_teleport,       4, false },
10-	{ "center",          cmd_center,         0, false },
11-	{ "fullscreen",      cmd_fullscreen,     0, false },
12-	{ "hide",            cmd_hide,           0, false },
13-	{ "show",            cmd_show,           0, false },
14-	{ "close",           cmd_close,          0, false },
15-	{ "workspace",       cmd_workspace,      1, false },
16-	{ "move_workspace",  cmd_move_workspace, 1, false },
17-	{ "geometry",        cmd_geometry,       0, false },
18-	{ "pid",             cmd_pid,            0, false },
19-	{ "title",           cmd_title,          0, false },
20-	{ "appid",           cmd_app_id,         0, false },
21-	{ "bind",            cmd_bind,           2, false },
22-	{ "modkey",          cmd_modkey,         1, true  },
23-	{ "focus_color",     cmd_focus_color,    1, true  },
24-	{ "unfocus_color",   cmd_unfocus_color,  1, true  },
25-	{ "border_width",    cmd_border_width,   1, true  },
26+	{ "move",                cmd_move,                2, false },
27+	{ "move_absolute",       cmd_move_absolute,       2, false },
28+	{ "resize",              cmd_resize,              2, false },
29+	{ "resize_absolute",     cmd_resize,              2, false },
30+	{ "teleport",            cmd_teleport,            4, false },
31+	{ "center",              cmd_center,              0, false },
32+	{ "fullscreen",          cmd_fullscreen,          0, false },
33+	{ "hide",                cmd_hide,                0, false },
34+	{ "show",                cmd_show,                0, false },
35+	{ "close",               cmd_close,               0, false },
36+	{ "workspace",           cmd_workspace,           1, false },
37+	{ "move_workspace",      cmd_move_workspace,      1, false },
38+	{ "geometry",            cmd_geometry,            0, false },
39+	{ "pid",                 cmd_pid,                 0, false },
40+	{ "title",               cmd_title,               0, false },
41+	{ "appid",               cmd_app_id,              0, false },
42+	{ "bind",                cmd_bind,                2, false },
43+	{ "modkey",              cmd_modkey,              1, true  },
44+	{ "inner_focus_color",   cmd_inner_focus_color,   1, true  },
45+	{ "inner_unfocus_color", cmd_inner_unfocus_color, 1, true  },
46+	{ "outer_focus_color",   cmd_outer_focus_color,   1, true  },
47+	{ "outer_unfocus_color", cmd_outer_unfocus_color, 1, true  },
48+	{ "inner_border_width",  cmd_inner_border_width,  1, true  },
49+	{ "outer_border_width",  cmd_outer_border_width,  1, true  },
50 	{ "quit",            cmd_quit,           0, false }
51 };
52 
53@@ -95,7 +98,7 @@ ipc_msg(const struct command *cmd, int argc, char **argv) {
54 int
55 main(int argc, char **argv) {
56 	if (argc < 2) {
57-		fprintf(stderr, "usage: %s cmd [args]\n", argv[0]);
58+		fprintf(stderr, "Usage: howlc cmd [args...]\n");
59 		return 1;
60 	}
61 
+2, -2
 1@@ -6,7 +6,7 @@
 2 .SH "SYNOPSIS"
 3 \fBhowlc\fR \fIcmd\fR [\fIargs\fR\|\.\|\.\|\.]
 4 .SH "DESCRIPTION"
 5-\fBhowlc\fR is a client that controls the howl compositor\.
 6+\fBhowlc\fR is a client that controls the \fBhowl\fR compositor\.
 7 .SH "COMMANDS"
 8 .TP
 9 \fBmove\fR, \fBmove_absolute\fR
10@@ -214,4 +214,4 @@ There is no way to unbind keys\. This is an swc problem, but still deserves to b
11 .SH "COPYRIGHT"
12 \fBhowl\fR and \fBhowlc\fR are (C) wf 2026 \fIhttps://codeberg\.org/wf\fR\.
13 .SH "SEE ALSO"
14-The README\.
15+README\.md
+3, -3
 1@@ -1,5 +1,5 @@
 2 howlc(1) -- client to control the howl compositor
 3-================================================
 4+=================================================
 5 
 6 ## SYNOPSIS
 7 
 8@@ -7,7 +7,7 @@ howlc(1) -- client to control the howl compositor
 9 
10 ## DESCRIPTION
11 
12-**howlc** is a client that controls the howl compositor.
13+**howlc** is a client that controls the `howl` compositor.
14 
15 ## COMMANDS
16 
17@@ -202,4 +202,4 @@ There is no way to unbind keys. This is an swc problem, but still deserves to be
18 
19 ## SEE ALSO
20 
21-The README.
22+README.md
M howl.c
+18, -16
 1@@ -214,9 +214,10 @@ bind_handler(void *data, uint32_t time, uint32_t value, uint32_t state) {
 2 
 3 static void
 4 setup(void) {
 5+	char *conf_path = malloc(MAXSIZE * sizeof(char));
 6 	wm.dpy = wl_display_create();
 7 	if (!wm.dpy) _err(1, "couldn't create Wayland display");
 8-	char *conf_path = malloc(MAXSIZE * sizeof(char));
 9+
10 	conf_path[0] = '\0';
11 
12 	wl_list_init(&wm.screens);
13@@ -228,10 +229,13 @@ setup(void) {
14 	wm.grab.client = NULL;
15 	wm.ws          = 1;
16 
17-	config.modkey        = SWC_MOD_LOGO;
18-	config.focus_color   = 0xFFE16C87;
19-	config.unfocus_color = 0xFF444059;
20-	config.border_width  = 2;
21+	config.mod      = SWC_MOD_LOGO;
22+	config.if_color = 0xFF8777E5;
23+	config.iu_color = 0xFF444444;
24+	config.of_color = 0xFF202020;
25+	config.ou_color = 0xFF202020;
26+	config.ib_width = 3;
27+	config.ob_width = 3;
28 
29 	wm.loop = wl_display_get_event_loop(wm.dpy);
30 	if (!swc_initialize(wm.dpy, wm.loop, &mgr))
31@@ -254,7 +258,7 @@ setup(void) {
32 		} else {
33 			char *home = getenv("HOME");
34 			if (home == NULL) {
35-				_wrn("could not find autostart file!");
36+				_wrn("couldn't find $HOME, autostart won't be loaded!");
37 				have_config = false;
38 			}
39 			snprintf(conf_path, MAXSIZE * sizeof(char), "%s/%s/%s/%s", home, ".config", "howl", "autostart");
40@@ -266,14 +270,14 @@ setup(void) {
41 	/* FIXME: these don't get enough time to inherit the modkey that the user configured */
42 	swc_add_binding(
43 		SWC_BINDING_BUTTON,
44-		config.modkey,
45+		config.mod,
46 		0x110, /* left mouse button */
47 		mouse_move,
48 		NULL
49 	);
50 	swc_add_binding(
51 		SWC_BINDING_BUTTON,
52-		config.modkey,
53+		config.mod,
54 		0x111, /* right mouse button */
55 		mouse_resize,
56 		NULL
57@@ -282,8 +286,6 @@ setup(void) {
58 	signal(SIGINT,  sig_handler);
59 	signal(SIGTERM, sig_handler);
60 	signal(SIGQUIT, sig_handler);
61-
62-	free(conf_path);
63 }
64 
65 void
66@@ -298,15 +300,15 @@ focus(struct client *c) {
67 	if (wm.cur)
68 		swc_window_set_border(
69 			wm.cur->win,
70-			config.unfocus_color, config.border_width,
71-			0, 0
72+			config.iu_color, config.ib_width,
73+			config.ou_color, config.ob_width
74 		);
75 
76 	if (c)
77 		swc_window_set_border(
78 			c->win,
79-			config.focus_color, config.border_width,
80-			0, 0
81+			config.if_color, config.ib_width,
82+			config.of_color, config.ob_width
83 		);
84 
85 	swc_window_focus(c ? c->win : NULL);
86@@ -534,9 +536,9 @@ on_scr_destroy(void *data) {
87 }
88 
89 int
90-main(void) {
91+main(int argc, char **argv) {
92 	setup();
93 	wl_display_run(wm.dpy);
94 	cleanup();
95-	return 1; /* NOTREACHED */
96+	return 1;
97 }
+6, -3
 1@@ -20,9 +20,12 @@ enum cmd {
 2 	cmd_app_id,
 3 	cmd_bind,
 4 	cmd_modkey,
 5-	cmd_focus_color,
 6-	cmd_unfocus_color,
 7-	cmd_border_width,
 8+	cmd_inner_focus_color,
 9+	cmd_inner_unfocus_color,
10+	cmd_outer_focus_color,
11+	cmd_outer_unfocus_color,
12+	cmd_inner_border_width,
13+	cmd_outer_border_width,
14 	cmd_quit,
15 	cmd_config,
16 	cmd_last
+7, -4
 1@@ -8,10 +8,13 @@
 2 #include <swc.h>
 3 
 4 struct config {
 5-	uint32_t  modkey;
 6-	uint32_t  focus_color;
 7-	uint32_t  unfocus_color;
 8-	int32_t   border_width;
 9+	uint32_t  mod;
10+	uint32_t  if_color;
11+	uint32_t  iu_color;
12+	uint32_t  of_color;
13+	uint32_t  ou_color;
14+	int32_t   ib_width;
15+	int32_t   ob_width;
16 };
17 
18 struct client {
M ipc.c
+21, -12
 1@@ -39,7 +39,7 @@ fn_bind(char *s) {
 2 	while (tok != NULL) {
 3 		uint32_t tmp = 0;
 4 
 5-		if (strcmp(tok, "mod") == 0) tmp = config.modkey;
 6+		if (strcmp(tok, "mod") == 0) tmp = config.mod;
 7 		else if (strcmp(tok, "alt") == 0) tmp = SWC_MOD_ALT;
 8 		else if (strcmp(tok, "win") == 0) tmp = SWC_MOD_LOGO;
 9 		else if (strcmp(tok, "ctrl") == 0) tmp = SWC_MOD_CTRL;
10@@ -304,16 +304,25 @@ ipc_config(char **arg) {
11 	switch (cmd) {
12 		case cmd_modkey:
13 			struct bind tmp = fn_bind(arg[2]);
14-			config.modkey = tmp.mod;
15+			config.mod = tmp.mod;
16 			break;
17-		case cmd_focus_color:
18-			config.focus_color = fn_hex(arg[2]);
19+		case cmd_inner_focus_color:
20+			config.if_color = fn_hex(arg[2]);
21 			break;
22-		case cmd_unfocus_color:
23-			config.unfocus_color = fn_hex(arg[2]);
24+		case cmd_outer_focus_color:
25+			config.of_color = fn_hex(arg[2]);
26 			break;
27-		case cmd_border_width:
28-			config.border_width = fn_int(arg[2]);
29+		case cmd_inner_unfocus_color:
30+			config.iu_color = fn_hex(arg[2]);
31+			break;
32+		case cmd_outer_unfocus_color:
33+			config.ou_color = fn_hex(arg[2]);
34+			break;
35+		case cmd_inner_border_width:
36+			config.ib_width = fn_int(arg[2]);
37+			break;
38+		case cmd_outer_border_width:
39+			config.ob_width = fn_int(arg[2]);
40 			break;
41 		default:
42 			break;
43@@ -324,14 +333,14 @@ ipc_config(char **arg) {
44 		if (c == wm.cur)
45 			swc_window_set_border(
46 				c->win,
47-				config.focus_color, config.border_width,
48-				0, 0
49+				config.if_color, config.ib_width,
50+				config.of_color, config.ob_width
51 			);
52 		else
53 			swc_window_set_border(
54 				c->win,
55-				config.unfocus_color, config.border_width,
56-				0, 0
57+				config.iu_color, config.ib_width,
58+				config.ou_color, config.ob_width
59 			);
60 	}
61 }