commit f98b253
wf
·
2026-04-04 19:14:52 +0000 UTC
parent 385193b
Extra eyecandy, versioning, small fixes
M
Makefile
+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 -----
M
client.c
+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 }