commit 5d4c8a4
shrub
·
2026-04-28 18:27:10 +0000 UTC
parent 9236a46
decor
5 files changed,
+102,
-7
M
Makefile
+4,
-5
1@@ -1,15 +1,14 @@
2 CC ?= cc
3-# CFLAGS = -std=c99 -Wall -Wextra -O0 -g -fcolor-diagnostics # debug
4-CFLAGS = -std=c99 -Wall -Wextra -O2 -fcolor-diagnostics
5+# CFLAGS = -std=c99 -Wall -Wextra -O0 -g -fdiagnostics-color=auto # debug
6+CFLAGS = -std=c99 -Wall -Wextra -O2
7 CPPFLAGS = -D_POSIX_C_SOURCE=200809L -Isource/include
8
9 OUT = tohu
10 SRC = source/tohu.c source/util.c
11
12 PKGS = swc wayland-server xkbcommon libinput pixman-1 libdrm wld libudev xcb xcb-composite xcb-ewmh xcb-icccm
13-CFLAGS += $(shell pkg-config --cflags $(PKGS))
14-LDLIBS += $(shell pkg-config --libs $(PKGS)) -lm
15-
16+CFLAGS = `pkg-config --cflags $(PKGS)`
17+LDLIBS = `pkg-config --libs $(PKGS)`
18 all: ${OUT}
19
20 ${OUT}: ${SRC}
+18,
-0
1@@ -0,0 +1,18 @@
2+build all: phony tohu
3+
4+rule r1
5+ command = cc -std=c99 -Wall -Wextra -O2 -fdiagnostics-color=auto -I/usr/local/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/libdrm/nouveau -D_POSIX_C_SOURCE=200809L -Isource/include -o tohu source/tohu.c source/util.c -L/usr/local/lib -lswc -lwayland-server -lxkbcommon -linput -lwld -lfontconfig -lpixman-1 -lfreetype -lwayland-client -lm -ldrm_nouveau -ldrm_intel -ldrm -ludev -lxcb-composite -lxcb-ewmh -lxcb-icccm -lxcb -lm -Wl,-rpath,/usr/local/lib
6+
7+build tohu: r1 source/tohu.c source/util.c
8+
9+rule r2
10+ command = rm -f tohu
11+
12+build clean: r2
13+
14+rule r3
15+ command = rm -f compile_flags.txt && for f in -std=c99 -Wall -Wextra -O2 -fdiagnostics-color=auto -I/usr/local/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/libdrm -I/usr/include/libdrm/nouveau -D_POSIX_C_SOURCE=200809L -Isource/include; do echo $$f >> compile_flags.txt; done
16+
17+build compile_flags: r3
18+
19+default all
+15,
-0
1@@ -12,6 +12,21 @@ static const struct config cfg = {
2 .border_col_active = 0xffed953e,
3 .border_col_normal = 0xff444444,
4 .border_width = 1,
5+ .decor = {
6+ .color = 0xff444444,
7+ .top = 2,
8+ .right = 2,
9+ .bottom = 2,
10+ .left = 24,
11+ .title = {
12+ .enabled = true,
13+ .edge = SWC_DECOR_EDGE_LEFT,
14+ .align = SWC_DECOR_ALIGN_START,
15+ .color = 0xffffffff,
16+ .padding = 8,
17+ .font = "gallant12x22:size=12", /*you should probably change this to a font you have*/
18+ },
19+ },
20 .gaps = 0,
21 };
22
+1,
-0
1@@ -54,6 +54,7 @@ struct config {
2 uint32_t border_col_active;
3 uint32_t border_col_normal;
4 uint32_t border_width;
5+ struct swc_decor decor;
6 uint32_t gaps;
7 };
8
+64,
-2
1@@ -1,6 +1,7 @@
2 #include <signal.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5+#include <string.h>
6 #include <unistd.h>
7
8 #include <swc.h>
9@@ -14,6 +15,8 @@
10 #include "tohu.h"
11
12 static void focus(struct client* c);
13+static void apply_decor(struct client* c, bool active);
14+static const char* decorstring(struct client* c, char* buf, size_t size);
15 static struct client* first_client(struct screen* s);
16 static bool is_ws_client(const struct client* c, const struct screen* s);
17 static void on_screen_destroy(void* data);
18@@ -36,24 +39,80 @@ struct swc_screen_handler screen_handler = {
19
20 static void focus(struct client* c)
21 {
22- if (wm.sel_client)
23+ if (wm.sel_client) {
24 swc_window_set_border(
25 wm.sel_client->win,
26 cfg.border_col_normal, cfg.border_width,
27 0, 0
28 );
29+ apply_decor(wm.sel_client, false);
30+ }
31
32- if (c)
33+ if (c) {
34 swc_window_set_border(
35 c->win,
36 cfg.border_col_active, cfg.border_width,
37 0, 0
38 );
39+ apply_decor(c, true);
40+ }
41
42 swc_window_focus(c ? c->win : NULL);
43 wm.sel_client = c;
44 }
45
46+static void apply_decor(struct client* c, bool active)
47+{
48+ char process_name[256];
49+ const char* title;
50+ struct swc_decor decor;
51+
52+ if (!c)
53+ return;
54+
55+ if (c->fullscreen) {
56+ swc_window_set_decor(c->win, NULL);
57+ return;
58+ }
59+
60+ decor = cfg.decor;
61+ decor.color = active ? cfg.border_col_active : cfg.border_col_normal;
62+ title = decorstring(c, process_name, sizeof(process_name));
63+ if (title)
64+ decor.title.string = title;
65+ swc_window_set_decor(c->win, &decor);
66+}
67+
68+static const char* decorstring(struct client* c, char* buf, size_t size)
69+{
70+ char path[64];
71+ FILE* fp;
72+ pid_t pid;
73+ size_t len;
74+
75+ if (!c || !buf || size == 0)
76+ return NULL;
77+
78+ pid = swc_window_get_pid(c->win);
79+ if (pid <= 0)
80+ return NULL;
81+
82+ snprintf(path, sizeof(path), "/proc/%lld/comm", (long long)pid);
83+ fp = fopen(path, "r");
84+ if (!fp)
85+ return NULL;
86+
87+ if (!fgets(buf, (int)size, fp)) {
88+ fclose(fp);
89+ return NULL;
90+ }
91+
92+ fclose(fp);
93+ len = strcspn(buf, "\n");
94+ buf[len] = '\0';
95+ return buf[0] ? buf : NULL;
96+}
97+
98 static struct client* first_client(struct screen* s)
99 {
100 struct client* c;
101@@ -310,6 +369,7 @@ void fullscreen(void* data, uint32_t time, uint32_t value, uint32_t state)
102 if (wm.sel_client->fullscreen) {
103 wm.sel_client->fullscreen = false;
104 swc_window_set_stacked(wm.sel_client->win);
105+ apply_decor(wm.sel_client, true);
106
107 if (wm.sel_client->w > 0 && wm.sel_client->h > 0) {
108 geom.x = wm.sel_client->x;
109@@ -332,6 +392,7 @@ void fullscreen(void* data, uint32_t time, uint32_t value, uint32_t state)
110 }
111
112 wm.sel_client->fullscreen = true;
113+ apply_decor(wm.sel_client, true);
114 swc_window_set_fullscreen(wm.sel_client->win, wm.sel_client->scr->scr);
115 }
116
117@@ -455,6 +516,7 @@ void new_window(struct swc_window* win)
118 wl_list_insert(&wm.clients, &c->link);
119 swc_window_set_handler(win, &window_handler, c);
120 swc_window_set_stacked(win);
121+ apply_decor(c, false);
122 {
123 /* swc reports cursor coordinates in wl_fixed_t (24.8) units */
124 int32_t cx_fixed = 0;